Statistics
| Revision:

root / trunk / extensions / extTopology / src / org / gvsig / fmap / tools / behavior / VectorBehavior.java @ 23163

History | View | Annotate | Download (9.46 KB)

1
/*
2
 * Created on 10-abr-2006
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
21
 *
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
/* CVS MESSAGES:
45
*
46
* $Id: 
47
* $Log: 
48
*/
49
package org.gvsig.fmap.tools.behavior;
50

    
51
import java.awt.Color;
52
import java.awt.Graphics;
53
import java.awt.Graphics2D;
54
import java.awt.Point;
55
import java.awt.Rectangle;
56
import java.awt.Stroke;
57
import java.awt.event.MouseEvent;
58
import java.awt.geom.AffineTransform;
59
import java.awt.geom.Point2D;
60
import java.awt.geom.Rectangle2D;
61
import java.awt.image.BufferedImage;
62
import java.util.List;
63

    
64
import org.gvsig.fmap.core.FGeometryUtil;
65
import org.gvsig.fmap.core.ShapePointExtractor;
66
import org.gvsig.fmap.tools.listeners.VectorListener;
67

    
68
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
69
import com.iver.andami.PluginServices;
70
import com.iver.cit.gvsig.fmap.ViewPort;
71
import com.iver.cit.gvsig.fmap.core.FPolyline2D;
72
import com.iver.cit.gvsig.fmap.core.FShape;
73
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
74
import com.iver.cit.gvsig.fmap.core.IFeature;
75
import com.iver.cit.gvsig.fmap.core.IGeometry;
76
import com.iver.cit.gvsig.fmap.drivers.IFeatureIterator;
77
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
78
import com.iver.cit.gvsig.fmap.tools.BehaviorException;
79
import com.iver.cit.gvsig.fmap.tools.Behavior.Behavior;
80
import com.iver.cit.gvsig.fmap.tools.Events.MoveEvent;
81
import com.iver.cit.gvsig.fmap.tools.Listeners.ToolListener;
82
import com.iver.cit.gvsig.project.documents.view.snapping.SnappingVisitor;
83
import com.iver.cit.gvsig.project.documents.view.snapping.snappers.NearestPointSnapper;
84

    
85
/**
86
 * Behavior to digitize two points vectors in mapcontrol
87
 * @author azabala
88
 */
89
public class VectorBehavior extends Behavior {
90

    
91
        NearestPointSnapper snapper = new NearestPointSnapper();
92
        PointSnapper pointSnapper = new PointSnapper();
93
        
94
        FLyrVect snappingLyr = null;
95
        
96
        
97
        private boolean isZooming = false;
98
        private Point2D m_FirstPoint;
99
        private Point2D m_LastPoint;
100
        private VectorListener listener;
101
        
102
        protected int lenghtArrow = 15;
103
        protected int widthArrow = 10;
104
        protected Color arrowColor = java.awt.Color.RED;
105
        protected int rgb;
106
        private Stroke stroke;
107
        protected static BufferedImage img = new BufferedImage(1, 1,
108
                        BufferedImage.TYPE_INT_ARGB);
109
        protected static Rectangle rect = new Rectangle(0, 0, 1, 1);
110

    
111
        
112
        class PointSnapper extends NearestPointSnapper {
113

    
114
                public Point2D getSnapPoint(Point2D queryPoint, IGeometry geomToSnap,
115
                                double tolerance, Point2D lastPointEntered) {
116
                        
117
                        Point2D solution = null;
118
                        double minDistance = tolerance;
119
                        
120
                        List<Point2D[]> pointsParts =
121
                                ShapePointExtractor.extractPoints(geomToSnap);
122
                        for(int i = 0; i < pointsParts.size(); i++){
123
                                Point2D[] points = pointsParts.get(i);
124
                                for(int j = 0; j < points.length; j++){
125
                                        Point2D point = points[j];
126
                                        double dist = point.distance(queryPoint);
127
                                        if(dist <= minDistance){
128
                                                solution = point;
129
                                                minDistance = dist;
130
                                        }//if
131
                                }//for j
132
                        }//for i
133
                        return solution;
134
                }
135

    
136
                public String getToolTipText() {
137
                        return PluginServices.getText(this, "nearest_point_for_point_layers");
138
                }
139
                
140
        }
141

    
142
        
143
        /**
144
         * Crea un nuevo RectangleBehavior.
145
         *
146
         * @param zili listener.
147
         */
148
        public VectorBehavior(VectorListener zili, FLyrVect snappingLyr) {
149
                listener = zili;
150
                this.snappingLyr = snappingLyr;
151
                Graphics2D g2 = img.createGraphics();
152
                drawInsideRectangle(g2, g2.getTransform(), rect);
153
                rgb = img.getRGB(0, 0);
154

    
155
        }
156

    
157
        private void drawInsideRectangle(Graphics2D g, AffineTransform scale,
158
                        Rectangle r) {
159
                FShape shp;
160
                AffineTransform mT = new AffineTransform();
161
                mT.setToIdentity();
162

    
163
                Rectangle rect = mT.createTransformedShape(r).getBounds();
164
                GeneralPathX line = new GeneralPathX();
165
                
166
                
167
                
168
                line.moveTo(rect.x, rect.y + (rect.height / 2));
169
                line.curveTo(rect.x + (rect.width / 3),
170
                        rect.y + (2 * rect.height),
171
                        rect.x + ((2 * rect.width) / 3), rect.y - rect.height,
172
                        rect.x + rect.width, rect.y + (rect.height / 2));
173

    
174
                shp = new FPolyline2D(line);
175
                drawLineWithArrow(g, mT, shp);
176

    
177
                
178
        }
179

    
180
        /**
181
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#paintComponent(java.awt.Graphics)
182
         */
183
        public void paintComponent(Graphics g) {
184
                BufferedImage img = getMapControl().getImage();
185
                g.drawImage(img, 0, 0, null);
186
                g.setColor(Color.black);
187
                g.setXORMode(Color.white);
188

    
189
                
190

    
191
                // Dibujamos el actual
192
                if ((m_FirstPoint != null) && (m_LastPoint != null) && !isZooming) {
193
                        GeneralPathX line = new GeneralPathX();                        
194
                        line.moveTo(m_FirstPoint.getX(), m_FirstPoint.getY());
195
                        line.lineTo(m_LastPoint.getX(), m_LastPoint.getY());
196
                        FPolyline2D shp = new FPolyline2D(line);
197
                        drawLineWithArrow((Graphics2D)g, getMapControl().getViewPort().getAffineTransform(), shp);
198
                }
199
                g.setPaintMode();
200
        }
201

    
202
        /**
203
         * Reimplementaci?n del m?todo mousePressed de Behavior.
204
         *
205
         * @param e MouseEvent
206
         */
207
        public void mousePressed(MouseEvent e) {
208

    
209
                        int modifiers = e.getModifiersEx();
210
                        int ctrlDownMask = modifiers & MouseEvent.CTRL_DOWN_MASK;
211
                        if(ctrlDownMask == MouseEvent.CTRL_DOWN_MASK ){
212
                                isZooming = true;
213
                        }
214
                        m_FirstPoint = e.getPoint();
215
                        getMapControl().repaint();
216

    
217
                        if (listener.cancelDrawing()) {
218
                                getMapControl().cancelDrawing();
219
                                getMapControl().repaint();
220
                        }
221
        }
222
        
223
        
224
        
225
                
226
        
227

    
228
        /**
229
         * Reimplementaci?n del m?todo mouseReleased de Behavior.
230
         *
231
         * @param e MouseEvent
232
         *
233
         * @throws BehaviorException Excepci?n lanzada cuando el Behavior.
234
         */
235
        public void mouseReleased(MouseEvent e) throws BehaviorException {
236
            if (m_FirstPoint == null) {
237
                    isZooming = false;
238
                    return;
239
            }
240
                Point2D p1;
241
                Point2D p2;
242
                Point pScreen = e.getPoint();
243

    
244
                ViewPort vp = getMapControl().getMapContext().getViewPort();
245
                p1 = vp.toMapPoint(m_FirstPoint);
246
                
247
                
248
                //we snap to the nearest point of the adjusting layer
249
                int pixelTolerance = 8;
250
                double mapTolerance = vp.toMapDistance(pixelTolerance);
251
                
252
                double minDist = mapTolerance;
253
                Rectangle2D r = new Rectangle2D.Double(p1.getX() - mapTolerance / 2,
254
                                p1.getY() - mapTolerance / 2, mapTolerance, mapTolerance);
255

    
256
                if (snappingLyr.isVisible()){
257
                        try {
258
                                IFeatureIterator iterator = snappingLyr.getSource().getFeatureIterator(r, null, null, false);
259
                                SnappingVisitor snapVisitor = 
260
                                        new SnappingVisitor(snapper, p1, mapTolerance, null);
261
                                SnappingVisitor snapVisitor2 = 
262
                                        new SnappingVisitor(pointSnapper, p1, mapTolerance, null);
263
                                
264
                                while(iterator.hasNext()){
265
                                        IFeature feature = iterator.next();
266
                                        IGeometry geo = feature.getGeometry();
267
                                        snapVisitor.visitItem(geo);
268
                                        snapVisitor2.visitItem(geo);
269
                                }
270
                                Point2D theSnappedPoint = snapVisitor.getSnapPoint();
271
                                if(theSnappedPoint == null)
272
                                        theSnappedPoint = snapVisitor2.getSnapPoint();
273
                                
274
                                if (theSnappedPoint != null) {
275
                                        p1.setLocation(theSnappedPoint);
276
                                }
277
                        } catch (ReadDriverException e1) {
278
                                e1.printStackTrace();
279
                                throw new BehaviorException("Error de driver intentando aplicar snap", e1);
280
                        }
281
                }//isVisible
282
                                
283
                                
284
                p2 = vp.toMapPoint(pScreen);
285
//                Rectangle2D.Double rectangle = new Rectangle2D.Double();
286
//                rectangle.setFrameFromDiagonal(p1, p2);
287

    
288
//                MoveEvent event = new MoveEvent(m_FirstPoint, e.getPoint(), e);
289
                MoveEvent event = new MoveEvent(p1, p2, e);
290
                listener.vector(event);
291

    
292

    
293
                m_FirstPoint = null;
294
                m_LastPoint = null;
295
                isZooming = false;
296
        }
297

    
298
        /**
299
         * Reimplementaci?n del m?todo mouseDragged de Behavior.
300
         *
301
         * @param e MouseEvent
302
         */
303
        public void mouseDragged(MouseEvent e) {
304
                m_LastPoint = e.getPoint();
305
                getMapControl().repaint();
306
        }
307

    
308
        /**
309
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#setListener(com.iver.cit.gvsig.fmap.tools.ToolListener)
310
         */
311
        public void setListener(ToolListener listener) {
312
                this.listener = (VectorListener) listener;
313
        }
314

    
315
        /**
316
         * @see com.iver.cit.gvsig.fmap.tools.Behavior.Behavior#getListener()
317
         */
318
        public ToolListener getListener() {
319
                return listener;
320
        }
321
        
322
        
323
        private void drawLineWithArrow(Graphics2D g, AffineTransform affineTransform, FShape shp){
324
                FGeometryUtil.drawLineWithArrow(g, affineTransform, shp, arrowColor, stroke, lenghtArrow, widthArrow);
325

    
326
        }
327

    
328
        public FLyrVect getSnappingLyr() {
329
                return snappingLyr;
330
        }
331

    
332
        public void setSnappingLyr(FLyrVect snappingLyr) {
333
                this.snappingLyr = snappingLyr;
334
        }
335

    
336
}
337