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 |
} |