Introduction

phpgeo is a small PHP library which provides abstractions to geographical coordinates (including support for different ellipsoids), polylines ("GPS Tracks"), polygons, bounds, and more. phpgeo allows you to perform different calculations with these abstractions, as distances, track lengths, etc.

phpgeo is developed by Marcus Jaschen and all contributors.

phpgeo is licensed under the GNU GENERAL PUBLIC LICENSE Version 3 (GPL-3.0)

The project is hosted on Github:

Requirements

phpgeo requires at least PHP 5.4.0.

Installation

phpgeo is best be installed using Composer. Please visit the Composer website website for more information.

To install phpgeo, simply "require" it using Composer:

php composer.phar require mjaschen/phpgeo

phpgeo is now ready to be used in your project!

API Documentation

Detailed API documentation is available.

Geometries

phpgeo provides several geometry classes:

A Coordinate represents a geographic location, i. e. it contains a latitude and a longitude - together with an so called Ellipsoid.

A Line consists of two coordinates, while polylines and polygons are built from two or more coordinates.

Coordinate

The Coordinate class is the most important class of phpgeo and provides the base for all features. It’s a representation of a geographic location and consists of three parts:

  • Geographic Latitude

  • Geographic Longitude

  • Ellipsoid

Geographic latitude and longitude values are float numbers between -90.0 and 90.0 (degrees latitude) and -180.0 and 180.0 (degrees longitude).

The Ellipsoid is a representation of an approximated shape of the earth and is abstracted in its own Ellipsoid class.

Line

A line consists of two points, i. e. instances of the Coordinate class.

Length

The Line class provides a method to calculate its own length. The method expects an instance of a class which implements the DistanceInterface.

<?php

use Location\Coordinate;
use Location\Distance\Haversine;
use Location\Line;

$line = new Line(
    new Coordinate(52.5, 13.5),
    new Coordinate(52.6, 13.4)
);

$length = $line->getLength(new Haversine()); (1)

printf("The line has a length of %.3f meters\n", $length);
1 Haversine is one of the currently two available classes for distance calculation. The other one is named Vincenty.

The code above will produce the output below:

The line has a length of 13013.849 meters

Bearing

The bearing of an instance can be calculated using the getBearing() method. An instance of BearingInterface must be provided as method argument.

<?php

use Location\Bearing\BearingEllipsoidal;
use Location\Coordinate;
use Location\Line;

$line = new Line(
    new Coordinate(52.5, 13.5),
    new Coordinate(52.6, 13.4)
);

$bearing = $line->getBearing(new BearingEllipsoidal()); (1)

printf("The line has a bearing of %.2f degrees\n", $bearing);
1 BearingEllipsoidal is one of the currently two available classes for bearing calculation. The other one is named BearingSpherical.

The code above will produce the output below:

The line has a bearing of 328.67 degrees

This ist the so called initial bearing. There exist another bearing angle, called the final bearing. It can be calculated as well:

<?php

use Location\Bearing\BearingEllipsoidal;
use Location\Coordinate;
use Location\Line;

$line = new Line(
    new Coordinate(52.5, 13.5),
    new Coordinate(52.6, 13.4)
);

$bearing = $line->getFinalBearing(new BearingEllipsoidal());

printf("The line has a final bearing of %.2f degrees\n", $bearing);

The code above will produce the output below:

The line has a final bearing of 328.59 degrees

See Bearing between two points for more information about bearings.

Polyline

A polyline consists of an ordered list of locations, i. e. instances of the Coordinate class.

Create a polyline

To create a polyline, just instantiate the class and add points:

<?php

use Location\Coordinate;
use Location\Polyline;

$polyline = new Polyline();
$polyline->addPoint(new Coordinate(52.5, 13.5));
$polyline->addPoint(new Coordinate(54.5, 12.5));
$polyline->addPoint(new Coordinate(55.5, 14.5));
?>

It’s possible to add points to the end of the polyline at every time.

Segments

It’s possible to get a list of polyline segments. Segments are returned as an array of Line instances.

<?php

use Location\Coordinate;
use Location\Polyline;

$track = new Polyline();
$track->addPoint(new Coordinate(52.5, 13.5));
$track->addPoint(new Coordinate(54.5, 12.5));
$track->addPoint(new Coordinate(55.5, 14.5));

foreach ($track->getSegments() as $segment) {
    printf(
        "Segment length: %0.2f kilometers\n",
        ($segment->getLength(new Haversine()) / 1000)
    );
}

The code above will produce the output below:

Segment length: 232.01 kilometers
Segment length: 169.21 kilometers

Length

Length calculation is described in the Distance and Length section.

Reverse Direction

It’s possible to get a new instance with reversed direction while the original polyline stays unchanged:

<?php

use Location\Coordinate;
use Location\Polyline;

$track = new Polyline();
$track->addPoint(new Coordinate(52.5, 13.5));
$track->addPoint(new Coordinate(54.5, 12.5));

$reversed = $track->getReverse();

print_r($reversed);

The code above will produce the output below:

Location\Polyline Object
(
    [points:protected] => Array
        (
            [0] => Location\Coordinate Object
                (
                    [lat:protected] => 54.5
                    [lng:protected] => 12.5
                    [ellipsoid:protected] => Location\Ellipsoid Object
                        (
                            [name:protected] => WGS-84
                            [a:protected] => 6378137
                            [f:protected] => 298.257223563
                        )

                )

            [1] => Location\Coordinate Object
                (
                    [lat:protected] => 52.5
                    [lng:protected] => 13.5
                    [ellipsoid:protected] => Location\Ellipsoid Object
                        (
                            [name:protected] => WGS-84
                            [a:protected] => 6378137
                            [f:protected] => 298.257223563
                        )

                )

        )

)

Polygon

A polygon consists of an ordered list of locations, i. e. instances of the Coordinate class. It’s very similar to a polyline, but its start and end points are connected.

Create a polygon

To create a polygon, just instantiate the class and add points:

<?php

use Location\Coordinate;
use Location\Polygon;

$polygon = new Polygon();
$polygon->addPoint(new Coordinate(52.5, 13.5));
$polygon->addPoint(new Coordinate(54.5, 12.5));
$polygon->addPoint(new Coordinate(55.5, 14.5));
?>

It’s possible to add points to the end at every time.

Get list of points

getPoints() is used to get the list of points, the number of points can be retrieved by calling getNumberOfPoints():

<?php

use Location\Coordinate;
use Location\Formatter\Coordinate\DMS;
use Location\Polygon;

$polygon = new Polygon();
$polygon->addPoint(new Coordinate(52.5, 13.5));
$polygon->addPoint(new Coordinate(54.5, 12.5));
$polygon->addPoint(new Coordinate(55.5, 14.5));

printf("The polygon consists of %d points:\n", $polygon->getNumberOfPoints());

foreach ($polygon->getPoints() as $point) {
    echo $point->format(new DMS()) . PHP_EOL;
}

The code above will produce the output below:

The polygon consists of 3 points:
52° 30′ 00″ 013° 30′ 00″
54° 30′ 00″ 012° 30′ 00″
55° 30′ 00″ 014° 30′ 00″

Segments

It’s possible to get a list of polygon segments. Segments are returned as an array of Line instances.

<?php

use Location\Coordinate;
use Location\Distance\Haversine;
use Location\Polygon;

$polygon = new Polygon();
$polygon->addPoint(new Coordinate(52.5, 13.5));
$polygon->addPoint(new Coordinate(54.5, 12.5));
$polygon->addPoint(new Coordinate(55.5, 14.5));

foreach ($polygon->getSegments() as $line) {
    printf("%0.3f m\n", $line->getLength(new Haversine()));
}

The code above will produce the output below:

232011.020 m
169207.795 m
339918.069 m

Length/Perimeter

Length calculation is described in the Distance and Length section.

Geofence

It’s possible to check if a geometry object (point, line, polyline, polygon) lies inside a polygon. The documentation can be found in the Geofence section.

Reverse Direction

It’s possible to get a new instance with reversed direction while the original polygon stays unchanged:

<?php

use Location\Coordinate;
use Location\Polygon;
use Location\Formatter\Coordinate\DecimalDegrees;

$polygon = new Polygon();
$polygon->addPoint(new Coordinate(52.5, 13.5));
$polygon->addPoint(new Coordinate(64.1, - 21.9));
$polygon->addPoint(new Coordinate(40.7, - 74.0));
$polygon->addPoint(new Coordinate(33.9, - 118.4));

$reversed = $polygon->getReverse();

foreach ($reversed->getPoints() as $point) {
    echo $point->format(new DecimalDegrees(', ')) . PHP_EOL;
}

The code above produces the output below:

33.90000, -118.40000
40.70000, -74.00000
64.10000, -21.90000
52.50000, 13.50000

Bounds

Ellipsoid

An ellipsoid is a mathematically defined approximation of the earth’s surface.

An ellipsoid is defined by two parameters:

  • the semi-major axis a (equatorial radius)

  • the semi-minor axis b (polar radius)

a and b together define the flattening of the ellipsoid f:

\(f = \frac{a-b}{a}\)

phpgeo’s ellipsoids are defined by a and 1/f instead of a and b. That’s not a problem because each of the three values can be calculated from the other two.

phpgeo supports arbitrary ellipsoids. WGS-84 is used as default when no other ellipsoid is given. For day-to-day calculations it’s not needed to care about ellipsoids in the most cases.

It’s possible to create an instance of the Ellipsoid class either by specifing a name or by providing the three parameters name, a, and 1/f.

use Location\Ellipsoid;

$ellipsoid = Ellipsoid::createDefault('WGS-84'); (1)

printf(
    "%s: a=%f; b=%f; 1/f=%f\n",
    $ellipsoid->getName(),
    $ellipsoid->getA(),
    $ellipsoid->getB(),
    $ellipsoid->getF()
);

$ellipsoid = new Ellipsoid('GRS-80', 6378137, 298.257222); (2)

printf(
    "%s: a=%f; b=%f; 1/f=%f\n",
    $ellipsoid->getName(),
    $ellipsoid->getA(),
    $ellipsoid->getB(),
    $ellipsoid->getF()
);
1 Create ellipsoid instance from one of the default configurations
2 Create custom ellipsoid by providing name, a, and 1/f

The code above will produce the output below:

WGS-84: a=6378137.000000; b=6356752.314245; 1/f=298.257224
GRS-80: a=6378137.000000; b=6356752.314133; 1/f=298.257222

Please take a look into the Ellipsoid source file for a list of pre-defined ellipsoids.

Calculations

Distance and Length

Distance Between Two Coordinates (Vincenty’s Formula)

Use the calculator object directly:

<?php

use Location\Coordinate;
use Location\Distance\Vincenty;

$coordinate1 = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit
$coordinate2 = new Coordinate(20.709722, -156.253333); // Haleakala Summit

$calculator = new Vincenty();

echo $calculator->getDistance($coordinate1, $coordinate2);

The code above will produce the output below:

128130.850

or call the getDistance() method of a Coordinate object by injecting a calculator object:

<?php

use Location\Coordinate;
use Location\Distance\Vincenty;

$coordinate1 = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit
$coordinate2 = new Coordinate(20.709722, -156.253333); // Haleakala Summit

echo $coordinate1->getDistance($coordinate2, new Vincenty());

The code above will produce the output below:

128130.850

Distance Between Two Coordinates (Haversine Formula)

There exist different methods for calculating the distance between two points. The Haversine formula is much faster than Vincenty’s method but less precise:

<?php

use Location\Coordinate;
use Location\Distance\Haversine;

$coordinate1 = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit
$coordinate2 = new Coordinate(20.709722, -156.253333); // Haleakala Summit

echo $coordinate1->getDistance($coordinate2, new Haversine());

The code above will produce the output below:

128384.515

Length of a Polyline

phpgeo has a polyline implementation which can be used to calculate the length of a GPS track or a route. A polyline consists of at least two points. Points are instances of the Coordinate class.

For more details about polylines/GPS tracks see the Polyline section.

<?php

use Location\Coordinate;
use Location\Polyline;
use Location\Distance\Vincenty;

$track = new Polyline();
$track->addPoint(new Coordinate(52.5, 13.5));
$track->addPoint(new Coordinate(54.5, 12.5));

echo $track->getLength(new Vincenty());

Perimeter of a Polygon

The perimeter is calculated as the sum of the length of all segments. The result is given in meters.

<?php

use Location\Distance\Vincenty;
use Location\Coordinate;
use Location\Polygon;

$polygon = new Polygon();
$polygon->addPoint(new Coordinate(10, 10));
$polygon->addPoint(new Coordinate(10, 20));
$polygon->addPoint(new Coordinate(20, 20));
$polygon->addPoint(new Coordinate(20, 10));

echo $polygon->getPerimeter(new Vincenty());

The code above will produce the output below:

4355689.472

Bearing and Destination

phpgeo can be used to calculate the bearing between two points and to get a destination point for a given start point together with a bearing angle and a distance.

Multiple calculation algorithms are supported. Currently phpgeo provides methods for calculations with a spherical earth model and with an ellipsoidal model. The spherical calculations are very fast, compared to the ellipsoidal methods. The ellipsoidal algorithms are a bit more precise on the other hand.

Bearing between two points

Given two points, it’s possible to calculate the bearing angled between those points.

phpgeo can calculate the initial bearing (bearing as seen from the first point) and the final bearing (bearing as seen approaching the destination point).

Calculation with a spherical earth model
<?php

use Location\Bearing\BearingSpherical;
use Location\Coordinate;

$berlin = new Coordinate(52.5, 13.5);
$london = new Coordinate(51.5, -0.12);

$bearingCalculator = new BearingSpherical();

$startTime = microtime(true);
var_dump($bearingCalculator->calculateBearing($berlin, $london));
var_dump($bearingCalculator->calculateFinalBearing($berlin, $london));
$endTime = microtime(true);
printf("Time elapsed: %0.6f s\n", ($endTime - $startTime));

The code above will produce the following output:

double(268.60722336693)
double(257.85494586285)
Time elapsed: 0.000285 s
Calculation with an ellipsoidal earth model
<?php

use Location\Bearing\BearingEllipsoidal;
use Location\Coordinate;

$berlin = new Coordinate(52.5, 13.5);
$london = new Coordinate(51.5, -0.12);

$bearingCalculator = new BearingEllipsoidal();

$startTime = microtime(true);
var_dump($bearingCalculator->calculateBearing($berlin, $london));
var_dump($bearingCalculator->calculateFinalBearing($berlin, $london));
$endTime = microtime(true);
printf("Time elapsed: %0.6f s\n", ($endTime - $startTime));

The code above will produce the following output:

double(268.62436347111)
double(257.87203657292)
Time elapsed: 0.000304 s

Both calculations finish in roughly the same time. One would expect the second calculation to be clearly slower than the first one. It seems the exit condition for the iteration is reached quite fast. There might exist other conditions where the ellipsoidal calculation is noticeable slower.

Destination point for given bearing and distance

As an example, starting from Berlin, calculate the destination point in 56.1 km distance with an initial bearing of 153 degrees:

<?php
use Location\Bearing\BearingEllipsoidal;
use Location\Bearing\BearingSpherical;
use Location\Coordinate;
use Location\Formatter\Coordinate\DecimalDegrees;

$berlin = new Coordinate(52.5, 13.5);

$bearingSpherical = new BearingSpherical();
$bearingEllipsoidal = new BearingEllipsoidal();

$destination1 = $BearingSpherical->calculateDestination($berlin, 153, 56100);
$destination2 = $bearingEllipsoidal->calculateDestination($berlin, 153, 56100);

echo "Spherical:   " . $destination1->format(new DecimalDegrees()) . PHP_EOL;
echo "Ellipsoidal: " . $destination2->format(new DecimalDegrees()) . PHP_EOL;

The code above will produce the output below:

Spherical:   52.04988 13.87628
Ellipsoidal: 52.05020 13.87126

Oh, look, what a beautiful spot on earth it is. ;-)

Final Bearing for a calculated destination

phpgeo can calculate the final bearing angle for a given starting point, an initial bearing, and the distance to the destination.

<?php
use Location\Bearing\BearingEllipsoidal;
use Location\Coordinate;
use Location\Formatter\Coordinate\DecimalDegrees;

$berlin = new Coordinate(52.5, 13.5);

$bearingEllipsoidal = new BearingEllipsoidal();

$finalBearing = $bearingEllipsoidal->calculateDestinationFinalBearing($berlin, 153, 56100);

var_dump($finalBearing);

The code above will produce the output below:

float(153.29365182147)

Perpendicular Distance

The perpendicular distance is defined as the shortest distance between a point and a line (in the two-dimensional plane) respectively between a point and a great circle on a spherical surface. With phpgeo it is possible to calculate the perpendicular distance between a point (instance of the Coordinate class) and a line (instance of the Line class). A line is defined by two coordinates, exactly as a great circle — both are interchangeable in this case.

<?php

use Location\Coordinate;
use Location\Line;
use Location\Utility\PerpendicularDistance;

$point = new Coordinate(52.44468, 13.57455);
$line = new Line(
    new Coordinate(52.4554, 13.5582),
    new Coordinate(52.4371, 13.5623)
);

$pdCalc = new PerpendicularDistance();

printf(
    "perpendicular distance: %.1f meters\n",
    $pdCalc->getPerpendicularDistance($point, $line)
);

The code above will produce the output below:

perpendicular distance: 936.7 meters

Geofence

phpgeo has a polygon implementation which can be used to determinate if a geometry (point, line, polyline, polygon) is contained in it or not. A polygon consists of at least three points.

The calculation gives wrong results if the polygons crosses the 180/-180 degrees meridian.
<?php

use Location\Coordinate;
use Location\Polygon;

$geofence = new Polygon();

$geofence->addPoint(new Coordinate(-12.085870,-77.016261));
$geofence->addPoint(new Coordinate(-12.086373,-77.033813));
$geofence->addPoint(new Coordinate(-12.102823,-77.030938));
$geofence->addPoint(new Coordinate(-12.098669,-77.006476));

$outsidePoint = new Coordinate(-12.075452, -76.985079);
$insidePoint = new Coordinate(-12.092542, -77.021540);

var_dump($geofence->contains($outsidePoint)); // returns bool(false) the point is outside the polygon
var_dump($geofence->contains($insidePoint)); // returns bool(true) the point is inside the polygon

Transformations and Processing

Simplifying a polyline

Polylines can be simplified to save storage space or bandwidth.

phpgeo provides two implementations for simplifying a polyline.

The first implementation uses the Ramer–Douglas–Peucker algorithm (also known as Douglas-Peucker algorithm). The other implementation examines the bearings of the polyline segments and removes a segment when its bearing angle is similar to the bearing angle of its predecessor segment. I named it the Delta-Bearing algorithm.

Ramer-Douglas-Peucker Algorithm
<?php

use Location\Coordinate;
use Location\Formatter\Coordinate\DecimalDegrees;
use Location\Polyline;
use Location\Processor\Polyline\SimplifyDouglasPeucker;

$polyline = new Polyline();
$polyline->addPoint(new Coordinate(10.0, 10.0));
$polyline->addPoint(new Coordinate(20.0, 20.0));
$polyline->addPoint(new Coordinate(30.0, 10.0));

$processor = new SimplifyDouglasPeucker(1500000); (1)

$simplified = $processor->simplify($polyline);

foreach ($simplified->getPoints() as $point) {
    echo $point->format(new DecimalDegrees()) . PHP_EOL;
}
1 remove all points which perpendicular distance is less than 1,500,000 meters (1,500 km) from the surrounding points.

The code above produces the output below:

10.00000 10.00000
30.00000 10.00000
Delta-Bearing Algorithm
<?php

use Location\Coordinate;
use Location\Formatter\Coordinate\DecimalDegrees;
use Location\Polyline;
use Location\Processor\Polyline\SimplifyBearing;

$polyline = new Polyline();
$polyline->addPoint(new Coordinate(10.0, 10.0));
$polyline->addPoint(new Coordinate(20.0, 20.0));
$polyline->addPoint(new Coordinate(30.0, 10.0));

$processor = new SimplifyBearing(90); (1)

$simplified = $processor->simplify($polyline);

foreach ($simplified->getPoints() as $point) {
    echo $point->format(new DecimalDegrees()) . PHP_EOL;
}
1 The constructor argument is the minimum required angle between two adjacent polyline segments so that no points will be removed. If the bearing angle difference is less that the given value, the middle point will be removed from the resulting polyline.

The code above produces the output below:

10.00000 10.00000
30.00000 10.00000

The following image shows both a polyline and its simplified version. The simplification was done with the Delta-Bearing Algorithm with a threshold angle of 20 degrees. The original polyline is painted in blue, the simplified polyline is magenta.

Delta-Bearing simplification

Formatting and Output

Coordinates

You can format a coordinate in different styles.

Decimal Degrees

<?php

use Location\Coordinate;
use Location\Formatter\Coordinate\DecimalDegrees;

$coordinate = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit

echo $coordinate->format(new DecimalDegrees());

The code above produces the output below:

19.82066 -155.46807

Degrees/Minutes/Seconds (DMS)

<?php

use Location\Coordinate;
use Location\Formatter\Coordinate\DMS;

$coordinate = new Coordinate(18.911306, -155.678268); // South Point, HI, USA

$formatter = new DMS();

echo $coordinate->format($formatter) . PHP_EOL;

$formatter->setSeparator(", ")
    ->useCardinalLetters(true)
    ->setUnits(DMS::UNITS_ASCII);

echo $coordinate->format($formatter) . PHP_EOL;

The code above produces the output below:

18° 54′ 41″ -155° 40′ 42″
18° 54' 41" N, 155° 40' 42" W

Decimal Minutes

This format is commonly used in the Geocaching community.

<?php

use Location\Coordinate;
use Location\Formatter\Coordinate\DecimalMinutes;

$coordinate = new Coordinate(43.62310, -70.20787); // Portland Head Light, ME, USA

$formatter = new DecimalMinutes();

echo $coordinate->format($formatter) . PHP_EOL;

$formatter->setSeparator(", ")
    ->useCardinalLetters(true)
    ->setUnits(DecimalMinutes::UNITS_ASCII);

echo $coordinate->format($formatter) . PHP_EOL;

The code above produces the output below:

43° 37.386′ -070° 12.472′
43° 37.386' N, 070° 12.472' W

GeoJSON

<?php

use Location\Coordinate;
use Location\Formatter\Coordinate\GeoJSON;

$coordinate = new Coordinate(18.911306, -155.678268); // South Point, HI, USA

echo $coordinate->format(new GeoJSON());

The code above produces the output below:

{"type":"Point","coordinates":[-155.678268,18.911306]}

Polylines

You can format a polyline in different styles.

GeoJSON

<?php

use Location\Coordinate;
use Location\Polyline;
use Location\Formatter\Polyline\GeoJSON;

$polyline = new Polyline;
$polyline->addPoint(new Coordinate(52.5, 13.5));
$polyline->addPoint(new Coordinate(62.5, 14.5));

$formatter = new GeoJSON;

echo $formatter->format($polyline);

The code above produces the output below:

{"type":"LineString","coordinates":[[13.5,52.5],[14.5,62.5]]}

Polygons

You can format a polygon in different styles.

GeoJSON

<?php

use Location\Coordinate;
use Location\Polygon;
use Location\Formatter\Polygon\GeoJSON;

$polygon = new Polygon;
$polygon->addPoint(new Coordinate(10, 20));
$polygon->addPoint(new Coordinate(20, 40));
$polygon->addPoint(new Coordinate(30, 40));
$polygon->addPoint(new Coordinate(30, 20));

$formatter = new GeoJSON;

echo $formatter->format($polygon);

The code above produces the output below:

{"type":"Polygon","coordinates":[[20,10],[40,20],[40,30],[20,30]]}

Parsing and Input

Coordinates Parser

phpgeo comes with a parser for several types of coordinate formats. The parser works as a factory which creates an instance of the Coordinate class.

Supported Formats

Decimal Degrees with or without cardinal letters, with or without a comma as separator, with or without whitespace between values and cardinal letters:

52.5, 13.5
52.5 13.5
-52.5 -13.5
52.345 N, 13.456 E
N52.345 E13.456

Decimal Minutes with or without cardinal letters, with or without degree and minute signs, with or without a comma as separator, with or without whitespace between values and cardinal letters:

N52° 12.345, E13° 34.567
52° 12.345′ N, E13° 34.567′ E
52 12.345, 013 34.567
-52 12.345, -013 34.567

The unit test shows some more examples.

Example

use Location\Factory\CoordinateFactory;
use Location\Formatter\Coordinate\DecimalDegrees;

require_once __DIR__ . '/vendor/autoload.php';

$point = CoordinateFactory::fromString('52° 13.698′ 020° 58.536′');

echo $point->format(new DecimalDegrees());

The code above produces the output below:

52.22830 20.97560