GeoTools JTS orthodromicDistance throws exception for latitude being out of range

StackOverflow https://stackoverflow.com//questions/24006631

  •  20-12-2019
  •  | 
  •  

문제

I am trying to get geotools to tell me the distance between two points. I am providing the points in degrees, and I want to get back the distance in meters. I followed this web page for instruction:

http://docs.geotools.org/stable/userguide/library/api/jts.html

Unfortunately when I run it, an exception is thrown because it says my latitude is out of range.

Here is my code:

public double measureDistanceInMeters(double[] coord1, double[] coord2) {
    System.out.println("latitude: "+coord1[0]+", longitude: "+coord1[1]);
    System.out.println("latitude: "+coord2[0]+", longitude: "+coord2[1]);
    CoordinateReferenceSystem crs = DefaultGeocentricCRS.CARTESIAN;
    // latitude first, longitude second.
    Coordinate start = new Coordinate(coord1[0],coord1[1]);
    Coordinate end = new Coordinate(coord2[0],coord2[1]);
    double distance = -1;
    try {
        distance = JTS.orthodromicDistance(start, end, crs);
    } catch (TransformException e1) {
        e1.printStackTrace();
    }
    return distance;

When I run it, the console prints this:

latitude: 38.8951, longitude: -77.0367
latitude: 40.7127, longitude: -74.0059

JUnit fails and here is the stack trace:

java.lang.IllegalArgumentException: Latitude �N is out of range (±90°).
    at org.geotools.referencing.GeodeticCalculator.checkLatitude(GeodeticCalculator.java:389)
    at org.geotools.referencing.GeodeticCalculator.setStartingGeographicPoint(GeodeticCalculator.java:550)
    at org.geotools.referencing.GeodeticCalculator.setStartingPosition(GeodeticCalculator.java:591)
    at org.geotools.geometry.jts.JTS.orthodromicDistance(JTS.java:635)
    at fungle.funfinder.data.geo.GeoToolsRuler.measureDistanceInMeters(GeoToolsRuler.java:49)
    at fungle.funfinder.data.geo.GeoRulerBase.getDistance(GeoRulerBase.java:15)
    at fungle.funfinder.data.geo.GeoToolsRulerTest.test(GeoToolsRulerTest.java:11)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

So I think I am misunderstanding something here. Geotools is huge, and even though it has documentation, it's pretty hard to find the documentation you're looking for because it's so huge and complicated.

I am guessing that I am using the wrong coordinate reference system here, or passing as an arg where I should not be. I don't know what I'm doing wrong. Please help.

도움이 되었습니까?

해결책

You are using the wrong coordinate system, essentially you have told JTS that your coordinates need to be converted to lat/long and then used so they go out of range.

By changing your code to include:

    CoordinateReferenceSystem crs = null;
    try {
        crs = CRS.decode("epsg:4326");
    } catch (NoSuchAuthorityCodeException e) {
        e.printStackTrace();
    } catch (FactoryException e) {
        e.printStackTrace();
    }

I get the answer 328739.66 m or 328Km which sounds about right (if it isn't then you may need to swap the latitude and longitude values round).

You will also need to add

    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-epsg-hsql</artifactId>
        <version>${geotools.version}</version>
    </dependency>

to your pom.xml file or the definition of the coordinate system won't be found.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top