Statistics
| Revision:

svn-document-layout / branches / usability_v2 / org.gvsig.app.document.layout.app / org.gvsig.app.document.layout.app.mainplugin / src / main / java / org / gvsig / app / project / documents / layout / FLayoutUtilities.java @ 141

History | View | Annotate | Download (13.1 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program 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
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.app.project.documents.layout;
23

    
24
import java.awt.Dimension;
25
import java.awt.Point;
26
import java.awt.geom.AffineTransform;
27
import java.awt.geom.NoninvertibleTransformException;
28
import java.awt.geom.Point2D;
29
import java.awt.geom.Rectangle2D;
30
import java.util.ArrayList;
31
import java.util.List;
32

    
33
import org.cresques.cts.IProjection;
34
import org.slf4j.Logger;
35
import org.slf4j.LoggerFactory;
36

    
37
import org.gvsig.app.project.documents.Document;
38
import org.gvsig.app.project.documents.layout.fframes.FFrameView;
39
import org.gvsig.app.project.documents.layout.fframes.IFFrame;
40
import org.gvsig.app.project.documents.layout.fframes.IFFrameUseFMap;
41
import org.gvsig.app.project.documents.view.ViewDocument;
42
import org.gvsig.fmap.mapcontext.MapContext;
43
import org.gvsig.fmap.mapcontext.ViewPort;
44
import org.gvsig.fmap.mapcontext.layers.FLayer;
45
import org.gvsig.fmap.mapcontext.layers.FLayers;
46
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
47

    
48
/**
49
 * Clase que recoge m?todos est?ticos sobre el Layout.
50
 * 
51
 * @author Vicente Caballero Navarro
52
 */
53
public class FLayoutUtilities {
54
    
55
    private static Logger logger = LoggerFactory.getLogger(
56
        FLayoutUtilities.class);
57

    
58
    /**
59
     * Devuelve true si las dos ArrayList que se le pasan como parametro son
60
     * iguales.
61
     * 
62
     * @param n
63
     *            lista anterior
64
     * @param l
65
     *            lista actual
66
     * 
67
     * @return true si los ArrayList son iguales.
68
     */
69
    public static boolean isEqualList(ArrayList n, ArrayList l) {
70
        if (n.size() != l.size()) {
71
            return false;
72
        }
73

    
74
        for (int i = 0; i < n.size(); i++) {
75
            if (l.get(i) != n.get(i)) {
76
                return false;
77
            }
78
        }
79

    
80
        return true;
81
    }
82

    
83
    /**
84
     * Pasa una distancia en pixels a unidades del folio.
85
     * 
86
     * @param d
87
     *            distancia en pixels.
88
     * @param at
89
     *            Matriz de transformaci?n.
90
     * 
91
     * @return distancia en unidades de folio.
92
     */
93
    public static double toSheetDistance(double d, AffineTransform at) {
94
        double dist = d / at.getScaleX(); // pProv.x;
95

    
96
        return dist;
97
    }
98

    
99
    /**
100
     * Pasa una distancia de coordenadas del folio a pixels.
101
     * 
102
     * @param d
103
     *            distancia en coordenadas de folio.
104
     * @param at
105
     *            Matriz de transformaci?n.
106
     * 
107
     * @return double en pixels.
108
     */
109
    public static double fromSheetDistance(double d, AffineTransform at) {
110
        Point2D.Double pSheet1 = new Point2D.Double(0, 0);
111
        Point2D.Double pSheet2 = new Point2D.Double(1, 0);
112
        Point2D.Double pScreen1 = new Point2D.Double();
113
        Point2D.Double pScreen2 = new Point2D.Double();
114

    
115
        try {
116
            at.transform(pSheet1, pScreen1);
117
            at.transform(pSheet2, pScreen2);
118
        } catch (Exception e) {
119
            System.err.print(e.getMessage());
120
        }
121

    
122
        return pScreen1.distance(pScreen2) * d;
123
    }
124

    
125
    /**
126
     * Pasa un punto en pixels a coordenadas del folio.
127
     * 
128
     * @param pScreen
129
     *            pixels.
130
     * @param at
131
     *            Matriz de transformaci?n.
132
     * 
133
     * @return Point2D en coordenadas de folio.
134
     */
135
    public static Point2D.Double toSheetPoint(Point2D pScreen,
136
        AffineTransform at) {
137
        Point2D.Double pWorld = new Point2D.Double();
138
        AffineTransform at1;
139

    
140
        try {
141
            at1 = at.createInverse();
142
            at1.transform(pScreen, pWorld);
143
        } catch (NoninvertibleTransformException e) {
144
        }
145

    
146
        return pWorld;
147
    }
148

    
149
    /**
150
     * Pasa un ret?ngulo de pixels a coordenadas del folio.
151
     * 
152
     * @param r
153
     *            rect?ngulo en coordenadas de pixels a coordenadas de folio.
154
     * @param at
155
     *            Matriz de transformaci?n.
156
     * 
157
     * @return Rectangle2D en coordenadas de folio.
158
     */
159
    public static Rectangle2D.Double toSheetRect(Rectangle2D r,
160
        AffineTransform at) {
161
        Point2D.Double pSheet =
162
            toSheetPoint(new Point2D.Double(r.getX(), r.getY()), at);
163
        Point2D.Double pSheetX =
164
            toSheetPoint(new Point2D.Double(r.getMaxX(), r.getMinY()), at);
165
        Point2D.Double pSheetY =
166
            toSheetPoint(new Point2D.Double(r.getMinX(), r.getMaxY()), at);
167
        Rectangle2D.Double res = new Rectangle2D.Double();
168
        res.setRect(pSheet.getX(), pSheet.getY(), pSheet.distance(pSheetX),
169
            pSheet.distance(pSheetY));
170

    
171
        return res;
172
    }
173

    
174
    /**
175
     * Pasa de un punto en coordenadas del folio a pixels.
176
     * 
177
     * @param pSheet
178
     *            punto en coordenadas de folio.
179
     * @param at
180
     *            Matriz de transformaci?n.
181
     * 
182
     * @return Point2D en pixels.
183
     */
184
    public static Point2D.Double fromSheetPoint(Point2D pSheet,
185
        AffineTransform at) {
186
        Point2D.Double pScreen = new Point2D.Double();
187

    
188
        try {
189
            at.transform(pSheet, pScreen);
190
        } catch (Exception e) {
191
            System.err.print(e.getMessage());
192
        }
193

    
194
        return pScreen;
195
    }
196

    
197
    /**
198
     * Pasa un rect?ngulo en coordenadas del folio a pixels.
199
     * 
200
     * @param r
201
     *            rect?ngulo en coordenadas de folio.
202
     * @param at
203
     *            Matriz de transformaci?n.
204
     * 
205
     * @return Rectangle2D en pixels.
206
     */
207
    public static Rectangle2D.Double fromSheetRect(Rectangle2D r,
208
        AffineTransform at) {
209
        Point2D.Double pSheet = new Point2D.Double(r.getX(), r.getY());
210
        Point2D.Double pSX = new Point2D.Double(r.getMaxX(), r.getMinY());
211
        Point2D.Double pSY = new Point2D.Double(r.getMinX(), r.getMaxY());
212
        Point2D.Double pScreen = new Point2D.Double();
213
        Point2D.Double pScreenX = new Point2D.Double();
214
        Point2D.Double pScreenY = new Point2D.Double();
215

    
216
        try {
217
            at.transform(pSheet, pScreen);
218
            at.transform(pSX, pScreenX);
219
            at.transform(pSY, pScreenY);
220
        } catch (Exception e) {
221
            System.err.print(e.getMessage());
222
        }
223

    
224
        Rectangle2D.Double res = new Rectangle2D.Double();
225
        res.setRect(pScreen.getX(), pScreen.getY(), pScreen.distance(pScreenX),
226
            pScreen.distance(pScreenY));
227

    
228
        return res;
229
    }
230

    
231
    /**
232
     * Obtiene el punto ajustado al grid del layout.
233
     * 
234
     * @param p
235
     *            Punto a ajustar.
236
     * @param distX
237
     *            Distancia m?nima en cm de X.
238
     * @param distY
239
     *            Distancia m?nima en cm de Y.
240
     * @param at
241
     *            Matriz de transformaci?n.
242
     */
243
    public static Point getPointGrid(Point p, double distX, double distY,
244
        AffineTransform at) {
245
        
246
        if (distX * at.getScaleX() < 2 && distY * at.getScaleY() < 2) {
247
            /*
248
             * In this case, it makes no sense to care about snapping
249
             * because snapping would mean to move the position by one pixel
250
             */
251
            return p;
252
        }
253

    
254
        Point2D.Double auxp =
255
            FLayoutUtilities.fromSheetPoint(new Point2D.Double(0, 0), at);
256
        
257
        double gridintx = distX * at.getScaleX();
258
        double gridinty = distY * at.getScaleY();
259
        
260
        double seppx = p.x - Math.round(auxp.x);
261
        double seppy = p.y - Math.round(auxp.y);
262
        
263
        long round_int_p_x = Math.round(seppx / gridintx);
264
        long round_int_p_y = Math.round(seppy / gridinty);
265
        
266
        // Rounded
267
        seppx = round_int_p_x * gridintx;
268
        seppy = round_int_p_y * gridinty;
269
        
270
        return new Point(
271
            (int) (auxp.x + seppx),
272
            (int) (auxp.y + seppy));
273
    }
274

    
275
    /**
276
     * Cuando se dibuja sobre el graphics todo se tiene que situar en enteros y
277
     * aqu? lo que se comprueba es que si los valores que contiene el
278
     * Rectangle2D, que toma como par?metro, supera los valores soportados por
279
     * un entero.
280
     * 
281
     * @param r
282
     *            Rectangle2D a comprobar si los valores que contiene no superan
283
     *            a los que puede tener un entero.
284
     * 
285
     * @return true si no se han superado los l?mites.
286
     */
287
    public static boolean isPosible(Rectangle2D.Double r) {
288
        if ((r.getMaxX() > Integer.MAX_VALUE)
289
            || (r.getMaxY() > Integer.MAX_VALUE)
290
            || (r.getMinX() < Integer.MIN_VALUE)
291
            || (r.getMinY() < Integer.MIN_VALUE)
292
            || (r.getWidth() > Integer.MAX_VALUE)
293
            || (r.getHeight() > Integer.MAX_VALUE)) {
294
            return false;
295
        }
296

    
297
        return true;
298
    }
299

    
300
    /**
301
     * Devuelve un long representando a la escala en funci?n de que unidad de
302
     * medida se pase como par?metro.
303
     * 
304
     * @param map
305
     *            FMap
306
     * @param h
307
     *            Rect?ngulo.
308
     * 
309
     * @return escala.
310
     */
311
    public static long getScaleView(
312
        ViewPort viewPort,
313
        double wcm,
314
        double wpixels) {
315
        
316
        double dpi = (2.54*wpixels) / wcm;
317
        IProjection proj = viewPort.getProjection();
318

    
319
        if (viewPort.getAdjustedEnvelope() == null) {
320
            return 0;
321
        }
322

    
323
        if (proj == null || viewPort.getImageSize() == null) {
324
            return (long) (viewPort.getAdjustedEnvelope().getLength(1)
325
                / wcm * Attributes.CHANGE[viewPort.getMapUnits()]);
326
        }
327

    
328
        double[] trans2Meter = MapContext.getDistanceTrans2Meter();
329
        int mUnits = viewPort.getMapUnits();
330
        
331
        return (long) proj.getScale(
332
            viewPort.getAdjustedEnvelope().getMinimum(0) * trans2Meter[mUnits],
333
            viewPort.getAdjustedEnvelope().getMaximum(0) * trans2Meter[mUnits],
334
            wpixels, dpi);
335
    }
336
    
337
    
338
    
339
    public static List<Document> removeEditing(List<Document> list) {
340
        
341
        List<Document> resp = new ArrayList<Document>();
342
        
343
        Document item = null;
344
        ViewDocument viewdoc = null;
345
        for (int i=0; i<list.size(); i++) {
346
            item = list.get(i);
347
            if (item instanceof ViewDocument) {
348
                viewdoc = (ViewDocument) item;
349
                if (!hasEditingLayers(viewdoc)) {
350
                    resp.add(item);
351
                }
352
            }
353
        }
354
        return resp;
355
    }
356
    
357

    
358
    public static boolean hasEditingLayers(ViewDocument viewdoc) {
359
        return hasEditingLayers(viewdoc.getMapContext().getLayers());
360
    }
361

    
362
    /**
363
     * Recursively find out if any layer is in editing mode
364
     * 
365
     * @param lyrs
366
     * @return
367
     */
368
    public static boolean hasEditingLayers(FLayers lyrs) {
369
        
370
        int len = lyrs.getLayersCount();
371
        FLayer lyr = null;
372
        FLyrVect vlyr = null;
373
        for (int i=0; i<len; i++) {
374
            lyr = lyrs.getLayer(i);
375
            if (lyr instanceof FLyrVect) {
376
                vlyr = (FLyrVect) lyr;
377
                if (vlyr.isEditing()) {
378
                    return true;
379
                }
380
            } else {
381
                if (lyr instanceof FLayers) {
382
                    if (hasEditingLayers((FLayers) lyr)) {
383
                        return true;
384
                    }
385
                }
386
            }
387
        }
388
        return false;
389
    }    
390
    
391
    public static Point2D screenCoordinatesToViewportImageCoordinates(
392
        Point2D screenp, IFFrame frame) {
393
        
394
        if (screenp == null || frame == null || !(frame instanceof IFFrameUseFMap)) {
395
            
396
            logger.info("Bad parameters in screenCoordinatesToViewportImageCoordinates",
397
                new Exception("Null values or Frame has no MapContext"));
398
            return screenp;
399
        }
400

    
401
        Rectangle2D.Double rect = frame.getBoundingBox(null);
402
        
403
        double screenRectWidth = rect.width;
404
        double vpWidth = ((IFFrameUseFMap) frame).getMapContext().getViewPort().getImageWidth();
405
        if (screenRectWidth < 1 || vpWidth < 1) {
406
            logger.info("Bad size in screen/viewport ("
407
                + "screenRectWidth = " + screenRectWidth + ", "
408
                + "vpWidth = " + vpWidth + ")");
409
            return screenp;
410
        }
411
        
412
        /*
413
         * Get coordinates in the rectangle (remove offset)
414
         */
415
        Point2D po = new Point2D.Double(
416
            screenp.getX() - rect.x, screenp.getY() - rect.y);
417
        
418
        double ratio = (vpWidth * 1d) / (screenRectWidth * 1d);
419
        Point2D resp = new Point2D.Double(ratio * po.getX(), ratio * po.getY());
420
        return resp;
421
    }
422
    
423
    
424

    
425
}