Statistics
| Revision:

gvsig-raster / org.gvsig.raster.wmts / trunk / org.gvsig.raster.wmts / org.gvsig.raster.wmts.ogc / org.gvsig.raster.wmts.ogc.impl / src / main / java / org / gvsig / raster / wmts / ogc / impl / struct / WMTSTileMatrixImpl.java @ 2613

History | View | Annotate | Download (16.3 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.raster.wmts.ogc.impl.struct;
23

    
24
import java.awt.geom.Point2D;
25
import java.awt.geom.Rectangle2D;
26
import java.io.IOException;
27
import java.util.ArrayList;
28
import java.util.List;
29

    
30
import org.cresques.cts.IProjection;
31
import org.gvsig.fmap.crs.CRSFactory;
32
import org.gvsig.raster.wmts.ogc.struct.WMTSTile;
33
import org.gvsig.raster.wmts.ogc.struct.WMTSTileMatrix;
34
import org.gvsig.raster.wmts.ogc.struct.WMTSTileMatrixLimits;
35
import org.kxml2.io.KXmlParser;
36
import org.xmlpull.v1.XmlPullParserException;
37

    
38
/**
39
 * Description of a tile matrix
40
 * @author Nacho Brodin (nachobrodin@gmail.com)
41
 */
42
public abstract class WMTSTileMatrixImpl extends WMTSBaseStruct implements WMTSTileMatrix {
43
    private double                  scaleDenominator             = 0;
44
    private Rectangle2D             bboxTileMatrixSet            = null;
45
    private double[]                topLeftCorner                = null;
46
    private int                     tileWidth                    = 0;
47
    private int                     tileHeight                   = 0;
48
    private long                    matrixWidth                  = 0;
49
    private long                    matrixHeight                 = 0;
50
    private static final double     MTS_X_GRADO                  = 111319.490793274;
51
    protected boolean               forceChangeAxisOrder         = false;
52
    private double                  epsilon                      = 1e-6;
53
    private String                  tileMatrixSetSupportedCRS    = null;
54
        
55
    
56
        /**
57
         * Force to change the axis order read from the capabilities
58
         * @param force
59
         */
60
        public void setForceChangeAxisOrder(boolean force) {
61
                this.forceChangeAxisOrder = force;
62
        }
63
        
64
        /**
65
         * Sets the CRS supported by the parent
66
         * @param parentSupportedCRS
67
         */
68
        public void setSupportedCRS(String parentSupportedCRS) {
69
                this.tileMatrixSetSupportedCRS = parentSupportedCRS;
70
        }
71
        
72
        /**
73
         * Gets the CRS supported by the parent
74
         * @return
75
         */
76
        public String getSupportedCRS() {
77
                return this.tileMatrixSetSupportedCRS;
78
        }
79
        
80
        public void checkChangeAxis() {
81
                if(forceChangeAxisOrder) {
82
                        double aux = topLeftCorner[0];
83
                        topLeftCorner[0] = topLeftCorner[1];
84
                        topLeftCorner[1] = aux;
85
                        return;
86
                }
87
                
88
            if(tileMatrixSetSupportedCRS.contains("CRS:84") || tileMatrixSetSupportedCRS.contains("CRS84"))
89
                    return;
90
            
91
                //Para CRS no proyectados menos CRS:84 hay que cambiar de orden los ejes
92
                String epsgNumber = tileMatrixSetSupportedCRS.substring(tileMatrixSetSupportedCRS.lastIndexOf(":") + 1);
93
                try {
94
                        Integer.parseInt(epsgNumber);
95
                        IProjection projSrc = CRSFactory.getCRS("EPSG:" + epsgNumber);
96
                        if(projSrc != null && !projSrc.isProjected()) {
97
                                double aux = topLeftCorner[0];
98
                                topLeftCorner[0] = topLeftCorner[1];
99
                                topLeftCorner[1] = aux;
100
                        }
101
                } catch (NumberFormatException e) {
102
                        //No se invierte el orden de los ejes
103
                } catch (Exception e) {
104
                }
105
        }
106
        
107
        public void setBBoxTileMatrixSet(Rectangle2D bbox) {
108
                if(bboxTileMatrixSet == null)
109
                        this.bboxTileMatrixSet = bbox;
110
        }
111
        
112
        public Rectangle2D getBBoxTileMatrixSet() {
113
                return bboxTileMatrixSet;
114
        }
115

    
116
    /*public class InternalTileImpl implements WMTSTile {
117
            public int       wPx, hPx;
118
            public int       row, col;
119
            public double    ulx, uly, lrx, lry;
120
            public File      file;
121

122
            public InternalTileImpl(int wPx, int hPx, int row, int col, double ulx, double uly, double lrx, double lry) {
123
                    this.row = row;
124
                    this.col = col;
125
                    this.ulx = ulx;
126
                    this.uly = uly;
127
                    this.lrx = lrx;
128
                    this.lry = lry;
129
                    this.wPx = wPx;
130
                    this.hPx = hPx;
131
            }
132
            
133
            public double getULX() {
134
                    return ulx;
135
            }
136
            
137
            public double getULY() {
138
                    return uly;        
139
            }
140
            
141
            public double getLRX() {
142
                    return lrx;
143
            }
144
            
145
            public double getLRY() {
146
                    return lry;
147
            }
148
            
149
            public int getWidthPx() {
150
                    return wPx;
151
            }
152
            
153
            public int getHeightPx() {
154
                    return hPx;
155
            }
156
            
157
            public int getRow() {
158
                    return row;
159
            }
160
            
161
            public int getCol() {
162
                    return col;
163
            }
164
            
165
            public void setFile(File file) {
166
                    this.file = file;
167
            }
168
            
169
            public File getFile() {
170
                    return file;
171
            }
172
             
173
            
174
            public Point2D worldToRaster(Point2D pt) {
175
                    Point2D p = new Point2D.Double();
176
                    double psX = (lrx - ulx) / tileWidth;
177
                    double psY = (lry - uly) / tileHeight;
178
                    AffineTransform t = new AffineTransform(psX, 0, 0, psY, ulx - (psX / 2), uly + (psY / 2));
179
                    try {
180
                            t.inverseTransform(pt, p);
181
                    } catch (NoninvertibleTransformException e) {
182
                            return pt;
183
                    }
184
                    return p;
185
            }
186
            
187
            public WMTSTile cloneTile() {
188
                    InternalTileImpl status = new InternalTileImpl(wPx, hPx, row, col, ulx, uly, lrx, lry);
189
                    status.file = file;
190
                    return status;
191
            }
192
    }*/
193

    
194
    /**
195
     * Parses this service
196
     * @param parser
197
     * @param content
198
     * @throws IOException
199
     * @throws XmlPullParserException
200
     */
201
        public abstract void parse(KXmlParser parser, List<WMTSTileMatrix> list) throws IOException, XmlPullParserException; 
202
        
203
    
204
        public double getScaleDenominator() {
205
                return scaleDenominator;
206
        }
207

    
208
        public void setScaleDenominator(double scaleDenominator) {
209
                this.scaleDenominator = scaleDenominator;
210
        }
211

    
212
        public int getTileWidth() {
213
                return tileWidth;
214
        }
215

    
216
        public void setTileWidth(int tileWidth) {
217
                this.tileWidth = tileWidth;
218
        }
219

    
220
        public int getTileHeight() {
221
                return tileHeight;
222
        }
223

    
224
        public void setTileHeight(int tileHeight) {
225
                this.tileHeight = tileHeight;
226
        }
227

    
228
        public long getMatrixWidth() {
229
                return matrixWidth;
230
        }
231

    
232
        public void setMatrixWidth(long matrixWidth) {
233
                this.matrixWidth = matrixWidth;
234
        }
235

    
236
        public long getMatrixHeight() {
237
                return matrixHeight;
238
        }
239

    
240
        public void setMatrixHeight(long matrixHeight) {
241
                this.matrixHeight = matrixHeight;
242
        }
243

    
244
        public double[] getTopLeftCorner() {
245
                if(topLeftCorner == null)
246
                        topLeftCorner = new double[2];
247
                return topLeftCorner;
248
        }
249
        
250
    public void parse(KXmlParser parser) throws IOException, XmlPullParserException {
251
            
252
    }
253
    
254
    /**
255
     * Gets the width in world coordinates of a tile
256
     * @return
257
     */
258
    public double getWidthWCTile(boolean projected) {
259
            double pixelSpan = 0;
260
            if(!projected) {
261
                    /*if(getBBoxTileMatrixSet() != null)
262
                            return getBBoxTileMatrixSet().getWidth() / matrixWidth;
263
                    else {*/
264
                            pixelSpan = (scaleDenominator * 0.00028) / MTS_X_GRADO;
265
                    //}
266
            } else {
267
                    pixelSpan = (scaleDenominator * 0.00028);
268
            }
269
            
270
            double w = pixelSpan * tileWidth;
271
                if(((w - ((int)w)) > (1 - epsilon) || (w - ((int)w)) < epsilon))
272
                        return Math.round(w);
273
                return w;
274
    }
275
    
276
    /**
277
     * Gets the height in world coordinates of a tile
278
     * @return
279
     */
280
    public double getHeightWCTile(boolean projected) {
281
            double pixelSpan = 0;
282
            if(!projected) {
283
                    /*if(getBBoxTileMatrixSet() != null)
284
                            return getBBoxTileMatrixSet().getHeight() / matrixHeight;
285
                    else {*/
286
                            pixelSpan = (scaleDenominator * 0.00028) / MTS_X_GRADO;
287
                    //}
288
            } else {
289
                    pixelSpan = (scaleDenominator * 0.00028);
290
            }
291
            
292
            double h = pixelSpan * tileHeight;
293
                if(((h - ((int)h)) > (1 - epsilon) || (h - ((int)h)) < epsilon))
294
                        return Math.round(h);
295
                return h;
296
    }
297
    
298
    /**
299
     * This function will check if the request coordinates intersects with the tiles in the matrix. If a tile
300
     * intersects then this will be added to the list.
301
     * @deprecated this method was for grid subsets.   
302
     */
303
        public List<WMTSTile> intersects(boolean projected, WMTSTileMatrixLimits tileMatrixLimits, Rectangle2D request, Rectangle2D extentLayer) {
304
            double widthMtsTile = getWidthWCTile(projected);
305
            double heightMtsTile = getHeightWCTile(projected);
306

    
307
                double ulx, uly, lrx, lry;
308
            List<WMTSTile> list = new ArrayList<WMTSTile>();
309
            Rectangle2D r = new Rectangle2D.Double(0, 0, 0, 0);
310

    
311
            //Recorre la matriz de tiles calculando las coordenadas de cada tile
312
            //Para cada tile comprueba si intersecta con el ?rea seleccionada si es as?
313
            //mete el tile en la lista para devolverlo como resultado
314
            
315
            //cambiar esto por un conversor entre coordenadas pixel y reales
316
            
317
            int i = 0, j = 0;
318
            double initX = topLeftCorner[1] + (widthMtsTile * tileMatrixLimits.getMinTileCol());
319
            double initY = topLeftCorner[0] - (heightMtsTile * (tileMatrixLimits.getMinTileRow()));
320
            
321
            for (int row = tileMatrixLimits.getMinTileRow(); row <= tileMatrixLimits.getMaxTileRow(); row++) {
322
                    uly = initY - (heightMtsTile * i);
323
                        lry = uly - heightMtsTile;
324
                        j = 0;
325
                        for (int col = tileMatrixLimits.getMinTileCol(); col <= tileMatrixLimits.getMaxTileCol(); col++) {
326
                                ulx = initX + (widthMtsTile * j);
327
                                lrx = ulx + widthMtsTile;
328
                                r.setRect(Math.min(ulx, lrx), Math.min(uly, lry), Math.abs(ulx - lrx), Math.abs(uly - lry));
329
                                if(request.intersects(r) && r.intersects(extentLayer)) {
330
                                        list.add(new WMTSTileImpl(tileWidth, tileHeight, row, col, ulx, uly, lrx, lry));
331
                                }
332
                                j ++;
333
                        }
334
                        i ++;
335
                }
336
            
337
            return list;
338
    }
339
    
340
    /**
341
     * This function will check if the request coordinates intersects with the tiles in the matrix. If a tile
342
     * intersects then this will be added to the list.  
343
     */
344
        public List<WMTSTile> intersects(boolean projected, Rectangle2D request, Rectangle2D extentLayer) {
345
            double widthWorldCoordTile = getWidthWCTile(projected);
346
            double heightWorldCoordTile = getHeightWCTile(projected); 
347

    
348
                double ulx, uly, lrx, lry;
349
                List<WMTSTile> list = new ArrayList<WMTSTile>();
350
            Rectangle2D r = new Rectangle2D.Double(0, 0, 0, 0);
351

    
352
            //Recorre la matriz de tiles calculando las coordenadas de cada tile
353
            //Para cada tile comprueba si intersecta con el ?rea seleccionada si es as?
354
            //mete el tile en la lista para devolverlo como resultado
355
            
356
            double initX = topLeftCorner[0];
357
            double initY = topLeftCorner[1];
358
            
359
            int tileInitX = 0;
360
            int tileInitY = 0;
361
            int tileEndX = (int)(matrixWidth - 1);
362
            int tileEndY = (int)(matrixHeight - 1);
363
            
364
            if(request.getMinX() >= initX)
365
                    tileInitX = (int)((request.getMinX() - initX) / widthWorldCoordTile);
366
            if(request.getMaxY() <= initY)
367
                    tileInitY = (int)(Math.abs(request.getMaxY() - initY) / heightWorldCoordTile);
368
            if(request.getMaxX() <= (widthWorldCoordTile * matrixWidth))
369
                    tileEndX = (int)((request.getMaxX() - initX) / widthWorldCoordTile);
370
            if(request.getMinY() >= (heightWorldCoordTile * matrixHeight))
371
                    tileEndY = (int)(Math.abs(request.getMinY() - initY) / heightWorldCoordTile);
372
            
373
            for (int row = tileInitY; row <= tileEndY; row++) {
374
                    uly = initY - (heightWorldCoordTile * row);
375
                        lry = uly - heightWorldCoordTile;
376
                        for (int col = tileInitX; col <= tileEndX; col++) {
377
                                ulx = initX + (widthWorldCoordTile * col);
378
                                lrx = ulx + widthWorldCoordTile;
379
                                r.setRect(Math.min(ulx, lrx), Math.min(uly, lry), Math.abs(ulx - lrx), Math.abs(uly - lry));
380
                                //El segundo intersects es necesario porque el extent de la capa puede variar por cada nivel de 
381
                                //resoluci?n en caso de que haya una lista de TileMatrix en el capabilities
382
                                if(row < matrixHeight && col < matrixWidth) {
383
                                        if(request.intersects(r) && r.intersects(extentLayer)) { 
384
                                                list.add(new WMTSTileImpl(tileWidth, tileHeight, row, col, ulx, uly, lrx, lry));
385
                                        }
386
                                }
387
                        }
388
                }
389
            
390
//            int i = 0, j = 0;
391
//            for (int row = 0; row < matrixHeight; row++) {
392
//                    uly = initY - (heightMtsTile * i);
393
//                        lry = uly - heightMtsTile;
394
//                        j = 0;
395
//                        for (int col = 0; col < matrixWidth; col++) {
396
//                                ulx = initX + (widthMtsTile * j);
397
//                                lrx = ulx + widthMtsTile;
398
//                                r.setRect(Math.min(ulx, lrx), Math.min(uly, lry), Math.abs(ulx - lrx), Math.abs(uly - lry));
399
//                                if(request.intersects(r)) {
400
//                                        list.add(new Tile(tileWidth, tileHeight, row, col, ulx, uly, lrx, lry));
401
//                                }
402
//                                j ++;
403
//                        }
404
//                        i ++;
405
//                }
406
            
407
            return list;
408
    }
409
        
410
    
411
    /**
412
     * This function will check if the request coordinates intersects with the tiles in the matrix. If a tile
413
     * intersects then this will be added to the list.  
414
     */
415
        public List<WMTSTile> contains(boolean projected, Point2D point, Rectangle2D extentLayer) {
416
                double widthMtsTile = getWidthWCTile(projected); //getWidthMtsTile(projected);
417
            double heightMtsTile = getHeightWCTile(projected); //getHeightMtsTile(projected);
418

    
419
                double ulx, uly, lrx, lry;
420
                List<WMTSTile> list = new ArrayList<WMTSTile>();
421
            Rectangle2D r = new Rectangle2D.Double(0, 0, 0, 0);
422

    
423
            //Recorre la matriz de tiles calculando las coordenadas de cada tile
424
            //Para cada tile comprueba si intersecta con el ?rea seleccionada si es as?
425
            //mete el tile en la lista para devolverlo como resultado
426
            
427
            int i = 0, j = 0;
428
            double initX = topLeftCorner[1];
429
            double initY = topLeftCorner[0];
430
            
431
            //cambiar esto por un conversor entre coordenadas pixel y reales
432
            for (int row = 0; row < matrixHeight; row++) {
433
                    uly = initY - (heightMtsTile * i);
434
                        lry = uly - heightMtsTile;
435
                        j = 0;
436
                        for (int col = 0; col < matrixWidth; col++) {
437
                                ulx = initX + (widthMtsTile * j);
438
                                lrx = ulx + widthMtsTile;
439
                                r.setRect(Math.min(ulx, lrx), Math.min(uly, lry), Math.abs(ulx - lrx), Math.abs(uly - lry));
440
                                if(r.contains(point)) {
441
                                        list.add(new WMTSTileImpl(tileWidth, tileHeight, row, col, ulx, uly, lrx, lry));
442
                                }
443
                                j ++;
444
                        }
445
                        i ++;
446
                }
447
            
448
            return list;
449
    }
450
    
451
    /**
452
     * This function will check if the request coordinates intersects with the tiles in the matrix. If a tile
453
     * intersects then this will be added to the list.  
454
     */
455
        public List<WMTSTile> contains(boolean projected, WMTSTileMatrixLimits tileMatrixLimits, Point2D point, Rectangle2D extentLayer) {
456
                double widthMtsTile = getWidthWCTile(projected);
457
            double heightMtsTile = getHeightWCTile(projected);
458

    
459
                double ulx, uly, lrx, lry;
460
                List<WMTSTile> list = new ArrayList<WMTSTile>();
461
            Rectangle2D r = new Rectangle2D.Double(0, 0, 0, 0);
462

    
463
            //Recorre la matriz de tiles calculando las coordenadas de cada tile
464
            //Para cada tile comprueba si intersecta con el ?rea seleccionada si es as?
465
            //mete el tile en la lista para devolverlo como resultado
466
            
467
            //cambiar esto por un conversor entre coordenadas pixel y reales
468
            
469
            int i = 0, j = 0;
470
            double initX = topLeftCorner[1] + (widthMtsTile * tileMatrixLimits.getMinTileCol());
471
            double initY = topLeftCorner[0] - (heightMtsTile * (tileMatrixLimits.getMinTileRow()));
472
            
473
            for (int row = tileMatrixLimits.getMinTileRow(); row <= tileMatrixLimits.getMaxTileRow(); row++) {
474
                    uly = initY - (heightMtsTile * i);
475
                        lry = uly - heightMtsTile;
476
                        j = 0;
477
                        for (int col = tileMatrixLimits.getMinTileCol(); col <= tileMatrixLimits.getMaxTileCol(); col++) {
478
                                ulx = initX + (widthMtsTile * j);
479
                                lrx = ulx + widthMtsTile;
480
                                r.setRect(Math.min(ulx, lrx), Math.min(uly, lry), Math.abs(ulx - lrx), Math.abs(uly - lry));
481
                                if(r.contains(point)) {
482
                                        list.add(new WMTSTileImpl(tileWidth, tileHeight, row, col, ulx, uly, lrx, lry));
483
                                }
484
                                j ++;
485
                        }
486
                        i ++;
487
                }
488
            
489
            return list;
490
    }
491
        
492
        public void print() {
493
                System.out.println("   *****WMTSTileMatrix******");
494
                System.out.println("   scaleDenominator:" + getScaleDenominator());
495
                if(topLeftCorner != null)
496
                        System.out.println("   topLeftCorner:" + topLeftCorner[0] + ", " + topLeftCorner[1]);
497
                System.out.println("   tileWidth:" + getTileWidth());
498
                System.out.println("   tileHeight:" + getTileHeight());
499
                System.out.println("   matrixWidth:" + getMatrixWidth());
500
                System.out.println("   matrixHeight:" + getMatrixHeight());
501
        }
502
}