[Schmitzm-commits] r156 - in trunk: dist src/schmitzm/geotools src/schmitzm/geotools/gui
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Mon Jun 22 14:58:50 CEST 2009
Author: mojays
Date: 2009-06-22 14:58:36 +0200 (Mon, 22 Jun 2009)
New Revision: 156
Modified:
trunk/dist/schmitzm-src.zip
trunk/dist/schmitzm.jar
trunk/src/schmitzm/geotools/JTSUtil.java
trunk/src/schmitzm/geotools/gui/JMapPane.java
Log:
JMapPane: Selection now "CRS-sensitive"
Modified: trunk/dist/schmitzm-src.zip
===================================================================
(Binary files differ)
Modified: trunk/dist/schmitzm.jar
===================================================================
(Binary files differ)
Modified: trunk/src/schmitzm/geotools/JTSUtil.java
===================================================================
--- trunk/src/schmitzm/geotools/JTSUtil.java 2009-06-22 10:53:59 UTC (rev 155)
+++ trunk/src/schmitzm/geotools/JTSUtil.java 2009-06-22 12:58:36 UTC (rev 156)
@@ -19,6 +19,7 @@
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
+import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
/**
@@ -66,4 +67,26 @@
}
return destEnv;
}
+
+ /**
+ * Transformiert eine Koordinate von einem CRS in ein anderes.
+ * @param sourceCoord Koordinate
+ * @param sourceCRS CRS von {@code sourceCoord}
+ * @param destCRS CRS in das umgerechnet werden soll
+ * @see CRS#findMathTransform(CoordinateReferenceSystem,CoordinateReferenceSystem)
+ * @see JTS#transform(Coordinate, Coordinate, MathTransform)
+ */
+ public static Coordinate transformCoordinate(Coordinate sourceCoord, CoordinateReferenceSystem sourceCRS, CoordinateReferenceSystem destCRS) {
+ Coordinate destCoord = null;
+ MathTransform transform;
+ try {
+ transform = CRS.findMathTransform(sourceCRS, destCRS);
+ destCoord = JTS.transform(sourceCoord,null,transform);
+ } catch (FactoryException e) {
+ LOGGER.warn("CRS tranformation for JTS coordinate not successful",e);
+ } catch (TransformException e) {
+ LOGGER.warn("CRS tranformation for JTS coordinate not successful",e);
+ }
+ return destCoord;
+ }
}
Modified: trunk/src/schmitzm/geotools/gui/JMapPane.java
===================================================================
--- trunk/src/schmitzm/geotools/gui/JMapPane.java 2009-06-22 10:53:59 UTC (rev 155)
+++ trunk/src/schmitzm/geotools/gui/JMapPane.java 2009-06-22 12:58:36 UTC (rev 156)
@@ -27,8 +27,10 @@
import java.awt.image.BufferedImage;
import java.io.IOException;
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;
@@ -46,6 +48,7 @@
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureType;
+import org.geotools.feature.GeometryAttributeType;
import org.geotools.filter.AbstractFilter;
import org.geotools.filter.FilterFactoryImpl;
import org.geotools.filter.GeometryFilterImpl;
@@ -69,6 +72,7 @@
import org.opengis.coverage.CannotEvaluateException;
import org.opengis.filter.Filter;
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;
@@ -78,6 +82,7 @@
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.map.event.FeatureSelectedEvent;
import schmitzm.geotools.map.event.GeneralSelectionEvent;
@@ -133,2272 +138,2430 @@
* {@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 org.geotools.gui.swing.JMapPane {
- /**
- * 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: 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.equals(mapArea) && (getState() == ZOOM_IN || getState() == ZOOM_OUT))
- fireMapPaneEvent(new MapAreaChangedEvent(this, oldMapArea, mapArea));
- }
+ // 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.equals(mapArea) && (getState() == ZOOM_IN || getState() == ZOOM_OUT))
+ fireMapPaneEvent(new MapAreaChangedEvent(this, oldMapArea, mapArea));
+ }
- private static final Cursor WAIT_CURSOR = Cursor
- .getPredefinedCursor(Cursor.WAIT_CURSOR);
+ private static final Cursor WAIT_CURSOR = Cursor
+ .getPredefinedCursor(Cursor.WAIT_CURSOR);
- /** Logger for debug messages. */
- protected static final Logger LOGGER = Logger.getLogger(JMapPane.class
- .getName());
+ /** Logger for debug messages. */
+ protected static final Logger LOGGER = Logger.getLogger(JMapPane.class
+ .getName());
- /** @deprecated ersetzt durch {@link #ZOOM_IN} */
- public static final int ZoomIn = org.geotools.gui.swing.JMapPane.ZoomIn;
- /** @deprecated ersetzt durch {@link #ZOOM_OUT} */
- public static final int ZoomOut = org.geotools.gui.swing.JMapPane.ZoomOut;
- /** @deprecated ersetzt durch {@link #PAN} */
- public static final int Pan = org.geotools.gui.swing.JMapPane.Pan;
- /** @deprecated ersetzt durch {@link #RESET} */
- public static final int Reset = org.geotools.gui.swing.JMapPane.Reset;
- /** @deprecated ersetzt durch {@link #SELECT_TOP} */
- public static final int Select = org.geotools.gui.swing.JMapPane.Select;
+ /** @deprecated ersetzt durch {@link #ZOOM_IN} */
+ public static final int ZoomIn = org.geotools.gui.swing.JMapPane.ZoomIn;
+ /** @deprecated ersetzt durch {@link #ZOOM_OUT} */
+ public static final int ZoomOut = org.geotools.gui.swing.JMapPane.ZoomOut;
+ /** @deprecated ersetzt durch {@link #PAN} */
+ public static final int Pan = org.geotools.gui.swing.JMapPane.Pan;
+ /** @deprecated ersetzt durch {@link #RESET} */
+ public static final int Reset = org.geotools.gui.swing.JMapPane.Reset;
+ /** @deprecated ersetzt durch {@link #SELECT_TOP} */
+ public static final int Select = org.geotools.gui.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 = org.geotools.gui.swing.JMapPane.Reset;
- /**
- * Flag fuer Modus "Kartenausschnitt bewegen". Nicht fuer Window-Auswahl
- * moeglich!
- *
- * @see #setState(int)
- */
- public static final int PAN = org.geotools.gui.swing.JMapPane.Pan;
- /**
- * Flag fuer Modus "Heran zoomen".
- *
- * @see #setWindowSelectionState(int)
- * @see #setState(int)
- */
- public static final int ZOOM_IN = org.geotools.gui.swing.JMapPane.ZoomIn;
- /**
- * Flag fuer Modus "Heraus zoomen". Nicht fuer Window-Auswahl moeglich!
- *
- * @see #setState(int)
- */
- public static final int ZOOM_OUT = org.geotools.gui.swing.JMapPane.ZoomOut;
- /**
- * Flag fuer Modus "Feature-Auswahl auf dem obersten (sichtbaren) Layer".
- *
- * @see #setWindowSelectionState(int)
- * @see #setState(int)
- */
- public static final int SELECT_TOP = org.geotools.gui.swing.JMapPane.Select;
- /**
- * Flag fuer Modus "Feature-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;
+ /**
+ * 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 = org.geotools.gui.swing.JMapPane.Reset;
+ /**
+ * Flag fuer Modus "Kartenausschnitt bewegen". Nicht fuer Window-Auswahl
+ * moeglich!
+ *
+ * @see #setState(int)
+ */
+ public static final int PAN = org.geotools.gui.swing.JMapPane.Pan;
+ /**
+ * Flag fuer Modus "Heran zoomen".
+ *
+ * @see #setWindowSelectionState(int)
+ * @see #setState(int)
+ */
+ public static final int ZOOM_IN = org.geotools.gui.swing.JMapPane.ZoomIn;
+ /**
+ * Flag fuer Modus "Heraus zoomen". Nicht fuer Window-Auswahl moeglich!
+ *
+ * @see #setState(int)
+ */
+ public static final int ZOOM_OUT = org.geotools.gui.swing.JMapPane.ZoomOut;
+ /**
+ * Flag fuer Modus "Feature-Auswahl auf dem obersten (sichtbaren) Layer".
+ *
+ * @see #setWindowSelectionState(int)
+ * @see #setState(int)
+ */
+ public static final int SELECT_TOP = org.geotools.gui.swing.JMapPane.Select;
+ /**
+ * Flag fuer Modus "Feature-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;
+ /** 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;
+ /**
+ * 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>();
+ /**
+ * Liste der angeschlossenen Listener, die auf Aktionen des MapPanes
+ * lauschen.
+ */
+ protected Vector<JMapPaneListener> mapPaneListeners = new Vector<JMapPaneListener>();
- protected MouseSelectionTracker_Public selTracker = new MouseSelectionTracker_Public() {
- // MS (2009-13-05): noch buggy -> wieder rausgenommen (Probleme mit
- // mehreren parallelen Mouse(Motion)Listenern
- 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;
- if (getState() == ZOOM_IN || getState() == ZOOM_OUT)
- return;
+ protected MouseSelectionTracker_Public selTracker = new MouseSelectionTracker_Public() {
+ 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);
- }
+ 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);
- }
- };
+ 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 FilterFactoryImpl ff = FilterUtil.FILTER_FAC;
- private static final GeometryFactory gf = FilterUtil.GEOMETRY_FAC;
+ private static final FilterFactoryImpl ff = FilterUtil.FILTER_FAC;
+ private static final GeometryFactory gf = FilterUtil.GEOMETRY_FAC;
- /**
- * A flag indicating if dispose() was already called. If true, then further
- * use of this {@link JMapPane} is undefined.
- */
- private boolean disposed = false;
+ /**
+ * 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 MouseWheelListener mouseWheelZoomListener;
+ /** Listener, der auf das Mausrad lauscht und mit Zoom reagiert */
+ private MouseWheelListener mouseWheelZoomListener;
- // /** 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 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;
+ /**
+ * 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);
+ /** 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;
+ /**
+ * Manuell gesetzter statischer Cursor, unabhaengig von der aktuellen
+ * MapPane-Funktion
+ */
+ protected Cursor staticCursor = null;
- private MouseInputAdapter dragWaitCursorListener;
+ private MouseInputAdapter dragWaitCursorListener;
- /** An (transparent) image to paint over the map in the lower right corner **/
- private BufferedImage mapImage = null;
+ /** An (transparent) image to paint over the map in the lower right corner **/
+ private BufferedImage mapImage = null;
- /**
- * Erzeugt ein neues MapPane.
- *
- * @param layout
- * Layout-Manager fuer die GUI-Komponente (z.B.
- * {@link BorderLayout})
- * @param isDoubleBuffered
- * siehe Konstruktor der
- * {@linkplain org.geotools.gui.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);
- }
+ /**
+ * Erzeugt ein neues MapPane.
+ *
+ * @param layout
+ * Layout-Manager fuer die GUI-Komponente (z.B.
+ * {@link BorderLayout})
+ * @param isDoubleBuffered
+ * siehe Konstruktor der
+ * {@linkplain org.geotools.gui.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);
+ }
- /**
- * Erzeugt ein neues MapPane.
- *
- * @param layout
- * Layout-Manager fuer die GUI-Komponente (z.B.
- * {@link BorderLayout})
- * @param isDoubleBuffered
- * siehe Konstruktor der
- * {@linkplain org.geotools.gui.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}
- * ).
- */
- public JMapPane(LayoutManager layout, Boolean isDoubleBuffered,
- GTRenderer renderer, MapContext context) {
- super(layout != null ? layout : new BorderLayout(), isDoubleBuffered != null ? isDoubleBuffered : true,
- renderer != null ? renderer : new StreamingRenderer(),
- context != null ? context : new DefaultMapContext(GTUtil.WGS84));
+ /**
+ * Erzeugt ein neues MapPane.
+ *
+ * @param layout
+ * Layout-Manager fuer die GUI-Komponente (z.B.
+ * {@link BorderLayout})
+ * @param isDoubleBuffered
+ * siehe Konstruktor der
+ * {@linkplain org.geotools.gui.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}
+ * ).
+ */
+ public JMapPane(LayoutManager layout, Boolean isDoubleBuffered,
+ GTRenderer renderer, MapContext context) {
+ super(layout != null ? layout : new BorderLayout(), isDoubleBuffered != null ? isDoubleBuffered : true,
+ renderer != null ? renderer : new StreamingRenderer(),
+ context != null ? context : new DefaultMapContext(GTUtil.WGS84));
- // 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 hints = ImageUtilities.NN_INTERPOLATION_HINT;
- getRenderer().setJava2DHints(hints);
+ // 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 hints = ImageUtilities.NN_INTERPOLATION_HINT;
+ getRenderer().setJava2DHints(hints);
- // 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 );
+ // 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);
+ setWindowSelectionState(ZOOM_IN);
+ setState(ZOOM_IN);
- // MS (2009-13-05): noch buggy -> wieder rausgenommen (Probleme mit
- // mehreren parallelen Mouse(Motion)Listenern
- // // Listener fuer Selektions-Rahmen
- // addMouseListener(selTracker);
+ // Listener, der auf das Mausrad lauscht und mit Zoom reagiert
+ mouseWheelZoomListener = new MouseWheelListener() {
+ public void mouseWheelMoved(MouseWheelEvent e) {
+ performMouseWheelEvent(e);
+ }
+ };
+ this.addMouseWheelListener(mouseWheelZoomListener);
- // Listener, der auf das Mausrad lauscht und mit Zoom reagiert
- mouseWheelZoomListener = new MouseWheelListener() {
- public void mouseWheelMoved(MouseWheelEvent e) {
- performMouseWheelEvent(e);
- }
- };
- this.addMouseWheelListener(mouseWheelZoomListener);
+ // Listener, der auf das Mausrad lauscht und mit Zoom reagiert
+ mouseWheelZoomListener = new MouseWheelListener() {
+ public void mouseWheelMoved(MouseWheelEvent e) {
+ performMouseWheelEvent(e);
+ }
+ };
+ 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);
+ /**
+ * 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
+ // 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());
- }
+ 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 layerAdded(
+ org.geotools.map.event.MapLayerListEvent e) {
+ resetHighlightLayer();
+ }
- public void layerChanged(
- 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 layerMoved(
+ org.geotools.map.event.MapLayerListEvent e) {
+ resetHighlightLayer();
+ }
- public void layerRemoved(
- 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 schmitzm.geotools.map.event.MapLayerListAdapter() {
- public void layerAdded(
- org.geotools.map.event.MapLayerListEvent e) {
- if (getContext().getLayerCount() == 1) {
- CoordinateReferenceSystem crs = null;
- // CRS aus Layer ermitteln
- try {
- crs = e.getLayer().getFeatureSource()
- .getSchema().getDefaultGeometry()
- .getCoordinateSystem();
- // 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());
- // 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)
- newMapArea.expandBy(
- newMapArea.getWidth() * 0.1,
- newMapArea.getHeight() * 0.1);
- 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. WGS84 used.");
- // err.printStackTrace();
- crs = DefaultGeographicCRS.WGS84;
- }
- // CRS dem MapContext zuweisen
- try {
- getContext().setCoordinateReferenceSystem(crs);
- } catch (Exception err) {
- LOGGER
- .error("CRS could not be assigned to map context.");
- }
- }
- }
- });
- }
+ // 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 schmitzm.geotools.map.event.MapLayerListAdapter() {
+ public void layerAdded(
+ org.geotools.map.event.MapLayerListEvent e) {
+ if (getContext().getLayerCount() == 1) {
+ CoordinateReferenceSystem crs = null;
+ // CRS aus Layer ermitteln
+ try {
+ crs = e.getLayer().getFeatureSource()
+ .getSchema().getDefaultGeometry()
+ .getCoordinateSystem();
+ // 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());
+ // 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)
+ newMapArea.expandBy(
+ newMapArea.getWidth() * 0.1,
+ newMapArea.getHeight() * 0.1);
+ 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. WGS84 used.");
+ // err.printStackTrace();
+ crs = DefaultGeographicCRS.WGS84;
+ }
+ // 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.");
+ }
+ }
+ }
+ });
+ }
- /**
- * 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;
- }
+ /**
+ * 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;
- }
+ /**
+ * 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üger</a>
- *
- * @return null oder {@link Component}
- */
- public Component getWaitCursorComponent() {
- return mouseWaitCursorComponent;
- }
+ /**
+ * 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ü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üger</a>
- */
- public void setWaitCursorComponent(Component parentComponent) {
- this.mouseWaitCursorComponent = parentComponent;
- }
+ /**
+ * 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ü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üger</a>
- */
- public void refresh() {
+ /**
+ * 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ü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);
+ // 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();
- }
+ 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ü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);
- }
+ /**
+ * 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ü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 {
+ /**
+ * 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 Envelope mapAreaNew = JTSUtil.transformEnvelope(layer
- .getFeatureSource().getBounds(), layer.getFeatureSource()
- .getSchema().getDefaultGeometry().getCoordinateSystem(),
- getContext().getCoordinateReferenceSystem());
- // 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)
- mapAreaNew.expandBy(mapAreaNew.getWidth() * 0.1, mapAreaNew
- .getHeight() * 0.1);
- setMapArea(mapAreaNew);
- } catch (Exception err) {
- LOGGER.warn("Zoom to layer did not terminate correctly", err);
- }
- }
+ // BB umrechnen von Layer-CRS in Map-CRS
+ final Envelope mapAreaNew = JTSUtil.transformEnvelope(layer
+ .getFeatureSource().getBounds(), layer.getFeatureSource()
+ .getSchema().getDefaultGeometry().getCoordinateSystem(),
+ getContext().getCoordinateReferenceSystem());
+ // 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)
+ mapAreaNew.expandBy(mapAreaNew.getWidth() * 0.1, mapAreaNew
+ .getHeight() * 0.1);
+ setMapArea(mapAreaNew);
+ } catch (Exception err) {
+ LOGGER.warn("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ü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 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ü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üger</a>
- */
- public void zoomToLayerIdxReverse(int index) {
- zoomToLayer(getContext().getLayerCount() - 1 - 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ü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 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 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 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 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 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;
- }
+ /**
+ * 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!");
+ /**
+ * 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!");
- // MS (2009-13-05): noch buggy -> wieder reingenommen (Probleme mit
- // mehreren parallelen Mouse(Motion)Listenern
- // MS (13.05.2009): Wird durch Ueberschreiben von mouseDragged(.) des
- // MouseSelectionTracker realisiert
- // 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);
- }
+ // 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;
+ this.selState = newSelState;
- // Je nach Aktion den Cursor umsetzen
- updateCursor();
- }
+ // 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);
- }
+ /**
+ * 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;
- }
+ /**
+ * 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;
- }
- }
+ /**
+ * 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;
- }
+ /**
+ * 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);
- }
+ /**
+ * 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);
- }
+ /**
+ * 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);
- }
+ /**
+ * 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 GeoMouseEvent)
- try {
- return ((GeoMouseEvent) e).getMapCoordinate(null).toPoint2D();
- } catch (Exception err) {
- err.printStackTrace();
- }
+ /**
+ * 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 GeoMouseEvent)
+ try {
+ return ((GeoMouseEvent) e).getMapCoordinate(null).toPoint2D();
+ } catch (Exception err) {
+ err.printStackTrace();
+ }
- // 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);
- }
+ // 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;
- }
+ 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;
+ /**
+ * 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)
- return;
+ // keine wirkliche Selektion, sondern nur ein Klick
+ if (ox == px || oy == py)
+ return;
- // Fenster-Koordinaten in Map-Koordinaten umwandeln
- Envelope env = tranformWindowToGeo(ox, oy, px, py);
+ // Fenster-Koordinaten in Map-Koordinaten umwandeln
+ Envelope env = tranformWindowToGeo(ox, oy, px, py);
- // Generelles Event ausloesen
- fireMapPaneEvent(new GeneralSelectionEvent(this, env));
+ // 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(
- createBoundingBoxFilter(env), selectState, env);
- if (selectState == SELECT_ALL || !featuresFound)
- findGridCoverageSubsetsAndFireEvents(env, selectState);
- break;
- }
- }
+ 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 e
- * Mausrad-Event
- */
- protected void performMouseWheelEvent(MouseWheelEvent e) {
- if (getContext().getLayerCount() == 0)
- return;
+ /**
+ * Verarbeitet die Mausrad-Aktion, indem gezoomed wird.
+ *
+ * @param e
+ * Mausrad-Event
+ */
+ protected void performMouseWheelEvent(MouseWheelEvent e) {
+ if (getContext().getLayerCount() == 0)
+ return;
- int units = e.getUnitsToScroll();
- // Positiver Wert --> Zoom in --> Faktor < 1
- // Negativer Wert --> Zoom out --> Faktir > 1
+ int units = e.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;
+ // 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
- Point2D mapCoord = getTransform().transform(e.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();
+ // Fenster-Koordinaten zu Karten-Koordinaten transformieren
+ Point2D mapCoord = getTransform().transform(e.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));
+ // 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();
- }
+ setWaitCursorDuringNextRepaint(true);
+ repaint();
+ }
- /**
- * 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 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 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);
- }
+ /**
+ * 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;
- 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());
- }
+ /**
+ * Berechnet die Transformation zwischen Fenster- und Karten-Koordinaten
+ * neu.
+ */
+ protected void resetTransform() {
+ if (getMapArea() == null || getWidth() == 0 || getHeight() == 0)
+ return;
+ 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;
- }
+ /**
+ * 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üger</a>
- */
- @Override
- public void setMapArea(Envelope env) {
- // **********************************************************************
- // 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);
- }
+ /**
+ * 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üger</a>
+ */
+ @Override
+ public void setMapArea(Envelope env) {
+ // **********************************************************************
+ // 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();
+ double oldScale = getScale();
+ Envelope oldEnv = getMapArea();
- super.setMapArea(env);
+ super.setMapArea(env);
- resetTransform();
- double newScale = getScale();
- Envelope newEnv = getMapArea();
+ 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));
- }
+ 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üger</a>
- */
- public void mouseClicked(MouseEvent e) {
- // wenn noch kein Layer dargestellt wird, nichts machen
- if (getContext().getLayerCount() == 0)
- return;
+ /**
+ * 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üger</a>
+ */
+ public void mouseClicked(MouseEvent e) {
+ // wenn noch kein Layer dargestellt wird, nichts machen
+ if (getContext().getLayerCount() == 0)
+ return;
- // double oldScale = getScale();
- // Envelope oldEnv = getMapArea();
+ // double oldScale = getScale();
+ // Envelope oldEnv = getMapArea();
- switch (e.getButton()) {
- // Linksklick --> Eingestellte Funktion
- case MouseEvent.BUTTON1: // Feature-Auswahl nicht ueber die
- // super-Funktion
- int state = getState();
+ switch (e.getButton()) {
+ // Linksklick --> Eingestellte Funktion
+ case MouseEvent.BUTTON1: // Feature-Auswahl nicht ueber die
+ // super-Funktion
+ int state = getState();
- if (state == SELECT_TOP || state == SELECT_ONE_FROM_TOP
- || state == SELECT_ALL) {
+ 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 Feature verschickt. Und zwar
- * jenes Feature, welches am nächsten liegt.
- */
+ /**
+ * 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 Feature verschickt. Und zwar
+ * jenes Feature, 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()));
+ // 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());
+ // 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());
- final Envelope envelope = new Envelope(geoCoord.getX(),
- geoCoord.getX(), geoCoord.getY(), geoCoord.getY());
+ final Envelope envelope = new Envelope(geoCoord.getX(),
+ geoCoord.getX(), geoCoord.getY(), geoCoord.getY());
- Hashtable<MapLayer, FeatureCollection> result = findVisibleFeatures(
- createNearPointFilter(geoCoord, dist), state, envelope);
+ Hashtable<MapLayer, FeatureCollection> result = findVisibleFeatures(
+ new NearPointFilterGenerator(geoCoord, dist, getContext().getCoordinateReferenceSystem()),
+ state,
+ envelope
+ );
- boolean featuresFound = false;
- // Events ausloesen fuer jedes Layer
- for (Enumeration<MapLayer> element = result.keys(); element
- .hasMoreElements();) {
+ boolean featuresFound = false;
+ // Events ausloesen fuer jedes Layer
+ for (Enumeration<MapLayer> element = result.keys(); element
+ .hasMoreElements();) {
- MapLayer layer = element.nextElement();
- FeatureCollection fc = result.get(layer);
- FeatureCollection fcOne;
+ MapLayer layer = element.nextElement();
+ FeatureCollection fc = result.get(layer);
+ FeatureCollection fcOne;
- if (fc != null && !fc.isEmpty()) {
+ if (fc != null && !fc.isEmpty()) {
- if (fc.size() > 1) {
- // Hier werden alle Features weggeschmissen, bis auf
- // das raeumlich naechste.
+ if (fc.size() > 1) {
+ // Hier werden alle Features weggeschmissen, bis auf
+ // das raeumlich naechste.
- Feature nearestFeature = null;
- Double nearestDist = 0.0;
+ Feature nearestFeature = null;
+ Double nearestDist = 0.0;
- Iterator<Feature> fcIt = fc.iterator();
- while (fcIt.hasNext()) {
- Feature f = fcIt.next();
- Object obj = f.getAttribute(0);
+ Iterator<Feature> fcIt = fc.iterator();
+ while (fcIt.hasNext()) {
+ Feature 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 (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());
- }
+ if ((nearestFeature == null)
+ || (distance < nearestDist)) {
+ nearestFeature = f;
+ nearestDist = distance;
+ }
+ } else {
+ LOGGER
+ .info("!obj instanceof Geometry obj = "
+ + obj.getClass()
+ .getSimpleName());
+ }
- }
- fc.close(fcIt);
+ }
+ fc.close(fcIt);
- fcOne = new MemoryFeatureCollection(fc
- .getFeatureType());
- fc.clear();
- fcOne.add(nearestFeature);
- } else {
- fcOne = fc;
- }
- fireMapPaneEvent(new FeatureSelectedEvent(
- JMapPane.this, layer, envelope, fcOne));
- featuresFound = true;
- }
- }
+ fcOne = new MemoryFeatureCollection(fc
+ .getFeatureType());
+ 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 Feature layers, dann
- // grid layers check ist doof!
- // if (state == SELECT_ALL || !result.isEmpty())
+ // TODO TODO TODO SK: DIese trennung: erst Feature 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);
- }
+ // LOGGER.info("state= "+state+" featuresFound = "+
+ // featuresFound);
+ if (state == SELECT_ALL || !featuresFound) {
+ // LOGGER.info(" findGridCoverageValuesAndFireEvents");
+ findGridCoverageValuesAndFireEvents(geoCoord, state);
+ }
- break;
- }
- super.mouseClicked(e);
- return; // was: breka, aber wir brauchen ja nicht das
- // setMapArea(mapArea)
+ break;
+ }
+ super.mouseClicked(e);
+ return; // was: breka, aber wir brauchen ja nicht das
+ // setMapArea(mapArea)
- // 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 Links-Klick auf ZOOM_IN eingestellt ist)
- // if ( oldState != ZOOM_IN )
- // return;
- setState(ZOOM_OUT);
- super.mouseClicked(e);
- setState(oldState);
- break;
- // Sonst nix
- default:
- return;
- }
+ // 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 Links-Klick auf ZOOM_IN eingestellt ist)
+ // if ( oldState != ZOOM_IN )
+ // return;
+ setState(ZOOM_OUT);
+ super.mouseClicked(e);
+ setState(oldState);
+ break;
+ // Sonst nix
+ default:
+ return;
+ }
- // In super.mouseClicked(.) wird (nach Zoom) die MapArea neu gesetzt,
- // aber
- // leider ohne setMapArea(.) aufzurufen, sondern indem einfach die
- // Variable
- // 'mapArea' neu belegt wird
- // --> Transform muss neu berechnet werden
- // --> Aenderung der Aufloesung propagieren
+ // In super.mouseClicked(.) wird (nach Zoom) die MapArea neu gesetzt,
+ // aber
+ // leider ohne setMapArea(.) aufzurufen, sondern indem einfach die
+ // Variable
+ // 'mapArea' neu belegt wird
+ // --> Transform muss neu berechnet werden
+ // --> Aenderung der Aufloesung propagieren
- setMapArea(mapArea);
- // 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) );
- }
+ setMapArea(mapArea);
+ // 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) );
+ }
- /**
- * 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.geotools.gui.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üger</a>
- */
- protected void paintComponent(Graphics g) {
- Cursor oldCursor = null;
- boolean seriouseChange = false;
+ /**
+ * 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.geotools.gui.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ü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 (!getBounds().equals(oldRect) || reset)
+ seriouseChange = true;
+ else if (!mapArea.equals(oldMapArea))
+ seriouseChange = true;
- if (seriouseChange) {
- if (setWaitCursorDuringNextRepaint) {
+ if (seriouseChange) {
+ if (setWaitCursorDuringNextRepaint) {
- if (getWaitCursorComponent() != null) {
- // Der Cursor soll auch in einer anderen Component geaendert
- // werden..
- oldCursor = getWaitCursorComponent().getCursor();
- getWaitCursorComponent().setCursor(WAIT_CURSOR);
- }
+ 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);
- }
- }
+ // Den Cursor extra nochmal in dieser COmponente aendern
+ setCursor(WAIT_CURSOR);
+ }
+ }
- try {
- super.paintComponent(g);
- } catch (Exception e) {
- /**
- * I only need to catch UnknownHostException.. well...
- */
- LOGGER.info(e);
- LOGGER
- .info("Probably we are offline and reference some online SVGs? ");
- }
- if (seriouseChange) {
- resetTransform();
- if (setWaitCursorDuringNextRepaint) {
- setWaitCursorDuringNextRepaint = false;
- if (oldCursor != null)
- getWaitCursorComponent().setCursor(oldCursor);
- updateCursor(); // Den Cursor in dieser Componente immer wieder
- // herstellen
- }
+ try {
+ super.paintComponent(g);
+ } catch (Exception e) {
+ /**
+ * I only need to catch UnknownHostException.. well...
+ */
+ LOGGER.info(e);
+ LOGGER
+ .info("Probably we are offline and reference some online SVGs? ");
+ }
+ 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) {
- baseImage
- .getGraphics()
- .drawImage(
- mapImage,
- baseImage.getWidth() - mapImage.getWidth() - 10,
- baseImage.getHeight() - mapImage.getHeight()
- - 10, this);
- // Repaint with the cached image (fast) which now contains the
- // logo
- super.paintComponent(g);
- }
- }
+ /**
+ * Paint an icon in the lower right corner. FeatureRequest: [#717]
+ * MapIcon has long been disabled and should come back
+ */
+ if (mapImage != null && baseImage != null) {
+ baseImage
+ .getGraphics()
+ .drawImage(
+ mapImage,
+ baseImage.getWidth() - mapImage.getWidth() - 10,
+ baseImage.getHeight() - mapImage.getHeight()
+ - 10, this);
+ // 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().getDefaultGeometry().getCoordinateSystem(),
- getContext().getCoordinateReferenceSystem());
+ /**
+ * 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().getDefaultGeometry().getCoordinateSystem(),
+ getContext().getCoordinateReferenceSystem());
- // TODO warum kann bounds_MapCRS == null sein ?? ?SK fragt martin???
- if (bounds_MapCRS == null)
- return false;
+ // 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;
- }
- }
+ 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);
- return !layer.getFeatureSource().getFeatures(filter).isEmpty();
- } 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);
+ GeometryFilterImpl filter = new BoundingBoxFilterGenerator(
+ env,
+ getContext().getCoordinateReferenceSystem()
+ ).adaptFilter(layer.getFeatureSource());
+ 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 distancefilter
- * Filter
- * @param mode
- * Suchmodus
- * @return eine leere {@link Hashtable} falls der Filter {@code null} ist
- */
- protected Hashtable<MapLayer, FeatureCollection> findVisibleFeatures(
- GeometryFilterImpl distancefilter, int mode, Envelope env) {
- Hashtable<MapLayer, FeatureCollection> result = new Hashtable<MapLayer, FeatureCollection>();
- if (distancefilter == null)
- return result;
+ /**
+ * 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> findVisibleFeatures(
+ GeomFilterGenerator filterGenerator, int mode, Envelope env) {
+ Hashtable<MapLayer, FeatureCollection> result = new Hashtable<MapLayer, FeatureCollection>();
+ 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;
+ // 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.
- // Ansonsten Raster-Layer einfach uebergehen.
- if (isGridCoverageLayer(layer)) {
- if (mode == SELECT_TOP
- && gridLayerIntersectsEnvelope(layer, env))
- break;
- continue;
- }
+ // 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 featureSource = layer.getFeatureSource();
- Expression geometry = ff.createAttributeExpression(featureSource
- .getSchema().getDefaultGeometry().getLocalName());
+ // 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 featureSource = layer.getFeatureSource();
+ final GeometryFilterImpl distancefilter = filterGenerator.adaptFilter(featureSource);
- distancefilter.setExpression1(geometry);
+ /**
+ * 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) {
+ filter = distancefilter.and(layerFilter);
+ }
+ }
- /**
- * 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) {
- 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 fc = featureSource.getFeatures(filter);
- try {
- // Filter auf Layer des Features anwenden
- // FeatureCollection fc = layer.getFeatureSource().getFeatures(
- // FilterUtil.cloneFilter(filter) ); // KLAPPT (NOCH) NICHT
- // FeatureCollection fc = featureSource.getFeatures(
- // distancefilter );
- FeatureCollection 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.
+ if (layer.getTitle().equals(
+ "vector_afrikan_countries_00040984322")) {
+ LOGGER.warn("Cancelling here to avoid infinite loop in ShapefileReader.ensureCapacity(ByteBuffer, int, boolean) line: 203.");
+ LOGGER.warn("Calling isEmpty() or getSize() in GT2.4.5 the ShapefileReader-Class enters infinite loop here for the here for layer vector_afrikan_countries_00040984322. It seems to be specific for this special ShapeFile. Canelling the operation here is a very ugly and very static work-arround. Hopefully this problem vanishes with GT 2.5");
+ continue;
+ }
- // Liefert eine FeatureCollection zurück, in welcher nur
- // Features enthalten sind, welche bei der aktuellen
- // Anzeigeskala aufgrund des Styles gerendert werden.
+ // @Martin Using size() produces the same problem
+ if (!fc.isEmpty()) {
+ fc = filterSLDVisibleOnly(fc, layer.getStyle());
- if (layer.getTitle().equals(
- "vector_afrikan_countries_00040984322")) {
- LOGGER
- .warn("Cancelling here to avoid infinite loop in ShapefileReader.ensureCapacity(ByteBuffer, int, boolean) line: 203.");
- LOGGER
- .warn("Calling isEmpty() or getSize() in GT2.4.5 the ShapefileReader-Class enters infinite loop here for the here for layer vector_afrikan_countries_00040984322. It seems to be specific for this special ShapeFile. Canelling the operation here is a very ugly and very static work-arround. Hopefully this problem vanishes with GT 2.5");
- continue;
- }
+ 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;
+ }
- // @Martin Using size() produces the same problem
- if (!fc.isEmpty()) {
+ }
+ } catch (IOException err) {
+ err.printStackTrace();
+ }
- 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;
- }
+ // for ( FeatureCollection fc1 : result.values() )
+ // LOGGER.debug("A "+fc1+" "+fc1.isEmpty());
+ }
+ // for ( FeatureCollection fc1 : result.values() )
+ // LOGGER.debug("B "+fc1+" "+fc1.isEmpty());
- }
- } catch (IOException err) {
- err.printStackTrace();
- }
+ return result;
+ }
- // for ( FeatureCollection fc1 : result.values() )
- // LOGGER.debug("A "+fc1+" "+fc1.isEmpty());
- }
- // for ( FeatureCollection fc1 : result.values() )
- // LOGGER.debug("B "+fc1+" "+fc1.isEmpty());
+ /**
+ * 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 filter
+ * Filter
+ * @param mode
+ * Suchmodus
+ * @return eine leere {@link Hashtable} falls der Filter {@code null} ist
+ */
+ protected Hashtable<MapLayer, FeatureCollection> findFeatures(
+ GeomFilterGenerator filterGenerator, int mode, Envelope env) {
+ Hashtable<MapLayer, FeatureCollection> result = new Hashtable<MapLayer, FeatureCollection>();
+ if (filterGenerator == null)
+ return result;
- 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;
- /**
- * 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 filter
- * Filter
- * @param mode
- * Suchmodus
- * @return eine leere {@link Hashtable} falls der Filter {@code null} ist
- */
- protected Hashtable<MapLayer, FeatureCollection> findFeatures(
- GeometryFilterImpl filter, int mode, Envelope env) {
- Hashtable<MapLayer, FeatureCollection> result = new Hashtable<MapLayer, FeatureCollection>();
- if (filter == null)
- return result;
+ // 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;
+ }
- // 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;
+ // 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 featureSource = layer.getFeatureSource();
+ final GeometryFilterImpl filter = filterGenerator.adaptFilter(featureSource);
- // 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;
- }
+ try {
+ // Filter auf Layer des Features anwenden
+ // FeatureCollection fc = layer.getFeatureSource().getFeatures(
+ // FilterUtil.cloneFilter(filter) ); // KLAPPT (NOCH) NICHT
+ FeatureCollection fc = featureSource.getFeatures(filter);
- // 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 featureSource = layer.getFeatureSource();
- Expression geometry = ff.createAttributeExpression(featureSource
- .getSchema().getDefaultGeometry().getLocalName());
+ // 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());
- filter.setExpression1(geometry);
+ 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) {
+ err.printStackTrace();
+ LOGGER.error(err);
+ }
- try {
- // Filter auf Layer des Features anwenden
- // FeatureCollection fc = layer.getFeatureSource().getFeatures(
- // FilterUtil.cloneFilter(filter) ); // KLAPPT (NOCH) NICHT
- FeatureCollection fc = featureSource.getFeatures(filter);
+ // for ( FeatureCollection fc1 : result.values() )
+ // LOGGER.debug("A "+fc1+" "+fc1.isEmpty());
+ }
+ // for ( FeatureCollection fc1 : result.values() )
+ // LOGGER.debug("B "+fc1+" "+fc1.isEmpty());
- // 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());
+ return result;
+ }
- 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) {
- err.printStackTrace();
- LOGGER.error(err);
- }
+ /**
+ * 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üger</a>
+ */
+ private MemoryFeatureCollection filterSLDVisibleOnly(
+ final FeatureCollection fc, final Style style) {
- // for ( FeatureCollection fc1 : result.values() )
- // LOGGER.debug("A "+fc1+" "+fc1.isEmpty());
- }
- // for ( FeatureCollection fc1 : result.values() )
- // LOGGER.debug("B "+fc1+" "+fc1.isEmpty());
+ // Der "scaleDenominator" der aktuellen JMapPane
+ Double scaleDenominator = RendererUtilities
+ .calculateOGCScale(new ReferencedEnvelope(getMapArea(),
+ getContext().getCoordinateReferenceSystem()),
+ getSize().width, null);
- return result;
- }
+ return StylingUtil.filterSLDVisibleOnly(fc, style, scaleDenominator);
+ }
- /**
- * 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üger</a>
- */
- private MemoryFeatureCollection filterSLDVisibleOnly(
- final FeatureCollection fc, final Style style) {
+ /**
+ * 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> result = findVisibleFeatures(
+ filterGenerator, mode, env);
- // Der "scaleDenominator" der aktuellen JMapPane
- Double scaleDenominator = RendererUtilities
- .calculateOGCScale(new ReferencedEnvelope(getMapArea(),
- getContext().getCoordinateReferenceSystem()),
- getSize().width, null);
+ // Events ausloesen fuer jedes Layer
+ for (final Enumeration<MapLayer> e = result.keys(); e.hasMoreElements();) {
+ final MapLayer layer = e.nextElement();
+ final FeatureCollection fc = result.get(layer);
+ if (fc != null && !fc.isEmpty())
+ fireMapPaneEvent(new FeatureSelectedEvent(this, layer, env, fc));
+ }
+ return !result.isEmpty();
+ }
- return StylingUtil.filterSLDVisibleOnly(fc, style, scaleDenominator);
- }
+ /**
+ * 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;
- /**
- * 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 filter
- * Filter
- * @param mode
- * Suchmodus
- * @param env
- * Bereich der durchsucht wird (fuer das Filtern irrelevant; wird
- * nur fuer Events benoetigt!)
- */
- protected boolean findFeaturesAndFireEvents(GeometryFilterImpl filter,
- int mode, Envelope env) {
- Hashtable<MapLayer, FeatureCollection> result = findVisibleFeatures(
- filter, mode, env);
+ 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;
- // Events ausloesen fuer jedes Layer
- for (final Enumeration<MapLayer> e = result.keys(); e.hasMoreElements();) {
- final MapLayer layer = e.nextElement();
- final FeatureCollection fc = result.get(layer);
- if (fc != null && !fc.isEmpty())
- fireMapPaneEvent(new FeatureSelectedEvent(this, layer, env, fc));
- }
- return !result.isEmpty();
- }
+ // 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;
+ }
- /**
- * 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;
+ 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
- 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;
+ // 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;
+ }
- // 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;
- }
+ /**
+ * 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();
+ }
- 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
+ /**
+ * 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üger</a>
+ */
+ protected Hashtable<MapLayer, double[]> findGridCoverageValues(
+ Point2D point, int mode) {
+ Hashtable<MapLayer, double[]> result = new Hashtable<MapLayer, double[]>();
- // 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;
- }
+ if (point == null)
+ 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();
- }
+ 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);
- /**
- * 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üger</a>
- */
- protected Hashtable<MapLayer, double[]> findGridCoverageValues(
- Point2D point, int mode) {
- Hashtable<MapLayer, double[]> result = new Hashtable<MapLayer, double[]>();
+ // LOGGER.info("layerObj = "+layerObj.getClass().getSimpleName());
- if (point == null)
- return result;
+ // 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;
+ // }
- 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);
+ // 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;
+ }
- // LOGGER.info("layerObj = "+layerObj.getClass().getSimpleName());
+ GridCoverage2D sourceGrid;
- // 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;
- // }
+ if (layerObj instanceof AbstractGridCoverage2DReader) {
+ // LOGGER.info("layerObj instanceof AbstractGridCoverage2DReader"
+ // );
+ AbstractGridCoverage2DReader reader = (AbstractGridCoverage2DReader) layerObj;
+ Parameter readGG = new Parameter(
+ AbstractGridFormat.READ_GRIDGEOMETRY2D);
- // 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;
- }
+ ReferencedEnvelope mapExtend = new org.geotools.geometry.jts.ReferencedEnvelope(
+ mapArea, context.getCoordinateReferenceSystem());
- GridCoverage2D sourceGrid;
+ readGG.setValue(new GridGeometry2D(new GeneralGridRange(
+ getBounds()), mapExtend));
- if (layerObj instanceof AbstractGridCoverage2DReader) {
- // LOGGER.info("layerObj instanceof AbstractGridCoverage2DReader"
- // );
- AbstractGridCoverage2DReader reader = (AbstractGridCoverage2DReader) layerObj;
- Parameter readGG = new Parameter(
- AbstractGridFormat.READ_GRIDGEOMETRY2D);
+ try {
+ sourceGrid = (GridCoverage2D) reader
+ .read(new GeneralParameterValue[] { readGG });
+ } catch (Exception e) {
+ LOGGER.error(e);
+ continue;
+ }
+ } else {
+ // Ein instanceof ist nicht noetig, da sonst schon break oder
+ // continue aufgerufen worden waere
+ sourceGrid = (GridCoverage2D) layerObj;
+ }
- ReferencedEnvelope mapExtend = new org.geotools.geometry.jts.ReferencedEnvelope(
- mapArea, context.getCoordinateReferenceSystem());
+ // vorher: double[] value = new double[2];
- readGG.setValue(new GridGeometry2D(new GeneralGridRange(
- getBounds()), mapExtend));
+ // getNumSampleDimensions gibt die Anzahl der Baender des Rasters
+ // zurueck.
+ double[] values = new double[sourceGrid.getNumSampleDimensions()];
- try {
- sourceGrid = (GridCoverage2D) reader
- .read(new GeneralParameterValue[] { readGG });
- } catch (Exception e) {
- LOGGER.error(e);
- continue;
- }
- } else {
- // Ein instanceof ist nicht noetig, da sonst schon break oder
- // continue aufgerufen worden waere
- sourceGrid = (GridCoverage2D) layerObj;
- }
+ 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(e);
+ continue;
+ }
- // vorher: double[] value = new double[2];
+ // SK: voher wurde nur der erste Wert zurueckgegeben
+ // result.put(layer,value[0]);
+ // jetzt werden alle werte zueuckgegeben
- // getNumSampleDimensions gibt die Anzahl der Baender des Rasters
- // zurueck.
- double[] values = new double[sourceGrid.getNumSampleDimensions()];
+ result.put(layer, values);
+ // Beim Modus "oberstes Layer selektieren" die Schleife beenden
+ if (mode == SELECT_TOP)
+ break;
+ }
+ return result;
+ }
- 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(e);
- continue;
- }
+ /**
+ * 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üger</a>
+ */
+ protected boolean findGridCoverageValuesAndFireEvents(Point2D point,
+ int mode) {
+ Hashtable<MapLayer, double[]> result = findGridCoverageValues(point,
+ mode);
- // SK: voher wurde nur der erste Wert zurueckgegeben
- // result.put(layer,value[0]);
- // jetzt werden alle werte zueuckgegeben
+ // 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();
+ }
- result.put(layer, values);
- // Beim Modus "oberstes Layer selektieren" die Schleife beenden
- if (mode == SELECT_TOP)
- break;
- }
- return result;
- }
+// /**
+// * Bereitet einen BoundingBox-Filter vor. Das "linke" Attribut der
+// * Expression (das Feature-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
+// * Feature-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 Feature-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ü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;
+// }
- /**
- * 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üger</a>
- */
- protected boolean findGridCoverageValuesAndFireEvents(Point2D point,
- int mode) {
- Hashtable<MapLayer, double[]> result = findGridCoverageValues(point,
- mode);
+ /**
+ * 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 Feature 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 Feature beinhalten
+ // if ( fc == null || fc.size() != 1 )
+ // return false;
+ // // Feature muss genau 1 Attribut mit dem Namen "GridCoverage" haben
+ // FeatureType ftype = fc.getFeatureType();
+ // if ( ftype == null || ftype.getAttributeCount() != 1 ||
+ // !"GridCoverage".equalsIgnoreCase(ftype.getAttributeType(0).getName())
+ // )
+ // return false;
+ // } catch (Exception err) {
+ // }
+ // return true;
+ }
- // 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();
- }
+ /**
+ * 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 Feature 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}.
+ *
+ * @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) {
+ try {
+ final FeatureSource featureSource = layer.getFeatureSource();
+ FeatureCollection fc = featureSource.getFeatures();
+ // RasterLayer muss genau ein Feature beinhalten
+ // Ist dies nicht der Fall wird die FeatureCollection zurueckgegeben
+ if (fc == null || fc.size() != 1) {
- /**
- * Bereitet einen BoundingBox-Filter vor. Das "linke" Attribut der
- * Expression (das Feature-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;
- }
+ return fc;
+ }
+ // FeatureType des RasterLayer muss genau 1 Attribut mit Namen
+ // "GridCoverage"
+ // Ist dies nicht der Fall wird die FeatureCollection zurueckgegeben
+ FeatureType ftype = fc.getFeatureType();
+ if (ftype == null
+ || ftype.getAttributeCount() != 1
+ || !"GridCoverage".equalsIgnoreCase(ftype.getAttributeType(
+ 0).getLocalName()))
+ return fc;
+ // (Einziges) Feature muss genau 2 Attribute besitzen, wobei das
+ // erste vom
+ // Typ Geometry ist und das zweite vom Typ GridCoverage2D
+ // sonst: FeatureCollextion zurueckgeben
- /**
- * Bereitet einen Punkt-Filter vor. Das "linke" Attribut der Expression (das
- * Feature-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;
- }
+ /** CHANGE SK 9.8.08 BEGIN */
+ Feature f = fc.features().next();
+ if ((f.getFeatureType().getTypeName().equals("GridCoverage") && f
+ .getNumberOfAttributes() >= 2)) {
+ // I am sure, that it is a raster some. We do not have to cast
+ // it to either cridcoverage or abstractReader, as the results
+ // are tested anyway...
+ return f.getAttribute(1);
+ }
+ /** CHANGE SK 9.8.08 END */
- /**
- * Bereitet einen "InDerNaehe von" Distance-Filter vor. Das "linke" Attribut
- * der Expression (das Feature-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ü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()));
+ if (f.getNumberOfAttributes() != 2
+ || // Geaendert, da es bei AbstractGridCoverageReader 3 sind
+ // (SK, 19.08.07)
+ !(f.getAttribute(0) instanceof com.vividsolutions.jts.geom.Geometry)
+ || !(f.getAttribute(1) instanceof GridCoverage2D))
+ return fc;
- final DWithinImpl dwithinFilter = (DWithinImpl) ff
- .createGeometryDistanceFilter(DWithinImpl.GEOMETRY_DWITHIN);
+ // Objekt ist ein Raster!
+ return (GridCoverage2D) f.getAttribute(1);
+ } catch (Exception err) {
+ LOGGER.warn(err.getMessage(), err);
+ return null;
+ }
+ }
- dwithinFilter.setDistance(dist);
+ /**
+ * 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üger</a>
+ */
- dwithinFilter.setExpression2(ff.createLiteralExpression(geometry));
+ public void dispose() {
+ if (isDisposed())
+ return;
- return dwithinFilter;
- }
+ if (dragWaitCursorListener != null)
+ this.removeMouseListener(dragWaitCursorListener);
+ if (mouseWheelZoomListener != null)
+ this.removeMouseWheelListener(mouseWheelZoomListener);
- /**
- * 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 Feature 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 Feature beinhalten
- // if ( fc == null || fc.size() != 1 )
- // return false;
- // // Feature muss genau 1 Attribut mit dem Namen "GridCoverage" haben
- // FeatureType ftype = fc.getFeatureType();
- // if ( ftype == null || ftype.getAttributeCount() != 1 ||
- // !"GridCoverage".equalsIgnoreCase(ftype.getAttributeType(0).getName())
- // )
- // return false;
- // } catch (Exception err) {
- // }
- // return true;
- }
+ // Alle mapPaneListener entfernen
+ mapPaneListeners.clear();
- /**
- * 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 Feature 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}.
- *
- * @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) {
- try {
- final FeatureSource featureSource = layer.getFeatureSource();
- FeatureCollection fc = featureSource.getFeatures();
- // RasterLayer muss genau ein Feature beinhalten
- // Ist dies nicht der Fall wird die FeatureCollection zurueckgegeben
- if (fc == null || fc.size() != 1) {
+ getContext().clearLayerList();
- return fc;
- }
- // FeatureType des RasterLayer muss genau 1 Attribut mit Namen
- // "GridCoverage"
- // Ist dies nicht der Fall wird die FeatureCollection zurueckgegeben
- FeatureType ftype = fc.getFeatureType();
- if (ftype == null
- || ftype.getAttributeCount() != 1
- || !"GridCoverage".equalsIgnoreCase(ftype.getAttributeType(
- 0).getLocalName()))
- return fc;
- // (Einziges) Feature muss genau 2 Attribute besitzen, wobei das
- // erste vom
- // Typ Geometry ist und das zweite vom Typ GridCoverage2D
- // sonst: FeatureCollextion zurueckgeben
+ removeAll();
+ disposed = true;
+ }
- /** CHANGE SK 9.8.08 BEGIN */
- Feature f = fc.features().next();
- if ((f.getFeatureType().getTypeName().equals("GridCoverage") && f
- .getNumberOfAttributes() >= 2)) {
- // I am sure, that it is a raster some. We do not have to cast
- // it to either cridcoverage or abstractReader, as the results
- // are tested anyway...
- return f.getAttribute(1);
- }
- /** CHANGE SK 9.8.08 END */
+ /**
+ * 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;
+ }
- if (f.getNumberOfAttributes() != 2
- || // Geaendert, da es bei AbstractGridCoverageReader 3 sind
- // (SK, 19.08.07)
- !(f.getAttribute(0) instanceof com.vividsolutions.jts.geom.Geometry)
- || !(f.getAttribute(1) instanceof GridCoverage2D))
- return fc;
+ //
+ // /**
+ // * Werden Rasterlayer waehrend einer PAN Aktion versteckt?
+ // * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+ // Krü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üger</a>
+ // */
+ // public void setHideRasterLayersDuringPan(boolean
+ // hideRasterLayersDuringPan) {
+ // this.hideRasterLayersDuringPan = hideRasterLayersDuringPan;
+ // }
- // Objekt ist ein Raster!
- return (GridCoverage2D) f.getAttribute(1);
- } catch (Exception err) {
- LOGGER.warn(err.getMessage(), err);
- return null;
- }
- }
+ public boolean isSetWaitCursorDuringNextRepaint() {
+ return setWaitCursorDuringNextRepaint;
+ }
- /**
- * 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üger</a>
- */
+ /**
+ * 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üger</a>
+ */
+ public void setWaitCursorDuringNextRepaint(
+ boolean waitCursorDuringNextRepaint) {
+ this.setWaitCursorDuringNextRepaint = waitCursorDuringNextRepaint;
+ }
- public void dispose() {
- if (isDisposed())
- return;
+ /**
+ * 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üger</a>
+ */
+ public Cursor getNormalCursor() {
+ return normalCursor;
+ }
- if (dragWaitCursorListener != null)
- this.removeMouseListener(dragWaitCursorListener);
- if (mouseWheelZoomListener != null)
- this.removeMouseWheelListener(mouseWheelZoomListener);
+ /**
+ * 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üger</a>
+ */
+ public void setNormalCursor(Cursor normalCursor) {
+ this.normalCursor = normalCursor;
+ }
- // Alle mapPaneListener entfernen
- mapPaneListeners.clear();
+ // /**
+ // * 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 Feature 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 Feature beinhalten
+ // if ( fc == null || fc.size() != 1 )
+ // return false;
+ // // Feature muss genau 1 Attribut vom Typ FeatureAttributeType haben
+ // FeatureType 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;
+ // }
- getContext().clearLayerList();
+ /**
+ * Nuetzlich wenn die Componente gedruckt wird. Dann werden wird der
+ * Hintergrund auf WEISS gesetzt.
+ *
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+ * Krüger</a>
+ */
+ @Override
+ public void print(Graphics g) {
+ Color orig = getBackground();
+ setBackground(Color.WHITE);
- removeAll();
- disposed = true;
- }
+ // wrap in try/finally so that we always restore the state
+ try {
+ super.print(g);
+ } finally {
+ setBackground(orig);
+ }
+ }
- /**
- * 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;
- }
+ /**
+ * Sets the mapArea to smartly present the given features. Note: The method
+ * does not call {@link #repaint()} on the {@link JMapPane}.
+ */
+ public void zoomTo(org.geotools.feature.Feature feature) {
+ final MemoryFeatureCollection mfc = new MemoryFeatureCollection(feature
+ .getFeatureType());
+ mfc.add(feature);
+ zoomTo(mfc);
+ }
- //
- // /**
- // * Werden Rasterlayer waehrend einer PAN Aktion versteckt?
- // * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
- // Krü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üger</a>
- // */
- // public void setHideRasterLayersDuringPan(boolean
- // hideRasterLayersDuringPan) {
- // this.hideRasterLayersDuringPan = hideRasterLayersDuringPan;
- // }
+ /**
+ * 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 features) {
- public boolean isSetWaitCursorDuringNextRepaint() {
- return setWaitCursorDuringNextRepaint;
- }
+ CoordinateReferenceSystem mapCRS = getContext()
+ .getCoordinateReferenceSystem();
+ CoordinateReferenceSystem fCRS = features.getSchema()
+ .getDefaultGeometry().getCoordinateSystem();
+ // if (! mapCRS.equals(fCRS)) {
+ // throw new
+ // RuntimeException("Projecting the features to show to the map CRS is not yet implemented.");
+ // }
- /**
- * 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üger</a>
- */
- public void setWaitCursorDuringNextRepaint(
- boolean waitCursorDuringNextRepaint) {
- this.setWaitCursorDuringNextRepaint = waitCursorDuringNextRepaint;
- }
+ double width = mapArea.getWidth();
+ double height = mapArea.getHeight();
+ double ratio = height / width;
- /**
- * 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üger</a>
- */
- public Cursor getNormalCursor() {
- return normalCursor;
- }
+ if (features == null || features.size() == 0) {
+ // feature count == 0 Zoom to the full extend
+ return;
+ } else if (features.size() == 1) {
- /**
- * 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üger</a>
- */
- public void setNormalCursor(Cursor normalCursor) {
- this.normalCursor = normalCursor;
- }
+ // feature count == 1 Just move the window to the point and zoom 'a
+ // bit'
+ Feature singleFeature = (Feature) features.iterator().next();
- // /**
- // * 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 Feature 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 Feature beinhalten
- // if ( fc == null || fc.size() != 1 )
- // return false;
- // // Feature muss genau 1 Attribut vom Typ FeatureAttributeType haben
- // FeatureType 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;
- // }
+ if (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;
+ }
- /**
- * Nuetzlich wenn die Componente gedruckt wird. Dann werden wird der
- * Hintergrund auf WEISS gesetzt.
- *
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
- * Krüger</a>
- */
- @Override
- public void print(Graphics g) {
- Color orig = getBackground();
- setBackground(Color.WHITE);
+ 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(e);
+ } catch (TransformException e) {
+ LOGGER.error(e);
+ }
+ }
- // wrap in try/finally so that we always restore the state
- try {
- super.print(g);
- } finally {
- setBackground(orig);
- }
- }
+ Coordinate newLeftBottom = new Coordinate(centre.x - width / 2.,
+ centre.y - height / 2.);
+ Coordinate newTopRight = new Coordinate(centre.x + width / 2.,
+ centre.y + height / 2.);
- /**
- * Sets the mapArea to smartly present the given features. Note: The method
- * does not call {@link #repaint()} on the {@link JMapPane}.
- */
- public void zoomTo(org.geotools.feature.Feature feature) {
- final MemoryFeatureCollection mfc = new MemoryFeatureCollection(feature
- .getFeatureType());
- mfc.add(feature);
- zoomTo(mfc);
- }
+ Envelope newMapArea = new Envelope(newLeftBottom, newTopRight);
- /**
- * 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 features) {
+ setMapArea(newMapArea);
- CoordinateReferenceSystem mapCRS = getContext()
- .getCoordinateReferenceSystem();
- CoordinateReferenceSystem fCRS = features.getSchema()
- .getDefaultGeometry().getCoordinateSystem();
- // if (! mapCRS.equals(fCRS)) {
- // throw new
- // RuntimeException("Projecting the features to show to the map CRS is not yet implemented.");
- // }
+ } else {
+ ReferencedEnvelope fBounds = features.getBounds();
- double width = mapArea.getWidth();
- double height = mapArea.getHeight();
- double ratio = height / width;
+ Envelope bounds;
+ if (!mapCRS.equals(fCRS)) {
+ bounds = JTSUtil.transformEnvelope(fBounds, fCRS, mapCRS);
+ } else {
+ bounds = fBounds;
+ }
+ // BB umrechnen von Layer-CRS in Map-CRS
- if (features == null || features.size() == 0) {
- // feature count == 0 Zoom to the full extend
- return;
- } else if (features.size() == 1) {
+ // Expand a bit
+ bounds.expandBy(bounds.getWidth() / 6., bounds.getHeight() / 6.);
- // feature count == 1 Just move the window to the point and zoom 'a
- // bit'
- Feature singleFeature = (Feature) features.iterator().next();
+ setMapArea(bounds);
+ }
+ }
- if (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;
- }
+ /**
+ * 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>();
- 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(e);
- } catch (TransformException e) {
- LOGGER.error(e);
- }
- }
+ /**
+ * 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;
+ }
- Coordinate newLeftBottom = new Coordinate(centre.x - width / 2.,
- centre.y - height / 2.);
- Coordinate newTopRight = new Coordinate(centre.x + width / 2.,
- centre.y + height / 2.);
+ /**
+ * 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);
- Envelope newMapArea = new Envelope(newLeftBottom, newTopRight);
+ /**
+ * 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 fs) {
+ GeometryAttributeType geomAttr = fs.getSchema().getDefaultGeometry();
+ CoordinateReferenceSystem fsCRS = geomAttr.getCoordinateSystem();
+ GeometryFilterImpl filter = filterCache.get(fsCRS);
+ if ( filter == null ) {
+ filter = prepareFilter(fsCRS);
+ filterCache.put(fsCRS, filter);
+ }
+ Expression geometry = ff.createAttributeExpression(geomAttr.getLocalName());
+ filter.setExpression1(geometry);
+ return filter;
+ }
- setMapArea(newMapArea);
+ }
- } else {
- ReferencedEnvelope fBounds = features.getBounds();
+ /**
+ * {@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;
- Envelope bounds;
- if (!mapCRS.equals(fCRS)) {
- bounds = JTSUtil.transformEnvelope(fBounds, fCRS, mapCRS);
- } else {
- bounds = fBounds;
- }
- // BB umrechnen von Layer-CRS in Map-CRS
+ /**
+ * 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;
+ }
- // Expand a bit
- bounds.expandBy(bounds.getWidth() / 6., bounds.getHeight() / 6.);
+ /**
+ * 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;
+ }
+ }
- setMapArea(bounds);
- }
- }
+ /**
+ * {@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 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(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);
+ nearDist = Math.abs(nearPoint.x - nearPoint2.x);
+ }
+ // Filter fuer Point zusammenstellen
+ final Geometry geometry = FilterUtil.GEOMETRY_FAC.createPoint(nearPoint);
+ final DWithinImpl dwithinFilter = (DWithinImpl)FilterUtil.FILTER_FAC.createGeometryDistanceFilter(DWithinImpl.GEOMETRY_DWITHIN);
+ dwithinFilter.setDistance(nearDist);
+ dwithinFilter.setExpression2(FilterUtil.FILTER_FAC.createLiteralExpression(geometry));
+
+ return dwithinFilter;
+ }
+
+ }
}
More information about the Schmitzm-commits
mailing list