add GeoShapeParser
This commit is contained in:
parent
fb6a8f3d02
commit
a38cb98478
@ -25,6 +25,7 @@
|
||||
#include "query/range_query_parser.h"
|
||||
#include "query/match_query_parser.h"
|
||||
#include "query/term_query_parser.h"
|
||||
#include "query/geo_shape_parser.h"
|
||||
#include <sstream>
|
||||
using namespace std;
|
||||
|
||||
@ -230,6 +231,8 @@ int Component::GetQueryWord(uint32_t &m_has_gis, string &err_msg){
|
||||
query_parser = new MatchQueryParser(m_appid, m_query["match"]);
|
||||
} else if(m_query.isMember("term")){
|
||||
query_parser = new TermQueryParser(m_appid, m_query["term"]);
|
||||
} else if(m_query.isMember("geo_shape")){
|
||||
query_parser = new GeoShapeParser(m_appid, m_query["geo_shape"]);
|
||||
}
|
||||
query_parser_res = new QueryParserRes();
|
||||
int ret = query_parser->ParseContent(query_parser_res);
|
||||
|
141
src/search_local/index_read/query/geo_shape_parser.cc
Normal file
141
src/search_local/index_read/query/geo_shape_parser.cc
Normal file
@ -0,0 +1,141 @@
|
||||
#include "geo_shape_parser.h"
|
||||
#include "../db_manager.h"
|
||||
#include <sstream>
|
||||
|
||||
const char* const POINTS ="points";
|
||||
const int GEO_PRECISION = 6;
|
||||
|
||||
GeoShapeParser::GeoShapeParser(uint32_t a, Json::Value& v)
|
||||
:appid(a),value(v)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
GeoShapeParser::~GeoShapeParser(){
|
||||
|
||||
}
|
||||
|
||||
vector<double> GeoShapeParser::splitDouble(const string& src, string separate_character)
|
||||
{
|
||||
vector<double> strs;
|
||||
|
||||
//分割字符串的长度,这样就可以支持如“,,”多字符串的分隔符
|
||||
int separate_characterLen = separate_character.size();
|
||||
int lastPosition = 0, index = -1;
|
||||
string str;
|
||||
double pos = 0;
|
||||
while (-1 != (index = src.find(separate_character, lastPosition)))
|
||||
{
|
||||
if (src.substr(lastPosition, index - lastPosition) != " ") {
|
||||
str = src.substr(lastPosition, index - lastPosition);
|
||||
pos = atof(str.c_str());
|
||||
strs.push_back(pos);
|
||||
}
|
||||
lastPosition = index + separate_characterLen;
|
||||
}
|
||||
string lastString = src.substr(lastPosition);//截取最后一个分隔符后的内容
|
||||
if (!lastString.empty() && lastString != " "){
|
||||
pos = atof(lastString.c_str());
|
||||
strs.push_back(pos);//如果最后一个分隔符后还有内容就入队
|
||||
}
|
||||
return strs;
|
||||
}
|
||||
|
||||
void GeoShapeParser::SetErrMsg(QueryParserRes* query_parser_res, string err_msg){
|
||||
log_error(err_msg.c_str());
|
||||
query_parser_res->ErrMsg() = err_msg;
|
||||
}
|
||||
|
||||
int GeoShapeParser::ParseContent(QueryParserRes* query_parser_res){
|
||||
Json::Value::Members member = value.getMemberNames();
|
||||
Json::Value::Members::iterator iter = member.begin();
|
||||
if(iter == member.end()){ // 一个geo_shape下只对应一个字段
|
||||
SetErrMsg(query_parser_res, "GeoShapeParser format error, content is null.");
|
||||
return -RT_PARSE_CONTENT_ERROR;
|
||||
}
|
||||
set<double> lat_arr;
|
||||
set<double> lon_arr;
|
||||
string fieldname = *iter;
|
||||
Json::Value field_value = value[fieldname];
|
||||
if(field_value.isMember(POINTS)){
|
||||
Json::Value points = field_value[POINTS];
|
||||
if(points.isArray()){
|
||||
for(int i = 0; i < (int)points.size(); i++){
|
||||
double lat;
|
||||
double lon;
|
||||
Json::Value geo_value = points[i];
|
||||
if(geo_value.isString()){
|
||||
string geo_str = geo_value.asString();
|
||||
vector<double> res = splitDouble(geo_str, ",");
|
||||
if(res.size() >= 2){
|
||||
lat = res[0];
|
||||
lon = res[1];
|
||||
} else {
|
||||
SetErrMsg(query_parser_res, "GeoShapeParser format error.");
|
||||
return -RT_PARSE_CONTENT_ERROR;
|
||||
}
|
||||
} else if (geo_value.isArray()){
|
||||
if(geo_value.size() >= 2){
|
||||
if(geo_value[0].isDouble()){
|
||||
lon = geo_value[0].asDouble();
|
||||
}
|
||||
if(geo_value[1].isDouble()){
|
||||
lat = geo_value[1].asDouble();
|
||||
}
|
||||
} else {
|
||||
SetErrMsg(query_parser_res, "GeoShapeParser format error.");
|
||||
return -RT_PARSE_CONTENT_ERROR;
|
||||
}
|
||||
} else if (geo_value.isObject()){
|
||||
if(geo_value.isMember("lat") && geo_value["lat"].isDouble()){
|
||||
lat = geo_value["lat"].asDouble();
|
||||
} else {
|
||||
SetErrMsg(query_parser_res, "GeoShapeParser lat format error.");
|
||||
return -RT_PARSE_CONTENT_ERROR;
|
||||
}
|
||||
if(geo_value.isMember("lon") && geo_value["lon"].isDouble()){
|
||||
lon = geo_value["lon"].asDouble();
|
||||
} else {
|
||||
SetErrMsg(query_parser_res, "GeoShapeParser lon format error.");
|
||||
return -RT_PARSE_CONTENT_ERROR;
|
||||
}
|
||||
} else {
|
||||
SetErrMsg(query_parser_res, "GeoShapeParser error, value is not string/array/object.");
|
||||
return -RT_PARSE_CONTENT_ERROR;
|
||||
}
|
||||
lat_arr.insert(lat);
|
||||
lon_arr.insert(lon);
|
||||
}
|
||||
} else {
|
||||
SetErrMsg(query_parser_res, "GeoShapeParser error, points is not a array.");
|
||||
return -RT_PARSE_CONTENT_ERROR;
|
||||
}
|
||||
} else {
|
||||
SetErrMsg(query_parser_res, "GeoShapeParser error, no points content provide.");
|
||||
return -RT_PARSE_CONTENT_ERROR;
|
||||
}
|
||||
if(lon_arr.size() > 0 && lat_arr.size() > 0){
|
||||
vector<string> gisCode = GetArroundGeoHash(*lon_arr.rbegin(), *lon_arr.begin(), *lat_arr.rbegin(), *lat_arr.begin(), GEO_PRECISION);
|
||||
if(gisCode.size() > 0){
|
||||
vector<FieldInfo> fieldInfos;
|
||||
uint32_t segment_tag = 0;
|
||||
FieldInfo fieldInfo;
|
||||
uint32_t field = DBManager::Instance()->GetWordField(segment_tag, appid, fieldname, fieldInfo);
|
||||
if (field != 0 && segment_tag == 0) {
|
||||
query_parser_res->HasGis() = 1;
|
||||
for (size_t index = 0; index < gisCode.size(); index++) {
|
||||
FieldInfo info;
|
||||
info.field = fieldInfo.field;
|
||||
info.field_type = fieldInfo.field_type;
|
||||
info.segment_tag = fieldInfo.segment_tag;
|
||||
info.word = gisCode[index];
|
||||
fieldInfos.push_back(info);
|
||||
}
|
||||
}
|
||||
if (fieldInfos.size() != 0) {
|
||||
query_parser_res->FieldKeysMap().insert(make_pair(fieldInfo.field, fieldInfos));
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
43
src/search_local/index_read/query/geo_shape_parser.h
Normal file
43
src/search_local/index_read/query/geo_shape_parser.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* Filename: geo_shape_parser.h
|
||||
*
|
||||
* Description: geo_shape_parser class definition.
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 08/05/2021
|
||||
* Revision: none
|
||||
* Compiler: gcc
|
||||
*
|
||||
* Author: zhulin, shzhulin3@jd.com
|
||||
* Company: JD.com, Inc.
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GEO_SHAPE_PARSER_H__
|
||||
#define __GEO_SHAPE_PARSER_H__
|
||||
#include "query_parser.h"
|
||||
#include "json/json.h"
|
||||
#include "geohash.h"
|
||||
|
||||
class GeoShapeParser : public QueryParser
|
||||
{
|
||||
public:
|
||||
GeoShapeParser(uint32_t a, Json::Value& v);
|
||||
~GeoShapeParser();
|
||||
int ParseContent(QueryParserRes* query_parser_res);
|
||||
|
||||
private:
|
||||
void SetErrMsg(QueryParserRes* query_parser_res, string err_msg);
|
||||
vector<double> splitDouble(const string& src, string separate_character);
|
||||
|
||||
private:
|
||||
uint32_t appid;
|
||||
Json::Value value;
|
||||
GeoPoint geo;
|
||||
double distance;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user