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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 76 - (show annotations)
Tue Apr 21 21:15:25 2009 UTC (15 years, 10 months ago) by alfonx
Original Path: trunk/src/org/geotools/gui/swing/JMapPane.java
File size: 43571 byte(s)
* SelectableFeatureTablePane can be constructed with a mapPane parameter. if not null, the toolbar contains a "ZoomToSelected" button.
* Added a zoomTom(FeatureCollection) to JMapPane. This is now used in the FeatureTablePane's preview, in the Atlas search dialog, and in the ZoomToSelected button of SelectableFeatureTablePane

1 /*
2 * GeoTools - OpenSource mapping toolkit
3 * http://geotools.org
4 * (C) 2002-2006, GeoTools Project Managment Committee (PMC)
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation;
9 * version 2.1 of the License.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 */
16 package org.geotools.gui.swing;
17
18 /**
19 * <b>Xulu:<br>
20 * Code taken from gt-2.4.2 to make some changes (marked with {@code xulu}),
21 * which can not be realized in a subclass:</b>
22 * <ul>
23 * <li>{@link #getMapArea()} declared as {@code final}<li>
24 * <li>some variables declared as {@code protected}</li>
25 * <li>minimal/maximal zoom scale</li>
26 * <li>zoom in and zoom out via mouse click realized by setMapArea(..)</li>
27 * </ul>
28 * <br><br>
29 * A simple map container that is a JPanel with a map in. provides simple
30 * pan,zoom, highlight and selection The mappane stores an image of the map
31 * (drawn from the context) and an image of the slected feature(s) to speed up
32 * rendering of the highlights. Thus the whole map is only redrawn when the bbox
33 * changes, selection is only redrawn when the selected feature changes.
34 *
35 *
36 * @author Ian Turton
37 *
38 */
39
40 import java.awt.Color;
41 import java.awt.Cursor;
42 import java.awt.Graphics;
43 import java.awt.Graphics2D;
44 import java.awt.LayoutManager;
45 import java.awt.Rectangle;
46 import java.awt.event.InputEvent;
47 import java.awt.event.MouseEvent;
48 import java.awt.event.MouseListener;
49 import java.awt.event.MouseMotionListener;
50 import java.awt.image.BufferedImage;
51 import java.beans.PropertyChangeEvent;
52 import java.beans.PropertyChangeListener;
53 import java.io.IOException;
54 import java.util.Date;
55 import java.util.HashMap;
56 import java.util.Map;
57
58 import javax.swing.JPanel;
59
60 import org.apache.log4j.Logger;
61 import org.geotools.data.memory.MemoryFeatureCollection;
62 import org.geotools.feature.Feature;
63 import org.geotools.feature.FeatureCollection;
64 import org.geotools.filter.IllegalFilterException;
65 import org.geotools.geometry.jts.ReferencedEnvelope;
66 import org.geotools.gui.swing.event.HighlightChangeListener;
67 import org.geotools.gui.swing.event.HighlightChangedEvent;
68 import org.geotools.gui.swing.event.SelectionChangeListener;
69 import org.geotools.gui.swing.event.SelectionChangedEvent;
70 import org.geotools.map.DefaultMapContext;
71 import org.geotools.map.MapContext;
72 import org.geotools.map.MapLayer;
73 import org.geotools.map.event.MapLayerListEvent;
74 import org.geotools.map.event.MapLayerListListener;
75 import org.geotools.referencing.crs.DefaultGeographicCRS;
76 import org.geotools.renderer.GTRenderer;
77 import org.geotools.renderer.lite.LabelCache;
78 import org.geotools.renderer.lite.LabelCacheDefault;
79 import org.geotools.renderer.lite.StreamingRenderer;
80 import org.geotools.styling.Graphic;
81 import org.geotools.styling.LineSymbolizer;
82 import org.geotools.styling.Mark;
83 import org.geotools.styling.PointSymbolizer;
84 import org.geotools.styling.PolygonSymbolizer;
85 import org.geotools.styling.Style;
86 import org.geotools.styling.StyleBuilder;
87 import org.geotools.styling.StyleFactory;
88 import org.opengis.filter.Filter;
89 import org.opengis.filter.FilterFactory2;
90 import org.opengis.referencing.crs.CoordinateReferenceSystem;
91
92 import schmitzm.swing.SwingUtil;
93
94 import com.sun.corba.se.spi.legacy.connection.GetEndPointInfoAgainException;
95 import com.vividsolutions.jts.geom.Coordinate;
96 import com.vividsolutions.jts.geom.Envelope;
97 import com.vividsolutions.jts.geom.Geometry;
98 import com.vividsolutions.jts.geom.GeometryFactory;
99
100 public class JMapPane extends JPanel implements MouseListener,
101 MouseMotionListener, HighlightChangeListener,SelectionChangeListener, PropertyChangeListener,
102 MapLayerListListener {
103 private static Logger LOGGER = Logger.getLogger( JMapPane.class.getName() );
104 /**
105 *
106 */
107 private static final long serialVersionUID = -8647971481359690499L;
108
109 public static final int Reset = 0;
110
111 public static final int ZoomIn = 1;
112
113 public static final int ZoomOut = 2;
114
115 public static final int Pan = 3;
116
117 public static final int Select = 4;
118
119 private static final int POLYGON = 0;
120
121 private static final int LINE = 1;
122
123 private static final int POINT = 2;
124
125 /**
126 * what renders the map
127 */
128 GTRenderer renderer;
129
130 private GTRenderer highlightRenderer, selectionRenderer;
131
132 /**
133 * the map context to render
134 */
135 MapContext context;
136
137 private MapContext selectionContext;
138
139 /**
140 * the area of the map to draw
141 */
142 //xulu.sc
143 // Envelope mapArea;
144 protected Envelope mapArea;
145 //xulu.ec
146
147 /**
148 * the size of the pane last time we drew
149 */
150 //xulu.sc
151 // private Rectangle oldRect = null;
152 protected Rectangle oldRect = null;
153 //xulu.ec
154
155 /**
156 * the last map area drawn.
157 */
158 //xulu.sc
159 // private Envelope oldMapArea = null;
160 protected Envelope oldMapArea = null;
161 //xulu.ec
162
163 /**
164 * the base image of the map
165 */
166 protected BufferedImage baseImage, panningImage;
167 // SK: private BufferedImage baseImage, panningImage;
168
169 /**
170 * image of selection
171 */
172 private BufferedImage selectImage;
173
174 /**
175 * style for selected items
176 */
177 private Style selectionStyle;
178
179 /**
180 * layer that selection works on
181 */
182 private MapLayer selectionLayer;
183
184 /**
185 * layer that highlight works on
186 */
187 private MapLayer highlightLayer;
188
189 /**
190 * the object which manages highlighting
191 */
192 private HighlightManager highlightManager;
193
194 /**
195 * is highlighting on or off
196 */
197 private boolean highlight = true;
198
199 /**
200 * a factory for filters
201 */
202 FilterFactory2 ff;
203
204 /**
205 * a factory for geometries
206 */
207 GeometryFactory gf = new GeometryFactory(); // FactoryFinder.getGeometryFactory(null);
208
209 /**
210 * the collections of features to be selected or highlighted
211 */
212 FeatureCollection selection;
213
214 /**
215 * the collections of features to be selected or highlighted
216 */
217 FeatureCollection highlightFeature;
218
219 private int state = ZoomIn;
220
221 /**
222 * how far to zoom in or out
223 */
224 private double zoomFactor = 2.0;
225
226 Style lineHighlightStyle;
227
228 Style pointHighlightStyle;
229
230 Style polygonHighlightStyle;
231
232 Style polygonSelectionStyle;
233
234 Style pointSelectionStyle;
235
236 Style lineSelectionStyle;
237
238 boolean changed = true;
239
240 LabelCache labelCache = new LabelCacheDefault();
241
242 //xulu.sc
243 // private boolean reset = false;
244 protected boolean reset = false;
245 //xulu.ec
246
247 int startX;
248
249 int startY;
250
251 private boolean clickable;
252
253 int lastX;
254
255 int lastY;
256
257 private SelectionManager selectionManager;
258 //xulu.sn
259 private Double maxZoomScale = Double.MIN_VALUE;
260 private Double minZoomScale = Double.MAX_VALUE;
261 //xulu.en
262
263 // sk.sn
264 /**
265 * Wenn true, dann wurde PANNING via mouseDraged-Events begonnen. Dieses Flag wird benutzt um nur einmal den passenden Cursor nur einmal zu setzen.
266 */
267 private boolean panning_started = false;
268 // sk.en
269
270 public JMapPane() {
271 this(null, true, null, null);
272 }
273
274 /**
275 * create a basic JMapPane
276 *
277 * @param render -
278 * how to draw the map
279 * @param context -
280 * the map context to display
281 */
282 public JMapPane(GTRenderer render, MapContext context) {
283 this(null, true, render, context);
284 }
285
286 /**
287 * full constructor extending JPanel
288 *
289 * @param layout -
290 * layout (probably shouldn't be set)
291 * @param isDoubleBuffered -
292 * a Swing thing I don't really understand
293 * @param render -
294 * what to draw the map with
295 * @param context -
296 * what to draw
297 */
298 public JMapPane(LayoutManager layout, boolean isDoubleBuffered,
299 GTRenderer render, MapContext context) {
300 super(layout, isDoubleBuffered);
301
302 ff = (FilterFactory2) org.geotools.factory.CommonFactoryFinder
303 .getFilterFactory(null);
304 setRenderer(render);
305
306 setContext(context);
307
308 this.addMouseListener(this);
309 this.addMouseMotionListener(this);
310 setHighlightManager(new HighlightManager(highlightLayer));
311 setSelectionManager(new SelectionManager(selectionLayer));
312 lineHighlightStyle = setupStyle(LINE, Color.red);
313
314 pointHighlightStyle = setupStyle(POINT, Color.red);
315
316 polygonHighlightStyle = setupStyle(POLYGON, Color.red);
317
318 polygonSelectionStyle = setupStyle(POLYGON, Color.cyan);
319
320 pointSelectionStyle = setupStyle(POINT, Color.cyan);
321
322 lineSelectionStyle = setupStyle(LINE, Color.cyan);
323 setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
324 }
325
326 /**
327 * get the renderer
328 */
329 public GTRenderer getRenderer() {
330 return renderer;
331 }
332
333 public void setRenderer(GTRenderer renderer) {
334 Map hints = new HashMap();
335 if (renderer instanceof StreamingRenderer) {
336 hints = renderer.getRendererHints();
337 if (hints == null) {
338 hints = new HashMap();
339 }
340 if (hints.containsKey(StreamingRenderer.LABEL_CACHE_KEY)) {
341 labelCache = (LabelCache) hints
342 .get(StreamingRenderer.LABEL_CACHE_KEY);
343 } else {
344 hints.put(StreamingRenderer.LABEL_CACHE_KEY, labelCache);
345 }
346 renderer.setRendererHints(hints);
347 }
348
349 this.renderer = renderer;
350 this.highlightRenderer = new StreamingRenderer();
351 this.selectionRenderer = new StreamingRenderer();
352
353 hints.put("memoryPreloadingEnabled", Boolean.FALSE);
354 highlightRenderer.setRendererHints(hints);
355 selectionRenderer.setRendererHints(hints);
356
357 if (this.context != null) {
358 this.renderer.setContext(this.context);
359 }
360 }
361
362 public MapContext getContext() {
363 return context;
364 }
365
366 public void setContext(MapContext context) {
367 if (this.context != null) {
368 this.context.removeMapLayerListListener(this);
369 }
370
371 this.context = context;
372
373 if (context != null) {
374 this.context.addMapLayerListListener(this);
375 }
376
377 if (renderer != null) {
378 renderer.setContext(this.context);
379 }
380 }
381
382 public Envelope getMapArea() {
383 return mapArea;
384 }
385
386 public void setMapArea(Envelope mapArea) {
387 this.mapArea = mapArea;
388 }
389
390 public int getState() {
391 return state;
392 }
393
394 public void setState(int state) {
395 this.state = state;
396
397 // System.out.println("State: " + state);
398 }
399
400 public double getZoomFactor() {
401 return zoomFactor;
402 }
403
404 public void setZoomFactor(double zoomFactor) {
405 this.zoomFactor = zoomFactor;
406 }
407
408 public MapLayer getSelectionLayer() {
409 return selectionLayer;
410 }
411
412 public void setSelectionLayer(MapLayer selectionLayer) {
413 this.selectionLayer = selectionLayer;
414 if(selectionManager!=null) {
415 selectionManager.setSelectionLayer(selectionLayer);
416 }
417 }
418
419 public boolean isHighlight() {
420 return highlight;
421 }
422
423 public void setHighlight(boolean highlight) {
424 this.highlight = highlight;
425 }
426
427 public MapLayer getHighlightLayer() {
428 return highlightLayer;
429 }
430
431 public void setHighlightLayer(MapLayer highlightLayer) {
432 this.highlightLayer = highlightLayer;
433
434 if (highlightManager != null) {
435 highlightManager.setHighlightLayer(highlightLayer);
436 }
437 }
438
439 public HighlightManager getHighlightManager() {
440 return highlightManager;
441 }
442
443 public void setHighlightManager(HighlightManager highlightManager) {
444 this.highlightManager = highlightManager;
445 this.highlightManager.addHighlightChangeListener(this);
446 this.addMouseMotionListener(this.highlightManager);
447 }
448
449 public Style getLineHighlightStyle() {
450 return lineHighlightStyle;
451 }
452
453 public void setLineHighlightStyle(Style lineHighlightStyle) {
454 this.lineHighlightStyle = lineHighlightStyle;
455 }
456
457 public Style getLineSelectionStyle() {
458 return lineSelectionStyle;
459 }
460
461 public void setLineSelectionStyle(Style lineSelectionStyle) {
462 this.lineSelectionStyle = lineSelectionStyle;
463 }
464
465 public Style getPointHighlightStyle() {
466 return pointHighlightStyle;
467 }
468
469 public void setPointHighlightStyle(Style pointHighlightStyle) {
470 this.pointHighlightStyle = pointHighlightStyle;
471 }
472
473 public Style getPointSelectionStyle() {
474 return pointSelectionStyle;
475 }
476
477 public void setPointSelectionStyle(Style pointSelectionStyle) {
478 this.pointSelectionStyle = pointSelectionStyle;
479 }
480
481 public Style getPolygonHighlightStyle() {
482 return polygonHighlightStyle;
483 }
484
485 public void setPolygonHighlightStyle(Style polygonHighlightStyle) {
486 this.polygonHighlightStyle = polygonHighlightStyle;
487 }
488
489 public Style getPolygonSelectionStyle() {
490 return polygonSelectionStyle;
491 }
492
493 public void setPolygonSelectionStyle(Style polygonSelectionStyle) {
494 this.polygonSelectionStyle = polygonSelectionStyle;
495 }
496
497 protected void paintComponent(Graphics g) {
498 super.paintComponent(g);
499
500 if ((renderer == null) || (mapArea == null) ) {
501 return;
502 }
503
504 Rectangle r = getBounds();
505 Rectangle dr = new Rectangle(r.width, r.height);
506
507 if (!r.equals(oldRect) || reset) {
508 if(!r.equals(oldRect) && (mapArea == null)) {
509 try {
510 mapArea=context.getLayerBounds();
511 } catch (IOException e) {
512 // TODO Auto-generated catch block
513 e.printStackTrace();
514 }
515 }
516
517 if (mapArea != null){
518 /* either the viewer size has changed or we've done a reset */
519 changed = true; /* note we need to redraw */
520 reset = false; /* forget about the reset */
521 oldRect = r; /* store what the current size is */
522
523 mapArea = fixAspectRatio(r, mapArea);
524 }
525 }
526
527 if (!mapArea.equals(oldMapArea)) { /* did the map extent change? */
528 changed = true;
529 oldMapArea = mapArea;
530 // when we tell the context that the bounds have changed WMSLayers
531 // can refresh them selves
532 context.setAreaOfInterest(mapArea, context
533 .getCoordinateReferenceSystem());
534 }
535
536 if (changed) { /* if the map changed then redraw */
537 changed = false;
538 baseImage = new BufferedImage(dr.width, dr.height,
539 BufferedImage.TYPE_INT_ARGB);
540
541 Graphics2D ig = baseImage.createGraphics();
542 /* System.out.println("rendering"); */
543 renderer.setContext(context);
544 labelCache.clear(); // work around anoying labelcache bug
545
546
547 // draw the map
548 renderer.paint((Graphics2D) ig, dr, mapArea);
549
550 // TODO , nur machen, wenn panning beginnt
551 panningImage = new BufferedImage(dr.width, dr.height,
552 BufferedImage.TYPE_INT_RGB);
553
554 }
555
556 ((Graphics2D) g).drawImage(baseImage, 0, 0, this);
557
558 if ((selection != null) && (selection.size() > 0)) {
559 // paint selection
560
561 String type = selectionLayer.getFeatureSource().getSchema()
562 .getDefaultGeometry().getType().getName();
563 /*String type = selection.getDefaultGeometry().getGeometryType();*/
564 /*System.out.println(type);*/
565 if (type == null)
566 type = "polygon";
567
568 /* String type = "point"; */
569
570 if (type.toLowerCase().endsWith("polygon")) {
571 selectionStyle = polygonSelectionStyle;
572 } else if (type.toLowerCase().endsWith("point")) {
573 selectionStyle = pointSelectionStyle;
574 } else if (type.toLowerCase().endsWith("line")) {
575 selectionStyle = lineSelectionStyle;
576 }
577
578 selectionContext = new DefaultMapContext(DefaultGeographicCRS.WGS84);
579
580 selectionContext.addLayer(selection, selectionStyle);
581 selectionRenderer.setContext(selectionContext);
582
583 selectImage = new BufferedImage(dr.width, dr.height,
584 BufferedImage.TYPE_INT_ARGB);
585
586 Graphics2D ig = selectImage.createGraphics();
587 /* System.out.println("rendering selection"); */
588 selectionRenderer.paint((Graphics2D) ig, dr, mapArea);
589
590 ((Graphics2D) g).drawImage(selectImage, 0, 0, this);
591 }
592
593 if (highlight && (highlightFeature != null)
594 && (highlightFeature.size() > 0)) {
595 /*
596 * String type = selection.getDefaultGeometry().getGeometryType();
597 * System.out.println(type); if(type==null) type="polygon";
598 */
599 String type = highlightLayer.getFeatureSource().getSchema()
600 .getDefaultGeometry().getType().getName();
601 /*String type = selection.getDefaultGeometry().getGeometryType();*/
602 //System.out.println(type);
603 if (type == null)
604 type = "polygon";
605
606 /* String type = "point"; */
607 Style highlightStyle = null;
608 if (type.toLowerCase().endsWith("polygon")) {
609 highlightStyle = polygonHighlightStyle;
610 } else if (type.toLowerCase().endsWith("point")) {
611 highlightStyle = pointHighlightStyle;
612 } else if (type.toLowerCase().endsWith("line")) {
613 highlightStyle = lineHighlightStyle;
614 }
615
616
617
618
619 MapContext highlightContext = new DefaultMapContext(
620 DefaultGeographicCRS.WGS84);
621
622 highlightContext.addLayer(highlightFeature, highlightStyle);
623 highlightRenderer.setContext(highlightContext);
624
625 /* System.out.println("rendering highlight"); */
626 highlightRenderer.paint((Graphics2D) g, dr, mapArea);
627 }
628 }
629
630 private Envelope fixAspectRatio(Rectangle r, Envelope mapArea) {
631
632 double mapWidth = mapArea.getWidth(); /* get the extent of the map */
633 double mapHeight = mapArea.getHeight();
634 double scaleX = r.getWidth() / mapArea.getWidth(); /*
635 * calculate the new
636 * scale
637 */
638
639 double scaleY = r.getHeight() / mapArea.getHeight();
640 double scale = 1.0; // stupid compiler!
641
642 if (scaleX < scaleY) { /* pick the smaller scale */
643 scale = scaleX;
644 } else {
645 scale = scaleY;
646 }
647
648 /* calculate the difference in width and height of the new extent */
649 double deltaX = /* Math.abs */((r.getWidth() / scale) - mapWidth);
650 double deltaY = /* Math.abs */((r.getHeight() / scale) - mapHeight);
651
652 /*
653 * System.out.println("delta x " + deltaX); System.out.println("delta y " +
654 * deltaY);
655 */
656
657 /* create the new extent */
658 Coordinate ll = new Coordinate(mapArea.getMinX() - (deltaX / 2.0),
659 mapArea.getMinY() - (deltaY / 2.0));
660 Coordinate ur = new Coordinate(mapArea.getMaxX() + (deltaX / 2.0),
661 mapArea.getMaxY() + (deltaY / 2.0));
662
663 return new Envelope(ll, ur);
664 }
665
666 public void doSelection(double x, double y, MapLayer layer) {
667
668 Geometry geometry = gf.createPoint(new Coordinate(x, y));
669
670 // org.opengis.geometry.Geometry geometry = new Point();
671
672 findFeature(geometry, layer);
673
674 }
675
676 /**
677 * @param geometry -
678 * a geometry to construct the filter with
679 * @param i -
680 * the index of the layer to search
681 * @throws IndexOutOfBoundsException
682 */
683 private void findFeature(Geometry geometry, MapLayer layer)
684 throws IndexOutOfBoundsException {
685 org.opengis.filter.spatial.BinarySpatialOperator f = null;
686
687
688 if ((context == null) || (layer==null)) {
689 return ;
690 }
691
692
693
694 try {
695 String name = layer.getFeatureSource().getSchema()
696 .getDefaultGeometry().getName();
697
698 if (name == "") {
699 name = "the_geom";
700 }
701
702 try {
703 f = ff.contains(ff.property(name), ff.literal(geometry));
704 if(selectionManager!=null) {
705 System.out.println("selection changed");
706 selectionManager.selectionChanged(this, f);
707
708 }
709 } catch (IllegalFilterException e) {
710 // TODO Auto-generated catch block
711 e.printStackTrace();
712 }
713
714 /*// f.addLeftGeometry(ff.property(name));
715 // System.out.println("looking with " + f);
716 FeatureCollection fc = layer.getFeatureSource().getFeatures(f);
717
718
719
720 if (fcol == null) {
721 fcol = fc;
722
723 // here we should set the defaultgeom type
724 } else {
725 fcol.addAll(fc);
726 }*/
727
728 /*
729 * GeometryAttributeType gat =
730 * layer.getFeatureSource().getSchema().getDefaultGeometry();
731 * fcol.setDefaultGeometry((Geometry)gat.createDefaultValue());
732 */
733
734 /*
735 * Iterator fi = fc.iterator(); while (fi.hasNext()) { Feature feat =
736 * (Feature) fi.next(); System.out.println("selected " +
737 * feat.getAttribute("STATE_NAME")); }
738 */
739 } catch (IllegalFilterException e) {
740 // TODO Auto-generated catch block
741 e.printStackTrace();
742 }
743 return ;
744 }
745
746 public void mouseClicked(MouseEvent e) {
747 // System.out.println("before area "+mapArea+"\nw:"+mapArea.getWidth()+"
748 // h:"+mapArea.getHeight());
749 Rectangle bounds = this.getBounds();
750 double x = (double) (e.getX());
751 double y = (double) (e.getY());
752 double width = mapArea.getWidth();
753 double height = mapArea.getHeight();
754 //xulu.sc
755 // double width2 = mapArea.getWidth() / 2.0;
756 // double height2 = mapArea.getHeight() / 2.0;
757 double width2 = width / 2.0;
758 double height2 = height / 2.0;
759 //xulu.ec
760 double mapX = ((x * width) / (double) bounds.width) + mapArea.getMinX();
761 double mapY = (((bounds.getHeight() - y) * height) / (double) bounds.height)
762 + mapArea.getMinY();
763
764 /*
765 * System.out.println(""+x+"->"+mapX);
766 * System.out.println(""+y+"->"+mapY);
767 */
768
769 /*
770 * Coordinate ll = new Coordinate(mapArea.getMinX(), mapArea.getMinY());
771 * Coordinate ur = new Coordinate(mapArea.getMaxX(), mapArea.getMaxY());
772 */
773 double zlevel = 1.0;
774
775 switch (state) {
776 case Pan:
777 zlevel = 1.0;
778 //xulu.sc SK: return here.. a mouselistener is maanaging the PANNING
779 // break;
780 return;
781 //xulu.ec
782 case ZoomIn:
783 zlevel = zoomFactor;
784
785 break;
786
787 case ZoomOut:
788 zlevel = 1.0 / zoomFactor;
789
790 break;
791
792 case Select:
793 doSelection(mapX, mapY, selectionLayer);
794
795
796 return;
797
798 default:
799 return;
800 }
801
802 Coordinate ll = new Coordinate(mapX - (width2 / zlevel), mapY
803 - (height2 / zlevel));
804 Coordinate ur = new Coordinate(mapX + (width2 / zlevel), mapY
805 + (height2 / zlevel));
806 //xulu.sc SK: Check for min/max scale
807 // mapArea = new Envelope(ll, ur);
808 final Envelope newMapArea = new Envelope(ll, ur);
809 setMapArea( bestAllowedMapArea( newMapArea ) );
810 //xulu.ec
811
812 // System.out.println("after area "+mapArea+"\nw:"+mapArea.getWidth()+"
813 // h:"+mapArea.getHeight());
814 repaint();
815 }
816
817 public void mouseEntered(MouseEvent e) {
818 }
819
820 public void mouseExited(MouseEvent e) {
821 }
822
823 public void mousePressed(MouseEvent e) {
824 startX = e.getX();
825 startY = e.getY();
826 lastX = 0;
827 lastY = 0;
828 }
829
830 public void mouseReleased(MouseEvent e) {
831 int endX = e.getX();
832 int endY = e.getY();
833
834 processDrag(startX, startY, endX, endY, e);
835 lastX = 0;
836 lastY = 0;
837
838 /**
839 * Es wird nicht (mehr) gepannt!
840 */
841 panning_started = false;
842 }
843
844 public void mouseDragged(MouseEvent e) {
845 Graphics graphics = this.getGraphics();
846 int x = e.getX();
847 int y = e.getY();
848
849
850 if ( (state == JMapPane.Pan) || ((e.getModifiersEx() & InputEvent.BUTTON3_DOWN_MASK) != 0)) {
851 /**
852 * SK:
853 * Der Cursor wird auf PANNING gesetzt.
854 */
855 if (panning_started == false){
856 panning_started = true;
857 setCursor( SwingUtil.PANNING_CURSOR );
858 }
859
860
861 // move the image with the mouse
862 if ((lastX > 0) && (lastY > 0)) {
863 int dx = lastX - startX;
864 int dy = lastY - startY;
865 // System.out.println("translate "+dx+","+dy);
866 final Graphics2D g2 = panningImage.createGraphics();
867 g2.setBackground( new Color(240,240,240) ); //TODO richtige farbe? am besten vom L&F die hintergrundfarbe auslesen...
868 g2.clearRect(0, 0, this.getWidth(), this.getHeight());
869 g2.drawImage(baseImage, dx, dy, this);
870 graphics.drawImage(panningImage, 0, 0, this);
871 }
872
873 lastX = x;
874 lastY = y;
875 } else
876
877 if ((state == JMapPane.ZoomIn) || (state == JMapPane.ZoomOut)) {
878
879
880 graphics.setXORMode(Color.WHITE);
881
882 if ((lastX > 0) && (lastY > 0)) {
883 drawRectangle(graphics);
884 }
885
886 // draw new box
887 lastX = x;
888 lastY = y;
889 drawRectangle(graphics);
890 } else if (state == JMapPane.Select && selectionLayer != null) {
891
892 // construct a new bbox filter
893 Rectangle bounds = this.getBounds();
894
895 double mapWidth = mapArea.getWidth();
896 double mapHeight = mapArea.getHeight();
897
898 double x1 = ((this.startX * mapWidth) / (double) bounds.width)
899 + mapArea.getMinX();
900 double y1 = (((bounds.getHeight() - this.startY) * mapHeight) / (double) bounds.height)
901 + mapArea.getMinY();
902 double x2 = ((x * mapWidth) / (double) bounds.width)
903 + mapArea.getMinX();
904 double y2 = (((bounds.getHeight() - y) * mapHeight) / (double) bounds.height)
905 + mapArea.getMinY();
906 double left = Math.min(x1, x2);
907 double right = Math.max(x1, x2);
908 double bottom = Math.min(y1, y2);
909 double top = Math.max(y1, y2);
910
911
912 String name = selectionLayer.getFeatureSource().getSchema()
913 .getDefaultGeometry().getName();
914
915 if (name == "") {
916 name = "the_geom";
917 }
918 Filter bb = ff.bbox(ff.property(name), left, bottom, right, top,
919 getContext().getCoordinateReferenceSystem().toString());
920 if(selectionManager!=null) {
921 selectionManager.selectionChanged(this, bb);
922 }
923
924 graphics.setXORMode(Color.green);
925
926 /*
927 * if ((lastX > 0) && (lastY > 0)) { drawRectangle(graphics); }
928 */
929
930 // draw new box
931 lastX = x;
932 lastY = y;
933 drawRectangle(graphics);
934 }
935
936 }
937
938 // sk.cs
939 // private void processDrag(int x1, int y1, int x2, int y2) {
940 // sk.ce
941 protected void processDrag(int x1, int y1, int x2, int y2, MouseEvent e) {
942
943 /****
944 * If no layer is availabe we dont want a NullPointerException
945 */
946 if (mapArea == null) return;
947
948 // System.out.println("processing drag from " + x1 + "," + y1 + " -> "
949 // + x2 + "," + y2);
950 if ((x1 == x2) && (y1 == y2)) {
951 if (isClickable()) {
952 mouseClicked(new MouseEvent(this, 0, new Date().getTime(), 0,
953 x1, y1, y2, false));
954 }
955
956 return;
957 }
958
959 Rectangle bounds = this.getBounds();
960
961 double mapWidth = mapArea.getWidth();
962 double mapHeight = mapArea.getHeight();
963
964 double startX = ((x1 * mapWidth) / (double) bounds.width)
965 + mapArea.getMinX();
966 double startY = (((bounds.getHeight() - y1) * mapHeight) / (double) bounds.height)
967 + mapArea.getMinY();
968 double endX = ((x2 * mapWidth) / (double) bounds.width)
969 + mapArea.getMinX();
970 double endY = (((bounds.getHeight() - y2) * mapHeight) / (double) bounds.height)
971 + mapArea.getMinY();
972
973 if ( (state == JMapPane.Pan) || (e.getButton()== MouseEvent.BUTTON3)) {
974 // move the image with the mouse
975 // calculate X offsets from start point to the end Point
976 double deltaX1 = endX - startX;
977
978 // System.out.println("deltaX " + deltaX1);
979 // new edges
980 double left = mapArea.getMinX() - deltaX1;
981 double right = mapArea.getMaxX() - deltaX1;
982
983 // now for Y
984 double deltaY1 = endY - startY;
985
986 // System.out.println("deltaY " + deltaY1);
987 double bottom = mapArea.getMinY() - deltaY1;
988 double top = mapArea.getMaxY() - deltaY1;
989 Coordinate ll = new Coordinate(left, bottom);
990 Coordinate ur = new Coordinate(right, top);
991 //xulu.sc
992 // mapArea = fixAspectRatio(this.getBounds(), new Envelope(ll, ur));
993 setMapArea( fixAspectRatio(this.getBounds(), new Envelope(ll, ur)) );
994 //xulu.ec
995 } else if (state == JMapPane.ZoomIn) {
996
997
998 // Zu kleine Flächen sollen nicht gezoomt werden.
999 //sk.bc
1000 if ( (Math.abs(x1-x2) * Math.abs(y2-y1) )<100 ) return;
1001 // sk.ec
1002
1003 drawRectangle(this.getGraphics());
1004 // make the dragged rectangle (in map coords) the new BBOX
1005 double left = Math.min(startX, endX);
1006 double right = Math.max(startX, endX);
1007 double bottom = Math.min(startY, endY);
1008 double top = Math.max(startY, endY);
1009 Coordinate ll = new Coordinate(left, bottom);
1010 Coordinate ur = new Coordinate(right, top);
1011 //xulu.sc
1012 // mapArea = fixAspectRatio(this.getBounds(), new Envelope(ll, ur));
1013 setMapArea( fixAspectRatio(this.getBounds(), new Envelope(ll, ur)) );
1014 //xulu.ec
1015 } else if (state == JMapPane.ZoomOut) {
1016 drawRectangle(this.getGraphics());
1017
1018 // make the dragged rectangle in screen coords the new map size?
1019 double left = Math.min(startX, endX);
1020 double right = Math.max(startX, endX);
1021 double bottom = Math.min(startY, endY);
1022 double top = Math.max(startY, endY);
1023 double nWidth = (mapWidth * mapWidth) / (right - left);
1024 double nHeight = (mapHeight * mapHeight) / (top - bottom);
1025 double deltaX1 = left - mapArea.getMinX();
1026 double nDeltaX1 = (deltaX1 * nWidth) / mapWidth;
1027 double deltaY1 = bottom - mapArea.getMinY();
1028 double nDeltaY1 = (deltaY1 * nHeight) / mapHeight;
1029 Coordinate ll = new Coordinate(mapArea.getMinX() - nDeltaX1,
1030 mapArea.getMinY() - nDeltaY1);
1031 double deltaX2 = mapArea.getMaxX() - right;
1032 double nDeltaX2 = (deltaX2 * nWidth) / mapWidth;
1033 double deltaY2 = mapArea.getMaxY() - top;
1034 double nDeltaY2 = (deltaY2 * nHeight) / mapHeight;
1035 Coordinate ur = new Coordinate(mapArea.getMaxX() + nDeltaX2,
1036 mapArea.getMaxY() + nDeltaY2);
1037 //xulu.sc
1038 // mapArea = fixAspectRatio(this.getBounds(), new Envelope(ll, ur));
1039 setMapArea( fixAspectRatio(this.getBounds(), new Envelope(ll, ur)) );
1040 //xulu.ec
1041 } else if (state == JMapPane.Select && selectionLayer !=null) {
1042 double left = Math.min(startX, endX);
1043 double right = Math.max(startX, endX);
1044 double bottom = Math.min(startY, endY);
1045 double top = Math.max(startY, endY);
1046
1047
1048 String name = selectionLayer.getFeatureSource().getSchema()
1049 .getDefaultGeometry().getLocalName();
1050
1051 if (name == "") {
1052 name = "the_geom";
1053 }
1054 Filter bb = ff.bbox(ff.property(name), left, bottom, right, top,
1055 getContext().getCoordinateReferenceSystem().toString());
1056 //System.out.println(bb.toString());
1057 if(selectionManager!=null) {
1058 selectionManager.selectionChanged(this, bb);
1059 }
1060 /*FeatureCollection fc;
1061 selection = null;
1062 try {
1063 fc = selectionLayer.getFeatureSource().getFeatures(bb);
1064 selection = fc;
1065 } catch (IOException e) {
1066 e.printStackTrace();
1067 }
1068 */
1069 }
1070
1071 //xulu.so
1072 // setMapArea(mapArea);
1073 //xulu.eo
1074 repaint();
1075 }
1076
1077 private boolean isClickable() {
1078 return clickable;
1079 }
1080
1081 private org.geotools.styling.Style setupStyle(int type, Color color) {
1082 StyleFactory sf = org.geotools.factory.CommonFactoryFinder
1083 .getStyleFactory(null);
1084 StyleBuilder sb = new StyleBuilder();
1085
1086 org.geotools.styling.Style s = sf.createStyle();
1087 s.setTitle("selection");
1088
1089 // TODO parameterise the color
1090 PolygonSymbolizer ps = sb.createPolygonSymbolizer(color);
1091 ps.setStroke(sb.createStroke(color));
1092
1093 LineSymbolizer ls = sb.createLineSymbolizer(color);
1094 Graphic h = sb.createGraphic();
1095 h.setMarks(new Mark[] { sb.createMark("square", color) });
1096
1097 PointSymbolizer pts = sb.createPointSymbolizer(h);
1098
1099 // Rule r = sb.createRule(new Symbolizer[]{ps,ls,pts});
1100 switch (type) {
1101 case POLYGON:
1102 s = sb.createStyle(ps);
1103
1104 break;
1105
1106 case POINT:
1107 s = sb.createStyle(pts);
1108
1109 break;
1110
1111 case LINE:
1112 s = sb.createStyle(ls);
1113 }
1114
1115 return s;
1116 }
1117
1118 public void highlightChanged(HighlightChangedEvent e) {
1119 org.opengis.filter.Filter f = e.getFilter();
1120
1121 try {
1122 highlightFeature = highlightLayer.getFeatureSource().getFeatures(f);
1123 } catch (IOException e1) {
1124 // TODO Auto-generated catch block
1125 e1.printStackTrace();
1126 }
1127
1128 repaint();
1129 }
1130
1131 public void propertyChange(PropertyChangeEvent evt) {
1132 String prop = evt.getPropertyName();
1133
1134 if (prop.equalsIgnoreCase("crs")) {
1135 context.setAreaOfInterest(context.getAreaOfInterest(),
1136 (CoordinateReferenceSystem) evt.getNewValue());
1137 }
1138 }
1139
1140 public boolean isReset() {
1141 return reset;
1142 }
1143
1144 public void setReset(boolean reset) {
1145 this.reset = reset;
1146 }
1147
1148 public void layerAdded(MapLayerListEvent event) {
1149 changed = true;
1150
1151 if (context.getLayers().length == 1) { // the first one
1152
1153 try {
1154 //xulu.sc
1155 // mapArea = context.getLayerBounds();
1156 mapArea = context.getAreaOfInterest();
1157 if ( mapArea == null )
1158 mapArea = context.getLayerBounds();
1159 //xulu.ec
1160 } catch (IOException e) {
1161 // TODO Auto-generated catch block
1162 e.printStackTrace();
1163 }
1164
1165 reset = true;
1166 }
1167
1168 repaint();
1169 }
1170
1171 public void layerRemoved(MapLayerListEvent event) {
1172 changed = true;
1173 repaint();
1174 }
1175
1176 public void layerChanged(MapLayerListEvent event) {
1177 changed = true;
1178 // System.out.println("layer changed - repaint");
1179 repaint();
1180 }
1181
1182 public void layerMoved(MapLayerListEvent event) {
1183 changed = true;
1184 repaint();
1185 }
1186
1187 protected void drawRectangle(Graphics graphics) {
1188 // undraw last box/draw new box
1189 int left = Math.min(startX, lastX);
1190 int right = Math.max(startX, lastX);
1191 int top = Math.max(startY, lastY);
1192 int bottom = Math.min(startY, lastY);
1193 int width = right - left;
1194 int height = top - bottom;
1195 // System.out.println("drawing rect("+left+","+bottom+","+ width+","+
1196 // height+")");
1197 graphics.drawRect(left, bottom, width, height);
1198 }
1199
1200 /**
1201 * if clickable is set to true then a single click on the map pane will zoom
1202 * or pan the map.
1203 *
1204 * @param clickable
1205 */
1206 public void setClickable(boolean clickable) {
1207 this.clickable = clickable;
1208 }
1209
1210 public void mouseMoved(MouseEvent e) {
1211 }
1212
1213 public FeatureCollection getSelection() {
1214 return selection;
1215 }
1216
1217 public void setSelection(FeatureCollection selection) {
1218 this.selection = selection;
1219 repaint();
1220 }
1221
1222 /* (non-Javadoc)
1223 * @see org.geotools.gui.swing.event.SelectionChangeListener#selectionChanged(org.geotools.gui.swing.event.SelectionChangedEvent)
1224 */
1225 public void selectionChanged(SelectionChangedEvent e) {
1226
1227 try {
1228 selection = selectionLayer.getFeatureSource().getFeatures(e.getFilter());
1229 repaint();
1230 } catch (IOException e1) {
1231 e1.printStackTrace();
1232 }
1233 }
1234
1235 public SelectionManager getSelectionManager() {
1236 return selectionManager;
1237 }
1238
1239 public void setSelectionManager(SelectionManager selectionManager) {
1240 this.selectionManager = selectionManager;
1241 this.selectionManager.addSelectionChangeListener(this);
1242
1243 }
1244
1245
1246 //xulu.sn
1247 /**
1248 * Korrigiert den {@link Envelope} aka {@code mapArea} auf die beste
1249 * erlaubte Flaeche damit die Massstabsbeschaenkungen noch eingehalten
1250 * werden, FALLS der uebergeben Envelope nicht schon gueltig sein sollte.<br/>
1251 * Since 21. April 09: Before thecalculation starts, the aspect ratio is
1252 * corrected. This change implies, that setMapArea() will most of the time
1253 * not allow setting to a wrong aspectRatio.
1254 *
1255 * @author <a href="mailto:[email protected]">Stefan Alfons
1256 * Kr&uuml;ger</a>
1257 */
1258 public Envelope bestAllowedMapArea(Envelope env) {
1259 if (getWidth() == 0)
1260 return env;
1261 if (env == null)
1262 return env;
1263
1264 /**
1265 * Correct the aspect Ratio before we check the rest. Otherwise we might easily fail.
1266 */
1267 env = fixAspectRatio(this.getBounds(), env);
1268
1269 double scale = env.getWidth() / getWidth();
1270 double centerX = env.getMinX() + env.getWidth() / 2.;
1271 double centerY = env.getMinY() + env.getHeight() / 2.;
1272 double newWidth2;
1273 double newHeight2;
1274 if (scale < getMaxZoomScale()) {
1275 // ****************************************************************************
1276 // Wir zoomen weiter rein als erlaubt => Anpassen des envelope
1277 // ****************************************************************************
1278 newWidth2 = getMaxZoomScale() * getWidth() / 2.;
1279 newHeight2 = getMaxZoomScale() * getHeight() / 2.;
1280 } else if (scale > getMinZoomScale()) {
1281 // ****************************************************************************
1282 // Wir zoomen weiter raus als erlaubt => Anpassen des envelope
1283 // ****************************************************************************
1284 newWidth2 = getMinZoomScale() * getWidth() / 2.;
1285 newHeight2 = getMinZoomScale() * getHeight() / 2.;
1286 } else {
1287 // ****************************************************************************
1288 // Die mapArea / der Envelope ist ist gueltig! Keine Aenderungen
1289 // ****************************************************************************
1290 return env;
1291 }
1292
1293 Coordinate ll = new Coordinate(centerX - newWidth2, centerY
1294 - newHeight2);
1295 Coordinate ur = new Coordinate(centerX + newWidth2, centerY
1296 + newHeight2);
1297
1298 return new Envelope(ll, ur);
1299 }
1300
1301 /**
1302 * Retuns the minimum allowed zoom scale. This is the bigger number value of the two.
1303 * Defaults to {@link Double}.MAX_VALUE
1304 *
1305 * @author <a href="mailto:[email protected]">Stefan Alfons Kr&uuml;ger</a>
1306 */
1307 public Double getMinZoomScale() {
1308 return minZoomScale;
1309 }
1310
1311 /**
1312 * Retuns the maximum allowed zoom scale. This is the smaller number value of the two.
1313 * Defaults to {@link Double}.MIN_VALUE
1314 *
1315 * @author <a href="mailto:[email protected]">Stefan Alfons Kr&uuml;ger</a>
1316 */
1317 public Double getMaxZoomScale() {
1318 return maxZoomScale;
1319 }
1320
1321 /**
1322 * Set the maximum allowed zoom scale. This is the smaller number value of the two.
1323 *
1324 * @author <a href="mailto:[email protected]">Stefan Alfons Kr&uuml;ger</a>
1325 */
1326 public void setMaxZoomScale(Double maxZoomScale) {
1327 // System.out.println("setting max scale to "+maxZoomScale);
1328 this.maxZoomScale = maxZoomScale;
1329 }
1330
1331 /**
1332 * Set the minimum (nearest) allowed zoom scale. This is the bigger number value of the two.
1333 *
1334 * @author <a href="mailto:[email protected]">Stefan Alfons Kr&uuml;ger</a>
1335 */
1336 public void setMinZoomScale(Double minZoomScale) {
1337 this.minZoomScale = minZoomScale;
1338 }
1339 //xulu.en
1340
1341
1342 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26