Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
镜像
OpenAtomFoundation
pika
提交
c78502b5
pika
项目概览
镜像
/
OpenAtomFoundation
/
pika
大约 1 年 前同步成功
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
pika
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
c78502b5
编写于
2月 17, 2017
作者:
L
leviathan
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Support GEORADIUS AND GEORADIUSBYMEMBER
上级
408e9cdc
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
356 addition
and
39 deletion
+356
-39
include/pika_command.h
include/pika_command.h
+12
-10
include/pika_geo.h
include/pika_geo.h
+65
-3
src/pika_command.cc
src/pika_command.cc
+14
-2
src/pika_geo.cc
src/pika_geo.cc
+264
-23
src/pika_geohash_helper.cc
src/pika_geohash_helper.cc
+1
-1
未找到文件。
include/pika_command.h
浏览文件 @
c78502b5
...
...
@@ -166,16 +166,18 @@ const std::string kCmdNameGeoAdd = "geoadd";
const
std
::
string
kCmdNameGeoPos
=
"geopos"
;
const
std
::
string
kCmdNameGeoDist
=
"geodist"
;
const
std
::
string
kCmdNameGeoHash
=
"geohash"
;
const
std
::
string
kCmdNameGeoRadius
=
"georadius"
;
const
std
::
string
kCmdNameGeoRadiusByMember
=
"georadiusbymember"
;
typedef
pink
::
RedisCmdArgsType
PikaCmdArgsType
;
enum
CmdFlagsMask
{
kCmdFlagsMaskRW
=
1
,
kCmdFlagsMaskType
=
14
,
kCmdFlagsMaskLocal
=
16
,
kCmdFlagsMaskSuspend
=
32
,
kCmdFlagsMaskPrior
=
64
,
kCmdFlagsMaskAdminRequire
=
128
kCmdFlagsMaskType
=
28
,
kCmdFlagsMaskLocal
=
32
,
kCmdFlagsMaskSuspend
=
64
,
kCmdFlagsMaskPrior
=
128
,
kCmdFlagsMaskAdminRequire
=
255
};
enum
CmdFlags
{
...
...
@@ -189,15 +191,15 @@ enum CmdFlags {
kCmdFlagsZset
=
10
,
kCmdFlagsBit
=
12
,
kCmdFlagsHyperLogLog
=
14
,
kCmdFlagsGeo
=
16
,
kCmdFlagsNoLocal
=
0
,
//default nolocal
kCmdFlagsLocal
=
16
,
kCmdFlagsGeo
=
18
,
kCmdFlagsLocal
=
32
,
kCmdFlagsNoSuspend
=
0
,
//default nosuspend
kCmdFlagsSuspend
=
32
,
kCmdFlagsSuspend
=
64
,
kCmdFlagsNoPrior
=
0
,
//default noprior
kCmdFlagsPrior
=
64
,
kCmdFlagsPrior
=
128
,
kCmdFlagsNoAdminRequire
=
0
,
//default no need admin
kCmdFlagsAdminRequire
=
128
kCmdFlagsAdminRequire
=
255
};
...
...
include/pika_geo.h
浏览文件 @
c78502b5
...
...
@@ -12,13 +12,39 @@
/*
* zset
*/
enum
Sort
{
Asc
,
Desc
};
struct
GeoPoint
{
std
::
string
name
;
std
::
string
member
;
double
longitude
;
double
latitude
;
};
struct
NeighborPoint
{
std
::
string
member
;
double
score
;
double
distance
;
};
struct
GeoRange
{
std
::
string
member
;
double
longitude
;
double
latitude
;
double
distance
;
std
::
string
unit
;
bool
withdist
;
bool
withhash
;
bool
withcoord
;
int
option_num
;
bool
count
;
int
count_limit
;
Sort
sort
;
};
class
GeoAddCmd
:
public
Cmd
{
public:
GeoAddCmd
()
{}
...
...
@@ -35,7 +61,7 @@ public:
virtual
void
Do
();
private:
std
::
string
key_
;
std
::
vector
<
std
::
string
>
name
_
;
std
::
vector
<
std
::
string
>
member
_
;
virtual
void
DoInitial
(
PikaCmdArgsType
&
argvs
,
const
CmdInfo
*
const
ptr_info
);
};
...
...
@@ -54,8 +80,44 @@ public:
virtual
void
Do
();
private:
std
::
string
key_
;
std
::
vector
<
std
::
string
>
name_
;
std
::
vector
<
std
::
string
>
member_
;
virtual
void
DoInitial
(
PikaCmdArgsType
&
argvs
,
const
CmdInfo
*
const
ptr_info
);
};
class
GeoRadiusCmd
:
public
Cmd
{
public:
GeoRadiusCmd
()
{}
virtual
void
Do
();
private:
std
::
string
key_
;
GeoRange
range_
;
virtual
void
DoInitial
(
PikaCmdArgsType
&
argvs
,
const
CmdInfo
*
const
ptr_info
);
virtual
void
Clear
()
{
range_
.
withdist
=
false
;
range_
.
withcoord
=
false
;
range_
.
withhash
=
false
;
range_
.
count
=
false
;
range_
.
option_num
=
0
;
range_
.
count_limit
=
0
;
}
};
class
GeoRadiusByMemberCmd
:
public
Cmd
{
public:
GeoRadiusByMemberCmd
()
{}
virtual
void
Do
();
private:
std
::
string
key_
;
GeoRange
range_
;
virtual
void
DoInitial
(
PikaCmdArgsType
&
argvs
,
const
CmdInfo
*
const
ptr_info
);
virtual
void
Clear
()
{
range_
.
withdist
=
false
;
range_
.
withcoord
=
false
;
range_
.
withhash
=
false
;
range_
.
count
=
false
;
range_
.
option_num
=
0
;
range_
.
count_limit
=
0
;
}
};
#endif
src/pika_command.cc
浏览文件 @
c78502b5
...
...
@@ -392,14 +392,20 @@ void InitCmdInfoTable() {
CmdInfo
*
geoaddptr
=
new
CmdInfo
(
kCmdNameGeoAdd
,
-
4
,
kCmdFlagsWrite
|
kCmdFlagsGeo
);
cmd_infos
.
insert
(
std
::
pair
<
std
::
string
,
CmdInfo
*>
(
kCmdNameGeoAdd
,
geoaddptr
));
////GeoPos
CmdInfo
*
geoposptr
=
new
CmdInfo
(
kCmdNameGeoPos
,
-
3
,
kCmdFlags
Write
|
kCmdFlagsGeo
);
CmdInfo
*
geoposptr
=
new
CmdInfo
(
kCmdNameGeoPos
,
-
3
,
kCmdFlags
Read
|
kCmdFlagsGeo
);
cmd_infos
.
insert
(
std
::
pair
<
std
::
string
,
CmdInfo
*>
(
kCmdNameGeoPos
,
geoposptr
));
////GeoDist
CmdInfo
*
geodistptr
=
new
CmdInfo
(
kCmdNameGeoDist
,
-
3
,
kCmdFlagsWrite
|
kCmdFlagsGeo
);
cmd_infos
.
insert
(
std
::
pair
<
std
::
string
,
CmdInfo
*>
(
kCmdNameGeoDist
,
geodistptr
));
////GeoHash
CmdInfo
*
geohashptr
=
new
CmdInfo
(
kCmdNameGeoHash
,
-
3
,
kCmdFlags
Write
|
kCmdFlagsGeo
);
CmdInfo
*
geohashptr
=
new
CmdInfo
(
kCmdNameGeoHash
,
-
3
,
kCmdFlags
Read
|
kCmdFlagsGeo
);
cmd_infos
.
insert
(
std
::
pair
<
std
::
string
,
CmdInfo
*>
(
kCmdNameGeoHash
,
geohashptr
));
////GeoRadius
CmdInfo
*
georadiusptr
=
new
CmdInfo
(
kCmdNameGeoRadius
,
-
3
,
kCmdFlagsRead
|
kCmdFlagsGeo
);
cmd_infos
.
insert
(
std
::
pair
<
std
::
string
,
CmdInfo
*>
(
kCmdNameGeoRadius
,
georadiusptr
));
////GeoRadiusByMember
CmdInfo
*
georadiusbymemberptr
=
new
CmdInfo
(
kCmdNameGeoRadiusByMember
,
-
3
,
kCmdFlagsRead
|
kCmdFlagsGeo
);
cmd_infos
.
insert
(
std
::
pair
<
std
::
string
,
CmdInfo
*>
(
kCmdNameGeoRadiusByMember
,
georadiusbymemberptr
));
}
void
DestoryCmdInfoTable
()
{
...
...
@@ -795,6 +801,12 @@ void InitCmdTable(std::unordered_map<std::string, Cmd*> *cmd_table) {
////GeoHash
Cmd
*
geohashptr
=
new
GeoHashCmd
();
cmd_table
->
insert
(
std
::
pair
<
std
::
string
,
Cmd
*>
(
kCmdNameGeoHash
,
geohashptr
));
////GeoRadius
Cmd
*
georadiusptr
=
new
GeoRadiusCmd
();
cmd_table
->
insert
(
std
::
pair
<
std
::
string
,
Cmd
*>
(
kCmdNameGeoRadius
,
georadiusptr
));
////GeoRadiusByMember
Cmd
*
georadiusbymemberptr
=
new
GeoRadiusByMemberCmd
();
cmd_table
->
insert
(
std
::
pair
<
std
::
string
,
Cmd
*>
(
kCmdNameGeoRadiusByMember
,
georadiusbymemberptr
));
}
Cmd
*
GetCmdFromTable
(
const
std
::
string
&
opt
,
...
...
src/pika_geo.cc
浏览文件 @
c78502b5
...
...
@@ -4,6 +4,7 @@
// of patent rights can be found in the PATENTS file in the same directory.
#include <sstream>
#include <algorithm>
#include "slash_string.h"
#include "nemo.h"
#include "pika_geo.h"
...
...
@@ -37,7 +38,7 @@ void GeoAddCmd::DoInitial(PikaCmdArgsType &argv, const CmdInfo* const ptr_info)
res_
.
SetRes
(
CmdRes
::
kInvalidFloat
);
return
;
}
point
.
name
=
argv
[
index
+
2
];
point
.
member
=
argv
[
index
+
2
];
point
.
longitude
=
longitude
;
point
.
latitude
=
latitude
;
pos_
.
push_back
(
point
);
...
...
@@ -60,13 +61,13 @@ void GeoAddCmd::Do() {
std
::
string
str_bits
=
std
::
to_string
(
bits
);
double
previous_score
,
score
;
slash
::
string2d
(
str_bits
.
data
(),
str_bits
.
size
(),
&
score
);
s
=
db
->
ZScore
(
key_
,
iter
->
name
,
&
previous_score
);
s
=
db
->
ZScore
(
key_
,
iter
->
member
,
&
previous_score
);
if
(
s
.
ok
())
{
exist
=
true
;
}
else
if
(
s
.
IsNotFound
()){
exist
=
false
;
}
s
=
db
->
ZAdd
(
key_
,
score
,
iter
->
name
,
&
ret
);
s
=
db
->
ZAdd
(
key_
,
score
,
iter
->
member
,
&
ret
);
if
(
s
.
ok
()
&&
!
exist
)
{
count
+=
1
;
}
else
if
(
s
.
ok
()
&&
exist
)
{
...
...
@@ -87,17 +88,17 @@ void GeoPosCmd::DoInitial(PikaCmdArgsType &argv, const CmdInfo* const ptr_info)
return
;
}
key_
=
argv
[
1
];
name
_
.
clear
();
member
_
.
clear
();
size_t
pos
=
2
;
while
(
pos
<
argv
.
size
())
{
name
_
.
push_back
(
argv
[
pos
++
]);
member
_
.
push_back
(
argv
[
pos
++
]);
}
}
void
GeoPosCmd
::
Do
()
{
double
score
;
res_
.
AppendArrayLen
(
name
_
.
size
());
for
(
auto
v
:
name
_
)
{
res_
.
AppendArrayLen
(
member
_
.
size
());
for
(
auto
v
:
member
_
)
{
nemo
::
Status
s
=
g_pika_server
->
db
()
->
ZScore
(
key_
,
v
,
&
score
);
if
(
s
.
ok
())
{
double
xy
[
2
];
...
...
@@ -125,6 +126,20 @@ void GeoPosCmd::Do() {
}
}
static
double
length_converter
(
double
meters
,
std
::
string
unit
)
{
if
(
unit
==
"m"
)
{
return
meters
;
}
else
if
(
unit
==
"km"
)
{
return
meters
/
1000
;
}
else
if
(
unit
==
"ft"
)
{
return
meters
/
0.3048
;
}
else
if
(
unit
==
"mi"
)
{
return
meters
/
1609.34
;
}
else
{
return
-
1
;
}
}
void
GeoDistCmd
::
DoInitial
(
PikaCmdArgsType
&
argv
,
const
CmdInfo
*
const
ptr_info
)
{
if
(
!
ptr_info
->
CheckArg
(
argv
.
size
()))
{
res_
.
SetRes
(
CmdRes
::
kWrongNum
,
kCmdNameGeoDist
);
...
...
@@ -169,17 +184,10 @@ void GeoDistCmd::Do() {
}
double
distance
=
geohashGetDistance
(
first_xy
[
0
],
first_xy
[
1
],
second_xy
[
0
],
second_xy
[
1
]);
if
(
unit_
==
"m"
)
{
distance
=
distance
;
}
else
if
(
unit_
==
"km"
)
{
distance
=
distance
/
1000
;
}
else
if
(
unit_
==
"ft"
)
{
distance
=
distance
/
0.3048
;
}
else
if
(
unit_
==
"mi"
)
{
distance
=
distance
/
1609.34
;
}
else
{
res_
.
SetRes
(
CmdRes
::
kErrOther
,
"unsupported unit provided. please use m, km, ft, mi"
);
return
;
distance
=
length_converter
(
distance
,
unit_
);
if
(
distance
==
-
1
)
{
res_
.
SetRes
(
CmdRes
::
kErrOther
,
"unsupported unit provided. please use m, km, ft, mi"
);
return
;
}
char
buf
[
32
];
int64_t
len
=
slash
::
d2string
(
buf
,
sizeof
(
buf
),
distance
);
...
...
@@ -193,17 +201,17 @@ void GeoHashCmd::DoInitial(PikaCmdArgsType &argv, const CmdInfo* const ptr_info)
return
;
}
key_
=
argv
[
1
];
name
_
.
clear
();
member
_
.
clear
();
size_t
pos
=
2
;
while
(
pos
<
argv
.
size
())
{
name
_
.
push_back
(
argv
[
pos
++
]);
member
_
.
push_back
(
argv
[
pos
++
]);
}
}
void
GeoHashCmd
::
Do
()
{
char
*
geoalphabet
=
"0123456789bcdefghjkmnpqrstuvwxyz"
;
res_
.
AppendArrayLen
(
name
_
.
size
());
for
(
auto
v
:
name
_
)
{
c
onst
c
har
*
geoalphabet
=
"0123456789bcdefghjkmnpqrstuvwxyz"
;
res_
.
AppendArrayLen
(
member
_
.
size
());
for
(
auto
v
:
member
_
)
{
double
score
;
nemo
::
Status
s
=
g_pika_server
->
db
()
->
ZScore
(
key_
,
v
,
&
score
);
if
(
s
.
ok
())
{
...
...
@@ -237,3 +245,236 @@ void GeoHashCmd::Do() {
}
}
}
static
bool
sort_distance_asc
(
const
NeighborPoint
&
pos1
,
const
NeighborPoint
&
pos2
)
{
return
pos1
.
distance
<
pos2
.
distance
;
}
static
bool
sort_distance_desc
(
const
NeighborPoint
&
pos1
,
const
NeighborPoint
&
pos2
)
{
return
pos1
.
distance
>
pos2
.
distance
;
}
static
void
GetAllNeighbors
(
std
::
string
&
key
,
GeoRange
&
range
,
CmdRes
&
res
)
{
nemo
::
Status
s
;
double
longitude
=
range
.
longitude
,
latitude
=
range
.
latitude
,
distance
=
range
.
distance
;
int
count_limit
=
0
;
if
(
range
.
unit
==
"m"
)
{
distance
=
distance
;
}
else
if
(
range
.
unit
==
"km"
)
{
distance
=
distance
*
1000
;
}
else
if
(
range
.
unit
==
"ft"
)
{
distance
=
distance
*
0.3048
;
}
else
if
(
range
.
unit
==
"mi"
)
{
distance
=
distance
*
1609.34
;
}
else
{
res
.
SetRes
(
CmdRes
::
kErrOther
,
"unsupported unit provided. please use m, km, ft, mi"
);
return
;
}
// Search the zset for all matching points
GeoHashRadius
georadius
=
geohashGetAreasByRadiusWGS84
(
longitude
,
latitude
,
distance
);
GeoHashBits
neighbors
[
9
];
neighbors
[
0
]
=
georadius
.
hash
;
neighbors
[
1
]
=
georadius
.
neighbors
.
north
;
neighbors
[
2
]
=
georadius
.
neighbors
.
south
;
neighbors
[
3
]
=
georadius
.
neighbors
.
east
;
neighbors
[
4
]
=
georadius
.
neighbors
.
west
;
neighbors
[
5
]
=
georadius
.
neighbors
.
north_east
;
neighbors
[
6
]
=
georadius
.
neighbors
.
north_west
;
neighbors
[
7
]
=
georadius
.
neighbors
.
south_east
;
neighbors
[
8
]
=
georadius
.
neighbors
.
south_west
;
// For each neighbor (*and* our own hashbox), get all the matching
// members and add them to the potential result list.
std
::
vector
<
NeighborPoint
>
result
;
for
(
size_t
i
=
0
;
i
<
sizeof
(
neighbors
)
/
sizeof
(
*
neighbors
);
i
++
)
{
GeoHashFix52Bits
min
,
max
;
if
(
HASHISZERO
(
neighbors
[
i
]))
continue
;
min
=
geohashAlign52Bits
(
neighbors
[
i
]);
neighbors
[
i
].
bits
++
;
max
=
geohashAlign52Bits
(
neighbors
[
i
]);
std
::
vector
<
nemo
::
SM
>
sm_v
;
s
=
g_pika_server
->
db
()
->
ZRangebyscore
(
key
,
(
double
)
min
,
(
double
)
max
,
sm_v
,
false
,
false
);
if
(
!
s
.
ok
())
{
res
.
SetRes
(
CmdRes
::
kErrOther
,
s
.
ToString
());
return
;
}
// Insert into result only if the point is within the search area.
for
(
int
i
=
0
;
i
<
sm_v
.
size
();
++
i
)
{
double
xy
[
2
],
real_distance
;
GeoHashBits
hash
=
{
.
bits
=
(
uint64_t
)
sm_v
[
i
].
score
,
.
step
=
GEO_STEP_MAX
};
geohashDecodeToLongLatWGS84
(
hash
,
xy
);
if
(
geohashGetDistanceIfInRadiusWGS84
(
longitude
,
latitude
,
xy
[
0
],
xy
[
1
],
distance
,
&
real_distance
))
{
NeighborPoint
item
;
item
.
member
=
sm_v
[
i
].
member
;
item
.
score
=
sm_v
[
i
].
score
;
item
.
distance
=
real_distance
;
result
.
push_back
(
item
);
}
}
}
// If using the count opiton
if
(
range
.
count
)
{
count_limit
=
range
.
count_limit
;
}
else
{
count_limit
=
result
.
size
();
}
// If using sort option
if
(
range
.
sort
==
Asc
)
{
std
::
sort
(
result
.
begin
(),
result
.
end
(),
sort_distance_asc
);
}
else
if
(
range
.
sort
==
Desc
)
{
std
::
sort
(
result
.
begin
(),
result
.
end
(),
sort_distance_desc
);
}
// For each the result
res
.
AppendArrayLen
(
count_limit
);
for
(
int
i
=
0
;
i
<
count_limit
;
++
i
)
{
if
(
range
.
option_num
!=
0
)
{
res
.
AppendArrayLen
(
range
.
option_num
+
1
);
}
// Member
res
.
AppendStringLen
(
result
[
i
].
member
.
size
());
res
.
AppendContent
(
result
[
i
].
member
);
// If using withdist option
if
(
range
.
withdist
)
{
double
xy
[
2
];
GeoHashBits
hash
=
{
.
bits
=
(
uint64_t
)
result
[
i
].
score
,
.
step
=
GEO_STEP_MAX
};
geohashDecodeToLongLatWGS84
(
hash
,
xy
);
double
distance
=
geohashGetDistance
(
longitude
,
latitude
,
xy
[
0
],
xy
[
1
]);
distance
=
length_converter
(
distance
,
range
.
unit
);
if
(
distance
==
-
1
)
{
res
.
SetRes
(
CmdRes
::
kErrOther
,
"unsupported unit provided. please use m, km, ft, mi"
);
return
;
}
char
buf
[
32
];
int64_t
len
=
slash
::
d2string
(
buf
,
sizeof
(
buf
),
distance
);
res
.
AppendStringLen
(
len
);
res
.
AppendContent
(
buf
);
}
// If using withcoord option
if
(
range
.
withcoord
)
{
res
.
AppendArrayLen
(
2
);
double
xy
[
2
];
GeoHashBits
hash
=
{
.
bits
=
(
uint64_t
)
result
[
i
].
score
,
.
step
=
GEO_STEP_MAX
};
geohashDecodeToLongLatWGS84
(
hash
,
xy
);
char
longitude
[
32
];
int64_t
len
=
slash
::
d2string
(
longitude
,
sizeof
(
longitude
),
xy
[
0
]);
res
.
AppendStringLen
(
len
);
res
.
AppendContent
(
longitude
);
char
latitude
[
32
];
len
=
slash
::
d2string
(
latitude
,
sizeof
(
latitude
),
xy
[
1
]);
res
.
AppendStringLen
(
len
);
res
.
AppendContent
(
latitude
);
}
// If using withhash option
if
(
range
.
withhash
)
{
char
buf
[
32
];
int64_t
len
=
slash
::
d2string
(
buf
,
sizeof
(
buf
),
result
[
i
].
score
);
res
.
AppendStringLen
(
len
);
res
.
AppendContent
(
buf
);
}
}
}
void
GeoRadiusCmd
::
DoInitial
(
PikaCmdArgsType
&
argv
,
const
CmdInfo
*
const
ptr_info
)
{
if
(
!
ptr_info
->
CheckArg
(
argv
.
size
()))
{
res_
.
SetRes
(
CmdRes
::
kWrongNum
,
kCmdNameGeoRadius
);
return
;
}
size_t
argc
=
argv
.
size
();
if
(
argc
<
6
)
{
res_
.
SetRes
(
CmdRes
::
kWrongNum
,
kCmdNameGeoRadius
);
return
;
}
key_
=
argv
[
1
];
slash
::
string2d
(
argv
[
2
].
data
(),
argv
[
2
].
size
(),
&
range_
.
longitude
);
slash
::
string2d
(
argv
[
3
].
data
(),
argv
[
3
].
size
(),
&
range_
.
latitude
);
slash
::
string2d
(
argv
[
4
].
data
(),
argv
[
4
].
size
(),
&
range_
.
distance
);
range_
.
unit
=
argv
[
5
];
size_t
pos
=
6
;
while
(
pos
<
argv
.
size
())
{
if
(
!
strcasecmp
(
argv
[
pos
].
c_str
(),
"withdist"
))
{
range_
.
withdist
=
true
;
range_
.
option_num
++
;
}
else
if
(
!
strcasecmp
(
argv
[
pos
].
c_str
(),
"withhash"
))
{
range_
.
withhash
=
true
;
range_
.
option_num
++
;
}
else
if
(
!
strcasecmp
(
argv
[
pos
].
c_str
(),
"withcoord"
))
{
range_
.
withcoord
=
true
;
range_
.
option_num
++
;
}
else
if
(
!
strcasecmp
(
argv
[
pos
].
c_str
(),
"count"
))
{
range_
.
count
=
true
;
range_
.
count_limit
=
std
::
stoi
(
argv
[
++
pos
]);
}
else
if
(
!
strcasecmp
(
argv
[
pos
].
c_str
(),
"asc"
))
{
range_
.
sort
=
Asc
;
}
else
if
(
!
strcasecmp
(
argv
[
pos
].
c_str
(),
"desc"
))
{
range_
.
sort
=
Desc
;
}
else
{
res_
.
SetRes
(
CmdRes
::
kSyntaxErr
);
return
;
}
pos
++
;
}
}
void
GeoRadiusCmd
::
Do
()
{
GetAllNeighbors
(
key_
,
range_
,
this
->
res_
);
}
void
GeoRadiusByMemberCmd
::
DoInitial
(
PikaCmdArgsType
&
argv
,
const
CmdInfo
*
const
ptr_info
)
{
if
(
!
ptr_info
->
CheckArg
(
argv
.
size
()))
{
res_
.
SetRes
(
CmdRes
::
kWrongNum
,
kCmdNameGeoRadius
);
return
;
}
size_t
argc
=
argv
.
size
();
if
(
argc
<
5
)
{
res_
.
SetRes
(
CmdRes
::
kWrongNum
,
kCmdNameGeoRadius
);
return
;
}
key_
=
argv
[
1
];
range_
.
member
=
argv
[
2
];
slash
::
string2d
(
argv
[
3
].
data
(),
argv
[
3
].
size
(),
&
range_
.
distance
);
range_
.
unit
=
argv
[
4
];
size_t
pos
=
5
;
while
(
pos
<
argv
.
size
())
{
if
(
!
strcasecmp
(
argv
[
pos
].
c_str
(),
"withdist"
))
{
range_
.
withdist
=
true
;
range_
.
option_num
++
;
}
else
if
(
!
strcasecmp
(
argv
[
pos
].
c_str
(),
"withhash"
))
{
range_
.
withhash
=
true
;
range_
.
option_num
++
;
}
else
if
(
!
strcasecmp
(
argv
[
pos
].
c_str
(),
"withcoord"
))
{
range_
.
withcoord
=
true
;
range_
.
option_num
++
;
}
else
if
(
!
strcasecmp
(
argv
[
pos
].
c_str
(),
"count"
))
{
range_
.
count
=
true
;
range_
.
count_limit
=
std
::
stoi
(
argv
[
++
pos
]);
}
else
if
(
!
strcasecmp
(
argv
[
pos
].
c_str
(),
"asc"
))
{
range_
.
sort
=
Asc
;
}
else
if
(
!
strcasecmp
(
argv
[
pos
].
c_str
(),
"desc"
))
{
range_
.
sort
=
Desc
;
}
else
{
res_
.
SetRes
(
CmdRes
::
kSyntaxErr
);
return
;
}
pos
++
;
}
}
void
GeoRadiusByMemberCmd
::
Do
()
{
nemo
::
Status
s
;
double
score
;
s
=
g_pika_server
->
db
()
->
ZScore
(
key_
,
range_
.
member
,
&
score
);
if
(
s
.
ok
())
{
double
xy
[
2
];
GeoHashBits
hash
=
{
.
bits
=
(
uint64_t
)
score
,
.
step
=
GEO_STEP_MAX
};
geohashDecodeToLongLatWGS84
(
hash
,
xy
);
range_
.
longitude
=
xy
[
0
];
range_
.
latitude
=
xy
[
1
];
}
GetAllNeighbors
(
key_
,
range_
,
this
->
res_
);
}
\ No newline at end of file
src/pika_geohash_helper.cc
浏览文件 @
c78502b5
...
...
@@ -60,7 +60,7 @@ static inline double rad_deg(double ang) { return ang / D_R; }
/* This function is used in order to estimate the step (bits precision)
* of the 9 search area boxes during radius queries. */
uint8_t
geohashEstimateStepsByRadius
(
double
range_meters
,
double
lat
)
{
if
(
range_meters
==
0
)
return
26
;
if
(
range_meters
==
0
)
return
18
;
int
step
=
1
;
while
(
range_meters
<
MERCATOR_MAX
)
{
range_meters
*=
2
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录