3

I'm trying to transform EPSG:27700 coordinates to latitude and longitude. From my research I understand that WGS 84 (EPSG:4326) is the SRS that resembles latitude and longitude.

I'm using Proj4j to try and convert a test coordinate (those familiar with my previous question will recognise Kirkby In Ashfield station).

My Java code snippet:

String projection27700 = "+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 "
    + "+x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs";
CRSFactory crsFactory = new CRSFactory();
CoordinateReferenceSystem sourceSRS = crsFactory.createFromParameters(null,
    projection27700);

String projection4326 = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs";
CoordinateReferenceSystem targetSRS = crsFactory.createFromParameters(null,
    projection4326);

CoordinateTransform transformation = new BasicCoordinateTransform(sourceSRS,
    targetSRS);

ProjCoordinate result = new ProjCoordinate();
ProjCoordinate input = new ProjCoordinate(450077, 356089);
transformation.transform(input, result);

System.out.println(result.x + ", " + result.y);

The result printed is:

-155.20355661333892, -35.91545136124713

This doesn't seem right - it neither makes sense as degrees or metres (to me at least). Have I missed out a conversion somewhere, either on my input data or in this output data I've produced?

I'm fairly happy my input data is right, based on this documentation, which confirms that +units=m will allow my input data to be in metres. It also suggests the output data should be in degrees, which is what I want.

  • Try adding +towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 to the projection27700 string. – BradHards Aug 7 '16 at 6:36
1

The proj4 string that GDAL version 2.3-dev is using is as follows:

gdalsrsinfo epsg:27700

PROJ.4 : '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100
00 +ellps=airy +towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 +units
m +no_defs'

Transformation with gdaltransform utility gives correct answer:

gdaltransform -s_srs epsg:27700 -t_srs epsg:4326
450077, 356089
-1.25355705622145 53.0996598531095 49.0407739514485

Adding the datum as used in your proj4 string has only very small effect:

gdaltransform -s_srs "+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.
9996012717 + +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_def
s" -t_srs epsg:4326
450077, 356089
-1.2535571019191 53.0996598519711 49.0382279874757

I am not sure what goes wrong but it seems that the error is in your code and not in proj4.

0

I haven't solved the original problem, but I've worked around it by using CTS instead.

CRSFactory crsFactory = new CRSFactory();

// Download the data files from Github and place on the class path
RegistryManager registryManager = crsFactory.getRegistryManager();
registryManager.addRegistry(new EPSGRegistry());
CoordinateReferenceSystem crs4326 = crsFactory.getCRS("EPSG:4326");
CoordinateReferenceSystem crs27700 = crsFactory.getCRS("EPSG:27700");

// These ugly casts seem unavoidable
List<CoordinateOperation> operations = CoordinateOperationFactory
    .createCoordinateOperations((GeodeticCRS) crs27700, (GeodeticCRS) crs4326);

double[] result = operations.get(0).transform(new double[] {450077, 356089});
System.out.println(Arrays.toString(result));

This produces:

[-1.2535570562769147, 53.09965984661543]

which is the correct answer.

0

Another option is Apache SIS - http://sis.apache.org. I found it cleaner and faster than most solutions:

val sourceCRS = CRS.forCode("EPSG:27700")
val targetCRS = CRS.forCode("EPSG:4326")

val operation = CRS.findOperation(sourceCRS, targetCRS, null)

// Threadsafe: https://sis.apache.org/apidocs/org/apache/sis/referencing/operation/transform/AbstractMathTransform.html
val transform = operation.getMathTransform

val ptSrc = new DirectPosition2D(450077, 356089)
val ptDst = transform.transform(ptSrc, null)

println("Source: " + ptSrc)
println("Target: " + ptDst)

This produces:

Source: POINT(450077 356089)
Target: POINT(53.09965984661642 -1.2535570562768357)

For dependencies you'd need:

    <dependency>
        <groupId>org.apache.sis.core</groupId>
        <artifactId>sis-referencing</artifactId>
        <version>0.8</version>
    </dependency>
    <dependency>
        <groupId>org.apache.sis.non-free</groupId>
        <artifactId>sis-embedded-data</artifactId>
        <version>0.8</version>
        <scope>runtime</scope>
    </dependency>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.