Beispiel #1
0
uint64_t geohash64(double longitude, double latitude) {
    if ((fabs(longitude) > 180.0) || (fabs(latitude) > 90.0))
        return 0;

    GeoHashBits h;
    geohashEncodeWGS84(longitude, latitude, GEO_STEP_MAX, &h);
    
    return geohashAlign52Bits(h);
}
Beispiel #2
0
uint64_t geohash_decode64(char* buf) {
    double coords[2][2] = { { -90.0, 90.0 }, 
                            { -180.0, 180.0 } };
    int bits[] = { 16, 8, 4, 2, 1 };
    int flip = 1;

    for (int i = 0; i < 11; i++) {
        char* pch = strchr(geoalphabet, buf[i]);
        if (pch == NULL) return 0;
        int pos = pch - geoalphabet;
        for (int j = 0; j < 5; j++) {
            coords[flip][((pos & bits[j]) > 0) ? 0 : 1] = (coords[flip][0] + coords[flip][1]) / 2.0;
            flip = !flip;
        }
    }

    GeoHashBits hash;
    geohashEncodeWGS84(*coords[1,1], *coords[1,0], GEO_STEP_MAX, &hash);
    return geohashAlign52Bits(hash);
}
Beispiel #3
0
bool ssdb_geo_set(
		SSDBSock *ssdb_sock,
		char *key,
		int key_len,
		char *member_key,
		int member_key_len,
		double latitude,
		double longitude,
		INTERNAL_FUNCTION_PARAMETERS) {
	GeoHashBits hash;
	if (!geohashEncodeWGS84(latitude, longitude, GEO_STEP_MAX, &hash)) {
		return false;
	}

	char *member_score_str = NULL, *cmd = NULL;
	GeoHashFix52Bits bits = geohashAlign52Bits(hash);
	int member_score_str_len = spprintf(&member_score_str, 0, "%lld", bits);
	int key_free = ssdb_key_prefix(ssdb_sock, &key, &key_len);
	int cmd_len = ssdb_cmd_format_by_str(ssdb_sock, &cmd, ZEND_STRL("zset"), key, key_len, member_key, member_key_len, member_score_str, member_score_str_len, NULL);

	efree(member_score_str);
	if (key_free) efree(key);
	if (0 == cmd_len) return false;

	if (ssdb_sock_write(ssdb_sock, cmd, cmd_len) < 0) {
		efree(cmd);
		return false;
	}
	efree(cmd);

	SSDBResponse *ssdb_response = ssdb_sock_read(ssdb_sock);
	if (ssdb_response == NULL || ssdb_response->status != SSDB_IS_OK) {
		ssdb_response_free(ssdb_response);
		return false;
	}

	ssdb_response_free(ssdb_response);
	RETVAL_LONG(bits);

	return true;
}
Beispiel #4
0
static SSDBGeoList *ssdb_geo_member_box(SSDBGeoObj *ssdb_geo_obj, GeoHashBits hash) {
    GeoHashFix52Bits min, max;

    min = geohashAlign52Bits(hash);
    hash.bits++;
    max = geohashAlign52Bits(hash);

    char *score_start = NULL;
    int score_start_len = spprintf(&score_start, 0, "%lld", min);

    char *score_end = NULL;
    int score_end_len = spprintf(&score_end, 0, "%lld", max);

    char *cmd = NULL;
	int cmd_len = 0, key_free = 0;

	key_free = ssdb_key_prefix(ssdb_geo_obj->ssdb_sock, &ssdb_geo_obj->key, &ssdb_geo_obj->key_len);
	cmd_len = ssdb_cmd_format_by_str(ssdb_geo_obj->ssdb_sock,
			&cmd, ZEND_STRL("zscan"),
			ssdb_geo_obj->key,
			ssdb_geo_obj->key_len,
			"",
			0,
			score_start,
			score_start_len,
			score_end,
			score_end_len,
			ssdb_geo_obj->limit_str,
			ssdb_geo_obj->limit_str_len,
			NULL);

	efree(score_start);
	efree(score_end);
	if (key_free) efree(ssdb_geo_obj->key);
	if (0 == cmd_len) return NULL;

	if (ssdb_sock_write(ssdb_geo_obj->ssdb_sock, cmd, cmd_len) < 0) {
		efree(cmd);
		return NULL;
	}
	efree(cmd);

	SSDBResponse *ssdb_response = ssdb_sock_read(ssdb_geo_obj->ssdb_sock);
	if (ssdb_response == NULL
			|| ssdb_response->status != SSDB_IS_OK
			|| ssdb_response->num % 2 != 0) {
		ssdb_response_free(ssdb_response);
		return NULL;
	}

	//创建链表
	SSDBGeoList *l = ssdb_geo_list_create();
	if (l == NULL) {
		return NULL;
	}

	l->free = free;

	double latlong[2] = {0};
	int i = 1;
	bool err = false;

	SSDBResponseBlock *ssdb_response_block = ssdb_response->block;
	while (ssdb_response_block != NULL) {
		if (0 == i % 2) {
			if (!decodeGeohash(atoll(ssdb_response_block->data), latlong)) {
				err = true;
				break;
			}

			SSDBGeoPoint *p   = malloc(sizeof (SSDBGeoPoint));
			p->member_key_len = ssdb_response_block->prev->len;
			p->member         = estrndup(ssdb_response_block->prev->data, ssdb_response_block->prev->len);
			p->dist           = 0.0;
			p->latitude       = latlong[0];
			p->longitude      = latlong[1];

			ssdb_geo_list_add_tail_node(l, p);
		}
		ssdb_response_block = ssdb_response_block->next;
		i++;
	}

	if (err || 0 == l->num) {
		ssdb_geo_list_destory(l);
		l = NULL;
	}

	ssdb_response_free(ssdb_response);
    return l;
}