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 Jump-pilot-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel