ehrid
ehrid

Reputation: 125

Getting coordinates in GeoTools

Thanks to Reading ESRI shapefiles from the InputStream in Java I can read my shapefiles and access every GeometryAttribute, but I also need to convert it coordinates in long/lat format, it might be 40°44′55″N, 73 59 11W or best 40.7486, -73.9864.

example of my WKT is

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]]

Upvotes: 1

Views: 911

Answers (1)

Ian Turton
Ian Turton

Reputation: 10976

GeoTools has a number of ways to reproject your geometries depending on what you want to do after your reproject them.

The simplest is to use a ReprojectingFeatureCollection to provide you with a new collection in your required projection (in this case EPSG:4326) or you can create a JTS.transform and use that on individual geometries.

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

or

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

Printing the coordinates of those new geometries will give you decimal degrees (3.234545) if you need DMS (1°3'3") then a class like this will help:

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;
  }
}

Upvotes: 1

Related Questions