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