The easy way

When working with the built-in Coordinate Reference Systems, PHPCoord can usually1 convert the coordinates in any given Point to be in a different system by calling the convert() method.

$newPoint = $point->convert(
    CoordinateReferenceSystem $to,
    bool $ignoreBoundaryRestrictions = false
); // returns a new Point

Ignoring the second optional parameter for now, calling convert() will first look to see if the built-in dataset knows how to perform a direct conversion. If it can, then PHPCoord will automatically invoke the relevant conversion methods with the appropriate parameters and return a new Point object with the adjusted coordinates in the target CRS.

Although PHPCoord has knowledge of thousands of different conversions, this does not cover many scenarios. For example there is no published direct conversion between a British National Grid reference and a UTM Grid reference. In these scenarios PHPCoord can “chain” conversions it does know about to achieve the desired result, for example it would automatically calculate British National Grid -> OSGB36 -> WGS84 -> UTM. This ability to chain means conversion between almost any two CRSs is possible as long as they have a common link.

$from = ProjectedPoint::createFromEastingNorthing(
    new Metre(577275),
    new Metre(69741),
    Projected::fromSRID(Projected::EPSG_OSGB_1936_BRITISH_NATIONAL_GRID)
);
$toCRS = Projected::fromSRID(Projected::EPSG_WGS_84_UTM_ZONE_31N);
$to = $from->convert($toCRS);

Note

Calculating every single possible permutation of chain between two CRSs is very computationally expensive and so for practicality PHPCoord limits the chain depth to 5 (i.e. the source CRS, 3 intermediate CRSs and the target CRS). If you know a transformation should be possible, but PHPCoord cannot find it you may wish to try an explicit 2-stage conversion (e.g. source to WGS84, WGS84 to target).

Boundaries

Every CRS has a defined area (“extent”) over which it operates. Some are worldwide (e.g WGS84), but most are regional (e.g. NAD83) or country-specific (e.g. GDA94). Trying to convert from one region/country specific CRS to another region/country CRS is likely to result in either inaccurate or completely nonsensical coordinates due to the relevant algorithms being designed and tested only over their defined areas. Plotting a point in Tokyo onto the New Zealand Map Grid just shouldn’t be done, regardless if a chain can be found through e.g. WGS84.

By default therefore PHPCoord will not allow such conversions to take place.

There are occasions however where the formal definitions of the CRS and real-life conflict - for example in Germany (which is partially in UTM zone 32 and partially in zone 33), coordinates are sometimes requested as zone 32-based even for points that are in zone 33. The administrative convenience is considered to outweigh the slight loss of accuracy of extending the zone.

If you are sure that you know what you’re doing, you can set the optional parameter $ignoreBoundaryRestrictions to true.

Caution

The importance of boundary checking to ensure fidelity of results means that converting a standalone VerticalPoint cannot safely be done. VerticalPoint objects therefore do not have a ->convert method.

In practice this should not affect you as a VerticalPoint will normally be used as part of a CompoundPoint.

Universal Transverse Mercator (UTM)

PHPCoord has 3 different ways of handling UTM references (see here for details).

For conversions that do not involve a UTMPoint, use the ->convert() method as described above.

For conversions from a GeographicPoint to a UTMPoint, call the ->asUTMPoint() method.

$from = GeographicPoint::create(
    new Degree(43.642567),
    new Degree(-79.387139),
    null,
    Geographic2D::fromSRID(Geographic2D::EPSG_WGS_84)
);
$to = $from->asUTMPoint();

Note

You cannot directly convert to a UTMPoint from a different kind of ProjectedPoint or a GeocentricPoint, you must convert to the relevant GeographicPoint first. This is because the projection parameters are calculated dynamically at runtime and are not available to take part in chain creation.

For conversions from a UTMPoint back to the associated GeographicPoint, call the ->asGeographicPoint() method.

$from = new UTMPoint(
    new Metre(630084),
    new Metre(4833439),
    17,
    UTMPoint::HEMISPHERE_NORTH,
    Geographic2D::fromSRID(Geographic2D::EPSG_WGS_84)
);
$to = $from->asGeographicPoint();

The ->convert() method is present on UTMPoints and can be used as normal to convert to any desired CRS (including the base CRS).

Footnotes

1

There are over 36 million possible combinations of source and target CRS. They haven’t all been tested…