]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.maps.elevation.server/src/org/simantics/maps/elevation/server/TiffInterface.java
Add SCL interface for District Elevation server
[simantics/district.git] / org.simantics.maps.elevation.server / src / org / simantics / maps / elevation / server / TiffInterface.java
1 package org.simantics.maps.elevation.server;
2
3 import java.awt.geom.Point2D;
4 import java.awt.image.DataBuffer;
5 import java.nio.file.Path;
6
7 import org.geotools.coverage.grid.GridCoverage2D;
8 import org.geotools.gce.geotiff.GeoTiffReader;
9 import org.geotools.geometry.Envelope2D;
10 import org.geotools.geometry.TransformedDirectPosition;
11 import org.opengis.geometry.DirectPosition;
12 import org.opengis.geometry.Envelope;
13 import org.opengis.referencing.crs.CoordinateReferenceSystem;
14 import org.opengis.referencing.operation.TransformException;
15 import org.simantics.maps.elevation.server.prefs.MapsElevationServerPreferences;
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
18
19 public class TiffInterface {
20
21     private static final Logger LOGGER = LoggerFactory.getLogger(TiffInterface.class);
22
23     private final Path tifPath;
24     private GridCoverage2D coverage;
25     private CoordinateReferenceSystem crs;
26
27     private boolean init = false;
28
29     public TiffInterface(Path tifPath) {
30         this.tifPath = tifPath;
31         loadMetadata();
32     }
33
34     private void loadMetadata() {
35         GeoTiffReader reader = null;
36         try {
37             reader = new GeoTiffReader(this.tifPath.toFile());
38             this.coverage = reader.read(null);
39             this.crs = coverage.getCoordinateReferenceSystem();
40             this.init = true;
41         } catch (Exception e) {
42             LOGGER.error("Could not load {}", tifPath, e);
43         } finally {
44             if (reader != null) {
45                 reader.dispose();
46             }
47         }
48     }
49
50     public boolean contains(DirectPosition pos) {
51         ensureInit();
52         Envelope2D e = coverage.getEnvelope2D();
53         try {
54             TransformedDirectPosition tdp = new TransformedDirectPosition(pos.getCoordinateReferenceSystem(), crs, null);
55             tdp.transform(pos);
56             
57             Point2D p = tdp.toPoint2D();
58             
59             boolean contains = e.contains(p);
60             return contains;
61         } catch (Exception ex) {
62             ex.printStackTrace();
63             return false;
64         }
65     }
66     
67     public Number lookup(DirectPosition pos) {
68         ensureInit();
69         Object r = coverage.evaluate(pos);
70         final int dataType = coverage.getRenderedImage().getSampleModel().getDataType();
71         int pipeDepthUnderGround = MapsElevationServerPreferences.pipeDepthUnderGround();
72         switch (dataType) {
73             case DataBuffer.TYPE_BYTE: {
74                 // TODO: if the result is byte how does one subtract the pipeDepth form the value?
75                 // Might not be even relevant with this use case 
76                 return new Byte(((byte[]) r)[0]);
77             }
78             case DataBuffer.TYPE_SHORT:  // Fall through
79             case DataBuffer.TYPE_USHORT: // Fall through
80             case DataBuffer.TYPE_INT: {
81                 int val = ((int[]) r)[0] - pipeDepthUnderGround;
82                 return new Integer(val);
83             }
84             case DataBuffer.TYPE_FLOAT: {
85                 float val = ((float[]) r)[0] - pipeDepthUnderGround;
86                 return new Float(val);
87             }
88             case DataBuffer.TYPE_DOUBLE: {
89                 double val = ((double[]) r)[0] - pipeDepthUnderGround;
90                 return new Double(val);
91             }
92             default: return null;
93         }
94     }
95
96     private void ensureInit() {
97         if (!init) {
98             throw new IllegalStateException("Interface is not initialized for " + this.tifPath);
99         }
100     }
101
102     public void close() {
103         coverage.dispose(true);
104     }
105
106     public Envelope2D getCornerCoords() {
107         return coverage.getEnvelope2D();
108     }
109
110     public CoordinateReferenceSystem getCRS() {
111         return crs;
112     }
113 }