mjaschen / phpgeo Goto Github PK
View Code? Open in Web Editor NEWSimple Yet Powerful Geo Library for PHP
Home Page: https://phpgeo.marcusjaschen.de
License: MIT License
Simple Yet Powerful Geo Library for PHP
Home Page: https://phpgeo.marcusjaschen.de
License: MIT License
Hello @mjaschen great work! I've been getting an ErrorException in line 148 of the Simplify.php file (when using the simplify method for a polyline object); Im making sure i'm only adding valid coordinates to the polyline and making sure no points are sent repeatedly.
Trying to search for a possible solution on the Simplify.php file, the error seems to happen when the function getPerpendicularDistance tries to find a length for two points on a line (the line provided as a parameter for the function contains two identical set of coordinates, even when the points provided for the Polyline were all different coordinates).
I've provided a set of coordinates that will trigger this exception; it won't happen if the parameter on the simplify method is a value higher than 2 (but this would be no solution as a different set of points could trigger it for a higher value). If you remove the last point from the array the exception will not be triggered.
$arr = [
[20.6579781231, -103.422906054] ,
[20.6580106449, -103.422897337] ,
[20.6580357067, -103.422887027] ,
[20.6580530573, -103.422873113] ,
[20.6580754789, -103.422858864] ,
[20.6581169274, -103.422843861] ,
[20.6581701944, -103.422823409] ,
[20.6582261855, -103.422804549] ,
[20.6582879601, -103.422781583] ,
[20.6583917403, -103.422747897] ,
[20.6584564535, -103.422721072] ,
[20.6585244273, -103.422692896] ,
[20.6586065208, -103.422658867] ,
[20.6586790699, -103.422628794] ,
[20.6587552535, -103.422597214] ,
[20.6588130308, -103.422573891] ,
[20.6588720341, -103.42255021] ,
[20.6589324369, -103.422525967] ,
[20.6590027634, -103.422497741] ,
[20.6590702995, -103.422468988] ,
[20.6591201277, -103.422444292] ,
[20.6591365207, -103.422436166] ,
[20.6591257477, -103.422441506] ,
[20.6591381119, -103.422435378] ,
[20.6592482509, -103.42239942] ,
[20.6592598032, -103.422395672] ,
[20.6592684096, -103.42239288] ,
[20.659233168, -103.422404313] ,
[20.6592154847, -103.42241005] ,
[20.6592024446, -103.422414281] ,
[20.6592397671, -103.422538089] ,
[20.6592234224, -103.422524845] ,
[20.6592450058, -103.422512105] ,
[20.6592722051, -103.422502633] ,
[20.6594071957, -103.422540268] ,
[20.6594734127, -103.42251244] ,
[20.6596607482, -103.422478996] ,
[20.6597573077, -103.42242334] ,
[20.6598714693, -103.422378581] ,
[20.6600107346, -103.422340276] ,
[20.6601370663, -103.422289965] ,
[20.6602900948, -103.422230188] ,
[20.6604063622, -103.422165179] ,
[20.660509254, -103.422112257] ,
[20.6606362708, -103.422059897] ,
[20.6607423011, -103.42200584] ,
[20.660834149, -103.421968132] ,
[20.6608913904, -103.421965255] ,
[20.660888676, -103.421957729] ,
[20.6608924298, -103.421968137] ,
[20.6608892495, -103.421959319] ,
[20.6608915012, -103.421965562] ,
[20.6608967866, -103.421980217] ,
[20.6608905586, -103.421962949] ,
[20.6608862009, -103.421950866] ,
[20.6608818429, -103.421938783] ,
[20.6608846513, -103.421946569] ,
[20.6608818429, -103.421938783] ,
[20.6610598314, -103.421866543] ,
[20.6610790881, -103.421889792]
];
$polyline = new Polyline();
foreach($arr as $point){
$polyline->addPoint(new Coordinate($point[0], $point[1]));
}
$processor = new \Location\Processor\Polyline\Simplify($polyline);
$simplified = $processor->simplify(2);
Thank you in advance for your help.
If we simplify a line, we usually do it for plotting the line on a map. This means that ideally, we would like to express the tolerance in terms of pixels on the map, not in kilometers. Since maps usually use the Mercator projection, there is not a simply linear correlation between the two.
So if accuracy is a concern, we would add a pixel-distance calculation. Otherwise, we could simply use the degrees to calculate a 'degrees distance' (perhaps with a crude cos(lattitude) correction, as to speed things up.
I like to calculate Bounds from a center point + distance to edge.
A pull request is made: #60
The CI fails but I think it failed before my changes as well because Phive requires PHP 7.1 and PHP 7.0 is tested.
I need any solution very urgently. Any help ?
- The requested package mjaschen/phpgeo No version set (parsed as 1.0.0) is
satisfiable by mjaschen/phpgeo[No version set (parsed as 1.0.0)] but these confl
ict with your requirements or minimum-stability.
Would be good to have support of GeoJSON as input data, eg. integration with jmikola/geojson could do the trick.
Hello,
I am trying to compute the extent ((latMin, latMax), (lngMin, lngMax))
, from a point (Coordinate
object) and a distance.
Is there an easy way to do that ? I am not familiar with GPS coordinates yet.
Thank for your time.
Given you have two Coordinates:
you'd like to know the shortest possible right angle to reach the Point2 from Point1
This would be possible by determining the point in the NorthWest corner (Point3) and calculate the distances Point1<->Point3 and Point2<->Point3.
As the sortest possible distances should be calculated, there has to be a check before: If Point1 is in NorthWest of Point2, the shortest directions are to go south and east.
Point1 in reference to Point2 | Directions |
---|---|
North | South |
East | West |
South | North |
West | East |
NorthWest | South, East |
NorthEast | South, West |
SouthWest | North, East |
SouthEast | North, West |
The only real new logic would be this determination.
The determining of Point3 could be done via the class Bounds
, the calculation of the distances via the class Coordinate
.
What do you think about this feature? If something is unclear, please ask me. :)
What do you think about to move the code to PHP7? If it seems legit, we will need create a v2.x.
PSR-12 sniffs are currently disabled as missing class constant visibility would lead to warnings.
It can be safely enabled as soon as we require PHP 7.1 as the minimum PHP version.
Please what can I use this library for in real life scenario.
I know I can use it to get distance of coordinate from a point... But I need to know more I can use it for...
Thanks...
This library can calculate perpendicular distance between point and great circle passing trough two points.
It can calculate distance between two points.
What about a line segment? Perpendicular distance may not exists between point and line segment on great circle -> how to check that?
That can be useful when calculating minimum distance between point and line.
Thanks.
It would be nice to see some sort of function with which a coordinate could be moved in a certain direction and distance, e.g.:
$point =new Coordinate(19.820664, -155.468066);
$point->move(45, 5000); // Move $point to the east over 5 km
A fmod()
calculation fails on HHVM. Probably it's a floating point problem, we need to investigate.
Travis build page: https://travis-ci.org/mjaschen/phpgeo/jobs/115529491
There was 1 failure:
1) Location\Bearing\BearingSphericalTest::testIfCalculateFinalBearingNorthernWorksAsExpected
Failed asserting that 360 matches expected 0.0.
/home/travis/build/mjaschen/phpgeo/tests/Location/Bearing/BearingSphericalTest.php:96
Hello,
I've been getting an ErrorException in line 206 of the BearingEllipsoidal.php file.
It would be nice to have a method in the Polygon
class, which computes and returns the center of all coordinates.
Is this something you would be interested in?
See http://tutorialspots.com/php-how-to-determine-the-center-of-a-polygon-637.html
An algorithm for calculating the similarity between two given polylines should be implemented.
Idea:
Sounds reasonable?
We can use Composer's autoloader as a replacement.
Sorry for the newbee question but when i am using the Distance calculation it provides me some false values. Went through the documentation but could not find some hint.
this is the function call:
$p1 = new \Location\Coordinate($point1_lat,$point1_long);
$p2 = new \Location\Coordinate($point2_lat,$point2_long);
$meters = $p1->getDistance($p2, new \Location\Distance\Vincenty());
and the result (sorry for the json encapsulation) is:
"distance": "4597208.7 Location\Coordinate Object\n(\n [lat:protected] => 16.1398995\n [lng:protected] => 48.0313793\n [ellipsoid:protected] => Location\Ellipsoid Object\n (\n [name:protected] => World Geodetic System 1984\n [a:protected] => 6378137\n [f:protected] => 298.257223563\n )\n\n)\n Location\Coordinate Object\n(\n [lat:protected] => 48.4664936\n [lng:protected] => 16.3988242\n [ellipsoid:protected] => Location\Ellipsoid Object\n (\n [name:protected] => World Geodetic System 1984\n [a:protected] => 6378137\n [f:protected] => 298.257223563\n )\n\n)\n"
is it a bug or is there a need to set unit system or is it just "stupid me"
Hi.
i using phpgeo for get nearby locations and everything works fine on my local. but on my server it returns this error:
Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Latitude value must be numeric -90.0 .. +90.0' in /home/jaajim/public/public/plugins/jaajim-api/Location/Coordinate.php on line 56
...
$ php -v
PHP 5.5.9-1ubuntu4.5
...
you can see the full error in this api call:
https://jaajim.com/api/v1/nearby_locations?lat=35.7001673&lng=51.4056248&radius=2000
thanks for your great job
Hi, I was doing a little bit of domain research for a side project of mine, and I noticed your library: it looks nice! :)
While reading the code, I noticed the "Coordinate" class and wondered if it shouldn't be named "Coordinates" (plural) as it represents a pair of coordinates(latitude and longitude, plus an ellipsoid).
Sorry for opening an issue for a single character, but I thought it could've been a possible item for the next major release.
Thanks!
Hi,
I just want to first off say thanks for making such a nice library, I played around with it a bit and It's definitely I want to use. Unfortunately due to the GPL license it seems that including within our codebase at work will effectively cause us to be violation of the GPL unless we open source our codebase. Considering we are a tech startup, this isn't an option.
I don't have any issues contributing any changes changes back to open source which LGPL enforces but forcing to open source our code base is a deal breaker for us.
Hi there,
I haven't studied the Douglas-Peucker algorithm in details, but if I execute the simplification algorithm multiple times, the polyline reduces/smoothes more and more, although the algorithm tolerance is still unchanged.
// 1 meter tolerance
$processor = new SimplifyDouglasPeucker(1);
$polyline = $processor->simplify($polyline);
echo sizeof($polyline->getPoints());
echo "<br>";
$polyline = $processor->simplify($polyline);
echo sizeof($polyline->getPoints());
echo "<br>";
$polyline = $processor->simplify($polyline);
echo sizeof($polyline->getPoints());
Shouldn't it be constant?
I want to use PHPGeo for simplifying lines in geojson files.
PHP has a precision set to 8 (Leaving 6 decimals for the coordinates)
I add points to a new Polyline with addPoint and new Coordinate.
$line = new Polyline;
foreach ($feature['geometry']['coordinates'] as $coordA){
$line->addPoint(new Coordinate($coordA[1],$coordA[0]));
}
I.e. the first coordinates from $feature['geometry']['coordinates'] are
Lng: 15.640289
Lat: 60.604169
For debugging I'm outputting to my html with:
$formatter = new GeoJSON;
echo var_dump($line->getPoints()[0]).'<br>';
echo $line->format(new GeoJSON()).'<br>';
The var dump on the points shows that the Polyline does indeed only have 6 decimals.
But the echo on the results from the format shows Lng and Lat with this amount of decimals:
Lng: 15.6402892857124840020333067514002323150634765625
Lat: 60.6041694346744890253830817528069019317626953125
Which defeats the whole purpose of my simplification goal. As I save more bandwidth by just removing decimals. I don't want precision on subatomic levels.
Edit: Fixed some typos. Was in a hurry when I wrote it.
I don't see the LICENSE file on your project, although composer.json indicates it's MIT. Please add it.
I see that you credit GPL licensed software, so maybe the license should be GPL.
I tried a straight actual GPS track from real device and calculated distance to be 128Km and by processing each coordinate individually using polyline method it comes out to be 97.2
composer.json
Good afternoon.
Put through composer require mjaschen/phpgeo (php 7.2).
I try to use an example from the description
`<?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;
`
I receive an error.
Uncaught Error: Call to a member function calculateDestination() on null in ...
But all other functions work.
What could be wrong?
Thanks.
Want to Simplify a GPX track, which includes not only lat+lon but also timestamps and other properties. After simplification, I want to retain these additional properties (most likely only the timestamp, the others need to be recalculated).
Looking at the documentation: https://phpgeo.marcusjaschen.de/Transformations_and_Processing/Simplifying_a_Polyline.html
How can I create a Polyline to be used by Simplify, which includes not only lat+lon, but additional properties? A la
$polyline->addPoint(new Coordinate($point['lat'], $point['lon']), $gpxDetails);
Alternatively, can you make it possible to retain the original array keys of the Polyline?
(e.g. $simplified->getPoints(): [ 0 => [...], 3 => [...], 9 => [...] ]
)
PS. the Github example for Simplify does not work, the one in the documentation does.
Why can't I simplify Polygon, but I can PolyLine?
I get Longitude value must be numeric -180.0 .. +180.0 (given: 180)
and looks like I should be able to put 180, right?
This is because in <
instead of <=
Line 177 in 3a03fe3
Have you ever considered to integrate https://trac.osgeo.org/geos like https://geophp.net/geos.html did?
Geophp seams very obsolete, with poor Composer and OOP support, while GEOS have a lot of useful methods, like touches, intersects, crosses, etc...
Circle is missing, though, but circle can be solved easily in terms of calculating distance, or checking weather circle touches/intersects/crosses/etc... some other geo object...
What do you think?
Example Google Maps Area Calculator - https://www.daftlogic.com/projects-google-maps-area-calculator-tool.htm
Hi. Thanks for project. Very nice and powerfull instrument! But i have some trouble:
getDistance($coordinate1, $coordinate2); ?>GOT:
Fatal error: Class 'Location\Coordinate' not found in /var/www/html/phpgeo/vendor/index.php on line 8
PHP Version 5.6.21
if ($distanceMax > $this->tolerance) {
$lineSplitFirst = array_slice($line, 0, $index);
$lineSplitSecond = array_slice($line, $index, $lineSize);
$resultsSplit1 = $this->douglasPeucker($lineSplitFirst);
$resultsSplit2 = $this->douglasPeucker($lineSplitSecond);
array_pop($resultsSplit1);
return array_merge($resultsSplit1, $resultsSplit2);
}
I think $resultsSplit1
's last point shouldn't be dropped because $lineSplitFirst
already only contains [$line[0],..., $line[$index-1]]
because array_slice
's second argument isn't inclusive. array_pop
causes loose the point whose index is $index-1
.
This feature would be great to help debug and visualize the calculated distance
Maybe something like ->geFromPoint()
?
Hi.
I had PHP 7.0 and it show a error:
mod_fcgid: stderr: PHP Parse error: syntax error, unexpected ':', expecting ';' or '{' in .../vendor/mjaschen/phpgeo/src/Location/Coordinate.php on line 73
,
Then I updated it to PHP 7.2 and the error disappeared.
Regards
Hello,
Thanks for this great library !
I'm facing this issue with version 1.3.5 and php cli version 5.5.9-1ubuntu4.14
$vincenty = new \Location\Distance\Vincenty();
$distance = $vincenty->getDistance(
new \Location\Coordinate(0, 0),
new \Location\Coordinate(0, 0.1)
);
PHP Warning: Division by zero in /home/.../vendor/mjaschen/phpgeo/src/Location/Distance/Vincenty.php on line 86
Any idea ?
Would it make sense to loosen the checks for lat -90..90 and lng -180..180 by building a "enable-wrap" option?
The world is round. It does not end at the dateline. However, most flat representations of the earth only extend up to 180 east and west longitude. This makes it difficult to visualize areas that span across the dateline, or routes that traverse the Pacific Ocean. It is possible to visualize a world map extending seamlessly beyond the dateline. By enabling wraparound on a map, the eastern and western hemispheres wrap around each other forming a continuous map, giving the impression that the map is endless. Panning a map becomes similar to spinning a globe.
quote from https://developers.arcgis.com/android/10-2/guide/enable-wrap-around.htm
Is it possible to find all the objects within a specified distance from a given location?
I've been using Haversine to do this with an old php 5 class. But I'm not sure how you'd do that with this library.
The examples show how to find distance between two specific locations. But I'd like to find all the locations within X miles or km, ordered by distance. Is that possible?
I already have a populated database table with all of the locations. They are postal codes with latitude and longitude columns.
Thanks for your help!
If you look at this GeoJSON demonstration:
http://geojson.io/#id=gist:acidjazz/8cd03298ddf9bf42168a9ded77577dcf&map=9/29.9216/-94.4000
I have a line drawn near Lake Charles, and a point set near Kingwood, about 120 miles away.
The following code results in 21,989 meters for those coordinates:
$perp = new PerpendicularDistance();
$line = new Line(
new Coordinate(29.888044473729,-93.580916446874),
new Coordinate(29.890583508738,-93.552272621677),
);
$point = new Coordinate(29.941561, -95.118365);
dd($perp->getPerpendicularDistance($point, $line));
This returns 21989.019190836
Now doing a point distance results in 148k-151k, ex:
dump($line->getPoint1()->getDistance($point, new Haversine()));
dd($line->getPoint2()->getDistance($point, new Haversine()));
this results in:
148298.123
151043.798
composer.json
Hi, I was wondering if you could create a tagged version in git so that I can specify the version in my composer file?
Hello,
First thank you for this awesome library !
I am trying to compute the area of a polygon.
Looking at the implementation of you Polygon
class, there is a getArea
method. Looking at the annotation, the method is giving false results.
It is still true ? Do you have any idea when it will be fixed ?
Best,
It seems that Vincenty calculation are wrong.
Distance between theses two points return 0
, it should return 1.255
meters
<?php
var_dump((new Vincenty())
->getDistance(
new Coordinate(45.306833,5.887717),
new Coordinate(45.306833,5.887733)
)); // float(0)
Using some other lib, it return the correct value.
>>> point1 = (45.306833,5.887717)
>>> point2 = (45.306833,5.887733)
>>> vincenty(point1, point2) * 1000
1.2550000000000001
Can i convert GeoJSON to phpgeo Polygon ?
The preconfigured ellipsoid WGS-84 has a double space in its name:
World␣Geodetic␣System␣␣1984
Name should read:
World␣Geodetic␣System␣1984
PHP version: 7.4.6
Library version: 3.0.0
Passing a set of non-decimal coordinates without seconds to CoordinateFactory::fromString()
will emit the following PHP warning:
PHP Warning: A non-numeric value encountered in /home/../vendor/mjaschen/phpgeo/src/Factory/CoordinateFactory.php on line 177
Reproducible by the following code:
$coordinates = CoordinateFactory::fromString('11°17′N 15°50′W');
The coordinates are for an airport in Guinea-Bissau. It should be noted that the library still calculates the correct latitude and longitude, so it works, but the warning poses a problem for anyone who converts warnings, notices, etc. into exceptions automatically (typically done when using a framework).
The warning is not emitted if you add zero-filled seconds to the coordinates:
$coordinates = CoordinateFactory::fromString('11°17′00″N 15°50′00″W');
However the coordinates in question are of a valid format, so the library shouldn't be emitting the warning.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.