/[schmitzm]/trunk/src/skrueger/geotools/XMapPane.java
ViewVC logotype

Diff of /trunk/src/skrueger/geotools/XMapPane.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 540 by alfonx, Fri Nov 20 19:34:50 2009 UTC revision 561 by mojays, Tue Nov 24 15:02:27 2009 UTC
# Line 26  import java.util.HashMap; Line 26  import java.util.HashMap;
26  import java.util.Map;  import java.util.Map;
27  import java.util.Vector;  import java.util.Vector;
28    
29    import javax.jws.soap.SOAPBinding.Style;
30  import javax.swing.Timer;  import javax.swing.Timer;
31    import javax.swing.border.Border;
32    
33  import org.apache.log4j.Logger;  import org.apache.log4j.Logger;
34  import org.geotools.feature.FeatureCollection;  import org.geotools.feature.FeatureCollection;
 import org.geotools.geometry.Envelope2D;  
35  import org.geotools.geometry.jts.JTS;  import org.geotools.geometry.jts.JTS;
36  import org.geotools.geometry.jts.ReferencedEnvelope;  import org.geotools.geometry.jts.ReferencedEnvelope;
37  import org.geotools.map.DefaultMapContext;  import org.geotools.map.DefaultMapContext;
# Line 99  public class XMapPane extends JPanel { Line 100  public class XMapPane extends JPanel {
100          private static final int IMAGETYPE = BufferedImage.TYPE_INT_RGB;          private static final int IMAGETYPE = BufferedImage.TYPE_INT_RGB;
101          private static final int IMAGETYPE_withAlpha = BufferedImage.TYPE_INT_ARGB;          private static final int IMAGETYPE_withAlpha = BufferedImage.TYPE_INT_ARGB;
102    
103          private static Logger LOGGER = Logger.getLogger(XMapPane.class);          private final static Logger LOGGER = Logger.getLogger(XMapPane.class);
104    
105          private boolean acceptsRepaintCalls = true;          private boolean acceptsRepaintCalls = true;
106    
# Line 125  public class XMapPane extends JPanel { Line 126  public class XMapPane extends JPanel {
126           * regularly and {@link #repaint()}. This {@link Timer} is stopped when all           * regularly and {@link #repaint()}. This {@link Timer} is stopped when all
127           * renderers have finished.           * renderers have finished.
128           *           *
129           * @see #INITIAL_REPAINT_DELAYAL           * @see INITIAL_REPAINT_DELAYAL
130           * @see #REPEATING_REPAINT_DELAY           * @see #REPEATING_REPAINT_DELAY
131           */           */
132          final private Timer repaintTimer;          final private Timer repaintTimer;
# Line 134  public class XMapPane extends JPanel { Line 135  public class XMapPane extends JPanel {
135           * The initial delay in milliseconds until the {@link #finalImage} is           * The initial delay in milliseconds until the {@link #finalImage} is
136           * updated the first time.           * updated the first time.
137           */           */
138          public static final int INITIAL_REPAINT_DELAY = 1000;          public static final int INITIAL_REPAINT_DELAY = 900;
139    
140          /**          /**
141           * While the {@link #bgExecuter} and {@link #localExecuter} are rendering,           * While the {@link #bgExecuter} and {@link #localExecuter} are rendering,
142           * the {@link #repaintTimer} is regularly updating the {@link #finalImage}           * the {@link #repaintTimer} is regularly updating the {@link #finalImage}
143           * with previews.           * with previews.
144           */           */
145          public static final long REPEATING_REPAINT_DELAY = 500;          public static final int REPEATING_REPAINT_DELAY = 500;
146    
147          /**          /**
148           * Default delay (milliseconds) before the map will be redrawn when resizing           * Default delay (milliseconds) before the map will be redrawn when resizing
149           * the pane. This is to avoid flickering while drag-resizing.           * the pane. This is to avoid flickering while drag-resizing.
150             *
151             * @see #resizeTimer
152           */           */
153          public static final int DEFAULT_RESIZING_PAINT_DELAY = 600;          public static final int DEFAULT_RESIZING_PAINT_DELAY = 600;
154    
155            /**
156             * This not-repeating {@link Timer} is re-started whenever the component is
157             * resized. That means => only if the component is not resizing for
158             * {@link #DEFAULT_RESIZING_PAINT_DELAY} milliseconds, does the
159             * {@link XMapPane} react.
160             */
161            private final Timer resizeTimer;
162    
163            /**
164             * Flag for no-tool.
165             */
166          public static final int NONE = -123;          public static final int NONE = -123;
167    
168          /**          /**
# Line 160  public class XMapPane extends JPanel { Line 174  public class XMapPane extends JPanel {
174          public static final int PAN = 1;          public static final int PAN = 1;
175    
176          /**          /**
177             * Flag fuer Modus "Heran zoomen".
178             *
179             * @see #setState(int)
180             * @see #setState(int)
181             */
182            public static final int ZOOM_IN = 2;
183    
184            /**
185             * Flag fuer Modus "Heraus zoomen". Nicht fuer Window-Auswahl moeglich!
186             *
187             * @see #setState(int)
188             */
189            public static final int ZOOM_OUT = 3;
190    
191            /**
192           * Flag fuer Modus "SimpleFeature-Auswahl auf allen (sichtbaren) Layern".           * Flag fuer Modus "SimpleFeature-Auswahl auf allen (sichtbaren) Layern".
193           *           *
194           * @see #setState(int)           * @see #setState(int)
# Line 183  public class XMapPane extends JPanel { Line 212  public class XMapPane extends JPanel {
212           */           */
213          public static final int SELECT_TOP = 4;          public static final int SELECT_TOP = 4;
214    
215          public static final Cursor WAIT_CURSOR = Cursor          /**
216                          .getPredefinedCursor(Cursor.WAIT_CURSOR);           * {@link Font} used to paint the wait messages into the map
217             *
218             * @see #addGadgets(Graphics2D, boolean)
219             */
220          final static Font waitFont = new Font("Arial", Font.BOLD, 30);          final static Font waitFont = new Font("Arial", Font.BOLD, 30);
         final String waitMsg = SwingUtil.R("WaitMess");  
         final static Font errorFont = new Font("Arial", Font.BOLD, 13);  
221    
222          /**          /**
223           * Flag fuer Modus "Heran zoomen".           * {@link Font} used to paint error messages into the map
224           *           *
225           * @see #setState(int)           * @see #addGadgets(Graphics2D, boolean)
          * @see #setState(int)  
226           */           */
227          public static final int ZOOM_IN = 2;          final static Font errorFont = new Font("Arial", Font.BOLD, 13);
228    
229          /**          /**
230           * Flag fuer Modus "Heraus zoomen". Nicht fuer Window-Auswahl moeglich!           * The wait message painted into the map while rendering is going on on
231             * another thread.
232           *           *
233           * @see #setState(int)           * @see #addGadgets(Graphics2D, boolean)
234           */           */
235          public static final int ZOOM_OUT = 3;          final String waitMsg = SwingUtil.R("WaitMess");
236    
237          /**          /**
238           * Konvertiert die Maus-Koordinaten (relativ zum <code>JMapPane</code>) in           * Konvertiert die Maus-Koordinaten (relativ zum <code>JMapPane</code>) in
# Line 249  public class XMapPane extends JPanel { Line 278  public class XMapPane extends JPanel {
278    
279                  @Override                  @Override
280                  public void layerAdded(final MapLayerListEvent event) {                  public void layerAdded(final MapLayerListEvent event) {
   
281                          MapLayer layer = event.getLayer();                          MapLayer layer = event.getLayer();
   
282                          layer.addMapLayerListener(bgMapLayerListener);                          layer.addMapLayerListener(bgMapLayerListener);
   
                         if (localContext.getLayers().length == 0  
                                         && bgContext.getLayers().length == 1) { // the first one and  
                                 // localContext is  
                                 // empty  
                                 if (!setMapArea(localContext.getAreaOfInterest()))  
                                         requestStartRendering();  
                                 return;  
                         }  
   
                         // We need to redraw, even in case that the mapArea didn't change  
                         // mapImageInvalid = true;  
                         // repaint();  
283                          requestStartRendering();                          requestStartRendering();
284    
285                  }                  }
286    
287                  @Override                  @Override
288                  public void layerChanged(final MapLayerListEvent event) {                  public void layerChanged(final MapLayerListEvent event) {
                         // mapImageInvalid = true;  
                         // repaint();  
289                          requestStartRendering();                          requestStartRendering();
290                  }                  }
291    
292                  @Override                  @Override
293                  public void layerMoved(final MapLayerListEvent event) {                  public void layerMoved(final MapLayerListEvent event) {
                         // mapImageInvalid = true;  
                         // repaint();  
294                          requestStartRendering();                          requestStartRendering();
295                  }                  }
296    
# Line 288  public class XMapPane extends JPanel { Line 298  public class XMapPane extends JPanel {
298                  public void layerRemoved(final MapLayerListEvent event) {                  public void layerRemoved(final MapLayerListEvent event) {
299                          if (event.getLayer() != null)                          if (event.getLayer() != null)
300                                  event.getLayer().removeMapLayerListener(bgMapLayerListener);                                  event.getLayer().removeMapLayerListener(bgMapLayerListener);
                         // mapImageInvalid = true;  
                         // repaint();  
301                          requestStartRendering();                          requestStartRendering();
302                  }                  }
303          };          };
304    
305          /**          /**
306           * compass and icon are rendered into this image           * This {@link RenderingExecutor} manages the creation and cancellation of
307             * up to one {@link Thread} for rendering the {@link #localContext}.
308           */           */
309          // protected BufferedImage gadgetsImage;          private final RenderingExecutor localExecuter = new RenderingExecutor(this);
310    
311            /**
312             * This {@link RenderingExecutor} manages the creation and cancellation of
313             * up to one {@link Thread} for rendering the {@link #bgContext}.
314             */
315          protected RenderingExecutor bgExecuter;          protected RenderingExecutor bgExecuter;
316    
317          /**          /**
318           * The Renderer for the LocalLayers uses this Image. When set to null,           * The {@link #localRenderer} for the {@link #localContext} uses this
319           * please dispose this {@link Graphics2D}           * {@link Image}.
320           */           */
321          private BufferedImage localImage;          private BufferedImage localImage;
322    
         private BufferedImage finalImage;  
323          /**          /**
324           * If # {@link #bgExecuter} is using {@link #bgRenderer} for the Background           * The {@link #bgRenderer} for the {@link #bgContext} uses this
325           * uses this Image. When set to null, please dispose the {@link Graphics2D}           * {@link Image}.
326           */           */
327          private BufferedImage bgImage;          private BufferedImage bgImage;
328    
329          /**          /**
330             * This {@link Image} is a merge of the {@link #bgImage},
331             * {@link #localImage} and {@link #addGadgets(Graphics2D, boolean)}. It is
332             * updated with {@link #updateFinalImage()} and used for painting in
333             * {@link #paintComponent(Graphics)}
334             */
335            private BufferedImage finalImage;
336    
337            /**
338           * Optionally a transparent image to paint over the map in the lower right           * Optionally a transparent image to paint over the map in the lower right
339           * corner.           * corner.
340           *           *
# Line 331  public class XMapPane extends JPanel { Line 351  public class XMapPane extends JPanel {
351    
352                  @Override                  @Override
353                  public void layerChanged(final MapLayerEvent event) {                  public void layerChanged(final MapLayerEvent event) {
                         // Change of SLD for example  
                         // mapImageInvalid = true;  
                         // repaint();  
354                          requestStartRendering();                          requestStartRendering();
355                  }                  }
356    
357                  @Override                  @Override
358                  public void layerHidden(final MapLayerEvent event) {                  public void layerHidden(final MapLayerEvent event) {
                         // mapImageInvalid = true;  
                         // repaint();  
359                          requestStartRendering();                          requestStartRendering();
360                  }                  }
361    
362                  @Override                  @Override
363                  public void layerShown(final MapLayerEvent event) {                  public void layerShown(final MapLayerEvent event) {
                         // mapImageInvalid = true;  
                         // repaint();  
364                          requestStartRendering();                          requestStartRendering();
365                  }                  }
366          };          };
# Line 384  public class XMapPane extends JPanel { Line 397  public class XMapPane extends JPanel {
397                  public void layerAdded(final MapLayerListEvent event) {                  public void layerAdded(final MapLayerListEvent event) {
398                          event.getLayer().addMapLayerListener(localMapLayerListener);                          event.getLayer().addMapLayerListener(localMapLayerListener);
399    
400                          localRenderer.setContext(getContext());                          getLocalRenderer().setContext(getMapContext());
   
                         if (localContext.getLayers().length == 1) { // the first one  
   
                                 // if the Area of Interest is unset, the LayerBounds are used  
                                 if (!setMapArea(localContext.getAreaOfInterest()))  
                                         repaint();  
   
                                 return;  
                         }  
   
                         // We need to redraw, even in case that the mapArea didn't change  
                         // mapImageInvalid = true;  
                         // repaint();  
401                          requestStartRendering();                          requestStartRendering();
402    
403                  }                  }
404    
405                  @Override                  @Override
406                  public void layerChanged(final MapLayerListEvent event) {                  public void layerChanged(final MapLayerListEvent event) {
407                          // mapImageInvalid = true;  //                      localRenderer = GTUtil.createGTRenderer();
408                          // repaint();                          getLocalRenderer().setContext(getMapContext());
                         localRenderer.setContext(getContext());  
409                          requestStartRendering();                          requestStartRendering();
410                  }                  }
411    
412                  @Override                  @Override
413                  public void layerMoved(final MapLayerListEvent event) {                  public void layerMoved(final MapLayerListEvent event) {
414                          // mapImageInvalid = true;                          getLocalRenderer().setContext(getMapContext());
                         // repaint();  
                         localRenderer.setContext(getContext());  
415                          requestStartRendering();                          requestStartRendering();
416                  }                  }
417    
# Line 422  public class XMapPane extends JPanel { Line 419  public class XMapPane extends JPanel {
419                  public void layerRemoved(final MapLayerListEvent event) {                  public void layerRemoved(final MapLayerListEvent event) {
420                          if (event.getLayer() != null)                          if (event.getLayer() != null)
421                                  event.getLayer().removeMapLayerListener(localMapLayerListener);                                  event.getLayer().removeMapLayerListener(localMapLayerListener);
422                          // mapImageInvalid = true;                          getLocalRenderer().setContext(getMapContext());
                         // repaint();  
                         localRenderer.setContext(getContext());  
423                          requestStartRendering();                          requestStartRendering();
424                  }                  }
425          };          };
426    
         private final RenderingExecutor localExecuter = new RenderingExecutor(this);  
   
427          /**          /**
428           * Listens to each layer in the local {@link MapContext} for changes and           * Listens to each layer in the local {@link MapContext} for changes and
429           * triggers repaints.           * triggers repaints.
# Line 439  public class XMapPane extends JPanel { Line 432  public class XMapPane extends JPanel {
432    
433                  @Override                  @Override
434                  public void layerChanged(final MapLayerEvent event) {                  public void layerChanged(final MapLayerEvent event) {
435                          localRenderer.setContext(getContext()); // betters for SLD changes?!                          getLocalRenderer().setContext(getMapContext()); // betters for SLD
436                          // Change of SLD for example                          // changes?!
                         // mapImageInvalid = true;  
                         // repaint();  
437                          requestStartRendering();                          requestStartRendering();
438                  }                  }
439    
440                  @Override                  @Override
441                  public void layerHidden(final MapLayerEvent event) {                  public void layerHidden(final MapLayerEvent event) {
                         // mapImageInvalid = true;  
                         // repaint();  
442                          requestStartRendering();                          requestStartRendering();
443                  }                  }
444    
445                  @Override                  @Override
446                  public void layerShown(final MapLayerEvent event) {                  public void layerShown(final MapLayerEvent event) {
                         // mapImageInvalid = true;  
                         // repaint();  
447                          requestStartRendering();                          requestStartRendering();
448                  }                  }
449          };          };
450    
451          private final GTRenderer localRenderer = GTUtil.createGTRenderer();          final private GTRenderer localRenderer = GTUtil.createGTRenderer();
452    
453          private final GTRenderer bgRenderer = GTUtil.createGTRenderer();          private final GTRenderer bgRenderer = GTUtil.createGTRenderer();
454    
# Line 482  public class XMapPane extends JPanel { Line 469  public class XMapPane extends JPanel {
469          /**          /**
470           * This color is used as the default background color when painting a map.           * This color is used as the default background color when painting a map.
471           */           */
472          private Color mapBackgroundColor = Color.WHITE;          private Color mapBackgroundColor = null;
473    
474          /**          /**
475           * A flag indicating that the shown image is invalid and needs to be           * A flag indicating that the shown image is invalid and needs to be
# Line 526  public class XMapPane extends JPanel { Line 513  public class XMapPane extends JPanel {
513           * A flag indicating, that the image size has changed and the buffered           * A flag indicating, that the image size has changed and the buffered
514           * images are not big enough any more           * images are not big enough any more
515           **/           **/
516          protected boolean paneResized = false;          protected boolean paneResized = true;
517    
518          private BufferedImage preFinalImage;          private BufferedImage preFinalImage;
519    
520          // if null, no quick preview will be shown          // ** if 0, no quick preview will be shown **/
521          private int quickPreviewHint = 0;          private int quickPreviewHint = 0;
522    
523          private Map<Object, Object> rendererHints = GTUtil          private Map<Object, Object> rendererHints = GTUtil
524                          .getDefaultGTRendererHints(localRenderer);                          .getDefaultGTRendererHints(getLocalRenderer());
525    
526            /**
527             * If set to <code>true</code>, the {@link #startRenderThreadsTimer} will
528             * start rendering {@link Thread}s
529             **/
530          private volatile Boolean requestStartRendering = false;          private volatile Boolean requestStartRendering = false;
531    
         private final Timer resizeTimer;  
   
532          /**          /**
533           * Transformation zwischen Fenster-Koordinaten und Karten-Koordinaten           * Transformation zwischen Fenster-Koordinaten und Karten-Koordinaten
534           * (lat/lon)           * (lat/lon)
# Line 576  public class XMapPane extends JPanel { Line 565  public class XMapPane extends JPanel {
565          /** Is set if a renderer has an error **/          /** Is set if a renderer has an error **/
566          protected ArrayList<Exception> renderingErrors = new ArrayList<Exception>();          protected ArrayList<Exception> renderingErrors = new ArrayList<Exception>();
567    
568          // TODO doku          /**
569             * If <code>true</code>, then rendering exceptions are rendererd into the
570             * map pane
571             **/
572            private boolean showExceptions = false;
573    
574          public XMapPane() {          public XMapPane() {
575                  this(null, null);                  this(null, null);
576          }          }
# Line 585  public class XMapPane extends JPanel { Line 579  public class XMapPane extends JPanel {
579           * full constructor extending JPanel           * full constructor extending JPanel
580           *           *
581           * @param rendererHints           * @param rendererHints
582             *            may be <code>null</code>. Otherwise a {@link Map<Object,
583             *            Object>} of {@link RenderingHints} to override the default
584             *            from {@link GTUtil#getDefaultGTRendererHints(GTRenderer)}
585           *           *
          * @param layout  
          *            - layout (probably shouldn't be set)  
          * @param isDoubleBuffered  
          *            - a Swing thing I don't really understand  
          * @param render  
          *            - what to draw the map with  
586           * @param localContext           * @param localContext
587           *            - {@link MapContext} of layer to render.           *            The main {@link MapContext} to use. If <code>null</code>, an
588             *            empty {@link DefaultMapContext} will be created.
589           */           */
590          public XMapPane(final MapContext localContext_,          public XMapPane(final MapContext localContext_,
591                          final Map<Object, Object> rendererHints) {                          final Map<Object, Object> rendererHints) {
# Line 620  public class XMapPane extends JPanel { Line 612  public class XMapPane extends JPanel {
612                   * Using a ComponentListener doesn't work because, unlike a JFrame, the                   * Using a ComponentListener doesn't work because, unlike a JFrame, the
613                   * pane receives a stream of events during drag-resizing.                   * pane receives a stream of events during drag-resizing.
614                   */                   */
615                  resizeTimer = new Timer(DEFAULT_RESIZING_PAINT_DELAY, new ActionListener() {                  resizeTimer = new Timer(DEFAULT_RESIZING_PAINT_DELAY,
616                                    new ActionListener() {
                         public void actionPerformed(final ActionEvent e) {  
                                 paneResized = true;  
   
                                 if (!isWellDefined())  
                                         return;  
617    
618                                  final Rectangle bounds = getVisibleRect();                                          public void actionPerformed(final ActionEvent e) {
619                                                    if (!isWellDefined())
620                                                            return;
621    
622                                  final Envelope geoMapArea = tranformWindowToGeo(bounds.x,                                                  LOGGER.debug("resizeTimer performed");
                                                 bounds.y, bounds.x + bounds.width, bounds.y  
                                                                 + bounds.height);  
623    
624                                  setMapArea(bestAllowedMapArea(geoMapArea));                                                  final Rectangle bounds = getVisibleRect();
625                          }                                                  //
626                  });                                                  // System.out.println("\n\ntimer performs with bounds = "
627                                                    // + bounds);
628    
629                                                    final Envelope geoMapArea = tranformWindowToGeo(
630                                                                    bounds.x, bounds.y, bounds.x + bounds.width,
631                                                                    bounds.y + bounds.height);
632    
633                                                    if (setMapArea(geoMapArea)) {
634                                                            LOGGER.debug("  maparea changed");
635                                                            paneResized = true;
636                                                    } else
637                                                            LOGGER.debug("  maparea NOT changed");
638                                            }
639                                    });
640                  resizeTimer.setRepeats(false);                  resizeTimer.setRepeats(false);
641    
642                  this.addComponentListener(new ComponentAdapter() {                  this.addComponentListener(new ComponentAdapter() {
643    
644                            private Rectangle oldVisibleRect;
645    
646                          @Override                          @Override
647                          public void componentResized(final ComponentEvent e) {                          public void componentResized(final ComponentEvent e) {
648                                  if (bgExecuter != null)  
649                                          bgExecuter.cancelTask();                                  // Seems to be called twice with the same size..
650                                  if (localExecuter != null)                                  if (oldVisibleRect != null
651                                          localExecuter.cancelTask();                                                  && oldVisibleRect.equals(getVisibleRect())) {
652                                            LOGGER.debug("skipping resize.");
653                                            return;
654                                    }
655    
656                                    LOGGER.debug("resized: " + getVisibleRect());
657                                  resizeTimer.restart();                                  resizeTimer.restart();
658                                    oldVisibleRect = getVisibleRect();
659                          }                          }
660    
661                  });                  });
# Line 654  public class XMapPane extends JPanel { Line 663  public class XMapPane extends JPanel {
663                  /*                  /*
664                   * Setting up the repaintTimer. Not started automatically.                   * Setting up the repaintTimer. Not started automatically.
665                   */                   */
666                  repaintTimer = new Timer((int) REPEATING_REPAINT_DELAY,                  repaintTimer = new Timer(REPEATING_REPAINT_DELAY, new ActionListener() {
667                                  new ActionListener() {  
668                            @Override
669                            public void actionPerformed(final ActionEvent e) {
670                                    if ((!localExecuter.isRunning())
671                                                    && (bgExecuter != null && !bgExecuter.isRunning())) {
672                                            repaintTimer.stop();
673                                    } else {
674                                            updateFinalImage();
675                                            XMapPane.this.repaint(100);
676    
677                                    }
678                            }
679                    });
680    
                                         @Override  
                                         public void actionPerformed(final ActionEvent e) {  
                                                 updateFinalImage();  
                                                 XMapPane.this.repaint();  
                                         }  
                                 });  
681                  repaintTimer.setInitialDelay(INITIAL_REPAINT_DELAY);                  repaintTimer.setInitialDelay(INITIAL_REPAINT_DELAY);
682                  repaintTimer.setRepeats(true);                  repaintTimer.setRepeats(true);
683    
# Line 680  public class XMapPane extends JPanel { Line 695  public class XMapPane extends JPanel {
695                                                  if (localExecuter.isRunning()) {                                                  if (localExecuter.isRunning()) {
696                                                          localExecuter.cancelTask();                                                          localExecuter.cancelTask();
697                                                  } else {                                                  } else {
698                                                            // Stupidly, but we have to recheck the
699                                                            setMapArea(getMapArea());
700                                                          requestStartRendering = false;                                                          requestStartRendering = false;
701                                                          startRendering();                                                          startRendering();
702                                                  }                                                  }
# Line 712  public class XMapPane extends JPanel { Line 729  public class XMapPane extends JPanel {
729           * @author <a href="mailto:[email protected]">Stefan Alfons           * @author <a href="mailto:[email protected]">Stefan Alfons
730           *         Kr&uuml;ger</a>           *         Kr&uuml;ger</a>
731           */           */
732          public Envelope bestAllowedMapArea(Envelope env) {          public ReferencedEnvelope bestAllowedMapArea(ReferencedEnvelope env) {
733                  // return env;  
734                  if (getWidth() == 0)                  if (getWidth() == 0)
735                          return env;                          return env;
736    
737                  if (env == null)                  if (env == null)
738                          return null;                          return null;
739    
# Line 765  public class XMapPane extends JPanel { Line 783  public class XMapPane extends JPanel {
783                  }                  }
784    
785                  final Envelope maxAllowedExtend = getMaxExtend();                  final Envelope maxAllowedExtend = getMaxExtend();
786    
787                  while (maxAllowedExtend != null && !maxAllowedExtend.contains(newArea)                  while (maxAllowedExtend != null && !maxAllowedExtend.contains(newArea)
788                                  && newArea != null && !newArea.isNull()                                  && newArea != null && !newArea.isNull()
789                                  && !Double.isNaN(newArea.getMinX())                                  && !Double.isNaN(newArea.getMinX())
# Line 794  public class XMapPane extends JPanel { Line 813  public class XMapPane extends JPanel {
813    
814                                          // LOGGER.debug("and fix aspect ratio");                                          // LOGGER.debug("and fix aspect ratio");
815    
816                                          newArea = JTSUtil.fixAspectRatio(getVisibleRect(), newArea,                                          newArea = JTSUtil.fixAspectRatio(getVisibleRect(),
817                                                          false);                                                          new ReferencedEnvelope(newArea, env
818                                                                            .getCoordinateReferenceSystem()), false);
819                                  }                                  }
820                          }                          }
821    
# Line 818  public class XMapPane extends JPanel { Line 838  public class XMapPane extends JPanel {
838    
839                                          // LOGGER.debug("and fix aspect ratio");                                          // LOGGER.debug("and fix aspect ratio");
840    
841                                          newArea = JTSUtil.fixAspectRatio(getVisibleRect(), newArea,                                          newArea = JTSUtil.fixAspectRatio(getVisibleRect(),
842                                                          false);                                                          new ReferencedEnvelope(newArea, env
843                                                                            .getCoordinateReferenceSystem()), false);
844                                  }                                  }
845                          }                          }
846    
# Line 844  public class XMapPane extends JPanel { Line 865  public class XMapPane extends JPanel {
865    
866                                          // LOGGER.debug("and fix aspect ratio");                                          // LOGGER.debug("and fix aspect ratio");
867    
868                                          newArea = JTSUtil.fixAspectRatio(getVisibleRect(), newArea,                                          newArea = JTSUtil.fixAspectRatio(getVisibleRect(),
869                                                          false);                                                          new ReferencedEnvelope(newArea, env
870                                                                            .getCoordinateReferenceSystem()), false);
871                                  }                                  }
872                          }                          }
873    
# Line 870  public class XMapPane extends JPanel { Line 892  public class XMapPane extends JPanel {
892    
893                                          // LOGGER.debug("and fix aspect ratio");                                          // LOGGER.debug("and fix aspect ratio");
894    
895                                          newArea = JTSUtil.fixAspectRatio(getVisibleRect(), newArea,                                          newArea = JTSUtil.fixAspectRatio(getVisibleRect(),
896                                                          false);                                                          new ReferencedEnvelope(newArea, env
897                                                                            .getCoordinateReferenceSystem()), false);
898                                  }                                  }
899                          }                          }
900                  }                  }
901    
902                  return newArea;                  return new ReferencedEnvelope(newArea, env
903                                    .getCoordinateReferenceSystem());
904          }          }
905    
906          /**          /**
# Line 904  public class XMapPane extends JPanel { Line 928  public class XMapPane extends JPanel {
928                          bgExecuter.dispose();                          bgExecuter.dispose();
929                  }                  }
930    
931                  if (localExecuter != null) {                  if (localExecuter.isRunning()) {
932                          int i = 0;                          int i = 0;
933                          localExecuter.cancelTask();                          localExecuter.cancelTask();
934                          while (i++ < 10 && localExecuter.isRunning()) {                          while (i++ < 10 && localExecuter.isRunning()) {
935                                  try {                                  try {
936                                          Thread.sleep(100);                                          Thread.sleep(200);
937                                  } catch (final InterruptedException e) {                                  } catch (final InterruptedException e) {
938                                          // TODO Auto-generated catch block                                          LOGGER
939                                          e.printStackTrace();                                                          .warn(
940                                                                            "while XMapPane we are waiting for the localExcutor to stop",
941                                                                            e);
942                                  }                                  }
943                          }                          }
944                          if (localExecuter.isRunning()) {                          if (localExecuter.isRunning()) {
945                                  System.out                                  LOGGER
946                                                  .println("BAD BAD BAD... still running the thread....");                                                  .warn("localExecutor Thread still running after 2s! Continuing anyways...");
947                          }                          }
948                          localExecuter.dispose();                          localExecuter.dispose();
949                  }                  }
950    
951                  disposeImages();                  disposeImages();
952    
953                  // LangUtil.gcTotal();                  // Remove all mapPaneListeners that have registered with us
   
                 // Alle mapPaneListener entfernen  
954                  mapPaneListeners.clear();                  mapPaneListeners.clear();
955    
956                  removeMouseMotionListener(zoomMapPaneMouseListener);                  removeMouseMotionListener(zoomMapPaneMouseListener);
957                  removeMouseListener(zoomMapPaneMouseListener);                  removeMouseListener(zoomMapPaneMouseListener);
958    
959                  if (localContext != null)                  if (localContext != null)
960                          getContext().clearLayerList();                          getMapContext().clearLayerList();
961                  if (bgContext != null)                  if (bgContext != null)
962                          getBgContext().clearLayerList();                          getBgContext().clearLayerList();
963    
# Line 979  public class XMapPane extends JPanel { Line 1003  public class XMapPane extends JPanel {
1003           */           */
1004          protected boolean drawScaledPreviewImage_Zoom(final Graphics2D graphics) {          protected boolean drawScaledPreviewImage_Zoom(final Graphics2D graphics) {
1005    
1006  //              if (1 == 1)return false;                  // if (1 == 1)return false;
1007                    
1008                  if (quickPreviewHint == 0)                  if (quickPreviewHint == 0)
1009                          return false;                          return false;
1010    
# Line 1044  public class XMapPane extends JPanel { Line 1068  public class XMapPane extends JPanel {
1068                  return bgImage;                  return bgImage;
1069          }          }
1070    
1071          public MapContext getContext() {          public MapContext getMapContext() {
1072                  if (localContext == null) {                  if (localContext == null) {
1073                          setLocalContext(new DefaultMapContext());                          setLocalContext(new DefaultMapContext());
1074                  }                  }
# Line 1091  public class XMapPane extends JPanel { Line 1115  public class XMapPane extends JPanel {
1115                          try {                          try {
1116                                  mapArea_ = localContext.getLayerBounds();                                  mapArea_ = localContext.getLayerBounds();
1117                          } catch (final IOException e) {                          } catch (final IOException e) {
1118                                  LOGGER.warn("context.getLayerBounds()", e);                                  LOGGER.warn("localContext.getLayerBounds()", e);
1119                            }
1120    
1121                            if (mapArea_ == null && bgContext != null) {
1122                                    try {
1123                                            mapArea_ = bgContext.getLayerBounds();
1124                                    } catch (final IOException e) {
1125                                            LOGGER.warn("bgContext.getLayerBounds()", e);
1126                                    }
1127                          }                          }
1128    
1129                          if (mapArea_ != null) {                          if (mapArea_ != null) {
                                 mapImageInvalid = true; /* note we need to redraw */  
                                 // setMapArea(mapArea_); // results in a loop  
1130                                  mapArea = bestAllowedMapArea(mapArea_);                                  mapArea = bestAllowedMapArea(mapArea_);
1131                                    requestStartRendering();
1132                          }                          }
1133                  }                  }
1134    
# Line 1118  public class XMapPane extends JPanel { Line 1149  public class XMapPane extends JPanel {
1149          }          }
1150    
1151          /**          /**
1152           * Returns the background {@link Color} of the map pane. Default is white.           * Returns the background {@link Color} of the map pane. If not set, the
1153             * methods looks for a parent component and will use its background color.
1154             * If no parent component is available, WHITE is returned.
1155           **/           **/
1156          public Color getMapBackgroundColor() {          public Color getMapBackgroundColor() {
1157                    if (mapBackgroundColor == null) {
1158                            if (getParent() != null)
1159                                    return getParent().getBackground();
1160                            else
1161                                    return Color.WHITE;
1162                    }
1163                  return mapBackgroundColor;                  return mapBackgroundColor;
1164          }          }
1165    
# Line 1147  public class XMapPane extends JPanel { Line 1186  public class XMapPane extends JPanel {
1186    
1187          public Envelope getMaxExtend() {          public Envelope getMaxExtend() {
1188                  if (maxExtend == null) {                  if (maxExtend == null) {
1189                          final ReferencedEnvelope layerBounds = GTUtil                          // Commented-out because it takes soo much time!
1190                                          .getVisibleLayoutBounds(localContext);                          //
1191                          if (layerBounds == null) {                          // long start = System.currentTimeMillis();
1192                                  // TODO Last fallback could be the CRS valid area                          // final ReferencedEnvelope layerBounds = GTUtil
1193                                  return null;                          // .getVisibleLayoutBounds(localContext);
1194                          }                          //                      
1195                            // LOGGER.info(
1196                          // Kartenbereich um 10% vergroessern                          // (System.currentTimeMillis()-start)+"m to get maxExtend");
1197                          return JTSUtil.fixAspectRatio(getVisibleRect(), JTSUtil                          //                      
1198                                          .expandEnvelope(layerBounds, 0.1), true);                          // if (layerBounds == null) {
1199                            // // TODO Last fallback could be the CRS valid area
1200                            // return null;
1201                            // }
1202                            //
1203                            // // Kartenbereich um 10% vergroessern
1204                            // return JTSUtil.fixAspectRatio(getVisibleRect(), JTSUtil
1205                            // .expandEnvelope(layerBounds, 0.1), true);
1206                  }                  }
1207                  return maxExtend;                  return maxExtend;
1208          }          }
# Line 1270  public class XMapPane extends JPanel { Line 1316  public class XMapPane extends JPanel {
1316           * {@link XMapPane} is visible and has bounds set.           * {@link XMapPane} is visible and has bounds set.
1317           */           */
1318          public boolean isWellDefined() {          public boolean isWellDefined() {
   
1319                  try {                  try {
1320                            if (getMapContext() == null)
                         if (getContext() == null)  
                                 return false;  
                         if (getContext().getLayerCount() <= 0)  
1321                                  return false;                                  return false;
1322                          if (getMapArea() == null)                          if (getMapContext().getLayerCount() <= 0)
1323                                  return false;                                  return false;
1324                          if (getBounds().getWidth() == 0)                          if (getVisibleRect().getWidth() == 0)
1325                                  return false;                                  return false;
1326                          if (getBounds().getHeight() == 0)                          if (getVisibleRect().getHeight() == 0)
1327                                  return false;                                  return false;
1328                            // if (getMapArea() == null)
1329                            // return false;
1330                  } catch (final Exception e) {                  } catch (final Exception e) {
1331                          return false;                          return false;
1332                  }                  }
1333                  return true;                  return true;
1334          }          }
1335    
1336            /**
1337             * Called from the listeners while the mouse is dragging, this method either
1338             * paints a translated (moved/panned) version of the image, or a rectangle.
1339             *
1340             * @param startPos
1341             *            in screen coordinates
1342             * @param lastPos
1343             *            in screen coordinates
1344             * @param event
1345             *            the {@link MouseEvent} to read the mouse buttons from
1346             */
1347          public void mouseDragged(final Point startPos, final Point lastPos,          public void mouseDragged(final Point startPos, final Point lastPos,
1348                          final MouseEvent event) {                          final MouseEvent event) {
1349    
1350                  if ((getState() == XMapPane.PAN)                  if ((getState() == XMapPane.PAN)
1351                                  || ((event.getModifiersEx() & InputEvent.BUTTON3_DOWN_MASK) != 0)) {                                  || ((event.getModifiersEx() & InputEvent.BUTTON3_DOWN_MASK) != 0)) {
1352    
1353                            // Panning needs a panning coursor
1354                          if (getCursor() != SwingUtil.PANNING_CURSOR) {                          if (getCursor() != SwingUtil.PANNING_CURSOR) {
1355                                  setCursor(SwingUtil.PANNING_CURSOR);                                  setCursor(SwingUtil.PANNING_CURSOR);
1356    
1357                                  // While panning, we deactivate the rendering. So the tasts are                                  // While panning, we deactivate the rendering. So the tasks are
1358                                  // ready to start when the panning os done.                                  // ready to start when the panning is finished.
1359                                  if (bgExecuter != null)                                  if (bgExecuter != null && bgExecuter.isRunning())
1360                                          bgExecuter.cancelTask();                                          bgExecuter.cancelTask();
1361                                  if (localExecuter != null)                                  if (localExecuter.isRunning())
1362                                          localExecuter.cancelTask();                                          localExecuter.cancelTask();
1363                          }                          }
1364    
# Line 1349  public class XMapPane extends JPanel { Line 1405  public class XMapPane extends JPanel {
1405                  } else if ((getState() == XMapPane.ZOOM_IN)                  } else if ((getState() == XMapPane.ZOOM_IN)
1406                                  || (getState() == XMapPane.ZOOM_OUT)                                  || (getState() == XMapPane.ZOOM_OUT)
1407                                  || (getState() == XMapPane.SELECT_ALL)                                  || (getState() == XMapPane.SELECT_ALL)
1408                                  || (getState() == XMapPane.SELECT_TOP)                                  || (getState() == XMapPane.SELECT_TOP)) {
                 // || (getState() == XMapPane.SELECT_ONE_FROM_TOP)  
                 ) {  
                         final Graphics graphics = getGraphics();  
1409    
1410                            // Draws a rectangle
1411                            final Graphics graphics = getGraphics();
1412                          drawRectangle(graphics, startPos, event.getPoint());                          drawRectangle(graphics, startPos, event.getPoint());
1413                            if ((lastPos.x > 0) && (lastPos.y > 0))
                         if ((lastPos.x > 0) && (lastPos.y > 0)) {  
1414                                  drawRectangle(graphics, startPos, lastPos);                                  drawRectangle(graphics, startPos, lastPos);
                         }  
   
1415                          graphics.dispose();                          graphics.dispose();
   
1416                  }                  }
   
1417          }          }
1418    
1419          /**          /**
1420           * Called by the {@link RenderingExecutor} when rendering was cancelled.           * Called by the {@link RenderingExecutor} when rendering was cancelled.
1421           */           */
1422          public void onRenderingCancelled() {          public void onRenderingCancelled() {
                 repaintTimer.stop();  
1423                  LOGGER.debug("Rendering cancelled");                  LOGGER.debug("Rendering cancelled");
1424                    repaintTimer.stop();
1425          }          }
1426    
1427          /**          /**
# Line 1379  public class XMapPane extends JPanel { Line 1429  public class XMapPane extends JPanel {
1429           * completed.           * completed.
1430           */           */
1431          public void onRenderingCompleted() {          public void onRenderingCompleted() {
1432                    LOGGER.debug("complete");
1433    
1434                  repaintTimer.stop();                  repaintTimer.stop();
1435                  updateFinalImage();  
1436                  repaint();                  // We "forget" about an exception every time we complete a rendering
1437                    // thread successfully
1438                  if (renderingErrors.size() > 0)                  if (renderingErrors.size() > 0)
1439                          renderingErrors.remove(0);                          renderingErrors.remove(0);
1440    
1441                    updateFinalImage();
1442                    repaint();
1443          }          }
1444    
1445          /**          /**
# Line 1397  public class XMapPane extends JPanel { Line 1453  public class XMapPane extends JPanel {
1453           * @see MapPaneListener#onRenderingStopped(org.geotools.swing.event.MapPaneEvent)           * @see MapPaneListener#onRenderingStopped(org.geotools.swing.event.MapPaneEvent)
1454           */           */
1455          public void onRenderingFailed(final Exception renderingError) {          public void onRenderingFailed(final Exception renderingError) {
1456                  this.renderingErrors.add(renderingError);  
1457                    // Store the exceptions so we can show it to the user:
1458                    if (!(renderingError instanceof java.lang.IllegalArgumentException && renderingError
1459                                    .getMessage().equals(
1460                                                    "Argument \"sourceCRS\" should not be null.")))
1461                            this.renderingErrors.add(renderingError);
1462                  if (renderingErrors.size() > 3)                  if (renderingErrors.size() > 3)
1463                          renderingErrors.remove(0);                          renderingErrors.remove(0);
1464    
1465                  repaintTimer.stop();                  repaintTimer.stop();
1466    
1467                  LOGGER.warn("Rendering failed", renderingError);                  LOGGER.warn("Rendering failed", renderingError);
1468                  updateFinalImage();                  updateFinalImage();
1469                  repaint();                  repaint();
1470    
1471          }          }
1472    
         public void onRenderingPending() {  
                 // LOGGER.debug("Pending rendering updates the preview...");  
                 updateFinalImage();  
                 repaint();  
         }  
   
1473          @Override          @Override
1474          protected void paintComponent(final Graphics g) {          protected void paintComponent(final Graphics g) {
                 if (!acceptsRepaintCalls)  
                         return;  
1475    
1476                  // Maybe update the cursor and maybe stop the repainting timer                  // Maybe update the cursor and maybe stop the repainting timer
1477                  updateCursor();                  updateCursor();
1478    
1479                  // super.paintComponent(g); // candidate for removal                  if (!acceptsRepaintCalls)
1480                            return;
1481    
1482                    if (!isWellDefined())
1483                            return;
1484    
1485    //               super.paintComponent(g); // candidate for removal
1486    
1487                  boolean paintedSomething = false;                  boolean paintedSomething = false;
1488    
# Line 1434  public class XMapPane extends JPanel { Line 1495  public class XMapPane extends JPanel {
1495                          // happening.                          // happening.
1496                          if (mapAreaChanged && oldMapArea != null                          if (mapAreaChanged && oldMapArea != null
1497                                          && getMapArea().intersects(oldMapArea)                                          && getMapArea().intersects(oldMapArea)
1498                                          & !getMapArea().equals(oldMapArea)) {                                          & !getMapArea().equals(oldMapArea) && !paneResized) {
1499    
1500                                  mapAreaChanged = false;                                  mapAreaChanged = false;
1501    
1502                                  if (getMapArea().covers(oldMapArea)) {                                  if (getMapArea().covers(oldMapArea)) {
1503                                          setQuickPreviewHint(ZOOM_OUT);                                          quickPreviewHint = ZOOM_OUT;
1504                                          paintedSomething = drawScaledPreviewImage_Zoom((Graphics2D) g);                                          paintedSomething = drawScaledPreviewImage_Zoom((Graphics2D) g);
1505                                  } else if (oldMapArea.covers(getMapArea())) {                                  } else if (oldMapArea.covers(getMapArea())) {
1506                                          setQuickPreviewHint(ZOOM_IN);                                          quickPreviewHint = ZOOM_IN;
1507                                          paintedSomething = drawScaledPreviewImage_Zoom((Graphics2D) g);                                          paintedSomething = drawScaledPreviewImage_Zoom((Graphics2D) g);
1508                                  }                                  }
   
1509                          }                          }
   
                         if (paneResized) {  
                                 paneResized = false;  
                                 disposeImages();  
                         }  
   
                         // Start the Threads and Timers to render the image  
                         requestStartRendering();  
   
1510                  }                  }
1511    
1512                  if (!paintedSomething) {                  if (!paintedSomething) {
# Line 1520  public class XMapPane extends JPanel { Line 1571  public class XMapPane extends JPanel {
1571          public void performPan() {          public void performPan() {
1572    
1573                  Rectangle winBounds = getVisibleRect();                  Rectangle winBounds = getVisibleRect();
1574                    
1575                  winBounds.translate(-imageOrigin.x, -imageOrigin.y);                  winBounds.translate(-imageOrigin.x, -imageOrigin.y);
1576                  final Envelope newMapArea = tranformWindowToGeo(winBounds.x,                  final Envelope newMapArea = tranformWindowToGeo(winBounds.x,
1577                                  winBounds.y, winBounds.x + winBounds.width, winBounds.y                                  winBounds.y, winBounds.x + winBounds.width, winBounds.y
# Line 1543  public class XMapPane extends JPanel { Line 1594  public class XMapPane extends JPanel {
1594                          setCursor(SwingUtil.PAN_CURSOR);                          setCursor(SwingUtil.PAN_CURSOR);
1595          }          }
1596    
         //  
         // /**  
         // * 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:[email protected]">Stefan Alfons  
         // * Kr&uuml;ger</a>  
         // */  
         // @Override  
         // public void print(final Graphics g) {  
         // final Color orig = getBackground();  
         // setBackground(Color.WHITE);  
         //  
         // // wrap in try/finally so that we always restore the state  
         // try {  
         // super.print(g);  
         // } finally {  
         // setBackground(orig);  
         // }  
         // }  
   
1597          /**          /**
1598           * Entfernt einen Listener von der Map.           * Entfernt einen Listener von der Map.
1599           *           *
# Line 1583  public class XMapPane extends JPanel { Line 1612  public class XMapPane extends JPanel {
1612          private void requestStartRendering() {          private void requestStartRendering() {
1613                  if (bgExecuter != null)                  if (bgExecuter != null)
1614                          bgExecuter.cancelTask();                          bgExecuter.cancelTask();
1615                  if (localExecuter != null)  
1616                          localExecuter.cancelTask();                  localExecuter.cancelTask();
1617    
1618                    mapImageInvalid = true;
1619                    if (paneResized) {
1620                            paneResized = false;
1621                            disposeImages();
1622                    }
1623                  requestStartRendering = true;                  requestStartRendering = true;
1624    
1625          }          }
1626    
         //  
         // /**  
         // * Berechnet die Transformation zwischen Fenster- und Karten-Koordinaten  
         // * neu.  
         // */  
         // protected void resetTransforms() {  
         // if (getMapArea() == null || getWidth() == 0 || getHeight() == 0)  
         // return;  
         //  
         // // We store the last Transform  
         // oldScreenToWorld = screenToWorld;  
         //  
         // this.screenToWorld = new AffineTransform(  
         // // Genauso wie die Fenster-Koordinaten, werden die Longitude-Koordinaten  
         // // nach rechts (Osten) hin groesser  
         // // --> positive Verschiebung  
         // getMapArea().getWidth() / getWidth(),  
         // // keine Verzerrung  
         // 0.0, 0.0,  
         // // Waehrend die Fenster-Koordinaten nach unten hin groesser  
         // // werden,  
         // // werden Latitude-Koordinaten nach Sueden hin keiner  
         // // --> negative Verschiebung  
         // -getMapArea().getHeight() / getHeight(),  
         // // Die Longitude-Koordinaten werden nach Osten hin groesser  
         // // --> obere linke Ecke des Fensters hat also den Minimalwert  
         // getMapArea().getMinX(),  
         // // Die Latitude-Koordinaten werden nach Norden hin groesser  
         // // --> obere linke Ecke des Fensters hat also den Maximalwert  
         // getMapArea().getMaxY());  
         //  
         // try {  
         // this.worldToScreen = screenToWorld.createInverse();  
         // } catch (final NoninvertibleTransformException e) {  
         // LOGGER.error(e);  
         // }  
         // }  
   
1627          /**          /**
1628           * Calculate the affine transforms used to convert between world and pixel           * Calculate the affine transforms used to convert between world and pixel
1629           * coordinates. The calculations here are very basic and assume a cartesian           * coordinates. The calculations here are very basic and assume a cartesian
# Line 1642  public class XMapPane extends JPanel { Line 1639  public class XMapPane extends JPanel {
1639           */           */
1640          private void resetTransforms() {          private void resetTransforms() {
1641                  ReferencedEnvelope refMapEnv = new ReferencedEnvelope(mapArea,                  ReferencedEnvelope refMapEnv = new ReferencedEnvelope(mapArea,
1642                                  getContext().getCoordinateReferenceSystem());                                  getMapContext().getCoordinateReferenceSystem());
1643    
1644                  Rectangle paintArea = getVisibleRect(); // NOT USE GET BOUNDS!                  // System.out
1645                                    // .println("paintArea in resetTeansofrms = " + getVisibleRect());
1646                  //                          if (!isWellDefined())
1647                  // double xscale = paintArea.getWidth() / refEnv.getWidth();                          return;
                 // double yscale = paintArea.getHeight() / refEnv.getHeight();  
                 //  
                 // double scale = Math.min(xscale, yscale);  
                 //  
                 // double xoff = refEnv.getMedian(0) * scale - paintArea.getCenterX();  
                 // double yoff = refEnv.getMedian(1) * scale + paintArea.getCenterY();  
1648    
1649                  worldToScreen = RendererUtilities.worldToScreenTransform(refMapEnv,                  worldToScreen = RendererUtilities.worldToScreenTransform(refMapEnv,
1650                                  paintArea);                                  getVisibleRect());
1651    
                 // worldToScreen = new AffineTransform(scale, 0, 0, -scale, -xoff,  
                 // yoff);  
1652                  try {                  try {
1653                          screenToWorld = worldToScreen.createInverse();                          screenToWorld = worldToScreen.createInverse();
1654    
1655                  } catch (NoninvertibleTransformException ex) {                  } catch (NoninvertibleTransformException ex) {
1656                          ex.printStackTrace();                          LOGGER
1657                                            .error("can't invert worldToScreen to get screenToWorld!",
1658                                                            ex);
1659                  }                  }
1660          }          }
1661    
# Line 1683  public class XMapPane extends JPanel { Line 1674  public class XMapPane extends JPanel {
1674                  this.bgContext = context;                  this.bgContext = context;
1675    
1676                  if (context != null) {                  if (context != null) {
1677                          setMapArea(bgContext.getAreaOfInterest());                          // setMapArea(bgContext.getAreaOfInterest());
1678    
1679                          this.bgContext.addMapLayerListListener(bgContextListener);                          this.bgContext.addMapLayerListListener(bgContextListener);
1680    
# Line 1692  public class XMapPane extends JPanel { Line 1683  public class XMapPane extends JPanel {
1683                                  mapLayer.addMapLayerListener(bgMapLayerListener);                                  mapLayer.addMapLayerListener(bgMapLayerListener);
1684                          }                          }
1685                  }                  }
1686                  mapImageInvalid = true;  
1687                  repaint();                  requestStartRendering();
1688          }          }
1689    
1690          public void setJava2dHints(final RenderingHints java2dHints) {          public void setJava2dHints(final RenderingHints java2dHints) {
1691                  this.java2dHints = java2dHints;                  this.java2dHints = java2dHints;
1692          }          }
1693    
         /**  
          *  
          * @param context  
          */  
1694          public void setLocalContext(final MapContext context) {          public void setLocalContext(final MapContext context) {
1695                  // Remove the default listener from the old context                  // Remove the default listener from the old context
1696                  if (this.localContext != null) {                  if (this.localContext != null) {
# Line 1719  public class XMapPane extends JPanel { Line 1706  public class XMapPane extends JPanel {
1706    
1707                  if (context != null) {                  if (context != null) {
1708    
1709                          setMapArea(localContext.getAreaOfInterest());                          // setMapArea(localContext.getAreaOfInterest());
1710    
1711                          localRenderer.setContext(localContext);                          getLocalRenderer().setContext(localContext);
1712    
1713                          this.localContext.addMapLayerListListener(localContextListener);                          this.localContext.addMapLayerListListener(localContextListener);
1714    
# Line 1731  public class XMapPane extends JPanel { Line 1718  public class XMapPane extends JPanel {
1718                          }                          }
1719                  }                  }
1720    
1721                    requestStartRendering();
1722    
1723            }
1724            
1725            public void setBorder(Border b) {
1726              super.setBorder(b);
1727            }
1728    
1729            /**
1730             * Triggers to repaint (fast) and re-render (slow) the JMapPane.
1731             */
1732            public void refresh() {
1733                  mapImageInvalid = true;                  mapImageInvalid = true;
1734                  repaint();                  repaint();
1735          }          }
1736    
1737            // /**
1738            // * Triggers to use new {@link GTRenderer} and refresh the map. Should be
1739            // * called after {@link Style}s have been changed because GTRenderer is
1740            // * otherwise not working well.
1741            // */
1742            // public void refreshRenderers() {
1743            // localRenderer = GTUtil.createGTRenderer();
1744            // setLocalContext(getMapContext());
1745            // mapImageInvalid = true;
1746            // repaint();
1747            // }
1748    
1749        /**
1750         * Set the new map area.
1751         * @param newMapArea
1752         * @return <code>true</code> if the mapArea has been changed and a repaint
1753         *         has been triggered.
1754         */
1755            public boolean setMapArea(final Envelope newMapArea) {
1756                    if (newMapArea == null)
1757                            return false;
1758                    if (getMapContext().getCoordinateReferenceSystem() == null)
1759                            return false;
1760                    return setMapArea(new ReferencedEnvelope(newMapArea, getMapContext()
1761                                    .getCoordinateReferenceSystem()));
1762            }
1763    
1764          /**          /**
1765         * Set the new map area.
1766           * @param newMapArea           * @param newMapArea
1767           * @return <code>true</code> if the mapArea has been changed and a repaint           * @return <code>true</code> if the mapArea has been changed and a repaint
1768           *         has been triggered.           *         has been triggered.
1769           */           */
1770          public boolean setMapArea(final Envelope newMapArea) {          public boolean setMapArea(final ReferencedEnvelope newMapArea) {
1771    
1772                  if (newMapArea == null                  if (newMapArea == null
1773                                  || bestAllowedMapArea(newMapArea).equals(mapArea)) {                                  || bestAllowedMapArea(newMapArea).equals(mapArea)) {
# Line 1795  public class XMapPane extends JPanel { Line 1822  public class XMapPane extends JPanel {
1822                          bgContext.setAreaOfInterest(mapArea, localContext                          bgContext.setAreaOfInterest(mapArea, localContext
1823                                          .getCoordinateReferenceSystem());                                          .getCoordinateReferenceSystem());
1824                  }                  }
1825                  mapImageInvalid = true;  
1826                  mapAreaChanged = true;                  mapAreaChanged = true;
                 repaint();  
1827    
1828                  LOGGER.debug("New maparea = " + mapArea);                  repaint(200); // Do not remove it!
1829    
1830                    requestStartRendering();
1831    
1832                  return true;                  return true;
1833          }          }
1834    
# Line 1809  public class XMapPane extends JPanel { Line 1838  public class XMapPane extends JPanel {
1838           * @param if <code>null</code>, white is used.           * @param if <code>null</code>, white is used.
1839           */           */
1840          public void setMapBackgroundColor(Color bgColor) {          public void setMapBackgroundColor(Color bgColor) {
                 if (bgColor == null)  
                         bgColor = Color.WHITE;  
1841                  this.mapBackgroundColor = bgColor;                  this.mapBackgroundColor = bgColor;
1842          }          }
1843    
# Line 1885  public class XMapPane extends JPanel { Line 1912  public class XMapPane extends JPanel {
1912          }          }
1913    
1914          /**          /**
1915           *           * If <code>true</code>, allow the {@link XMapPane} to process #repaint()
1916           * @param b           * requests. Otherwise the map will not paint anything and not start any
1917             * rendering {@link Thread}s.
1918           */           */
1919          public void setPainting(final boolean b) {          public void setPainting(final boolean b) {
1920                  acceptsRepaintCalls = b;                  acceptsRepaintCalls = b;
1921          }                  if (acceptsRepaintCalls == true)
1922                            repaint();
         // /**  
         // * Returns in milli seconds the time the last rending of the  
         // * {@link SelectableXMapPane} took. #Long.MAX_VALUE if the JMapPane has  
         // not  
         // * been rendered yet.  
         // */  
         // public long getLastRenderingDuration() {  
         // return lastRenderingDuration;  
         // }  
   
         public void setQuickPreviewHint(final int quickPreviewHint) {  
                 this.quickPreviewHint = quickPreviewHint;  
   
1923          }          }
1924    
1925          private void setRendererHints(final Map<Object, Object> rendererHints) {          private void setRendererHints(final Map<Object, Object> rendererHints) {
# Line 1949  public class XMapPane extends JPanel { Line 1964  public class XMapPane extends JPanel {
1964           */           */
1965          private void startRendering() {          private void startRendering() {
1966    
1967                  if (!isWellDefined())                  if (!isWellDefined() || !acceptsRepaintCalls) {
1968                            // if we are not ready to start rendering, try it again the next
1969                            // time the timer is chacking the flag.
1970                            requestStartRendering = true;
1971                          return;                          return;
1972                    }
1973    
1974                  if (bgExecuter != null) {                  if (bgExecuter != null) {
1975                          // Stop all renderers                          // Stop all renderers
1976                          bgExecuter.cancelTask();                          bgExecuter.cancelTask();
1977                  }                  }
1978    
1979                  if (localExecuter != null) {                  localExecuter.cancelTask();
                         localExecuter.cancelTask();  
                 }  
1980    
1981                  final Rectangle curPaintArea = getVisibleRect();                  final Rectangle curPaintArea = getVisibleRect();
1982    
# Line 1982  public class XMapPane extends JPanel { Line 1999  public class XMapPane extends JPanel {
1999                          // (Graphics2D) getBgImage().getGraphics(), createGTRenderer);                          // (Graphics2D) getBgImage().getGraphics(), createGTRenderer);
2000                  }                  }
2001    
2002                  if (getContext() != null) {                  if (getMapContext() != null) {
2003                          // localExecuter = new RenderingExecutor(this, 150l);                          // localExecuter = new RenderingExecutor(this, 150l);
2004                          // LOGGER.debug("starting local renderer:");                          // LOGGER.debug("starting local renderer:");
2005    
2006                          localRenderer.setJava2DHints(getJava2dHints());                          getLocalRenderer().setJava2DHints(getJava2dHints());
2007                          localRenderer.setRendererHints(getRendererHints());                          getLocalRenderer().setRendererHints(getRendererHints());
2008    
2009                          ReferencedEnvelope areaOfInterest = getMapArea();                          final boolean submitted = localExecuter.submit(getMapArea(),
                         final boolean submitted = localExecuter.submit(areaOfInterest,  
2010                                          curPaintArea, (Graphics2D) getLocalImage().getGraphics(),                                          curPaintArea, (Graphics2D) getLocalImage().getGraphics(),
2011                                          localRenderer, getWorldToScreenTransform());                                          getLocalRenderer());
2012                          if (submitted)                          if (submitted)
2013                                  repaintTimer.restart();                                  repaintTimer.restart();
2014                          else                          else
2015                                  requestStartRendering = true; // Try to start rendering again in                                  requestStartRendering = true; // Try to start rendering
2016                            // again in
2017                          // a moment                          // a moment
2018                  }                  }
2019    
# Line 2049  public class XMapPane extends JPanel { Line 2066  public class XMapPane extends JPanel {
2066                  final AffineTransform at = getScreenToWorld();                  final AffineTransform at = getScreenToWorld();
2067                  final Point2D geoO = at.transform(new Point2D.Double(ox, oy), null);                  final Point2D geoO = at.transform(new Point2D.Double(ox, oy), null);
2068                  final Point2D geoP = at.transform(new Point2D.Double(px, py), null);                  final Point2D geoP = at.transform(new Point2D.Double(px, py), null);
2069                    
2070                  // Mmmmm... don't really understand why its x,x,y,y                  // Mmmmm... don't really understand why its x,x,y,y
2071  //              return new Envelope(geoO.getX(), geoP.getX(), geoO.getY(), geoP.getY());                  // return new Envelope(geoO.getX(), geoP.getX(), geoO.getY(),
2072                  return new Envelope( new Coordinate(geoO.getX(), geoO.getY()), new Coordinate(geoP.getX(), geoP.getY()));                  // geoP.getY());
2073                    return new Envelope(new Coordinate(geoO.getX(), geoO.getY()),
2074                                    new Coordinate(geoP.getX(), geoP.getY()));
2075          }          }
2076    
2077          /**          /**
# Line 2064  public class XMapPane extends JPanel { Line 2083  public class XMapPane extends JPanel {
2083                  // if the renderers have stopped, also stop the timer that is updating                  // if the renderers have stopped, also stop the timer that is updating
2084                  // the final image                  // the final image
2085                  if (bgExecuter != null && bgExecuter.isRunning()                  if (bgExecuter != null && bgExecuter.isRunning()
2086                                  || localExecuter != null && localExecuter.isRunning()) {                                  || localExecuter.isRunning()) {
2087                          setCursor(WAIT_CURSOR);                          setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
2088                          return;                          return;
2089                  } else {                  } else {
2090                          // Allow one last rendering                          // Allow one last rendering
2091                          if (repaintTimer.isRunning()) {                          if (repaintTimer.isRunning()) {
2092                                  System.out.println("one last rendering....");                                  // System.out.println("one last rendering....");
2093                                  repaintTimer.stop();                                  repaintTimer.stop();
2094                                  updateFinalImage();                                  updateFinalImage();
2095                                  repaint();                                  repaint();
# Line 2178  public class XMapPane extends JPanel { Line 2197  public class XMapPane extends JPanel {
2197    
2198                  // If the rendering process is still running, indicate this is the image                  // If the rendering process is still running, indicate this is the image
2199                  if (forceWait || bgExecuter != null && bgExecuter.isRunning()                  if (forceWait || bgExecuter != null && bgExecuter.isRunning()
2200                                  || localExecuter != null && localExecuter.isRunning()) {                                  || localExecuter.isRunning()) {
2201    
2202                          y += 8;                          y += 8;
2203    
# Line 2197  public class XMapPane extends JPanel { Line 2216  public class XMapPane extends JPanel {
2216                          y += 24;                          y += 24;
2217                  }                  }
2218    
2219                  if (renderingErrors != null) {                  if (!renderingErrors.isEmpty() && isShowExceptions()) {
2220    
2221                          final Color c = graphics.getColor();                          final Color c = graphics.getColor();
2222                          graphics.setFont(errorFont);                          graphics.setFont(errorFont);
2223    
2224                          for (Exception ex : renderingErrors) {                          for (Exception ex : renderingErrors) {
2225    
                                 if (ex instanceof java.lang.IllegalArgumentException  
                                                 && ex.getMessage().equals(  
                                                                 "Argument \"sourceCRS\" should not be null."))  
                                         continue;  
   
2226                                  String errStr = ex.getLocalizedMessage();                                  String errStr = ex.getLocalizedMessage();
2227    
2228                                  graphics.setColor(Color.WHITE);                                  if (errStr == null)
2229                                            errStr = ex.getMessage();
2230                                    if (errStr == null)
2231                                            errStr = "unknown error: " + ex.getClass().getSimpleName();
2232    
2233                                    graphics.setColor(getMapBackgroundColor());
2234                                  graphics.drawString(errStr, 5, y);                                  graphics.drawString(errStr, 5, y);
2235                                  graphics.setColor(Color.RED);                                  graphics.setColor(Color.RED);
2236                                  graphics.drawString(errStr, 6, y + 1);                                  graphics.drawString(errStr, 6, y + 1);
# Line 2234  public class XMapPane extends JPanel { Line 2253  public class XMapPane extends JPanel {
2253          public void zoomTo(          public void zoomTo(
2254                          final FeatureCollection<SimpleFeatureType, SimpleFeature> features) {                          final FeatureCollection<SimpleFeatureType, SimpleFeature> features) {
2255    
2256                  final CoordinateReferenceSystem mapCRS = getContext()                  // if (!isWellDefined()) return;
2257    
2258                    final CoordinateReferenceSystem mapCRS = getMapContext()
2259                                  .getCoordinateReferenceSystem();                                  .getCoordinateReferenceSystem();
2260                  final CoordinateReferenceSystem fCRS = features.getSchema()                  final CoordinateReferenceSystem fCRS = features.getSchema()
2261                                  .getGeometryDescriptor().getCoordinateReferenceSystem();                                  .getGeometryDescriptor().getCoordinateReferenceSystem();
2262    
2263                  double width = mapArea.getWidth();                  ReferencedEnvelope _mapArea;
2264                  double height = mapArea.getHeight();                  if (mapArea == null)
2265                            _mapArea = features.getBounds();
2266                    else
2267                            _mapArea = getMapArea();
2268                    double width = _mapArea.getWidth();
2269                    double height = _mapArea.getHeight();
2270                  final double ratio = height / width;                  final double ratio = height / width;
2271    
2272                  if (features == null || features.size() == 0) {                  if (features == null || features.size() == 0) {
# Line 2292  public class XMapPane extends JPanel { Line 2318  public class XMapPane extends JPanel {
2318                  } else {                  } else {
2319                          final ReferencedEnvelope fBounds = features.getBounds();                          final ReferencedEnvelope fBounds = features.getBounds();
2320    
2321                          Envelope bounds;                          ReferencedEnvelope bounds;
2322                          if (!mapCRS.equals(fCRS)) {                          if (!mapCRS.equals(fCRS)) {
2323                                  bounds = JTSUtil.transformEnvelope(fBounds, fCRS, mapCRS);                                  bounds = JTSUtil.transformEnvelope(fBounds, mapCRS);
2324                          } else {                          } else {
2325                                  bounds = fBounds;                                  bounds = fBounds;
2326                          }                          }
# Line 2349  public class XMapPane extends JPanel { Line 2375  public class XMapPane extends JPanel {
2375                  newMapArea.expandBy((mapArea.getWidth() * zoomFaktor - mapArea                  newMapArea.expandBy((mapArea.getWidth() * zoomFaktor - mapArea
2376                                  .getWidth()) / 2., (mapArea.getHeight() * zoomFaktor - mapArea                                  .getWidth()) / 2., (mapArea.getHeight() * zoomFaktor - mapArea
2377                                  .getHeight()) / 2.);                                  .getHeight()) / 2.);
2378                    
2379  // TODO we actually want that                  // TODO we actually want that
2380  //              // Move the newMapArea above the new center                  // // Move the newMapArea above the new center
2381  //              newMapArea.translate(gcenter.getX() - mapArea.centre().x, gcenter                  // newMapArea.translate(gcenter.getX() - mapArea.centre().x, gcenter
2382  //                              .getY()                  // .getY()
2383  //                              - mapArea.centre().y);                  // - mapArea.centre().y);
2384    
2385                  setMapArea(newMapArea);                  setMapArea(newMapArea);
2386          }          }
2387    
2388            /**
2389             * Shall non-fatal rendering exceptions be reported in the mappane or be
2390             * dropped quitely.
2391             */
2392            public void setShowExceptions(boolean showExceptions) {
2393                    this.showExceptions = showExceptions;
2394            }
2395    
2396            /**
2397             * Shall exceptions be reported in the mappane?
2398             */
2399            public boolean isShowExceptions() {
2400                    return showExceptions;
2401            }
2402    
2403            public GTRenderer getLocalRenderer() {
2404                    return localRenderer;
2405            }
2406    
2407  }  }

Legend:
Removed from v.540  
changed lines
  Added in v.561

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26