SpringBoot知识体系(四)springboot整合Elasticsearch(6)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_37338761/article/details/102668103

Elasticsearch地理坐标与百度地图

想要使用百度地图,可以在百度地图的控制台免费注册,然后使用,控制台地址:http://lbsyun.baidu.com/apiconsole/center#/home
我使用的百度地图版本是v4
LBS.云服务接口文档:http://lbsyun.baidu.com/index.php?title=lbscloud/api/geodataV4

API接口初始化

BAIDU_MAP_KEY 为自己的ak,需要在控制台创建应用

    private static final String BAIDU_MAP_KEY = "aSg2jDQuYk9PaeeRqCb7rG6seU123456";

    private static final String BAIDU_MAP_GEOCONV_API = "http://api.map.baidu.com/geocoding/v3/?";

    // 百度地图API :http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding

    //http://api.map.baidu.com/geocoding/v3/?address=%E5%8C%97%E4%BA%AC%E5%B8%82%E6%B5%B7%E6%B7%80%E5%8C%BA%E4%B8%8A%E5%9C%B0%E5%8D%81%E8%A1%9710%E5%8F%B7&output=json&ak=qSg2jDQuYk9PaVBRqCb7rG6seU0gmBsT&callback=showLocation
    /**
     * POI数据管理接口
     */
    private static final String LBS_CREATE_API = "http://api.map.baidu.com/geodata/v4/poi/create";

    private static final String LBS_QUERY_API = "http://api.map.baidu.com/geodata/v4/poi/list?";

    private static final String LBS_UPDATE_API = "http://api.map.baidu.com/geodata/v4/poi/update";

    private static final String LBS_DELETE_API = "http://api.map.baidu.com/geodata/v4/poi/delete";

上传坐标

虎鲸数据管理平台 v3链接:http://lbsyun.baidu.com/data/mydata#/?_k=awsg5v

    public ServiceResult lbsUpload(BaiduMapLocation location, String title,
                                   String address,
                                   long houseId, int price,
                                   int area) {
        HttpClient httpClient = HttpClients.createDefault();
        List<NameValuePair> nvps = new ArrayList<>();
        nvps.add(new BasicNameValuePair("latitude", String.valueOf(location.getLatitude())));
        nvps.add(new BasicNameValuePair("longitude", String.valueOf(location.getLongitude())));
        nvps.add(new BasicNameValuePair("coord_type", "3")); // 百度坐标系
        nvps.add(new BasicNameValuePair("geotable_id", "1000006426"));
        // 需要在虎鲸数据管理平台 v3中创建表,除了基本的字段增加houseId、price、area
        nvps.add(new BasicNameValuePair("ak", BAIDU_MAP_KEY));
        nvps.add(new BasicNameValuePair("houseId", String.valueOf(houseId)));
        nvps.add(new BasicNameValuePair("price", String.valueOf(price)));
        nvps.add(new BasicNameValuePair("area", String.valueOf(area)));
        nvps.add(new BasicNameValuePair("title", title));
        nvps.add(new BasicNameValuePair("address", address));

        HttpPost post;
        JsonNode isjsonNode = isLbsDataExists(houseId);
        if (null!=isjsonNode) {
            List<JsonNode> nodeList =isjsonNode.findValues("pois");
            if(null!=nodeList&&!nodeList.isEmpty()) {
                JsonNode jsonNode =nodeList.get(0);
                if(null!=jsonNode.get("id")){
                    String id = jsonNode.get("id").asText();
                    nvps.add(new BasicNameValuePair("id", id));
                    post = new HttpPost(LBS_UPDATE_API);
                }else {
                    post = new HttpPost(LBS_CREATE_API);
                }

            }else {
                post = new HttpPost(LBS_CREATE_API);
            }

        } else {
            post = new HttpPost(LBS_CREATE_API);
        }

        try {
            post.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
            HttpResponse response = httpClient.execute(post);
            String result = EntityUtils.toString(response.getEntity(), "UTF-8");
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                logger.error("Can not upload lbs data for response: " + result);
                return new ServiceResult(false, "Can not upload baidu lbs data");
            } else {
                JsonNode jsonNode = objectMapper.readTree(result);
                int  status = jsonNode.get("status").asInt();
                if (status != 0) {
                    String message = jsonNode.get("message").asText();
                    logger.error("Error to upload lbs data for status: {}, and message: {}", status, message);
                    return new ServiceResult(false, "Error to upload lbs data");
                } else {
                    // int id = jsonNode.get("id").asInt();
                    return ServiceResult.success();
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ServiceResult(false);
    }

判断坐标是否存在

    private JsonNode isLbsDataExists(Long houseId) {
        HttpClient httpClient = HttpClients.createDefault();
        StringBuilder sb = new StringBuilder(LBS_QUERY_API);
        sb.append("geotable_id=").append("1000006426").append("&")
                .append("ak=").append(BAIDU_MAP_KEY).append("&")
                .append("houseId=").append(houseId).append(",").append(houseId);
        HttpGet get = new HttpGet(sb.toString());
        try {
            HttpResponse response = httpClient.execute(get);
            String result = EntityUtils.toString(response.getEntity(), "UTF-8");
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                logger.error("Can not get lbs data for response: " + result);
                return null;
            }

            JsonNode jsonNode = objectMapper.readTree(result);
            int status = jsonNode.get("status").asInt();
            if (status != 0) {
                logger.error("Error to get lbs data for status: " + status);
                return null;
            } else {
                long size = jsonNode.get("size").asLong();
                if (size > 0) {
                    return jsonNode;
                } else {
                    return null;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

移除坐标

   public ServiceResult removeLbs(Long houseId) {
        HttpClient httpClient = HttpClients.createDefault();
        List<NameValuePair> nvps = new ArrayList<>();
        nvps.add(new BasicNameValuePair("geotable_id", "1000006426"));
        nvps.add(new BasicNameValuePair("ak", BAIDU_MAP_KEY));
        nvps.add(new BasicNameValuePair("houseId", String.valueOf(houseId)));

       JsonNode isjsonNode = isLbsDataExists(houseId);
       if(null!=isjsonNode){
           List<JsonNode> nodeList =isjsonNode.findValues("pois");
           if(null!=nodeList&&nodeList.size()>0){
               Optional.ofNullable(nodeList.get(0).get("id")).ifPresent(n->{
                   String id = nodeList.get(0).get("id").asText();
                   nvps.add(new BasicNameValuePair("id", id));
               });
           }
       }
        HttpPost delete = new HttpPost(LBS_DELETE_API);
        try {
            delete.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
            HttpResponse response = httpClient.execute(delete);
            String result = EntityUtils.toString(response.getEntity(), "UTF-8");
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                logger.error("Error to delete lbs data for response: " + result);
                return new ServiceResult(false);
            }

            JsonNode jsonNode = objectMapper.readTree(result);
            int status = jsonNode.get("status").asInt();
            if (status != 0) {
                String message = jsonNode.get("message").asText();
                logger.error("Error to delete lbs data for message: " + message);
                return new ServiceResult(false, "Error to delete lbs data for: " + message);
            }
            return ServiceResult.success();
        } catch (IOException e) {
            logger.error("Error to delete lbs data.", e);
            return new ServiceResult(false);
        }
    }

通过地址获取地图坐标

   @Override
    public ServiceResult<BaiduMapLocation> getBaiduMapLocation(String city, String address) {
        String encodeAddress;

        try {
            encodeAddress = URLEncoder.encode(address, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            logger.error("Error to encode house address", e);
            return new ServiceResult<BaiduMapLocation>(false, "Error to encode hosue address");
        }

        HttpClient httpClient = HttpClients.createDefault();
        StringBuilder sb = new StringBuilder(BAIDU_MAP_GEOCONV_API);
        sb.append("address=").append(encodeAddress).append("&")
                .append("output=json&")
                .append("ak=").append(BAIDU_MAP_KEY);

        HttpGet get = new HttpGet(sb.toString());
        try {
            HttpResponse response = httpClient.execute(get);
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                return new ServiceResult<BaiduMapLocation>(false, "Can not get baidu map location");
            }

            String result = EntityUtils.toString(response.getEntity(), "UTF-8");
            JsonNode jsonNode = objectMapper.readTree(result);
            int status = jsonNode.get("status").asInt();
            if (status != 0) {
                return new ServiceResult<BaiduMapLocation>(false, "Error to get map location for status: " + status);
            } {
                BaiduMapLocation location = new BaiduMapLocation();
                JsonNode jsonLocation = jsonNode.get("result").get("location");
                location.setLongitude(jsonLocation.get("lng").asDouble());
                location.setLatitude(jsonLocation.get("lat").asDouble());
                return ServiceResult.of(location);
            }

        } catch (IOException e) {
            logger.error("Error to fetch baidumap api", e);
            return new ServiceResult<BaiduMapLocation>(false, "Error to fetch baidumap api");
        }
    }

Elasticsearch 的geoBoundingBoxQuery查询地理坐标信息

Elasticsearch的地图坐标JavaApi:
https://www.elastic.co/guide/en/elasticsearch/client/java-api/2.4/java-geo-queries.html
首先在Elasticsearch中增加索引坐标属性
例:

{
  "settings": {
    "number_of_replicas": 0,
    "number_of_shards": 5,
    "index.store.type": "niofs",
    "index.query.default_field": "title",
    "index.unassigned.node_left.delayed_timeout": "5m"
  },
  "mappings": {
    "house": {
      "dynamic": "strict",
      "_all": {
        "enabled": false
      },
      "properties": {
        "Id": {
          "type": "long"
        },
        "title": {
          "type": "text",
          "index": "analyzed",
          "analyzer": "ik_smart",
          "search_analyzer": "ik_smart"
        },
        "suggest": {
          "type": "completion"
        },
        "location": {
          "type": "geo_point"
        }
      }
    }
  }
}

可以通过postman直接post请求http://192.168.108.102:9200/test,在body中增加索引json。
然后查看head插件中是否生成成功。

java查询地理区域代码:

   public ServiceMultiResult<Long> mapQuery(MapSearch mapSearch) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.filter(QueryBuilders.termQuery(HouseIndexKey.CITY_EN_NAME,mapSearch.getCityEnName()));
        boolQueryBuilder.filter(
                geoBoundingBoxQuery("location")
                        .topLeft(mapSearch.getLeftLatitude(),mapSearch.getLeftLongitude())
                        .bottomRight(mapSearch.getRightLatitude(),mapSearch.getRightLongitude())
        );

        SearchRequestBuilder searchRequestBuilder = this.esClient.prepareSearch(INDEX_NAME)
                .setTypes(INDEX_TYPE)
                .setQuery(boolQueryBuilder)
                .addSort(HouseSort.getSortKey(mapSearch.getOrderBy()),SortOrder.valueOf(mapSearch.getOrderDirection()))
                .setFrom(mapSearch.getStart())
                .setSize(mapSearch.getSize());
        List<Long> houseIds = new ArrayList<>();
        SearchResponse response = searchRequestBuilder.get();
        if(response.status()!=RestStatus.OK){
            logger.warn("Search status is not ok for "+ searchRequestBuilder);
            return new ServiceMultiResult<>(0,houseIds);
        }
        for (SearchHit hit : response.getHits()) {
            houseIds.add(Longs.tryParse(String.valueOf(hit.getSource().get(HouseIndexKey.HOUSE_ID))));
        }
        return new ServiceMultiResult<>(response.getHits().getTotalHits(),houseIds);
    }

猜你喜欢

转载自blog.csdn.net/qq_37338761/article/details/102668103