-
Notifications
You must be signed in to change notification settings - Fork 19
Add geohashing capabilities #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Add support for geohash_encode and geohash_encode Bump extension version to 0.1.2
Codecov Report
@@ Coverage Diff @@
## master #20 +/- ##
==========================================
+ Coverage 63.09% 67.51% +4.42%
==========================================
Files 2 3 +1
Lines 439 508 +69
Branches 67 0 -67
==========================================
+ Hits 277 343 +66
- Misses 162 165 +3
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi!
Thanks for this PR, I like having this functionality. Also apologies for the large amounts of comments in this code review, but I feel these need to be addressed before I can merge this.
cheers,
Derick
geohash.h
Outdated
| Authors: Derick Rethans <github@derickrethans.nl> | | ||
| Michael Maclean <michael@no-surprises.co.uk> | | ||
| Nathaniel McHugh <nmchugh@inviqa.com> | | ||
| Marcus Deglos <marcus@deglos.com> | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These first four lines are not needed, as we didn't write any of this code.
geohash.h
Outdated
+----------------------------------------------------------------------+ | ||
| PHP Version 5/7 | | ||
+----------------------------------------------------------------------+ | ||
| Copyright (c) 1997-2016 The PHP Group | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should only be "2017" in here.
geohash.h
Outdated
| Emir Beganovic <emir@php.net> | | ||
+----------------------------------------------------------------------+ | ||
*/ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Header files should have a guard, such as done at:
https://github.com/php-geospatial/geospatial/blob/master/php_geospatial.h#L22
I just realized geo_array.h
doesn't have that either, so created a ticket: #21
geohash.h
Outdated
typedef struct IntervalStruct { | ||
double high; | ||
double low; | ||
} Interval; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current coding standard would have used "interval_struct", but it looks like this is something internal to the geohash algorithm, so should probably not be in a public header.
geohash.h
Outdated
typedef struct GeoCoordStruct { | ||
double latitude; | ||
double longitude; | ||
} GeoCoord; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto here, these should both be geo_coord - and private.
geospatial.c
Outdated
|
||
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dd|l", &lat, &lng, &precision); | ||
char* hash; | ||
hash = _geohash_encode(lat, lng, precision); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new line between declarations and code please, and none needed among the declarations.
geospatial.c
Outdated
#endif | ||
} | ||
|
||
/* {{{ string geohash_decode( [ string $geohash ] ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$geohash
is not optional here, so shouldn't have [ .. ]
geospatial.c
Outdated
|
||
array_init(return_value); | ||
add_assoc_double(return_value, "latitude", area.latitude); | ||
add_assoc_double(return_value, "longitude", area.longitude); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return of this should be a GeoJSONPoint.
php_geospatial.h
Outdated
@@ -22,7 +22,7 @@ | |||
#ifndef PHP_GEOSPATIAL_H | |||
#define PHP_GEOSPATIAL_H | |||
|
|||
#define PHP_GEOSPATIAL_VERSION "0.1.1-dev" | |||
#define PHP_GEOSPATIAL_VERSION "0.1.2" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to bump the version, this we only do when making a release. However, you probably should change it to 0.2.0-dev, as there is new functionality with this PR.
@@ -143,6 +150,8 @@ PHP_FUNCTION(vincenty); | |||
PHP_FUNCTION(rdp_simplify); | |||
PHP_FUNCTION(interpolate_linestring); | |||
PHP_FUNCTION(interpolate_polygon); | |||
PHP_FUNCTION(geohash_encode); | |||
PHP_FUNCTION(geohash_decode); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also add documentation and an example to the README.rst file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added.
README.rst
Outdated
[0]=> | ||
float(16.4) | ||
[1]=> | ||
float(48.2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get the following output:
array(2) {
'type' =>
string(5) "Point"
'coordinates' =>
array(2) {
[0] =>
double(171.02859674022)
[1] =>
double(49.674154138193)
}
}
Perhaps make the input the same as the output from above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've adjusted it but bear in mind that the output of a 12 char geohash will be a a float with 12 decimal places because of high detail level.
README.rst
Outdated
|
||
The `geohash_encode` function can be used to convert GeoJSON Point to a geohash:: | ||
|
||
$geohash = geohash_encode(array('type' => 'Point', 'coordinates' => [16.4, 48.2]), 12); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would change this to:
echo geohash_encode(array('type' => 'Point', 'coordinates' => [16.4, 48.2]), 12);
As that actually outputs, and perhaps explain the 12
as well - which I presume is the length of the returned string?
geo_lat_long.h
Outdated
double height; | ||
} geo_lat_long; | ||
|
||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit pick: misses CR at end of line.
geohash.c
Outdated
typedef struct IntervalStruct { | ||
double high; | ||
double low; | ||
} interval_struct; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you missed changing "struct IntervalStruct" to "struct interval_string" here? It's not used really, so the compiler wouldn't bitch.
geohash.c
Outdated
hash = (char*)safe_emalloc(precision, sizeof(char), 1); | ||
|
||
hash[precision] = '\0'; | ||
steps = precision*5.0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit pick: add spaces around the *
.
geo_lat_long.h
Outdated
|
||
typedef struct { | ||
double latitude; | ||
double longitude; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realise this was my mistake, but can you swap latitude and longitude, so that the order is x, y, and z ?
geo_lat_long.h
Outdated
+----------------------------------------------------------------------+ | ||
| PHP Version 7 | | ||
+----------------------------------------------------------------------+ | ||
| Copyright (c) 1997-2016 The PHP Group | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can just use "2017" here.
geospatial.c
Outdated
RETURN_FALSE; | ||
} | ||
|
||
char* hash; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be up with the other variable declarations, as in C you can't mix code and declarations.
geospatial.c
Outdated
return; | ||
} | ||
|
||
geo_lat_long area = php_geo_geohash_decode(hash); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the decoding altogether fail? With an invalid string for example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really, I've tried to break it though with utf8 chars and so on...
echo geohash_encode(array('type' => 'Point', 'coordinates' => [90, 90]), 6).PHP_EOL; | ||
echo geohash_encode(array('type' => 'Point', 'coordinates' => [16.363, 48.21]), 32).PHP_EOL; | ||
echo geohash_encode(array('type' => 'Point', 'coordinates' => [95, 95]), 6).PHP_EOL; | ||
echo geohash_encode(array('type' => 'Point', 'coordinates' => [185, 185]), 12).PHP_EOL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these numbers in the last two not out of range? Shouldn't that make it return false?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By definition of the geohashing algorithm there should always be a return AFAIK, and or everything out of bounds >180 it will return zzzzzzzzzzzz. This is the behaviour that I've seen in geohash libraries in other languages as well.
Hi! Are you still interested in working further on this? cheers, |
Hi @derickr. I didn't have time lately to finish final changes on this but will do so today or tomorrow. Thanks for your patience! Cheers |
@derickr Sorry for the long delay. I hope that's it now and that you can finally merge the code additions and release new version. Merry Christmas! |
Merged, after rebase, and some code standard changes. I've also released 0.2.0. |
I'd like to propose two new functionalities to be added to geospatial extension:
Geohash is a geocoding system invented by Gustavo Niemeyer. https://en.wikipedia.org/wiki/Geohash
There is a significant performance gain from using this extension compared to user-land libraries.
Source code is available at https://github.com/emirb/php-geohash-ext
Rather than creating a standalone extension for the sole purpose of dealing with geohashes, a mutual agreement has been met concerning merging it to the existing geospatial PHP extension.