-
Notifications
You must be signed in to change notification settings - Fork 62
/
AsciiGridReader.java
224 lines (202 loc) · 8.21 KB
/
AsciiGridReader.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/**
* H2GIS is a library that brings spatial support to the H2 Database Engine
* <http://www.h2database.com>.
*
* H2GIS is distributed under GPL 3 license. It is produced by CNRS
* <http://www.cnrs.fr/>.
*
* H2GIS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* H2GIS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* H2GIS. If not, see <http://www.gnu.org/licenses/>.
*
* For more information, please consult: <http://www.h2gis.org/>
* or contact directly: info_at_h2gis.org
*/
package org.h2gis.drivers.asciiGrid;
import it.geosolutions.imageio.plugins.arcgrid.AsciiGridsImageReader;
import it.geosolutions.imageio.plugins.arcgrid.raster.AsciiGridRaster;
import it.geosolutions.imageio.plugins.arcgrid.spi.AsciiGridsImageReaderSpi;
import it.geosolutions.imageio.stream.input.FileImageInputStreamExtImpl;
import org.h2.api.GeoRaster;
import org.h2.util.GeoRasterRenderedImage;
import org.h2.util.RasterUtils;
import org.h2gis.drivers.utility.FileUtil;
import org.h2gis.drivers.utility.PRJUtil;
import org.h2gis.h2spatialapi.InputStreamProgressMonitor;
import org.h2gis.h2spatialapi.ProgressVisitor;
import org.h2gis.utilities.JDBCUtilities;
import org.h2gis.utilities.TableLocation;
import javax.imageio.stream.ImageInputStream;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;
/**
* Class to read an Arc/Info ASCII Grid or GRASS ASCII Grid format using
* imageio-ext.
*
* @author Erwan Bocher
*/
public class AsciiGridReader {
private File imageFile;
private String fileNameExtension;
private int srid = 0;
private AsciiGridRaster asciiGridRaster;
private RenderedImage image;
/**
* Use {@link #fetch(Connection, File)}
*/
private AsciiGridReader() {
}
/**
* Create AsciiGridReader using asc or arx file on disk.
*
* @param connection Active connection, not closed by this method
* @param imageFile Ascii file path
* @return Instance of AsciiGridReader
* @throws IOException
* @throws SQLException
*/
public static AsciiGridReader fetch(Connection connection, File imageFile) throws IOException, SQLException {
AsciiGridReader asciiGridReader = new AsciiGridReader();
asciiGridReader.imageFile = imageFile;
String filePath = imageFile.getPath();
final int dotIndex = filePath.lastIndexOf('.');
asciiGridReader.fileNameExtension = filePath.substring(dotIndex + 1).toLowerCase();
if (asciiGridReader.fileNameExtension.equals("asc") || asciiGridReader.fileNameExtension.equals("arx")) {
asciiGridReader.prepareImage();
Map<String, File> matchExt = FileUtil.fetchFileByIgnoreCaseExt(imageFile.getParentFile(), FileUtil
.getBaseName(imageFile), "prj");
asciiGridReader.srid = PRJUtil.getSRID(connection, matchExt.get("prj"));
return asciiGridReader;
} else {
throw new IllegalArgumentException("Supported extensions are asc or arx.");
}
}
/**
* Copy the ascii grid file into a table
*
* @param tableReference
* @param connection
* @param progress
* @throws SQLException
* @throws IOException
*/
public void read(String tableReference, Connection connection, ProgressVisitor progress) throws SQLException, IOException {
final boolean isH2 = JDBCUtilities.isH2DataBase(connection.getMetaData());
readImage(tableReference, isH2, connection, progress);
}
/**
* @return MetaData of loaded ascii grid file
*/
public RasterUtils.RasterMetaData getRasterMetaData() {
double scaleX = asciiGridRaster.getCellSizeX();
// WKB Raster is mirrored on Y plane
double scaleY = - asciiGridRaster.getCellSizeY();
double upperLeftX = asciiGridRaster.getXllCellCoordinate();
// WKB Raster Y is Upper. Ascii Grid Y is Lower (ll for lower left)
double upperLeftY = asciiGridRaster.getYllCellCoordinate() + (-scaleY * (asciiGridRaster.getNRows()));// + scaleY * asciiGridRaster.getNRows();
RasterUtils.RasterBandMetaData rbmd = new RasterUtils.RasterBandMetaData(asciiGridRaster.getNoData(), RasterUtils.PixelType.PT_32BF, true, 0);
return new RasterUtils.RasterMetaData(RasterUtils.LAST_WKB_VERSION, 1, scaleX, scaleY, upperLeftX, upperLeftY, 0, 0, srid,
asciiGridRaster.getNCols(), asciiGridRaster.getNRows(),
new RasterUtils.RasterBandMetaData[]{rbmd});
}
/**
* Import the ascii grid file
*
* @param tableReference
* @param isH2
* @param connection
* @param progressVisitor
* @throws java.sql.SQLException
*/
public void readImage(String tableReference, boolean isH2, Connection connection, ProgressVisitor progressVisitor) throws
SQLException {
TableLocation location = TableLocation.parse(tableReference, isH2);
try {
RasterUtils.RasterMetaData rmd = getRasterMetaData();
StringBuilder sb = new StringBuilder();
sb.append("create table ").append(location.toString()).append("(id serial, the_raster raster) as ");
sb.append("select null, ");
if (isH2) {
sb.append("?;");
} else {
sb.append("ST_SetGeoReference(ST_FromGDALRaster(?,");
sb.append(srid);
sb.append("), ");
sb.append(rmd.ipX).append(",");
sb.append(rmd.ipY).append(",");
sb.append(rmd.scaleX).append(",");
sb.append(rmd.scaleY).append(",");
sb.append(0).append(",");
sb.append(0);
sb.append("));");
}
PreparedStatement stmt = connection.prepareStatement(sb.toString());
try {
GeoRaster geoRaster = GeoRasterRenderedImage
.create(image, rmd);
InputStream wkbStream = geoRaster.asWKBRaster();
try {
stmt.setBinaryStream(1, new InputStreamProgressMonitor(progressVisitor, wkbStream, geoRaster
.getMetaData().getTotalLength()));
stmt.execute();
} finally {
wkbStream.close();
}
} finally {
stmt.close();
}
} catch (FileNotFoundException ex) {
throw new SQLException(ex.getLocalizedMessage(), ex);
} catch (IOException ex) {
throw new SQLException(ex.getLocalizedMessage(), ex);
}
}
/**
* Prepare the image reader to get AsciiGridRaster metadata
*/
private void prepareImage() throws IOException {
AsciiGridsImageReader asciiGridsImageReader = new AsciiGridsImageReader(new AsciiGridsImageReaderSpi());
ImageInputStream fileImageInputStreamExt = new FileImageInputStreamExtImpl(imageFile);
asciiGridsImageReader.setInput(fileImageInputStreamExt);
asciiGridRaster = asciiGridsImageReader.getRasterReader();
image = asciiGridsImageReader.readAsRenderedImage(asciiGridsImageReader.getMinIndex(), asciiGridsImageReader
.getDefaultReadParam());
}
/**
* @return Projection srid
*/
public int getSrid() {
return srid;
}
/**
* Get the AsciiGridRaster to obtain metadata.
*
* @return
*/
public AsciiGridRaster getAsciiGridRaster() {
return asciiGridRaster;
}
/**
* Get an instance of the image
*
* @return
*/
public RenderedImage getImage() {
return image;
}
}