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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26