最近给第三方提供接口,接口要求我们可以查询指定的圆形区域或者指定多边形区域内的数据:
提供的查询参数格式如下:
{
"KEY": "LOC",
"TYPE": "region",
"VALUE": "[[118.07572,24.87644],[118.04562,24.89767],[118.12345,24.63234]]"
},
{
"KEY": "LOC",
"TYPE": "circle",
"VALUE": "[118.07572,24.87644,1000]"
}
而且访问的数据库可能是mongo,也可能是es。
对mongo的处理如下:
// 圆形区域
String[] params = value.replaceAll("\\[","").replaceAll("]","").split(",");
LinkedList<Object> circle = new LinkedList<>();
//设置中心点
circle.addLast(new double[]{Double.parseDouble(params[0]), Double.parseDouble(params[1])});
//设置圆半径-单位(米)
circle.addLast(Double.parseDouble(params[2])/6378137.0);
MCondition mCondition = new MCondition();
mCondition.append("loc", new BasicDBObject("$geoWithin", new BasicDBObject("$centerSphere", circle)));
// 给定坐标的多边形区域
LinkedList<Object> polygon = new LinkedList<>();
String[] pointArr = value.replaceAll("\\[\\[", "").replaceAll("]]", "").replaceAll(" ", "").split("],\\[");
for (String point : pointArr) {
polygon.addLast(new double[]{Double.valueOf(point.split(",")[0]),Double.valueOf(point.split(",")[1])});
}
MCondition mCondition = new MCondition();
mCondition.append(key, new BasicDBObject("$within", new BasicDBObject("$polygon", polygon)));
以上需要的注意到是MCondition 为再次封装,使用中改造为DBObject即可,进而转化为你的个人封装。
此处不再提供mongo原生查询语句,想要原生语句打上断点然后观察(DBObject.toString())。
下面es的操作则以语句形式呈现:
"bool": {
"should": [
{
"geo_distance": {
"distance": "1000m",
"loc": {
"lat": 24.87644,
"lon": 118.07572
}
}
},
{
"geo_polygon": {
"loc": {
"points": [
{
"lat": 24.87644,
"lon": 118.07572
},
{
"lat": 24.89767,
"lon": 118.04562
},
{
"lat": 24.63234,
"lon": 118.12345
}
]
}
}
}
]
}
其他类型的区域查询请参考相关资料。