/[schmitzm]/branches/2.0-RC2/src/skrueger/geotools/XMapPane.java
ViewVC logotype

Annotation of /branches/2.0-RC2/src/skrueger/geotools/XMapPane.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations)
Tue Feb 24 22:43:52 2009 UTC (16 years ago) by mojays
Original Path: trunk/src/org/geotools/gui/swing/JMapPane.java
File size: 43112 byte(s)
First Commit, corresponds to Revision 1008 of Wikisquare-SVN
includes:
- schmitzm.* (except schmitzm.test)
- org.geotools.* (all overridden classes)
- skrueger.geotools
- skrueger.i8n
- skrueger.swing
- appl.data.LateLoadable (dependency in SCHMITZM)
- appl.data.LoadingException (dependency in SCHMITZM)
- appl.util.RasterMetaData (dependency in SCHMITZM)

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26