Commit 5e46e8a5 authored by antirez's avatar antirez
Browse files

Geo: removed useless functions, Marcatore coordinates, bool usage

parent 7f4ac3d1
......@@ -43,38 +43,23 @@
* -----------------
*/
bool geohashGetCoordRange(uint8_t coord_type, GeoHashRange *lat_range,
GeoHashRange *long_range) {
switch (coord_type) {
case GEO_WGS84_TYPE: {
/* These are constraints from EPSG:900913 / EPSG:3785 / OSGEO:41001 */
/* We can't geocode at the north/south pole. */
lat_range->max = 85.05112878;
lat_range->min = -85.05112878;
long_range->max = 180.0;
long_range->min = -180.0;
break;
}
case GEO_MERCATOR_TYPE: {
lat_range->max = 20037726.37;
lat_range->min = -20037726.37;
long_range->max = 20037726.37;
long_range->min = -20037726.37;
break;
}
default: { return false; }
}
return true;
void geohashGetCoordRange(GeoHashRange *lat_range, GeoHashRange *long_range) {
/* These are constraints from EPSG:900913 / EPSG:3785 / OSGEO:41001 */
/* We can't geocode at the north/south pole. */
lat_range->max = 85.05112878;
lat_range->min = -85.05112878;
long_range->max = 180.0;
long_range->min = -180.0;
}
bool geohashEncode(GeoHashRange *lat_range, GeoHashRange *long_range,
double latitude, double longitude, uint8_t step,
GeoHashBits *hash) {
int geohashEncode(GeoHashRange *lat_range, GeoHashRange *long_range,
double latitude, double longitude, uint8_t step,
GeoHashBits *hash) {
uint8_t i;
if (NULL == hash || step > 32 || step == 0 || RANGEPISZERO(lat_range) ||
RANGEPISZERO(long_range)) {
return false;
return 0;
}
hash->bits = 0;
......@@ -82,7 +67,7 @@ bool geohashEncode(GeoHashRange *lat_range, GeoHashRange *long_range,
if (latitude < lat_range->min || latitude > lat_range->max ||
longitude < long_range->min || longitude > long_range->max) {
return false;
return 0;
}
for (i = 0; i < step; i++) {
......@@ -108,38 +93,31 @@ bool geohashEncode(GeoHashRange *lat_range, GeoHashRange *long_range,
hash->bits <<= 1;
hash->bits += lat_bit;
}
return true;
return 1;
}
bool geohashEncodeType(uint8_t coord_type, double latitude, double longitude,
uint8_t step, GeoHashBits *hash) {
int geohashEncodeType(double latitude, double longitude, uint8_t step, GeoHashBits *hash) {
GeoHashRange r[2] = { { 0 } };
geohashGetCoordRange(coord_type, &r[0], &r[1]);
geohashGetCoordRange(&r[0], &r[1]);
return geohashEncode(&r[0], &r[1], latitude, longitude, step, hash);
}
bool geohashEncodeWGS84(double latitude, double longitude, uint8_t step,
GeoHashBits *hash) {
return geohashEncodeType(GEO_WGS84_TYPE, latitude, longitude, step, hash);
}
bool geohashEncodeMercator(double latitude, double longitude, uint8_t step,
GeoHashBits *hash) {
return geohashEncodeType(GEO_MERCATOR_TYPE, latitude, longitude, step,
hash);
int geohashEncodeWGS84(double latitude, double longitude, uint8_t step,
GeoHashBits *hash) {
return geohashEncodeType(latitude, longitude, step, hash);
}
static inline uint8_t get_bit(uint64_t bits, uint8_t pos) {
return (bits >> pos) & 0x01;
}
bool geohashDecode(const GeoHashRange lat_range, const GeoHashRange long_range,
int geohashDecode(const GeoHashRange lat_range, const GeoHashRange long_range,
const GeoHashBits hash, GeoHashArea *area) {
uint8_t i;
if (HASHISZERO(hash) || NULL == area || RANGEISZERO(lat_range) ||
RANGEISZERO(long_range)) {
return false;
return 0;
}
area->hash = hash;
......@@ -168,52 +146,45 @@ bool geohashDecode(const GeoHashRange lat_range, const GeoHashRange long_range,
(area->longitude.max + area->longitude.min) / 2;
}
}
return true;
return 1;
}
bool geohashDecodeType(uint8_t coord_type, const GeoHashBits hash,
GeoHashArea *area) {
int geohashDecodeType(const GeoHashBits hash, GeoHashArea *area) {
GeoHashRange r[2] = { { 0 } };
geohashGetCoordRange(coord_type, &r[0], &r[1]);
geohashGetCoordRange(&r[0], &r[1]);
return geohashDecode(r[0], r[1], hash, area);
}
bool geohashDecodeWGS84(const GeoHashBits hash, GeoHashArea *area) {
return geohashDecodeType(GEO_WGS84_TYPE, hash, area);
}
bool geohashDecodeMercator(const GeoHashBits hash, GeoHashArea *area) {
return geohashDecodeType(GEO_MERCATOR_TYPE, hash, area);
int geohashDecodeWGS84(const GeoHashBits hash, GeoHashArea *area) {
return geohashDecodeType(hash, area);
}
bool geohashDecodeAreaToLatLong(const GeoHashArea *area, double *latlong) {
int geohashDecodeAreaToLatLong(const GeoHashArea *area, double *latlong) {
double y, x;
if (!latlong)
return false;
if (!latlong) return 0;
y = (area->latitude.min + area->latitude.max) / 2;
x = (area->longitude.min + area->longitude.max) / 2;
latlong[0] = y;
latlong[1] = x;
return true;
return 1;
}
bool geohashDecodeToLatLongType(uint8_t coord_type, const GeoHashBits hash,
double *latlong) {
int geohashDecodeToLatLongType(const GeoHashBits hash, double *latlong) {
GeoHashArea area = { { 0 } };
if (!latlong || !geohashDecodeType(coord_type, hash, &area))
return false;
if (!latlong || !geohashDecodeType(hash, &area))
return 0;
return geohashDecodeAreaToLatLong(&area, latlong);
}
bool geohashDecodeToLatLongWGS84(const GeoHashBits hash, double *latlong) {
return geohashDecodeToLatLongType(GEO_WGS84_TYPE, hash, latlong);
int geohashDecodeToLatLongWGS84(const GeoHashBits hash, double *latlong) {
return geohashDecodeToLatLongType(hash, latlong);
}
bool geohashDecodeToLatLongMercator(const GeoHashBits hash, double *latlong) {
return geohashDecodeToLatLongType(GEO_MERCATOR_TYPE, hash, latlong);
int geohashDecodeToLatLongMercator(const GeoHashBits hash, double *latlong) {
return geohashDecodeToLatLongType(hash, latlong);
}
static void geohash_move_x(GeoHashBits *hash, int8_t d) {
......
......@@ -32,7 +32,7 @@
#define GEOHASH_H_
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdint.h>
#if defined(__cplusplus)
......@@ -43,9 +43,6 @@ extern "C" {
#define RANGEISZERO(r) (!(r).max && !(r).min)
#define RANGEPISZERO(r) (r == NULL || RANGEISZERO(*r))
#define GEO_WGS84_TYPE 1
#define GEO_MERCATOR_TYPE 2
#define GEO_STEP_MAX 26
typedef enum {
......@@ -90,28 +87,22 @@ typedef struct {
* 0:success
* -1:failed
*/
bool geohashGetCoordRange(uint8_t coord_type, GeoHashRange *lat_range,
GeoHashRange *long_range);
bool geohashEncode(GeoHashRange *lat_range, GeoHashRange *long_range,
double latitude, double longitude, uint8_t step,
GeoHashBits *hash);
bool geohashEncodeType(uint8_t coord_type, double latitude, double longitude,
uint8_t step, GeoHashBits *hash);
bool geohashEncodeMercator(double latitude, double longitude, uint8_t step,
GeoHashBits *hash);
bool geohashEncodeWGS84(double latitude, double longitude, uint8_t step,
GeoHashBits *hash);
bool geohashDecode(const GeoHashRange lat_range, const GeoHashRange long_range,
const GeoHashBits hash, GeoHashArea *area);
bool geohashDecodeType(uint8_t coord_type, const GeoHashBits hash,
GeoHashArea *area);
bool geohashDecodeMercator(const GeoHashBits hash, GeoHashArea *area);
bool geohashDecodeWGS84(const GeoHashBits hash, GeoHashArea *area);
bool geohashDecodeAreaToLatLong(const GeoHashArea *area, double *latlong);
bool geohashDecodeToLatLongType(uint8_t coord_type, const GeoHashBits hash,
double *latlong);
bool geohashDecodeToLatLongWGS84(const GeoHashBits hash, double *latlong);
bool geohashDecodeToLatLongMercator(const GeoHashBits hash, double *latlong);
void geohashGetCoordRange(GeoHashRange *lat_range, GeoHashRange *long_range);
int geohashEncode(GeoHashRange *lat_range, GeoHashRange *long_range,
double latitude, double longitude, uint8_t step,
GeoHashBits *hash);
int geohashEncodeType(double latitude, double longitude,
uint8_t step, GeoHashBits *hash);
int geohashEncodeWGS84(double latitude, double longitude, uint8_t step,
GeoHashBits *hash);
int geohashDecode(const GeoHashRange lat_range, const GeoHashRange long_range,
const GeoHashBits hash, GeoHashArea *area);
int geohashDecodeType(const GeoHashBits hash, GeoHashArea *area);
int geohashDecodeWGS84(const GeoHashBits hash, GeoHashArea *area);
int geohashDecodeAreaToLatLong(const GeoHashArea *area, double *latlong);
int geohashDecodeToLatLongType(const GeoHashBits hash, double *latlong);
int geohashDecodeToLatLongWGS84(const GeoHashBits hash, double *latlong);
int geohashDecodeToLatLongMercator(const GeoHashBits hash, double *latlong);
void geohashNeighbors(const GeoHashBits *hash, GeoHashNeighbors *neighbors);
#if defined(__cplusplus)
......
......@@ -53,33 +53,6 @@ const double MERCATOR_MIN = -20037726.37;
static inline double deg_rad(double ang) { return ang * D_R; }
static inline double rad_deg(double ang) { return ang / D_R; }
double mercator_y(double lat) {
lat = fmin(89.5, fmax(lat, -89.5));
double phi = deg_rad(lat);
double sinphi = sin(phi);
double con = ECCENT * sinphi;
con = pow((1.0 - con) / (1.0 + con), COM);
double ts = tan(0.5 * (M_PI * 0.5 - phi)) / con;
return 0 - R_MAJOR * log(ts);
}
double mercator_x(double lon) { return R_MAJOR * deg_rad(lon); }
double merc_lon(double x) { return rad_deg(x) / R_MAJOR; }
double merc_lat(double y) {
double ts = exp(-y / R_MAJOR);
double phi = M_PI_2 - 2 * atan(ts);
double dphi = 1.0;
int i;
for (i = 0; fabs(dphi) > 0.000000001 && i < 15; i++) {
double con = ECCENT * sin(phi);
dphi =
M_PI_2 - 2 * atan(ts * pow((1.0 - con) / (1.0 + con), COM)) - phi;
phi += dphi;
}
return rad_deg(phi);
}
/* You must *ONLY* estimate steps when you are encoding.
* If you are decoding, always decode to GEO_STEP_MAX (26). */
uint8_t geohashEstimateStepsByRadius(double range_meters) {
......@@ -94,31 +67,14 @@ uint8_t geohashEstimateStepsByRadius(double range_meters) {
return step > 26 ? 26 : step;
}
double geohashGetXWGS84(double x) { return merc_lon(x); }
double geohashGetYWGS84(double y) { return merc_lat(y); }
double geohashGetXMercator(double longtitude) {
if (longtitude > 180 || longtitude < -180) {
return longtitude;
}
return mercator_x(longtitude);
}
double geohashGetYMercator(double latitude) {
if (latitude > 90 || latitude < -90) {
return latitude;
}
return mercator_y(latitude);
}
int geohashBitsComparator(const GeoHashBits *a, const GeoHashBits *b) {
/* If step not equal, compare on step. Else, compare on bits. */
return a->step != b->step ? a->step - b->step : a->bits - b->bits;
}
bool geohashBoundingBox(double latitude, double longitude, double radius_meters,
double *bounds) {
if (!bounds)
return false;
int geohashBoundingBox(double latitude, double longitude, double radius_meters,
double *bounds) {
if (!bounds) return 0;
double latr, lonr;
latr = deg_rad(latitude);
......@@ -139,38 +95,28 @@ bool geohashBoundingBox(double latitude, double longitude, double radius_meters,
bounds[2] = rad_deg(max_latitude);
bounds[3] = rad_deg(max_longitude);
return true;
return 1;
}
GeoHashRadius geohashGetAreasByRadius(uint8_t coord_type, double latitude,
double longitude, double radius_meters) {
GeoHashRadius geohashGetAreasByRadius(double latitude, double longitude, double radius_meters) {
GeoHashRange lat_range, long_range;
GeoHashRadius radius = { { 0 } };
GeoHashBits hash = { 0 };
GeoHashNeighbors neighbors = { { 0 } };
GeoHashArea area = { { 0 } };
double delta_longitude, delta_latitude;
double min_lat, max_lat, min_lon, max_lon;
double bounds[4];
int steps;
if (coord_type == GEO_WGS84_TYPE) {
double bounds[4];
geohashBoundingBox(latitude, longitude, radius_meters, bounds);
min_lat = bounds[0];
min_lon = bounds[1];
max_lat = bounds[2];
max_lon = bounds[3];
} else {
delta_latitude = delta_longitude = radius_meters;
min_lat = latitude - delta_latitude;
max_lat = latitude + delta_latitude;
min_lon = longitude - delta_longitude;
max_lon = longitude + delta_longitude;
}
geohashBoundingBox(latitude, longitude, radius_meters, bounds);
min_lat = bounds[0];
min_lon = bounds[1];
max_lat = bounds[2];
max_lon = bounds[3];
steps = geohashEstimateStepsByRadius(radius_meters);
geohashGetCoordRange(coord_type, &lat_range, &long_range);
geohashGetCoordRange(&lat_range, &long_range);
geohashEncode(&lat_range, &long_range, latitude, longitude, steps, &hash);
geohashNeighbors(&hash, &neighbors);
geohashDecode(lat_range, long_range, hash, &area);
......@@ -203,14 +149,7 @@ GeoHashRadius geohashGetAreasByRadius(uint8_t coord_type, double latitude,
GeoHashRadius geohashGetAreasByRadiusWGS84(double latitude, double longitude,
double radius_meters) {
return geohashGetAreasByRadius(GEO_WGS84_TYPE, latitude, longitude,
radius_meters);
}
GeoHashRadius geohashGetAreasByRadiusMercator(double latitude, double longitude,
double radius_meters) {
return geohashGetAreasByRadius(GEO_MERCATOR_TYPE, latitude, longitude,
radius_meters);
return geohashGetAreasByRadius(latitude, longitude, radius_meters);
}
GeoHashFix52Bits geohashAlign52Bits(const GeoHashBits hash) {
......@@ -232,48 +171,27 @@ double distanceEarth(double lat1d, double lon1d, double lat2d, double lon2d) {
asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v));
}
bool geohashGetDistanceIfInRadius(uint8_t coord_type, double x1, double y1,
double x2, double y2, double radius,
double *distance) {
if (coord_type == GEO_WGS84_TYPE) {
*distance = distanceEarth(y1, x1, y2, x2);
if (*distance > radius) {
return false;
}
} else {
double xx = (x1 - x2) * (x1 - x2);
double yy = (y1 - y2) * (y1 - y2);
double dd = xx + yy;
*distance = dd;
if (dd > (radius * radius)) {
return false;
}
}
return true;
}
bool geohashGetDistanceIfInRadiusWGS84(double x1, double y1, double x2,
double y2, double radius,
double *distance) {
return geohashGetDistanceIfInRadius(GEO_WGS84_TYPE, x1, y1, x2, y2, radius,
distance);
int geohashGetDistanceIfInRadius(double x1, double y1,
double x2, double y2, double radius,
double *distance) {
*distance = distanceEarth(y1, x1, y2, x2);
if (*distance > radius) return 0;
return 1;
}
bool geohashGetDistanceSquaredIfInRadiusMercator(double x1, double y1,
double x2, double y2,
double radius,
double *distance) {
return geohashGetDistanceIfInRadius(GEO_MERCATOR_TYPE, x1, y1, x2, y2,
radius, distance);
int geohashGetDistanceIfInRadiusWGS84(double x1, double y1, double x2,
double y2, double radius,
double *distance) {
return geohashGetDistanceIfInRadius(x1, y1, x2, y2, radius, distance);
}
bool geohashVerifyCoordinates(uint8_t coord_type, double x, double y) {
int geohashVerifyCoordinates(double x, double y) {
GeoHashRange lat_range, long_range;
geohashGetCoordRange(coord_type, &lat_range, &long_range);
geohashGetCoordRange(&lat_range, &long_range);
if (x < long_range.min || x > long_range.max || y < lat_range.min ||
y > lat_range.max) {
return false;
return 0;
}
return true;
return 1;
}
......@@ -32,7 +32,6 @@
#define GEOHASH_HELPER_HPP_
#include <math.h>
#include <stdbool.h>
#include "geohash.h"
#define GZERO(s) s.bits = s.step = 0;
......@@ -50,9 +49,9 @@ typedef struct {
int GeoHashBitsComparator(const GeoHashBits *a, const GeoHashBits *b);
uint8_t geohashEstimateStepsByRadius(double range_meters);
bool geohashBoundingBox(double latitude, double longitude, double radius_meters,
int geohashBoundingBox(double latitude, double longitude, double radius_meters,
double *bounds);
GeoHashRadius geohashGetAreasByRadius(uint8_t coord_type, double latitude,
GeoHashRadius geohashGetAreasByRadius(double latitude,
double longitude, double radius_meters);
GeoHashRadius geohashGetAreasByRadiusWGS84(double latitude, double longitude,
double radius_meters);
......@@ -63,16 +62,16 @@ double geohashGetXMercator(double longtitude);
double geohashGetYMercator(double latitude);
double geohashGetXWGS84(double x);
double geohashGetYWGS84(double y);
bool geohashVerifyCoordinates(uint8_t coord_type, double x, double y);
bool geohashGetDistanceIfInRadius(uint8_t coord_type, double x1, double y1,
double x2, double y2, double radius,
double *distance);
bool geohashGetDistanceIfInRadiusWGS84(double x1, double y1, double x2,
double y2, double radius,
double *distance);
bool geohashGetDistanceSquaredIfInRadiusMercator(double x1, double y1,
double x2, double y2,
double radius,
double *distance);
int geohashVerifyCoordinates(double x, double y);
int geohashGetDistanceIfInRadius(double x1, double y1,
double x2, double y2, double radius,
double *distance);
int geohashGetDistanceIfInRadiusWGS84(double x1, double y1, double x2,
double y2, double radius,
double *distance);
int geohashGetDistanceSquaredIfInRadiusMercator(double x1, double y1,
double x2, double y2,
double radius,
double *distance);
#endif /* GEOHASH_HELPER_HPP_ */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment