[Schmitzm-commits] r360 - branches/1.0-gt2-2.6/src/schmitzm/geotools/gui
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Mon Aug 31 18:04:47 CEST 2009
Author: alfonx
Date: 2009-08-31 18:04:44 +0200 (Mon, 31 Aug 2009)
New Revision: 360
Modified:
branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JMapPane.java
Log:
* getLayerSourceObject changed...
Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JMapPane.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JMapPane.java 2009-08-31 14:42:58 UTC (rev 359)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JMapPane.java 2009-08-31 16:04:44 UTC (rev 360)
@@ -65,6 +65,8 @@
import org.geotools.data.memory.MemoryFeatureCollection;
import org.geotools.factory.GeoTools;
import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.FeatureIterator;
+import org.geotools.feature.NameImpl;
import org.geotools.filter.AbstractFilter;
import org.geotools.filter.GeometryFilterImpl;
import org.geotools.filter.spatial.DWithinImpl;
@@ -166,2602 +168,2651 @@
*/
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);
+ private static final NameImpl GC_NAME = new NameImpl(
+ "http://www.opengis.net/gml", "GridCoverage");
- // SK, 19.6.2009:
- // Ein MapAreaChangedEvent soll nur geworfen werden, wenn auch gezoomt
- // wurde! Irgendwie wird das auch aufgerufen, wenn man mit InfoClick
- // tool nur click - also garkeit kein draggin gemacht hat.
- if ((oldMapArea == null || !oldMapArea.equals(mapArea))
- && (getState() == ZOOM_IN || getState() == ZOOM_OUT))
- fireMapPaneEvent(new MapAreaChangedEvent(this, oldMapArea, mapArea));
- }
+ /**
+ * 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);
- private static final Cursor WAIT_CURSOR = Cursor
- .getPredefinedCursor(Cursor.WAIT_CURSOR);
+ // SK, 19.6.2009:
+ // Ein MapAreaChangedEvent soll nur geworfen werden, wenn auch gezoomt
+ // wurde! Irgendwie wird das auch aufgerufen, wenn man mit InfoClick
+ // tool nur click - also garkeit kein draggin gemacht hat.
+ if ((oldMapArea == null || !oldMapArea.equals(mapArea))
+ && (getState() == ZOOM_IN || getState() == ZOOM_OUT))
+ fireMapPaneEvent(new MapAreaChangedEvent(this, oldMapArea, mapArea));
+ }
- /** Logger for debug messages. */
- protected static final Logger LOGGER = Logger
- .getLogger(JMapPane.class
- .getName());
+ private static final Cursor WAIT_CURSOR = Cursor
+ .getPredefinedCursor(Cursor.WAIT_CURSOR);
- /** @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;
+ /** Logger for debug messages. */
+ protected static final Logger LOGGER = Logger.getLogger(JMapPane.class
+ .getName());
- /**
- * 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
- * "SimpleFeature-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 "SimpleFeature-Auswahl auf allen (sichtbaren) Layern".
- *
- * @see #setWindowSelectionState(int)
- * @see #setState(int)
- */
- public static final int SELECT_ALL = 103;
- /**
- * Flag fuer Modus "Auswahl nur eines Features, das erste sichtbare von Oben".
- *
- * @see #setWindowSelectionState(int)
- * @see #setState(int)
- */
- public static final int SELECT_ONE_FROM_TOP = 104;
+ /** @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;
- /** Modus fuer Window-Selektion (Default: {@link #ZOOM_IN}). */
- protected int selState = NONE;
+ /**
+ * 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
+ * "SimpleFeature-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 "SimpleFeature-Auswahl auf allen (sichtbaren) Layern".
+ *
+ * @see #setWindowSelectionState(int)
+ * @see #setState(int)
+ */
+ public static final int SELECT_ALL = 103;
+ /**
+ * Flag fuer Modus
+ * "Auswahl nur eines Features, das erste sichtbare von Oben".
+ *
+ * @see #setWindowSelectionState(int)
+ * @see #setState(int)
+ */
+ public static final int SELECT_ONE_FROM_TOP = 104;
- /**
- * Transformation zwischen Fenster-Koordinaten und Karten-Koordinaten
- * (lat/lon)
- */
- protected AffineTransform transform = null;
+ /** Modus fuer Window-Selektion (Default: {@link #ZOOM_IN}). */
+ protected int selState = NONE;
- /**
- * Liste der angeschlossenen Listener, die auf Aktionen des MapPanes lauschen.
- */
- protected Vector<JMapPaneListener> mapPaneListeners = new Vector<JMapPaneListener>();
+ /**
+ * Transformation zwischen Fenster-Koordinaten und Karten-Koordinaten
+ * (lat/lon)
+ */
+ protected AffineTransform transform = null;
- 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;
+ /**
+ * Liste der angeschlossenen Listener, die auf Aktionen des MapPanes
+ * lauschen.
+ */
+ protected Vector<JMapPaneListener> mapPaneListeners = new Vector<JMapPaneListener>();
- super
- .mouseDragged(event);
- }
+ 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;
- 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
- // 2
- // x
- // gezoomt
- // wird
- // !
- // !
- if (getState() != ZOOM_IN)
- performSelectionEvent(
- ox,
- oy,
- px,
- py);
- }
- };
+ super.mouseDragged(event);
+ }
- private static final FilterFactory ff = FilterUtil.FILTER_FAC;
- private static final GeometryFactory gf = FilterUtil.GEOMETRY_FAC;
+ 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
+ // 2
+ // x
+ // gezoomt
+ // wird
+ // !
+ // !
+ if (getState() != ZOOM_IN)
+ performSelectionEvent(ox, oy, px, py);
+ }
+ };
- /**
- * A flag indicating if dispose() was already called. If true, then further
- * use of this {@link JMapPane} is undefined.
- */
- private boolean disposed = false;
+ private static final FilterFactory ff = FilterUtil.FILTER_FAC;
+ private static final GeometryFactory gf = FilterUtil.GEOMETRY_FAC;
- /** Listener, der auf das Mausrad lauscht und mit Zoom reagiert */
- private MouseWheelListener mouseWheelZoomListener;
+ /**
+ * A flag indicating if dispose() was already called. If true, then further
+ * use of this {@link JMapPane} is undefined.
+ */
+ private boolean disposed = false;
- // /** 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>();
+ /** Listener, der auf das Mausrad lauscht und mit Zoom reagiert */
+ private MouseWheelListener mouseWheelZoomListener;
- /**
- * 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 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>();
- /** Cursor wenn kein Mausbutton gedrueckt wird. default oder SwingUtil.PAN **/
- private Cursor normalCursor = Cursor
- .getPredefinedCursor(Cursor.DEFAULT_CURSOR);
+ /**
+ * 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;
- /**
- * Manuell gesetzter statischer Cursor, unabhaengig von der aktuellen
- * MapPane-Funktion
- */
- protected Cursor staticCursor = null;
+ /** Cursor wenn kein Mausbutton gedrueckt wird. default oder SwingUtil.PAN **/
+ private Cursor normalCursor = Cursor
+ .getPredefinedCursor(Cursor.DEFAULT_CURSOR);
- private MouseInputAdapter dragWaitCursorListener;
+ /**
+ * Manuell gesetzter statischer Cursor, unabhaengig von der aktuellen
+ * MapPane-Funktion
+ */
+ protected Cursor staticCursor = null;
- /** An (transparent) image to paint over the map in the lower right corner **/
- private BufferedImage mapImage = null;
+ private MouseInputAdapter dragWaitCursorListener;
- /** A cache to optionally supply AttributeMetaData to the {@link JMapPane}. */
- final protected HashMap<String, Map<Integer, AttributeMetaData>> attributeMetaDataMapCache = new HashMap<String, Map<Integer, AttributeMetaData>>();
+ /** 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);
- }
+ /** A cache to optionally supply AttributeMetaData to the {@link JMapPane}. */
+ final protected HashMap<String, Map<Integer, AttributeMetaData>> attributeMetaDataMapCache = new HashMap<String, Map<Integer, AttributeMetaData>>();
- /**
- * Erzeugt ein neues MapPane. Benutzt einen
- * {@link TransitionShapefileRenderer} als default!
- *
- * @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 ShapefileRenderer(context),
- // 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}
+ * @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);
+ }
- // 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);
+ /**
+ * Erzeugt ein neues MapPane. Benutzt einen
+ * {@link TransitionShapefileRenderer} als default!
+ *
+ * @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 ShapefileRenderer(context),
+ // renderer != null ? renderer : new StreamingRenderer(),
+ context != null ? context : new DefaultMapContext(GTUtil.WGS84));
- // 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 );
+ // 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);
- setWindowSelectionState(ZOOM_IN);
- setState(ZOOM_IN);
+ // 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 );
- // Listener, der auf das Mausrad lauscht und mit Zoom reagiert
- mouseWheelZoomListener = new MouseWheelListener() {
- public void mouseWheelMoved(MouseWheelEvent e) {
- performMouseWheelEvent(e);
- }
- };
- this.addMouseWheelListener(mouseWheelZoomListener);
+ setWindowSelectionState(ZOOM_IN);
+ setState(ZOOM_IN);
- // 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);
-//
-// // 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
+ // Listener, der auf das Mausrad lauscht und mit Zoom reagiert
+ mouseWheelZoomListener = new MouseWheelListener() {
+ public void mouseWheelMoved(MouseWheelEvent e) {
+ performMouseWheelEvent(e);
+ }
+ };
+ this.addMouseWheelListener(mouseWheelZoomListener);
- getContext().addMapLayerListListener(
- new schmitzm.geotools.map.event.MapLayerListAdapter() {
- private void resetHighlightLayer() {
-// if (isHighlight())
-// setHighlightLayer(getTopVisibleNonGridCoverageLayer());
- }
+ /**
+ * 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
- public void layerAdded(org.geotools.map.event.MapLayerListEvent e) {
- resetHighlightLayer();
- }
+ getContext().addMapLayerListListener(
+ new schmitzm.geotools.map.event.MapLayerListAdapter() {
+ private void resetHighlightLayer() {
+ // if (isHighlight())
+ // setHighlightLayer(getTopVisibleNonGridCoverageLayer());
+ }
- public void layerChanged(org.geotools.map.event.MapLayerListEvent e) {
- resetHighlightLayer();
- }
+ public void layerAdded(
+ org.geotools.map.event.MapLayerListEvent e) {
+ resetHighlightLayer();
+ }
- public void layerMoved(org.geotools.map.event.MapLayerListEvent e) {
- resetHighlightLayer();
- }
+ public void layerChanged(
+ org.geotools.map.event.MapLayerListEvent e) {
+ resetHighlightLayer();
+ }
- public void layerRemoved(org.geotools.map.event.MapLayerListEvent e) {
- resetHighlightLayer();
- }
- });
+ public void layerMoved(
+ 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()
- .getGeometryDescriptor().getCoordinateReferenceSystem();
- // wenn noch keine MapArea gesetzt wurde, den
- // Ausdehnungsbereich des ersten Layers
- // verwenden, so dass die erste
- // Karte komplett angezeigt wird
- if (getMapArea() == null) {
- Envelope newMapArea = new Envelope(e.getLayer()
- .getFeatureSource().getBounds());
- // 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.", err);
- }
- }
- }
- });
- }
+ public void layerRemoved(
+ org.geotools.map.event.MapLayerListEvent e) {
+ resetHighlightLayer();
+ }
+ });
- /**
- * 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;
- }
+ // 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().getGeometryDescriptor()
+ .getCoordinateReferenceSystem();
+ // wenn noch keine MapArea gesetzt wurde, den
+ // Ausdehnungsbereich des ersten Layers
+ // verwenden, so dass die erste
+ // Karte komplett angezeigt wird
+ if (getMapArea() == null) {
+ Envelope newMapArea = new Envelope(e
+ .getLayer().getFeatureSource()
+ .getBounds());
+ // 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.",
+ err);
+ }
+ }
+ }
+ });
+ }
- /**
- * 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;
- }
+ /**
+ * 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;
+ }
- /**
- * 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;
- }
+ /**
+ * 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;
+ }
- /**
- * 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;
- }
+ /**
+ * 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;
+ }
- /**
- * 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() {
+ /**
+ * 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;
+ }
- // SK: Added by SK, 27.09.2007
- // Durch den reset ist das repaint immer etwas aufwaendiger. Der Cursor
- // wechselt dann auf WAIT
- setWaitCursorDuringNextRepaint(true);
+ /**
+ * 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() {
- setReset(true);
- repaint();
- }
+ // SK: Added by SK, 27.09.2007
+ // Durch den reset ist das repaint immer etwas aufwaendiger. Der Cursor
+ // wechselt dann auf WAIT
+ setWaitCursorDuringNextRepaint(true);
- /**
- * 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);
- }
+ setReset(true);
+ repaint();
+ }
- /**
- * 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 {
+ /**
+ * 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);
+ }
- // BB umrechnen von Layer-CRS in Map-CRS
- final Envelope mapAreaNew = JTSUtil.transformEnvelope(layer
- .getFeatureSource().getBounds(), layer.getFeatureSource().getSchema()
- .getGeometryDescriptor().getCoordinateReferenceSystem(), 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)
+ /**
+ * 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 {
- if (mapAreaNew != null) {
- mapAreaNew.expandBy(mapAreaNew.getWidth() * 0.1,
- mapAreaNew.getHeight() * 0.1);
- setMapArea(mapAreaNew);
- } else {
- LOGGER.warn("Couldn't transformEnvelope when zooming to the layer");
- }
- } catch (Exception err) {
- LOGGER.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().getGeometryDescriptor()
+ .getCoordinateReferenceSystem(), 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)
- /**
- * 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));
- }
+ if (mapAreaNew != null) {
+ mapAreaNew.expandBy(mapAreaNew.getWidth() * 0.1, mapAreaNew
+ .getHeight() * 0.1);
+ setMapArea(mapAreaNew);
+ } else {
+ LOGGER
+ .warn("Couldn't transformEnvelope when zooming to the layer");
+ }
+ } catch (Exception err) {
+ LOGGER.warn("Zoom to layer did not terminate correctly", err);
+ }
+ }
- /**
- * 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 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));
+ }
- /**
- * 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();
- }
+ /**
+ * 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 oberste Layer (sichtbar oder unsichtbar).
- */
- public MapLayer getTopLayer() {
- int count = getContext().getLayerCount();
- return count > 0 ? getContext().getLayer(count - 1) : null;
- }
+ /**
+ * 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 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 Layer (sichtbar oder unsichtbar).
+ */
+ public MapLayer getTopLayer() {
+ int count = getContext().getLayerCount();
+ return count > 0 ? getContext().getLayer(count - 1) : 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 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 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 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 unterste Layer (sichtbar oder unsichtbar).
- */
- public MapLayer getBottomLayer() {
- return getContext().getLayerCount() > 0 ? getContext().getLayer(0) : 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;
+ }
- /**
- * 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!");
+ /**
+ * Liefert unterste Layer (sichtbar oder unsichtbar).
+ */
+ public MapLayer getBottomLayer() {
+ return getContext().getLayerCount() > 0 ? getContext().getLayer(0)
+ : null;
+ }
- // 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);
- }
+ /**
+ * 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!");
- this.selState = newSelState;
+ // 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);
+ }
- // Je nach Aktion den Cursor umsetzen
- updateCursor();
- }
+ this.selState = newSelState;
- /**
- * 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);
- }
+ // Je nach Aktion den Cursor umsetzen
+ updateCursor();
+ }
- /**
- * 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;
- }
+ /**
+ * 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);
+ }
- /**
- * 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 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 Modus fuer Window-Selektion.
- *
- * @see #setWindowSelectionState(int)
- */
- public int getWindowSelectionState() {
- return this.selState;
- }
+ /**
+ * 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;
+ }
+ }
- /**
- * Fuegt der Map einen Listener hinzu.
- *
- * @param l
- * neuer Listener
- */
- public void addMapPaneListener(JMapPaneListener l) {
- mapPaneListeners.add(l);
- }
+ /**
+ * Liefert den Modus fuer Window-Selektion.
+ *
+ * @see #setWindowSelectionState(int)
+ */
+ public int getWindowSelectionState() {
+ return this.selState;
+ }
- /**
- * Entfernt einen Listener von der Map.
- *
- * @param l
- * zu entfernender Listener
- */
- public void removeMapPaneListener(JMapPaneListener l) {
- mapPaneListeners.remove(l);
- }
+ /**
+ * Fuegt der Map einen Listener hinzu.
+ *
+ * @param l
+ * neuer Listener
+ */
+ public void addMapPaneListener(JMapPaneListener l) {
+ mapPaneListeners.add(l);
+ }
- /**
- * Propagiert ein Ereignis an alle angeschlossenen Listener.
- *
- * @param e
- * Ereignis
- */
- protected void fireMapPaneEvent(JMapPaneEvent e) {
- for (JMapPaneListener l : mapPaneListeners)
- l.performMapPaneEvent(e);
- }
+ /**
+ * Entfernt einen Listener von der Map.
+ *
+ * @param l
+ * zu entfernender Listener
+ */
+ public void removeMapPaneListener(JMapPaneListener l) {
+ mapPaneListeners.remove(l);
+ }
- /**
- * Konvertiert die Maus-Koordinaten (relativ zum <code>JMapPane</code>) in
- * Karten-Koordinaten.
- *
- * @param e
- * Maus-Ereignis
- */
- public static Point2D getMapCoordinatesFromEvent(MouseEvent e) {
- // aktuelle Geo-Position aus GeoMouseEvent ermitteln
- if (e != null && e instanceof MapMouseEvent)
- try {
- return ((MapMouseEvent) e).getMapPosition().toPoint2D();
- } catch (Exception err) {
- LOGGER.error(
- "return ((GeoMouseEvent) e).getMapCoordinate(null).toPoint2D();",
- err);
- }
+ /**
+ * Propagiert ein Ereignis an alle angeschlossenen Listener.
+ *
+ * @param e
+ * Ereignis
+ */
+ protected void fireMapPaneEvent(JMapPaneEvent e) {
+ for (JMapPaneListener l : mapPaneListeners)
+ l.performMapPaneEvent(e);
+ }
- // 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);
- }
+ /**
+ * Konvertiert die Maus-Koordinaten (relativ zum <code>JMapPane</code>) in
+ * Karten-Koordinaten.
+ *
+ * @param e
+ * Maus-Ereignis
+ */
+ public static Point2D getMapCoordinatesFromEvent(MouseEvent e) {
+ // aktuelle Geo-Position aus GeoMouseEvent ermitteln
+ if (e != null && e instanceof MapMouseEvent)
+ try {
+ return ((MapMouseEvent) e).getMapPosition().toPoint2D();
+ } catch (Exception err) {
+ LOGGER
+ .error(
+ "return ((GeoMouseEvent) e).getMapCoordinate(null).toPoint2D();",
+ err);
+ }
- return 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);
+ }
- /**
- * 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;
+ return null;
+ }
- // keine wirkliche Selektion, sondern nur ein Klick
- if (ox == px || oy == py)
- 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;
- // Fenster-Koordinaten in Map-Koordinaten umwandeln
- Envelope env = tranformWindowToGeo(ox, oy, px, py);
+ // keine wirkliche Selektion, sondern nur ein Klick
+ if (ox == px || oy == py)
+ return;
- // Generelles Event ausloesen
- fireMapPaneEvent(new GeneralSelectionEvent(this, env));
+ // Fenster-Koordinaten in Map-Koordinaten umwandeln
+ Envelope env = tranformWindowToGeo(ox, oy, px, py);
- 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;
- }
- }
+ // Generelles Event ausloesen
+ fireMapPaneEvent(new GeneralSelectionEvent(this, env));
- /**
- * Verarbeitet die Mausrad-Aktion, indem gezoomed wird.
- *
- * @param e
- * Mausrad-Event
- */
- protected void performMouseWheelEvent(MouseWheelEvent e) {
- if (getContext().getLayerCount() == 0)
- return;
+ 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;
+ }
+ }
- int units = e.getUnitsToScroll();
- // Positiver Wert --> Zoom in --> Faktor < 1
- // Negativer Wert --> Zoom out --> Faktir > 1
+ /**
+ * Verarbeitet die Mausrad-Aktion, indem gezoomed wird.
+ *
+ * @param e
+ * Mausrad-Event
+ */
+ protected void performMouseWheelEvent(MouseWheelEvent e) {
+ if (getContext().getLayerCount() == 0)
+ return;
- // 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;
+ int units = e.getUnitsToScroll();
+ // Positiver Wert --> Zoom in --> Faktor < 1
+ // Negativer Wert --> Zoom out --> Faktir > 1
- // 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();
+ // 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;
- // 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));
+ // 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();
- setWaitCursorDuringNextRepaint(true);
- repaint();
- }
+ // 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));
- /**
- * 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());
- }
+ setWaitCursorDuringNextRepaint(true);
+ repaint();
+ }
- /**
- * 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 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());
+ }
- /**
- * 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());
- }
+ /**
+ * 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);
+ }
- /**
- * 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;
- }
+ /**
+ * 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());
+ }
- /**
- * 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);
- }
+ /**
+ * 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;
+ }
- double oldScale = getScale();
- Envelope oldEnv = getMapArea();
+ /**
+ * 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);
+ }
- super.setMapArea(env);
+ double oldScale = getScale();
+ Envelope oldEnv = getMapArea();
- resetTransform();
- double newScale = getScale();
- Envelope newEnv = getMapArea();
+ super.setMapArea(env);
- 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));
- }
+ resetTransform();
+ double newScale = getScale();
+ Envelope newEnv = getMapArea();
- /**
- * 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;
+ 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));
+ }
- // double oldScale = getScale();
- // Envelope oldEnv = getMapArea();
+ /**
+ * 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;
- switch (e.getButton()) {
- // Linksklick --> Eingestellte Funktion
- case MouseEvent.BUTTON1: // SimpleFeature-Auswahl nicht ueber die
- // super-Funktion
- int state = getState();
+ // double oldScale = getScale();
+ // Envelope oldEnv = getMapArea();
- if (state == SELECT_TOP || state == SELECT_ONE_FROM_TOP
- || state == SELECT_ALL) {
+ switch (e.getButton()) {
+ // Linksklick --> Eingestellte Funktion
+ case MouseEvent.BUTTON1: // SimpleFeature-Auswahl nicht ueber die
+ // super-Funktion
+ int state = getState();
- /**
- * BEGIN StefanChange Dieser Block findet sichtbare Features im Umkreis
- * des Mausklicks und kümmert sich selbst um das verschicken der Events.
- * Dabei wird z.Zt. immer eine FeaterCollection mit nur einem
- * SimpleFeature verschickt. Und zwar jenes SimpleFeature, welches am
- * nächsten liegt.
- */
+ if (state == SELECT_TOP || state == SELECT_ONE_FROM_TOP
+ || state == SELECT_ALL) {
- // 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()));
+ /**
+ * BEGIN StefanChange Dieser Block findet sichtbare Features im
+ * Umkreis des Mausklicks und kümmert sich selbst um das
+ * verschicken der Events. Dabei wird z.Zt. immer eine
+ * FeaterCollection mit nur einem SimpleFeature verschickt. Und
+ * zwar jenes SimpleFeature, welches am nächsten liegt.
+ */
- // 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());
+ // 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()));
- final Envelope envelope = new Envelope(geoCoord.getX(),
- geoCoord.getX(), geoCoord.getY(), 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());
- Hashtable<MapLayer, FeatureCollection<SimpleFeatureType,SimpleFeature>> result = findVisibleFeatures(
- new NearPointFilterGenerator(geoCoord, dist, getContext()
- .getCoordinateReferenceSystem()), state, envelope);
+ final Envelope envelope = new Envelope(geoCoord.getX(),
+ geoCoord.getX(), geoCoord.getY(), geoCoord.getY());
- boolean featuresFound = false;
- // Events ausloesen fuer jedes Layer
- for (Enumeration<MapLayer> element = result.keys(); element
- .hasMoreElements();) {
+ Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> result = findVisibleFeatures(
+ new NearPointFilterGenerator(geoCoord, dist,
+ getContext().getCoordinateReferenceSystem()),
+ state, envelope);
- MapLayer layer = element.nextElement();
- FeatureCollection<SimpleFeatureType, SimpleFeature> fc = result
- .get(layer);
- FeatureCollection<SimpleFeatureType, SimpleFeature> fcOne;
+ boolean featuresFound = false;
+ // Events ausloesen fuer jedes Layer
+ for (Enumeration<MapLayer> element = result.keys(); element
+ .hasMoreElements();) {
- if (fc != null && !fc.isEmpty()) {
+ MapLayer layer = element.nextElement();
+ FeatureCollection<SimpleFeatureType, SimpleFeature> fc = result
+ .get(layer);
+ FeatureCollection<SimpleFeatureType, SimpleFeature> fcOne;
- if (fc.size() > 1) {
- // Hier werden alle Features weggeschmissen, bis auf
- // das raeumlich naechste.
+ if (fc != null && !fc.isEmpty()) {
- SimpleFeature nearestFeature = null;
- Double nearestDist = 0.0;
+ if (fc.size() > 1) {
+ // Hier werden alle Features weggeschmissen, bis auf
+ // das raeumlich naechste.
- Iterator<SimpleFeature> fcIt = fc.iterator();
- while (fcIt.hasNext()) {
- SimpleFeature f = fcIt.next();
- Object obj = f.getAttribute(0);
+ SimpleFeature nearestFeature = null;
+ Double nearestDist = 0.0;
- if (obj instanceof Geometry) {
- // Bei Punkten ja noch ganz einfach:
- Geometry featureGeometry = (Geometry) obj;
- double distance = featureGeometry.distance(mousePoint);
+ Iterator<SimpleFeature> fcIt = fc.iterator();
+ while (fcIt.hasNext()) {
+ SimpleFeature f = fcIt.next();
+ Object obj = f.getAttribute(0);
- if ((nearestFeature == null) || (distance < nearestDist)) {
- nearestFeature = f;
- nearestDist = distance;
- }
- } else {
- LOGGER.info("!obj instanceof Geometry obj = "
- + obj.getClass().getSimpleName());
- }
+ if (obj instanceof Geometry) {
+ // Bei Punkten ja noch ganz einfach:
+ Geometry featureGeometry = (Geometry) obj;
+ double distance = featureGeometry
+ .distance(mousePoint);
- }
- fc.close(fcIt);
+ if ((nearestFeature == null)
+ || (distance < nearestDist)) {
+ nearestFeature = f;
+ nearestDist = distance;
+ }
+ } else {
+ LOGGER
+ .info("!obj instanceof Geometry obj = "
+ + obj.getClass()
+ .getSimpleName());
+ }
- fcOne = new MemoryFeatureCollection(fc.getSchema());
- fc.clear();
- fcOne.add(nearestFeature);
- } else {
- fcOne = fc;
- }
- fireMapPaneEvent(new FeatureSelectedEvent(JMapPane.this, layer,
- envelope, fcOne));
- featuresFound = true;
- }
- }
+ }
+ fc.close(fcIt);
- // TODO TODO TODO SK: DIese trennung: erst SimpleFeature layers, dann
- // grid layers check ist doof!
- // if (state == SELECT_ALL || !result.isEmpty())
+ fcOne = new MemoryFeatureCollection(fc.getSchema());
+ fc.clear();
+ fcOne.add(nearestFeature);
+ } else {
+ fcOne = fc;
+ }
+ fireMapPaneEvent(new FeatureSelectedEvent(
+ JMapPane.this, layer, envelope, fcOne));
+ featuresFound = true;
+ }
+ }
- // LOGGER.info("state= "+state+" featuresFound = "+
- // featuresFound);
- if (state == SELECT_ALL || !featuresFound) {
- // LOGGER.info(" findGridCoverageValuesAndFireEvents");
- findGridCoverageValuesAndFireEvents(geoCoord, state);
- }
+ // TODO TODO TODO SK: DIese trennung: erst SimpleFeature layers,
+ // dann
+ // grid layers check ist doof!
+ // if (state == SELECT_ALL || !result.isEmpty())
- break;
- }
- super.mouseClicked(e);
- return; // was: breka, aber wir brauchen ja nicht das
- // setMapArea(mapArea)
+ // LOGGER.info("state= "+state+" featuresFound = "+
+ // featuresFound);
+ if (state == SELECT_ALL || !featuresFound) {
+ // LOGGER.info(" findGridCoverageValuesAndFireEvents");
+ findGridCoverageValuesAndFireEvents(geoCoord, state);
+ }
- // 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;
- }
+ break;
+ }
+ super.mouseClicked(e);
+ return; // was: breka, aber wir brauchen ja nicht das
+ // setMapArea(mapArea)
- // 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
+ // 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;
+ }
- 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 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 <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) {
+ 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) );
+ }
- // if (!reset) return; // TEST TEST TETS ONLY REMOVE!!
+ /**
+ * 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 (!reset) return; // TEST TEST TETS ONLY REMOVE!!
- if (!getBounds().equals(oldRect) || reset)
- seriouseChange = true;
- else if (!mapArea.equals(oldMapArea))
- seriouseChange = true;
+ Cursor oldCursor = null;
+ boolean seriouseChange = false;
- if (seriouseChange) {
- if (setWaitCursorDuringNextRepaint) {
+ if (!getBounds().equals(oldRect) || reset)
+ seriouseChange = true;
+ else if (!mapArea.equals(oldMapArea))
+ seriouseChange = true;
- if (getWaitCursorComponent() != null) {
- // Der Cursor soll auch in einer anderen Component geaendert
- // werden..
- oldCursor = getWaitCursorComponent().getCursor();
- getWaitCursorComponent().setCursor(WAIT_CURSOR);
- }
+ if (seriouseChange) {
+ if (setWaitCursorDuringNextRepaint) {
- // Den Cursor extra nochmal in dieser COmponente aendern
- setCursor(WAIT_CURSOR);
- }
- }
+ if (getWaitCursorComponent() != null) {
+ // Der Cursor soll auch in einer anderen Component geaendert
+ // werden..
+ oldCursor = getWaitCursorComponent().getCursor();
+ getWaitCursorComponent().setCursor(WAIT_CURSOR);
+ }
- try {
- // if (!seriouseChange) {
- // LOGGER.info("No seriouse Change => reset = false");
- // reset= false;
- // }
- super.paintComponent(g);
- } catch (Exception e) {
- /**
- * I only need to catch UnknownHostException.. well...
- */
- LOGGER
- .info(
- "Error during JMapPane printComponent. Probably we are offline and reference some online SVGs?",
- e);
- }
- if (seriouseChange) {
- resetTransform();
- if (setWaitCursorDuringNextRepaint) {
- setWaitCursorDuringNextRepaint = false;
- if (oldCursor != null)
- getWaitCursorComponent().setCursor(oldCursor);
- updateCursor(); // Den Cursor in dieser Componente immer wieder
- // herstellen
- }
+ // Den Cursor extra nochmal in dieser COmponente aendern
+ setCursor(WAIT_CURSOR);
+ }
+ }
- /**
- * 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);
- }
- }
+ try {
+ // if (!seriouseChange) {
+ // LOGGER.info("No seriouse Change => reset = false");
+ // reset= false;
+ // }
+ super.paintComponent(g);
+ } catch (Exception e) {
+ /**
+ * I only need to catch UnknownHostException.. well...
+ */
+ LOGGER
+ .info(
+ "Error during JMapPane printComponent. Probably we are offline and reference some online SVGs?",
+ e);
+ }
+ if (seriouseChange) {
+ resetTransform();
+ if (setWaitCursorDuringNextRepaint) {
+ setWaitCursorDuringNextRepaint = false;
+ if (oldCursor != null)
+ getWaitCursorComponent().setCursor(oldCursor);
+ updateCursor(); // Den Cursor in dieser Componente immer wieder
+ // herstellen
+ }
- }
+ /**
+ * Paint an icon in the lower right corner. FeatureRequest: [#717]
+ * MapIcon has long been disabled and should come back
+ */
+ if (mapImage != null && baseImage != null) {
+ 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()
- .getGeometryDescriptor().getCoordinateReferenceSystem(), getContext()
- .getCoordinateReferenceSystem());
+ }
- // TODO warum kann bounds_MapCRS == null sein ?? ?SK fragt martin???
- if (bounds_MapCRS == null)
- return false;
+ /**
+ * Testet (anhand der Bounding-Box), ob das Objekt eines Layers eine andere
+ * Bounding-Box schneidet. Die Bounding-Box des Layer-Objekts wird zunaechst
+ * in das CRS des MapPanes umgerechnets.
+ *
+ * @param layer
+ * ein Layer
+ * @param env
+ * Bounding-Box in CRS des MapPane
+ */
+ private boolean gridLayerIntersectsEnvelope(MapLayer layer, Envelope env) {
+ try {
+ // BB des Layers umrechnen von Layer-CRS in Map-CRS
+ Envelope bounds_MapCRS = JTSUtil.transformEnvelope(layer
+ .getFeatureSource().getBounds(), layer.getFeatureSource()
+ .getSchema().getGeometryDescriptor()
+ .getCoordinateReferenceSystem(), getContext()
+ .getCoordinateReferenceSystem());
- return bounds_MapCRS.intersects(env);
- } catch (Exception err) {
- return false;
- }
- }
+ // TODO warum kann bounds_MapCRS == null sein ?? ?SK fragt martin???
+ if (bounds_MapCRS == null)
+ return false;
- /**
- * Testet (anhand der Features), ob das Objekt eines Layers eine Bounding-Box
- * schneidet.
- *
- * @param layer
- * ein Layer
- * @param env
- * Bounding-Box in CRS des MapPane
- */
- private boolean featureLayerIntersectsEnvelope(MapLayer layer, Envelope env) {
- try {
- // // BB umrechnen von Map-CRS in Layer-CRS
- // Envelope env_LayerCRS = JTSUtil.transformEnvelope(env,
- // getContext()
- // .getCoordinateReferenceSystem(), layer.getFeatureSource()
- // .getSchema().getDefaultGeometry().getCoordinateSystem());
- // GeometryFilterImpl filter =
- // createBoundingBoxFilter(env_LayerCRS);
- // Expression geometry = ff.createAttributeExpression(layer
- // .getFeatureSource().getSchema().getDefaultGeometry()
- // .getLocalName());
- // filter.setExpression1(geometry);
- FeatureSource<SimpleFeatureType,SimpleFeature> featureSource = (FeatureSource<SimpleFeatureType,SimpleFeature>)layer.getFeatureSource();
- GeometryFilterImpl filter = new BoundingBoxFilterGenerator(env,
- getContext().getCoordinateReferenceSystem()).adaptFilter(featureSource);
- return !layer.getFeatureSource().getFeatures(filter).isEmpty();
- } catch (Exception err) {
- return false;
- }
- }
+ return bounds_MapCRS.intersects(env);
+ } catch (Exception err) {
+ return false;
+ }
+ }
- /**
- * Ermittelt alle sichtbaren Features, die einen Filter erfuellen. Beim Modus
- * {@link #SELECT_TOP} wird nur das oberste sichtbare Layer durchsucht. Beim
- * Modus {@link #SELECT_ALL} werden alle sichtbaren Layer durchsucht.
- *
- * @see #findFeatures(GeometryFilterImpl, int, Envelope)
- *
- * @param filterGenerator
- * adapts the filter to a concrete FeatureSource
- * @param mode
- * Suchmodus
- * @return eine leere {@link Hashtable} falls der Filter {@code null} ist
- */
- protected Hashtable<MapLayer, FeatureCollection<SimpleFeatureType,SimpleFeature>> findVisibleFeatures(
- GeomFilterGenerator filterGenerator, int mode, Envelope env) {
- Hashtable<MapLayer, FeatureCollection<SimpleFeatureType,SimpleFeature>> result = new Hashtable<MapLayer, FeatureCollection<SimpleFeatureType,SimpleFeature>>();
- if (filterGenerator == null)
- return result;
+ /**
+ * Testet (anhand der Features), ob das Objekt eines Layers eine
+ * Bounding-Box schneidet.
+ *
+ * @param layer
+ * ein Layer
+ * @param env
+ * Bounding-Box in CRS des MapPane
+ */
+ private boolean featureLayerIntersectsEnvelope(MapLayer layer, Envelope env) {
+ try {
+ // // BB umrechnen von Map-CRS in Layer-CRS
+ // Envelope env_LayerCRS = JTSUtil.transformEnvelope(env,
+ // getContext()
+ // .getCoordinateReferenceSystem(), layer.getFeatureSource()
+ // .getSchema().getDefaultGeometry().getCoordinateSystem());
+ // GeometryFilterImpl filter =
+ // createBoundingBoxFilter(env_LayerCRS);
+ // Expression geometry = ff.createAttributeExpression(layer
+ // .getFeatureSource().getSchema().getDefaultGeometry()
+ // .getLocalName());
+ // filter.setExpression1(geometry);
+ FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) layer
+ .getFeatureSource();
+ GeometryFilterImpl filter = new BoundingBoxFilterGenerator(env,
+ getContext().getCoordinateReferenceSystem())
+ .adaptFilter(featureSource);
+ return !layer.getFeatureSource().getFeatures(filter).isEmpty();
+ } catch (Exception err) {
+ return false;
+ }
+ }
- // 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 sichtbaren Features, die einen Filter erfuellen. Beim
+ * Modus {@link #SELECT_TOP} wird nur das oberste sichtbare Layer
+ * durchsucht. Beim Modus {@link #SELECT_ALL} werden alle sichtbaren Layer
+ * durchsucht.
+ *
+ * @see #findFeatures(GeometryFilterImpl, int, Envelope)
+ *
+ * @param filterGenerator
+ * adapts the filter to a concrete FeatureSource
+ * @param mode
+ * Suchmodus
+ * @return eine leere {@link Hashtable} falls der Filter {@code null} ist
+ */
+ protected Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> findVisibleFeatures(
+ GeomFilterGenerator filterGenerator, int mode, Envelope env) {
+ Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> result = new Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>>();
+ if (filterGenerator == null)
+ return result;
- if (attributeMetaDataMapCache.containsKey(layer.getTitle())) {
- /* AttributeMetaData is available... */
- Map<Integer, AttributeMetaData> amdMap = attributeMetaDataMapCache
- .get(layer.getTitle());
+ // 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;
- if (StyledLayerUtil.getVisibleAttributeMetaData(amdMap, true).size() == 0) {
- LOGGER.debug("Ignoring layer " + layer.getTitle()
- + " because it has no visible attributes");
- continue;
- }
- }
+ if (attributeMetaDataMapCache.containsKey(layer.getTitle())) {
+ /* AttributeMetaData is available... */
+ Map<Integer, AttributeMetaData> amdMap = attributeMetaDataMapCache
+ .get(layer.getTitle());
- LOGGER.debug("mode = " + mode);
+ if (StyledLayerUtil.getVisibleAttributeMetaData(amdMap, true)
+ .size() == 0) {
+ LOGGER.debug("Ignoring layer " + layer.getTitle()
+ + " because it has no visible attributes");
+ continue;
+ }
+ }
- /*
- * SK: Change! If AttributeMetadata is provided, we check whether any
- * attribute is
- */
+ LOGGER.debug("mode = " + mode);
- // Bei einem Raster-Layer, das die BB schneidet, abbrechen, wenn nur
- // im obersten (sichtbaren) Layer gesucht wird.
- // Ansonsten Raster-Layer einfach uebergehen.
- if (isGridCoverageLayer(layer)) {
- if (mode == SELECT_TOP && gridLayerIntersectsEnvelope(layer, env))
- break;
- continue;
- }
+ /*
+ * SK: Change! If AttributeMetadata is provided, we check whether
+ * any attribute is
+ */
- // Filter an Layer koppeln
- // WICHTIG: Dies darf erst geschehen, NACHDEM das
- // Schleifen-Abbruch-Kriterium
- // fuer die Raster-Layer geprueft wurde!!
- // Werden folgende Zeilen naemlich auf das FeatureSource des
- // Raster-Layers angewandt, dann "bricht" der Filter "irgendwie"
- // zusammen und auch die ZUVOR gefilterten FeatureCollections,
- // sind ploetzlich EMPTY!!!!!!!!!!!!!!!!!!!!!!!!!!!
- final FeatureSource<SimpleFeatureType,SimpleFeature> featureSource = (FeatureSource<SimpleFeatureType,SimpleFeature>)layer.getFeatureSource();
- final GeometryFilterImpl distancefilter = filterGenerator
- .adaptFilter(featureSource);
+ // 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;
+ }
- /**
- * 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);
- }
- }
+ // Filter an Layer koppeln
+ // WICHTIG: Dies darf erst geschehen, NACHDEM das
+ // Schleifen-Abbruch-Kriterium
+ // fuer die Raster-Layer geprueft wurde!!
+ // Werden folgende Zeilen naemlich auf das FeatureSource des
+ // Raster-Layers angewandt, dann "bricht" der Filter "irgendwie"
+ // zusammen und auch die ZUVOR gefilterten FeatureCollections,
+ // sind ploetzlich EMPTY!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ final FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) layer
+ .getFeatureSource();
+ final GeometryFilterImpl distancefilter = filterGenerator
+ .adaptFilter(featureSource);
- try {
- // Filter auf Layer des Features anwenden
- // FeatureCollection fc = layer.getFeatureSource().getFeatures(
- // FilterUtil.cloneFilter(filter) ); // KLAPPT (NOCH) NICHT
- // FeatureCollection fc = featureSource.getFeatures(
- // distancefilter );
- FeatureCollection<SimpleFeatureType,SimpleFeature> fc = featureSource.getFeatures(filter);
+ /**
+ * 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);
+ }
+ }
- LOGGER.info("Crazy finsvisible features position reached");
+ try {
+ // Filter auf Layer des Features anwenden
+ // FeatureCollection fc = layer.getFeatureSource().getFeatures(
+ // FilterUtil.cloneFilter(filter) ); // KLAPPT (NOCH) NICHT
+ // FeatureCollection fc = featureSource.getFeatures(
+ // distancefilter );
+ FeatureCollection<SimpleFeatureType, SimpleFeature> fc = featureSource
+ .getFeatures(filter);
- // 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;
- }
+ LOGGER.info("Crazy finsvisible features position reached");
- // @Martin Using size() produces the same problem
- if (!fc.isEmpty()) {
- fc = filterSLDVisibleOnly(fc, layer.getStyle());
+ // 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;
+ }
- 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()) {
+ fc = filterSLDVisibleOnly(fc, layer.getStyle());
- }
- } catch (IOException err) {
- LOGGER.error("applying the distanceWithin filter", err);
- }
+ 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) {
+ LOGGER.error("applying the distanceWithin filter", err);
+ }
- 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<SimpleFeatureType,SimpleFeature>> findFeatures(
- GeomFilterGenerator filterGenerator, int mode, Envelope env) {
- Hashtable<MapLayer, FeatureCollection<SimpleFeatureType,SimpleFeature>> result = new Hashtable<MapLayer, FeatureCollection<SimpleFeatureType,SimpleFeature>>();
- if (filterGenerator == null)
- return result;
+ 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<SimpleFeatureType, SimpleFeature>> findFeatures(
+ GeomFilterGenerator filterGenerator, int mode, Envelope env) {
+ Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> result = new Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>>();
+ if (filterGenerator == null)
+ return result;
- // 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<SimpleFeatureType,SimpleFeature> featureSource = (FeatureSource<SimpleFeatureType,SimpleFeature>)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<SimpleFeatureType,SimpleFeature> 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<SimpleFeatureType, SimpleFeature> featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) layer
+ .getFeatureSource();
+ final GeometryFilterImpl filter = filterGenerator
+ .adaptFilter(featureSource);
- // 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());
+ try {
+ // Filter auf Layer des Features anwenden
+ // FeatureCollection fc = layer.getFeatureSource().getFeatures(
+ // FilterUtil.cloneFilter(filter) ); // KLAPPT (NOCH) NICHT
+ FeatureCollection<SimpleFeatureType, SimpleFeature> fc = featureSource
+ .getFeatures(filter);
- if (!fc.isEmpty()) {
- result.put(layer, fc);
- // Beim Modus "oberstes Layer selektieren" die Schleife
- // jetzt beenden, da wir sichtbare Features gefunden haben.
- if (mode == SELECT_TOP || mode == SELECT_ONE_FROM_TOP)
- break;
- }
- } catch (Exception err) {
- LOGGER.error("Looking for features:", err);
- }
+ // 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());
- // for ( FeatureCollection fc1 : result.values() )
- // LOGGER.debug("A "+fc1+" "+fc1.isEmpty());
- }
- // for ( FeatureCollection fc1 : result.values() )
- // LOGGER.debug("B "+fc1+" "+fc1.isEmpty());
+ if (!fc.isEmpty()) {
+ result.put(layer, fc);
+ // Beim Modus "oberstes Layer selektieren" die Schleife
+ // jetzt beenden, da wir sichtbare Features gefunden haben.
+ if (mode == SELECT_TOP || mode == SELECT_ONE_FROM_TOP)
+ break;
+ }
+ } catch (Exception err) {
+ LOGGER.error("Looking for features:", err);
+ }
- return result;
- }
+ // for ( FeatureCollection fc1 : result.values() )
+ // LOGGER.debug("A "+fc1+" "+fc1.isEmpty());
+ }
+ // for ( FeatureCollection fc1 : result.values() )
+ // LOGGER.debug("B "+fc1+" "+fc1.isEmpty());
- /**
- * 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<SimpleFeatureType,SimpleFeature> fc, final Style style) {
+ return result;
+ }
- // Der "scaleDenominator" der aktuellen JMapPane
- Double scaleDenominator = RendererUtilities.calculateOGCScale(
- new ReferencedEnvelope(getMapArea(), getContext()
- .getCoordinateReferenceSystem()), getSize().width, null);
+ /**
+ * 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<SimpleFeatureType, SimpleFeature> fc,
+ final Style style) {
- return StylingUtil.filterSLDVisibleOnly(fc, style, scaleDenominator);
- }
+ // Der "scaleDenominator" der aktuellen JMapPane
+ Double scaleDenominator = RendererUtilities
+ .calculateOGCScale(new ReferencedEnvelope(getMapArea(),
+ getContext().getCoordinateReferenceSystem()),
+ getSize().width, null);
- /**
- * Ermittelt alle Features, die in einem Bereich liegen und erzeugt
- * entsprechende {@link FeatureSelectedEvent FeatureSelectedEvents}. Beim
- * Modus {@link #SELECT_TOP} wird nur das oberste sichtbare Layer durchsucht.
- * Beim Modus {@link #SELECT_ALL} werden alle sichtbaren Layer durchsucht.
- *
- * @param filterGenerator
- * adapts a filter to a concrete {@link FeatureSource}
- * @param mode
- * Suchmodus
- * @param env
- * Bereich der durchsucht wird (fuer das Filtern irrelevant; wird nur
- * fuer Events benoetigt!)
- */
- protected boolean findFeaturesAndFireEvents(
- GeomFilterGenerator filterGenerator, int mode, Envelope env) {
- Hashtable<MapLayer, FeatureCollection<SimpleFeatureType,SimpleFeature>> result = findVisibleFeatures(
- filterGenerator, mode, env);
+ return StylingUtil.filterSLDVisibleOnly(fc, style, scaleDenominator);
+ }
- // Events ausloesen fuer jedes Layer
- for (final Enumeration<MapLayer> e = result.keys(); e.hasMoreElements();) {
- final MapLayer layer = e.nextElement();
- final FeatureCollection<SimpleFeatureType,SimpleFeature> fc = result.get(layer);
- if (fc != null && !fc.isEmpty())
- fireMapPaneEvent(new FeatureSelectedEvent(this, layer, env, fc));
- }
- return !result.isEmpty();
- }
+ /**
+ * Ermittelt alle Features, die in einem Bereich liegen und erzeugt
+ * entsprechende {@link FeatureSelectedEvent FeatureSelectedEvents}. Beim
+ * Modus {@link #SELECT_TOP} wird nur das oberste sichtbare Layer
+ * durchsucht. Beim Modus {@link #SELECT_ALL} werden alle sichtbaren Layer
+ * durchsucht.
+ *
+ * @param filterGenerator
+ * adapts a filter to a concrete {@link FeatureSource}
+ * @param mode
+ * Suchmodus
+ * @param env
+ * Bereich der durchsucht wird (fuer das Filtern irrelevant; wird
+ * nur fuer Events benoetigt!)
+ */
+ protected boolean findFeaturesAndFireEvents(
+ GeomFilterGenerator filterGenerator, int mode, Envelope env) {
+ Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> result = findVisibleFeatures(
+ filterGenerator, mode, env);
- /**
- * 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;
+ // Events ausloesen fuer jedes Layer
+ for (final Enumeration<MapLayer> e = result.keys(); e.hasMoreElements();) {
+ final MapLayer layer = e.nextElement();
+ final FeatureCollection<SimpleFeatureType, SimpleFeature> fc = result
+ .get(layer);
+ if (fc != null && !fc.isEmpty())
+ fireMapPaneEvent(new FeatureSelectedEvent(this, layer, env, fc));
+ }
+ return !result.isEmpty();
+ }
- 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;
+ /**
+ * 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;
- // 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;
- }
+ 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 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
+ // Bei einem Nicht-Raster-Layer, das die BB schneidet, abbrechen,
+ // wenn nur im obersten (sichtbaren) Layer gesucht wird.
+ // Ansonsten Nicht-Raster-Layer einfach uebergehen.
+ if (!(layerObj instanceof GridCoverage2D)) {
+ if ((mode == SELECT_TOP || mode == SELECT_ONE_FROM_TOP)
+ && featureLayerIntersectsEnvelope(layer, env))
+ break;
+ continue;
+ }
- // GridCoverage2D 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;
- }
+ 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 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 subsetGrid =
+ // (GridCoverage2D)Operations.DEFAULT.crop(sourceGrid,gtGenEnv);
+ GridCoverage2D subsetGrid = GridUtil.createGridCoverage(sourceGrid,
+ gtGenEnv);
+ if (subsetGrid != null)
+ result.put(layer, subsetGrid);
+ // Beim Modus "oberstes Layer selektieren" die Schleife beenden
+ if (mode == SELECT_TOP || mode == SELECT_ONE_FROM_TOP)
+ break;
+ }
+ return result;
+ }
- /**
- * Ermittelt alle 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[]>();
+ /**
+ * 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();
+ }
- if (point == null)
- return result;
+ /**
+ * Ermittelt alle Raster-Werte, die an einer bestimmten Geo-Position liegen.
+ * Beim Modus {@link #SELECT_TOP} wird nur das oberste sichtbare Layer
+ * durchsucht. Beim Modus {@link #SELECT_ALL} werden alle sichtbaren Layer
+ * durchsucht.
+ * <p>
+ * SK: 28.09.2007 Da ein Rasterlayer auch mehrere Baender haben kann, ist es
+ * sinnvoll, nicht <code>Hashtable MapLayer,Double </code> sondern
+ * <code>Hashtable MapLayer,Double[] </code> zurueckzugeben.
+ *
+ * @param point
+ * Geo-Referenzgeop
+ * @param mode
+ * Suchmodus
+ * @return eine leere {@link Hashtable} falls keine Werte ermittelt werden
+ * konnten
+ *
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ * (University of Bonn/Germany)
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+ * Krüger</a>
+ */
+ protected Hashtable<MapLayer, double[]> findGridCoverageValues(
+ Point2D point, int mode) {
+ Hashtable<MapLayer, double[]> result = new Hashtable<MapLayer, double[]>();
- 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);
+ if (point == null)
+ return result;
- // LOGGER.info("layerObj = "+layerObj.getClass().getSimpleName());
+ 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);
- // 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;
- // }
+ // LOGGER.info("layerObj = "+layerObj.getClass().getSimpleName());
- // 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;
- }
+ // 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;
+ // }
- GridCoverage2D sourceGrid;
+ // 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;
+ }
- if (layerObj instanceof AbstractGridCoverage2DReader) {
- // LOGGER.info("layerObj instanceof AbstractGridCoverage2DReader"
- // );
- AbstractGridCoverage2DReader reader = (AbstractGridCoverage2DReader) layerObj;
- Parameter readGG = new Parameter(AbstractGridFormat.READ_GRIDGEOMETRY2D);
+ GridCoverage2D sourceGrid;
- ReferencedEnvelope mapExtend = new org.geotools.geometry.jts.ReferencedEnvelope(
- mapArea, context.getCoordinateReferenceSystem());
+ if (layerObj instanceof AbstractGridCoverage2DReader) {
+ // LOGGER.info("layerObj instanceof AbstractGridCoverage2DReader"
+ // );
+ AbstractGridCoverage2DReader reader = (AbstractGridCoverage2DReader) layerObj;
+ Parameter readGG = new Parameter(
+ AbstractGridFormat.READ_GRIDGEOMETRY2D);
- readGG.setValue(new GridGeometry2D(
- new GeneralGridEnvelope(getBounds()), mapExtend));
+ ReferencedEnvelope mapExtend = new org.geotools.geometry.jts.ReferencedEnvelope(
+ mapArea, context.getCoordinateReferenceSystem());
- try {
- sourceGrid = (GridCoverage2D) reader
- .read(new GeneralParameterValue[] { readGG });
- } catch (Exception e) {
- LOGGER.error("read(new GeneralParameterValue[] { readGG })", e);
- continue;
- }
- } else {
- // Ein instanceof ist nicht noetig, da sonst schon break oder
- // continue aufgerufen worden waere
- sourceGrid = (GridCoverage2D) layerObj;
- }
+ readGG.setValue(new GridGeometry2D(new GeneralGridEnvelope(
+ getBounds()), mapExtend));
- // vorher: double[] value = new double[2];
+ try {
+ sourceGrid = (GridCoverage2D) reader
+ .read(new GeneralParameterValue[] { readGG });
+ } catch (Exception e) {
+ LOGGER.error(
+ "read(new GeneralParameterValue[] { readGG })", e);
+ continue;
+ }
+ } else {
+ // Ein instanceof ist nicht noetig, da sonst schon break oder
+ // continue aufgerufen worden waere
+ sourceGrid = (GridCoverage2D) layerObj;
+ }
- // getNumSampleDimensions gibt die Anzahl der Baender des Rasters
- // zurueck.
- double[] values = new double[sourceGrid.getNumSampleDimensions()];
+ // vorher: double[] value = new double[2];
- try {
- // Grid an Geo-Position auswerten
- sourceGrid.evaluate(point, values);
- } catch (CannotEvaluateException err) {
- // z.B. Punkt ausserhalb des Rasters --> Layer uebergehen
- continue;
- } catch (Exception e) {
- LOGGER.error("sourceGrid.evaluate(point, values);", e);
- continue;
- }
+ // getNumSampleDimensions gibt die Anzahl der Baender des Rasters
+ // zurueck.
+ double[] values = new double[sourceGrid.getNumSampleDimensions()];
- // SK: voher wurde nur der erste Wert zurueckgegeben
- // result.put(layer,value[0]);
- // jetzt werden alle werte zueuckgegeben
+ try {
+ // Grid an Geo-Position auswerten
+ sourceGrid.evaluate(point, values);
+ } catch (CannotEvaluateException err) {
+ // z.B. Punkt ausserhalb des Rasters --> Layer uebergehen
+ continue;
+ } catch (Exception e) {
+ LOGGER.error("sourceGrid.evaluate(point, values);", e);
+ continue;
+ }
- result.put(layer, values);
- // Beim Modus "oberstes Layer selektieren" die Schleife beenden
- if (mode == SELECT_TOP)
- break;
- }
- return result;
- }
+ // SK: voher wurde nur der erste Wert zurueckgegeben
+ // result.put(layer,value[0]);
+ // jetzt werden alle werte zueuckgegeben
- /**
- * 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);
+ result.put(layer, values);
+ // Beim Modus "oberstes Layer selektieren" die Schleife beenden
+ if (mode == SELECT_TOP)
+ break;
+ }
+ return result;
+ }
- // 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();
- }
+ /**
+ * 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);
- // /**
- // * Bereitet einen BoundingBox-Filter vor. Das "linke" Attribut der
- // * Expression (das SimpleFeature-Attribut, auf das der Filter angewendet
- // wird),
- // * wird dabei noch nicht belegt. Dies geschieht erst bei der Auswertung
- // * entsprechend des jeweiligen Layers
- // *
- // * @param env
- // * Bounding-Box
- // */
- // private static GeometryFilterImpl createBoundingBoxFilter(Envelope env) {
- // // Filter fuer Envelope zusammenstellen
- // Expression bbox = ff.createBBoxExpression(env);
- // GeometryFilterImpl bboxFilter = (GeometryFilterImpl) ff
- // .createGeometryFilter(AbstractFilter.GEOMETRY_BBOX);
- // // GeometryFilterImpl bboxFilter =
- // // (GeometryFilterImpl)ff.createGeometryFilter
- // // (AbstractFilter.GEOMETRY_WITHIN);
- // bboxFilter.setExpression2(bbox);
- // return bboxFilter;
- // }
- //
- // /**
- // * Bereitet einen Punkt-Filter vor. Das "linke" Attribut der Expression
- // (das
- // * SimpleFeature-Attribut, auf das der Filter angewendet wird), wird dabei
- // noch
- // * nicht belegt. Dies geschieht erst bei der Auswertung entsprechend des
- // * jeweiligen Layers
- // *
- // * @param point
- // * Geo-Koordinate
- // */
- // private static GeometryFilterImpl createPointFilter(Point2D point) {
- // // Filter fuer Envelope zusammenstellen
- // Geometry geometry = gf.createPoint(new Coordinate(point.getX(), point
- // .getY()));
- // GeometryFilterImpl pointFilter = (GeometryFilterImpl) ff
- // .createGeometryFilter(GeometryFilterImpl.GEOMETRY_CONTAINS);
- // pointFilter.setExpression2(ff.createLiteralExpression(geometry));
- // return pointFilter;
- // }
- //
- // /**
- // * Bereitet einen "InDerNaehe von" Distance-Filter vor. Das "linke"
- // Attribut
- // * der Expression (das SimpleFeature-Attribut, auf das der Filter angewendet
- // * wird), wird dabei noch nicht belegt. Dies geschieht erst bei der
- // * Auswertung entsprechend des jeweiligen Layers
- // *
- // * Wird benoetigt, um mit der Maus einen Punkt zu treffen.
- // *
- // * @param point
- // * Geo-Koordinate
- // * @param dist
- // * Distanz zum Punkt in Einheiten des Layers
- // *
- // * TODO SK Auf FilterFactory2 ändern... Beispiel von
- // * http://docs.codehaus.org/display/GEOTDOC/Filter+Examples
- // * funktioniert erst ab 2.5 ?? Vor dem Distcheck einen BBOX check
- // * sollte die geschwindigkeit erhöhen.
- // *
- // * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
- // * Krü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;
- // }
+ // 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();
+ }
- /**
- * Prueft, ob es sich bei einem Layer um ein Raster-Layer handelt.
- * Raster-Layer zeichnen sich dadurch aus, dass die zugrunde liegende
- * {@link FeatureCollection} nur ein SimpleFeature enthaelt, das genau ein
- * Attribut mit dem Namen "GridCoverage" hat.
- *
- * SK: Pyramidenlayer aka AbstractGridCoverage2DReader geben auch true zurück.
- *
- * @param layer
- * zu ueberpruefendes Layer
- */
- public static boolean isGridCoverageLayer(MapLayer layer) {
- final Object layerSourceObject = getLayerSourceObject(layer);
- boolean b = (layerSourceObject instanceof GridCoverage2D)
- || (layerSourceObject instanceof AbstractGridCoverage2DReader);
- // if (!b && layerSourceObject instanceof DefaultFeatureResults){
- // DefaultFeatureResults dfr = (DefaultFeatureResults)
- // layerSourceObject;
- // }
- // LOGGER.debug(b+"= "+layerSourceObject.getClass().getSimpleName()+" "+
- // layer.getTitle());
- return b;
- // try {
- // FeatureCollection fc = layer.getFeatureSource().getFeatures();
- // // Layer muss genau ein SimpleFeature beinhalten
- // if ( fc == null || fc.size() != 1 )
- // return false;
- // // SimpleFeature muss genau 1 Attribut mit dem Namen "GridCoverage" haben
- // SimpleFeatureType ftype = fc.getFeatureType();
- // if ( ftype == null || ftype.getAttributeCount() != 1 ||
- // !"GridCoverage".equalsIgnoreCase(ftype.getAttributeType(0).getName())
- // )
- // return false;
- // } catch (Exception err) {
- // }
- // return true;
- }
+ // /**
+ // * Bereitet einen BoundingBox-Filter vor. Das "linke" Attribut der
+ // * Expression (das SimpleFeature-Attribut, auf das der Filter angewendet
+ // wird),
+ // * wird dabei noch nicht belegt. Dies geschieht erst bei der Auswertung
+ // * entsprechend des jeweiligen Layers
+ // *
+ // * @param env
+ // * Bounding-Box
+ // */
+ // private static GeometryFilterImpl createBoundingBoxFilter(Envelope env) {
+ // // Filter fuer Envelope zusammenstellen
+ // Expression bbox = ff.createBBoxExpression(env);
+ // GeometryFilterImpl bboxFilter = (GeometryFilterImpl) ff
+ // .createGeometryFilter(AbstractFilter.GEOMETRY_BBOX);
+ // // GeometryFilterImpl bboxFilter =
+ // // (GeometryFilterImpl)ff.createGeometryFilter
+ // // (AbstractFilter.GEOMETRY_WITHIN);
+ // bboxFilter.setExpression2(bbox);
+ // return bboxFilter;
+ // }
+ //
+ // /**
+ // * Bereitet einen Punkt-Filter vor. Das "linke" Attribut der Expression
+ // (das
+ // * SimpleFeature-Attribut, auf das der Filter angewendet wird), wird dabei
+ // noch
+ // * nicht belegt. Dies geschieht erst bei der Auswertung entsprechend des
+ // * jeweiligen Layers
+ // *
+ // * @param point
+ // * Geo-Koordinate
+ // */
+ // private static GeometryFilterImpl createPointFilter(Point2D point) {
+ // // Filter fuer Envelope zusammenstellen
+ // Geometry geometry = gf.createPoint(new Coordinate(point.getX(), point
+ // .getY()));
+ // GeometryFilterImpl pointFilter = (GeometryFilterImpl) ff
+ // .createGeometryFilter(GeometryFilterImpl.GEOMETRY_CONTAINS);
+ // pointFilter.setExpression2(ff.createLiteralExpression(geometry));
+ // return pointFilter;
+ // }
+ //
+ // /**
+ // * Bereitet einen "InDerNaehe von" Distance-Filter vor. Das "linke"
+ // Attribut
+ // * der Expression (das SimpleFeature-Attribut, auf das der Filter
+ // angewendet
+ // * wird), wird dabei noch nicht belegt. Dies geschieht erst bei der
+ // * Auswertung entsprechend des jeweiligen Layers
+ // *
+ // * Wird benoetigt, um mit der Maus einen Punkt zu treffen.
+ // *
+ // * @param point
+ // * Geo-Koordinate
+ // * @param dist
+ // * Distanz zum Punkt in Einheiten des Layers
+ // *
+ // * TODO SK Auf FilterFactory2 ändern... Beispiel von
+ // * http://docs.codehaus.org/display/GEOTDOC/Filter+Examples
+ // * funktioniert erst ab 2.5 ?? Vor dem Distcheck einen BBOX check
+ // * sollte die geschwindigkeit erhöhen.
+ // *
+ // * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+ // * Krü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;
+ // }
- /**
- * Liefert das Objekt ({@link GridCoverage2D} oder {@link FeatureCollection}
- * oder {@link AbstractGridCoverageReader} auf dem ein Layer basiert. Ein
- * Raster-Layer zeichnen sich dadurch aus, dass die zugrunde liegende
- * {@link FeatureCollection} nur ein SimpleFeature enthaelt, das genau ein
- * Attribut mit Namen "GridCoverage" und Typ {@code GridCoverage2D} oder
- * {@link AbstractGridCoverageReader} hat. Sind diese Bedingungen erfuellt,
- * wird das 2. Attribut zurueckgegeben, ansonsten die
- * {@link FeatureCollection}.
- *
- * @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<SimpleFeatureType, SimpleFeature> featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) layer
- .getFeatureSource();
- FeatureCollection<SimpleFeatureType, SimpleFeature> fc = featureSource
- .getFeatures();
- // RasterLayer muss genau ein SimpleFeature beinhalten
- // Ist dies nicht der Fall wird die FeatureCollection zurueckgegeben
- if (fc == null || fc.size() != 1) {
+ /**
+ * Prueft, ob es sich bei einem Layer um ein Raster-Layer handelt.
+ * Raster-Layer zeichnen sich dadurch aus, dass die zugrunde liegende
+ * {@link FeatureCollection} nur ein SimpleFeature enthaelt, das genau ein
+ * Attribut mit dem Namen "GridCoverage" hat.
+ *
+ * SK: Pyramidenlayer aka AbstractGridCoverage2DReader geben auch true
+ * zurück.
+ *
+ * @param layer
+ * zu ueberpruefendes Layer
+ */
+ public static boolean isGridCoverageLayer(MapLayer layer) {
+ final Object layerSourceObject = getLayerSourceObject(layer);
+ boolean b = (layerSourceObject instanceof GridCoverage2D)
+ || (layerSourceObject instanceof AbstractGridCoverage2DReader);
+ // if (!b && layerSourceObject instanceof DefaultFeatureResults){
+ // DefaultFeatureResults dfr = (DefaultFeatureResults)
+ // layerSourceObject;
+ // }
+ // LOGGER.debug(b+"= "+layerSourceObject.getClass().getSimpleName()+" "+
+ // layer.getTitle());
+ return b;
+ // try {
+ // FeatureCollection fc = layer.getFeatureSource().getFeatures();
+ // // Layer muss genau ein SimpleFeature beinhalten
+ // if ( fc == null || fc.size() != 1 )
+ // return false;
+ // // SimpleFeature muss genau 1 Attribut mit dem Namen "GridCoverage"
+ // haben
+ // SimpleFeatureType ftype = fc.getFeatureType();
+ // if ( ftype == null || ftype.getAttributeCount() != 1 ||
+ // !"GridCoverage".equalsIgnoreCase(ftype.getAttributeType(0).getName())
+ // )
+ // return false;
+ // } catch (Exception err) {
+ // }
+ // return true;
+ }
- return fc;
- }
- // SimpleFeatureType des RasterLayer muss genau 1 Attribut mit Namen
- // "GridCoverage"
- // Ist dies nicht der Fall wird die FeatureCollection zurueckgegeben
- SimpleFeatureType ftype = fc.getSchema();
- if (ftype == null
- || ftype.getAttributeCount() != 1
- || !"GridCoverage".equalsIgnoreCase(ftype.getAttributeDescriptors()
- .get(0).getLocalName()))
- return fc;
- // (Einziges) SimpleFeature muss genau 2 Attribute besitzen, wobei das
- // erste vom
- // Typ Geometry ist und das zweite vom Typ GridCoverage2D
- // sonst: FeatureCollextion zurueckgeben
+ /**
+ * Liefert das Objekt ({@link GridCoverage2D} oder {@link FeatureCollection}
+ * oder {@link AbstractGridCoverageReader} auf dem ein Layer basiert. Ein
+ * Raster-Layer zeichnen sich dadurch aus, dass die zugrunde liegende
+ * {@link FeatureCollection} nur ein SimpleFeature enthaelt, das genau ein
+ * Attribut mit Namen "GridCoverage" und Typ {@code GridCoverage2D} oder
+ * {@link AbstractGridCoverageReader} hat. Sind diese Bedingungen erfuellt,
+ * wird das 2. Attribut zurueckgegeben, ansonsten die
+ * {@link FeatureCollection}.
+ *
+ * @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<SimpleFeatureType, SimpleFeature> featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) layer
+ .getFeatureSource();
+ FeatureCollection<SimpleFeatureType, SimpleFeature> fc = featureSource
+ .getFeatures();
- /** CHANGE SK 9.8.08 BEGIN */
- SimpleFeature f = fc.features().next();
- if ((f.getFeatureType().getTypeName().equals("GridCoverage") && f
- .getAttributeCount() >= 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 */
+ // RasterLayer muss genau ein SimpleFeature beinhalten
+ // Ist dies nicht der Fall wird die FeatureCollection zurueckgegeben
+ if (fc == null || fc.size() != 1) {
+ return fc;
+ }
- if (f.getAttributeCount() != 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;
+ // Ist dies nicht der Fall wird die FeatureCollection zurueckgegeben
+ SimpleFeatureType ftype = fc.getSchema();
- // Objekt ist ein Raster!
- return (GridCoverage2D) f.getAttribute(1);
- } catch (Exception err) {
- LOGGER.warn(err.getMessage(), err);
- return null;
- }
- }
+ if (ftype == null || !GC_NAME.equals(ftype.getName()))
+ return fc;
- /**
- * 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>
- */
+ FeatureIterator<SimpleFeature> fIt = fc.features();
- public void dispose() {
- if (isDisposed())
- return;
+ try {
+ SimpleFeature onlyFeature = fIt.next();
+ GridCoverage2D grid = (GridCoverage2D) onlyFeature
+ .getAttribute(1);
- if (dragWaitCursorListener != null)
- this.removeMouseListener(dragWaitCursorListener);
- if (mouseWheelZoomListener != null)
- this.removeMouseWheelListener(mouseWheelZoomListener);
+ return grid;
- // Alle mapPaneListener entfernen
- mapPaneListeners.clear();
+ } finally {
+ fIt.close();
+ }
+
+ } catch (Exception err) {
+ LOGGER.warn(err.getMessage(), err);
+ return null;
+ }
+ }
- getContext().clearLayerList();
+ /**
+ * 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>
+ */
- removeAll();
- disposed = true;
- }
+ public void dispose() {
+ if (isDisposed())
+ return;
- /**
- * 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 (dragWaitCursorListener != null)
+ this.removeMouseListener(dragWaitCursorListener);
+ if (mouseWheelZoomListener != null)
+ this.removeMouseWheelListener(mouseWheelZoomListener);
- //
- // /**
- // * 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;
- // }
+ // Alle mapPaneListener entfernen
+ mapPaneListeners.clear();
- public boolean isSetWaitCursorDuringNextRepaint() {
- return setWaitCursorDuringNextRepaint;
- }
+ getContext().clearLayerList();
- /**
- * 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;
- }
+ removeAll();
+ disposed = true;
+ }
- /**
- * 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;
- }
+ /**
+ * 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;
+ }
- /**
- * 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;
- }
+ //
+ // /**
+ // * 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;
+ // }
- // /**
- // * Prueft, ob es sich bei einem Layer um ein Raster-Layer handelt.
- // * Raster-Layer zeichnen sich dadurch aus, dass die zugrunde liegende
- // * {@link FeatureCollection} nur ein SimpleFeature enthaelt, das genau ein
- // Attribut
- // * vom Type {@link org.geotools.feature.type.FeatureAttributeType} hat,
- // welches
- // * wiederum genau zwei Attribute hat:<br>
- // * Eines vom Typ {@link
- // org.opengis.spatialschema.geometry.geometry.Polygon}
- // * und eines vom Typ {@link org.opengis.coverage.grid.GridCoverage}.
- // * @param layer zu ueberpruefendes Layer
- // */
- // public static boolean isGridCoverageLayer(MapLayer layer) {
- // try {
- // FeatureCollection fc = layer.getFeatureSource().getFeatures();
- // // Layer muss genau ein SimpleFeature beinhalten
- // if ( fc == null || fc.size() != 1 )
- // return false;
- // // SimpleFeature muss genau 1 Attribut vom Typ FeatureAttributeType haben
- // SimpleFeatureType ftype = fc.getFeatureType();
- // if ( ftype == null || ftype.getAttributeCount() != 1 ||
- // !(ftype.getAttributeType(0) instanceof
- // org.geotools.feature.type.FeatureAttributeType) )
- // return false;
- // // FeatureAttribute muss genau 2 Atrribute haben
- // org.geotools.feature.type.FeatureAttributeType atype =
- // (org.geotools.feature
- // .type.FeatureAttributeType)ftype.getAttributeType(0);
- // if ( atype == null || atype.getAttributeCount() != 2 )
- // return false;
- // // Typ des ersten Attributs muss Polygon sein
- // if ( !com.vividsolutions.jts.geom.Polygon.class.isAssignableFrom(
- // atype.getAttributeType(0).getType() ) )
- // return false;
- // // Typ des zweiten Attributs muss GridCoverage sein
- // if ( !org.opengis.coverage.grid.GridCoverage.class.isAssignableFrom(
- // atype.getAttributeType(1).getType() ) )
- // return false;
- //
- // } catch (Exception err) {
- // }
- // return true;
- // }
+ public boolean isSetWaitCursorDuringNextRepaint() {
+ return setWaitCursorDuringNextRepaint;
+ }
- /**
- * Nuetzlich wenn die Componente gedruckt (z.B. wenn ein Screenshot gemacht
- * wird) wird. Dann werden wird der Hintergrund auf WEISS gesetzt.
- *
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
- * Krüger</a>
- */
- @Override
- public void print(Graphics g) {
- Color orig = getBackground();
- setBackground(Color.WHITE);
+ /**
+ * 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;
+ }
- // wrap in try/finally so that we always restore the state
- try {
- super.print(g);
- } finally {
- setBackground(orig);
- }
- }
+ /**
+ * 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;
+ }
- /**
- * Sets the mapArea to smartly present the given features. Note: The method
- * does not call {@link #repaint()} on the {@link JMapPane}.
- */
- public void zoomTo(SimpleFeature feature) {
- final MemoryFeatureCollection mfc = new MemoryFeatureCollection(feature
- .getFeatureType());
- mfc.add(feature);
- zoomTo(mfc);
- }
+ /**
+ * 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;
+ }
- /**
- * Sets the mapArea to best possibly present the given features. If only one
- * single point is given, the window is moved over the point.
- *
- * Note: The method does not call {@link #repaint()} on the {@link JMapPane} .
- *
- * @param features
- * if <code>null</code> or size==0, the function doesn nothing.
- */
- public void zoomTo(FeatureCollection<SimpleFeatureType,SimpleFeature> features) {
+ // /**
+ // * Prueft, ob es sich bei einem Layer um ein Raster-Layer handelt.
+ // * Raster-Layer zeichnen sich dadurch aus, dass die zugrunde liegende
+ // * {@link FeatureCollection} nur ein SimpleFeature enthaelt, das genau ein
+ // Attribut
+ // * vom Type {@link org.geotools.feature.type.FeatureAttributeType} hat,
+ // welches
+ // * wiederum genau zwei Attribute hat:<br>
+ // * Eines vom Typ {@link
+ // org.opengis.spatialschema.geometry.geometry.Polygon}
+ // * und eines vom Typ {@link org.opengis.coverage.grid.GridCoverage}.
+ // * @param layer zu ueberpruefendes Layer
+ // */
+ // public static boolean isGridCoverageLayer(MapLayer layer) {
+ // try {
+ // FeatureCollection fc = layer.getFeatureSource().getFeatures();
+ // // Layer muss genau ein SimpleFeature beinhalten
+ // if ( fc == null || fc.size() != 1 )
+ // return false;
+ // // SimpleFeature muss genau 1 Attribut vom Typ FeatureAttributeType haben
+ // SimpleFeatureType ftype = fc.getFeatureType();
+ // if ( ftype == null || ftype.getAttributeCount() != 1 ||
+ // !(ftype.getAttributeType(0) instanceof
+ // org.geotools.feature.type.FeatureAttributeType) )
+ // return false;
+ // // FeatureAttribute muss genau 2 Atrribute haben
+ // org.geotools.feature.type.FeatureAttributeType atype =
+ // (org.geotools.feature
+ // .type.FeatureAttributeType)ftype.getAttributeType(0);
+ // if ( atype == null || atype.getAttributeCount() != 2 )
+ // return false;
+ // // Typ des ersten Attributs muss Polygon sein
+ // if ( !com.vividsolutions.jts.geom.Polygon.class.isAssignableFrom(
+ // atype.getAttributeType(0).getType() ) )
+ // return false;
+ // // Typ des zweiten Attributs muss GridCoverage sein
+ // if ( !org.opengis.coverage.grid.GridCoverage.class.isAssignableFrom(
+ // atype.getAttributeType(1).getType() ) )
+ // return false;
+ //
+ // } catch (Exception err) {
+ // }
+ // return true;
+ // }
- CoordinateReferenceSystem mapCRS = getContext()
- .getCoordinateReferenceSystem();
- CoordinateReferenceSystem fCRS = features.getSchema()
- .getGeometryDescriptor().getCoordinateReferenceSystem();
- // if (! mapCRS.equals(fCRS)) {
- // throw new
- // RuntimeException(
- // "Projecting the features to show to the map CRS is not yet implemented."
- // );
- // }
+ /**
+ * Nuetzlich wenn die Componente gedruckt (z.B. wenn ein Screenshot gemacht
+ * wird) wird. Dann werden wird der Hintergrund auf WEISS gesetzt.
+ *
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+ * Krüger</a>
+ */
+ @Override
+ public void print(Graphics g) {
+ Color orig = getBackground();
+ setBackground(Color.WHITE);
- double width = mapArea.getWidth();
- double height = mapArea.getHeight();
- double ratio = height / width;
+ // wrap in try/finally so that we always restore the state
+ try {
+ super.print(g);
+ } finally {
+ setBackground(orig);
+ }
+ }
- if (features == null || features.size() == 0) {
- // feature count == 0 Zoom to the full extend
- return;
- } else if (features.size() == 1) {
+ /**
+ * Sets the mapArea to smartly present the given features. Note: The method
+ * does not call {@link #repaint()} on the {@link JMapPane}.
+ */
+ public void zoomTo(SimpleFeature feature) {
+ final MemoryFeatureCollection mfc = new MemoryFeatureCollection(feature
+ .getFeatureType());
+ mfc.add(feature);
+ zoomTo(mfc);
+ }
- // feature count == 1 Just move the window to the point and zoom 'a
- // bit'
- SimpleFeature singleFeature = (SimpleFeature) features.iterator().next();
+ /**
+ * Sets the mapArea to best possibly present the given features. If only one
+ * single point is given, the window is moved over the point.
+ *
+ * Note: The method does not call {@link #repaint()} on the {@link JMapPane}
+ * .
+ *
+ * @param features
+ * if <code>null</code> or size==0, the function doesn nothing.
+ */
+ public void zoomTo(
+ FeatureCollection<SimpleFeatureType, SimpleFeature> features) {
- if (((Geometry) singleFeature.getDefaultGeometry()).getCoordinates().length > 1) {
- // System.out.println("Zoomed to only pne poylgon");
- // Poly
- // TODO max width vs. height
- width = features.getBounds().getWidth() * 3;
- height = ratio * width;
- } else {
- // System.out.println("Zoomed in a bit becasue only one point");
- // width *= .9;
- // height *= .9;
- }
+ CoordinateReferenceSystem mapCRS = getContext()
+ .getCoordinateReferenceSystem();
+ CoordinateReferenceSystem fCRS = features.getSchema()
+ .getGeometryDescriptor().getCoordinateReferenceSystem();
+ // if (! mapCRS.equals(fCRS)) {
+ // throw new
+ // RuntimeException(
+ // "Projecting the features to show to the map CRS is not yet implemented."
+ // );
+ // }
- Coordinate centre = features.getBounds().centre();
- if (!mapCRS.equals(fCRS)) {
- // only to calculations if the CRS differ
- try {
- MathTransform fToMap;
- fToMap = CRS.findMathTransform(fCRS, mapCRS);
- // centre is transformed to the mapCRS
- centre = JTS.transform(centre, null, fToMap);
- } catch (FactoryException e) {
- LOGGER.error("Looking for a Math transform", e);
- } catch (TransformException e) {
- LOGGER.error("Looking for a Math transform", e);
- }
- }
+ double width = mapArea.getWidth();
+ double height = mapArea.getHeight();
+ double ratio = height / width;
- Coordinate newLeftBottom = new Coordinate(centre.x - width / 2., centre.y
- - height / 2.);
- Coordinate newTopRight = new Coordinate(centre.x + width / 2., centre.y
- + height / 2.);
+ if (features == null || features.size() == 0) {
+ // feature count == 0 Zoom to the full extend
+ return;
+ } else if (features.size() == 1) {
- Envelope newMapArea = new Envelope(newLeftBottom, newTopRight);
+ // feature count == 1 Just move the window to the point and zoom 'a
+ // bit'
+ SimpleFeature singleFeature = (SimpleFeature) features.iterator()
+ .next();
- setMapArea(newMapArea);
+ if (((Geometry) singleFeature.getDefaultGeometry())
+ .getCoordinates().length > 1) {
+ // System.out.println("Zoomed to only pne poylgon");
+ // Poly
+ // TODO max width vs. height
+ width = features.getBounds().getWidth() * 3;
+ height = ratio * width;
+ } else {
+ // System.out.println("Zoomed in a bit becasue only one point");
+ // width *= .9;
+ // height *= .9;
+ }
- } else {
- ReferencedEnvelope fBounds = features.getBounds();
+ Coordinate centre = features.getBounds().centre();
+ if (!mapCRS.equals(fCRS)) {
+ // only to calculations if the CRS differ
+ try {
+ MathTransform fToMap;
+ fToMap = CRS.findMathTransform(fCRS, mapCRS);
+ // centre is transformed to the mapCRS
+ centre = JTS.transform(centre, null, fToMap);
+ } catch (FactoryException e) {
+ LOGGER.error("Looking for a Math transform", e);
+ } catch (TransformException e) {
+ LOGGER.error("Looking for a Math transform", e);
+ }
+ }
- Envelope bounds;
- if (!mapCRS.equals(fCRS)) {
- bounds = JTSUtil.transformEnvelope(fBounds, fCRS, mapCRS);
- } else {
- bounds = fBounds;
- }
- // BB umrechnen von Layer-CRS in Map-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.);
- // Expand a bit
- bounds.expandBy(bounds.getWidth() / 6., bounds.getHeight() / 6.);
+ Envelope newMapArea = new Envelope(newLeftBottom, newTopRight);
- setMapArea(bounds);
- }
- }
+ setMapArea(newMapArea);
- /**
- * 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>();
+ } else {
+ ReferencedEnvelope fBounds = features.getBounds();
- /**
- * 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;
- }
+ 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 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);
+ // Expand a bit
+ bounds.expandBy(bounds.getWidth() / 6., bounds.getHeight() / 6.);
- /**
- * Completes the filter with its "left" argument for a concrete
- * {@link FeatureSource}. If the {@link FeatureSource FeatureSource's} CRS
- * differs from the CRS the base constraint is specified in, first a new
- * filter is created by calling
- * {@link #prepareFilter(CoordinateReferenceSystem)}.
- *
- * @param fs
- * {@link FeatureSource} the filter is adaped to
- * @return
- */
- public GeometryFilterImpl adaptFilter(FeatureSource<SimpleFeatureType,SimpleFeature> fs) {
- GeometryDescriptor geomDescr = fs.getSchema().getGeometryDescriptor();
- CoordinateReferenceSystem fsCRS = geomDescr
- .getCoordinateReferenceSystem();
- GeometryFilterImpl filter = filterCache.get(fsCRS);
- if (filter == null) {
- filter = prepareFilter(fsCRS);
- filterCache.put(fsCRS, filter);
- }
- Expression geometry = ff.property(geomDescr
- .getLocalName());
- filter.setExpression1(geometry);
- return filter;
- }
+ setMapArea(bounds);
+ }
+ }
- }
+ /**
+ * The {@link GeomFilterGenerator} prepares a {@link BinarySpatialOperator}
+ * filter for multiple use. Only the "right" argument is prepared. The
+ * "left" argument (the geometry attribute of the {@link FeatureSource} to
+ * filter) is first set on calling {@link #adaptFilter(FeatureSource)} for a
+ * specific {@link FeatureSource}. This method also takes care to recreate
+ * the filter (or its "right" argument) if the given {@link FeatureSource}
+ * has another {@link CoordinateReferenceSystem} than the base constraint.<br>
+ * The type of filter (e.g. distance or bounding box) is specified by the
+ * subclass implemenation of
+ * {@link #prepareFilter(CoordinateReferenceSystem)} .
+ *
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ */
+ private static abstract class GeomFilterGenerator {
+ /**
+ * Holds the {@link CoordinateReferenceSystem} the filter constraint
+ * bases on.
+ */
+ protected CoordinateReferenceSystem baseCRS = null;
+ /**
+ * Caches the base filter constraint for several
+ * {@link CoordinateReferenceSystem CoordinateReferenceSystems}.
+ */
+ protected Map<CoordinateReferenceSystem, GeometryFilterImpl> filterCache = new HashMap<CoordinateReferenceSystem, GeometryFilterImpl>();
- /**
- * {@link GeomFilterGenerator} for a bounding box constraint.
- *
- * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
- */
- private static class BoundingBoxFilterGenerator extends GeomFilterGenerator {
- /**
- * Holds the base constraint (bounding box {@link Envelope}) relative to the
- * {@linkplain GeomFilterGenerator#baseCRS base CRS}.
- */
- protected Envelope baseEnv = null;
+ /**
+ * Creates a new filter generator
+ *
+ * @param crs
+ * {@link CoordinateReferenceSystem} the base constraint
+ * ("right" filter argument is relative to)
+ */
+ public GeomFilterGenerator(CoordinateReferenceSystem crs) {
+ this.baseCRS = 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;
- }
+ /**
+ * 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);
- /**
- * 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;
- }
- }
+ /**
+ * Completes the filter with its "left" argument for a concrete
+ * {@link FeatureSource}. If the {@link FeatureSource FeatureSource's}
+ * CRS differs from the CRS the base constraint is specified in, first a
+ * new filter is created by calling
+ * {@link #prepareFilter(CoordinateReferenceSystem)}.
+ *
+ * @param fs
+ * {@link FeatureSource} the filter is adaped to
+ * @return
+ */
+ public GeometryFilterImpl adaptFilter(
+ FeatureSource<SimpleFeatureType, SimpleFeature> fs) {
+ GeometryDescriptor geomDescr = fs.getSchema()
+ .getGeometryDescriptor();
+ CoordinateReferenceSystem fsCRS = geomDescr
+ .getCoordinateReferenceSystem();
+ GeometryFilterImpl filter = filterCache.get(fsCRS);
+ if (filter == null) {
+ filter = prepareFilter(fsCRS);
+ filterCache.put(fsCRS, filter);
+ }
+ Expression geometry = ff.property(geomDescr.getLocalName());
+ filter.setExpression1(geometry);
+ return filter;
+ }
- /**
- * {@link GeomFilterGenerator} for a "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);
- }
+ /**
+ * {@link GeomFilterGenerator} for a bounding box constraint.
+ *
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ */
+ private static class BoundingBoxFilterGenerator extends GeomFilterGenerator {
+ /**
+ * Holds the base constraint (bounding box {@link Envelope}) relative to
+ * the {@linkplain GeomFilterGenerator#baseCRS base CRS}.
+ */
+ protected Envelope baseEnv = null;
- /**
- * Creates a new filter generator.
- *
- * @param 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);
- }
+ /**
+ * Creates a new filter generator.
+ *
+ * @param baseEnv
+ * defines the bounding box
+ * @param crs
+ * defines the CRS of the bounding box
+ */
+ public BoundingBoxFilterGenerator(Envelope baseEnv,
+ CoordinateReferenceSystem crs) {
+ super(crs);
+ this.baseEnv = baseEnv;
+ }
- /**
- * Prepares a filter with the 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);
+ /**
+ * 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;
+ }
+ }
- if (nearPoint == null || nearPoint2 == null)
- throw new RuntimeException("Unable to transform CRS from " + baseCRS
- + " to " + crs);
+ /**
+ * {@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;
- 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));
-
+ /**
+ * 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);
+ }
- return dwithinFilter;
- }
+ /**
+ * 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);
- /**
- * Allows to optionally supply the {@link JMapPane} with meta information
- * about layers. This is used (when supplied) for the algorithm that selects
- * features with a mouse click.
- *
- * @param layerID
- * @param atm
- */
- public void setAttributeMetaDataFor(String layerID,
- Map<Integer, AttributeMetaData> aMDMap) {
- attributeMetaDataMapCache.put(layerID, aMDMap);
- }
+ if (nearPoint == null || nearPoint2 == null)
+ throw new RuntimeException("Unable to transform CRS from "
+ + baseCRS + " to " + crs);
+
+ nearDist = Math.abs(nearPoint.x - nearPoint2.x);
+ }
+ // Filter fuer Point zusammenstellen
+ final Geometry geometry = FilterUtil.GEOMETRY_FAC
+ .createPoint(nearPoint);
+
+ final DWithinImpl dwithinFilter = (DWithinImpl) FilterUtil.FILTER_FAC
+ .createGeometryDistanceFilter(DWithinImpl.GEOMETRY_DWITHIN);
+ dwithinFilter.setDistance(nearDist);
+ dwithinFilter.setExpression2(FilterUtil.FILTER_FAC
+ .createLiteralExpression(geometry));
+
+ return dwithinFilter;
+ }
+
+ }
+
+ /**
+ * Allows to optionally supply the {@link JMapPane} with meta information
+ * about layers. This is used (when supplied) for the algorithm that selects
+ * features with a mouse click.
+ *
+ * @param layerID
+ * @param atm
+ */
+ public void setAttributeMetaDataFor(String layerID,
+ Map<Integer, AttributeMetaData> aMDMap) {
+ attributeMetaDataMapCache.put(layerID, aMDMap);
+ }
}
More information about the Schmitzm-commits
mailing list