/[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 226 - (show annotations)
Thu Jul 16 07:37:43 2009 UTC (15 years, 7 months ago) by alfonx
Original Path: trunk/src/org/geotools/gui/swing/JMapPane.java
File size: 38412 byte(s)
* Created a new ManageChartsForMapDialog that allows to manage charts and define which chart is visible in which map. Besides, that saving the ChartSTyles is not implemented, you can now basically define and use the charts.

* Created a TransitionShapefileRenderer in schmitzm. It's a copy (extend was not possible) of a normal ShapefileRenderer class, but extended by a hack to fall back to the normal StreamingRenderer if a FeatureOperationTreeFilter is applied to a MapLayer. 
* I have set this TransitionShapefileRenderer as default in JMapPane & Co.
* It's called "transition", because we will remove it as soon as we moved to GT 2.6 and switched the filters to eCQL.

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26