Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libRemoteServices / src / org / gvsig / remoteclient / wmts / struct / WMTSTileMatrix.java @ 38531

History | View | Annotate | Download (12.9 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.remoteclient.wmts.struct;
23

    
24
import java.awt.geom.AffineTransform;
25
import java.awt.geom.NoninvertibleTransformException;
26
import java.awt.geom.Point2D;
27
import java.awt.geom.Rectangle2D;
28
import java.io.File;
29
import java.io.IOException;
30
import java.util.ArrayList;
31

    
32
import org.kxml2.io.KXmlParser;
33
import org.xmlpull.v1.XmlPullParserException;
34

    
35
/**
36
 * Description of a tile matrix
37
 * @author Nacho Brodin (nachobrodin@gmail.com)
38
 */
39
public abstract class WMTSTileMatrix extends WMTSBaseStruct {
40
    private double                  scaleDenominator             = 0;
41
    private double[]                topLeftCorner                = null;
42
    private int                     tileWidth                    = 0;
43
    private int                     tileHeight                   = 0;
44
    private long                    matrixWidth                  = 0;
45
    private long                    matrixHeight                 = 0;
46
    private static final double     MTS_X_GRADO                  = 111319.490793274;
47
    protected boolean               forceLongitudeFirstAxisOrder = false;
48
        
49
        /**
50
         * Sets longitude first in the axis order read from the capabilities file
51
         * @param force
52
         */
53
        public void setForceLongitudeFirstAxisOrder(boolean force) {
54
                this.forceLongitudeFirstAxisOrder = force;
55
        }
56

    
57
    public class Tile {
58
            public int       wPx, hPx;
59
            public int       row, col;
60
            public double    ulx, uly, lrx, lry;
61
            public File      file;
62

    
63
            public Tile(int wPx, int hPx, int row, int col, double ulx, double uly, double lrx, double lry) {
64
                    this.row = row;
65
                    this.col = col;
66
                    this.ulx = ulx;
67
                    this.uly = uly;
68
                    this.lrx = lrx;
69
                    this.lry = lry;
70
                    this.wPx = wPx;
71
                    this.hPx = hPx;
72
            }
73
            
74
            /**
75
             * Convierte un punto desde del mundo a coordenadas pixel.
76
             * @param pt Punto a transformar
77
             * @return punto transformado en coordenadas pixel
78
             */
79
            public Point2D worldToRaster(Point2D pt) {
80
                    Point2D p = new Point2D.Double();
81
                    double psX = (lrx - ulx) / tileWidth;
82
                    double psY = (lry - uly) / tileHeight;
83
                    AffineTransform t = new AffineTransform(psX, 0, 0, psY, ulx - (psX / 2), uly + (psY / 2));
84
                    try {
85
                            t.inverseTransform(pt, p);
86
                    } catch (NoninvertibleTransformException e) {
87
                            return pt;
88
                    }
89
                    return p;
90
            }
91
            
92
            public Tile cloneTile() {
93
                    Tile status = new Tile(wPx, hPx, row, col, ulx, uly, lrx, lry);
94
                    status.file = file;
95
                    return status;
96
            }
97
    }
98

    
99
    /**
100
     * Parses this service
101
     * @param parser
102
     * @param content
103
     * @throws IOException
104
     * @throws XmlPullParserException
105
     */
106
        public abstract void parse(KXmlParser parser, ArrayList list) throws IOException, XmlPullParserException; 
107
        
108
    
109
        public double getScaleDenominator() {
110
                return scaleDenominator;
111
        }
112

    
113
        public void setScaleDenominator(double scaleDenominator) {
114
                this.scaleDenominator = scaleDenominator;
115
        }
116

    
117
        public int getTileWidth() {
118
                return tileWidth;
119
        }
120

    
121
        public void setTileWidth(int tileWidth) {
122
                this.tileWidth = tileWidth;
123
        }
124

    
125
        public int getTileHeight() {
126
                return tileHeight;
127
        }
128

    
129
        public void setTileHeight(int tileHeight) {
130
                this.tileHeight = tileHeight;
131
        }
132

    
133
        public long getMatrixWidth() {
134
                return matrixWidth;
135
        }
136

    
137
        public void setMatrixWidth(long matrixWidth) {
138
                this.matrixWidth = matrixWidth;
139
        }
140

    
141
        public long getMatrixHeight() {
142
                return matrixHeight;
143
        }
144

    
145
        public void setMatrixHeight(long matrixHeight) {
146
                this.matrixHeight = matrixHeight;
147
        }
148

    
149
        public double[] getTopLeftCorner() {
150
                if(topLeftCorner == null)
151
                        topLeftCorner = new double[2];
152
                return topLeftCorner;
153
        }
154
        
155
    public void parse(KXmlParser parser) throws IOException, XmlPullParserException {
156
            
157
    }
158
    
159
    /**
160
     * Gets the width in meters of a tile
161
     * @param projected
162
     * @return
163
     */
164
    public double getWidthMtsTile(boolean projected) {
165
            if(!projected) {
166
                    return (scaleDenominator * tileWidth * 0.28) / (MTS_X_GRADO * 1000);
167
            } else {
168
                    return (scaleDenominator * tileWidth * 0.28) / 1000;
169
            }
170
    }
171
    
172
    /**
173
     * Gets the height in meters of a tile
174
     * @param projected
175
     * @return
176
     */
177
    public double getHeightMtsTile(boolean projected) {
178
            if(!projected) {
179
                    double coord = (scaleDenominator * tileHeight * 0.28) / (MTS_X_GRADO * 1000);
180
                    if(coord > 0.99 || coord < 0.005)
181
                            return Math.round(coord);
182
                    return coord;
183
            } else {
184
                    return (scaleDenominator * tileHeight * 0.28) / 1000;
185
            }
186
    }
187
    
188
    /**
189
     * This function will check if the request coordinates intersects with the tiles in the matrix. If a tile
190
     * intersects then this will be added to the list.
191
     * @deprecated this method was for grid subsets.   
192
     */
193
        public ArrayList intersects(boolean projected, WMTSTileMatrixLimits tileMatrixLimits, Rectangle2D request, Rectangle2D extentLayer) {
194
            double widthMtsTile = getWidthMtsTile(projected);
195
            double heightMtsTile = getHeightMtsTile(projected);
196

    
197
                double ulx, uly, lrx, lry;
198
            ArrayList list = new ArrayList();
199
            Rectangle2D r = new Rectangle2D.Double(0, 0, 0, 0);
200

    
201
            //Recorre la matriz de tiles calculando las coordenadas de cada tile
202
            //Para cada tile comprueba si intersecta con el ?rea seleccionada si es as?
203
            //mete el tile en la lista para devolverlo como resultado
204
            
205
            //cambiar esto por un conversor entre coordenadas pixel y reales
206
            
207
            int i = 0, j = 0;
208
            double initX = topLeftCorner[1] + (widthMtsTile * tileMatrixLimits.getMinTileCol());
209
            double initY = topLeftCorner[0] - (heightMtsTile * (tileMatrixLimits.getMinTileRow()));
210
            
211
            for (int row = tileMatrixLimits.getMinTileRow(); row <= tileMatrixLimits.getMaxTileRow(); row++) {
212
                    uly = initY - (heightMtsTile * i);
213
                        lry = uly - heightMtsTile;
214
                        j = 0;
215
                        for (int col = tileMatrixLimits.getMinTileCol(); col <= tileMatrixLimits.getMaxTileCol(); col++) {
216
                                ulx = initX + (widthMtsTile * j);
217
                                lrx = ulx + widthMtsTile;
218
                                r.setRect(Math.min(ulx, lrx), Math.min(uly, lry), Math.abs(ulx - lrx), Math.abs(uly - lry));
219
                                if(request.intersects(r) && r.intersects(extentLayer)) {
220
                                        list.add(new Tile(tileWidth, tileHeight, row, col, ulx, uly, lrx, lry));
221
                                }
222
                                j ++;
223
                        }
224
                        i ++;
225
                }
226
            
227
            return list;
228
    }
229
    
230
    /**
231
     * This function will check if the request coordinates intersects with the tiles in the matrix. If a tile
232
     * intersects then this will be added to the list.  
233
     */
234
        public ArrayList intersects(boolean projected, Rectangle2D request, Rectangle2D extentLayer) {
235
            double widthMtsTile = getWidthMtsTile(projected);
236
            double heightMtsTile = getHeightMtsTile(projected);
237

    
238
                double ulx, uly, lrx, lry;
239
            ArrayList list = new ArrayList();
240
            Rectangle2D r = new Rectangle2D.Double(0, 0, 0, 0);
241

    
242
            //Recorre la matriz de tiles calculando las coordenadas de cada tile
243
            //Para cada tile comprueba si intersecta con el ?rea seleccionada si es as?
244
            //mete el tile en la lista para devolverlo como resultado
245
            
246
            double initX = topLeftCorner[1];
247
            double initY = topLeftCorner[0];
248
            
249
            int tileInitX = (int)((request.getMinX() - initX) / widthMtsTile);
250
            int tileInitY = (int)(Math.abs(request.getMaxY() - initY) / heightMtsTile);
251
            int tileEndX = (int)((request.getMaxX() - initX) / widthMtsTile);
252
            int tileEndY = (int)(Math.abs(request.getMinY() - initY) / heightMtsTile);
253
            
254
            for (int row = tileInitY; row <= tileEndY; row++) {
255
                    uly = initY - (heightMtsTile * row);
256
                        lry = uly - heightMtsTile;
257
                        for (int col = tileInitX; col <= tileEndX; col++) {
258
                                ulx = initX + (widthMtsTile * col);
259
                                lrx = ulx + widthMtsTile;
260
                                r.setRect(Math.min(ulx, lrx), Math.min(uly, lry), Math.abs(ulx - lrx), Math.abs(uly - lry));
261
                                //El segundo intersects es necesario porque el extent de la capa puede variar por cada nivel de 
262
                                //resoluci?n en caso de que haya una lista de TileMatrix en el capabilities
263
                                if(request.intersects(r) && r.intersects(extentLayer)) { 
264
                                        list.add(new Tile(tileWidth, tileHeight, row, col, ulx, uly, lrx, lry));
265
                                }
266
                        }
267
                }
268
            
269
//            int i = 0, j = 0;
270
//            for (int row = 0; row < matrixHeight; row++) {
271
//                    uly = initY - (heightMtsTile * i);
272
//                        lry = uly - heightMtsTile;
273
//                        j = 0;
274
//                        for (int col = 0; col < matrixWidth; col++) {
275
//                                ulx = initX + (widthMtsTile * j);
276
//                                lrx = ulx + widthMtsTile;
277
//                                r.setRect(Math.min(ulx, lrx), Math.min(uly, lry), Math.abs(ulx - lrx), Math.abs(uly - lry));
278
//                                if(request.intersects(r)) {
279
//                                        list.add(new Tile(tileWidth, tileHeight, row, col, ulx, uly, lrx, lry));
280
//                                }
281
//                                j ++;
282
//                        }
283
//                        i ++;
284
//                }
285
            
286
            return list;
287
    }
288
        
289
    
290
    /**
291
     * This function will check if the request coordinates intersects with the tiles in the matrix. If a tile
292
     * intersects then this will be added to the list.  
293
     */
294
        public ArrayList contains(boolean projected, Point2D point, Rectangle2D extentLayer) {
295
                double widthMtsTile = getWidthMtsTile(projected);
296
            double heightMtsTile = getHeightMtsTile(projected);
297

    
298
                double ulx, uly, lrx, lry;
299
            ArrayList list = new ArrayList();
300
            Rectangle2D r = new Rectangle2D.Double(0, 0, 0, 0);
301

    
302
            //Recorre la matriz de tiles calculando las coordenadas de cada tile
303
            //Para cada tile comprueba si intersecta con el ?rea seleccionada si es as?
304
            //mete el tile en la lista para devolverlo como resultado
305
            
306
            int i = 0, j = 0;
307
            double initX = topLeftCorner[1];
308
            double initY = topLeftCorner[0];
309
            
310
            //cambiar esto por un conversor entre coordenadas pixel y reales
311
            for (int row = 0; row < matrixHeight; row++) {
312
                    uly = initY - (heightMtsTile * i);
313
                        lry = uly - heightMtsTile;
314
                        j = 0;
315
                        for (int col = 0; col < matrixWidth; col++) {
316
                                ulx = initX + (widthMtsTile * j);
317
                                lrx = ulx + widthMtsTile;
318
                                r.setRect(Math.min(ulx, lrx), Math.min(uly, lry), Math.abs(ulx - lrx), Math.abs(uly - lry));
319
                                if(r.contains(point)) {
320
                                        list.add(new Tile(tileWidth, tileHeight, row, col, ulx, uly, lrx, lry));
321
                                }
322
                                j ++;
323
                        }
324
                        i ++;
325
                }
326
            
327
            return list;
328
    }
329
    
330
    /**
331
     * This function will check if the request coordinates intersects with the tiles in the matrix. If a tile
332
     * intersects then this will be added to the list.  
333
     */
334
        public ArrayList contains(boolean projected, WMTSTileMatrixLimits tileMatrixLimits, Point2D point, Rectangle2D extentLayer) {
335
                double widthMtsTile = getWidthMtsTile(projected);
336
            double heightMtsTile = getHeightMtsTile(projected);
337

    
338
                double ulx, uly, lrx, lry;
339
            ArrayList list = new ArrayList();
340
            Rectangle2D r = new Rectangle2D.Double(0, 0, 0, 0);
341

    
342
            //Recorre la matriz de tiles calculando las coordenadas de cada tile
343
            //Para cada tile comprueba si intersecta con el ?rea seleccionada si es as?
344
            //mete el tile en la lista para devolverlo como resultado
345
            
346
            //cambiar esto por un conversor entre coordenadas pixel y reales
347
            
348
            int i = 0, j = 0;
349
            double initX = topLeftCorner[1] + (widthMtsTile * tileMatrixLimits.getMinTileCol());
350
            double initY = topLeftCorner[0] - (heightMtsTile * (tileMatrixLimits.getMinTileRow()));
351
            
352
            for (int row = tileMatrixLimits.getMinTileRow(); row <= tileMatrixLimits.getMaxTileRow(); row++) {
353
                    uly = initY - (heightMtsTile * i);
354
                        lry = uly - heightMtsTile;
355
                        j = 0;
356
                        for (int col = tileMatrixLimits.getMinTileCol(); col <= tileMatrixLimits.getMaxTileCol(); col++) {
357
                                ulx = initX + (widthMtsTile * j);
358
                                lrx = ulx + widthMtsTile;
359
                                r.setRect(Math.min(ulx, lrx), Math.min(uly, lry), Math.abs(ulx - lrx), Math.abs(uly - lry));
360
                                if(r.contains(point)) {
361
                                        list.add(new Tile(tileWidth, tileHeight, row, col, ulx, uly, lrx, lry));
362
                                }
363
                                j ++;
364
                        }
365
                        i ++;
366
                }
367
            
368
            return list;
369
    }
370
        
371
        public void print() {
372
                System.out.println("   *****WMTSTileMatrix******");
373
                System.out.println("   scaleDenominator:" + getScaleDenominator());
374
                if(topLeftCorner != null)
375
                        System.out.println("   topLeftCorner:" + topLeftCorner[0] + ", " + topLeftCorner[1]);
376
                System.out.println("   tileWidth:" + getTileWidth());
377
                System.out.println("   tileHeight:" + getTileHeight());
378
                System.out.println("   matrixWidth:" + getMatrixWidth());
379
                System.out.println("   matrixHeight:" + getMatrixHeight());
380
        }
381
}