1 |
mojays |
2 |
package skrueger.geotools.io; |
2 |
|
|
|
3 |
|
|
import java.awt.geom.Rectangle2D; |
4 |
|
|
import java.awt.image.BufferedImage; |
5 |
|
|
import java.io.IOException; |
6 |
|
|
import java.net.URL; |
7 |
|
|
|
8 |
|
|
import javax.imageio.IIOException; |
9 |
|
|
import javax.imageio.ImageIO; |
10 |
|
|
|
11 |
|
|
import org.apache.log4j.Logger; |
12 |
|
|
import org.geotools.coverage.grid.GridCoverage2D; |
13 |
|
|
import org.geotools.coverage.grid.GridCoverageFactory; |
14 |
|
|
import org.geotools.factory.Hints; |
15 |
|
|
import org.geotools.gce.geotiff.GeoTiffReader; |
16 |
|
|
import org.geotools.geometry.Envelope2D; |
17 |
|
|
import org.opengis.referencing.crs.CoordinateReferenceSystem; |
18 |
|
|
|
19 |
|
|
import schmitzm.geotools.io.GeoImportUtil; |
20 |
|
|
import schmitzm.io.IOUtil; |
21 |
|
|
|
22 |
|
|
/** |
23 |
|
|
* Erweiterungen von Martin's {@link GeoImportUtil} classe fuer die konsequente Benutzung mit {@link URL}s. |
24 |
|
|
* TODO Diese Klasse sollte vielleicht mit der {@link GeoImportUtil} zusammengefuegt werden. |
25 |
|
|
* |
26 |
|
|
* @author <a href="mailto:[email protected]">Stefan Alfons Krüger</a> |
27 |
|
|
* |
28 |
|
|
*/ |
29 |
|
|
public class GeoImportUtilURL extends GeoImportUtil { |
30 |
|
|
final static private Logger log = Logger.getLogger(GeoImportUtilURL.class); |
31 |
|
|
|
32 |
|
|
/** |
33 |
|
|
* Read a {@link GridCoverage2D} from an image file. .prj and .wld files are usually expected |
34 |
|
|
*/ |
35 |
|
|
public static GridCoverage2D readGridFromImage(URL url) throws IOException { |
36 |
|
|
return readGridFromImage(url, null); |
37 |
|
|
} |
38 |
|
|
|
39 |
|
|
/** |
40 |
|
|
* Read a {@link GridCoverage2D} from an image file. .wld file is usually expected also. The CRS can be given as the crs parameter. null is valid. |
41 |
|
|
* |
42 |
|
|
* @author <a href="mailto:[email protected]">Martin Schmitz</a> (University of Bonn/Germany) |
43 |
|
|
* @author <a href="mailto:[email protected]">Stefan Alfons Krüger</a> |
44 |
|
|
*/ |
45 |
|
|
public static GridCoverage2D readGridFromImage(URL url, |
46 |
|
|
CoordinateReferenceSystem crs) throws IOException { |
47 |
|
|
GridCoverage2D gc = null; |
48 |
|
|
|
49 |
|
|
BufferedImage im = ImageIO.read(url); |
50 |
|
|
if (im == null) |
51 |
|
|
throw new IIOException("No image reader found for this image type!"); |
52 |
|
|
|
53 |
|
|
// World-File einlesen |
54 |
|
|
double[] tfwInfo = null; |
55 |
|
|
|
56 |
|
|
for (WORLD_POSTFIXES pf : WORLD_POSTFIXES.values()){ |
57 |
|
|
if (tfwInfo == null) { |
58 |
|
|
try { |
59 |
|
|
tfwInfo = readWorldFile( IOUtil.changeUrlExt(url, pf.toString() ).openStream()); |
60 |
|
|
} catch (Exception e) { |
61 |
|
|
} |
62 |
|
|
} |
63 |
|
|
} |
64 |
|
|
|
65 |
|
|
if (tfwInfo == null) |
66 |
|
|
throw new IllegalArgumentException( |
67 |
|
|
"No georeferencing information found.\n" |
68 |
|
|
+ "Attach a .wld file to "+url+"please."); |
69 |
|
|
|
70 |
|
|
float w = (float) (im.getWidth() * tfwInfo[0]); // reale Breite = |
71 |
|
|
// RasterSpalten * |
72 |
|
|
// hor. Aufloesung |
73 |
|
|
float h = (float) (im.getHeight() * (-tfwInfo[3])); // reale Hoehe = |
74 |
|
|
// RasterZeilen |
75 |
|
|
// * vert. |
76 |
|
|
// Aufloesung |
77 |
|
|
float x = (float) tfwInfo[4]; // Suedwestliche Ecke! |
78 |
|
|
float y = (float) tfwInfo[5] - h; // Suedwestliche Ecke (im |
79 |
|
|
// tfw-File steht die |
80 |
|
|
// Nordwestliche!) |
81 |
|
|
// ggf. Projektion einlesen |
82 |
|
|
if (crs == null) { |
83 |
|
|
crs = determineProjection( IOUtil.changeUrlExt(url, "prj") ); |
84 |
|
|
} |
85 |
|
|
Envelope2D envelope = new Envelope2D(crs, new Rectangle2D.Float(x, y, |
86 |
|
|
w, h)); |
87 |
|
|
// WICHTIG: Name des Rasters sollte Leer-String sein, da ansonsten |
88 |
|
|
// das |
89 |
|
|
// Coloring des Rasters nicht klappt. |
90 |
|
|
// --> Name der Categories und ColorMapEntries-Labels muss (warum auch immer) mit dem Namen |
91 |
|
|
// des Rasters uebereinstimmen!!! |
92 |
|
|
gc = new GridCoverageFactory().create("", im, envelope); |
93 |
|
|
|
94 |
|
|
return gc; |
95 |
|
|
} |
96 |
|
|
|
97 |
|
|
/** |
98 |
|
|
* Diese Methode importiert ein Raster aus einer Datei im GeoTIFF-Format. |
99 |
|
|
* Zunaechst wird versucht, die Geo-Informationen (Referenz+CRS) aus den |
100 |
|
|
* TIFF-Metadaten zu ermitteln. Ist dies nicht erfolgreich, werden ein |
101 |
|
|
* gleichnamiges World-File (.tfw) und Projection-File (.prj) herangezogen. |
102 |
|
|
* Als Projektion (.prj) ist sowohl ein EPSG-Code "EPSG:...", als auch eine |
103 |
|
|
* WKT-Definition erlaubt. Kann kein CRS ermitteln werden, wird |
104 |
|
|
* {@link #DEFAULT_CRS} als CRS verwendet. |
105 |
|
|
* |
106 |
|
|
* @param geotiffURL |
107 |
|
|
* URL to GeoTIFF-File |
108 |
|
|
* @param crs |
109 |
|
|
* erzwungenes CoordinateReferenceSystem fuer das Raster (kann |
110 |
|
|
* {@code null} sein) |
111 |
|
|
* @throws java.lang.Exception |
112 |
|
|
* bei irgendeinem Fehler |
113 |
|
|
* |
114 |
|
|
* @author <a href="mailto:[email protected]">Martin Schmitz</a> |
115 |
|
|
* (University of Bonn/Germany) |
116 |
|
|
* @author <a href="mailto:[email protected]">Stefan Alfons Krüger</a> |
117 |
|
|
*/ |
118 |
|
|
public static GridCoverage2D readGridFromGeoTiff(URL geotiffURL, |
119 |
|
|
CoordinateReferenceSystem crs) throws Exception { |
120 |
|
|
GridCoverage2D gc = null; |
121 |
|
|
log.debug("Loading GeoTiff from URL = " + geotiffURL + " now."); |
122 |
|
|
|
123 |
|
|
// Versuchen Geo-Information aus Tiff zu lesen |
124 |
|
|
try { |
125 |
|
|
|
126 |
|
|
// Wenn CRS angegeben, dieses durch Hint erzwingen |
127 |
|
|
Hints hints = new Hints(null); |
128 |
|
|
|
129 |
|
|
if (crs != null) |
130 |
|
|
hints.put(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, crs); |
131 |
|
|
// Reader (mit Metadaten) erzeugen |
132 |
|
|
|
133 |
|
|
log.debug("First try to create GeoTiff reader"); |
134 |
|
|
|
135 |
|
|
GeoTiffReader reader = new GeoTiffReader(geotiffURL, hints); |
136 |
|
|
|
137 |
|
|
// Wenn kein Referenzsystem vorhanden, versuchen ein prj-File zu |
138 |
|
|
// verwenden |
139 |
|
|
if (reader.getOriginalEnvelope().getCoordinateReferenceSystem() == null) { |
140 |
|
|
log |
141 |
|
|
.warn("No projection information found in GeoTIFF. Using prj-file..."); |
142 |
|
|
|
143 |
|
|
final CoordinateReferenceSystem determineProjection = determineProjection(IOUtil.changeUrlExt( |
144 |
|
|
geotiffURL, "prj")); |
145 |
|
|
hints.put(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, |
146 |
|
|
determineProjection); |
147 |
|
|
reader = new GeoTiffReader(geotiffURL, hints); |
148 |
|
|
} |
149 |
|
|
gc = (GridCoverage2D) reader.read(null); |
150 |
|
|
} catch (UnsupportedOperationException err) { |
151 |
|
|
log.warn("No GeoTIFF information found. Using simple image + world- and prj-file..."); |
152 |
|
|
gc = readGridFromImage(geotiffURL, crs); //TODO style |
153 |
|
|
} |
154 |
|
|
return gc; |
155 |
|
|
} |
156 |
|
|
|
157 |
|
|
|
158 |
|
|
} |