在 GeoTools 中获取坐标

Getting coordinates in GeoTools

感谢 Reading ESRI shapefiles from the InputStream in Java 我可以读取我的 shapefile 并访问每个 GeometryAttribute,但我还需要将它的坐标转换为 long/lat 格式,它可能是 40°44′55″N, 73 59 11W 或最佳 40.7486, -73.9864.

我的 WKT 示例是

GeometryAttribute sourceGeometry = feature.getDefaultGeometryProperty();
CoordinateReferenceSystem example = sourceGeometry.getDescriptor().getCoordinateReferenceSystem();
String wkt = example.toWKT();

PROJCS["ETRS_1989_Poland_CS92", 
  GEOGCS["GCS_ETRS_1989", 
    DATUM["D_ETRS_1989", 
      SPHEROID["GRS_1980", 6378137.0, 298.257222101]], 
    PRIMEM["Greenwich", 0.0], 
    UNIT["degree", 0.017453292519943295], 
    AXIS["Longitude", EAST], 
    AXIS["Latitude", NORTH]], 
  PROJECTION["Transverse_Mercator"], 
  PARAMETER["central_meridian", 19.0], 
  PARAMETER["latitude_of_origin", 0.0], 
  PARAMETER["scale_factor", 0.9993], 
  PARAMETER["false_easting", 500000.0], 
  PARAMETER["false_northing", -5300000.0], 
  UNIT["m", 1.0], 
  AXIS["x", EAST], 
  AXIS["y", NORTH]]

GeoTools 有多种方法可以重新投影您的几何图形,具体取决于您在重新投影几何图形后要执行的操作。

最简单的方法是使用 ReprojectingFeatureCollection 为您提供所需投影中的新集合(在本例中为 EPSG:4326),或者您可以创建一个 JTS.transform 并使用它在个别几何形状上。

ReprojectingFeatureCollection rfc = new ReprojectingFeatureCollection(features, CRS.decode("epsg:4326"));

CoordinateReferenceSystem source = sourceGeometry.getDescriptor().getCoordinateReferenceSystem();
CoordinateReferenceSystem target = CRS.decode("epsg:4326");
MathTransform transform = CRS.findMathTransform(source, target, lenient);
Geometry geometry2 = JTS.transform(geometry, transform);

如果您需要 DMS (1°3'3"),打印这些新几何图形的坐标将为您提供十进制度数 (3.234545),那么像这样的 class 会有所帮助:

public class DMSToDegrees {
  static public double convert(int degrees, int minutes, double seconds) {
    //to allow for negative (i.e. W or S) values note the sign of the degrees
    float sign = Math.signum(degrees);
    if(sign==0.0) {
      //we'll consider 0 to be positive
      sign = 1.0f;
    }
    //seconds are 1/60th of a minute so express as a fractional minute
    double dmins = minutes+seconds/60.0;
    //minutes are 1/60th of a degree so express as a fractional degree
    double deg = Math.abs(degrees) + dmins/60.0;
    // put the sign back on the result
    return sign*deg;
  }
  static public double[] reverse(double degrees){
  //to allow for negative (i.e. W or S) values note the sign of the degrees
    double sign = Math.signum(degrees);
    if(sign==0.0) {
      //we'll consider 0 to be positive
      sign = 1.0f;
    }
    double[] ret = new double[3];
    degrees = Math.abs(degrees);
    ret[0] = Math.floor(degrees);
    double mins = degrees - ret[0];
    ret[1] = Math.floor(mins*60);
    ret[2] = ((mins*60 - ret[1]))*60;
    ret[0]*=sign;
    return ret;
  }
}