Revision 9392

View differences:

org.gvsig.raster.gdal/tags/org.gvsig.raster.gdal-2.2.80/org.gvsig.raster.gdal.io/src/main/resources/META-INF/services/org.gvsig.tools.library.Library
1
org.gvsig.raster.gdal.io.DefaultGdalIOLibrary
org.gvsig.raster.gdal/tags/org.gvsig.raster.gdal-2.2.80/org.gvsig.raster.gdal.io/src/main/java/org/gvsig/raster/gdal/util/DefaultCRSUtils.java
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.gdal.util;
23

  
24
import org.cresques.cts.ICRSFactory;
25
import org.cresques.cts.IProjection;
26
import org.gdal.osr.SpatialReference;
27

  
28
import org.gvsig.fmap.crs.CRSFactory;
29
import org.gvsig.fmap.dal.coverage.util.CRSUtils;
30

  
31
/**
32
 * Esta clase se encarga de hacer la conversion entre Wkt e IProjection.
33
 *
34
 * El uso se hace mediante dos llamadas estaticas que son:
35
 * convertIProjectionToWkt y
36
 * convertWktToIProjection.
37
 *
38
 * Antes de usarlos, hay que saber si tenemos acceso a gvSIG e intentar coger el
39
 * factory desde all?.
40
 * Ya que su uso consume tiempo y espacio de memoria y es preferible
41
 * reaprovechar ese objeto ya
42
 * creado. Esto se hace con setCRSFactory.
43
 *
44
 * En caso de no asignarse el ya existente, el crear? uno interno y lo dejara en
45
 * una variable estatica.
46
 *
47
 * @version 11/07/2008
48
 * @author BorSanZa - Borja S?nchez Zamorano (borja.sanchez@iver.es)
49
 */
50
public class DefaultCRSUtils implements CRSUtils {
51

  
52
    private ICRSFactory factory = null;
53

  
54
    public void setCRSFactory(ICRSFactory factory) {
55
        this.factory = factory;
56
    }
57

  
58
    /**
59
     * Devuelve el CRSFactory asignado desde fuera o creado desde dentro, todo
60
     * depende de como se haya
61
     * usado.
62
     *
63
     * @param code
64
     * @return
65
     */
66
    private IProjection getCRS(String code) {
67
        if (factory == null)
68
            factory = CRSFactory.getCRSFactory(); // new ProjectionPool();
69
        return factory.get(code);
70
    }
71

  
72
    public IProjection convertWktToIProjection(String wkt) {
73
        if (wkt == null || wkt.equals(""))
74
            return null;
75

  
76
        String code = null;
77
        String name = null;
78

  
79
        SpatialReference oSRSSource = new SpatialReference();
80

  
81
        oSRSSource.ImportFromWkt(wkt);
82

  
83
        code = oSRSSource.GetAuthorityCode("PROJCS");
84
        if (code == null)
85
            code = oSRSSource.GetAuthorityCode("GEOGCS");
86
        name = oSRSSource.GetAuthorityName("PROJCS");
87
        if (name == null)
88
            name = oSRSSource.GetAuthorityName("GEOGCS");
89
        try {
90
            if (name != null && code != null)
91
                return getCRS(name + ":" + code);
92
        } catch (NumberFormatException ex) {
93
            return null;
94
        }
95

  
96
        return null;
97
    }
98

  
99
    public String convertIProjectionToWkt(IProjection projection) {
100
        if (projection == null)
101
            return null;
102
        return projection.export(ICRSFactory.FORMAT_WKT);
103
    }
104
}
0 105

  
org.gvsig.raster.gdal/tags/org.gvsig.raster.gdal-2.2.80/org.gvsig.raster.gdal.io/src/main/java/org/gvsig/raster/gdal/overview/GdalOverviewBuilder.java
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.gdal.overview;
23

  
24
import org.gvsig.addo.BuildingOverviewsException;
25
import org.gvsig.addo.IOverviewIncrement;
26
import org.gvsig.addo.Jaddo;
27
import org.gvsig.addo.WritingException;
28
import org.gvsig.fmap.dal.coverage.exception.OverviewException;
29
import org.gvsig.fmap.dal.coverage.process.BaseIncrementableTask;
30
import org.gvsig.fmap.dal.coverage.process.overview.OverviewBuilder;
31

  
32
/**
33
 * Servicios ofrecidos por el proceso de construcci?n de overviews. Esta
34
 * implementaci?n usa gdal para construir las overviews.
35
 * 
36
 * @author Nacho Brodin (nachobrodin@gmail.com)
37
 */
38
public class GdalOverviewBuilder implements OverviewBuilder {
39
	private Jaddo        build         = new Jaddo();
40
	private int          value         = 0;
41

  
42
	/**
43
	 * Bindings between an IOverviewIncrement and a BaseIncrementableTask
44
	 * @author Nacho Brodin (nachobrodin@gmail.com)
45
	 */
46
	class ProcessBinding implements IOverviewIncrement {
47
		private BaseIncrementableTask  task = null;
48
		
49
		public ProcessBinding(BaseIncrementableTask task) {
50
			this.task = task;	
51
		}
52
		
53
		public int getPercent() {
54
			return task.getPercent();
55
		}
56

  
57
		public void setPercent(int value) {
58
			task.setPercent(value);
59
		}
60
	}
61
	
62
	/*
63
	 * (non-Javadoc)
64
	 * @see org.gvsig.fmap.dal.coverage.process.overview.OverviewBuilder#buildOverviews(int, java.lang.String, int[])
65
	 */
66
	public void buildOverviews(int resamplingAlg, String file, int[] overviews)
67
			throws OverviewException {
68
		try {
69
			build.buildOverviews(resamplingAlg, file, overviews);
70
		} catch (BuildingOverviewsException e) {
71
			throw new OverviewException("Error building overviews", e);
72
		} catch (WritingException e) {
73
			throw new OverviewException("Error writing overviews", e);
74
		}
75
	}
76

  
77
	/*
78
	 * (non-Javadoc)
79
	 * @see org.gvsig.fmap.dal.coverage.process.overview.OverviewBuilder#getPercent()
80
	 */
81
	public int getPercent() {
82
		return value;
83
	}
84

  
85
	/*
86
	 * (non-Javadoc)
87
	 * @see org.gvsig.fmap.dal.coverage.process.overview.OverviewBuilder#setIncrementListener(org.gvsig.addo.IOverviewIncrement)
88
	 */
89
	public void setIncrementListener(BaseIncrementableTask incr) {
90
		build.setIncrementListener(new ProcessBinding(incr));
91
	}
92

  
93
	/*
94
	 * (non-Javadoc)
95
	 * @see org.gvsig.fmap.dal.coverage.process.overview.OverviewBuilder#setPercent(int)
96
	 */
97
	public void setPercent(int value) {
98
		this.value = value;
99
	}
100
}
0 101

  
org.gvsig.raster.gdal/tags/org.gvsig.raster.gdal-2.2.80/org.gvsig.raster.gdal.io/src/main/java/org/gvsig/raster/gdal/io/PngWriter.java
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.gdal.io;
23

  
24
import java.awt.geom.AffineTransform;
25
import java.io.File;
26
import java.io.IOException;
27

  
28
import org.cresques.cts.IProjection;
29
import org.gvsig.fmap.dal.coverage.RasterLocator;
30
import org.gvsig.fmap.dal.coverage.datastruct.Params;
31
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
32
import org.gvsig.fmap.dal.coverage.store.DataServerWriter;
33
import org.gvsig.jgdal.GdalDataset;
34
import org.gvsig.jgdal.GdalDriver;
35
import org.gvsig.jgdal.GdalException;
36
import org.gvsig.raster.gdal.io.features.PngFeatures;
37
import org.gvsig.raster.impl.store.WriteFileFormatFeatures;
38
import org.gvsig.raster.impl.store.writer.DefaultRasterWriter;
39
import org.gvsig.raster.util.DefaultProviderServices;
40
import org.gvsig.tools.ToolsLocator;
41
import org.gvsig.tools.extensionpoint.ExtensionPoint;
42
import org.gvsig.tools.extensionpoint.ExtensionPointManager;
43
/**
44
 * Driver para la escritura de Png.
45
 * Este driver utiliza GdalWriter para salvar Png.
46
 * La escritura de un png no es posible utilizando un servidor de datos
47
 * como el que usan los drivers comunes por lo que ser? necesario salvar antes
48
 * a Tif con el driver de Gdal para posteriormente convertir la imagen completa
49
 * a png. El problema que tiene es el mismo del jpg y es que el dataset solo soporta la
50
 * escritura rw y no rw+.
51
 *
52
 * @version 22/07/2008
53
 * @author Nacho Brodin (nachobrodin@gmail.com)
54
 */
55
public class PngWriter extends DefaultRasterWriter {
56

  
57
	// Datos de registro de drivers
58
	public static void register() {
59
		DefaultProviderServices pInfo = (DefaultProviderServices)RasterLocator.getManager().getProviderServices();
60
		ExtensionPointManager extensionPoints =ToolsLocator.getExtensionPointManager();
61
		ExtensionPoint point=extensionPoints.get("RasterWriter");
62
		point.append("png", "", PngWriter.class);
63
		pInfo.getFileFeature().put("png", new PngFeatures());
64
	}
65

  
66
	private GdalWriter gdalWriter = null;
67
	private String     outTif     = null;
68
	private String     outPng     = null;
69

  
70
	/**
71
	 * Carga los par?metros de este driver.
72
	 */
73
	public void loadParams(String ident) {
74
		WriteFileFormatFeatures wfff = (WriteFileFormatFeatures) pInfo.getFileFeature().get(ident);
75
		wfff.loadParams();
76
		driverParams = wfff.getParams();
77
	}
78
	
79
	/*
80
	 * (non-Javadoc)
81
	 * @see org.gvsig.fmap.dal.coverage.store.RasterWriter#getProviderName()
82
	 */
83
	public String getProviderName() {
84
		return GdalProvider.NAME;
85
	}
86

  
87
	/**
88
	 * Constructor para la obtenci?n de par?metros del driver
89
	 * @param drvType Tipo de driver
90
	 */
91
	public PngWriter(String fileName) {
92
		ident = fileUtil.getExtensionFromFileName(fileName);
93
		driver = ((WriteFileFormatFeatures) pInfo.getFileFeature().get(ident)).getDriverName();
94
		gdalWriter = new GdalWriter(fileName);
95

  
96
		loadParams(ident);
97
	}
98

  
99
	/**
100
	 * Constructor para salvar datos servidos por el cliente
101
	 * @param dataWriter Objeto servidor de datos para el driver de escritura
102
	 * @param outSizeX N?mero de pixels en X de la imagen de salida
103
	 * @param outSizeY N?mero de pixels en Y de la imagen de salida
104
	 * @param outFilename Fichero de salida
105
	 * @param extentMaxX Posici?n en X m?xima del extent
106
	 * @param extentMinX Posici?n en X m?nima del extent
107
	 * @param extentMaxY Posici?n en Y m?xima del extent
108
	 * @param extentMinY Posici?n en Y m?nima del extent
109
	 * @param nBands N?mero de bandas
110
	 * @param drvType Tipo de driver
111
	 * @throws GdalException
112
	 * @throws IOException
113
	 */
114
	public PngWriter(DataServerWriter dataWriter,
115
							String outFileName,
116
							Integer nBands,
117
							AffineTransform at,
118
							Integer outSizeX,
119
							Integer outSizeY,
120
							Integer dataType,
121
							Params params,
122
							IProjection proj,
123
							Boolean geo)throws GdalException, IOException  {
124
		ident = fileUtil.getExtensionFromFileName(outFileName);
125
		driver = ((WriteFileFormatFeatures) pInfo.getFileFeature().get(ident)).getDriverName();
126
		outPng = outFileName;
127
		outTif = outFileName.substring(0, outFileName.lastIndexOf("."));
128
		outTif += ".tif";
129
		this.at = at;
130

  
131
		gdalWriter = new GdalWriter(dataWriter, outTif, nBands, at, outSizeX, outSizeY, dataType, params, proj, geo);
132
		if (params == null)
133
			loadParams(ident);
134
		else
135
			this.driverParams = params;
136
	}
137

  
138
	/**
139
	 * Asigna el tipo de driver con el que se salvar? la imagen
140
	 * @param drvType Tipo de driver
141
	 */
142
	public void setDriverType(String drvType) {
143
		gdalWriter.setDriverType(drvType);
144
	}
145

  
146
		/**
147
	 * Realiza la funci?n de compresi?n a partir de un GeoRasterFile.
148
	 * @throws IOException
149
	 */
150
	public void fileWrite() throws IOException, ProcessInterruptedException {
151
		gdalWriter.fileWrite();
152
	}
153

  
154
	/**
155
	 * Realiza una copia en el formato especificado.
156
	 * @throws IOException
157
	 */
158
	public static void createCopy(GdalDriver driverDst, String dst, String src,
159
			boolean bstrict, String[] params) throws IOException, GdalException {
160
		GdalWriter.createCopy(driverDst, dst, src, bstrict, params);
161
	}
162

  
163
	/**
164
	 * Realiza la escritura de datos con los datos que le pasa el cliente.
165
	 * @throws IOException
166
	 */
167
	public void dataWrite() throws IOException, ProcessInterruptedException {
168
		if(colorInterp != null)
169
			gdalWriter.setColorBandsInterpretation(colorInterp.getValues());
170
		gdalWriter.dataWrite();
171
		if (gdalWriter.isWrite()) {
172
			gdalWriter.writeClose();
173
			if (outTif != null) {
174
				GdalDriver driver = null;
175
				try {
176
					driver = GdalDataset.getDriverByName("PNG");
177
					GdalWriter.createCopy(driver, outPng, outTif, false, gdalWriter.gdalParamsFromRasterParams(driverParams));
178
				} catch (GdalException exc) {
179
					throw new IOException("No se ha podido obtener el driver.");
180
				}
181
				File file = new File(outTif);
182
				file.delete();
183
			}
184
		}
185
	}
186

  
187
	/**
188
	 * Cancela el salvado de datos.
189
	 */
190
	public void writeCancel() {
191
		gdalWriter.setWrite(false);
192
	}
193

  
194
	/*
195
	 * (non-Javadoc)
196
	 * @see org.gvsig.raster.dataset.GeoRasterWriter#setParams(org.gvsig.raster.dataset.Params)
197
	 */
198
	public void setParams(Params params) {
199
		driverParams = params;
200
		if (gdalWriter != null)
201
			gdalWriter.setParams(params);
202
	}
203

  
204
	/**
205
	 * Cierra el compresor ecw.
206
	 * @throws GdalException
207
	 */
208
	public void writeClose() {
209
	// El close del tif se hizo en dataWrite
210
	}
211

  
212
	public void setWkt(String wkt) {}
213
}
0 214

  
org.gvsig.raster.gdal/tags/org.gvsig.raster.gdal-2.2.80/org.gvsig.raster.gdal.io/src/main/java/org/gvsig/raster/gdal/io/GdalDataSource.java
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.gdal.io;
23

  
24
import java.awt.Color;
25
import java.awt.Rectangle;
26
import java.awt.geom.AffineTransform;
27
import java.awt.geom.NoninvertibleTransformException;
28
import java.awt.geom.Point2D;
29
import java.io.IOException;
30
import java.util.ArrayList;
31
import java.util.List;
32

  
33
import org.gdal.gdal.gdal;
34
import org.gdal.ogr.ogr;
35
import org.slf4j.Logger;
36
import org.slf4j.LoggerFactory;
37

  
38
import org.gvsig.fmap.dal.coverage.RasterLibrary;
39
import org.gvsig.fmap.dal.coverage.RasterLocator;
40
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
41
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
42
import org.gvsig.fmap.dal.coverage.datastruct.ColorItem;
43
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
44
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
45
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
46
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
47
import org.gvsig.fmap.dal.coverage.store.props.ColorTable;
48
import org.gvsig.fmap.dal.coverage.util.FileUtils;
49
import org.gvsig.jgdal.GdalBuffer;
50
import org.gvsig.jgdal.GdalColorEntry;
51
import org.gvsig.jgdal.GdalColorTable;
52
import org.gvsig.jgdal.GdalDataset;
53
import org.gvsig.jgdal.GdalException;
54
import org.gvsig.jgdal.GdalRasterBand;
55
import org.gvsig.jgdal.GeoTransform;
56
import org.gvsig.jgdal.GeoTransform.GeoTransformException;
57
import org.gvsig.raster.impl.datastruct.ColorItemImpl;
58
import org.gvsig.raster.impl.datastruct.DefaultNoData;
59
import org.gvsig.raster.impl.datastruct.ExtentImpl;
60
import org.gvsig.raster.impl.process.RasterTask;
61
import org.gvsig.raster.impl.process.RasterTaskQueue;
62
import org.gvsig.raster.impl.store.properties.DataStoreColorInterpretation;
63
import org.gvsig.raster.impl.store.properties.DataStoreColorTable;
64
import org.gvsig.raster.impl.store.properties.DataStoreMetadata;
65
import org.gvsig.raster.impl.store.properties.DataStoreTransparency;
66
import org.gvsig.tools.dispose.Disposable;
67
import org.gvsig.tools.task.TaskStatus;
68
/**
69
 * Soporte 'nativo' para ficheros desde GDAL.
70
 */
71
public class GdalDataSource extends GdalDataset implements Disposable {
72
	private String                       fileName                = null;
73
	private String                       shortName               = "";
74
	public 	GeoTransform                 trans                   = null;
75
	public int                           width                   = 0, height = 0;
76
	public double                        originX                 = 0D, originY = 0D;
77
	public String                        version                 = "";
78
	protected int                        rBandNr                 = 1, gBandNr = 2, bBandNr = 3, aBandNr = 4;
79
	private int[]                        dataType                = null;
80
	DataStoreMetadata                    metadata                = null;
81
	protected boolean                    georeferenced           = true;
82

  
83
	private static final Logger logger = LoggerFactory.getLogger(GdalDataSource.class);
84

  
85
	/**
86
	 * Vectores que contiene los desplazamientos de un pixel cuando hay supersampling.
87
	 * , es decir el n?mero de pixels de pantalla que tiene un pixel de imagen. Como todos
88
	 * los pixeles no tienen el mismo ancho y alto ha de meterse en un array y no puede ser
89
	 * una variable. Adem?s hay que tener en cuenta que el primer y ?ltimo pixel son de
90
	 * distinto tama?o que el resto.
91
	 */
92
	public int[]                              stepArrayX             = null;
93
	public int[]                              stepArrayY             = null;
94
	protected GdalRasterBand[]                gdalBands              = null;
95
	private double                            lastReadLine           = -1;
96
	private int                               overviewWidth          = -1;
97
	private int                               overviewHeight         = -1;
98
	private int                               currentViewWidth       = -1;
99
	private int                               currentViewHeight      = -1;
100
	private double                            currentViewX           = 0D;
101
	private double                            viewportScaleX         = 0D;
102
	private double                            viewportScaleY         = 0D;
103
	private double                            stepX                  = 0D;
104
	private double                            stepY                  = 0D;
105
	public boolean                            isSupersampling        = false;
106
	private boolean                           open                   = false;
107
	/**
108
	 * Estado de transparencia del raster.
109
	 */
110
	protected DataStoreTransparency           fileTransparency       = null;
111
	protected DataStoreColorTable             palette                = null;
112
	protected DataStoreColorInterpretation    colorInterpr           = null;
113
	protected AffineTransform                 ownTransformation      = null;
114
	protected AffineTransform                 externalTransformation = new AffineTransform();
115

  
116
	public static int getGdalTypeFromRasterBufType(int rasterBufType) {
117
		switch (rasterBufType) {
118
			case Buffer.TYPE_BYTE: return GdalDataset.GDT_Byte;
119
			case Buffer.TYPE_USHORT: return GdalDataset.GDT_UInt16;
120
			case Buffer.TYPE_SHORT: return GdalDataset.GDT_Int16;
121
			case Buffer.TYPE_INT: return GdalDataset.GDT_Int32;
122
			case Buffer.TYPE_FLOAT: return GdalDataset.GDT_Float32;
123
			case Buffer.TYPE_DOUBLE: return GdalDataset.GDT_Float64;
124
			case Buffer.TYPE_UNDEFINED: return GdalDataset.GDT_Unknown;
125
			case Buffer.TYPE_IMAGE: return GdalDataset.GDT_Byte;
126
		}
127
		return GdalDataset.GDT_Unknown;
128
	}
129

  
130
	/**
131
	 * Conversi?n de los tipos de datos de gdal a los tipos de datos de RasterBuf
132
	 * @param gdalType Tipo de dato de gdal
133
	 * @return Tipo de dato de RasterBuf
134
	 */
135
	public static int getRasterBufTypeFromGdalType(int gdalType) {
136
		switch (gdalType) {
137
			case 1:// Eight bit unsigned integer GDT_Byte = 1
138
				return Buffer.TYPE_BYTE;
139

  
140
			case 3:// Sixteen bit signed integer GDT_Int16 = 3,
141
				return Buffer.TYPE_SHORT;
142

  
143
			case 2:// Sixteen bit unsigned integer GDT_UInt16 = 2
144
				//return RasterBuffer.TYPE_USHORT;
145
				return Buffer.TYPE_SHORT; //Apa?o para usar los tipos de datos que soportamos
146

  
147
			case 5:// Thirty two bit signed integer GDT_Int32 = 5
148
				return Buffer.TYPE_INT;
149

  
150
			case 6:// Thirty two bit floating point GDT_Float32 = 6
151
				return Buffer.TYPE_FLOAT;
152

  
153
			case 7:// Sixty four bit floating point GDT_Float64 = 7
154
				return Buffer.TYPE_DOUBLE;
155

  
156
				// TODO:Estos tipos de datos no podemos gestionarlos. Habria que definir
157
				// el tipo complejo y usar el tipo long que de momento no se gasta.
158
			case 4:// Thirty two bit unsigned integer GDT_UInt32 = 4,
159
				return Buffer.TYPE_INT;
160
				//return RasterBuffer.TYPE_UNDEFINED; // Deberia devolver un Long
161

  
162
			case 8:// Complex Int16 GDT_CInt16 = 8
163
			case 9:// Complex Int32 GDT_CInt32 = 9
164
			case 10:// Complex Float32 GDT_CFloat32 = 10
165
			case 11:// Complex Float64 GDT_CFloat64 = 11
166
				return Buffer.TYPE_UNDEFINED;
167
		}
168
		return Buffer.TYPE_UNDEFINED;
169
	}
170

  
171
	/**
172
	 * Overview usada en el ?ltimo setView
173
	 */
174
	int currentOverview = -1;
175

  
176
	public GdalDataSource(String fName) throws GdalException, IOException {
177
		super();
178
		init(fName);
179
	}
180

  
181
//	private static Dataset initializeGdal(String fName) throws GdalException {
182
//		gdal.AllRegister();
183
//		ogr.RegisterAll();
184
//		Dataset data = gdal.Open(fName, 1);
185
//		if (data == null)
186
//			throw new GdalException("Error en la apertura del fichero. El fichero no tiene un formato v?lido.");
187
//
188
//		return data;
189
//	}
190

  
191
	private void init(String fName) throws GdalException, IOException {
192
		gdal.AllRegister();
193
		ogr.RegisterAll();
194
		fileName = fName;
195
		open(fName, GA_ReadOnly);
196
		open = true;
197
		if (getDataset() == null)
198
			throw new GdalException("Error en la apertura del fichero. El fichero no tiene un formato v?lido.");
199
		width = getRasterXSize();
200
		height = getRasterYSize();
201

  
202
		int[] dt = new int[getRasterCount()];
203
		for (int i = 0; i < getRasterCount(); i++)
204
			dt[i] = this.getRasterBand(i + 1).getRasterDataType();
205
		setDataType(dt);
206
		shortName = getDriverShortName();
207
		colorInterpr = new DataStoreColorInterpretation(getRasterCount());
208
		fileTransparency = new DataStoreTransparency(colorInterpr);
209
		metadata = new DataStoreMetadata(getMetadata(), colorInterpr);
210

  
211
		// Asignamos la interpretaci?n de color leida por gdal a cada banda. Esto
212
		// nos sirve para saber que banda de la imagen va asignada a cada banda de
213
		// visualizaci?n (ARGB)
214
		metadata.initNoDataByBand(getRasterCount());
215
		for (int i = 0; i < getRasterCount(); i++) {
216
			GdalRasterBand rb = getRasterBand(i + 1);
217
			String colorInt = getColorInterpretationName(rb.getRasterColorInterpretation());
218
			metadata.setNoDataEnabled(rb.existsNoDataValue());
219
			if(rb.existsNoDataValue()) {
220
				metadata.setNoDataValue(i, rb.getRasterNoDataValue());
221
				metadata.setNoDataEnabled(rb.existsNoDataValue());
222
			}
223
			colorInterpr.setColorInterpValue(i, colorInt);
224
			if (colorInt.equals("Alpha"))
225
				fileTransparency.setTransparencyBand(i);
226

  
227
			if (rb.getRasterColorTable() != null && palette == null) {
228
				palette = new DataStoreColorTable(gdalColorTable2ColorItems(rb.getRasterColorTable()), false);
229
//				fileTransparency.setTransparencyRangeList(palette.getTransparencyRange());
230
			}
231
		}
232
		fileTransparency.setTransparencyByPixelFromMetadata(metadata);
233

  
234
		try {
235
			trans = getGeoTransform();
236
                        if( !trans.isValid() ) {
237
                            throw new GeoTransformException();
238
                        }
239

  
240
			double psX = trans.adfgeotransform[1];
241
			double psY = trans.adfgeotransform[5];
242
			double rotX = trans.adfgeotransform[4];
243
			double rotY = trans.adfgeotransform[2];
244
			double offX = trans.adfgeotransform[0];
245
			double offY = trans.adfgeotransform[3];
246

  
247
			ownTransformation = new AffineTransform(psX, rotX, rotY, psY, offX, offY);
248
					//trans.adfgeotransform[1], trans.adfgeotransform[4], trans.adfgeotransform[2], trans.adfgeotransform[5], trans.adfgeotransform[0], trans.adfgeotransform[3]);
249
			externalTransformation = (AffineTransform) ownTransformation.clone();
250
			overviewWidth = width;
251
			overviewHeight = height;
252

  
253
			this.georeferenced = true;
254
                } catch (GeoTransformException exc) {
255
                    // Transformaci?n para ficheros sin georreferenciaci?n. Se invierte la Y
256
                    // ya que las WC decrecen de
257
                    // arriba a abajo y los pixeles crecen de arriba a abajo
258
		    logger.warn("Can't retrieve transformation from file '"+fName+"' use default.");
259
                    ownTransformation = new AffineTransform(1, 0, 0, -1, 0, height);
260
                    externalTransformation = (AffineTransform) ownTransformation.clone();
261
                    overviewWidth = width;
262
                    overviewHeight = height;
263
                    this.georeferenced = false;
264

  
265
                } catch (Exception exc) {
266
			// Transformaci?n para ficheros sin georreferenciaci?n. Se invierte la Y
267
			// ya que las WC decrecen de
268
			// arriba a abajo y los pixeles crecen de arriba a abajo
269
		    logger.warn("Can't retrieve transformation from file '"+fName+"' use default.", exc);
270
			ownTransformation = new AffineTransform(1, 0, 0, -1, 0, height);
271
			externalTransformation = (AffineTransform) ownTransformation.clone();
272
			overviewWidth = width;
273
			overviewHeight = height;
274
			this.georeferenced = false;
275

  
276
		}
277
	}
278

  
279
	/**
280
	 * Returns true if this provider is open and false if don't
281
	 * @return
282
	 */
283
	public boolean isOpen() {
284
		return open;
285
	}
286

  
287
	/**
288
	 * Obtiene el flag que informa de si el raster tiene valor no data o no.
289
	 * Consultar? todas las bandas del mismo y si alguna tiene valor no data
290
	 * devuelve true sino devolver? false.
291
	 * @return true si tiene valor no data y false si no lo tiene
292
	 * @throws GdalException
293
	 */
294
	public boolean existsNoDataValue() throws GdalException {
295
		for (int i = 0; i < getRasterCount(); i++) {
296
			GdalRasterBand rb = getRasterBand(i + 1);
297
			if (rb.existsNoDataValue())
298
				return true;
299
		}
300
		return false;
301
	}
302

  
303
	/**
304
	 * Obtiene el flag que informa de si el raster tiene valor no data o no
305
	 * en una banda concreta.
306
	 * @return true si tiene valor no data en esa banda y false si no lo tiene
307
	 * @param band Posici?n de la banda a consultar (0..n)
308
	 * @throws GdalException
309
	 */
310
	public boolean existsNoDataValue(int band) throws GdalException {
311
		GdalRasterBand rb = getRasterBand(band + 1);
312
		return rb.existsNoDataValue();
313
	}
314

  
315
	/**
316
	 * Gets nodata value
317
	 * @return
318
	 */
319
	public NoData getNoDataValue() {
320
		Number value = null;
321
		int type = getRasterBufTypeFromGdalType(getDataType()[0]);
322
		if (metadata != null && metadata.isNoDataEnabled() && metadata.getNoDataValue().length > 0) {
323
			switch (type) {
324
			case Buffer.TYPE_BYTE:
325
				if (metadata == null || metadata.getNoDataValue().length == 0)
326
					value = new Byte(RasterLibrary.defaultByteNoDataValue);
327
				else
328
					value = new Byte((byte)metadata.getNoDataValue()[0]);
329
				break;
330
			case Buffer.TYPE_SHORT:
331
				if (metadata == null || metadata.getNoDataValue().length == 0)
332
					value = new Short(RasterLibrary.defaultShortNoDataValue);
333
				else
334
					value = new Short((short)metadata.getNoDataValue()[0]);
335
				break;
336
			case Buffer.TYPE_INT:
337
				if (metadata == null || metadata.getNoDataValue().length == 0)
338
					value = new Integer((int)RasterLibrary.defaultIntegerNoDataValue);
339
				else
340
					value = new Integer((int)metadata.getNoDataValue()[0]);
341
				break;
342
			case Buffer.TYPE_FLOAT:
343
				if (metadata == null || metadata.getNoDataValue().length == 0)
344
					value = new Float(RasterLibrary.defaultFloatNoDataValue);
345
				else
346
					value = new Float(metadata.getNoDataValue()[0]);
347
				break;
348
			case Buffer.TYPE_DOUBLE:
349
				if (metadata == null || metadata.getNoDataValue().length == 0)
350
					value = new Double(RasterLibrary.defaultFloatNoDataValue);
351
				else
352
					value = new Double(metadata.getNoDataValue()[0]);
353
				break;
354
			}
355
		}
356

  
357
		NoData nodata = new DefaultNoData(value, value, fileName);
358
		nodata.setNoDataTransparent(false);
359
		return nodata;
360
	}
361

  
362
	/**
363
	 * Asigna el tipo de dato
364
	 * @param dt entero que representa el tipo de dato
365
	 */
366
	public void setDataType(int[] dt) {
367
		dataType = dt;
368
	}
369

  
370
	/**
371
	 * Obtiene el tipo de dato
372
	 * @return entero que representa el tipo de dato
373
	 */
374
	public int[] getDataType() {
375
		return dataType;
376
	}
377

  
378
	/**
379
	 * Gets the color interpretation
380
	 * @return
381
	 */
382
	public ColorInterpretation getColorInterpretation() {
383
		return colorInterpr;
384
	}
385

  
386
	/**
387
	 * Gets the color table
388
	 * @return
389
	 */
390
	public ColorTable getColorTable() {
391
		return palette;
392
	}
393

  
394
	/**
395
	 * Obtiene un punto 2D con las coordenadas del raster a partir de uno en coordenadas
396
	 * del punto real.
397
	 * Supone rasters no girados
398
	 * @param pt	punto en coordenadas del punto real
399
	 * @return	punto en coordenadas del raster
400
	 */
401
	public Point2D worldToRasterWithoutRot(Point2D pt) {
402
		Point2D p = new Point2D.Double();
403
		AffineTransform at = new AffineTransform(	externalTransformation.getScaleX(), 0,
404
													0, externalTransformation.getScaleY(),
405
													externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
406
		try {
407
			at.inverseTransform(pt, p);
408
		} catch (NoninvertibleTransformException e) {
409
			return pt;
410
		}
411
		return p;
412
	}
413

  
414
	/**
415
	 * Obtiene un punto 2D con las coordenadas del raster a partir de uno en coordenadas
416
	 * del punto real.
417
	 * Supone rasters no girados
418
	 * @param pt	punto en coordenadas del punto real
419
	 * @return	punto en coordenadas del raster
420
	 */
421
	public Point2D worldToRaster(Point2D pt) {
422
		Point2D p = new Point2D.Double();
423
		try {
424
			externalTransformation.inverseTransform(pt, p);
425
		} catch (NoninvertibleTransformException e) {
426
			return pt;
427
		}
428
		return p;
429
	}
430

  
431
	/**
432
	 * Obtiene un punto del raster en coordenadas pixel a partir de un punto en coordenadas
433
	 * reales.
434
	 * @param pt Punto en coordenadas reales
435
	 * @return Punto en coordenadas pixel.
436
	 */
437
	public Point2D rasterToWorld(Point2D pt) {
438
		Point2D p = new Point2D.Double();
439
		externalTransformation.transform(pt, p);
440
		return p;
441
	}
442

  
443
	/**
444
	 * Calcula el overview a usar. Hay que tener en cuenta que tenemos que tener calculadas las variables
445
	 * viewPortScale, currentFullWidth y currentFulHeight
446
	 * @param coordenada pixel expresada en double que indica la posici?n superior izquierda
447
	 * @throws GdalException
448
	 */
449
	private void calcOverview(Point2D tl, Point2D br) throws GdalException {
450
		gdalBands[0] = getRasterBand(1);
451
		currentOverview = -1;
452
		if (gdalBands[0].getOverviewCount() > 0) {
453
			GdalRasterBand ovb = null;
454
			for (int i = gdalBands[0].getOverviewCount() - 1; i > 0; i--) {
455
				ovb = gdalBands[0].getOverview(i);
456
				if (ovb.getRasterBandXSize() > getRasterXSize() * viewportScaleX) {
457
					currentOverview = i;
458
					viewportScaleX *= ((double) width / (double) ovb.getRasterBandXSize());
459
					viewportScaleY *= ((double) height / (double) ovb.getRasterBandYSize());
460
					stepX = 1D / viewportScaleX;
461
					stepY = 1D / viewportScaleY;
462
					overviewWidth = ovb.getRasterBandXSize();
463
					overviewHeight = ovb.getRasterBandYSize();
464
					currentViewX = Math.min(tl.getX(), br.getX());
465
					lastReadLine = Math.min(tl.getY(), br.getY());
466
					break;
467
				}
468
			}
469
		}
470
	}
471

  
472
	public void setView(double dWorldTLX, double dWorldTLY,
473
						double dWorldBRX, double dWorldBRY,
474
						int nWidth, int nHeight) throws GdalException {
475
		overviewWidth = width;
476
		overviewHeight = height;
477
		Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
478
		Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY));
479
		// Calcula cual es la primera l?nea a leer;
480
		currentViewWidth = nWidth;
481
		currentViewHeight = nHeight;
482
//		wcWidth = Math.abs(br.getX() - tl.getX());
483

  
484
		currentViewX = Math.min(tl.getX(), br.getX());
485

  
486
		viewportScaleX = (double) currentViewWidth / (br.getX() - tl.getX());
487
		viewportScaleY = (double) currentViewHeight / (br.getY() - tl.getY());
488
		stepX = 1D / viewportScaleX;
489
		stepY = 1D / viewportScaleY;
490

  
491
		lastReadLine = Math.min(tl.getY(), br.getY());
492

  
493
		//Para lectura del renderizado (ARGB). readWindow selecciona las bandas que necesita.
494

  
495
		// calcula el overview a usar
496
		gdalBands = new GdalRasterBand[4];
497
		calcOverview(tl, br);
498
	}
499

  
500
	/**
501
	 * Selecciona bandas y overview en el objeto GdalRasterBand[] para el n?mero de bandas solicitado.
502
	 * @param nbands N?mero de bandas solicitado.
503
	 * @throws GdalException
504
	 */
505
	public void selectGdalBands(int nbands) throws GdalException {
506
		gdalBands = new GdalRasterBand[nbands];
507
		// Selecciona las bandas y los overviews necesarios
508
		gdalBands[0] = getRasterBand(1);
509
		for (int i = 0; i < nbands; i++)
510
			gdalBands[i] = gdalBands[0];
511

  
512
		assignDataTypeFromGdalRasterBands(gdalBands);
513
//		setDataType(gdalBands[0].getRasterDataType());
514

  
515
		for (int i = 2; i <= nbands; i++) {
516
			if (getRasterCount() >= i) {
517
				gdalBands[i - 1] = getRasterBand(i);
518
				for (int j = i; j < nbands; j++)
519
					gdalBands[j] = gdalBands[i - 1];
520
			}
521
		}
522

  
523
		if (currentOverview > 0) {
524
			gdalBands[0] = gdalBands[0].getOverview(currentOverview);
525
			for (int i = 2; i <= nbands; i++) {
526
				if (getRasterCount() >= i)
527
					gdalBands[i - 1] = gdalBands[i - 1].getOverview(currentOverview);
528
			}
529
		}
530
	}
531

  
532
	int lastY = -1;
533

  
534
	/**
535
	 * Lee una l?nea de bytes
536
	 * @param line Buffer donde se cargan los datos
537
	 * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
538
	 * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
539
	 * por la izquierda a mitad de pixel
540
	 * @param gdalBuffer Buffer con la l?nea de datos original
541
	 */
542
	private void readLine(byte[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
543
		double j = 0D;
544
		int i = 0;
545
		for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
546
			for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
547
				line[iBand][i] = gdalBuffer[iBand].buffByte[(int) j];
548
			}
549
		}
550
	}
551

  
552
	/**
553
	 * Lee una l?nea de shorts
554
	 * @param line Buffer donde se cargan los datos
555
	 * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
556
	 * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
557
	 * por la izquierda a mitad de pixel
558
	 * @param gdalBuffer Buffer con la l?nea de datos original
559
	 */
560
	private void readLine(short[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
561
		double j = 0D;
562
		int i = 0;
563
		for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
564
			for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
565
				line[iBand][i] = (short) (gdalBuffer[iBand].buffShort[(int) j] & 0xffff);
566
			}
567
		}
568
	}
569

  
570
	/**
571
	 * Lee una l?nea de ints
572
	 * @param line Buffer donde se cargan los datos
573
	 * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
574
	 * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
575
	 * por la izquierda a mitad de pixel
576
	 * @param gdalBuffer Buffer con la l?nea de datos original
577
	 */
578
	private void readLine(int[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
579
		double j = 0D;
580
		int i = 0;
581
		for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
582
			for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
583
				line[iBand][i] = (gdalBuffer[iBand].buffInt[(int) j] & 0xffffffff);
584
			}
585
		}
586
	}
587

  
588
	/**
589
	 * Lee una l?nea de float
590
	 * @param line Buffer donde se cargan los datos
591
	 * @param initOffset Desplazamiento inicial desde el margen izquierdo. Esto es necesario para cuando
592
	 * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
593
	 * por la izquierda a mitad de pixel
594
	 * @param gdalBuffer Buffer con la l?nea de datos original
595
	 */
596
	private void readLine(float[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
597
		double j = 0D;
598
		int i = 0;
599
		for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
600
			for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
601
				line[iBand][i] = gdalBuffer[iBand].buffFloat[(int) j];
602
			}
603
		}
604
	}
605

  
606
	/**
607
	 * Lee una l?nea de doubles
608
	 * @param line Buffer donde se cargan los datos
609
	 * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
610
	 * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
611
	 * por la izquierda a mitad de pixel
612
	 * @param gdalBuffer Buffer con la l?nea de datos original
613
	 */
614
	private void readLine(double[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
615
		double j = 0D;
616
		int i = 0;
617
		for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
618
			for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
619
				line[iBand][i] = gdalBuffer[iBand].buffDouble[(int) j];
620
			}
621
		}
622
	}
623

  
624
	/**
625
	 * Lee una l?nea completa del raster y devuelve un array del tipo correcto. Esta funci?n es util
626
	 * para una lectura rapida de todo el fichero sin necesidad de asignar vista.
627
	 * @param nLine N?mero de l?nea a leer
628
	 * @param band Banda requerida
629
	 * @return Object que es un array unidimendional del tipo de datos del raster
630
	 * @throws GdalException
631
	 */
632
	public Object readCompleteLine(int nLine, int band) throws GdalException {
633
		GdalRasterBand gdalBand = super.getRasterBand(band + 1);
634
		GdalBuffer gdalBuf = null;
635

  
636
		gdalBuf = gdalBand.readRaster(0, nLine, getRasterXSize(), 1, getRasterXSize(), 1, dataType[band]);
637

  
638
		if (dataType[band] == GDT_Byte)
639
			return gdalBuf.buffByte;
640

  
641
		if (dataType[band] == GDT_Int16 || dataType[band] == GDT_UInt16)
642
			return gdalBuf.buffShort;
643

  
644
		if (dataType[band] == GDT_Int32 || dataType[band] == GDT_UInt32)
645
			return gdalBuf.buffInt;
646

  
647
		if (dataType[band] == GDT_Float32)
648
			return gdalBuf.buffFloat;
649

  
650
		if (dataType[band] == GDT_Float64)
651
			return gdalBuf.buffDouble;
652

  
653
		if (dataType[band] == GDT_CInt16 || dataType[band] == GDT_CInt32 ||
654
				dataType[band] == GDT_CFloat32 || dataType[band] == GDT_CFloat64)
655
			return null;
656

  
657
		return null;
658
	}
659

  
660
	/**
661
	 * Lee una bloque completo del raster y devuelve un array tridimensional del tipo correcto. Esta funci?n es util
662
	 * para una lectura rapida de todo el fichero sin necesidad de asignar vista.
663
	 * @param nLine N?mero de l?nea a leer
664
	 * @param band Banda requerida
665
	 * @return Object que es un array unidimendional del tipo de datos del raster
666
	 * @throws GdalException
667
	 */
668
	public Object readBlock(int pos, int blockHeight, double scale) throws GdalException, ProcessInterruptedException {
669
		bBandNr = super.getRasterCount();
670
		int widthBuffer = (int)(getRasterXSize() * scale);
671
		int heightBuffer = (int)(blockHeight * scale);
672

  
673
		RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
674

  
675
		GdalRasterBand[] gdalBand = new GdalRasterBand[bBandNr];
676
		for (int iBand = 0; iBand < gdalBand.length; iBand++)
677
			gdalBand[iBand] = super.getRasterBand(iBand + 1);
678

  
679
		GdalBuffer[] gdalBuf = new GdalBuffer[bBandNr];
680

  
681
		if (dataType[0] == GDT_Byte) {
682
			byte[][][] buf = new byte[bBandNr][heightBuffer][widthBuffer];
683
			for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
684
				gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
685
				for (int iRow = 0; iRow < heightBuffer; iRow++) {
686
					for (int iCol = 0; iCol < widthBuffer; iCol++)
687
						buf[iBand][iRow][iCol] = gdalBuf[iBand].buffByte[iRow * widthBuffer + iCol];
688
					if(task.getEvent() != null)
689
						task.manageEvent(task.getEvent());
690
				}
691
				gdalBuf[iBand].buffByte = null;
692
			}
693
			return buf;
694
		} else if (dataType[0] == GDT_CInt16 || dataType[0] == GDT_Int16  || dataType[0] == GDT_UInt16) {
695
			short[][][] buf = new short[bBandNr][heightBuffer][widthBuffer];
696
			for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
697
				gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
698
				for (int iRow = 0; iRow < heightBuffer; iRow++) {
699
					for (int iCol = 0; iCol < widthBuffer; iCol++)
700
						buf[iBand][iRow][iCol] = gdalBuf[iBand].buffShort[iRow * widthBuffer + iCol];
701
					if(task.getEvent() != null)
702
						task.manageEvent(task.getEvent());
703
				}
704
				gdalBuf[iBand].buffShort = null;
705
			}
706
			return buf;
707
		} else if (dataType[0] == GDT_CInt32 || dataType[0] == GDT_Int32  || dataType[0] == GDT_UInt32) {
708
			int[][][] buf = new int[bBandNr][heightBuffer][widthBuffer];
709
			for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
710
				gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
711
				for (int iRow = 0; iRow < heightBuffer; iRow++) {
712
					for (int iCol = 0; iCol < widthBuffer; iCol++)
713
						buf[iBand][iRow][iCol] = gdalBuf[iBand].buffInt[iRow * widthBuffer + iCol];
714
					if(task.getEvent() != null)
715
						task.manageEvent(task.getEvent());
716
				}
717
				gdalBuf[iBand].buffInt = null;
718
			}
719
			return buf;
720
		} else if(dataType[0] == GDT_Float32 || dataType[0] == GDT_CFloat32) {
721
			float[][][] buf = new float[bBandNr][heightBuffer][widthBuffer];
722
			for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
723
				gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
724
				for (int iRow = 0; iRow < heightBuffer; iRow++) {
725
					for (int iCol = 0; iCol < widthBuffer; iCol++)
726
						buf[iBand][iRow][iCol] = gdalBuf[iBand].buffFloat[iRow * widthBuffer + iCol];
727
					if(task.getEvent() != null)
728
						task.manageEvent(task.getEvent());
729
				}
730
				gdalBuf[iBand].buffFloat = null;
731
			}
732
			return buf;
733
		} else if(dataType[0] == GDT_Float64 || dataType[0] == GDT_CFloat64) {
734
			double[][][] buf = new double[bBandNr][heightBuffer][widthBuffer];
735
			for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
736
				gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
737
				for (int iRow = 0; iRow < heightBuffer; iRow++) {
738
					for (int iCol = 0; iCol < widthBuffer; iCol++)
739
						buf[iBand][iRow][iCol] = gdalBuf[iBand].buffDouble[iRow * widthBuffer + iCol];
740
					if(task.getEvent() != null)
741
						task.manageEvent(task.getEvent());
742
				}
743
				gdalBuf[iBand].buffDouble = null;
744
			}
745
			return buf;
746
		}
747

  
748
		return null;
749
	}
750

  
751
	/**
752
	 * Lectura de una l?nea de datos.
753
	 * @param line
754
	 * @throws GdalException
755
	 */
756
	public void readLine(Object line) throws GdalException {
757
		int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1);
758
		int x = (int) (currentViewX);
759
		int y = (int) (lastReadLine);
760
		GdalBuffer r = null, g = null, b = null;
761
		GdalBuffer a = new GdalBuffer();
762

  
763
		while(y >= gdalBands[0].getRasterBandYSize())
764
			y--;
765

  
766
		if (x+w > gdalBands[0].getRasterBandXSize())
767
			w = gdalBands[0].getRasterBandXSize()-x;
768

  
769
		if(gdalBands[0].getRasterColorTable() != null) {
770
			palette = new DataStoreColorTable(gdalColorTable2ColorItems(gdalBands[0].getRasterColorTable()), false);
771
			r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType[0]);
772
		} else {
773
			a.buffByte = new byte[w];
774
			r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType[0]);
775
			g = b = r;
776
			if (getRasterCount() > 1 && gdalBands[1] != null)
777
				g = gdalBands[1].readRaster(x, y, w, 1, w, 1, dataType[0]);
778
			if (getRasterCount() > 2 && gdalBands[2] != null)
779
				b = gdalBands[2].readRaster(x, y, w, 1, w, 1, dataType[0]);
780
		}
781

  
782
		lastReadLine += stepY;
783

  
784
		double initOffset =  Math.abs(currentViewX - ((int)currentViewX));
785
		GdalBuffer[] bands = {r, g, b};
786

  
787
		if (dataType[0] == GDT_Byte)
788
			readLine((byte[][])line, initOffset, bands);
789
		else if (dataType[0] == GDT_CInt16 || dataType[0] == GDT_Int16  || dataType[0] == GDT_UInt16)
790
			readLine((short[][])line, initOffset, bands);
791
		else if (dataType[0] == GDT_CInt32 || dataType[0] == GDT_Int32  || dataType[0] == GDT_UInt32)
792
			readLine((int[][])line, initOffset, bands);
793
		else if(dataType[0] == GDT_Float32 || dataType[0] == GDT_CFloat32)
794
			readLine((float[][])line, initOffset, bands);
795
		else if(dataType[0] == GDT_Float64 || dataType[0] == GDT_CFloat64)
796
			readLine((double[][])line, initOffset, bands);
797

  
798
		return;
799
	}
800

  
801
	private List<ColorItem> gdalColorTable2ColorItems(GdalColorTable table) {
802
		try {
803
			List<ColorItem> colorItems = new ArrayList<ColorItem>();
804
			for (int iEntry = 0; iEntry < table.getColorEntryCount(); iEntry++) {
805
				GdalColorEntry entry = table.getColorEntryAsRGB(iEntry);
806

  
807
				ColorItem colorItem = new ColorItemImpl();
808
				colorItem.setNameClass("");
809
				colorItem.setValue(iEntry);
810
				colorItem.setColor(new Color(	(int) (entry.c1 & 0xff),
811
																			(int) (entry.c2 & 0xff),
812
																			(int) (entry.c3 & 0xff),
813
																			(int) (entry.c4 & 0xff)));
814

  
815
				colorItems.add(colorItem);
816
			}
817
			return colorItems;
818
		} catch (GdalException ex) {
819
			// No se crea la paleta
820
		}
821
		return null;
822
	}
823

  
824

  
825
	/**
826
	 * Cuando se hace una petici?n de carga de buffer la extensi?n pedida puede
827
	 * estar ajustada a la extensi?n del raster o no estarlo. En caso de no
828
	 * estarlo los pixeles del buffer que caen fuera de la extensi?n del raster
829
	 * tendr?n valor de NoData. Esta funci?n calcula en que pixel del buffer hay
830
	 * que empezar a escribir en caso de que este sea mayor que los datos a leer.
831
	 *
832
	 * @param dWorldTLX Posici?n X superior izquierda en coord reales
833
	 * @param dWorldTLY Posici?n Y superior izquierda en coord reales
834
	 * @param dWorldBRX Posici?n X inferior derecha en coord reales
835
	 * @param dWorldBRY Posici?n Y inferior derecha en coord reales
836
	 * @param nWidth Ancho en pixeles del buffer
837
	 * @param nHeight Alto en pixeles del buffer
838
	 * @return desplazamiento dentro del buffer en X e Y
839
	 */
840
	private int[] calcStepBuffer(Extent dataExtent, int nWidth, int nHeight, int[] stpBuffer) {
841
		Extent imageExtent = getExtentWithoutRot();
842
		Extent ajustDataExtent = RasterLocator.getManager().getRasterUtils().calculateAdjustedView(dataExtent, imageExtent);
843
		if(!RasterLocator.getManager().getRasterUtils().compareExtents(dataExtent, ajustDataExtent)){
844
			Point2D p1 = worldToRasterWithoutRot(new Point2D.Double(ajustDataExtent.minX(), ajustDataExtent.maxY()));
845
			Point2D p2 = worldToRasterWithoutRot(new Point2D.Double(ajustDataExtent.maxX(), ajustDataExtent.minY()));
846
			Point2D p3 = worldToRasterWithoutRot(new Point2D.Double(dataExtent.minX(), dataExtent.maxY()));
847
			//    		Point2D p4 = worldToRasterWithoutRot(new Point2D.Double(dataExtent.maxX(), dataExtent.minY()));
848
			//Ese es el ancho y alto q tendr?a el buffer en caso de haberse ajustado
849
			int w = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX()));
850
			int h = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
851

  
852
			stpBuffer[0] = (int)(p1.getX() + (-p3.getX()));
853
			stpBuffer[1] = (int)(p1.getY() + (-p3.getY()));
854
			stpBuffer[2] = stpBuffer[0] + w;
855
			stpBuffer[3] = stpBuffer[1] + h;
856
			return new int[]{w, h};
857
		}
858
		return new int[]{nWidth, nHeight};
859
	}
860

  
861
	/**
862
	 * Lee una ventana de datos sin resampleo a partir de coordenadas reales.
863
	 * @param buf Buffer donde se almacenan los datos
864
	 * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
865
	 * @param dWorldTLX Posici?n X superior izquierda en coord reales
866
	 * @param dWorldTLY Posici?n Y superior izquierda en coord reales
867
	 * @param dWorldBRX Posici?n X inferior derecha en coord reales
868
	 * @param dWorldBRY Posici?n Y inferior derecha en coord reales
869
	 * @param nWidth Ancho en pixeles del buffer
870
	 * @param nHeight Alto en pixeles del buffer
871
	 * @throws GdalException
872
	 */
873
	public void readWindow(Buffer buf, BandList bandList, double ulx, double uly,double lrx, double lry,
874
			int nWidth, int nHeight, boolean adjustToExtent, TaskStatus status) throws GdalException, ProcessInterruptedException {
875
		Extent petExtent = new ExtentImpl(ulx, uly, lrx, lry);
876
		setView(ulx, uly, lrx, lry, nWidth, nHeight);
877
		Point2D tl = worldToRaster(new Point2D.Double(ulx, uly));
878
		Point2D br = worldToRaster(new Point2D.Double(lrx, lry));
879

  
880
		if(tl.getX() > br.getX())
881
			tl.setLocation(tl.getX() - 1, tl.getY());
882
		else
883
			br.setLocation(br.getX() - 1, br.getY());
884

  
885
		if(tl.getY() > br.getY())
886
			tl.setLocation(tl.getX(), tl.getY() - 1);
887
		else
888
			br.setLocation(br.getX(), br.getY() - 1);
889

  
890
		if(gdalBands.length == 0)
891
			return;
892

  
893
		selectGdalBands(/*buf.getBandCount()*/getRasterCount());
894

  
895
		int x = (int) Math.round(Math.min(tl.getX(), br.getX()));
896
		int y = (int) Math.round(Math.min(tl.getY(), br.getY()));
897

  
898
		int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
899
		//Si el buffer no se ajusta al extent entonces calculamos en que posici?n comienza a escribirse dentro del buffer
900
		//ya que lo que cae fuera ser?n valores NoData
901
		if(!adjustToExtent){
902
			int[] wh = calcStepBuffer(petExtent, nWidth, nHeight, stpBuffer);
903
			if(x < 0)
904
				x  = 0;
905
			if(y < 0)
906
				y  = 0;
907
			readDataCachedBuffer(buf, bandList, new int[]{x, y, wh[0], wh[1]},
908
					wh[0], wh[1], 0, 0, stpBuffer, status);
909
			return;
910
		}
911

  
912
		readDataCachedBuffer(buf, bandList, new int[]{x, y, nWidth, nHeight},
913
				nWidth, nHeight, 0, 0, stpBuffer, status);
914
	}
915

  
916
	public void readWindow(Buffer buf, BandList bandList, Extent ext, Rectangle adjustedWindow, TaskStatus status) throws GdalException, ProcessInterruptedException {
917
		setView(ext.getULX(), ext.getULY(), ext.getLRX(), ext.getLRY(), buf.getWidth(), buf.getHeight());
918

  
919
		if(gdalBands.length == 0)
920
			return;
921

  
922
		selectGdalBands(getRasterCount());
923

  
924
		int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
925

  
926
		adjustedWindow = getAdjustedWindowInOverviewCoordinates(adjustedWindow);
927

  
928
		readDataCachedBuffer(buf,
929
				bandList,
930
				new int[]{(int)adjustedWindow.getX(), (int)adjustedWindow.getY(), (int)adjustedWindow.getWidth(), (int)adjustedWindow.getHeight()},
931
				buf.getWidth(),
932
				buf.getHeight(),
933
				0, 0, stpBuffer, status);
934
	}
935

  
936
	/**
937
	 * Adjust the request rectangle to the overview size. The requests in Gdal have to be
938
	 * in the overview scale
939
	 * @param adjustedWindow
940
	 * @return
941
	 */
942
	private Rectangle getAdjustedWindowInOverviewCoordinates(Rectangle adjustedWindow) {
943
		int nWidth = (int)(((long)adjustedWindow.getWidth() * overviewWidth) / width);
944
		int nHeight = (int)(((long)adjustedWindow.getHeight() * overviewHeight) / height);
945
		int x = (int)(((long)adjustedWindow.getX() * (long)overviewWidth) / (long)width);
946
		int y = (int) (((long)adjustedWindow.getY() * (long)overviewHeight) / (long)height);
947
		return new Rectangle(x, y, nWidth, nHeight);
948
	}
949

  
950
	/**
951
	 * Lee una ventana de datos con resampleo a partir de coordenadas reales. Este m?todo lee la
952
	 * ventana de una vez cargando los datos de un golpe en el buffer. Las coordenadas se solicitan
953
	 * en coordenadas del mundo real por lo que estas pueden caer en cualquier parte de un pixel.
954
	 * Esto se hace m?s evidente cuando supersampleamos en la petici?n, es decir el buffer de de
955
	 * mayor tama?o que el n?mero de pixels solicitado.
956
	 *
957
	 * Para resolver esto escribiremos con la funci?n readRaster los datos sobre un buffer mayor
958
	 * que el solicitado. Despu?s calcularemos el desplazamiento en pixels dentro de este buffer
959
	 * de mayor tama?o hasta llegar a la coordenada real donde comienza la petici?n real que ha
960
	 * hecho el usuario. Esto es as? porque cuando supersampleamos no queremos los pixeles del
961
	 * raster de disco completos sino que en los bordes del buffer quedan cortados.
962
	 *
963
	 * @param buf Buffer donde se almacenan los datos
964
	 * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
965
	 * @param dWorldTLX Posici?n X superior izquierda en coord reales
966
	 * @param dWorldTLY Posici?n Y superior izquierda en coord reales
967
	 * @param dWorldBRX Posici?n X inferior derecha en coord reales
968
	 * @param dWorldBRY Posici?n Y inferior derecha en coord reales
969
	 * @param nWidth Ancho en pixeles de la petici?n
970
	 * @param nHeight Alto en pixeles de la petici?n
971
	 * @param bufWidth Ancho del buffer
972
	 * @param bufHeight Alto del buffer
973
	 * @throws GdalException
974
	 */
975
	public void readWindow(Buffer buf, BandList bandList, double ulx, double uly, double lrx, double lry,
976
							double nWidth, double nHeight, int bufWidth, int bufHeight, boolean adjustToExtent, TaskStatus status) throws GdalException, ProcessInterruptedException {
977
		Extent petExtent = new ExtentImpl(ulx, uly, lrx, lry);
978
		setView(ulx, uly, lrx, lry, bufWidth, bufHeight);
979
		Point2D ul = worldToRaster(new Point2D.Double(ulx, uly));
980
		Point2D lr = worldToRaster(new Point2D.Double(lrx, lry));
981
		ul.setLocation(ul.getX() < 0 ? 1 : ul.getX(), ul.getY() < 0 ? 1 : ul.getY());
982
		lr.setLocation(lr.getX() < 0 ? 1 : lr.getX(), lr.getY() < 0 ? 1 : lr.getY());
983
		ul.setLocation(ul.getX() - 0.5, ul.getY() - 0.5);
984
		lr.setLocation(lr.getX() - 0.5, lr.getY() - 0.5);
985

  
986
		adjustPoints(ul, lr);
987

  
988
		if(gdalBands.length == 0)
989
			return;
990

  
991
		selectGdalBands(/*buf.getBandCount()*/getRasterCount());
992

  
993
		Rectangle requestWindow = new Rectangle(
994
				(int) Math.min(ul.getX(), lr.getX()),
995
				(int) Math.min(ul.getY(), lr.getY()),
996
				(int)nWidth,
997
				(int)nHeight);
998

  
999
		requestWindow = getAdjustedWindowInOverviewCoordinates(requestWindow);
1000

  
1001
		int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
1002
		//Si el buffer no se ajusta al extent entonces calculamos en que posici?n comienza a escribirse dentro del buffer
1003
		//ya que lo que cae fuera ser?n valores NoData
1004
		if(!adjustToExtent){
1005
			int[] wh = calcStepBuffer(petExtent, bufWidth, bufHeight, stpBuffer);
1006
			if(requestWindow.getX() < 0)
1007
				requestWindow.setLocation(0, (int)requestWindow.getY());
1008
			if(requestWindow.getY() < 0)
1009
				requestWindow.setLocation((int)requestWindow.getX(), 0);
1010
			stpBuffer[0] = (int)((stpBuffer[0] * bufWidth) / requestWindow.getWidth());
1011
			stpBuffer[1] = (int)((stpBuffer[1] * bufHeight) / requestWindow.getHeight());
1012
			stpBuffer[2] = (int)((stpBuffer[2] * bufWidth) / requestWindow.getWidth());
1013
			stpBuffer[3] = (int)((stpBuffer[3] * bufHeight) / requestWindow.getHeight());
1014
			bufWidth = (int)Math.abs(stpBuffer[2] - stpBuffer[0]);
1015
			bufHeight = (int)Math.abs(stpBuffer[3] - stpBuffer[1]);
1016
			readDataCachedBuffer(buf, bandList,
1017
					new int[]{(int)requestWindow.getX(), (int)requestWindow.getY(), wh[0], wh[1]},
1018
						bufWidth, bufHeight, 0, 0, stpBuffer, status);
1019
			return;
1020
		}
1021

  
1022
		if ((requestWindow.getX() + requestWindow.getWidth()) > gdalBands[0].getRasterBandXSize())
1023
			requestWindow.setSize((int)(gdalBands[0].getRasterBandXSize() - requestWindow.getX()), (int)requestWindow.getHeight());
1024

  
1025
		if ((requestWindow.getY() + requestWindow.getHeight()) > gdalBands[0].getRasterBandYSize())
1026
			requestWindow.setSize((int)requestWindow.getWidth(), (int)(gdalBands[0].getRasterBandYSize() - requestWindow.getY()));
1027

  
1028
		readDataCachedBuffer(buf, bandList,
1029
				new int[]{(int)requestWindow.getX(), (int)requestWindow.getY(), (int)requestWindow.getWidth(), (int)requestWindow.getHeight()},
1030
				bufWidth, bufHeight, 0, 0, stpBuffer, status);
1031
	}
1032

  
1033
	private void adjustPoints(Point2D ul, Point2D lr) {
1034
		double a = (ul.getX() - (int)ul.getX());
1035
		double b = (ul.getY() - (int)ul.getY());
1036
		ul.setLocation(	(a > 0.95 || a < 0.05) ? Math.round(ul.getX()) : ul.getX(),
1037
						(b > 0.95 || b < 0.05) ? Math.round(ul.getY()) : ul.getY());
1038
		lr.setLocation(	(a > 0.95 || a < 0.05) ? Math.round(lr.getX()) : lr.getX(),
1039
						(b > 0.95 || b < 0.05) ? Math.round(lr.getY()) : lr.getY());
1040
	}
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff