微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Elasticsearch 关于GeoShape应用小结

Elasticsearch 关于GeoShape应用小结

特别注意:ES只有一种坐标系wgs84
ES GeoShape 一共提供了4中关系

  • INTERSECTS 相交的
  • disJOINT 不相交的
  • WITHIN 在。。内
  • CONTAINS 包含
    几种关系比较好理解

分类

· 点
· 线
· 圈
· 多边形

对于点类型的储存和查询相对简单不多赘述,可以使用范围查覆盖的点,也可以用点查在某个线、圈或多边形上
代码:
Rest API

GET businessAreaShape/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "geo_shape": {
            "s_location_circle": {
              "shape": {
                "type": "point",
                "coordinates": [
                  116.311434,
                  39.909228
                ]
              },
              "relation": "contains"
            },
            "ignore_unmapped": false,
            "boost": 1
          }
        },
        {
          "geo_shape": {
            "s_location_polygon": {
              "shape": {
                "type": "point",
                "coordinates": [
                  116.311434,
                  39.909228
                ]
              },
              "relation": "contains"
            },
            "ignore_unmapped": false,
            "boost": 1
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  },
  "sort": [
    {
      "create_time": {
        "order": "asc"
      }
    }
  ]
}

JAVA Hight Level API

BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            PointBuilder pointBuilder = new PointBuilder(lng, lat);
            GeoShapeQueryBuilder shapeQueryCirleBuilder = QueryBuilders.geoShapeQuery(ShopAnalyzeAnchorMapping.SHOP_POINT_FIELD_S_LOCATION_CIRCLE, pointBuilder).relation(ShapeRelation.CONTAINS);
            boolQueryBuilder.should(shapeQueryCirleBuilder);
            GeoShapeQueryBuilder shapeQuerypolygonBuilder = QueryBuilders.geoShapeQuery(ShopAnalyzeAnchorMapping.SHOP_POINT_FIELD_S_LOCATION_polyGON, pointBuilder).relation(ShapeRelation.CONTAINS);
            boolQueryBuilder.should(shapeQuerypolygonBuilder);

            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.query(boolQueryBuilder);
            sourceBuilder.sort(ShopAnalyzeAnchorMapping.SHOP_POINT_FIELD_CREATE_TIME, SortOrder.ASC);
            //只获取ID就足够了后续所有详细信息从数据库获取
            sourceBuilder.fetchSource("k_anchor_id","");
            SearchRequest searchRequest = new SearchRequest(ANCHOR_SHAPE);
            searchRequest.source(sourceBuilder);
            SearchResponse search = getRestHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

线

暂未涉及 值得注意的是计算距离需要指定方式,ES只有两种方式一是平面二是球型。

圈(CIRCLE)

圈主要有一个中心坐标和半径组成,可以根据半径排序,可根据关系查询
代码

  • mapping
"s_location_circle" : {
    "type" : "geo_shape",
    "strategy" : "recursive"
}

我是用的是ES 5.x版本高版本"strategy" : "recursive"将被弃用

  • 插入
    直接上JAVA,重点就是这个JSON
"s_location_circle":{
"coordinates":[116.55251722897378,39.98890616238562],
"type":"circle",
"radius":"600m"
}
GET businessAreaShape/_search
{
  "query": {
    "geo_shape": {
      "s_location_circle": {
        "shape": {
          "type": "circle",
          "radius": "600.0m",
          "coordinates": [
            116.55251722897378,
            39.98890616238562
          ]
        },
        "relation": "contains"
      },
      "ignore_unmapped": false,
      "boost": 1
    }
  }
}

JAVA Hight Level API

CircleBuilder circleBuilder = new CircleBuilder();
            circleBuilder.center(lng, lat);
            distanceUnit.distance distance = new distanceUnit.distance(range, distanceUnit.METERS);
            circleBuilder.radius(distance);

            GeoShapeQueryBuilder shapeQueryBuilder = QueryBuilders.geoShapeQuery(ShopAnalyzeAnchorMapping.SHOP_POINT_FIELD_S_LOCATION_CIRCLE, circleBuilder).relation(ShapeRelation.CONTAINS);

多边形(polyGON)

  • 插入
"s_location_polygon":{"coordinates":[[[116.47311930720184,39.97367261625567],[116.46083817432645,39.97588286009428],[116.45497672470651,39.971177091927984],[116.46400149615897,39.96704145151183],[116.4741427350599,39.96811103788185],[116.47311930720184,39.97367261625567]]],"type":"polygon"}
GET businessAreaShape/_search
{
  "query": {
    "geo_shape": {
      "s_location_polygon": {
        "shape": {
          "type": "polygon",
          "orientation": "right",
          "coordinates": [
            [
              [
                116.47311930720184,
                39.97367261625567
              ],
              [
                116.46083817432645,
                39.97588286009428
              ],
              [
                116.45497672470651,
                39.971177091927984
              ],
              [
                116.46400149615897,
                39.96704145151183
              ],
              [
                116.4741427350599,
                39.96811103788185
              ],
              [
                116.47311930720184,
                39.97367261625567
              ]
            ]
          ]
        },
        "relation": "contains"
      },
      "ignore_unmapped": false,
      "boost": 1
    }
  }
}

JAVA Hight Level API

 //多边形
 	CoordinatesBuilder coordinatesBuilder = new CoordinatesBuilder();
    List<Location> boundaryPoints = locationForm.getBoundaryPoints();
    for (Location location : boundaryPoints) {
        coordinatesBuilder.coordinate(location.getLng().doubleValue(), location.getLat().doubleValue());
    }
    polygonBuilder polygonBuilder = new polygonBuilder(coordinatesBuilder);
    GeoShapeQueryBuilder shapeQueryBuilder = QueryBuilders.geoShapeQuery(ShopAnalyzeAnchorMapping.SHOP_POINT_FIELD_S_LOCATION_polyGON, polygonBuilder).relation(ShapeRelation.CONTAINS);

目前实现的功能

  1. 根据地图上画出的范围获取范围内的点位搜索;
  2. 根据点搜索在地图上画过并保存过的范围;
  3. 在地图上画范围保存是验证是否被某个范围完全包含,前提是相通的图形,不同图形不支持,也就是说圈只能判断是否有圈包含它,多边形只能判断是有多边形包含它。

目前使用经验分享于此,由于ES版本较低使用较新版本的同学可根据该版本API玩。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐