svn-gvsig-desktop / tags / v1_1_Build_1000 / libraries / libCq_CMS_praster / src / org / cresques / io / GdalFile.java @ 11885
History | View | Annotate | Download (67.8 KB)
1 | 8026 | nacho | /*
|
---|---|---|---|
2 | * Cresques Mapping Suite. Graphic Library for constructing mapping applications.
|
||
3 | *
|
||
4 | * Copyright (C) 2004-5.
|
||
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
|
||
19 | *
|
||
20 | * For more information, contact:
|
||
21 | *
|
||
22 | * cresques@gmail.com
|
||
23 | */
|
||
24 | package org.cresques.io; |
||
25 | |||
26 | import java.awt.Image; |
||
27 | import java.awt.geom.AffineTransform; |
||
28 | import java.awt.geom.NoninvertibleTransformException; |
||
29 | import java.awt.geom.Point2D; |
||
30 | import java.awt.geom.Rectangle2D; |
||
31 | import java.awt.image.BufferedImage; |
||
32 | import java.io.IOException; |
||
33 | import java.util.Vector; |
||
34 | |||
35 | import org.cresques.cts.ICoordTrans; |
||
36 | import org.cresques.cts.IProjection; |
||
37 | import org.cresques.io.data.BandList; |
||
38 | import org.cresques.io.data.RasterBuf; |
||
39 | import org.cresques.io.datastruct.Metadata; |
||
40 | import org.cresques.io.datastruct.Palette; |
||
41 | import org.cresques.io.exceptions.NotSupportedExtensionException; |
||
42 | import org.cresques.io.exceptions.SupersamplingNotSupportedException; |
||
43 | import org.cresques.px.Extent; |
||
44 | import org.cresques.util.Utilities; |
||
45 | |||
46 | import es.gva.cit.jgdal.Gdal; |
||
47 | import es.gva.cit.jgdal.GdalBuffer; |
||
48 | import es.gva.cit.jgdal.GdalException; |
||
49 | import es.gva.cit.jgdal.GdalRasterBand; |
||
50 | import es.gva.cit.jgdal.GeoTransform; |
||
51 | |||
52 | /**
|
||
53 | * Soporte 'nativo' para ficheros desde GDAL.
|
||
54 | * Este conjunto de funcionalidades est? tomado de manera casi literal
|
||
55 | * del soporte para ECW de ermapper.<br>
|
||
56 | * Probablemente esto deber?a formar parte del JNI que recubre a la
|
||
57 | * librer?a en C extraida de gdal.<br>
|
||
58 | * Lo pongo aqu? a manera de ejemplo de como atacar un formato binario
|
||
59 | * desde Java.<br><br>
|
||
60 | * @author Luis W. Sevilla.
|
||
61 | */
|
||
62 | |||
63 | class GdalNative extends Gdal { |
||
64 | static boolean WITH_OVERVIEWS = true; |
||
65 | private GdalFile driver = null; |
||
66 | private String ext = ""; |
||
67 | private String fileName = null; |
||
68 | /**
|
||
69 | * Nombre corto del driver de gdal
|
||
70 | */
|
||
71 | private String shortName = ""; |
||
72 | public GeoTransform trans = null; |
||
73 | /**
|
||
74 | * Contorno en coordenadas geogr?ficas. (y Extent del raster).
|
||
75 | */
|
||
76 | public Contour bBoxRot = new Contour(); |
||
77 | /**
|
||
78 | * Contorno en coordenadas geogr?ficas sin rotaci?n aplicada. Esto es util para poder
|
||
79 | * calcular los pixeles necesarios que se van a leer del raster. Cuando el raster no tiene
|
||
80 | * rotaci?n coincide con esq.
|
||
81 | */
|
||
82 | public Contour bBoxWithoutRot = new Contour(); |
||
83 | public int width = 0, height = 0; |
||
84 | public double originX = 0D, originY = 0D; |
||
85 | public String version = ""; |
||
86 | private int alpha = 0; |
||
87 | protected int rBandNr = 1, gBandNr = 2, bBandNr = 3, aBandNr = 4; |
||
88 | private int dataType = GDT_Byte; |
||
89 | /**
|
||
90 | * Metadatos leidos de la imagen
|
||
91 | */
|
||
92 | private Metadata metadata = null; |
||
93 | private boolean georeferenced = true; |
||
94 | |||
95 | /**
|
||
96 | * Vectores que contiene los desplazamientos de un pixel cuando hay supersampling.
|
||
97 | * , es decir el n?mero de pixels de pantalla que tiene un pixel de imagen. Como todos
|
||
98 | * los pixeles no tienen el mismo ancho y alto ha de meterse en un array y no puede ser
|
||
99 | * una variable. Adem?s hay que tener en cuenta que el primer y ?ltimo pixel son de
|
||
100 | * distinto tama?o que el resto.
|
||
101 | */
|
||
102 | public int[] stepArrayX = null, stepArrayY = null; |
||
103 | protected GdalRasterBand[] gdalBands = null; |
||
104 | private double lastReadLine = -1; |
||
105 | private int currentFullWidth = -1; |
||
106 | private int currentFullHeight = -1; |
||
107 | private int currentViewWidth = -1; |
||
108 | private int currentViewHeight = -1; |
||
109 | private double currentViewX = 0D; |
||
110 | private double currentViewY = 0D; |
||
111 | private double viewportScaleX = 0D; |
||
112 | private double viewportScaleY = 0D; |
||
113 | private double wcWidth = 0D; |
||
114 | private double stepX = 0D; |
||
115 | private double stepY = 0D; |
||
116 | public boolean isSupersampling = false; |
||
117 | 8631 | nacho | private boolean[] orientation; |
118 | 8026 | nacho | |
119 | /**
|
||
120 | * Overview usada en el ?ltimo setView
|
||
121 | */
|
||
122 | int currentOverview = -1; |
||
123 | |||
124 | // Polilinea con extent
|
||
125 | public class Contour extends Vector { |
||
126 | final private static long serialVersionUID = -3370601314380922368L; |
||
127 | public double minX = Double.MAX_VALUE, minY = Double.MAX_VALUE; |
||
128 | public double maxX = -Double.MAX_VALUE, maxY = -Double.MAX_VALUE; |
||
129 | public Contour() {
|
||
130 | super();
|
||
131 | } |
||
132 | public void add(Point2D pt) { |
||
133 | super.add(pt);
|
||
134 | if (pt.getX() > maxX) maxX = pt.getX();
|
||
135 | if (pt.getX() < minX) minX = pt.getX();
|
||
136 | if (pt.getY() > maxY) maxY = pt.getY();
|
||
137 | if (pt.getY() < minY) minY = pt.getY();
|
||
138 | } |
||
139 | } |
||
140 | |||
141 | public GdalNative(String fName, GdalFile driver) throws GdalException, IOException { |
||
142 | super();
|
||
143 | this.driver = driver;
|
||
144 | init(fName); |
||
145 | } |
||
146 | 10645 | nacho | |
147 | public Point2D rasterToWorld(Point2D pt) { |
||
148 | double x = bBoxWithoutRot.minX + ((pt.getX() * (bBoxWithoutRot.maxX - bBoxWithoutRot.minX)) / width);
|
||
149 | double y = bBoxWithoutRot.maxY - ((pt.getY() * (bBoxWithoutRot.maxY - bBoxWithoutRot.minY)) / height);
|
||
150 | Point2D ptRes = new Point2D.Double(x, y); |
||
151 | return ptRes;
|
||
152 | } |
||
153 | 8026 | nacho | |
154 | /**
|
||
155 | 8631 | nacho | * <P>
|
156 | 8026 | nacho | * Calcula la bounding box en la que est? metido el raster teniendo en cuenta
|
157 | 8631 | nacho | * el tama?o de pixel y la rotaci?n. Esto lo hace con los valores de transformaci?n
|
158 | * leidos por gdal en el vector de 6 elementos adfGeoTransform donde cada elemento
|
||
159 | * del vector represnta los siguientes valores
|
||
160 | * </P>
|
||
161 | * <UL>
|
||
162 | * <LI>0-origen X</LI>
|
||
163 | * <LI>1-tama?o de pixel X</LI>
|
||
164 | * <LI>2-shear en X</LI>
|
||
165 | * <LI>3-origen Y</LI>
|
||
166 | * <LI>4-shear en Y</LI>
|
||
167 | * <LI>5-Tama?o de pixel Y</LI>
|
||
168 | * </UL>
|
||
169 | * <P>
|
||
170 | * Para el calculo de una esquina aplicamos la formula siguiente:<BR>
|
||
171 | * PtoX = originX + pixelSizeX * x + shearX * y;<BR>
|
||
172 | * PtoY = originY + shearY * x + pixelSizeY * y;<BR>
|
||
173 | * Aplicandolo a las cuatro esquinas sustituimos en cada una de ellas por.
|
||
174 | * </P>
|
||
175 | * <UL>
|
||
176 | * <LI>Esquina superior izquierda: x = 0; y = 0;</LI>
|
||
177 | * <LI>Esquina superior derecha: x = MaxX; y = 0;</LI>
|
||
178 | * <LI>Esquina inferior izquierda: x = 0; y = MaxY;</LI>
|
||
179 | * <LI>Esquina inferior derecha: x = MaxX; y = MaxY;</LI>
|
||
180 | * </UL>
|
||
181 | * <P>
|
||
182 | * quedandonos en los cuatro casos:
|
||
183 | * </P>
|
||
184 | * <UL>
|
||
185 | * <LI>Esquina superior izquierda: originX; originY;</LI>
|
||
186 | * <LI>Esquina superior derecha: PtoX = originX + pixelSizeX * x; PtoY = originY + shearY * x;</LI>
|
||
187 | * <LI>Esquina inferior izquierda: PtoX = originX + shearX * y; PtoY = originY + pixelSizeY * y;</LI>
|
||
188 | * <LI>Esquina inferior derecha: PtoX = originX + pixelSizeX * x + shearX * y; PtoY = originY + shearY * x + pixelSizeY * y;</LI>
|
||
189 | * </UL>
|
||
190 | *
|
||
191 | 8026 | nacho | */
|
192 | private void boundingBoxFromGeoTransform(){ |
||
193 | double geoX = 0D, geoY = 0D; |
||
194 | 8631 | nacho | |
195 | //Upper left corner
|
||
196 | 8026 | nacho | bBoxRot.add(new Point2D.Double(trans.adfgeotransform[0], trans.adfgeotransform[3])); |
197 | 8631 | nacho | |
198 | //Lower left corner
|
||
199 | 8026 | nacho | geoX = trans.adfgeotransform[0] + trans.adfgeotransform[2] * height; |
200 | geoY = trans.adfgeotransform[3] + trans.adfgeotransform[5] * height; |
||
201 | bBoxRot.add(new Point2D.Double(geoX, geoY)); |
||
202 | |||
203 | 8631 | nacho | //Upper right corner
|
204 | 8026 | nacho | geoX = trans.adfgeotransform[0] + trans.adfgeotransform[1] * width; |
205 | geoY = trans.adfgeotransform[3] + trans.adfgeotransform[4] * width; |
||
206 | bBoxRot.add(new Point2D.Double(geoX, geoY)); |
||
207 | |||
208 | 8631 | nacho | //Lower right corner
|
209 | 8026 | nacho | geoX = trans.adfgeotransform[0] + trans.adfgeotransform[1] * width + trans.adfgeotransform[2] * height; |
210 | geoY = trans.adfgeotransform[3] + trans.adfgeotransform[4] * width + trans.adfgeotransform[5] * height; |
||
211 | bBoxRot.add(new Point2D.Double(geoX, geoY)); |
||
212 | |||
213 | //TODO: ?OJO! con coordenadas geogr?ficas
|
||
214 | } |
||
215 | |||
216 | /**
|
||
217 | * Calcula la bounding box en la que est? metido el raster teniendo en cuenta
|
||
218 | * el tama?o de pixel y la rotaci?n.
|
||
219 | */
|
||
220 | private void boundingBoxWithoutRotation(){ |
||
221 | double ox = trans.adfgeotransform[0]; |
||
222 | double oy = trans.adfgeotransform[3]; |
||
223 | double resx = trans.adfgeotransform[1]; |
||
224 | double resy = trans.adfgeotransform[5]; |
||
225 | 8631 | nacho | |
226 | 8026 | nacho | bBoxWithoutRot.add(new Point2D.Double(ox, oy)); |
227 | bBoxWithoutRot.add(new Point2D.Double(ox + resx * width, oy)); |
||
228 | bBoxWithoutRot.add(new Point2D.Double(ox, oy + resy * height)); |
||
229 | bBoxWithoutRot.add(new Point2D.Double(ox + resx * width, oy + resy * height)); |
||
230 | 8631 | nacho | |
231 | 8026 | nacho | //TODO: ?OJO! con coordenadas geogr?ficas
|
232 | } |
||
233 | |||
234 | private void init(String fName) throws GdalException, IOException { |
||
235 | fileName = fName; |
||
236 | open(fName,GA_ReadOnly); |
||
237 | ext = fName.toLowerCase().substring(fName.lastIndexOf('.')+1); |
||
238 | if (ext.compareTo("tif") == 0) |
||
239 | WITH_OVERVIEWS = false;
|
||
240 | width = getRasterXSize(); |
||
241 | height = getRasterYSize(); |
||
242 | setDataType(this.getRasterBand(1).getRasterDataType()); |
||
243 | shortName = getDriverShortName(); |
||
244 | metadata = new Metadata(getMetadata());
|
||
245 | |||
246 | //Asignamos la interpretaci?n de color leida por gdal a cada banda. Esto nos sirve
|
||
247 | //para saber que banda de la imagen va asignada a cada banda de visualizaci?n (ARGB)
|
||
248 | metadata.initColorInterpretation(getRasterCount()); |
||
249 | metadata.initNoDataByBand(getRasterCount()); |
||
250 | for(int i = 0; i < getRasterCount(); i++){ |
||
251 | GdalRasterBand rb = getRasterBand(i + 1);
|
||
252 | String colorInt = getColorInterpretationName(rb.getRasterColorInterpretation());
|
||
253 | metadata.setNoDataValue(i, rb.getRasterNoDataValue()); |
||
254 | metadata.setColorInterpValue(i, colorInt); |
||
255 | if(colorInt.equals("Red")) |
||
256 | rBandNr = i + 1;
|
||
257 | if(colorInt.equals("Green")) |
||
258 | gBandNr = i + 1;
|
||
259 | if(colorInt.equals("Blue")) |
||
260 | bBandNr = i + 1;
|
||
261 | if(colorInt.equals("Alpha")) |
||
262 | aBandNr = i + 1;
|
||
263 | } |
||
264 | |||
265 | try{
|
||
266 | trans = getGeoTransform(); |
||
267 | 10645 | nacho | |
268 | boolean isCorrect = false; |
||
269 | for(int i = 0; i < trans.adfgeotransform.length; i++) |
||
270 | if(trans.adfgeotransform[i] != 0) |
||
271 | isCorrect = true;
|
||
272 | if(!isCorrect)
|
||
273 | throw new GdalException(""); |
||
274 | |||
275 | 8026 | nacho | boundingBoxWithoutRotation(); |
276 | boundingBoxFromGeoTransform(); |
||
277 | |||
278 | this.georeferenced = true; |
||
279 | }catch(GdalException exc){
|
||
280 | bBoxRot.add(new Point2D.Double(0, 0)); |
||
281 | bBoxRot.add(new Point2D.Double(width, 0)); |
||
282 | bBoxRot.add(new Point2D.Double(0, height)); |
||
283 | 8631 | nacho | bBoxRot.add(new Point2D.Double(width, height)); |
284 | bBoxWithoutRot = bBoxRot; |
||
285 | 8026 | nacho | this.georeferenced = false; |
286 | } |
||
287 | 10645 | nacho | readPalette(); |
288 | 8026 | nacho | } |
289 | |||
290 | 10645 | nacho | public void readPalette(){ |
291 | //Cargamos la tabla de color si la tiene
|
||
292 | try{
|
||
293 | gdalBands = new GdalRasterBand[1]; |
||
294 | gdalBands[0] = getRasterBand(1); |
||
295 | if(gdalBands[0] != null && gdalBands[0].getRasterColorTable() != null){ |
||
296 | Palette palette = new Palette();
|
||
297 | palette.createPaletteFromGdalColorTable(gdalBands[0].getRasterColorTable());
|
||
298 | driver.setPalette(palette); |
||
299 | } |
||
300 | }catch(GdalException exc){
|
||
301 | //No cargamos la tabla de color
|
||
302 | } |
||
303 | } |
||
304 | |||
305 | 8026 | nacho | /**
|
306 | * Asigna el valor de Alpha
|
||
307 | * @param a
|
||
308 | */
|
||
309 | public void setAlpha(int a) { |
||
310 | alpha = a; |
||
311 | } |
||
312 | |||
313 | /**
|
||
314 | * Asigna el tipo de dato
|
||
315 | * @param dt entero que representa el tipo de dato
|
||
316 | */
|
||
317 | public void setDataType(int dt) { |
||
318 | dataType = dt; |
||
319 | } |
||
320 | |||
321 | /**
|
||
322 | * Obtiene el tipo de dato
|
||
323 | * @return entero que representa el tipo de dato
|
||
324 | */
|
||
325 | public int getDataType() { |
||
326 | return dataType;
|
||
327 | } |
||
328 | |||
329 | // Supone rasters no girados
|
||
330 | public Point2D worldToRaster(Point2D pt) { |
||
331 | double x = (((double) currentFullWidth) / (bBoxWithoutRot.maxX - bBoxWithoutRot.minX)) * (pt.getX() - bBoxWithoutRot.minX); |
||
332 | double y = (((double) currentFullHeight) / (bBoxWithoutRot.maxY - bBoxWithoutRot.minY)) * (bBoxWithoutRot.maxY - pt.getY()); |
||
333 | Point2D ptRes = new Point2D.Double(x, y); |
||
334 | return ptRes;
|
||
335 | } |
||
336 | |||
337 | /**
|
||
338 | * Calcula el overview a usar. Hay que tener en cuenta que tenemos que tener calculadas las variables
|
||
339 | * viewPortScale, currentFullWidth y currentFulHeight
|
||
340 | * @param coordenada pixel expresada en double que indica la posici?n superior izquierda
|
||
341 | * @throws GdalException
|
||
342 | */
|
||
343 | 8631 | nacho | private void calcOverview(Point2D tl, Point2D br, boolean[] orientation) throws GdalException{ |
344 | 8026 | nacho | gdalBands[0] = getRasterBand(1); |
345 | currentOverview = -1;
|
||
346 | if (WITH_OVERVIEWS && gdalBands[0].getOverviewCount() > 0) { |
||
347 | GdalRasterBand ovb = null;
|
||
348 | for (int i = gdalBands[0].getOverviewCount()-1; i > 0; i--) { |
||
349 | ovb = gdalBands[0].getOverview(i);
|
||
350 | if (ovb.getRasterBandXSize()>getRasterXSize()*viewportScaleX) {
|
||
351 | currentOverview = i; |
||
352 | viewportScaleX *= ((double) width/(double) ovb.getRasterBandXSize()); |
||
353 | viewportScaleY *= ((double) height/(double) ovb.getRasterBandYSize()); |
||
354 | stepX = 1D/viewportScaleX;
|
||
355 | stepY = 1D/viewportScaleY;
|
||
356 | currentFullWidth = ovb.getRasterBandXSize(); |
||
357 | currentFullHeight = ovb.getRasterBandYSize(); |
||
358 | 8631 | nacho | if(!orientation[0])//Invierte la orientaci?n en X |
359 | currentViewX = (width - tl.getX()) - (br.getX()-tl.getX()); |
||
360 | else
|
||
361 | currentViewX = tl.getX(); |
||
362 | if(orientation[1])//Invierte la orientaci?n en Y |
||
363 | lastReadLine = (height - tl.getY()) - (br.getY()-tl.getY()); |
||
364 | else
|
||
365 | lastReadLine = tl.getY(); |
||
366 | 8026 | nacho | break;
|
367 | } |
||
368 | } |
||
369 | } |
||
370 | } |
||
371 | |||
372 | public void setView(double dWorldTLX, double dWorldTLY, |
||
373 | double dWorldBRX, double dWorldBRY, |
||
374 | 8631 | nacho | int nWidth, int nHeight, boolean[] orientation) { |
375 | this.orientation = orientation;
|
||
376 | 8026 | nacho | currentFullWidth = width; |
377 | currentFullHeight = height; |
||
378 | Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY)); |
||
379 | Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY)); |
||
380 | // Calcula cual es la primera l?nea a leer;
|
||
381 | currentViewWidth = nWidth; |
||
382 | currentViewHeight = nHeight; |
||
383 | wcWidth = Math.abs(br.getX() - tl.getX());
|
||
384 | |||
385 | 8631 | nacho | if(!orientation[0]) //Invierte la orientaci?n en X |
386 | currentViewX = (width - tl.getX()) - (br.getX()-tl.getX()); |
||
387 | else
|
||
388 | currentViewX = tl.getX(); |
||
389 | |||
390 | 8026 | nacho | viewportScaleX = (double) currentViewWidth/(br.getX()-tl.getX());
|
391 | viewportScaleY = (double) currentViewHeight/(br.getY()-tl.getY());
|
||
392 | stepX = 1D/viewportScaleX;
|
||
393 | stepY = 1D/viewportScaleY;
|
||
394 | |||
395 | 8631 | nacho | if(orientation[1])//Invierte la orientaci?n en Y |
396 | lastReadLine = (height - tl.getY()) - (br.getY()-tl.getY()); |
||
397 | else
|
||
398 | lastReadLine = tl.getY(); |
||
399 | 8026 | nacho | |
400 | //Para lectura del renderizado (ARGB). readWindow selecciona las bandas que necesita.
|
||
401 | try {
|
||
402 | // calcula el overview a usar
|
||
403 | gdalBands = new GdalRasterBand[4]; |
||
404 | 8631 | nacho | calcOverview(tl, br, orientation); |
405 | 8026 | nacho | calcArraySteps(); |
406 | |||
407 | // Selecciona las bandas y los overviews necesarios
|
||
408 | gdalBands[0] = getRasterBand(rBandNr);
|
||
409 | gdalBands[1] = gdalBands[0]; |
||
410 | gdalBands[2] = gdalBands[1]; |
||
411 | setDataType(gdalBands[0].getRasterDataType());
|
||
412 | if(this.getRasterCount() >= 2) { |
||
413 | gdalBands[1] = getRasterBand(gBandNr);
|
||
414 | gdalBands[2] = gdalBands[1]; |
||
415 | } |
||
416 | if(this.getRasterCount() >= 3) |
||
417 | gdalBands[2] = getRasterBand(bBandNr);
|
||
418 | if(metadata.isAlphaBand())
|
||
419 | gdalBands[3] = getRasterBand(aBandNr);
|
||
420 | |||
421 | |||
422 | if (currentOverview > 0) { |
||
423 | gdalBands[0] = gdalBands[0].getOverview(currentOverview); |
||
424 | gdalBands[1] = gdalBands[0]; |
||
425 | gdalBands[2] = gdalBands[1]; |
||
426 | if(this.getRasterCount() >= 2) { |
||
427 | gdalBands[1] = gdalBands[1].getOverview(currentOverview); |
||
428 | gdalBands[2] = gdalBands[1]; |
||
429 | } |
||
430 | if(this.getRasterCount() >= 3) |
||
431 | gdalBands[2] = gdalBands[2].getOverview(currentOverview); |
||
432 | if(metadata.isAlphaBand())
|
||
433 | gdalBands[3] = gdalBands[3].getOverview(currentOverview); |
||
434 | |||
435 | } |
||
436 | |||
437 | } catch (GdalException e) {
|
||
438 | e.printStackTrace(); |
||
439 | } |
||
440 | } |
||
441 | |||
442 | /**
|
||
443 | * Esta funci?n calcula los arrays de steps en X e Y para que cuando hay supersampleo
|
||
444 | * se aplique el filtro solo a la esquina superior izquierda de cada pixel.
|
||
445 | */
|
||
446 | private void calcArraySteps(){ |
||
447 | if(stepX < 1 && stepY < 1){ |
||
448 | isSupersampling = true;
|
||
449 | int w = (int) (Math.ceil(((double)currentViewWidth) * stepX) + 1); |
||
450 | this.stepArrayX = new int[w]; |
||
451 | for (double j = Math.abs(currentViewX - ((int)currentViewX)); j < w; j += stepX) |
||
452 | stepArrayX[(int)(j)] ++;
|
||
453 | |||
454 | int h = (int) (Math.ceil(((double)currentViewHeight) * stepY) + 1); |
||
455 | this.stepArrayY = new int[h]; |
||
456 | 10645 | nacho | for (double j = Math.abs(lastReadLine - ((int)lastReadLine)); j < h; j += stepY) |
457 | 8026 | nacho | stepArrayY[(int)(j)] ++;
|
458 | }else{
|
||
459 | isSupersampling = false;
|
||
460 | this.stepArrayX = this.stepArrayY = null; |
||
461 | } |
||
462 | } |
||
463 | |||
464 | int lastY = -1; |
||
465 | |||
466 | /**
|
||
467 | * Lee una l?nea de bytes
|
||
468 | * @param line Buffer donde se cargan los datos
|
||
469 | * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
|
||
470 | * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
|
||
471 | * por la izquierda a mitad de pixel
|
||
472 | * @param gdalBuffer Buffer con la l?nea de datos original
|
||
473 | */
|
||
474 | private void readLine(byte[][] line, double initOffset, GdalBuffer[] gdalBuffer){ |
||
475 | double j = 0D; |
||
476 | int i = 0; |
||
477 | for (int iBand = 0; iBand < gdalBuffer.length; iBand++){ |
||
478 | for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) { |
||
479 | line[iBand][i] = gdalBuffer[iBand].buffByte[(int) j];
|
||
480 | } |
||
481 | } |
||
482 | } |
||
483 | |||
484 | /**
|
||
485 | * Lee una l?nea de shorts
|
||
486 | * @param line Buffer donde se cargan los datos
|
||
487 | * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
|
||
488 | * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
|
||
489 | * por la izquierda a mitad de pixel
|
||
490 | * @param gdalBuffer Buffer con la l?nea de datos original
|
||
491 | */
|
||
492 | private void readLine(short[][] line, double initOffset, GdalBuffer[] gdalBuffer){ |
||
493 | double j = 0D; |
||
494 | int i = 0; |
||
495 | for (int iBand = 0; iBand < gdalBuffer.length; iBand++){ |
||
496 | for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) { |
||
497 | line[iBand][i] = (short)(gdalBuffer[iBand].buffShort[(int) j] & 0xffff); |
||
498 | } |
||
499 | } |
||
500 | } |
||
501 | |||
502 | /**
|
||
503 | * Lee una l?nea de ints
|
||
504 | * @param line Buffer donde se cargan los datos
|
||
505 | * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
|
||
506 | * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
|
||
507 | * por la izquierda a mitad de pixel
|
||
508 | * @param gdalBuffer Buffer con la l?nea de datos original
|
||
509 | */
|
||
510 | private void readLine(int[][] line, double initOffset, GdalBuffer[] gdalBuffer){ |
||
511 | double j = 0D; |
||
512 | int i = 0; |
||
513 | for (int iBand = 0; iBand < gdalBuffer.length; iBand++){ |
||
514 | for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) { |
||
515 | line[iBand][i] = (gdalBuffer[iBand].buffInt[(int) j] & 0xffffffff); |
||
516 | } |
||
517 | } |
||
518 | } |
||
519 | |||
520 | /**
|
||
521 | * Lee una l?nea de float
|
||
522 | * @param line Buffer donde se cargan los datos
|
||
523 | * @param initOffset Desplazamiento inicial desde el margen izquierdo. Esto es necesario para cuando
|
||
524 | * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
|
||
525 | * por la izquierda a mitad de pixel
|
||
526 | * @param gdalBuffer Buffer con la l?nea de datos original
|
||
527 | */
|
||
528 | private void readLine(float[][] line, double initOffset, GdalBuffer[] gdalBuffer){ |
||
529 | double j = 0D; |
||
530 | int i = 0; |
||
531 | for (int iBand = 0; iBand < gdalBuffer.length; iBand++){ |
||
532 | for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) { |
||
533 | line[iBand][i] = gdalBuffer[iBand].buffFloat[(int) j];
|
||
534 | } |
||
535 | } |
||
536 | } |
||
537 | |||
538 | /**
|
||
539 | * Lee una l?nea de doubles
|
||
540 | * @param line Buffer donde se cargan los datos
|
||
541 | * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
|
||
542 | * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
|
||
543 | * por la izquierda a mitad de pixel
|
||
544 | * @param gdalBuffer Buffer con la l?nea de datos original
|
||
545 | */
|
||
546 | private void readLine(double[][] line, double initOffset, GdalBuffer[] gdalBuffer){ |
||
547 | double j = 0D; |
||
548 | int i = 0; |
||
549 | for (int iBand = 0; iBand < gdalBuffer.length; iBand++){ |
||
550 | for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) { |
||
551 | line[iBand][i] = gdalBuffer[iBand].buffDouble[(int) j];
|
||
552 | } |
||
553 | } |
||
554 | } |
||
555 | |||
556 | public void readLine(Object line) throws GdalException { |
||
557 | int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1); |
||
558 | 8475 | nacho | int x = (int) (currentViewX); |
559 | int y = (int) (lastReadLine); |
||
560 | 8026 | nacho | GdalBuffer r = null, g = null, b = null; |
561 | GdalBuffer a = new GdalBuffer();
|
||
562 | |||
563 | while(y >= gdalBands[0].getRasterBandYSize()) |
||
564 | y--; |
||
565 | |||
566 | if (x+w > gdalBands[0].getRasterBandXSize()) |
||
567 | w = gdalBands[0].getRasterBandXSize()-x;
|
||
568 | |||
569 | if(gdalBands[0].getRasterColorTable() != null){ |
||
570 | 10645 | nacho | /*Palette palette = new Palette();
|
571 | 8026 | nacho | palette.createPaletteFromGdalColorTable(gdalBands[0].getRasterColorTable());
|
572 | 10645 | nacho | driver.setPalette(palette);*/
|
573 | 8026 | nacho | r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType); |
574 | }else{
|
||
575 | a.buffByte = new byte[w]; |
||
576 | r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType); |
||
577 | g = b = r; |
||
578 | if (getRasterCount() > 1 && gdalBands[1] != null) |
||
579 | g = gdalBands[1].readRaster(x, y, w, 1, w, 1, dataType); |
||
580 | if (getRasterCount() > 2 && gdalBands[2] != null) |
||
581 | b = gdalBands[2].readRaster(x, y, w, 1, w, 1, dataType); |
||
582 | } |
||
583 | |||
584 | lastReadLine += stepY; |
||
585 | |||
586 | double initOffset = Math.abs(currentViewX - ((int)currentViewX)); |
||
587 | GdalBuffer[] bands = {r, g, b};
|
||
588 | |||
589 | if (dataType == GDT_Byte)
|
||
590 | readLine((byte[][])line, initOffset, bands); |
||
591 | else if (dataType == GDT_CInt16 || dataType == GDT_Int16 || dataType == GDT_UInt16) |
||
592 | readLine((short[][])line, initOffset, bands); |
||
593 | else if (dataType == GDT_CInt32 || dataType == GDT_Int32 || dataType == GDT_UInt32) |
||
594 | readLine((int[][])line, initOffset, bands); |
||
595 | else if(dataType == GDT_Float32 || dataType == GDT_CFloat32) |
||
596 | readLine((float[][])line, initOffset, bands); |
||
597 | else if(dataType == GDT_Float64 || dataType == GDT_CFloat64) |
||
598 | readLine((double[][])line, initOffset, bands); |
||
599 | |||
600 | return;
|
||
601 | } |
||
602 | |||
603 | /**
|
||
604 | * Lee una l?nea y la guarda cada elemento sobre un entero. Este entero representa
|
||
605 | * un valor ARGB
|
||
606 | * @param line Buffer sobre el que se escribe la linea
|
||
607 | * @return
|
||
608 | * @throws GdalException
|
||
609 | */
|
||
610 | int readLineRGBA(int[] line) throws GdalException { |
||
611 | int err = 0; |
||
612 | |||
613 | int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1); |
||
614 | int x = (int) currentViewX; |
||
615 | int y = (int) lastReadLine; |
||
616 | GdalBuffer r = null, g = null, b = null, p = null; |
||
617 | GdalBuffer a = new GdalBuffer();
|
||
618 | |||
619 | while(y >= gdalBands[0].getRasterBandYSize()) |
||
620 | y--; |
||
621 | |||
622 | if (x+w > gdalBands[0].getRasterBandXSize()) |
||
623 | w = gdalBands[0].getRasterBandXSize()-x;
|
||
624 | |||
625 | if(gdalBands[0].getRasterColorTable() != null){ |
||
626 | 10645 | nacho | /*Palette palette = new Palette();
|
627 | 8026 | nacho | palette.createPaletteFromGdalColorTable(gdalBands[0].getRasterColorTable());
|
628 | 10645 | nacho | driver.setPalette(palette);*/
|
629 | 8026 | nacho | r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType); |
630 | }else{
|
||
631 | |||
632 | r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType); |
||
633 | g = b = r; |
||
634 | if (getRasterCount() > 1 && gdalBands[1] != null) |
||
635 | g = gdalBands[1].readRaster(x, y, w, 1, w, 1, dataType); |
||
636 | if (getRasterCount() > 2 && gdalBands[2] != null) |
||
637 | b = gdalBands[2].readRaster(x, y, w, 1, w, 1, dataType); |
||
638 | |||
639 | if(metadata.isAlphaBand()){
|
||
640 | a = gdalBands[3].readRaster(x, y, w, 1, w, 1, GDT_Byte); |
||
641 | }else{
|
||
642 | a.buffByte = new byte[w]; |
||
643 | for (int i = 0;i < w;i++) |
||
644 | a.buffByte[i] = (byte)255; |
||
645 | } |
||
646 | } |
||
647 | lastReadLine += stepY; |
||
648 | |||
649 | int i=0; |
||
650 | double j = Math.abs(currentViewX - ((int)currentViewX)); |
||
651 | int alpha = (this.alpha & 0xff) << 24; |
||
652 | 8631 | nacho | |
653 | if(orientation[0]){ //Pixel size en X positivo |
||
654 | if (dataType == GDT_Byte){
|
||
655 | if(gdalBands[0].getRasterColorTable() != null){ |
||
656 | for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) { |
||
657 | int jInt = (int)(j); |
||
658 | line[i] = (alpha) + ((r.buffByte[jInt] & 0xff) << 16) + ((r.buffByte[jInt] & 0xff) << 8) + (r.buffByte[jInt] & 0xff); |
||
659 | } |
||
660 | }else{
|
||
661 | for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) { |
||
662 | int jInt = (int)(j); |
||
663 | line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + ((r.buffByte[jInt] & 0xff) << 16) + ((g.buffByte[jInt] & 0xff) << 8) + (b.buffByte[jInt] & 0xff); |
||
664 | } |
||
665 | } |
||
666 | }else if (dataType == GDT_CInt16 || dataType == GDT_Int16 || dataType == GDT_UInt16){ |
||
667 | if (g == null) // Sibgle Band (Typical DEM) |
||
668 | for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) { |
||
669 | int jInt = (int)(j); |
||
670 | line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + r.buffShort[jInt]; |
||
671 | } |
||
672 | else { // Multiband |
||
673 | // System.err.println("Raster 16bits multibanda");
|
||
674 | for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) { |
||
675 | int jInt = (int)(j); |
||
676 | line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) | (((r.buffShort[jInt] & 0xfff0) << 12) & 0xff0000 ) | |
||
677 | (((g.buffShort[jInt] & 0xfff0) << 4 ) & 0xff00 ) | |
||
678 | (((b.buffShort[jInt] & 0xfff0) >> 4 ) & 0xff ); |
||
679 | } |
||
680 | } |
||
681 | } |
||
682 | }else{ //Pixel size en X negativo |
||
683 | if (dataType == GDT_Byte){
|
||
684 | if(gdalBands[0].getRasterColorTable() != null){ |
||
685 | for (i=currentViewWidth - 1; i>=0 && j<r.getSize(); i--, j+=stepX) { |
||
686 | int jInt = (int)(j); |
||
687 | line[i] = (alpha) + ((r.buffByte[jInt] & 0xff) << 16) + ((r.buffByte[jInt] & 0xff) << 8) + (r.buffByte[jInt] & 0xff); |
||
688 | } |
||
689 | }else{
|
||
690 | for (i=currentViewWidth - 1; i>=0 && j<r.getSize(); i--, j+=stepX) { |
||
691 | int jInt = (int)(j); |
||
692 | line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + ((r.buffByte[jInt] & 0xff) << 16) + ((g.buffByte[jInt] & 0xff) << 8) + (b.buffByte[jInt] & 0xff); |
||
693 | } |
||
694 | } |
||
695 | }else if (dataType == GDT_CInt16 || dataType == GDT_Int16 || dataType == GDT_UInt16){ |
||
696 | if (g == null) // Sibgle Band (Typical DEM) |
||
697 | for (i=currentViewWidth - 1; i>=0 && j<r.getSize(); i--, j+=stepX) { |
||
698 | int jInt = (int)(j); |
||
699 | line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + r.buffShort[jInt]; |
||
700 | } |
||
701 | else { // Multiband |
||
702 | // System.err.println("Raster 16bits multibanda");
|
||
703 | for (i=currentViewWidth - 1; i>=0 && j<r.getSize(); i--, j+=stepX) { |
||
704 | int jInt = (int)(j); |
||
705 | line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) | (((r.buffShort[jInt] & 0xfff0) << 12) & 0xff0000 ) | |
||
706 | (((g.buffShort[jInt] & 0xfff0) << 4 ) & 0xff00 ) | |
||
707 | (((b.buffShort[jInt] & 0xfff0) >> 4 ) & 0xff ); |
||
708 | } |
||
709 | } |
||
710 | } |
||
711 | } |
||
712 | 8026 | nacho | return err;
|
713 | } |
||
714 | |||
715 | /**
|
||
716 | * Lee una ventana de datos sin resampleo a partir de coordenadas reales.
|
||
717 | * @param buf Buffer donde se almacenan los datos
|
||
718 | * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
|
||
719 | * @param dWorldTLX Posici?n X en pixeles
|
||
720 | * @param dWorldTLY Posici?n Y en pixeles
|
||
721 | * @param w Ancho en pixeles
|
||
722 | * @param h Alto en pixeles
|
||
723 | * @throws GdalException
|
||
724 | */
|
||
725 | public void readWindow(RasterBuf buf, BandList bandList, double dWorldTLX, double dWorldTLY, |
||
726 | int nWidth, int nHeight) throws GdalException { |
||
727 | Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY)); |
||
728 | |||
729 | gdalBands = new GdalRasterBand[getRasterCount()];
|
||
730 | isSupersampling = false;
|
||
731 | if(gdalBands.length == 0) |
||
732 | return;
|
||
733 | |||
734 | try {
|
||
735 | // Selecciona las bandas
|
||
736 | gdalBands[0] = getRasterBand(1); |
||
737 | setDataType(gdalBands[0].getRasterDataType());
|
||
738 | for(int iBand = 1; iBand < gdalBands.length; iBand++) |
||
739 | gdalBands[iBand] = getRasterBand(iBand + 1);
|
||
740 | |||
741 | } catch (GdalException e) {
|
||
742 | e.printStackTrace(); |
||
743 | } |
||
744 | |||
745 | int x = (int) Math.ceil(tl.getX()); |
||
746 | int y = (int) Math.ceil(tl.getY()); |
||
747 | |||
748 | if ((x + nWidth) > gdalBands[0].getRasterBandXSize()) |
||
749 | nWidth = gdalBands[0].getRasterBandXSize() - x;
|
||
750 | |||
751 | if ((y + nHeight) > gdalBands[0].getRasterBandYSize()) |
||
752 | nHeight = gdalBands[0].getRasterBandYSize() - y;
|
||
753 | |||
754 | int yMax = y + nHeight;
|
||
755 | readData(buf, bandList, x, y, nWidth, yMax); |
||
756 | } |
||
757 | |||
758 | /**
|
||
759 | 10645 | nacho | * Lee una ventana de datos con resampleo a partir de coordenadas reales. Este m?todo lee la
|
760 | * ventana de una vez cargando los datos de un golpe en el buffer. Las coordenadas se solicitan
|
||
761 | * en coordenadas del mundo real por lo que estas pueden caer en cualquier parte de un pixel.
|
||
762 | * Esto se hace m?s evidente cuando supersampleamos en la petici?n, es decir el buffer de de
|
||
763 | * mayor tama?o que el n?mero de pixels solicitado.
|
||
764 | *
|
||
765 | * Para resolver esto escribiremos con la funci?n readRaster los datos sobre un buffer mayor
|
||
766 | * que el solicitado. Despu?s calcularemos el desplazamiento en pixels dentro de este buffer
|
||
767 | * de mayor tama?o hasta llegar a la coordenada real donde comienza la petici?n real que ha
|
||
768 | * hecho el usuario. Esto es as? porque cuando supersampleamos no queremos los pixeles del
|
||
769 | * raster de disco completos sino que en los bordes del buffer quedan cortados.
|
||
770 | *
|
||
771 | * @param buf Buffer donde se almacenan los datos
|
||
772 | * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
|
||
773 | * @param dWorldTLX Posici?n X en pixeles
|
||
774 | * @param dWorldTLY Posici?n Y en pixeles
|
||
775 | * @param nWidth Ancho en pixeles
|
||
776 | * @param nHeight Alto en pixeles
|
||
777 | * @param bufWidth Ancho del buffer
|
||
778 | * @param bufHeight Alto del buffer
|
||
779 | * @throws GdalException
|
||
780 | */
|
||
781 | public void readWindow(RasterBuf buf, BandList bandList, double dWorldTLX, double dWorldTLY, double dWorldBRX, double dWorldBRY, |
||
782 | double nWidth, double nHeight, int bufWidth, int bufHeight) throws GdalException { |
||
783 | setView(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, bufWidth, bufHeight, new boolean[]{true, false}); |
||
784 | Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY)); |
||
785 | Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY)); |
||
786 | |||
787 | if(gdalBands.length == 0) |
||
788 | return;
|
||
789 | |||
790 | selectGdalBands(buf.getBandCount()); |
||
791 | |||
792 | int x = (int) tl.getX(); |
||
793 | int y = (int) tl.getY(); |
||
794 | int endX = (int) Math.ceil(br.getX()); |
||
795 | int endY = (int) Math.ceil(br.getY()); |
||
796 | |||
797 | int stpX = 0; |
||
798 | int stpY = 0; |
||
799 | |||
800 | if(bufWidth > Math.ceil(nWidth)){ |
||
801 | stpX = (int)(((tl.getX() - x) * bufWidth) / nWidth);
|
||
802 | bufWidth = (int)((Math.abs(endX - x) * bufWidth) / nWidth); |
||
803 | } |
||
804 | if(bufHeight > Math.ceil(nHeight)){ |
||
805 | stpY = (int)(((tl.getY() - y) * bufHeight) / nHeight);
|
||
806 | bufHeight = (int)((Math.abs(endY - y) * bufHeight) / nHeight); |
||
807 | } |
||
808 | |||
809 | nWidth = (int)Math.abs(endX - x); |
||
810 | nHeight = (int)Math.abs(endY - y); |
||
811 | |||
812 | if ((x + nWidth) > gdalBands[0].getRasterBandXSize()) |
||
813 | nWidth = gdalBands[0].getRasterBandXSize() - x;
|
||
814 | |||
815 | if ((y + nHeight) > gdalBands[0].getRasterBandYSize()) |
||
816 | nHeight = gdalBands[0].getRasterBandYSize() - y;
|
||
817 | |||
818 | int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()}; |
||
819 | readData(buf, bandList, x, y, (int)nWidth, (int)nHeight, bufWidth, bufHeight, stpX, stpY, stpBuffer); |
||
820 | } |
||
821 | |||
822 | /**
|
||
823 | * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles. Esta funci?n es usuada por
|
||
824 | * readWindow para coordenadas reales y readWindow en coordenadas pixel.
|
||
825 | * @param buf Buffer donde se almacenan los datos
|
||
826 | * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
|
||
827 | * @param x Posici?n X en pixeles
|
||
828 | * @param y Posici?n Y en pixeles
|
||
829 | * @param w Ancho en pixeles
|
||
830 | * @param yMax altura m?xima de y
|
||
831 | * @throws GdalException
|
||
832 | */
|
||
833 | private void readData(RasterBuf buf, BandList bandList, int x, int y, int w, int h, int bufWidth, int bufHeight, int stpX, int stpY, int[] stepBuffer) throws GdalException { |
||
834 | //TODO: FUNCIONALIDAD: Orientaci?n del raster. orientaion[0] para pixels en X y orientation[1] para pixels en Y
|
||
835 | GdalBuffer gdalBuf = null;
|
||
836 | for(int iBand = 0; iBand < gdalBands.length; iBand++){ |
||
837 | int[] drawableBands = bandList.getBufferBandToDraw(fileName, iBand); |
||
838 | if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1)) |
||
839 | continue;
|
||
840 | int init = (int)((bufWidth * stpY) + stpX); //Pos inicial. Desplazamos stpX pixels hacia la derecha y bajamos stpY lineas |
||
841 | int pos = init;
|
||
842 | gdalBuf = gdalBands[iBand].readRaster(x, y, w, h, bufWidth, bufHeight, dataType); |
||
843 | if(dataType == Gdal.GDT_Byte){
|
||
844 | for (int line = stepBuffer[1]; line < stepBuffer[3]/*buf.getHeight()*/; line++) { |
||
845 | pos = (int)((bufWidth * line) + init);
|
||
846 | for (int col = stepBuffer[0]; col < stepBuffer[2]/*buf.getWidth()*/; col ++){ |
||
847 | for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){ //Una misma banda del raster puede ir dibujada en varias bandas del buffer. |
||
848 | buf.setElemByte(line, col, drawableBands[drawBands], gdalBuf.buffByte[pos]); |
||
849 | } |
||
850 | pos ++; |
||
851 | } |
||
852 | } |
||
853 | }else if((dataType == Gdal.GDT_UInt16) || (dataType == Gdal.GDT_Int16) || (dataType == Gdal.GDT_CInt16)){ |
||
854 | for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) { |
||
855 | pos = (int)((bufWidth * line) + init);
|
||
856 | for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++){ |
||
857 | for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){ //Una misma banda del raster puede ir dibujada en varias bandas del buffer. |
||
858 | buf.setElemShort(line, col, drawableBands[drawBands], gdalBuf.buffShort[pos]); |
||
859 | } |
||
860 | pos ++; |
||
861 | } |
||
862 | } |
||
863 | }else if((dataType == Gdal.GDT_UInt32) || (dataType == Gdal.GDT_Int32) || (dataType == Gdal.GDT_CInt32)){ |
||
864 | for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) { |
||
865 | pos = (int)((bufWidth * line) + init);
|
||
866 | for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++){ |
||
867 | for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){ //Una misma banda del raster puede ir dibujada en varias bandas del buffer. |
||
868 | buf.setElemInt(line, col, drawableBands[drawBands], gdalBuf.buffInt[pos]); |
||
869 | } |
||
870 | pos ++; |
||
871 | } |
||
872 | } |
||
873 | }else if(dataType == Gdal.GDT_Float32){ |
||
874 | for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) { |
||
875 | pos = (int)((bufWidth * line) + init);
|
||
876 | for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++){ |
||
877 | for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){ //Una misma banda del raster puede ir dibujada en varias bandas del buffer. |
||
878 | buf.setElemFloat(line, col, drawableBands[drawBands], gdalBuf.buffFloat[pos]); |
||
879 | } |
||
880 | pos ++; |
||
881 | } |
||
882 | } |
||
883 | }else if(dataType == Gdal.GDT_Float64){ |
||
884 | for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) { |
||
885 | pos = (int)((bufWidth * line) + init);
|
||
886 | for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++){ |
||
887 | for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){ //Una misma banda del raster puede ir dibujada en varias bandas del buffer. |
||
888 | buf.setElemDouble(line, col, drawableBands[drawBands], gdalBuf.buffDouble[pos]); |
||
889 | } |
||
890 | pos ++; |
||
891 | } |
||
892 | } |
||
893 | } |
||
894 | } |
||
895 | } |
||
896 | |||
897 | |||
898 | /**
|
||
899 | * Lee una ventana de datos sin resampleo a partir de coordenadas reales.
|
||
900 | * @param buf Buffer donde se almacenan los datos
|
||
901 | * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
|
||
902 | * @param dWorldTLX Posici?n X superior izquierda en coord reales
|
||
903 | * @param dWorldTLY Posici?n Y superior izquierda en coord reales
|
||
904 | * @param dWorldBRX Posici?n X inferior derecha en coord reales
|
||
905 | * @param dWorldBRY Posici?n Y inferior derecha en coord reales
|
||
906 | * @param nWidth Ancho en pixeles del buffer
|
||
907 | * @param nHeight Alto en pixeles del buffer
|
||
908 | * @throws GdalException
|
||
909 | */
|
||
910 | public void readWindowWithNoData(RasterBuf buf, BandList bandList, double dWorldTLX, double dWorldTLY,double dWorldBRX, double dWorldBRY, |
||
911 | int nWidth, int nHeight) throws GdalException { |
||
912 | Extent petExtent = new Extent(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY);
|
||
913 | if(dWorldTLX < bBoxWithoutRot.minX)
|
||
914 | dWorldTLX = bBoxWithoutRot.minX; |
||
915 | if(dWorldTLY > bBoxWithoutRot.maxY)
|
||
916 | dWorldTLY = bBoxWithoutRot.maxY; |
||
917 | if(dWorldBRX > bBoxWithoutRot.maxX)
|
||
918 | dWorldBRX = bBoxWithoutRot.maxX; |
||
919 | if(dWorldBRY < bBoxWithoutRot.minY)
|
||
920 | dWorldBRY = bBoxWithoutRot.minY; |
||
921 | setView(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, nWidth, nHeight, new boolean[]{true, false}); |
||
922 | Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY)); |
||
923 | |||
924 | if(gdalBands.length == 0) |
||
925 | return;
|
||
926 | |||
927 | selectGdalBands(buf.getBandCount()); |
||
928 | |||
929 | int x = (int) tl.getX(); |
||
930 | int y = (int) tl.getY(); |
||
931 | |||
932 | int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()}; |
||
933 | //Si el buffer no se ajusta al extent entonces calculamos en que posici?n comienza a escribirse dentro del buffer
|
||
934 | //ya que lo que cae fuera ser?n valores NoData
|
||
935 | |||
936 | int[] wh = calcStepBuffer(petExtent, nWidth, nHeight, stpBuffer); |
||
937 | if(x < 0) |
||
938 | x = 0;
|
||
939 | if(y < 0) |
||
940 | y = 0;
|
||
941 | readData(buf, bandList, x, y, wh[0], wh[1], wh[0], wh[1], 0, 0, stpBuffer); |
||
942 | } |
||
943 | |||
944 | /**
|
||
945 | * Cuando se hace una petici?n de carga de buffer la extensi?n pedida puede estar ajustada a la extensi?n del raster
|
||
946 | * o no estarlo. En caso de no estarlo los pixeles del buffer que caen fuera de la extensi?n del raster tendr?n valor
|
||
947 | * de NoData. Esta funci?n calcula en que pixel del buffer hay que empezar a escribir en caso de que este sea mayor
|
||
948 | * que los datos a leer.
|
||
949 | * @param dWorldTLX Posici?n X superior izquierda en coord reales
|
||
950 | * @param dWorldTLY Posici?n Y superior izquierda en coord reales
|
||
951 | * @param dWorldBRX Posici?n X inferior derecha en coord reales
|
||
952 | * @param dWorldBRY Posici?n Y inferior derecha en coord reales
|
||
953 | * @param nWidth Ancho en pixeles del buffer
|
||
954 | * @param nHeight Alto en pixeles del buffer
|
||
955 | * @return desplazamiento dentro del buffer en X e Y
|
||
956 | */
|
||
957 | private int[] calcStepBuffer(Extent dataExtent, int nWidth, int nHeight, int[] stpBuffer){ |
||
958 | Extent imageExtent = new Extent(bBoxWithoutRot.minX, bBoxWithoutRot.minY, bBoxWithoutRot.maxX, bBoxWithoutRot.maxY);
|
||
959 | Extent ajustDataExtent = Utilities.calculateAdjustedView(dataExtent, imageExtent);
|
||
960 | if(!Utilities.compareExtents(dataExtent, ajustDataExtent)){ |
||
961 | Point2D p1 = worldToRaster(new Point2D.Double(ajustDataExtent.minX(), ajustDataExtent.maxY())); |
||
962 | Point2D p2 = worldToRaster(new Point2D.Double(ajustDataExtent.maxX(), ajustDataExtent.minY())); |
||
963 | Point2D p3 = worldToRaster(new Point2D.Double(dataExtent.minX(), dataExtent.maxY())); |
||
964 | Point2D p4 = worldToRaster(new Point2D.Double(dataExtent.maxX(), dataExtent.minY())); |
||
965 | //Ese es el ancho y alto q tendr?a el buffer en caso de haberse ajustado
|
||
966 | int w = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX())); |
||
967 | int h = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY())); |
||
968 | |||
969 | stpBuffer[0] = (int)(p1.getX() + (-p3.getX())); |
||
970 | stpBuffer[1] = (int)(p1.getY() + (-p3.getY())); |
||
971 | stpBuffer[2] = stpBuffer[0] + w; |
||
972 | stpBuffer[3] = stpBuffer[1] + h; |
||
973 | return new int[]{w, h}; |
||
974 | } |
||
975 | return new int[]{nWidth, nHeight}; |
||
976 | } |
||
977 | |||
978 | /**
|
||
979 | * Selecciona bandas y overview en el objeto GdalRasterBand[] para el n?mero de bandas solicitado.
|
||
980 | * @param nbands N?mero de bandas solicitado.
|
||
981 | * @throws GdalException
|
||
982 | */
|
||
983 | public void selectGdalBands(int nbands)throws GdalException{ |
||
984 | gdalBands = new GdalRasterBand[nbands];
|
||
985 | //Selecciona las bandas y los overviews necesarios
|
||
986 | gdalBands[0] = getRasterBand(1); |
||
987 | for(int i = 0; i < nbands; i++) |
||
988 | gdalBands[i] = gdalBands[0];
|
||
989 | |||
990 | setDataType(gdalBands[0].getRasterDataType());
|
||
991 | |||
992 | for(int i = 2; i <= nbands; i++){ |
||
993 | if(getRasterCount() >= i){
|
||
994 | gdalBands[i - 1] = getRasterBand(i);
|
||
995 | for(int j = i; j < nbands; j++) |
||
996 | gdalBands[j] = gdalBands[i - 1];
|
||
997 | } |
||
998 | } |
||
999 | |||
1000 | if (currentOverview > 0) { |
||
1001 | gdalBands[0] = gdalBands[0].getOverview(currentOverview); |
||
1002 | for(int i = 2; i <= nbands; i++){ |
||
1003 | if(getRasterCount() >= i)
|
||
1004 | gdalBands[i - 1] = gdalBands[i - 1].getOverview(currentOverview); |
||
1005 | } |
||
1006 | } |
||
1007 | } |
||
1008 | |||
1009 | /**
|
||
1010 | 8026 | nacho | * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles.
|
1011 | * @param buf Buffer donde se almacenan los datos
|
||
1012 | * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
|
||
1013 | * @param x Posici?n X en pixeles
|
||
1014 | * @param y Posici?n Y en pixeles
|
||
1015 | * @param w Ancho en pixeles
|
||
1016 | * @param h Alto en pixeles
|
||
1017 | * @throws GdalException
|
||
1018 | */
|
||
1019 | public void readWindow(RasterBuf buf, BandList bandList, int x, int y, int w, int h) throws GdalException { |
||
1020 | GdalBuffer gdalBuf = null;
|
||
1021 | gdalBands = new GdalRasterBand[getRasterCount()];
|
||
1022 | isSupersampling = false;
|
||
1023 | if(gdalBands.length == 0) |
||
1024 | return;
|
||
1025 | |||
1026 | // Selecciona las bandas
|
||
1027 | gdalBands[0] = getRasterBand(1); |
||
1028 | setDataType(gdalBands[0].getRasterDataType());
|
||
1029 | for(int iBand = 1; iBand < gdalBands.length; iBand++) |
||
1030 | gdalBands[iBand] = getRasterBand(iBand + 1);
|
||
1031 | |||
1032 | int yMax = y + h;
|
||
1033 | readData(buf, bandList, x, y, w, yMax); |
||
1034 | } |
||
1035 | |||
1036 | /**
|
||
1037 | * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles. Esta funci?n es usuada por
|
||
1038 | * readWindow para coordenadas reales y readWindow en coordenadas pixel.
|
||
1039 | * @param buf Buffer donde se almacenan los datos
|
||
1040 | * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
|
||
1041 | * @param x Posici?n X en pixeles
|
||
1042 | * @param y Posici?n Y en pixeles
|
||
1043 | * @param w Ancho en pixeles
|
||
1044 | * @param yMax altura m?xima de y
|
||
1045 | * @throws GdalException
|
||
1046 | */
|
||
1047 | private void readData(RasterBuf buf, BandList bandList, int x, int y, int w, int yMax) throws GdalException { |
||
1048 | GdalBuffer gdalBuf = null;
|
||
1049 | int rasterBufLine;
|
||
1050 | for(int iBand = 0; iBand < gdalBands.length; iBand++){ |
||
1051 | int[] drawableBands = bandList.getBufferBandToDraw(fileName, iBand); |
||
1052 | if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1)) |
||
1053 | continue;
|
||
1054 | if(dataType == Gdal.GDT_Byte){
|
||
1055 | for (int line = y; line < yMax; line++) { |
||
1056 | gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType); |
||
1057 | rasterBufLine = line - y; |
||
1058 | for(int drawBands = 0; drawBands < drawableBands.length; drawBands++) |
||
1059 | buf.setLineInBandByte(gdalBuf.buffByte, rasterBufLine, drawableBands[drawBands]); |
||
1060 | } |
||
1061 | }else if((dataType == Gdal.GDT_UInt16) || (dataType == Gdal.GDT_Int16) || (dataType == Gdal.GDT_CInt16)){ |
||
1062 | for (int line = y; line < yMax; line++) { |
||
1063 | gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType); |
||
1064 | rasterBufLine = line - y; |
||
1065 | for(int drawBands = 0; drawBands < drawableBands.length; drawBands++) |
||
1066 | buf.setLineInBandShort(gdalBuf.buffShort, rasterBufLine, drawableBands[drawBands]); |
||
1067 | } |
||
1068 | }else if((dataType == Gdal.GDT_UInt32) || (dataType == Gdal.GDT_Int32) || (dataType == Gdal.GDT_CInt32)){ |
||
1069 | for (int line = y; line < yMax; line++) { |
||
1070 | gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType); |
||
1071 | rasterBufLine = line - y; |
||
1072 | for(int drawBands = 0; drawBands < drawableBands.length; drawBands++) |
||
1073 | buf.setLineInBandInt(gdalBuf.buffInt, rasterBufLine, drawableBands[drawBands]); |
||
1074 | } |
||
1075 | }else if(dataType == Gdal.GDT_Float32){ |
||
1076 | for (int line = y; line < yMax; line++) { |
||
1077 | gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType); |
||
1078 | rasterBufLine = line - y; |
||
1079 | for(int drawBands = 0; drawBands < drawableBands.length; drawBands++) |
||
1080 | buf.setLineInBandFloat(gdalBuf.buffFloat, rasterBufLine, drawableBands[drawBands]); |
||
1081 | } |
||
1082 | }else if(dataType == Gdal.GDT_Float64){ |
||
1083 | for (int line = y; line < yMax; line++) { |
||
1084 | gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType); |
||
1085 | rasterBufLine = line - y; |
||
1086 | for(int drawBands = 0; drawBands < drawableBands.length; drawBands++) |
||
1087 | buf.setLineInBandDouble(gdalBuf.buffDouble, rasterBufLine, drawableBands[drawBands]); |
||
1088 | } |
||
1089 | } |
||
1090 | } |
||
1091 | } |
||
1092 | |||
1093 | 10645 | nacho | /* (non-Javadoc)
|
1094 | * @see org.cresques.io.GeoRasterFile#getData(int, int, int)
|
||
1095 | */
|
||
1096 | public Object[] getData(int x, int y) { |
||
1097 | try {
|
||
1098 | Object[] data = new Object[getRasterCount()]; |
||
1099 | for(int i = 0; i < getRasterCount(); i++){ |
||
1100 | GdalRasterBand rb = getRasterBand(i + 1);
|
||
1101 | GdalBuffer r = rb.readRaster(x, y, 1, 1, 1, 1, dataType); |
||
1102 | switch(dataType){
|
||
1103 | case 0: break; //Sin tipo |
||
1104 | case 1: data[i] = new Integer(r.buffByte[0]); //Buffer byte (8) |
||
1105 | break;
|
||
1106 | case 2: //Buffer short (16) |
||
1107 | case 3: data[i] = new Integer(r.buffShort[0]); //Buffer short (16) |
||
1108 | break;
|
||
1109 | case 4: //Buffer int (32) |
||
1110 | case 5: data[i] = new Integer(r.buffInt[0]); //Buffer int (32) |
||
1111 | break;
|
||
1112 | case 6: data[i] = new Float(r.buffFloat[0]); //Buffer float (32) |
||
1113 | break;
|
||
1114 | case 7: data[i] = new Double(r.buffDouble[0]); //Buffer double (64) |
||
1115 | break;
|
||
1116 | } |
||
1117 | } |
||
1118 | return data;
|
||
1119 | } catch (GdalException e) {
|
||
1120 | return null; |
||
1121 | } |
||
1122 | } |
||
1123 | |||
1124 | 8026 | nacho | void pintaInfo() {
|
1125 | try {
|
||
1126 | //System.out.println("Origin = "+originX+","+originY);
|
||
1127 | //System.out.println("Origin = "+this.);
|
||
1128 | System.out.println("GeoTransform:"); |
||
1129 | GeoTransform trans = getGeoTransform(); |
||
1130 | for (int i=0; i<6; i++) |
||
1131 | System.out.println(" param["+i+"]="+trans.adfgeotransform[i]); |
||
1132 | System.out.println("Metadata:"); |
||
1133 | String [] metadata = getMetadata(); |
||
1134 | for (int i=0; i<metadata.length; i++) { |
||
1135 | System.out.println(metadata[i]);
|
||
1136 | } |
||
1137 | } catch (GdalException e) {
|
||
1138 | |||
1139 | } |
||
1140 | |||
1141 | } |
||
1142 | |||
1143 | void pintaPaleta() {
|
||
1144 | } |
||
1145 | |||
1146 | public int getBlockSize(){ |
||
1147 | return this.getBlockSize(); |
||
1148 | } |
||
1149 | |||
1150 | /**
|
||
1151 | * Obtiene el objeto que contiene los metadatos
|
||
1152 | */
|
||
1153 | public Metadata getMetadataJavaObject() {
|
||
1154 | return metadata;
|
||
1155 | } |
||
1156 | |||
1157 | /**
|
||
1158 | * Obtiene el flag que dice si la imagen est? o no georreferenciada
|
||
1159 | * @return true si est? georreferenciada y false si no lo est?.
|
||
1160 | */
|
||
1161 | public boolean isGeoreferenced() { |
||
1162 | return georeferenced;
|
||
1163 | } |
||
1164 | |||
1165 | } |
||
1166 | |||
1167 | /**
|
||
1168 | * @author Luis W. Sevilla
|
||
1169 | */
|
||
1170 | public class GdalFile extends GeoRasterFile { |
||
1171 | public final static int BAND_HEIGHT = 64; |
||
1172 | protected GdalNative file = null; |
||
1173 | /**
|
||
1174 | * Tama?o de pixel para las imagenes con fichero RMF. No podemos salvarlo en file porque es necesario conocer el
|
||
1175 | * tama?o de pixel asignado por rl .rmf y el tama?o de pixel real.
|
||
1176 | */
|
||
1177 | private double pixelSizeX = 0D, pixelSizeY = 0D; |
||
1178 | |||
1179 | private Extent v = null; |
||
1180 | |||
1181 | public GdalFile(IProjection proj, String fName)throws NotSupportedExtensionException{ |
||
1182 | super(proj, fName);
|
||
1183 | extent = new Extent();
|
||
1184 | try {
|
||
1185 | file = new GdalNative(fName, this); |
||
1186 | load(); |
||
1187 | readGeoInfo(fName); |
||
1188 | bandCount = file.getRasterCount(); |
||
1189 | if ( bandCount > 2) { |
||
1190 | setBand(RED_BAND, 0);
|
||
1191 | setBand(GREEN_BAND, 1);
|
||
1192 | setBand(BLUE_BAND, 2);
|
||
1193 | } else
|
||
1194 | setBand(RED_BAND|GREEN_BAND|BLUE_BAND, 0);
|
||
1195 | } catch (GdalException e) {
|
||
1196 | throw new NotSupportedExtensionException("Extension not supported"); |
||
1197 | } catch(Exception e){ |
||
1198 | System.out.println("Error en GdalOpen"); |
||
1199 | e.printStackTrace(); |
||
1200 | file = null;
|
||
1201 | } |
||
1202 | |||
1203 | //Obtenemos el tipo de dato de gdal y lo convertimos el de RasterBuf
|
||
1204 | setDataType(org.cresques.util.Utilities.getRasterBufTypeFromGdalType(file.getDataType())); |
||
1205 | } |
||
1206 | |||
1207 | /**
|
||
1208 | * Obtenemos o calculamos el extent de la imagen.
|
||
1209 | */
|
||
1210 | public GeoFile load() {
|
||
1211 | extent = new Extent(file.bBoxRot.minX, file.bBoxRot.minY, file.bBoxRot.maxX, file.bBoxRot.maxY);
|
||
1212 | requestExtent = new Extent(file.bBoxWithoutRot.minX, file.bBoxWithoutRot.minY, file.bBoxWithoutRot.maxX, file.bBoxWithoutRot.maxY);
|
||
1213 | return this; |
||
1214 | } |
||
1215 | |||
1216 | /**
|
||
1217 | * Cierra el fichero de imagen
|
||
1218 | */
|
||
1219 | public void close() { |
||
1220 | try {
|
||
1221 | if(file != null){ |
||
1222 | file.close(); |
||
1223 | file = null;
|
||
1224 | } |
||
1225 | } catch (GdalException e) {
|
||
1226 | // TODO Auto-generated catch block
|
||
1227 | e.printStackTrace(); |
||
1228 | } |
||
1229 | } |
||
1230 | |||
1231 | /**
|
||
1232 | * Asigna a cada banda R,G o B una banda de la imagen
|
||
1233 | */
|
||
1234 | public void setBand(int flag, int bandNr) { |
||
1235 | super.setBand(flag, bandNr);
|
||
1236 | if ((flag & GeoRasterFile.RED_BAND) == GeoRasterFile.RED_BAND) file.rBandNr = bandNr+1; |
||
1237 | if ((flag & GeoRasterFile.GREEN_BAND) == GeoRasterFile.GREEN_BAND) file.gBandNr = bandNr+1; |
||
1238 | if ((flag & GeoRasterFile.BLUE_BAND) == GeoRasterFile.BLUE_BAND) file.bBandNr = bandNr+1; |
||
1239 | } |
||
1240 | |||
1241 | /**
|
||
1242 | * Asigna el extent de la vista actual. existe un fichero .rmf debemos hacer una transformaci?n
|
||
1243 | * de la vista asignada ya que la petici?n viene en coordenadas del fichero .rmf y la vista (v)
|
||
1244 | * ha de estar en coordenadas del fichero.
|
||
1245 | */
|
||
1246 | public void setView(Extent e) { |
||
1247 | if(rmfExists){
|
||
1248 | 8631 | nacho | |
1249 | 8026 | nacho | Point2D.Double petInit = null, petEnd = null; |
1250 | try{
|
||
1251 | petInit = new Point2D.Double(e.minX(), e.maxY()); |
||
1252 | petEnd = new Point2D.Double(e.maxX(), e.minY()); |
||
1253 | 8631 | nacho | transformRMF.inverseTransform(petInit, petInit); |
1254 | transformRMF.inverseTransform(petEnd, petEnd); |
||
1255 | transformTFW.transform(petInit, petInit); |
||
1256 | transformTFW.transform(petEnd, petEnd); |
||
1257 | 8026 | nacho | }catch(NoninvertibleTransformException ex){} |
1258 | 8631 | nacho | double h = file.bBoxWithoutRot.maxY - file.bBoxWithoutRot.minY;
|
1259 | if(!file.isGeoreferenced())
|
||
1260 | v = new Extent( petInit.getX(), h - petInit.getY(), petEnd.getX(), h - petEnd.getY());
|
||
1261 | else
|
||
1262 | v = new Extent( petInit.getX(), petInit.getY(), petEnd.getX(), petEnd.getY());
|
||
1263 | 8026 | nacho | |
1264 | }else
|
||
1265 | v = new Extent(e.minX(), e.minY(), e.maxX(), e.maxY());
|
||
1266 | } |
||
1267 | |||
1268 | 8631 | nacho | /**
|
1269 | * Calcula la transformaci?n que se produce sobre la vista cuando la imagen tiene un fichero .rmf
|
||
1270 | * asociado. En Gdal el origen de coordenadas en Y es el valor m?nimo y crece hasta el m?ximo. De la
|
||
1271 | * misma forma calcula la matriz de transformaci?n de la cabecera del fichero o del world file asociado
|
||
1272 | * @param originX Origen de la imagen en la coordenada X
|
||
1273 | * @param originY Origen de la imagen en la coordenada Y
|
||
1274 | */
|
||
1275 | public void setExtentTransform(double originX, double originY, double psX, double psY) { |
||
1276 | transformRMF.setToTranslation(originX, originY); |
||
1277 | transformRMF.scale(psX, psY); |
||
1278 | |||
1279 | if(file.trans != null){ |
||
1280 | transformTFW.setToTranslation(file.trans.adfgeotransform[0], file.trans.adfgeotransform[3]); |
||
1281 | transformTFW.scale(file.trans.adfgeotransform[1], file.trans.adfgeotransform[5]); |
||
1282 | } |
||
1283 | } |
||
1284 | |||
1285 | 8026 | nacho | /**
|
1286 | * Obtiene extent de la vista actual
|
||
1287 | */
|
||
1288 | public Extent getView() {
|
||
1289 | return v;
|
||
1290 | } |
||
1291 | |||
1292 | /**
|
||
1293 | * Obtiene la anchura del fichero
|
||
1294 | */
|
||
1295 | public int getWidth() { |
||
1296 | return file.width;
|
||
1297 | } |
||
1298 | |||
1299 | /**
|
||
1300 | * Obtiene la altura del fichero
|
||
1301 | */
|
||
1302 | public int getHeight() { |
||
1303 | return file.height;
|
||
1304 | } |
||
1305 | |||
1306 | /* (non-Javadoc)
|
||
1307 | * @see org.cresques.io.GeoRasterFile#reProject(org.cresques.cts.ICoordTrans)
|
||
1308 | */
|
||
1309 | public void reProject(ICoordTrans rp) { |
||
1310 | // TODO Auto-generated method stub
|
||
1311 | } |
||
1312 | |||
1313 | 8631 | nacho | /**
|
1314 | * Obtiene la orientaci?n de la imagen a partir del signo del tama?o de pixel para poder
|
||
1315 | * asignarlo en el setView. Esto es util para poder conocer como debe leerse la image,
|
||
1316 | * de abajo a arriba, de arriba a abajo, de izquierda a derecha o de derecha a izquierda.
|
||
1317 | * La posici?n habitual es la que el pixel size en X es positivo y en Y negativo leyendose
|
||
1318 | * en este caso las X de menor a mayor y las Y de mayor a menor. Los casos posibles son:
|
||
1319 | * <UL>
|
||
1320 | * <LI><B>X > 0; Y < 0;</B> {true, false}</LI>
|
||
1321 | * <LI><B>X > 0; Y > 0;</B> {true, true}</LI>
|
||
1322 | * <LI><B>X < 0; Y > 0;</B> {false, true}</LI>
|
||
1323 | * <LI><B>X < 0; Y < 0;</B> {false, false}</LI>
|
||
1324 | * </UL>
|
||
1325 | *
|
||
1326 | * @return
|
||
1327 | */
|
||
1328 | private boolean[] getOrientation(){ |
||
1329 | boolean[] orientation = {true, false}; |
||
1330 | if(!rmfExists){
|
||
1331 | if(file.trans != null && file.trans.adfgeotransform != null && file.trans.adfgeotransform[5] > 0) |
||
1332 | orientation[1] = true; |
||
1333 | if(file.trans != null && file.trans.adfgeotransform != null && file.trans.adfgeotransform[1] < 0) |
||
1334 | orientation[0] = false; |
||
1335 | }else{
|
||
1336 | if(rmfTransform.getScaleY() > 0) |
||
1337 | orientation[1] = true; |
||
1338 | if(rmfTransform.getScaleX() < 0) |
||
1339 | orientation[0] = false; |
||
1340 | } |
||
1341 | return orientation;
|
||
1342 | } |
||
1343 | |||
1344 | 8026 | nacho | /* (non-Javadoc)
|
1345 | * @see org.cresques.io.GeoRasterFile#updateImage(int, int, org.cresques.cts.ICoordTrans)
|
||
1346 | */
|
||
1347 | public Image updateImage(int width, int height, ICoordTrans rp) { |
||
1348 | int line, pRGBArray[] = null; |
||
1349 | Image image = null; |
||
1350 | |||
1351 | if (mustVerifySize()) {
|
||
1352 | // Work out the correct aspect for the setView call.
|
||
1353 | double dFileAspect = (double)v.width()/(double)v.height(); |
||
1354 | double dWindowAspect = (double)width /(double)height; |
||
1355 | |||
1356 | if (dFileAspect > dWindowAspect) {
|
||
1357 | height =(int)((double)width/dFileAspect); |
||
1358 | } else {
|
||
1359 | width = (int)((double)height*dFileAspect); |
||
1360 | } |
||
1361 | } |
||
1362 | |||
1363 | // Set the view
|
||
1364 | 8631 | nacho | file.setView(v.minX(), v.maxY(), v.maxX(), v.minY(), width, height, getOrientation()); |
1365 | 8026 | nacho | setStep(file.stepArrayX, file.stepArrayY); |
1366 | |||
1367 | if(width<=0)width=1; |
||
1368 | if(height<=0)height=1; |
||
1369 | |||
1370 | image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); |
||
1371 | //image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||
1372 | pRGBArray = new int[width/**BAND_HEIGHT*/]; |
||
1373 | try {
|
||
1374 | //int nLin = height % BAND_HEIGHT;
|
||
1375 | file.setAlpha(getAlpha()); |
||
1376 | setBand(RED_BAND, rBandNr); |
||
1377 | setBand(GREEN_BAND, gBandNr); |
||
1378 | setBand(BLUE_BAND, bBandNr); |
||
1379 | for (line=0; line < height; line++) { //+=BAND_HEIGHT) { |
||
1380 | //int bandH = Math.min(BAND_HEIGHT, height-line);
|
||
1381 | //file.readBandRGBA(bandH, BAND_HEIGHT, pRGBArray);
|
||
1382 | file.readLineRGBA(pRGBArray); |
||
1383 | setRGBLine((BufferedImage) image, 0, line, width, 1/*bandH*/, pRGBArray, 0, width); |
||
1384 | } |
||
1385 | } catch (Exception e) { |
||
1386 | // TODO Auto-generated catch block
|
||
1387 | e.printStackTrace(); |
||
1388 | } |
||
1389 | |||
1390 | return image;
|
||
1391 | } |
||
1392 | |||
1393 | public RasterBuf getRaster(int width, int height, ICoordTrans rp) { |
||
1394 | int line;
|
||
1395 | RasterBuf raster = null;
|
||
1396 | |||
1397 | if(mustVerifySize()){
|
||
1398 | // Work out the correct aspect for the setView call.
|
||
1399 | double dFileAspect = (double)v.width()/(double)v.height(); |
||
1400 | double dWindowAspect = (double)width /(double)height; |
||
1401 | |||
1402 | if (dFileAspect > dWindowAspect) {
|
||
1403 | height =(int)((double)width/dFileAspect); |
||
1404 | } else {
|
||
1405 | width = (int)((double)height*dFileAspect); |
||
1406 | } |
||
1407 | } |
||
1408 | |||
1409 | // Set the view
|
||
1410 | 8631 | nacho | boolean[] orientation = getOrientation(); |
1411 | file.setView(v.minX(), v.maxY(), v.maxX(), v.minY(), |
||
1412 | width, height, orientation); |
||
1413 | 8026 | nacho | setStep(file.stepArrayX, file.stepArrayY); |
1414 | |||
1415 | try {
|
||
1416 | //Esta funci?n se usa para la renderizaci?n, por eso se crean 4 bandas a pi?on fijo
|
||
1417 | raster = new RasterBuf(getDataType(), width, height, 4, true); |
||
1418 | |||
1419 | file.setAlpha(getAlpha()); |
||
1420 | setBand(RED_BAND, rBandNr); |
||
1421 | setBand(GREEN_BAND, gBandNr); |
||
1422 | setBand(BLUE_BAND, bBandNr); |
||
1423 | |||
1424 | switch(getDataType()){
|
||
1425 | case RasterBuf.TYPE_BYTE:
|
||
1426 | 10645 | nacho | for (line = 0; line < height; line++) |
1427 | 8026 | nacho | file.readLine(raster.getLineByte(line)); |
1428 | break;
|
||
1429 | case RasterBuf.TYPE_SHORT:;
|
||
1430 | 10645 | nacho | for (line = 0; line < height; line++) |
1431 | 8026 | nacho | file.readLine(raster.getLineShort(line)); |
1432 | break;
|
||
1433 | case RasterBuf.TYPE_INT:
|
||
1434 | 10645 | nacho | for (line = 0; line < height; line++) |
1435 | 8026 | nacho | file.readLine(raster.getLineInt(line)); |
1436 | break;
|
||
1437 | case RasterBuf.TYPE_FLOAT:
|
||
1438 | 10645 | nacho | for (line = 0; line < height; line++) |
1439 | 8026 | nacho | file.readLine(raster.getLineFloat(line)); |
1440 | break;
|
||
1441 | case RasterBuf.TYPE_DOUBLE:
|
||
1442 | 10645 | nacho | for (line = 0; line < height; line++) |
1443 | 8026 | nacho | file.readLine(raster.getLineDouble(line)); |
1444 | break;
|
||
1445 | case RasterBuf.TYPE_UNDEFINED:break; |
||
1446 | } |
||
1447 | |||
1448 | } catch (Exception e) { |
||
1449 | e.printStackTrace(); |
||
1450 | } |
||
1451 | |||
1452 | return raster;
|
||
1453 | } |
||
1454 | |||
1455 | /**
|
||
1456 | * Asigna al objeto Image los valores con los dato de la imagen contenidos en el
|
||
1457 | * vector de enteros.
|
||
1458 | * @param image imagen con los datos actuales
|
||
1459 | * @param startX inicio de la posici?n en X dentro de la imagen
|
||
1460 | * @param startY inicio de la posici?n en X dentro de la imagen
|
||
1461 | * @param w Ancho de la imagen
|
||
1462 | * @param h Alto de la imagen
|
||
1463 | * @param rgbArray vector que contiene la banda que se va a sustituir
|
||
1464 | * @param offset desplazamiento
|
||
1465 | * @param scansize tama?o de imagen recorrida por cada p
|
||
1466 | */
|
||
1467 | protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h, int[] rgbArray, |
||
1468 | int offset, int scansize) { |
||
1469 | image.setRGB(startX, startY, w, h, rgbArray, offset, scansize); |
||
1470 | } |
||
1471 | |||
1472 | /**
|
||
1473 | * Asigna al objeto Image la mezcla entre los valores que ya tiene y los valores
|
||
1474 | * con los dato de la imagen contenidos en el vector de enteros. De los valores RGB
|
||
1475 | * que ya contiene se mantienen las bandas que no coinciden con el valor de flags. La
|
||
1476 | * banda correspondiente a flags es sustituida por los datos del vector.
|
||
1477 | * @param image imagen con los datos actuales
|
||
1478 | * @param startX inicio de la posici?n en X dentro de la imagen
|
||
1479 | * @param startY inicio de la posici?n en X dentro de la imagen
|
||
1480 | * @param w Ancho de la imagen
|
||
1481 | * @param h Alto de la imagen
|
||
1482 | * @param rgbArray vector que contiene la banda que se va a sustituir
|
||
1483 | * @param offset desplazamiento
|
||
1484 | * @param scansize tama?o de imagen recorrida por cada paso
|
||
1485 | * @param flags banda que se va a sustituir (Ctes de GeoRasterFile)
|
||
1486 | */
|
||
1487 | protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h, int[] rgbArray, |
||
1488 | int offset, int scansize, int flags) { |
||
1489 | int [] line = new int[rgbArray.length]; |
||
1490 | image.getRGB(startX, startY, w, h, line, offset, scansize); |
||
1491 | if (flags == GeoRasterFile.RED_BAND)
|
||
1492 | for (int i=0; i<line.length; i++) |
||
1493 | line[i] = (line[i] & 0x0000ffff) | (rgbArray[i] & 0xffff0000); |
||
1494 | else if (flags == GeoRasterFile.GREEN_BAND) |
||
1495 | for (int i=0; i<line.length; i++) |
||
1496 | line[i] = (line[i] & 0x00ff00ff) | (rgbArray[i] & 0xff00ff00); |
||
1497 | else if (flags == GeoRasterFile.BLUE_BAND) |
||
1498 | for (int i=0; i<line.length; i++) |
||
1499 | line[i] = (line[i] & 0x00ffff00) | (rgbArray[i] & 0xff0000ff); |
||
1500 | image.setRGB(startX, startY, w, h, line, offset, scansize); |
||
1501 | } |
||
1502 | |||
1503 | /**
|
||
1504 | * Asigna al objeto Image la mezcla entre los valores que ya tiene y los valores
|
||
1505 | * con los dato de la imagen contenidos en el vector de enteros. De los valores RGB
|
||
1506 | * que ya contiene se mantienen las bandas que no coinciden con el valor de flags. La
|
||
1507 | * banda correspondiente a flags es sustituida por los datos del vector.
|
||
1508 | * @param image imagen con los datos actuales
|
||
1509 | * @param startX inicio de la posici?n en X dentro de la imagen
|
||
1510 | * @param startY inicio de la posici?n en X dentro de la imagen
|
||
1511 | * @param w Ancho de la imagen
|
||
1512 | * @param h Alto de la imagen
|
||
1513 | * @param rgbArray vector que contiene la banda que se va a sustituir
|
||
1514 | * @param offset desplazamiento
|
||
1515 | * @param scansize tama?o de imagen recorrida por cada paso
|
||
1516 | * @param origBand Banda origen del GeoRasterFile
|
||
1517 | * @param destBandFlag banda que se va a sustituir (Ctes de GeoRasterFile)
|
||
1518 | */
|
||
1519 | protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h, int[] rgbArray, |
||
1520 | int offset, int scansize, int origBand, int destBandFlag) { |
||
1521 | int [] line = new int[rgbArray.length]; |
||
1522 | image.getRGB(startX, startY, w, h, line, offset, scansize); |
||
1523 | if (origBand == 0 && destBandFlag == GeoRasterFile.RED_BAND) |
||
1524 | for (int i=0; i<line.length; i++) |
||
1525 | line[i] = (line[i] & 0x0000ffff) | (rgbArray[i] & 0xffff0000); |
||
1526 | else if (origBand == 1 && destBandFlag == GeoRasterFile.GREEN_BAND) |
||
1527 | for (int i=0; i<line.length; i++) |
||
1528 | line[i] = (line[i] & 0x00ff00ff) | (rgbArray[i] & 0xff00ff00); |
||
1529 | else if (origBand == 2 && destBandFlag == GeoRasterFile.BLUE_BAND) |
||
1530 | for (int i=0; i<line.length; i++) |
||
1531 | line[i] = (line[i] & 0x00ffff00) | (rgbArray[i] & 0xff0000ff); |
||
1532 | |||
1533 | else if (origBand == 0 && destBandFlag == GeoRasterFile.GREEN_BAND) |
||
1534 | for (int i=0; i<line.length; i++) |
||
1535 | line[i] = (line[i] & 0xffff00ff) | ((rgbArray[i] & 0x00ff0000) >> 8) ; |
||
1536 | else if (origBand == 0 && destBandFlag == GeoRasterFile.BLUE_BAND) |
||
1537 | for (int i=0; i<line.length; i++) |
||
1538 | line[i] = (line[i] & 0xffffff00) | ((rgbArray[i] & 0x00ff0000) >> 16); |
||
1539 | else if (origBand == 1 && destBandFlag == GeoRasterFile.RED_BAND) |
||
1540 | for (int i=0; i<line.length; i++) |
||
1541 | line[i] = (line[i] & 0xff00ffff) | ((rgbArray[i] & 0x0000ff00) << 8); |
||
1542 | |||
1543 | else if (origBand == 1 && destBandFlag == GeoRasterFile.BLUE_BAND) |
||
1544 | for (int i=0; i<line.length; i++) |
||
1545 | line[i] = (line[i] & 0xffffff00) | ((rgbArray[i] & 0x0000ff00) >> 8); |
||
1546 | else if (origBand == 2 && destBandFlag == GeoRasterFile.RED_BAND) |
||
1547 | for (int i=0; i<line.length; i++) |
||
1548 | line[i] = (line[i] & 0xff00ffff) | ((rgbArray[i] & 0x000000ff) << 16); |
||
1549 | else if (origBand == 2 && destBandFlag == GeoRasterFile.GREEN_BAND) |
||
1550 | for (int i=0; i<line.length; i++) |
||
1551 | line[i] = (line[i] & 0xffff00ff) | ((rgbArray[i] & 0x000000ff) << 8); |
||
1552 | image.setRGB(startX, startY, w, h, line, offset, scansize); |
||
1553 | } |
||
1554 | |||
1555 | private void showOnOpen() { |
||
1556 | // Report en la apertura (quitar)
|
||
1557 | System.out.println("Fichero GDAL '"+getName()+"' abierto."); |
||
1558 | System.out.println("Version = "+file.version); |
||
1559 | System.out.println(" Size = ("+file.width+","+file.height+")"); |
||
1560 | try {
|
||
1561 | System.out.println(" NumBands = ("+file.getRasterCount()+")"); |
||
1562 | } catch (GdalException e) {
|
||
1563 | // TODO Auto-generated catch block
|
||
1564 | e.printStackTrace(); |
||
1565 | } |
||
1566 | //file.pintaInfo();
|
||
1567 | file.pintaPaleta(); |
||
1568 | |||
1569 | } |
||
1570 | |||
1571 | /* (non-Javadoc)
|
||
1572 | * @see org.cresques.io.GeoRasterFile#updateImage(int, int, org.cresques.cts.ICoordTrans, java.awt.Image, int, int)
|
||
1573 | */
|
||
1574 | public Image updateImage(int width, int height, ICoordTrans rp, Image img, int origBand, int destBandFlag)throws SupersamplingNotSupportedException{ |
||
1575 | int line, pRGBArray[] = null; |
||
1576 | |||
1577 | if(mustVerifySize()){
|
||
1578 | // Work out the correct aspect for the setView call.
|
||
1579 | double dFileAspect = (double)v.width()/(double)v.height(); |
||
1580 | double dWindowAspect = (double)width /(double)height; |
||
1581 | |||
1582 | if (dFileAspect > dWindowAspect) {
|
||
1583 | height =(int)((double)width/dFileAspect); |
||
1584 | } else {
|
||
1585 | width = (int)((double)height*dFileAspect); |
||
1586 | } |
||
1587 | } |
||
1588 | |||
1589 | 8631 | nacho | // Set the view
|
1590 | boolean[] orientation = getOrientation(); |
||
1591 | file.setView(v.minX(), v.maxY(), v.maxX(), v.minY(), |
||
1592 | width, height, orientation); |
||
1593 | 8026 | nacho | setStep(file.stepArrayX, file.stepArrayY); |
1594 | |||
1595 | if(width<=0)width=1; |
||
1596 | if(height<=0)height=1; |
||
1597 | |||
1598 | pRGBArray = new int[width]; |
||
1599 | try {
|
||
1600 | setBand(RED_BAND, rBandNr); |
||
1601 | setBand(GREEN_BAND, gBandNr); |
||
1602 | setBand(BLUE_BAND, bBandNr); |
||
1603 | file.setAlpha(getAlpha()); |
||
1604 | if(img!=null){ |
||
1605 | 8631 | nacho | if(orientation[1]){ |
1606 | for (line=0; line < height; line++) { |
||
1607 | file.readLineRGBA(pRGBArray); |
||
1608 | setRGBLine((BufferedImage) img, 0, height - 1 - line, width, 1, pRGBArray, 0, width, origBand, destBandFlag); |
||
1609 | } |
||
1610 | }else{
|
||
1611 | for (line=0; line < height; line++) { |
||
1612 | file.readLineRGBA(pRGBArray); |
||
1613 | setRGBLine((BufferedImage) img, 0, line, width, 1, pRGBArray, 0, width, origBand, destBandFlag); |
||
1614 | } |
||
1615 | 8026 | nacho | } |
1616 | return img;
|
||
1617 | }else{
|
||
1618 | Image image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); |
||
1619 | 8631 | nacho | if(orientation[1]){ |
1620 | for (line=0; line < height; line++) { |
||
1621 | file.readLineRGBA(pRGBArray); |
||
1622 | setRGBLine((BufferedImage) image, 0, height - 1 - line, width, 1, pRGBArray, 0, width); |
||
1623 | } |
||
1624 | }else{
|
||
1625 | for (line=0; line < height; line++) { |
||
1626 | file.readLineRGBA(pRGBArray); |
||
1627 | setRGBLine((BufferedImage) image, 0, line, width, 1, pRGBArray, 0, width); |
||
1628 | } |
||
1629 | } |
||
1630 | 8026 | nacho | return image;
|
1631 | } |
||
1632 | } catch (Exception e) { |
||
1633 | // TODO Auto-generated catch block
|
||
1634 | e.printStackTrace(); |
||
1635 | } |
||
1636 | |||
1637 | return img;
|
||
1638 | } |
||
1639 | |||
1640 | /* (non-Javadoc)
|
||
1641 | * @see org.cresques.io.GeoRasterFile#getData(int, int, int)
|
||
1642 | */
|
||
1643 | public Object getData(int x, int y, int band) { |
||
1644 | 10645 | nacho | if(file != null){ |
1645 | Object[] data = file.getData(x, y); |
||
1646 | return data[band];
|
||
1647 | } |
||
1648 | 8026 | nacho | return null; |
1649 | } |
||
1650 | |||
1651 | /**
|
||
1652 | * Devuelve los datos de una ventana solicitada
|
||
1653 | * @param ulX coordenada X superior izda.
|
||
1654 | * @param ulY coordenada Y superior derecha.
|
||
1655 | * @param sizeX tama?o en X de la ventana.
|
||
1656 | * @param sizeY tama?o en Y de la ventana.
|
||
1657 | * @param band Banda solicitada.
|
||
1658 | */
|
||
1659 | public byte[] getWindow(int ulX, int ulY, int sizeX, int sizeY, int band){ |
||
1660 | |||
1661 | return null; |
||
1662 | } |
||
1663 | |||
1664 | public RasterBuf getWindowRaster(double x, double y, double w, double h, BandList bandList, RasterBuf rasterBuf) { |
||
1665 | Extent selectedExtent = new Extent(x, y, x + w, y - h);
|
||
1666 | setView(selectedExtent); |
||
1667 | |||
1668 | int width = 0; |
||
1669 | int height = 0; |
||
1670 | if(file.trans != null){ |
||
1671 | width = (int)Math.abs(selectedExtent.width() / file.trans.adfgeotransform[1]);//(int)(selectedExtent.width() * file.width) / extent.width(); |
||
1672 | height = (int)Math.abs(selectedExtent.height() / file.trans.adfgeotransform[5]); |
||
1673 | }else{
|
||
1674 | width = (int)Math.abs(selectedExtent.width()); |
||
1675 | height = (int)Math.abs(selectedExtent.height()); |
||
1676 | } |
||
1677 | |||
1678 | try {
|
||
1679 | file.readWindow(rasterBuf, bandList, x, y, width, height); |
||
1680 | } catch (Exception e) { |
||
1681 | e.printStackTrace(); |
||
1682 | } |
||
1683 | |||
1684 | return rasterBuf;
|
||
1685 | } |
||
1686 | |||
1687 | 10645 | nacho | /*
|
1688 | * (non-Javadoc)
|
||
1689 | * @see org.gvsig.fmap.driver.GeoRasterFile#getWindowRaster(double, double, double, double, int, int, org.gvsig.fmap.driver.BandList, org.gvsig.fmap.driver.IBuffer)
|
||
1690 | */
|
||
1691 | public RasterBuf getWindowRaster(double minX, double minY, double maxX, double maxY, int bufWidth, int bufHeight, BandList bandList, RasterBuf rasterBuf) { |
||
1692 | Extent selectedExtent = new Extent(minX, minY, maxX, maxY);
|
||
1693 | setView(selectedExtent); |
||
1694 | |||
1695 | double width = 0; |
||
1696 | double height = 0; |
||
1697 | if(getTransform() != null){ |
||
1698 | width = (double)(Math.abs(selectedExtent.width() / getTransform()[1]));//(int)(selectedExtent.width() * file.width) / extent.width(); |
||
1699 | height = (double)(Math.abs(selectedExtent.height() / getTransform()[5])); |
||
1700 | }else{
|
||
1701 | width = (double)Math.abs(selectedExtent.width()); |
||
1702 | height = (double)Math.abs(selectedExtent.height()); |
||
1703 | } |
||
1704 | |||
1705 | try {
|
||
1706 | file.readWindow(rasterBuf, bandList, minX, maxY, maxX, minY, width, height, bufWidth, bufHeight); |
||
1707 | } catch (Exception e) { |
||
1708 | e.printStackTrace(); |
||
1709 | } |
||
1710 | |||
1711 | return rasterBuf;
|
||
1712 | } |
||
1713 | |||
1714 | 8026 | nacho | public RasterBuf getWindowRaster(int x, int y, int w, int h, BandList bandList, RasterBuf rasterBuf) { |
1715 | try {
|
||
1716 | setView( |
||
1717 | new Extent( Utilities.getMapRectFromPxRect(getExtent().toRectangle2D(), |
||
1718 | getWidth(), |
||
1719 | getHeight(), |
||
1720 | new Rectangle2D.Double(x, y, w, h))) |
||
1721 | ); |
||
1722 | file.readWindow(rasterBuf, bandList, x, y, w, h); |
||
1723 | } catch (Exception e) { |
||
1724 | e.printStackTrace(); |
||
1725 | } |
||
1726 | return rasterBuf;
|
||
1727 | } |
||
1728 | |||
1729 | 10645 | nacho | public RasterBuf getWindowRasterWithNoData(double x, double y, double w, double h, BandList bandList, RasterBuf rasterBuf) { |
1730 | Extent selectedExtent = new Extent(x, y, x + w, y - h);
|
||
1731 | setView(selectedExtent); |
||
1732 | |||
1733 | try {
|
||
1734 | file.readWindowWithNoData(rasterBuf, bandList, x, y, x + w, y - h, rasterBuf.getWidth(), rasterBuf.getHeight()); |
||
1735 | } catch (Exception e) { |
||
1736 | e.printStackTrace(); |
||
1737 | } |
||
1738 | |||
1739 | return rasterBuf;
|
||
1740 | } |
||
1741 | |||
1742 | 8026 | nacho | /**
|
1743 | * Obtiene la zona (Norte / Sur)
|
||
1744 | * @return true si la zona es norte y false si es sur
|
||
1745 | */
|
||
1746 | |||
1747 | public boolean getZone(){ |
||
1748 | |||
1749 | return false; |
||
1750 | } |
||
1751 | |||
1752 | /**
|
||
1753 | *Devuelve el n?mero de zona UTM
|
||
1754 | *@return N?mero de zona
|
||
1755 | */
|
||
1756 | |||
1757 | public int getUTM(){ |
||
1758 | |||
1759 | return 0; |
||
1760 | } |
||
1761 | |||
1762 | /**
|
||
1763 | * Obtiene el sistema de coordenadas geograficas
|
||
1764 | * @return Sistema de coordenadas geogr?ficas
|
||
1765 | */
|
||
1766 | public String getGeogCS(){ |
||
1767 | return new String(""); |
||
1768 | } |
||
1769 | |||
1770 | /**
|
||
1771 | * Devuelve el tama?o de bloque
|
||
1772 | * @return Tama?o de bloque
|
||
1773 | */
|
||
1774 | public int getBlockSize(){ |
||
1775 | if(file != null) |
||
1776 | return file.getBlockSize();
|
||
1777 | else
|
||
1778 | return 0; |
||
1779 | } |
||
1780 | |||
1781 | /**
|
||
1782 | * Obtiene el objeto que contiene los metadatos
|
||
1783 | */
|
||
1784 | public Metadata getMetadata() {
|
||
1785 | if(file != null) |
||
1786 | return file.getMetadataJavaObject();
|
||
1787 | else
|
||
1788 | return null; |
||
1789 | } |
||
1790 | |||
1791 | /**
|
||
1792 | * Obtiene el flag que dice si la imagen est? o no georreferenciada
|
||
1793 | * @return true si est? georreferenciada y false si no lo est?.
|
||
1794 | */
|
||
1795 | public boolean isGeoreferenced() { |
||
1796 | if(file != null) |
||
1797 | return file.isGeoreferenced();
|
||
1798 | else
|
||
1799 | return false; |
||
1800 | } |
||
1801 | |||
1802 | /**
|
||
1803 | * Informa de si el driver ha supersampleado en el ?ltimo dibujado. Es el driver el que colocar?
|
||
1804 | * el valor de esta variable cada vez que dibuja.
|
||
1805 | * @return true si se ha supersampleado y false si no se ha hecho.
|
||
1806 | */
|
||
1807 | public boolean isSupersampling() { |
||
1808 | if(file != null) |
||
1809 | return file.isSupersampling;
|
||
1810 | else
|
||
1811 | return false; |
||
1812 | } |
||
1813 | |||
1814 | /**
|
||
1815 | * Obtiene los par?metros de la transformaci?n af?n que corresponde con los elementos de
|
||
1816 | * un fichero tfw.
|
||
1817 | * <UL>
|
||
1818 | * <LI>[1]tama?o de pixel en X</LI>
|
||
1819 | * <LI>[2]rotaci?n en X</LI>
|
||
1820 | * <LI>[4]rotaci?n en Y</LI>
|
||
1821 | * <LI>[5]tama?o de pixel en Y</LI>
|
||
1822 | * <LI>[0]origen en X</LI>
|
||
1823 | * <LI>[3]origen en Y</LI>
|
||
1824 | * </UL>
|
||
1825 | * Este m?todo debe ser reimplementado por el driver si tiene esta informaci?n. En principio
|
||
1826 | * Gdal es capaz de proporcionarla de esta forma.
|
||
1827 | 8631 | nacho | *
|
1828 | * En caso de que exista fichero .rmf asociado al raster pasaremos de la informaci?n de georreferenciaci?n
|
||
1829 | * del .tfw y devolveremos la que est? asociada al rmf
|
||
1830 | 8026 | nacho | * @return vector de double con los elementos de la transformaci?n af?n.
|
1831 | */
|
||
1832 | public double[] getTransform(){ |
||
1833 | 8631 | nacho | if(file != null && file.trans != null && !this.rmfExists()) |
1834 | 8026 | nacho | return file.trans.adfgeotransform;
|
1835 | 8631 | nacho | else{
|
1836 | if(this.rmfExists){ |
||
1837 | double[] rmfGeoref = { rmfTransform.getTranslateX(), |
||
1838 | rmfTransform.getScaleX(), |
||
1839 | rmfTransform.getShearX(), |
||
1840 | rmfTransform.getTranslateY(), |
||
1841 | rmfTransform.getShearY(), |
||
1842 | rmfTransform.getScaleY()}; |
||
1843 | return rmfGeoref;
|
||
1844 | } |
||
1845 | return null; |
||
1846 | } |
||
1847 | |||
1848 | 8026 | nacho | } |
1849 | 10645 | nacho | |
1850 | /*
|
||
1851 | * (non-Javadoc)
|
||
1852 | * @see org.gvsig.fmap.driver.GeoRasterFile#rasterToWorld(java.awt.geom.Point2D)
|
||
1853 | */
|
||
1854 | public Point2D rasterToWorld(Point2D pt) { |
||
1855 | return file.rasterToWorld(pt);
|
||
1856 | } |
||
1857 | 8026 | nacho | |
1858 | 10645 | nacho | /*
|
1859 | * (non-Javadoc)
|
||
1860 | * @see org.gvsig.fmap.driver.GeoRasterFile#worldToRaster(java.awt.geom.Point2D)
|
||
1861 | */
|
||
1862 | public Point2D worldToRaster(Point2D pt){ |
||
1863 | return file.worldToRaster(pt);
|
||
1864 | } |
||
1865 | |||
1866 | public void readPalette(){ |
||
1867 | file.readPalette(); |
||
1868 | } |
||
1869 | 8026 | nacho | } |
1870 | |||
1871 |