Hey all,
I think I am misunderstanding something regarding the projections. If someone could help me out here, I would really appreciate it.
We have in our code functions to convert a lat/long to the Google projection, and back. It is a bunch of straight math transforms on points, and I wanted to make it a little more generic to use the Geometry class. I started up a test to check that I could go from one to the other (note: I am not certain what the actual expected values from the Google projection are right now, so bear with me) and back, but I obviously have something wrong. Can someone look over what I have below and let me know where my confusion is? I have tried changing both the source and target projections in the transform, as well as using the same source and target projections but inverting the transform. Here is my code:
package ca.intelliware.services;
import junit.framework.TestCase;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.geotools.referencing.factory.AbstractAuthorityFactory;
import org.geotools.referencing.factory.epsg.PostgreDataSource;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.PrecisionModel;
public class TestProjectAndProjectBack extends TestCase {
public static final String EPSG_4326 = “EPSG:4326”;
public static final String EPSG_900913 = “PROJCS["WGS84 / Google Mercator", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4326"]], PROJECTION["Mercator_1SP"], PARAMETER["semi_minor", 6378137.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","900913"]]”;
@SuppressWarnings(“deprecation”)
public void testConvertFromDecimalDegreesToGoogleAndBackGivesSameValuesUsingGeometries() {
Geometry original = new Point(new Coordinate(new Double(“-81.123456”), new Double(“45.123456”)),new PrecisionModel(PrecisionModel.FLOATING_SINGLE), 4326);
Geometry converted = fromDecimalDegreesToGoogleTransverseMercator(original);
assertSignificantlyDifferent(original, converted);
Geometry convertedBack = fromGoogleTransverseMercatorToDecimalDegrees(original);
assertNotSignificantlyDifferent(original, convertedBack);
}
private void assertSignificantlyDifferent(Geometry geo1, Geometry geo2) {
assertTrue(!geo1.equals(geo2));
}
private void assertNotSignificantlyDifferent(Geometry geo1, Geometry geo2) {
assertTrue(geo1.equals(geo2));
}
private Geometry fromDecimalDegreesToGoogleTransverseMercator(Geometry geom) {
try {
MathTransform math = CRS.findMathTransform(getEpsg4326CRS(), getEpsg900913CRS());
return JTS.transform(geom, math);
} catch (Exception e) {
throw new IllegalStateException(“Unable to convert geometry:\n” + e.getMessage());
}
}
public Geometry fromGoogleTransverseMercatorToDecimalDegrees(Geometry geom) {
try {
MathTransform math = CRS.findMathTransform(getEpsg900913CRS(), getEpsg4326CRS());
return JTS.transform(geom, math);
// MathTransform math = CRS.findMathTransform(getEpsg4326CRS(), getEpsg900913CRS());
// return JTS.transform(geom, math.inverse());
} catch (Exception e) {
throw new IllegalStateException(“Unable to convert geometry:\n” + e.getMessage());
}
}
public CoordinateReferenceSystem getEpsg4326CRS() {
try {
PostgreDataSource postgreDataSource = SpringLocator.getEPSGPostgreDataSource();
AbstractAuthorityFactory abstractAuthorityFactory = postgreDataSource.createFactory(null);
return abstractAuthorityFactory.createCoordinateReferenceSystem(EPSG_4326);
} catch (Exception e) {
throw new RuntimeException("FATAL: Unable to create a CRS for " + EPSG_4326);
}
}
public CoordinateReferenceSystem getEpsg900913CRS() {
try {
return CRS.parseWKT(EPSG_900913);
} catch (FactoryException e) {
throw new RuntimeException("FATAL: Unable to create a CRS for " + EPSG_900913);
}
}
}
Thanks,
-mike
“I don’t think that the right time to tell a dog not to pee on the carpet is semiannually.”
House MD on performance reviews