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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 76 - (hide 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 mojays 2 /*
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 alfonx 76 import org.geotools.data.memory.MemoryFeatureCollection;
62     import org.geotools.feature.Feature;
63 mojays 2 import org.geotools.feature.FeatureCollection;
64     import org.geotools.filter.IllegalFilterException;
65 alfonx 76 import org.geotools.geometry.jts.ReferencedEnvelope;
66 mojays 2 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 alfonx 76 import com.sun.corba.se.spi.legacy.connection.GetEndPointInfoAgainException;
95 mojays 2 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 alfonx 76 /**
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 mojays 2
1264 alfonx 76 /**
1265     * Correct the aspect Ratio before we check the rest. Otherwise we might easily fail.
1266     */
1267     env = fixAspectRatio(this.getBounds(), env);
1268 mojays 2
1269 alfonx 76 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 mojays 2
1293 alfonx 76 Coordinate ll = new Coordinate(centerX - newWidth2, centerY
1294     - newHeight2);
1295     Coordinate ur = new Coordinate(centerX + newWidth2, centerY
1296     + newHeight2);
1297 mojays 2
1298 alfonx 76 return new Envelope(ll, ur);
1299     }
1300    
1301 mojays 2 /**
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 alfonx 76
1342 mojays 2 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26