소스 검색

地名地址搜索功能完善

DESKTOP-6LTVLN7\Liumouren 2 달 전
부모
커밋
af7cd70858

BIN
doc/marge_excel_uuid-1.xlsx


BIN
doc/marge_excel_uuid-2.xlsx


BIN
doc/outPutTableHeader.xlsx


BIN
doc/tableHeader.xlsx


+ 5 - 0
pom.xml

@@ -31,6 +31,11 @@
         <java.version>17</java.version>
     </properties>
     <dependencies>
+        <dependency>
+            <groupId>org.json</groupId>
+            <artifactId>json</artifactId>
+            <version>20231013</version>
+        </dependency>
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-databind</artifactId>

+ 221 - 48
src/main/java/com/skyversation/poiaddr/addquery/AddressQueryEngine.java

@@ -9,18 +9,26 @@ import com.skyversation.poiaddr.service.AreaService;
 import com.skyversation.poiaddr.util.net.AddressNetTools;
 import com.skyversation.poiaddr.util.status.AddressLevel;
 import com.skyversation.poiaddr.util.status.AddressResultEnum;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 public class AddressQueryEngine {
 
     private static AddressQueryEngine instance = new AddressQueryEngine();
-    private AddressQueryEngine(){}
-    public synchronized static AddressQueryEngine getInstance(){
-        if(instance == null){
+
+    private AddressQueryEngine() {
+    }
+
+    public synchronized static AddressQueryEngine getInstance() {
+        if (instance == null) {
             instance = new AddressQueryEngine();
         }
         return instance;
@@ -29,8 +37,9 @@ public class AddressQueryEngine {
     private WDToken wdToken = null;
 
     public static void main(String[] args) {
-
-        AddressQueryEngine.getInstance().gdV3SearchByName("上海市青浦区徐泾镇尚茂路226弄通用昱慧苑");
+        String[] address = new String[]{"上海市青浦区未来城"};
+        AddressResult addressResult = AddressQueryEngine.getInstance().commonSearchByName(address,AddressLevel.values()[1]);
+        System.out.println(addressResult);
     }
 
     /***
@@ -44,26 +53,77 @@ public class AddressQueryEngine {
      *              5. 结果与基准数据完全一致,则使用。
      * @return
      */
-    public AddressResult commonSearchByName(String[] addrs, AddressLevel level){
-        if(addrs == null || addrs.length < 1){
+    public AddressResult commonSearchByName(String[] addrs, AddressLevel level) {
+        if (addrs == null || addrs.length < 1) {
             return null;
         }
-        for(String addr : addrs){
-            verificaData(wdjaSearchByName(addr), level);
+        AddressResult addressResult = new AddressResult();
+        List<AddressResult.ContentBean> contentBeans = new ArrayList<>();
+        for (String addr : addrs) {
+            AddressResult.ContentBean contentBean = verificaData(wdjaSearchByName(addr), level, addr);
+            if (contentBean != null) {
+                contentBeans.add(contentBean);
+                addressResult.setData(contentBeans);
+                addressResult.setCode(AddressResultEnum.WDJA_SUCCESS);
+                addressResult.setMessage("成功");
+                return addressResult;
+            }
         }
+        if (addressResult.getData() == null || addressResult.getData().size() == 0) {
+            for (String addr : addrs) {
+                AddressResult.ContentBean contentBean = verificaData(szxSearchByName(addr), level, addr);
+                if (contentBean != null) {
+                    contentBeans.add(contentBean);
+                    addressResult.setData(contentBeans);
+                    addressResult.setCode(AddressResultEnum.SZX_SUCCESS);
+                    addressResult.setMessage("成功");
+                    return addressResult;
+                }
+            }
+        }
+        if (addressResult.getData() == null || addressResult.getData().size() == 0) {
+            for (String addr : addrs) {
+                AddressResult.ContentBean contentBean = verificaData(gdSearchByName(addr), level, addr);
+                if (contentBean != null) {
+                    contentBeans.add(contentBean);
+                    addressResult.setData(contentBeans);
+                    addressResult.setCode(AddressResultEnum.GD_SUCCESS);
+                    addressResult.setMessage("成功");
+                    return addressResult;
+                }
+            }
+        }
+        if (addressResult.getData() == null || addressResult.getData().size() == 0) {
+            for (String addr : addrs) {
+                AddressResult.ContentBean contentBean = verificaData(gdV3SearchByName(addr), level, addr);
+                if (contentBean != null) {
+                    contentBeans.add(contentBean);
+                    addressResult.setData(contentBeans);
+                    addressResult.setCode(AddressResultEnum.GD_SUCCESS);
+                    addressResult.setMessage("成功");
+                    return addressResult;
+                }
+            }
+        }
+        addressResult.setCode(AddressResultEnum.RESULT_NULL);
+        addressResult.setMessage("失败");
+        return addressResult;
     }
 
     /***
      * 武大吉奥单条地名搜索
      * @param address
      */
-    public AddressResult wdjaSearchByName(String address){
+    public AddressResult wdjaSearchByName(String address) {
         System.out.println("<<<<<<<<<<----------开始武大吉奥地名地址搜索------------>>>>>>>>>>>>>");
-        if(wdToken == null || System.currentTimeMillis() - wdToken.getTime() > 36000000){
+        if (wdToken == null || System.currentTimeMillis() - wdToken.getTime() > 36000000) {
             wdToken = AddressTools.getInstance().getWDToken(Constant.WD_USER_NAME, Constant.WD_USER_PWD);
+            if(wdToken == null){
+                return null;
+            }
             wdToken.setTime(System.currentTimeMillis());
         }
-        if(wdToken == null)
+        if (wdToken == null)
             return AddressTools.getInstance().faildQuery(AddressResultEnum.NO_TOKEN, "token获取失败");
         String token = wdToken.getToken();
 
@@ -74,12 +134,12 @@ public class AddressQueryEngine {
         } catch (Exception e) {
             e.toString();
         }
-        if(body == null || body.equals("null") || !StringUtils.hasText(body))
+        if (body == null || body.equals("null") || !StringUtils.hasText(body))
             return AddressTools.getInstance().faildQuery(AddressResultEnum.RESULT_NULL, "搜索无结果");
         try {
             JSONObject json = JSONObject.parseObject(body);
             return TransfromDataTool.wdResultToResult(json);
-        } catch (Exception e){
+        } catch (Exception e) {
             return AddressTools.getInstance().faildQuery(AddressResultEnum.DATA_FROMAT_FAILD, "格式化失败");
         }
     }
@@ -89,16 +149,41 @@ public class AddressQueryEngine {
      * @param address
      * @return
      */
-    public AddressResult szxSearchByName(String address){
+    public AddressResult szxSearchByName(String address) {
         ResponseEntity response = AddressNetTools.getInstance().requestGet(Constant.SZX_URL + address, null, null);
-        String body = response.getBody() + "";
-        if(!StringUtils.hasText(body))
-            return AddressTools.getInstance().faildQuery(AddressResultEnum.RESULT_NULL, "搜索无结果");
-        try {
-            JSONObject json = JSONObject.parseObject(body);
-            return TransfromDataTool.szxResultToResult(json);
-        } catch (Exception e){
-            return AddressTools.getInstance().faildQuery(AddressResultEnum.DATA_FROMAT_FAILD, "格式化失败");
+        if (response != null) {
+            String body = response.getBody() + "";
+            if (!StringUtils.hasText(body))
+                return AddressTools.getInstance().faildQuery(AddressResultEnum.RESULT_NULL, "搜索无结果");
+            try {
+                JSONObject json = JSONObject.parseObject(body);
+                return getCjWgWgwByLoc(TransfromDataTool.szxResultToResult(json));
+            } catch (Exception e) {
+                System.err.println(e);
+                return AddressTools.getInstance().faildQuery(AddressResultEnum.DATA_FROMAT_FAILD, "格式化失败");
+            }
+        } else {
+            System.out.println("地址" + address + "未查询到数据!");
+            return null;
+        }
+    }
+
+    public AddressResult v4SearchByName(String address) {
+        ResponseEntity response = AddressNetTools.getInstance().requestGet(Constant.V4_URL + address, null, null);
+        if (response != null) {
+            String body = response.getBody() + "";
+            if (!StringUtils.hasText(body))
+                return AddressTools.getInstance().faildQuery(AddressResultEnum.RESULT_NULL, "搜索无结果");
+            try {
+                JSONObject json = JSONObject.parseObject(body);
+                return TransfromDataTool.szxResultToResult(json);
+            } catch (Exception e) {
+                System.err.println(e);
+                return AddressTools.getInstance().faildQuery(AddressResultEnum.DATA_FROMAT_FAILD, "格式化失败");
+            }
+        } else {
+            System.out.println("地址" + address + "未查询到数据!");
+            return null;
         }
     }
 
@@ -107,14 +192,19 @@ public class AddressQueryEngine {
      * @param address
      * @return
      */
-    public AddressResult gdSearchByName(String address){
+    public AddressResult gdSearchByName(String address) {
         String geoUrl = Constant.AMAP_GEO_URL + "?key=" + Constant.AMAP_KEY + "&address=" + address + "&city=" + Constant.AMAP_CITY_CODE + "&output=JSON";
         ResponseEntity response = AddressNetTools.getInstance().requestGet(geoUrl, null, null);
         String body = response.getBody() + "";
-        if(!StringUtils.hasText(body))
+        if (!StringUtils.hasText(body))
             return AddressTools.getInstance().faildQuery(AddressResultEnum.RESULT_NULL, "搜索无结果");
-        JSONObject json = JSONObject.parseObject(body);
-        return TransfromDataTool.gdResultToResult(json);
+        try {
+            JSONObject json = JSONObject.parseObject(body);
+            return getCjWgWgwByLoc(TransfromDataTool.gdResultToResult(json));
+        } catch (Exception e) {
+            System.err.println(e);
+            return AddressTools.getInstance().faildQuery(AddressResultEnum.DATA_FROMAT_FAILD, "格式化失败");
+        }
     }
 
     /***
@@ -122,14 +212,15 @@ public class AddressQueryEngine {
      * @param address
      * @return
      */
-    public AddressResult gdV3SearchByName(String address){
+    public AddressResult gdV3SearchByName(String address) {
         String geoUrl =
+//                + Constant.AMAP_SEARCH_TYPES  070500
                 Constant.AMAP_SEARCH_NAME_V3 + "?key=" + Constant.AMAP_KEY + "&types=" + Constant.AMAP_SEARCH_TYPES +
                         "&keywords=" + address + "&city=" + Constant.AMAP_CITY_CODE + "&offset=20";
         System.out.println("geoUrl:" + geoUrl);
         String body = null;
-        body = AddressNetTools.getInstance().requestGet(geoUrl,null, null).getBody() + "";
-        if(!StringUtils.hasText(body)){
+        body = AddressNetTools.getInstance().requestGet(geoUrl, null, null).getBody() + "";
+        if (!StringUtils.hasText(body)) {
             return AddressTools.getInstance().faildQuery(AddressResultEnum.RESULT_NULL, "搜索无结果");
         }
         JSONArray pois = new JSONArray();
@@ -137,19 +228,24 @@ public class AddressQueryEngine {
         pois.addAll(json.getJSONArray("pois"));
 
         int count = Integer.valueOf(json.get("count") + "");
-        if(count > 20){
-            for(int i = 2; i < (count % 20 + 1); i ++){
+        if (count > 20) {
+            for (int i = 2; i < (count % 20 + 1); i++) {
                 geoUrl =
                         Constant.AMAP_SEARCH_NAME_V3 + "?key=" + Constant.AMAP_KEY + "&types=" + Constant.AMAP_SEARCH_TYPES +
                                 "&keywords=" + address + "&city=" + Constant.AMAP_CITY_CODE + "&offset=20&page=" + i;
-                body = AddressNetTools.getInstance().requestGet(geoUrl,null, null).getBody() + "";
-                if(!StringUtils.hasText(body)){
+                body = AddressNetTools.getInstance().requestGet(geoUrl, null, null).getBody() + "";
+                if (!StringUtils.hasText(body)) {
                     return AddressTools.getInstance().faildQuery(AddressResultEnum.RESULT_AGAIN_NULL, "多次搜索无结果");
                 }
                 pois.addAll(JSONObject.parseObject(body).getJSONArray("pois"));
             }
         }
-        return TransfromDataTool.gdV3ResultToResult(pois);
+        try {
+            return getCjWgWgwByLoc(TransfromDataTool.gdV3ResultToResult(pois));
+        } catch (Exception e) {
+            System.err.println(e);
+            return AddressTools.getInstance().faildQuery(AddressResultEnum.DATA_FROMAT_FAILD, "格式化失败");
+        }
     }
 
 
@@ -158,47 +254,124 @@ public class AddressQueryEngine {
      * @param result
      * @return
      */
-    public AddressResult getCjWgWgwByLoc(AddressResult result){
-        if(result == null || result.getData() == null || result.getData().size() < 1){
+    public AddressResult getCjWgWgwByLoc(AddressResult result) {
+        if (result == null || result.getData() == null || result.getData().size() < 1) {
             return result;
         } else {
-            for(AddressResult.ContentBean content : result.getData()){
-                GeoJsonBean cjBean = AreaService.getInstance().isInCJPolygon(content.getLon(), content.getLat());
+            AreaService areaService = AreaService.getInstance();
+            for (AddressResult.ContentBean content : result.getData()) {
+                GeoJsonBean cjBean = areaService.isInCJPolygon(content.getLon(), content.getLat());
                 content.setCjJson(cjBean == null ? new JSONObject() : cjBean.getProperties());
-                GeoJsonBean gridBean = AreaService.getInstance().isInGridPolygon(content.getLon(), content.getLat());
+                GeoJsonBean gridBean = areaService.isInGridPolygon(content.getLon(), content.getLat());
                 content.setWgwJson(gridBean == null ? new JSONObject() : gridBean.getProperties());
-                GeoJsonBean wgridBean = AreaService.getInstance().isInWGridPolygon(content.getLon(), content.getLat());
+                GeoJsonBean wgridBean = areaService.isInWGridPolygon(content.getLon(), content.getLat());
                 content.setWgwJson(wgridBean == null ? new JSONObject() : wgridBean.getProperties());
             }
             return result;
         }
     }
 
-    public AddressResult.ContentBean verificaData(AddressResult result, AddressLevel level){
-        switch (level){
+    /**
+     * 1. 搜索到结果就返回第一个;
+     * 2. 搜索到结果去除行政区划后,存在包含关系,则使用;
+     * 3. 搜索到结果,数字进行分词,数字匹配则使用;
+     * 4. 搜索到结果,数字与文本均匹配,则使用;
+     * 5. 结果与基准数据完全一致,则使用。
+     *
+     * @param result
+     * @param level
+     * @return
+     */
+    public AddressResult.ContentBean verificaData(AddressResult result, AddressLevel level, String addr) {
+        switch (level) {
             case LEVEL_1 -> {
-                if(result != null && result.getData() != null && result.getData().size() > 0){
+                if (result != null && result.getData() != null && result.getData().size() > 0) {
                     return result.getData().get(0);
                 } else {
                     return null;
                 }
             }
             case LEVEL_CONTAINS_2 -> {
-
+                if (result != null && result.getData() != null && result.getData().size() > 0) {
+                    List<AddressResult.ContentBean> contentBean = result.getData();
+                    for (AddressResult.ContentBean contentBean1 : contentBean) {
+                        String address = contentBean1.getAddress().replaceAll("上海市", "").replaceAll("青浦", "").replaceAll("区", "");
+                        String address2 = addr.replaceAll("上海市", "").replaceAll("青浦", "").replaceAll("区", "");
+                        if (address.contains(address2)) {
+                            return contentBean1;
+                        }
+                    }
+                } else {
+                    return null;
+                }
             }
             case LEVLE_NUMBER_3 -> {
-
+                if (result != null && result.getData() != null && result.getData().size() > 0) {
+                    List<AddressResult.ContentBean> contentBean = result.getData();
+                    for (AddressResult.ContentBean contentBean1 : contentBean) {
+                        String address = extractNumbers(contentBean1.getAddress(), false);
+                        String address2 = extractNumbers(addr, false);
+                        if (address.contains(address2)) {
+                            return contentBean1;
+                        }
+                    }
+                } else {
+                    return null;
+                }
             }
             case LEVEL_NUMBER_TEXT_4 -> {
-
+                if (result != null && result.getData() != null && result.getData().size() > 0) {
+                    List<AddressResult.ContentBean> contentBean = result.getData();
+                    for (AddressResult.ContentBean contentBean1 : contentBean) {
+                        String address = extractNumbers(contentBean1.getAddress().replaceAll("上海市", "").replaceAll("青浦", "").replaceAll("区", ""), true);
+                        String address2 = extractNumbers(addr.replaceAll("上海市", "").replaceAll("青浦", "").replaceAll("区", ""), true);
+                        String addressNumber = extractNumbers(contentBean1.getAddress(), false);
+                        String addressNumber2 = extractNumbers(addr, false);
+                        if (address.contains(address2) && addressNumber.contains(addressNumber2)) {
+                            return contentBean1;
+                        }
+                    }
+                } else {
+                    return null;
+                }
             }
             case LEVEL_TOTAL_CONTAINS_5 -> {
-
+                if (result != null && result.getData() != null && result.getData().size() > 0) {
+                    List<AddressResult.ContentBean> contentBean = result.getData();
+                    for (AddressResult.ContentBean contentBean1 : contentBean) {
+                        String address = contentBean1.getAddress().replaceAll("上海市", "").replaceAll("青浦", "").replaceAll("区", "");
+                        String address2 = addr.replaceAll("上海市", "").replaceAll("青浦", "").replaceAll("区", "");
+                        if (address.equals(address2)) {
+                            return contentBean1;
+                        }
+                    }
+                } else {
+                    return null;
+                }
             }
             default -> {
                 return null;
             }
         }
+        return null;
+    }
+
+    /**
+     * 得到字符串中所有的数字
+     *
+     * @param input
+     * @return
+     */
+    public static String extractNumbers(String input, boolean ifString) {
+        // 定义正则表达式,用于匹配一个或多个数字
+        Pattern pattern = Pattern.compile(ifString ? "\\D+" : "\\d+");
+        Matcher matcher = pattern.matcher(input);
+        String out = "";
+        // 查找所有匹配的数字
+        while (matcher.find()) {
+            out += matcher.group();
+        }
+        return out;
     }
 
 }

+ 9 - 4
src/main/java/com/skyversation/poiaddr/addquery/AddressTools.java

@@ -32,10 +32,15 @@ public class AddressTools {
 
         String param = "?user=" + userName + "&secret=" + secret + "&time=" + time;
         System.out.println("准备获取token,获取地址为:" + Constant.GET_TOKEN_URL + param);
-        String body = AddressNetTools.getInstance().requestGet(Constant.GET_TOKEN_URL + param, null, null).getBody() + "";
-        WDToken wdToken = JSONObject.parseObject(body, WDToken.class);
-        System.out.println("获取token完成,返回信息为:" + body);
-        return wdToken;
+        ResponseEntity responseEntity =AddressNetTools.getInstance().requestGet(Constant.GET_TOKEN_URL + param, null, null);
+        if(responseEntity != null){
+            String body = responseEntity.getBody() + "";
+            WDToken wdToken = JSONObject.parseObject(body, WDToken.class);
+            System.out.println("获取token完成,返回信息为:" + body);
+            return wdToken;
+        }else{
+            return null;
+        }
     }
 
     private String md5_32(String msg){

+ 2 - 1
src/main/java/com/skyversation/poiaddr/addquery/Constant.java

@@ -17,7 +17,8 @@ public class Constant {
     public static final String WD_USER_PWD = "yuanyi@123";
     public static final String GET_TOKEN_URL = "http://10.235.245.226:7010/addrMatch/auth/getToken";
     public static final String GET_ADDRESS_MEG_URL = "http://10.235.245.226:7010/addrMatch/addrApi/searchAddr";
-    public static final String SZX_URL = "https://service-api.onemap.sh.gov.cn/data-service-manage-service/MapProxyApi/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBsaWNhdGlvbl9pZCI6NjEsImFwcGxpY2F0aW9uX25hbWUiOiLpnZLmtabkuozkuInnu7TmnI3liqHns7vnu58iLCJleHAiOjIwNDY2Nzg0MDN9.IKUMdjUX4U1jncIUNren-iotL7duXI90aLECMjpvUX8/address_search/MapServer?region=310000&page_num=1&page_size=10&query=";
+    public static final String SZX_URL = "https://service-api.onemap.sh.gov.cn/data-service-manage-service/MapProxyApi/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBsaWNhdGlvbl9pZCI6NjEsImFwcGxpY2F0aW9uX25hbWUiOiLpnZLmtabkuozkuInnu7TmnI3liqHns7vnu58iLCJleHAiOjIwNDY2Nzg0MDN9.IKUMdjUX4U1jncIUNren-iotL7duXI90aLECMjpvUX8/address_search/MapServer?region=310118&page_num=1&page_size=1&query=";
+    public static final String V4_URL = "http://10.235.245.174:10011/proxy/address/getAddressV4?token=65463DEE-620A-0ED5-2385-17ECD07CD351&address=";
 
     public static String AMAP_GEO_URL = "https://restapi.amap.com/v3/geocode/geo";
     public static String AMAP_REGEO_URL = "https://restapi.amap.com/v3/geocode/regeo";

+ 76 - 0
src/main/java/com/skyversation/poiaddr/addquery/SearchHttpAK.java

@@ -0,0 +1,76 @@
+package com.skyversation.poiaddr.addquery;
+
+import org.springframework.web.util.UriUtils;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * 百度地图 地理编码 (限额:300万次/天)
+ * https://lbsyun.baidu.com/faq/api?title=webapi/guide/webservice-geocoding
+ */
+public class SearchHttpAK {
+
+    public static String URL = "https://api.map.baidu.com/geocoding/v3?";
+
+    public static String AK = "7x5HhZqeAaz1vKHnFqo8PjpQ1b9zGI2G";
+
+    public static void main(String[] args) throws Exception {
+
+        SearchHttpAK snCal = new SearchHttpAK();
+
+        Map params = new LinkedHashMap<String, String>();
+        params.put("address", "上海市青浦区前云路10弄南宅小区进大门2号");
+        params.put("output", "json");
+        params.put("ak", AK);
+        snCal.requestGetAK(URL, params);
+    }
+
+    /**
+     * 默认ak
+     * 选择了ak,使用IP白名单校验:
+     * 根据您选择的AK已为您生成调用代码
+     * 检测到您当前的ak设置了IP白名单校验
+     * 您的IP白名单中的IP非公网IP,请设置为公网IP,否则将请求失败
+     * 请在IP地址为xxxxxxx的计算发起请求,否则将请求失败
+     */
+    public void requestGetAK(String strUrl, Map<String, String> param) throws Exception {
+        if (strUrl == null || strUrl.length() <= 0 || param == null || param.size() <= 0) {
+            return;
+        }
+
+        StringBuffer queryString = new StringBuffer();
+        queryString.append(strUrl);
+        for (Map.Entry<?, ?> pair : param.entrySet()) {
+            queryString.append(pair.getKey() + "=");
+            //    第一种方式使用的 jdk 自带的转码方式  第二种方式使用的 spring 的转码方法 两种均可
+            //    queryString.append(URLEncoder.encode((String) pair.getValue(), "UTF-8").replace("+", "%20") + "&");
+            queryString.append(UriUtils.encode((String) pair.getValue(), "UTF-8") + "&");
+        }
+
+        if (queryString.length() > 0) {
+            queryString.deleteCharAt(queryString.length() - 1);
+        }
+
+        java.net.URL url = new URL(queryString.toString());
+        System.out.println(queryString.toString());
+        URLConnection httpConnection = (HttpURLConnection) url.openConnection();
+        httpConnection.connect();
+
+        InputStreamReader isr = new InputStreamReader(httpConnection.getInputStream());
+        BufferedReader reader = new BufferedReader(isr);
+        StringBuffer buffer = new StringBuffer();
+        String line;
+        while ((line = reader.readLine()) != null) {
+            buffer.append(line);
+        }
+        reader.close();
+        isr.close();
+        System.out.println("AK: " + buffer.toString());
+    }
+}

+ 1 - 1
src/main/java/com/skyversation/poiaddr/bean/Village.java

@@ -31,7 +31,7 @@ public class Village implements Serializable {
      */
 
     private int cartodb_id;
-    private int _;
+    private int _5658;
     private int objectid;
     private String __12;
     private String __11;

+ 98 - 13
src/main/java/com/skyversation/poiaddr/controller/PoiAddressController.java

@@ -1,17 +1,25 @@
 package com.skyversation.poiaddr.controller;
 
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.skyversation.poiaddr.addquery.AddressQueryEngine;
+import com.skyversation.poiaddr.addquery.Constant;
+import com.skyversation.poiaddr.bean.AddressResult;
 import com.skyversation.poiaddr.entity.FileDataDto;
 import com.skyversation.poiaddr.entity.PoiAddress;
 import com.skyversation.poiaddr.service.PoiAddressService;
 import com.skyversation.poiaddr.util.ExcelReaderUtils;
 import com.skyversation.poiaddr.util.RequestUtils;
 import com.skyversation.poiaddr.util.fileTools.ReadFileData;
+import com.skyversation.poiaddr.util.net.AddressNetTools;
+import com.skyversation.poiaddr.util.status.AddressLevel;
 import lombok.extern.slf4j.Slf4j;
 import org.locationtech.jts.geom.Coordinate;
 import org.locationtech.jts.geom.GeometryFactory;
 import org.locationtech.jts.geom.Point;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
@@ -91,7 +99,8 @@ public class PoiAddressController {
                                 @RequestParam(name = "outCoordinate", required = false) String outCoordinate,
                                 @RequestParam(name = "matchingLevel", required = false) String matchingLevel,
                                 @RequestParam(name = "regionalJudgment", required = false) MultipartFile regionalJudgment,
-                                @RequestParam(name = "outFileType", required = false) String outFileType) throws IOException {
+                                @RequestParam(name = "outFileType", required = false) String outFileType,
+                                @RequestParam(name = "outputFileName", required = false) String outputFileName) throws IOException {
 //            参数合法性判断
         if ((file != null && !file.isEmpty()) && (addrColNames != null && !addrColNames.isEmpty())) {
 //          搜索地址key
@@ -123,6 +132,16 @@ public class PoiAddressController {
                     return "当匹配距离参数不为空时,必须传入经纬度参数!";
                 }
             }
+            if(outFileType != null){
+                if(outFileType.contains("csv")){
+                    outFileType = "csv";
+                }
+                if(outFileType.contains("xlsx")){
+                    outFileType = "xlsx";
+                }
+            }else{
+                outFileType = "csv";
+            }
 //          经纬度合法性判断
             if (latLonColName != null) {
 //              两个key
@@ -141,22 +160,29 @@ public class PoiAddressController {
 //          封装解析文件的参数
 //          TODO 文件数据解析
             List<FileDataDto> fileDataDtoList = ReadFileData.ReadMultipartFile(file);
+            int index = 0;
 //          TODO 补充FileDataDto中的搜索条件参数
             for (FileDataDto fileDataDto : fileDataDtoList) {
+                index++;
+                System.out.println("处理进度:" + index + "/" + fileDataDtoList.size());
 //              搜索等级
                 fileDataDto.setMatchingLevel(matchingLevel);
 //              TODO 数据过滤
 //              set地名地址搜索字段
                 Map<String, Object> properties = fileDataDto.getProperties();
-                if (addr1Key != null && !addr1Key.isEmpty() && ExcelReaderUtils.isOtherDistrictThanQingpu(addr1Key)) {
-                    String address = "上海市青浦区" + properties.getOrDefault(addr1Key, "").toString().replace("青浦区", "").replace(
-                            "青浦", "").replace("上海市", "").replace("上海", "").replace("/弄", "").replace("/号", "").replace("弄", "").replace("/幢", "").replace("/室", " ").replace("(号楼) ", " ");
-                    fileDataDto.setAddr1(address);
-                }
-                if (addr2Key != null && !addr2Key.isEmpty() && ExcelReaderUtils.isOtherDistrictThanQingpu(addr2Key)) {
-                    String address = "上海市青浦区" + properties.getOrDefault(addr2Key, "").toString().replace("青浦区", "").replace(
-                            "青浦", "").replace("上海市", "").replace("上海", "").replace("/弄", "").replace("/号", "").replace("弄", "").replace("/幢", "").replace("/室", " ").replace("(号楼) ", " ");
-                    fileDataDto.setAddr2(address);
+                try {
+                    if (properties != null && properties.get(addr1Key) != null && addr1Key != null && properties.get(addr1Key).toString().length() > 2 && ExcelReaderUtils.isOtherDistrictThanQingpu(properties.get(addr1Key).toString())) {
+                        String address = "上海市青浦区" + properties.getOrDefault(addr1Key, "").toString().replace("青浦区", "").replace(
+                                "青浦", "").replace("上海市", "").replace("上海", "").replaceAll("-", "");
+                        fileDataDto.setAddr1(address);
+                    }
+                    if (addr2Key != null && !addr2Key.isEmpty() && ExcelReaderUtils.isOtherDistrictThanQingpu(addr2Key)) {
+                        String address = "上海市青浦区" + properties.getOrDefault(addr2Key.trim(), "").toString().replace("青浦区", "").replace(
+                                "青浦", "").replace("上海市", "").replace("上海", "").replace("/弄", "").replace("/号", "").replace("弄", "").replace("/幢", "").replace("/室", " ").replace("(号楼) ", " ");
+                        fileDataDto.setAddr2(address);
+                    }
+                } catch (Exception e) {
+                    System.err.println(e);
                 }
 //              判断是否有参考经纬度字段
                 if (latKey != null && !latKey.isEmpty() && lonKey != null && !lonKey.isEmpty() && properties.get(latKey) != null && properties.get(lonKey) != null) {
@@ -173,8 +199,57 @@ public class PoiAddressController {
                         fileDataDto.setLon(Double.valueOf(lonStr));
                     }
                 }
+//              TODO 地名查询
+                if ((fileDataDto.getAddr1() != null || fileDataDto.getAddr2() != null) && (fileDataDto.getProperties().get("户籍街镇") == null || fileDataDto.getProperties().get("户籍街镇").toString().trim().isEmpty() || "".equals(fileDataDto.getProperties().get("户籍街镇").toString()))) {
+                    System.out.println("开始搜索:" + index + "/" + fileDataDtoList.size());
+                    AddressResult addressResult = AddressQueryEngine.getInstance().commonSearchByName(new String[]{fileDataDto.getAddr1().isEmpty() ? fileDataDto.getAddr2() : fileDataDto.getAddr1()}, AddressLevel.values()[1]);
+                    if (addressResult != null) {
+                        if (addressResult.getData() == null || addressResult.getData().size() < 1) {
+                            fileDataDto.getProperties().put("户籍街镇", null);
+                            fileDataDto.getProperties().put("户籍居委", null);
+                            fileDataDto.getProperties().put("纬度", null);
+                            fileDataDto.getProperties().put("经度", null);
+                            fileDataDto.getProperties().put("搜索结果地址", null);
+                        } else {
+                            try {
+                                for (AddressResult.ContentBean contentBean : addressResult.getData()) {
+                                    String resultAddrKey = contentBean.getAddress();
+                                    if (resultAddrKey != null && contentBean.getLon() != null && contentBean.getLat() != null && contentBean.getAdname() != null && contentBean.getCjJson() != null) {
+                                        String lng = contentBean.getLat() + "";
+                                        String lat = contentBean.getLon() + "";
+                                        fileDataDto.getProperties().put("户籍街镇", contentBean.getAdname());
+                                        fileDataDto.getProperties().put("户籍居委", contentBean.getCjJson().getString("所属居委"));
+                                        fileDataDto.getProperties().put("纬度", lng);
+                                        fileDataDto.getProperties().put("经度", lat);
+                                        fileDataDto.getProperties().put("搜索结果地址", resultAddrKey);
+                                        System.out.println("成功:" + lat + "," + lng);
+                                        break;
+                                    } else {
+                                        fileDataDto.getProperties().put("户籍街镇", null);
+                                        fileDataDto.getProperties().put("户籍居委", null);
+                                        fileDataDto.getProperties().put("纬度", null);
+                                        fileDataDto.getProperties().put("经度", null);
+                                        fileDataDto.getProperties().put("搜索结果地址", null);
+                                    }
+                                }
+                            } catch (Exception e) {
+                                fileDataDto.getProperties().put("户籍街镇", null);
+                                fileDataDto.getProperties().put("户籍居委", null);
+                                fileDataDto.getProperties().put("纬度", null);
+                                fileDataDto.getProperties().put("经度", null);
+                                fileDataDto.getProperties().put("搜索结果地址", null);
+                                System.err.println(e);
+                            }
+                        }
+                    }
+                } else {
+                    fileDataDto.getProperties().put("户籍街镇", null);
+                    fileDataDto.getProperties().put("户籍居委", null);
+                    fileDataDto.getProperties().put("纬度", null);
+                    fileDataDto.getProperties().put("经度", null);
+                    fileDataDto.getProperties().put("搜索结果地址", null);
+                }
             }
-//          TODO 地名查询
 //          TODO 转换坐标(根据输入坐标系将参考坐标统一转换成wgs84)
             ArrayList<String> selectOptions = new ArrayList<>();
 //            {"WGS84(国际通用)", "GCJ02(高德、QQ地图)", "BD09(百度地图)", "上海2000坐标系"}
@@ -189,6 +264,8 @@ public class PoiAddressController {
             } else {
                 inCoordinate = "WGS84";
             }
+            List<Map<String, Object>> dataList = new ArrayList<>();
+            // TODO 距离计算和区域判断
             for (FileDataDto fileDataDto : fileDataDtoList) {
                 if (fileDataDto.getLat() != null && fileDataDto.getLon() != null) {
                     double[] lonLat = com.skyversation.poiaddr.util.Coordinate.transformationCoordinateByCoordinate(fileDataDto.getLat(), fileDataDto.getLon(), inCoordinate, outCoordinate);
@@ -211,11 +288,19 @@ public class PoiAddressController {
                 //          TODO 区域判断
                 if (regionalJudgment != null && !regionalJudgment.isEmpty()) {
 //                  解析geojson文件得到区域
-
                 }
+                dataList.add(fileDataDto.getProperties());
             }
 //          TODO 转换坐标
-//          TODO 结果输出
+//          TODO 结果输出 result[_匹配等级][_匹配距离][_区域名称][_坐标系].[文件类型]
+            switch (outFileType){
+                case "xlsx":
+                    ExcelReaderUtils.writeToExcel(dataList, "C:\\Users\\Liumouren\\Desktop\\output" + outputFileName + ".xlsx");
+                    break;
+                case "csv":
+                    break;
+            }
+            System.out.println("处理完成!");
             return "文件解析完成,共" + fileDataDtoList.size() + "条数据!";
         } else {
             return "file或addrColName不能为空!";

+ 3 - 0
src/main/java/com/skyversation/poiaddr/service/AreaService.java

@@ -26,6 +26,9 @@ public class AreaService {
 
     private static AreaService instance;
     public static AreaService getInstance(){
+        if(instance == null){
+            return new AreaService();
+        }
         return instance;
     }
 

+ 0 - 132
src/main/java/com/skyversation/poiaddr/util/ExcelReaderUtils.java

@@ -187,101 +187,6 @@ public class ExcelReaderUtils {
         return baseName + "_part_" + (index + 1) + extension;
     }
 
-    private static Map<String, String> updateTableHeader() {
-        Map<String, String> table1colToName = new HashMap<>();
-        table1colToName.put("ID", "序列号");
-        table1colToName.put("TASKID", "任务编号");
-        table1colToName.put("BANLIRESULT_12345", "办理结果");
-        table1colToName.put("APPEAL_EXPLAIN", "诉求认定说明");
-        table1colToName.put("DESCRIPTION_12345", "反馈结论");
-        table1colToName.put("NOT_REASON", "未联原因");
-        table1colToName.put("CASEVALUATION_12345", "是否满意");
-        table1colToName.put("VIEWINFO", "现场查看");
-        table1colToName.put("DISPATCHNOTE", "派遣备注");
-        table1colToName.put("ENDNOTE", "结案备注");
-        table1colToName.put("PARTSN", "部件编号");
-        table1colToName.put("WORKGRID", "工作网格");
-        table1colToName.put("SPEICALSIGN", "案件特殊标识(特征要素)");
-        table1colToName.put("CANCLETIME", "作废时间");
-        table1colToName.put("CONTACTINFO", "联系方式");
-        table1colToName.put("ACCEPTTIME", "接单时间(最后一次主责部门处理完成时间)");
-        table1colToName.put("LASTCONTACTTIME", "首次联系截止时间(最后主责)");
-        table1colToName.put("INFOSOURCENAME", "来源名");
-        table1colToName.put("INFOTYPENAME", "案件属性名");
-        table1colToName.put("INFOBCNAME", "大类名");
-        table1colToName.put("INFOSCNAME", "小类名");
-        table1colToName.put("INFOZCNAME", "子类名");
-        table1colToName.put("STREETNAME", "街道名");
-        table1colToName.put("COMMUNITYNAME", "居委名");
-        table1colToName.put("WORKGRIDCODE", "责任网格");
-        table1colToName.put("EXECUTEDEPTNAME", "最后主责部门");
-        table1colToName.put("REPORTER", "反映人");
-        table1colToName.put("REPORTDEPTNAME", "渠道来源");
-        table1colToName.put("SYNCTIME", "更新时间");
-        table1colToName.put("WP_SOURCE", "工单来源");
-        table1colToName.put("CASESN", "案卷编号");
-        table1colToName.put("INFOSOURCEID", "问题来源");
-        table1colToName.put("DISCOVERTIME", "发现时间");
-        table1colToName.put("PERCREATETIME", "受理时间(最后一次受理时间)");
-        table1colToName.put("CREATETIME", "立案时间(最后一次立案时间)");
-        table1colToName.put("DISPATCHTIME", "派遣时间(最后一次派遣时间)");
-        table1colToName.put("SOLVINGTIME", "处理完成时间(最后一次主责部门处理完成时间)");
-        table1colToName.put("TELASKTIME", "回访时间(最后一次回访时间)");
-        table1colToName.put("ENDTIME", "结案时间");
-        table1colToName.put("STREETCODE", "街道编号");
-        table1colToName.put("COMMUNITYCODE", "村、居村编码");
-        table1colToName.put("GRIDCODE", "万米网格编码");
-        table1colToName.put("COORDX", "X坐标");
-        table1colToName.put("COORDY", "Y坐标");
-        table1colToName.put("ADDRESS", "发生地址");
-        table1colToName.put("INFOTYPEID", "问题类型编码(0,value:部件;1:事件;...)");
-        table1colToName.put("INFOBCCODE", "问题大类编号");
-        table1colToName.put("INFOSCCODE", "问题小类编号");
-        table1colToName.put("INFOZCCODE", "问题子类编码");
-        table1colToName.put("INFOATCODE", "问题管理要点编码");
-        table1colToName.put("DESCRIPTION", "问题描述");
-        table1colToName.put("STATUS", "T_INFO_MAIN表状态");
-        table1colToName.put("DEPTCODE", "立案部门");
-        table1colToName.put("EXECUTEDEPTCODE", "最后一次主责部门");
-        table1colToName.put("INSERTDEPTCODE", "收集部门");
-        table1colToName.put("KEEPERSN", "上报监督员编号");
-        table1colToName.put("INSERTUSER", "记录添加操作员(收集人)");
-        table1colToName.put("URGENTDEGREE", "紧急程度(0:一般;1:紧急)");
-        table1colToName.put("APPROACH", "12345工单处理方式/案卷类型(0:转办; /1:督办; /2:回访复核)");
-        table1colToName.put("SIMILARCASESN", "相关案件编号");
-        table1colToName.put("SERVICETYPE", "业务类型");
-        table1colToName.put("ISANONYMITY", "是否匿名");
-        table1colToName.put("USEREVALUATE", "用户评价/满意度(0,value:满意; /1,value:基本满意; /2,value:不满意)");
-        table1colToName.put("ALLMIDDLETIME", "整体案卷黄灯开始时间(根据紧急程度middle计算的)");
-        table1colToName.put("ALLIMPORTANTTIME", "整体案卷橙灯开始时间(根据紧急程度important计算的)");
-        table1colToName.put("ALLENDTIME", "整体案卷截止时间(红灯开始时间)");
-        table1colToName.put("MIDDLESOLVINGTIME", "处理阶段黄灯开始时间");
-        table1colToName.put("IMPORTANTSOLVINGTIME", "处理阶段橙灯开始时间");
-        table1colToName.put("LASTSOLVINGTIME", "处理阶段红灯开始时间(处理截止时间)");
-        table1colToName.put("CALLBACK_FLAG", "12345回访复核单状态标识(0:否,1:是)");
-        table1colToName.put("URGE_COUNT", "12345催单次数(12345催单时带过来的催单次数)");
-        table1colToName.put("DU_LIMIT", "12345督办时限(天)");
-        table1colToName.put("CASEEND", "是否自行处置");
-        table1colToName.put("BANLIRESULT", "12345办理结果(0,value:解决,1,value:未解决,2,value:部分解决,3,value:不办理退单)");
-        table1colToName.put("ENDRESULT", "结案评价");
-        table1colToName.put("VERIFYRESULT", "最后的核实结果(1,value:属实,0,value:不属实)");
-        table1colToName.put("CHECKRESULT", "最后的核查结果(1,value:完成,0,value:未完成)");
-        table1colToName.put("PRIORITYAREA", "重要区域");
-        table1colToName.put("CONTACTMODE", "反映人联系方式");
-        table1colToName.put("BACKCOUNT", "退单次数(案件所有主责部门累加)");
-        table1colToName.put("HESHICOUNT", "核实次数");
-        table1colToName.put("HECHACOUNT", "核查次数");
-        table1colToName.put("HUIFANGCOUNT", "回访次数");
-        table1colToName.put("HASLEADTYPECOUNT", "领导督办次数");
-        table1colToName.put("HASTENTYPECOUNT", "催办过的次数");
-        table1colToName.put("HOTLINESN", "12319编号,延伸为外系统管理单号");
-        table1colToName.put("JHPT_UPDATE_TIME", "JHPT_UPDATE_TIME");
-        table1colToName.put("JHPT_DELETE", "JHPT_UPDATE_TIME");
-        table1colToName.put("DEPTNAME", "部门名");
-        table1colToName.put("STATUSNAME", "状态名");
-        return table1colToName;
-    }
-
     private static String getCellValueAsString(Cell cell) {
         switch (cell.getCellType()) {
             case STRING:
@@ -305,43 +210,6 @@ public class ExcelReaderUtils {
         }
     }
 
-    /**
-     * 替换表头
-     */
-    private static void ModifyExcelHeaderJExcelApi() {
-        try {
-            // 读取现有的Excel文件
-            FileInputStream file = new FileInputStream("C:\\Users\\Liumouren\\Desktop\\临时文件\\元以科技\\青浦\\青浦城建所\\poiAddr\\doc\\tableHeader.xlsx");
-            Workbook workbook = new XSSFWorkbook(file);
-            Map<String, String> table1colToName = updateTableHeader();
-            // 遍历每个工作表
-            for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++) {
-                Sheet sheet = workbook.getSheetAt(sheetIndex);
-                // 获取表头行(假设第一行是表头)
-                Row headerRow = sheet.getRow(0);
-                if (headerRow != null) {
-                    // 遍历每个表头单元格进行替换
-                    // 遍历表头行中的每个单元格
-                    for (Cell cell : headerRow) {
-                        if (cell != null) {
-                            String oldHeaderValue = getCellValueAsString(cell);
-                            if (table1colToName.containsKey(oldHeaderValue)) {
-                                cell.setCellValue(table1colToName.get(oldHeaderValue));
-                            }
-                        }
-                    }
-                }
-            }
-            // 保存修改后的Excel文件
-            FileOutputStream outputStream = new FileOutputStream("C:\\Users\\Liumouren\\Desktop\\临时文件\\元以科技\\青浦\\青浦城建所\\poiAddr\\doc\\outPutTableHeader.xlsx");
-            workbook.write(outputStream);
-            outputStream.close();
-            file.close();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
     private static void XlsxFileSplitByRowRange(String filePath, int tag) {
         try {
             // 读取原始xlsx文件

+ 45 - 0
src/main/java/com/skyversation/poiaddr/util/RequestUtils.java

@@ -85,4 +85,49 @@ public class RequestUtils {
             return null;
         }
     }
+
+
+    /**
+     * httpPost 请求,参数类型为formData
+     *
+     * @param url
+     * @param headers
+     * @param formDatas
+     * @return
+     */
+    public static JSONObject requestPost2(String url, Map<String, String> headers, org.json.JSONObject formDatas) {
+        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+            HttpPost httpPost = new HttpPost(url); // 替换为实际的 API 地址
+            if (headers != null && headers.size() > 0) {
+                // 设置自定义 Header
+                for (String key : headers.keySet()) {
+                    httpPost.addHeader(key, headers.get(key));
+                }
+            }
+
+            if (formDatas != null && formDatas.length() > 0) {
+                // 设置 formData
+                List<NameValuePair> formData = new ArrayList<>();
+                for (String key : formDatas.keySet()) {
+                    formData.add(new BasicNameValuePair(key, formDatas.get(key).toString()));
+                }
+                httpPost.setEntity(new UrlEncodedFormEntity(formData));
+            }
+            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
+                int statusCode = response.getStatusLine().getStatusCode();
+                if (statusCode == 200) {
+                    HttpEntity entity = response.getEntity();
+                    JSONParser jsonParser = new JSONParser();
+                    return (JSONObject) jsonParser.parse(EntityUtils.toString(entity));
+                } else {
+                    System.err.println("请求失败,状态码: " + statusCode);
+                    return null;
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.err.println(e.getMessage());
+            return null;
+        }
+    }
 }

+ 107 - 1
src/main/java/com/skyversation/poiaddr/util/dms/login.java

@@ -1,9 +1,17 @@
 package com.skyversation.poiaddr.util.dms;
 
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.skyversation.poiaddr.util.RequestUtils;
+import org.json.JSONArray;
 import org.json.simple.JSONObject;
 
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 public class login {
@@ -33,7 +41,7 @@ public class login {
         return RequestUtils.requestPost("http://121.43.55.7:2101/proxy_dms/content/selectContentList", headers, formDatas);
     }
 
-    public static JSONObject addContent(Map<String, String> formDatas){
+    public static JSONObject addContent(Map<String, String> formDatas) {
         Map<String, String> headers = new HashMap<>();
         if (DmsToken != null && DmsToken.length() > 0) {
             headers.put("Token", DmsToken);
@@ -42,4 +50,102 @@ public class login {
         }
         return RequestUtils.requestPost("http://121.43.55.7:2101/proxy_dms/content/addContent", headers, formDatas);
     }
+
+    public static JSONObject updateContent(org.json.JSONObject formDatas) {
+        Map<String, String> headers = new HashMap<>();
+        if (DmsToken != null && DmsToken.length() > 0) {
+            headers.put("Token", DmsToken);
+        } else {
+            headers.put("Token", getDmsToken());
+        }
+        return RequestUtils.requestPost2("http://121.43.55.7:2101/proxy_dms/content/updateContent", headers, formDatas);
+    }
+
+    public static void main(String[] args) {
+//      解析geojson文件并将学校名称和招生区域保存为一个Map<String(学校名称),String(招生区域geojson)>
+//      是否检查数据(true:不更新DMS只检查文件数据,false:数据正确的前提下执行DMS更新操作)
+        Boolean ifDatas = false;
+        Map<String, org.json.JSONObject> fileDatas = new HashMap<>();
+        String filePath = "C:\\Users\\Liumouren\\Desktop\\临时文件\\元以科技\\青浦\\教育局\\geojsonUpdate\\幼儿园更新.json";
+        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
+            StringBuilder stringBuilder = new StringBuilder();
+            String line;
+            while ((line = reader.readLine()) != null) {
+                stringBuilder.append(line);
+            }
+            String jsonString = stringBuilder.toString();
+            org.json.JSONObject jsonObject1 = new org.json.JSONObject(jsonString);
+            JSONArray features = jsonObject1.getJSONArray("features");
+//            System.out.println(features);
+            for (int i = 0; i < features.length(); i++) {
+                if (features.getJSONObject(i).getJSONObject("properties").has("name") && features.getJSONObject(i).getJSONObject("geometry").getJSONArray("coordinates").length() > 0) {
+                    String schoolName = features.getJSONObject(i).getJSONObject("properties").getString("name");
+                    features.getJSONObject(i).remove("properties");
+                    fileDatas.put(schoolName, features.getJSONObject(i));
+                }
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+//      查询columnId为1477的所有数据
+        JSONObject dmsDatas1 = selectDms("1477");
+//      遍历数据
+//        System.out.println(dmsDatas1);
+        List<String> hasName = new ArrayList<>();
+        Map<String, org.json.JSONObject> newSchoolGeojson = new HashMap<>();
+        if ("200".equals(dmsDatas1.get("code").toString())) {
+//          请求成功,遍历数据
+            org.json.JSONObject dmsDataContents = new org.json.JSONObject(dmsDatas1.get("content").toString());
+            JSONArray dmsDataList = dmsDataContents.getJSONArray("data");
+            for (int i = 0; i < dmsDataList.length(); i++) {
+                org.json.JSONObject item = dmsDataList.getJSONObject(i);
+                if (fileDatas.containsKey(item.getString("title"))) {
+//                  是否名字能匹配上,能的话记录一下id
+                    hasName.add(item.getString("title"));
+                    String id = item.getString("id");
+                    if (ifDatas) {
+                        newSchoolGeojson.put(item.getString("title"), fileDatas.get(item.getString("title")));
+                    } else {
+                        newSchoolGeojson.put(item.getString("title") + "_" + id, fileDatas.get(item.getString("title")));
+                    }
+                    if (item.has("c_geojson") && item.getString("c_geojson").length() > 2) {
+                        System.out.println("替换geojson的学校名称:" + item.getString("title"));
+                    } else {
+                        System.out.println("新增geojson的学校名称:" + item.getString("title"));
+                    }
+                }
+            }
+        }
+        if(ifDatas){
+            System.out.println("解析到的文件数据:" + fileDatas.size());
+            System.out.println(newSchoolGeojson);
+            for (String schoolName : fileDatas.keySet()) {
+                if (!newSchoolGeojson.containsKey(schoolName)) {
+                    System.err.println("DMS中不存在学校:" + schoolName);
+                }
+            }
+        }else{
+//      准备更新数据
+//      首先得到关键数据(id\columnId\modelId)
+            org.json.JSONObject params = new org.json.JSONObject();
+            params.put("columnId", "1477");
+            params.put("modelId", "1358");
+            for (String schoolNameAndId : newSchoolGeojson.keySet()) {
+                String schoolName = schoolNameAndId.split("_")[0];
+                String id = schoolNameAndId.split("_")[1];
+                org.json.JSONObject paramsContent = new org.json.JSONObject();
+                paramsContent.put("id", id);
+                org.json.JSONObject cGeojson = new org.json.JSONObject();
+                cGeojson.put("type", "FeatureCollection");
+                JSONArray coordinates = new JSONArray();
+                coordinates.put(newSchoolGeojson.get(schoolNameAndId));
+                cGeojson.put("features", coordinates);
+                paramsContent.put("c_geojson", cGeojson.toString());
+                params.put("content", paramsContent);
+                System.out.println("更新" + schoolName + updateContent(params));
+            }
+//      更新结束
+        }
+
+    }
 }

+ 0 - 3
src/main/java/com/skyversation/poiaddr/util/status/AddressLevel.java

@@ -1,12 +1,9 @@
 package com.skyversation.poiaddr.util.status;
 
 public enum AddressLevel {
-
     LEVEL_1,// 有结果就用
     LEVEL_CONTAINS_2,// 有包含关系就用
     LEVLE_NUMBER_3,//数字匹配则使用
     LEVEL_NUMBER_TEXT_4,// 文字与数字均包含
     LEVEL_TOTAL_CONTAINS_5;// 完全匹配正确则使用
-
-
 }

+ 172 - 0
src/main/java/com/skyversation/poiaddr/util/根据jsonarray查询地址_四中心搜索_V4.java

@@ -0,0 +1,172 @@
+package com.skyversation.poiaddr.util;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.skyversation.poiaddr.util.net.AddressNetTools;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.StringUtils;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * 政务网
+ */
+public class 根据jsonarray查询地址_四中心搜索_V4 {
+    public static final String szxUrl = "https://service-api.onemap.sh.gov.cn/data-service-manage-service/MapProxyApi/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBsaWNhdGlvbl9pZCI6NjEsImFwcGxpY2F0aW9uX25hbWUiOiLpnZLmtabkuozkuInnu7TmnI3liqHns7vnu58iLCJleHAiOjIwNDY2Nzg0MDN9.IKUMdjUX4U1jncIUNren-iotL7duXI90aLECMjpvUX8/address_search/MapServer?region=310118&page_num=1&page_size=10&query=";
+    public static final String v4Url = "http://10.235.245.174:10011/proxy/address/getAddressV4?token=65463DEE-620A-0ED5-2385-17ECD07CD351&address=";
+//  TODO 是否使用市中心的返回方法
+    public static final Boolean ifSzxResult = true;
+
+    public static void main(String[] args) {
+        String path = "D:\\work\\晗哥\\城建所\\数据处理\\赵巷单位2.xlsx";
+        String outputPath = "D:\\work\\晗哥\\城建所\\数据处理\\output赵巷单位2.xlsx";
+//        // V4地名地址,结果:33空地址,地址不完全匹配
+        searchLocToV4ByAddress("上海市青浦区", "经营地址", path, outputPath);
+
+
+    }
+
+    public static void searchLocToV4ByAddress(String heaeName, String addressKey, String path, String outputPath) {
+        try {
+            List<Map<String, Object>> listAddr = ExcelReaderUtils.readExcel(path);
+            int size = (listAddr.size() / 1000) + 1;
+            System.out.println("<<<<<<<   " + size + "     >>>>>>>>>");
+//            ExecutorService executor = Executors.newFixedThreadPool(size);
+//            for(int i = 0; i < size; i ++){
+
+//                List<Map<String, String>> list = listAddr.subList(i * 1000, (i+1)*1000 > listAddr.size() ? listAddr.size(): (i+1)*1000);
+            List<Map<String, Object>> list = listAddr;
+
+//                executor.execute(() ->{
+            List<Map<String, Object>> result = new ArrayList<>();
+            for (Map<String, Object> map : list) {
+                if (map.get("搜索结果地址") != null && StringUtils.hasText(map.get("搜索结果地址").toString())) {
+                    result.add(map);
+                } else {
+                    // 开始查询
+                    String address = map.get(addressKey).toString().trim().replaceAll("-", "");
+                    address = address.replace("上海市", "");
+                    address = address.replace("青浦区", "");
+                    address = heaeName + address;
+                    ResponseEntity response = AddressNetTools.getInstance().requestGet((ifSzxResult ? szxUrl : v4Url) + address, null, null);
+                    if (response != null) {
+                        JSONObject json = JSONObject.parseObject(response.getBody() + "");
+                        JSONArray array = null;
+                        if (ifSzxResult) {
+//                          TODO 市中心搜索方法
+                            array = json.getJSONArray("result");
+                        } else {
+//                          TODO V4搜索方法
+                            JSONObject content = json.getJSONObject("content");
+                            int resultCode = content.getInteger("resultCode");
+                            if (resultCode == 0) {
+                                array = content.getJSONArray("exactResult");
+                            } else {
+                                array = content.getJSONArray("recomResult");
+                            }
+                        }
+                        if (array == null || array.size() < 1) {
+//                            map.put("所属区县", " ");
+//                            map.put("所属街道", " ");
+                            map.put("搜索结果纬度", " ");
+                            map.put("搜索结果经度", " ");
+//                            map.put("所属居委", " ");
+                            map.put("是否精确", "否");
+                            map.put("搜索结果地址", "");
+                        } else {
+                            for (int j = 0; j < array.size(); j++) {
+                                JSONObject jsonRes = array.getJSONObject(j);
+                                String lng = "";
+                                String lat = "";
+                                String resultAddrKey = jsonRes.getString(ifSzxResult ? "address" : "搜索结果地址");
+                                if (ifSzxResult && jsonRes.getJSONObject("location") != null && jsonRes.getJSONObject("location").get("lng") != null && jsonRes.getJSONObject("location").get("lat") != null) {
+                                    lng = jsonRes.getJSONObject("location").getDoubleValue("lng") + "";
+                                    lat = jsonRes.getJSONObject("location").getDoubleValue("lat") + "";
+                                } else if (jsonRes.get("纬度") != null && jsonRes.get("经度") != null) {
+                                    lng = jsonRes.getDoubleValue("纬度") + "";
+                                    lat = jsonRes.getDoubleValue("经度") + "";
+                                } else {
+                                    map.put("搜索结果纬度", "");
+                                    map.put("搜索结果经度", "");
+                                    map.put("搜索结果地址", "");
+                                    continue;
+                                }
+                                map.put("搜索结果纬度", lng);
+                                map.put("搜索结果经度", lat);
+                                map.put("搜索结果地址", resultAddrKey);
+//                              map.put("所属区县", jsonRes.getString("所属区县"));
+//                              map.put("所属街道", jsonRes.getString("所属街道"));
+//                              map.put("所属居委", jsonRes.getJSONObject("村居信息").getString("所属居委"));
+                                if (("上海市青浦区" + resultAddrKey).contains(address.replace("上海市青浦区", ""))) {
+                                    map.put("是否精确", "是");
+                                    break;
+                                } else if (resultAddrKey != null && !resultAddrKey.isEmpty() && address.contains(resultAddrKey.replace("上海市青浦区", ""))) {
+                                    map.put("是否精确", "近似");
+                                    break;
+                                } else {
+                                    double lat1 = Double.parseDouble(map.get("经度") + "");
+                                    double lon1 = Double.parseDouble(map.get("纬度") + "");
+                                    double lat2 = Double.parseDouble(lat);
+                                    double lon2 = Double.parseDouble(lng);
+                                    if (Coordinate.calculateDistance(lat1, lon1, lat2, lon2) <= 100) {
+                                        map.put("是否精确", "接近100m");
+                                        break;
+                                    } else {
+                                        map.put("搜索结果纬度", "");
+                                        map.put("搜索结果经度", "");
+                                        map.put("搜索结果地址", "");
+                                        continue;
+                                    }
+                                }
+                            }
+
+                            if (!ifSzxResult && !StringUtils.hasText(map.get("搜索结果经度") + "")) {
+                                boolean isError = false;
+                                JSONObject json1 = array.getJSONObject(0);
+                                if (json1.getString("搜索结果地址").length() < 5) {
+                                    try {
+                                        json1 = array.getJSONObject(1);
+                                    } catch (Exception e) {
+                                        isError = true;
+//                                        map.put("所属区县", " ");
+//                                        map.put("所属街道", " ");
+                                        map.put("搜索结果纬度", " ");
+                                        map.put("搜索结果经度", " ");
+//                                        map.put("所属居委", " ");
+                                        map.put("是否精确", "否");
+                                        map.put("搜索结果地址", "");
+                                    }
+                                }
+                                if (!isError) {
+//                                    JSONObject jsonWWG = json1.getJSONObject("微格网信息");
+//                                    map.put("所属区县", jsonWWG.getString("所属区县"));
+//                                    map.put("所属街道", jsonWWG.getString("所属街道"));
+                                    map.put("搜索结果纬度", json1.getDoubleValue("纬度") + "");
+                                    map.put("搜索结果经度", json1.getDoubleValue("经度") + "");
+                                    map.put("是否精确", "否");
+                                    map.put("搜索结果地址", json1.getString("搜索结果地址"));
+//                                    map.put("所属居委", json1.getJSONObject("村居信息").getString("所属居委"));
+                                }
+                            }
+                        }
+                    }
+                    result.add(map);
+                }
+            }
+            try {
+                ExcelReaderUtils.writeToExcel(result, outputPath.replace(".xlsx", UUID.randomUUID().toString() + ".xlsx"));
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+//                });
+
+//            }
+//            executor.shutdown();
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+}