Revision: 5008
http://sourceforge.net/p/jump-pilot/code/5008
Author: michaudm
Date: 2016-09-04 17:01:18 +0000 (Sun, 04 Sep 2016)
Log Message:
-----------
ProjUtils2, a refactoring of ProjUtil (work on progress)
Added Paths:
-----------
core/trunk/src/org/openjump/core/ccordsys/utils/ProjUtils2.java
Added: core/trunk/src/org/openjump/core/ccordsys/utils/ProjUtils2.java
===================================================================
--- core/trunk/src/org/openjump/core/ccordsys/utils/ProjUtils2.java
(rev 0)
+++ core/trunk/src/org/openjump/core/ccordsys/utils/ProjUtils2.java
2016-09-04 17:01:18 UTC (rev 5008)
@@ -0,0 +1,882 @@
+package org.openjump.core.ccordsys.utils;
+
+import com.sun.media.jai.codec.FileSeekableStream;
+import com.sun.media.jai.codec.TIFFDirectory;
+import com.sun.media.jai.codec.TIFFField;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jump.I18N;
+import com.vividsolutions.jump.feature.Feature;
+import com.vividsolutions.jump.feature.FeatureCollection;
+import com.vividsolutions.jump.io.datasource.DataSourceQuery;
+import com.vividsolutions.jump.util.FileUtil;
+import com.vividsolutions.jump.workbench.Logger;
+import com.vividsolutions.jump.workbench.imagery.ImageryLayerDataset;
+import com.vividsolutions.jump.workbench.imagery.ReferencedImageStyle;
+import com.vividsolutions.jump.workbench.model.Layer;
+import
com.vividsolutions.jump.workbench.ui.plugin.datastore.DataStoreDataSource;
+import org.apache.commons.imaging.formats.tiff.TiffField;
+import org.apache.commons.imaging.formats.tiff.TiffImageMetadata;
+import org.apache.commons.imaging.formats.tiff.TiffImageParser;
+import org.apache.commons.io.FilenameUtils;
+import org.openjump.core.ccordsys.srid.SRIDStyle;
+import org.openjump.core.rasterimage.GeoTiffConstants;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.awt.Point;
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Scanner;
+
+/**
+ * Giuseppe Aruta [23_3_2016] This class is used to recognize file
+ * projection. There are different methods A) a method to decode projection
+ * information from GeoTIFF metadata. B) a method to decode projection info
+ * from auxiliary files (.proj and .aux.xml).
+ * http://landsathandbook.gsfc.nasa.gov/pdfs/geotiff_spec.pdf
+ * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/GeoTiff.html
+ * http://www.remotesensing.org/geotiff/spec/geotiff6.html
+ *
+ * the following datasets have been used to test this library: QGIS
+ * (http://qgis.org/downloads/data/) OSGEO data samples (
+ * http://download.osgeo.org/geotiff/samples/)
+ */
+public class ProjUtils2 {
+
+ private static final String PROJECTION_UNSPECIFIED = I18N
+
.get("org.openjump.core.ui.plugin.raster.RasterImageLayerPropertiesPlugIn.unknown_projection");
+ private static final String USER_DEFINED = I18N
+
.get("org.openjump.core.ui.plugin.layer.LayerPropertiesPlugIn.User_defined");
+ private static final String NOT_RECOGNIZED = I18N
+
.get("org.openjump.core.ui.plugin.layer.LayerPropertiesPlugIn.Not_recognized");
+
+
+ /**
+ * Test method - to get GeoTiff envelope in case of no srid def.
+ *
+ * @param fileSourcePath
+ * @return envelope
+ */
+ public static Envelope GeoTiffEnvelope(String fileSourcePath)
+ throws Exception {
+ BufferedImage image = ImageIO.read(new File(fileSourcePath));
+ Point imageDimensions = new Point(image.getWidth(), image.getHeight());
+ Envelope env = null;
+ Coordinate tiePoint = null, pixelOffset = null, pixelScale = null;
+ FileSeekableStream fileSeekableStream = new FileSeekableStream(
+ fileSourcePath);
+ TIFFDirectory tiffDirectory = new TIFFDirectory(fileSeekableStream, 0);
+
+ TIFFField[] availTags = tiffDirectory.getFields();
+
+ for (TIFFField availTag : availTags) {
+ if (availTag.getTag() == GeoTiffConstants.ModelTiepointTag) {
+ double[] doubles = availTag.getAsDoubles();
+ if (doubles.length != 6) {
+ throw new Exception(
+ "unsupported value for ModelTiepointTag ("
+ + GeoTiffConstants.ModelTiepointTag + ")");
+ }
+ pixelOffset = new Coordinate(doubles[0], doubles[1]);
+ tiePoint = new Coordinate(doubles[3], doubles[4]);
+ } else if (availTag.getTag() ==
GeoTiffConstants.ModelPixelScaleTag) {
+ // Karteneinheiten pro pixel x bzw. y
+ double[] doubles = availTag.getAsDoubles();
+ pixelScale = new Coordinate(doubles[0], doubles[1]);
+ } else {}
+ }
+
+ fileSeekableStream.close();
+
+ if (tiePoint != null && pixelScale != null) {
+ Coordinate upperLeft;
+ Coordinate lowerRight;
+
+ if (pixelOffset == null) {
+ upperLeft = tiePoint;
+ } else {
+ upperLeft = new Coordinate(tiePoint.x
+ - (pixelOffset.x * pixelScale.x), tiePoint.y
+ - (pixelOffset.y * pixelScale.y));
+ }
+
+ lowerRight = new Coordinate(upperLeft.x
+ + (imageDimensions.x * pixelScale.x), upperLeft.y
+ - (imageDimensions.y * pixelScale.y));
+
+ env = new Envelope(upperLeft, lowerRight);
+ }
+ return env;
+ }
+
+ /**
+ * Test method to read the entire GeoKeyDirectoryTag, only used to study
+ * GeoKeyDirectoryTag structure
+ *
+ * @param fileSourcePath
+ * @return GeoKeyDirectoryTag
+ * @throws IOException
+ * @throws URISyntaxException
+ */
+ @SuppressWarnings("static-access")
+ public static String readGeoTiffGeoKeyDirectoryTag(String fileSourcePath)
+ throws IOException, URISyntaxException {
+ String prjname = "";
+ File tiffFile = new File(fileSourcePath);
+ try {
+ TiffImageParser parser = new TiffImageParser();
+ TiffImageMetadata metadata = (TiffImageMetadata) parser
+ .getMetadata(tiffFile);
+ if (metadata != null) {
+ java.util.List<TiffField> tiffFields = metadata.getAllFields();
+ GeoTiffConstants constants = new GeoTiffConstants();
+ for (TiffField tiffField : tiffFields) {
+ if (tiffField.getTag() == constants.GeoKeyDirectoryTag) {
+ prjname = tiffField.getValueDescription();
+ }
+ }
+ } else {
+ prjname = "GeoKeyDirectoryTagis empty";
+ }
+ } catch (Exception ex) {
+ prjname = PROJECTION_UNSPECIFIED;
+ }
+ return prjname;
+ }
+
+ /**
+ * - Read SRS from GeoTIFF tag - This method gets projection srid code and
+ * projection info from a geotiff file. It first scans GeoKeyDirectoryTag
to
+ * get either geographic/geocentric (2048 - GeographicTypeGeoKey),
projected
+ * (3072 - ProjectedCSTypeGeoKey) or vertical (4096 - VerticalCSTypeGeoKey)
+ * info. If no key ID is identified, it scans for GeoAsciiParamsTag
+ * projection definition. Last choice, it search for an auxiliary file
+ *
+ * @param fileSourcePath
+ * . eg. "c\documents\folder\image.tif"
+ * @return the projection srid as a string. eg "32632"
+ * @throws IOException
+ * @throws URISyntaxException
+ */
+ @SuppressWarnings("static-access")
+ public static String readSRSFromGeoTiffFile(String fileSourcePath)
+ throws IOException, URISyntaxException {
+ String geoDirTag = "";
+ String geoDirTag2 = "";
+ String prjname = "";
+ File tiffFile = new File(fileSourcePath);
+ try {
+ TiffImageParser parser = new TiffImageParser();
+ TiffImageMetadata metadata = (TiffImageMetadata) parser
+ .getMetadata(tiffFile);
+ if (metadata != null) {
+ java.util.List<TiffField> tiffFields = metadata.getAllFields();
+ GeoTiffConstants constants = new GeoTiffConstants();
+ for (TiffField tiffField : tiffFields) {
+ if (tiffField.getTag() == constants.GeoKeyDirectoryTag) {
+ geoDirTag = tiffField.getValueDescription();
+ }
+ if (tiffField.getTag() == constants.GeoAsciiParamsTag) {
+ geoDirTag2 = tiffField.getStringValue().replaceAll(
+ "[\\t\\n\\r\\_\\|]", " ");
+ }
+ if (tiffField.getTag() == constants.ModelTiepointTag) {
+ }
+ }
+ prjname = getPrjNameFromGeoDirTags(fileSourcePath, geoDirTag,
geoDirTag2);
+ }
+ } catch (Exception ex) {
+ prjname = PROJECTION_UNSPECIFIED;
+ }
+ return prjname;
+ }
+
+ private static String getPrjNameFromGeoDirTags(String fileSourcePath,
String geoDirTag, String geoDirTag2)
+ throws IOException, URISyntaxException {
+ if (geoDirTag.contains("3072"))
+ return getPrjNameFromGeoDirTags("3072", geoDirTag, geoDirTag2,
"32767");
+ else if (geoDirTag.contains("4096"))
+ return getPrjNameFromGeoDirTags("4096", geoDirTag, geoDirTag2,
"32767");
+ else if (geoDirTag.contains("2048"))
+ return getPrjNameFromGeoDirTags("2048", geoDirTag, geoDirTag2,
"32767");
+ else if (geoDirTag2.isEmpty())
+ return readSRSFromAuxiliaryFile(fileSourcePath);
+ else
+ return "SRID: " + USER_DEFINED + " - " + geoDirTag2;
+ }
+
+ private static String getPrjNameFromGeoDirTags(String key, String
geoDirTag, String geoDirTag2, String exclude)
+ throws IOException, URISyntaxException {
+ int start = geoDirTag.indexOf(key);
+ String ID = geoDirTag.substring(start);
+ String[] parts = ID.split(",");
+ if (parts.length > 3 && !parts[3].contains(exclude)) {
+ return getSRSFromWkt(parts[3].replaceAll(" ", ""));
+ } else {
+ return "SRID: " + USER_DEFINED + " - " + geoDirTag2;
+ }
+ }
+
+ /**
+ * - Read SRS from auxiliary file - Method to get a SRS (SRID code + SRID
+ * definition) scanning the aux projection file (AUX.XML or PRJ file) for a
+ * search string (SRID code or SRID definition). It scans into the registry
+ * file (srid.txt) to find a correspondence between the search string and
+ * lines of the srid.txt. If the source string corresponds as substring to
a
+ * line, it returns the complete line as string. For instance, search
+ * strings like "NAD83 UTM zone 10N" or "26910" both return
+ * "SRID:26910 - NAD83 UTM zone 10N".
+ *
+ * @param fileSourcePath auxiliary file path
+ * @return SRID and Projection definition
+ * @throws URISyntaxException
+ * @throws IOException
+ */
+
+ public static String readSRSFromAuxiliaryFile(String fileSourcePath)
+ throws URISyntaxException, IOException {
+
+ // --- it reads an auxiliary file and decode a possible proj
+ // --- definition to a simple string. Ex. "WGS 84 UTM Zone 32"
+ int pos = fileSourcePath.lastIndexOf('.');
+ // .shp, .dxf, .asc, .flt files
+ String projectSourceFilePrj = fileSourcePath.substring(0, pos) +
".prj";
+ // image files
+ String projectSourceRFilePrj = fileSourcePath + ".prj";
+ String projectSourceRFileAux = fileSourcePath + ".aux.xml";
+
+ String type = FilenameUtils.getExtension(fileSourcePath).toUpperCase();
+
+ String textProj = "";
+ if (type.matches("SHP|DXF|ASC|FLT|ADF|GRD|BIL")) {
+ if (new File(projectSourceFilePrj).exists()) {
+ Scanner scanner = new Scanner(new File(projectSourceFilePrj));
+ textProj = scanner.nextLine();
+ scanner.close();
+ }
+ } else if (new File(projectSourceRFileAux).exists()) {
+ Scanner scanner = new Scanner(new File(projectSourceRFileAux));
+ textProj = scanner.useDelimiter("\\A").next();
+ if (!textProj.contains("<WKT>") && !textProj.contains("<SRS>") &&
+ new File(projectSourceRFilePrj).exists()) {
+ Scanner scanner2 = new Scanner(new
File(projectSourceRFilePrj));
+ textProj = scanner2.nextLine();
+ scanner2.close();
+ }
+ } else if (new File(projectSourceRFilePrj).exists()) {
+ Scanner scanner = new Scanner(new File(projectSourceRFilePrj));
+ textProj = scanner.nextLine();
+ scanner.close();
+ }
+
+ String prjname = decodeProjDescription(textProj);
+
+ // --- it extracts from proj register file all the info related
+ // --- to the previous string (SRSDef). Ex.
+ // --- "EPSG:32632 - WGS 84 UTM zone 32"
+ if (!prjname.isEmpty()) {
+ String[] srsAndUnit =
SridLookupTable.getSrsAndUnitFromName(prjname);
+ if (srsAndUnit == null) return PROJECTION_UNSPECIFIED;
+ else return getPrefixedCode(srsAndUnit[0]) + " - " + srsAndUnit[1];
+ } else {
+ return PROJECTION_UNSPECIFIED;
+ }
+ }
+
+
+ private static String getPrefixedCode(String code) {
+ // 1) WKID <32768 or >5999999
+ // will result in an AUTHORITY name of "EPSG".
+ // 2) A WKID in range between 33000 and 199999
+ // will result in an AUTHORITY name of "ESRI".
+ //
(http://help.arcgis.com/en/arcgisserver/10.0/apis/soap/whnjs.htm#SOAP_Geometry_FindSRByWKID.htm)
+
+ String Registry = "SRID"; // Used if code is negative or non-numeric
+ if (code.matches("\\d+")) {
+ int srid = Integer.parseInt(code);
+ if (srid < 32768 || srid > 5999999) {
+ Registry = "EPSG";
+ } else if (srid > 32999 && srid < 200000) {
+ Registry = "ESRI";
+ }
+ }
+ return Registry + ":" + code;
+ }
+
+ /**
+ * Method to show an OGC WKT string in a more readable style
+ *
+ * @param WKT OGC WKT from auxiliary proj file
+ * @return Readable string
+ */
+ public static String readableFormatWKTCode(String WKT) {
+ String HROGC = "";
+ // String add_spaces = String.format("%" + count_add++ + "s", "");
+ HROGC = WKT.replace(",GEOGCS", ",<br>" + "GEOCS")
+ .replace(",DATUM", ",<br>" + "DATUM")
+ .replace(",SPHEROID", ",<br>" + "SPEROID")
+ .replace("],", "],<br>");
+ return HROGC;
+
+ }
+
+ /**
+ * Decode a OGC string to get a unique SRS string definition. This method
is
+ * able to understand some WKT common aliases, like OGC WKT and ESRI
WKTCode.
+ * For instance: "WGS 84 / UTM zone 32", "WGS 1984 UTM zone 32" and
+ * "WGS_84_UTM_Zone_32" are converted to the same string
+ * "WGS 84 UTM zone 32"
+ *
+ * @param textProj
+ * <String> - OGC/ESRI/other WKT code
+ * @return <String> - SRS definition
+ */
+ private static String decodeProjDescription(String textProj) {
+ String prjname = "";
+ try {
+ // Workaround if aux.xml has been download from web.
+ // convert HTML quotes ["] to ["]
+ textProj = textProj.replaceAll(""", "\"");
+ int start = textProj.indexOf("[\"");
+ int end = textProj.indexOf("\",", start);
+ prjname = textProj.substring(start + 2, end);
+ // The following set of replacements allows to "harmonize" OGC,
ESRI
+ // and
+ // few other WKT projection definitions
+ prjname = prjname.replaceAll("_", " ").replace(" / ", " ")
+ .replaceAll("\\bft US\\b", "(ftUS)")
+ .replaceAll("\\bftUS\\b", "(ftUS)")
+ .replaceAll("\\bft\\b", "(ft)").replaceAll("feet", "ft")
+ .replaceAll("WGS 1984", "WGS 84")
+ .replaceAll("NAD 1983 UTM", "NAD83 UTM")
+ .replaceAll("HARN", "(HARN)")
+ .replaceAll("\\bCSRS98\\b", "(CSRS98)")
+ .replaceAll("CSRS", "(CSRS)")
+ .replaceAll("\\bNSRS2007\\b", "(NSRS2007)")
+ .replaceAll("\\bNAD27_76\\b", "NAD27(76)")
+ .replaceAll("\\bCGQ77\\b", " (CGQ77)")
+ .replaceAll("\\bED77\\b", "(ED77)")
+ .replaceAll("\\b1942 83\\b", "1942(83)")
+ .replaceAll("\\b1942 58\\b", "1942(58)")
+ .replaceAll("\\bSegara Jakarta\\b", "Segara (Jakarta)")
+ .replaceAll("\\bRome\\b", "(Rome)")
+ .replaceAll("\\bParis\\b", "(Paris)")
+ .replaceAll("\\bFerro\\b", "(Ferro)");
+
+ } catch (Exception ex) {
+ // If there is other info than a WKT definition in the aux file
+ prjname = NOT_RECOGNIZED;
+ }
+ return prjname;
+ }
+
+ /**
+ * returns OGC WKT string located between projection tags (<WKT> or <SRS>)
+ * in a projection auxiliary file (AUX.XML)
+ *
+ * @param textProj
+ * string
+ * @return OGC WKT string
+ */
+ private static String getWktProjDefinition(String textProj) {
+ String prjname = "";
+ try {
+ if (textProj.contains("<WKT>")) {
+ int start = textProj.indexOf("<WKT>");
+ int end = textProj.indexOf("</WKT>", start);
+ prjname = textProj.substring(start, end);
+ } else if (textProj.contains("<SRS>")) {
+ int start = textProj.indexOf("<SRS>");
+ int end = textProj.indexOf("</SRS>", start);
+ prjname = textProj.substring(start, end);
+ } else
+ prjname = textProj;
+ } catch (Exception ex) {
+ prjname = textProj;
+ }
+ return prjname;
+ }
+
+ /**
+ * It returns the path name of the auxiliary file (AUX.XML or PRJ file)
+ * where a projection code is located
+ *
+ * @param fileSourcePath auxiliary file path
+ * @return path name of projection auxiliary file
+ * @throws IOException
+ */
+ public static String getAuxiliaryProjFilePath(String fileSourcePath)
+ throws IOException {
+
+ String filename = "";
+ Scanner scanner;
+ int pos = fileSourcePath.lastIndexOf('.');
+ String projectSourceFilePrj = fileSourcePath.substring(0, pos) +
".prj";
+ String projectSourceRFileAux = fileSourcePath + ".aux.xml";
+ String projectSourceRFilePrj = fileSourcePath + ".prj";
+ String type = FilenameUtils.getExtension(fileSourcePath).toUpperCase();
+
+ if (type.matches("SHP|DXF|ASC|FLT|ADF|GRD|BIL")) {
+ if (new File(projectSourceFilePrj).exists()) {
+ filename = projectSourceFilePrj;
+ }
+ } else if (new File(projectSourceRFileAux).exists()) {
+ scanner = new Scanner(new File(projectSourceRFileAux));
+ String textProj = scanner.useDelimiter("\\A").next();
+ scanner.close();
+ if (textProj.contains("<WKT>") || textProj.contains("<SRS>")) {
+ filename = projectSourceRFileAux;
+ } else if (new File(projectSourceRFilePrj).exists()) {
+ filename = projectSourceRFilePrj;
+ }
+ } else if (new File(projectSourceRFilePrj).exists()) {
+ filename = projectSourceRFilePrj;
+ }
+ return filename;
+ }
+
+ /**
+ * Method to get a SRS (SRID code + SRID definition) using a search string.
+ * It scans into the srid list (srid.txt) to find a correspondence between
+ * the search string and lines of the srid.txt. If the source string
+ * corresponds as substring to a line, it returns the complete line as
+ * string.The code is biunivocal: it can use as searchQuerry either SRID
+ * code ("26910" or Project definition ("NAD83 UTM zone 10N"). For
instance,
+ * search queries like "NAD83 UTM zone 10N" or "26910" both return
+ * "SRID:26910 - NAD83 UTM zone 10N".
+ *
+ * @param searchQuery search quaery
+ * @return SRID and Projection definition
+ * @throws URISyntaxException
+ * @throws IOException
+ */
+
+ public static String getSRSFromWkt(String searchQuery)
+ throws URISyntaxException, IOException {
+
+ String[] srsAndUnit =
SridLookupTable.getSrsAndUnitFromCodeOrName(searchQuery);
+ if (srsAndUnit == null) return PROJECTION_UNSPECIFIED;
+ else return getPrefixedCode(srsAndUnit[0]) + " - " + srsAndUnit[1];
+ }
+
+ /**
+ * Check if selected file is a GeoTIFF. This java code comes from Deegree
+ * project org.deegree.tools.raster.MergeRaster
+ * (https://github.com/camptocamp
+ * /secureOWS/blob/master/owsproxyserver/src/org
+ * /deegree/tools/raster/MergeRaster.java)
+ *
+ * @param fileSourcePath
+ * @return true
+ * @throws IOException
+ */
+
+ public static boolean isGeoTIFF(String fileSourcePath) throws IOException {
+ FileSeekableStream fileSeekableStream = new FileSeekableStream(
+ fileSourcePath);
+ TIFFDirectory tifDir = new TIFFDirectory(fileSeekableStream, 0);
+ // definition of a geotiff
+ if (tifDir.getField(GeoTiffConstants.ModelPixelScaleTag) == null
+ && tifDir.getField(GeoTiffConstants.ModelTransformationTag) ==
null
+ && tifDir.getField(GeoTiffConstants.ModelTiepointTag) == null
+ && tifDir.getField(GeoTiffConstants.GeoKeyDirectoryTag) == null
+ && tifDir.getField(GeoTiffConstants.GeoDoubleParamsTag) == null
+ && tifDir.getField(GeoTiffConstants.GeoAsciiParamsTag) ==
null) {
+ return false;
+ } else {
+ // is a geotiff and possibly might need to be treated as raw data
+ TIFFField bitsPerSample = tifDir.getField(258);
+ if (bitsPerSample != null) {
+ int samples = bitsPerSample.getAsInt(0);
+ if (samples == 16)
+ new Integer(16);
+ }
+ // check the EPSG number
+ TIFFField ff =
tifDir.getField(GeoTiffConstants.GeoKeyDirectoryTag);
+ if (ff == null) {
+ return false;
+ }
+ char[] ch = ff.getAsChars();
+ // resulting HashMap, containing the key and the array of values
+ HashMap<Integer, int[]> geoKeyDirectoryTag = new HashMap<Integer,
int[]>(
+ ff.getCount() / 4);
+ // array of values. size is 4-1.
+ int keydirversion, keyrevision, minorrevision, numberofkeys = -99;
+ for (int i = 0; i < ch.length; i = i + 4) {
+ int[] keys = new int[3];
+ keydirversion = ch[i];
+ keyrevision = ch[i + 1];
+ minorrevision = ch[i + 2];
+ numberofkeys = ch[i + 3];
+ keys[0] = keyrevision;
+ keys[1] = minorrevision;
+ keys[2] = numberofkeys;
+ geoKeyDirectoryTag.put(new Integer(keydirversion), keys);
+ }
+ int[] content = new int[3];
+ if (geoKeyDirectoryTag.containsKey(new Integer(
+ GeoTiffConstants.ModelTiepointTag))) {
+ content = (int[]) geoKeyDirectoryTag.get(new Integer(
+ GeoTiffConstants.ModelTiepointTag));
+ // TIFFTagLocation
+ if (content[0] == 0) {
+ // return Value_Offset key = content[2];
+ } else {
+ // TODO other TIFFTagLocation that GeoKeyDirectoryTag
+ }
+ } else {
+ Logger.warn("Can't check EPSG codes, make sure it is ok!");
+ }
+ return true;
+ }
+ }
+
+ /**
+ * - Read SRID from GeoTIFF tag - This method gets projection srid code
from
+ * a geotiff file. It first scans GeoKeyDirectoryTag to get either
+ * geographic/geocentric (2048 - GeographicTypeGeoKey), projected (3072 -
+ * ProjectedCSTypeGeoKey) or vertical (4096 - VerticalCSTypeGeoKey) info.
If
+ * no key ID is identified, it scans for GeoAsciiParamsTag projection
+ * definition. Last choice, it search for an auxiliary file
+ *
+ * @param fileSourcePath
+ * . eg. "c\documents\folder\image.tif"
+ * @return <String> projection srid code as string. eg "32632"
+ * @throws IOException
+ * @throws URISyntaxException
+ */
+ @SuppressWarnings("static-access")
+ public static String readSRIDFromGeoTiffFile(String fileSourcePath)
+ throws IOException, URISyntaxException {
+ String GeoDirTag = "";
+ String GeoDirTag2 = "";
+ String prjname = "";
+ File tiffFile = new File(fileSourcePath);
+ try {
+ TiffImageParser parser = new TiffImageParser();
+ TiffImageMetadata metadata = (TiffImageMetadata) parser
+ .getMetadata(tiffFile);
+ if (metadata != null) {
+ java.util.List<TiffField> tiffFields = metadata.getAllFields();
+ GeoTiffConstants constants = new GeoTiffConstants();
+
+ String ID = "";
+ int start;
+ for (TiffField tiffField : tiffFields) {
+ if (tiffField.getTag() == constants.GeoKeyDirectoryTag) {
+ GeoDirTag = tiffField.getValueDescription();
+ }
+ if (tiffField.getTag() == constants.GeoAsciiParamsTag) {
+ GeoDirTag2 = tiffField.getStringValue().replaceAll(
+ "[\\t\\n\\r\\_\\|]", " ");
+ }
+ if (tiffField.getTag() == constants.ModelTiepointTag) {
+ }
+ }
+ if (GeoDirTag.contains("3072")) {
+ start = GeoDirTag.indexOf("3072");
+ ID = GeoDirTag.substring(start);
+ String[] parts = ID.split(",");
+ String part1 = parts[3];
+ if (!part1.contains("32767")) {
+ prjname = part1.replaceAll(" ", "");
+ } else {
+ prjname = "0";
+ }
+ } else if (!GeoDirTag.contains("3072")
+ & GeoDirTag.contains("4096")) {
+ start = GeoDirTag.indexOf("4096");
+ ID = GeoDirTag.substring(start);
+ String[] parts = ID.split(",");
+ String part1 = parts[3];
+ if (!part1.contains("32767")) {
+ prjname = part1.replaceAll(" ", "");
+ } else {
+ prjname = "0";
+ }
+ } else if (!GeoDirTag.contains("3072")
+ & !GeoDirTag.contains("4096")
+ & GeoDirTag.contains("2048")) {
+ start = GeoDirTag.indexOf("2048");
+ ID = GeoDirTag.substring(start);
+ String[] parts = ID.split(",");
+ String part1 = parts[3];
+ if (!part1.contains("32767")) {
+ prjname = part1.replaceAll(" ", "");
+ } else {
+ prjname = "0";
+ }
+
+ } else if (!GeoDirTag.contains("4096")
+ & !GeoDirTag.contains("3072")
+ & !GeoDirTag.contains("2048")) {
+ if (!GeoDirTag2.isEmpty())
+ // It gets "0" which is a non defined projection
+ prjname = "0";
+ else
+ prjname = readSRIDFromAuxiliaryFile(fileSourcePath);
+
+ }
+ }
+
+ } catch (Exception ex) {
+ prjname = PROJECTION_UNSPECIFIED;
+ }
+ return prjname;
+ }
+
+ /**
+ * - Read SRID from auxiliary file - Method to get SRID code from auxiliary
+ * projection file (AUX.XML or PRJ file). It scans into the registry file
+ * (srid.txt) to find a correspondence between the search string (auxiliary
+ * layer) and lines of the srid.txt. If the source string corresponds as
+ * substring to a line, it returns its SRID. For instance, search strings
+ * like "NAD83 UTM zone 10N" returns "26910".
+ *
+ * @param fileSourcePath auxiliary file path
+ * @return SRID as String
+ * @throws URISyntaxException
+ * @throws IOException
+ */
+
+ public static String readSRIDFromAuxiliaryFile(String fileSourcePath)
+ throws URISyntaxException, IOException {
+
+ // --- it reads an auxiliary file and decode a possible proj
+ // --- definition to a simple string. Ex. "WGS 84 UTM Zone 32"
+ int pos = fileSourcePath.lastIndexOf('.');
+ // .shp, .dxf, .asc, .flt files
+ String projectSourceFilePrj = fileSourcePath.substring(0, pos) +
".prj";
+ // image files
+ String projectSourceRFilePrj = fileSourcePath + ".prj";
+ String projectSourceRFileAux = fileSourcePath + ".aux.xml";
+
+ String type = FilenameUtils.getExtension(fileSourcePath).toUpperCase();
+
+ String textProj = "";
+ if (type.matches("SHP|DXF|ASC|FLT|ADF|GRD|BIL")) {
+ if (new File(projectSourceFilePrj).exists()) {
+ Scanner scanner = new Scanner(new File(projectSourceFilePrj));
+ textProj = scanner.nextLine();
+ scanner.close();
+ }
+ } else if (new File(projectSourceRFileAux).exists()) {
+ Scanner scanner = new Scanner(new File(projectSourceRFileAux));
+ textProj = scanner.useDelimiter("\\A").next();
+ if (!textProj.contains("<WKT>") && !textProj.contains("<SRS>") &&
+ new File(projectSourceRFilePrj).exists()) {
+ Scanner scanner2 = new Scanner(new
File(projectSourceRFilePrj));
+ textProj = scanner2.nextLine();
+ scanner2.close();
+ }
+ } else if (new File(projectSourceRFilePrj).exists()) {
+ Scanner scanner = new Scanner(new File(projectSourceRFilePrj));
+ textProj = scanner.nextLine();
+ scanner.close();
+ }
+
+ String prjname = decodeProjDescription(textProj);
+
+ // --- it extracts from proj register file all the info related
+ // --- to the previous string (SRSDef). Ex.
+ // --- "EPSG:32632 - WGS 84 UTM zone 32"
+ if (!prjname.isEmpty()) {
+ String[] srsAndUnit =
SridLookupTable.getSrsAndUnitFromName(prjname);
+ if (srsAndUnit == null) return PROJECTION_UNSPECIFIED;
+ else return getPrefixedCode(srsAndUnit[0]) + " - " + srsAndUnit[1];
+ } else {
+ return PROJECTION_UNSPECIFIED;
+ }
+ }
+
+ /**
+ * Method to get SRID from a layer from Style or from auxiliary file. First
+ * scans SRIDStyle, than auxiliary file or GeoTIFF tag. If SRID does not
+ * exist, it returns 0.
+ *
+ * @param layer
+ * @return SRID
+ * @throws Exception
+ */
+ public static int SRID(Layer layer) throws Exception {
+ String fileSourcePath = "";
+ int projection = 0;
+ String extension = "";
+ SRIDStyle sridStyle = (SRIDStyle) layer.getStyle(SRIDStyle.class);
+ final int oldSRID = sridStyle.getSRID();
+ // if (layers.length == 1) {
+ // First we check if a SRID (Spatial Reference Identifier)
+ // code has been recorded by OJ (eg. Spatialite)
+ // it excludes 0 from the range of search as it can
+ // be consider as "no SRID"
+ if (oldSRID > 0) {
+ projection = oldSRID;
+ // If no SRID has been identified. it checks
+ // projection info into external auxiliary files (.prj,
+ // aux.xml) or as Geotiff tag
+ } else {// Check if selected layer is related to an image file
+ if (isImageFileLayer(layer)) {
+ FeatureCollection featureCollection = layer
+ .getFeatureCollectionWrapper();
+ String sourcePathImage = null;
+ for (Iterator<?> i = featureCollection.iterator();
i.hasNext();) {
+ Feature feature = (Feature) i.next();
+ sourcePathImage = (String) feature
+ .getString(ImageryLayerDataset.ATTR_URI);
+ sourcePathImage = sourcePathImage.substring(5);
+ File f = new File(sourcePathImage);
+ String filePath = f.getAbsolutePath();
+ String filePath1 = filePath.replace("%20", " ");
+ fileSourcePath = filePath1;
+
+ }
+ extension =
FileUtil.getExtension(fileSourcePath).toUpperCase();
+ if ((extension.equals("TIF") || extension.equals("TIFF"))) {
+ // If TIFF file is a geotiff, it scans into
+ // embedded tag
+ if (ProjUtils.isGeoTIFF(fileSourcePath)) {
+
+ projection = Integer.parseInt(ProjUtils
+ .readSRIDFromGeoTiffFile(fileSourcePath));
+ // If the TIF file is not a GeiTIFF it looks
+ // for a proj code into aux files
+ } else {
+ projection = Integer.parseInt(ProjUtils
+ .readSRIDFromAuxiliaryFile(fileSourcePath));
+ }
+ } else {
+ if (fileSourcePath != null) {
+ projection = Integer.parseInt(ProjUtils
+ .readSRIDFromAuxiliaryFile(fileSourcePath));
+ }
+ }// Check if source file is is a file-based vector
+ } else { // Only Vector files
+ if (!isDataBaseLayer(layer)) {
+ DataSourceQuery dsq = layer.getDataSourceQuery();
+ String sourceClass = "";
+ String sourcePath = "";
+ String dsqSourceClass = dsq.getDataSource().getClass()
+ .getName();
+ if (sourceClass.equals("")) {
+ sourceClass = dsqSourceClass;
+ }
+ Object fnameObj = dsq.getDataSource().getProperties()
+ .get("File");
+ sourcePath = fnameObj.toString();
+ fileSourcePath = sourcePath;
+ projection = Integer.parseInt(ProjUtils
+ .readSRIDFromAuxiliaryFile(fileSourcePath));
+ } else {
+
+ projection = 0;
+ }
+ }
+ }
+
+ return projection;
+
+ }
+
+ /**
+ * Method to get SRID from a layer file from auxiliary files (.prj or .aux)
+ * or GeoTIFFed tag. If the auxiliary file SRID does not exist, it returns
+ * 0.
+ *
+ * @param layer
+ * @return SRID
+ * @throws Exception
+ */
+ public static int SRIDFromFile(Layer layer) throws Exception {
+ String fileSourcePath = "";
+ int SRID = 0;
+ String extension = "";
+ // First check if selected Layer has an image datasource file
+ if (isImageFileLayer(layer)) {
+ FeatureCollection featureCollection = layer
+ .getFeatureCollectionWrapper();
+ String sourcePathImage = null;
+ for (Iterator<?> i = featureCollection.iterator(); i.hasNext();) {
+ Feature feature = (Feature) i.next();
+ sourcePathImage = (String) feature
+ .getString(ImageryLayerDataset.ATTR_URI);
+ sourcePathImage = sourcePathImage.substring(5);
+ File f = new File(sourcePathImage);
+ String filePath = f.getAbsolutePath();
+ String filePath1 = filePath.replace("%20", " ");
+ fileSourcePath = filePath1;
+
+ }
+ extension = FileUtil.getExtension(fileSourcePath).toUpperCase();
+ if ((extension.equals("TIF") || extension.equals("TIFF"))) {
+ // If TIFF file is a geotiff, it scans into
+ // embedded tag
+ if (ProjUtils.isGeoTIFF(fileSourcePath)) {
+
+ SRID = Integer.parseInt(ProjUtils
+ .readSRIDFromGeoTiffFile(fileSourcePath));
+ // If the TIF file is not a GeiTIFF it looks
+ // for a proj code into aux files
+ } else {
+ SRID = Integer.parseInt(ProjUtils
+ .readSRIDFromAuxiliaryFile(fileSourcePath));
+ }
+ // For all other image file types, not TIF
+ } else {
+ if (fileSourcePath != null) {
+ SRID = Integer.parseInt(ProjUtils
+ .readSRIDFromAuxiliaryFile(fileSourcePath));
+ }
+ }
+ // Than check if source file is is a file-based vector
+ } else {
+ // Only Vector files, excluding databases:
+ // OpenJUMP has different approches to detect
+ // SRIDs for them
+ if (!isDataBaseLayer(layer)) {
+ DataSourceQuery dsq = layer.getDataSourceQuery();
+ String sourceClass = "";
+ String sourcePath = "";
+ String dsqSourceClass = dsq.getDataSource().getClass()
+ .getName();
+ if (sourceClass.equals("")) {
+ sourceClass = dsqSourceClass;
+ }
+ Object fnameObj = dsq.getDataSource().getProperties()
+ .get("File");
+ sourcePath = fnameObj.toString();
+ fileSourcePath = sourcePath;
+ SRID = Integer.parseInt(ProjUtils
+ .readSRIDFromAuxiliaryFile(fileSourcePath));
+ } else {
+ SRID = 0;
+ }
+ }
+ return SRID;
+ }
+
+ // Boolean. Selected layer is related to an image file
+ private static boolean isImageFileLayer(Layer layer) {
+ if (layer.getStyle(ReferencedImageStyle.class) != null
+ && (layer.getDescription() != null)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ // Boolean. Selected layer is related to a database
+ private static boolean isDataBaseLayer(Layer layer) {
+ DataSourceQuery dsq = layer.getDataSourceQuery();
+ if (dsq == null || dsq.getDataSource() instanceof DataStoreDataSource)
{
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+}
+
------------------------------------------------------------------------------
_______________________________________________
Jump-pilot-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel