add GeoShapeParser
This commit is contained in:
parent
fb6a8f3d02
commit
a38cb98478
@ -25,6 +25,7 @@
|
|||||||
#include "query/range_query_parser.h"
|
#include "query/range_query_parser.h"
|
||||||
#include "query/match_query_parser.h"
|
#include "query/match_query_parser.h"
|
||||||
#include "query/term_query_parser.h"
|
#include "query/term_query_parser.h"
|
||||||
|
#include "query/geo_shape_parser.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
using namespace std;
|
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"]);
|
query_parser = new MatchQueryParser(m_appid, m_query["match"]);
|
||||||
} else if(m_query.isMember("term")){
|
} else if(m_query.isMember("term")){
|
||||||
query_parser = new TermQueryParser(m_appid, m_query["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();
|
query_parser_res = new QueryParserRes();
|
||||||
int ret = query_parser->ParseContent(query_parser_res);
|
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