ソースを参照

添加模型和统一流程接口

DESKTOP-6LTVLN7\Liumouren 3 ヶ月 前
コミット
28f9c92719

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

@@ -49,6 +49,7 @@ public class AddressQueryEngine {
         for (String addr : addrs) {
             //  创建请求
             addressResult = sj_szxSearchByName(addr);
+//            addressResult = szxSearchByName(addr);
             if (addressResult != null) {
                 addressResult.setCode(AddressResultEnum.SZX_SUCCESS);
                 addressResult.setMessage("成功");
@@ -175,8 +176,6 @@ public class AddressQueryEngine {
             try {
                 if (body.indexOf("[") != 0) {
                     return TransfromDataTool.szxResultToResult(JSONObject.parseObject(body),address);
-//                    System.out.println("请求地址:" + address + ";返回结果错误:" + body);
-//                    return AddressTools.getInstance().faildQuery(AddressResultEnum.DATA_FROMAT_FAILD, "请求地址:" + address + ";返回结果错误:" + body);
                 } else {
 //                  将得分最高的结果映射到实体类
                     return TransfromDataTool.szxResultToResult2(com.skyversation.poiaddr.util.AddressTools.getInstance().findBestMatch(address, JSONArray.parseArray(body), "address"));

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

@@ -48,7 +48,7 @@ public class Constant {
     }
 
     public static String getAMAP_CITY_CODE() {
-        return "青浦".equals(getArea()) ? "310118" : "310117";
+        return "青浦".equals(getArea()) ? "310118" : "松江".equals(getArea()) ? "310117" : "310000";
     }
 
     public static final String WD_USER_NAME = "yuanyi";
@@ -56,7 +56,7 @@ public class Constant {
     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?page_num=1&page_size=5";
-//    TODO 服务器融合版地名地址接口
+    //    TODO 服务器融合版地名地址接口
 //    public static final String SJ_SZX_SEARCH_BY_NAME = "http://172.30.77.19:8081/openapi/1736930075105";
     //    TODO 关键字模糊搜索服务
 //    public static final String SJ_SZX_SEARCH_BY_NAME2 = "http://172.30.77.19:8081/openapi/1742459783686";

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

@@ -152,7 +152,8 @@ public class TransfromDataTool {
                 }
             }
             for (String item : addressList) {
-                if (item.contains("上海市") && item.contains(Constant.getArea() + "区") && item.length() > content.getAddress().length()) {
+//                item.contains("上海市") && item.contains(Constant.getArea() + "区") &&
+                if (item.length() > content.getAddress().length()) {
                     content.setAddress(item);
                 }
             }

+ 46 - 0
src/main/java/com/skyversation/poiaddr/controller/CorporateLibraryController.java

@@ -0,0 +1,46 @@
+package com.skyversation.poiaddr.controller;
+
+import com.skyversation.poiaddr.service.impl.YyskAddressStandardizationServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.MediaType;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * 法人库处理类
+ */
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("/corporate_library")
+public class CorporateLibraryController {
+
+    @Resource
+    private YyskAddressStandardizationServiceImpl yyskAddressStandardizationService;
+
+
+    /**
+     * (开发中)
+     * 定时器:每天都全量更新法人库的地名地址数据
+     * 每次分页查询每批次处理1W条数据
+     * 1、获取数据库连接
+     * 2、查询数据
+     * 3、得到地名地址字段和值(清洗数据,并地名格式调整)
+     * 4、批量多任务处理查询结果并判断网格区划
+     * 5、将结果保存为ser文件
+     */
+    @PostMapping(value = "/test", produces = MediaType.APPLICATION_JSON_VALUE)
+    public Object updateDataBaseData(@RequestParam(name = "pageSize") Integer pageSize, @RequestParam(name = "init") Integer init, @RequestParam(name = "tableName") String tableName) {
+        // 记录程序开始时间
+        long startTime = System.currentTimeMillis();
+        yyskAddressStandardizationService.iterativeProcessing(pageSize, init, tableName);// 记录程序结束时间
+        long endTime = System.currentTimeMillis();
+        return "处理完成!用时" + (endTime - startTime) / 1000 + "秒!";
+    }
+
+}

+ 92 - 3
src/main/java/com/skyversation/poiaddr/controller/PoiAddressController.java

@@ -1,8 +1,12 @@
 package com.skyversation.poiaddr.controller;
 
 import com.skyversation.poiaddr.addquery.AddressQueryEngine;
+import com.skyversation.poiaddr.addquery.Constant;
+import com.skyversation.poiaddr.bean.AddressResult;
 import com.skyversation.poiaddr.config.DbConnection;
 import com.skyversation.poiaddr.service.impl.SjArrDzbzhSjWcbryDzxxServiceImpl;
+import com.skyversation.poiaddr.util.AddressTools;
+import com.skyversation.poiaddr.util.ExcelReaderUtils;
 import com.skyversation.poiaddr.util.RequestUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.MediaType;
@@ -11,7 +15,13 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 
+/**
+ * 地名地址测试类
+ */
 @Slf4j
 @Validated
 @RestController
@@ -47,22 +57,101 @@ public class PoiAddressController {
         return "处理完成!用时" + (endTime - startTime) / 1000 + "秒!";
     }
 
+    /**
+     * 自定义处理逻辑,用完要删除
+     * 1、读取xlsx数据
+     * 2、得到查询地址列集合
+     * 3、使用四中心的地名地址接口跑一下地址
+     * 4、调整返回的数据结构
+     * 5、保存新的规范性地址和所属街镇
+     *
+     * @return
+     */
+    @PostMapping(value = "/diyCode", produces = MediaType.APPLICATION_JSON_VALUE)
+    public Object diyCode() {
+        // 记录程序开始时间
+        long startTime = System.currentTimeMillis();
+//        1、读取xlsx数据
+        try {
+            List<Map<String, Object>> fileDatas = ExcelReaderUtils.readExcel("output/松江26487数据治理结果数据.xlsx");
+//          得到所属街镇为空的数据
+            for (Map<String, Object> item : fileDatas) {
+                if (item.get("所属街镇") == null || item.get("所属街镇").toString().isEmpty()) {
+//                   2、得到查询地址列集合
+                    List<String> addrList = new ArrayList<>();
+                    if (item.get("sk_hjdx(实口户籍)") != null && !item.get("sk_hjdx(实口户籍)").toString().isEmpty() && item.get("sk_hjdx(实口户籍)").toString().length() > 3 && AddressTools.isOtherDistrictThanSongJiang(item.get("sk_hjdx(实口户籍)").toString())) {
+                        //  实口户籍地址
+                        addrList.add("上海市" + Constant.getArea() + "区" + AddressQueryEngine.addressReplaceAll(item.get("sk_hjdx(实口户籍)").toString()));
+                    }
+                    if (item.get("sk_jzdz(实口居住)") != null && !item.get("sk_jzdz(实口居住)").toString().isEmpty() && item.get("sk_jzdz(实口居住)").toString().length() > 3 && AddressTools.isOtherDistrictThanSongJiang(item.get("sk_jzdz(实口居住)").toString())) {
+                        //  实口居住地址
+                        addrList.add("上海市" + Constant.getArea() + "区" + AddressQueryEngine.addressReplaceAll(item.get("sk_jzdz(实口居住)").toString()));
+                    }
+                    if (item.get("jc_hjdz(基层户籍)") != null && !item.get("jc_hjdz(基层户籍)").toString().isEmpty() && item.get("jc_hjdz(基层户籍)").toString().length() > 3 && AddressTools.isOtherDistrictThanSongJiang(item.get("jc_hjdz(基层户籍)").toString())) {
+                        //  基层户籍地址
+                        addrList.add("上海市" + Constant.getArea() + "区" + AddressQueryEngine.addressReplaceAll(item.get("jc_hjdz(基层户籍)").toString()));
+                    }
+                    if (item.get("jc_jzdz(基层居住)") != null && !item.get("jc_jzdz(基层居住)").toString().isEmpty() && item.get("jc_jzdz(基层居住)").toString().length() > 3 && AddressTools.isOtherDistrictThanSongJiang(item.get("jc_jzdz(基层居住)").toString())) {
+                        //  基层居住地址
+                        addrList.add("上海市" + Constant.getArea() + "区" + AddressQueryEngine.addressReplaceAll(item.get("jc_jzdz(基层居住)").toString()));
+                    }
+
+                    if (addrList.size() > 0) {
+                        AddressResult addressResult = AddressQueryEngine.getInstance().commonSearchByName(addrList);
+                        if (addressResult != null && addressResult.getData() != null && addressResult.getData().size() > 0) {
+                            for (AddressResult.ContentBean contentBean : addressResult.getData()) {
+                                String resultAddrKey = contentBean.getAddress();
+                                if (resultAddrKey != null && contentBean.getLon() != null && contentBean.getLat() != null && AddressTools.isOtherDistrictThanSongJiang(resultAddrKey)) {
+                                    if (contentBean.getAdname() != null && !contentBean.getAdname().isEmpty()) {
+                                        item.put("所属街镇", contentBean.getAdname());
+                                    } else if (contentBean.getTownJson().getString("name") != null) {
+                                        item.put("所属街镇", contentBean.getTownJson().getString("name"));
+                                    }
+                                    item.put("参考地址", resultAddrKey);
+                                    //  开始规范化地址(把查询地址的市、区、街镇替换为空,然后把得到的区、街镇拼接上去)(得到区、街镇)
+                                    String oldAddress = contentBean.getSearchAddress().replaceAll("上海市", "").replaceAll("松江区", "");
+                                    String[] towns = Constant.getTowns();
+                                    for (String town : towns) {
+                                        oldAddress = oldAddress.replaceAll(town, "");
+                                    }
+                                    if (contentBean.getCjJson() != null && contentBean.getCjJson().containsKey("所属居委")) {
+                                        oldAddress = contentBean.getCjJson().getString("所属居委") + oldAddress;
+                                    }
+                                    item.put("规范化地名地址", "上海市松江区" + item.get("所属街镇") + oldAddress);
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+//          保存新的数据文件
+            ExcelReaderUtils.writeToExcel(fileDatas, "output/松江26487数据治理结果数据_new.xlsx");
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        long endTime = System.currentTimeMillis();
+        System.out.println("处理完成!用时" + (endTime - startTime) / 1000 + "秒!");
+        return "处理完成!用时" + (endTime - startTime) / 1000 + "秒!";
+    }
+
     /**
      * 全量查询表数据并将处理后的结果序列化到本地(待测试)
      *
      * @return
      */
     @PostMapping(value = "/uploadDataBaseDataToLocal", produces = MediaType.APPLICATION_JSON_VALUE)
-    public Object uploadDataBaseDataToLocal(@RequestParam(name = "reAddr") String reAddr,@RequestParam(name = "updateBase") Boolean updateBase) {
+    public Object uploadDataBaseDataToLocal(@RequestParam(name = "reAddr") String reAddr, @RequestParam(name = "updateBase") Boolean updateBase) {
         // 记录程序开始时间
         long startTime = System.currentTimeMillis();
-        testDataService.uploadAllData(reAddr,updateBase);// 记录程序结束时间
+        testDataService.uploadAllData(reAddr, updateBase);// 记录程序结束时间
         long endTime = System.currentTimeMillis();
         return "处理完成!用时" + (endTime - startTime) / 1000 + "秒!";
     }
 
     @GetMapping(value = "/uploadDataBase", produces = MediaType.APPLICATION_JSON_VALUE)
-    public Object uploadDataBase(){
+    public Object uploadDataBase() {
         long startTime = System.currentTimeMillis();
         testDataService.uploadDataBase();
         long endTime = System.currentTimeMillis();

+ 78 - 0
src/main/java/com/skyversation/poiaddr/entity/YyskAddressStandardization.java

@@ -0,0 +1,78 @@
+package com.skyversation.poiaddr.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 地址表模版
+ * @Description  
+ * @Author  LiuMengxiang
+ * @Date 2025-03-25 11:00:00
+ */
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+//@Table ( name ="yysk_*_address_standardization" , schema = "")
+public class YyskAddressStandardization implements Serializable {
+
+	private static final long serialVersionUID =  5402991726683110730L;
+
+	/**
+	 * 搜索地址:主键
+	 */
+	private String address;
+
+	/**
+	 * 省、市
+	 */
+	private String market;
+
+	/**
+	 * 行政区划
+	 */
+	private String distinguish;
+
+	/**
+	 * 街镇
+	 */
+	private String streetTown;
+
+	/**
+	 * 居委
+	 */
+	private String residentialCommittee;
+
+	/**
+	 * 返回参考地址
+	 */
+	private String returnAddress;
+
+	/**
+	 * 标准化地址
+	 */
+	private String standardAddress;
+
+	/**
+	 * 匹配等级
+	 */
+	private String matchLevel;
+
+	/**
+	 * 经度
+	 */
+	private String lat;
+
+	/**
+	 * 纬度
+	 */
+	private String lon;
+	/**
+	 * 更新时间
+	 */
+	private Date updateTime;
+}

+ 2 - 4
src/main/java/com/skyversation/poiaddr/service/AreaService.java

@@ -6,9 +6,7 @@ import com.skyversation.poiaddr.addquery.AddressQueryEngine;
 import com.skyversation.poiaddr.addquery.Constant;
 import com.skyversation.poiaddr.bean.AddressResult;
 import com.skyversation.poiaddr.bean.GeoJsonBean;
-import com.skyversation.poiaddr.entity.SjArrDzbzhSjWcbryDzxx;
 import com.skyversation.poiaddr.service.impl.SjArrDzbzhSjWcbryDzxxServiceImpl;
-import com.skyversation.poiaddr.util.status.AddressLevel;
 import org.geotools.geojson.geom.GeometryJSON;
 import org.geotools.geometry.jts.JTSFactoryFinder;
 import org.locationtech.jts.geom.Geometry;
@@ -81,13 +79,13 @@ public class AreaService {
             System.err.println(">>>>>>>>------网络连通性测试结果:" + e);
         }
 //      TODO 数据库连通性测试
-        try {
+        /*try {
             System.out.println("<<<<<<<<------开始数据库连通性测试");
             List<SjArrDzbzhSjWcbryDzxx> listData = sjArrDzbzhSjWcbryDzxxService.getAllDataPage(1);
             System.out.println(">>>>>>>>------数据库连通性测试结果:" + listData.toString());
         } catch (Exception e) {
             System.err.println(">>>>>>>>------数据库连通性测试结果:" + e);
-        }
+        }*/
     }
 
     public void initPolygons() {

+ 263 - 0
src/main/java/com/skyversation/poiaddr/service/impl/YyskAddressStandardizationServiceImpl.java

@@ -0,0 +1,263 @@
+package com.skyversation.poiaddr.service.impl;
+
+import com.skyversation.poiaddr.addquery.AddressQueryEngine;
+import com.skyversation.poiaddr.bean.AddressResult;
+import com.skyversation.poiaddr.config.DbConnection;
+import com.skyversation.poiaddr.entity.YyskAddressStandardization;
+import com.skyversation.poiaddr.util.ExcelReaderUtils;
+import org.springframework.stereotype.Service;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.*;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+/**
+ * 法人库服务层
+ * 更新操作
+ * 查询操作
+ * 插入操作
+ * 查询dws库的fusion_nfrk_corp_info_partition_dsjzx_v1表的corp_name\real_address字段
+ * 将这两个字段中的非空数据保存到一个Set集合中
+ * 先将这个集合中的数据都插入到yysk_*_address_standardization表中,并作为主键
+ * <p>
+ * 先初始化表,然后每每天凌晨一点跑前一天的更新数据
+ */
+@Service
+public class YyskAddressStandardizationServiceImpl {
+
+    //  下载所有数据到xlsx
+    public void uploadDataBase(String tableName) {
+        try {
+            List<Map<String, Object>> oldDbData = DbConnection.getInstance().runSqlStr("select * FROM " + tableName);
+//          去重
+            Map<String, Map<String, Object>> newRequestData = new HashMap<>();
+            for (Map<String, Object> item : oldDbData) {
+                if (item.get("address") != null) {
+                    newRequestData.put(item.get("address").toString(), item);
+                }
+            }
+            List<Map<String, Object>> dbData = new ArrayList<>();
+            for (String address : newRequestData.keySet()) {
+                dbData.add(newRequestData.get(address));
+            }
+//          直接保存数据到xlsx
+            ExcelReaderUtils.writeToExcel(dbData, "output/" + tableName + ".xlsx");
+        } catch (Exception e) {
+            System.err.println("下载失败!" + e);
+        }
+    }
+
+    //  分页查询地址表
+    public List<YyskAddressStandardization> getAllDataPage(int size, String tableName) {
+        try {
+            List<YyskAddressStandardization> requestData = new ArrayList<>();
+            String sql = "SELECT * FROM " + tableName + " WHERE update_time is null limit " + size;
+            List<Map<String, Object>> dbData = DbConnection.getInstance().runSqlStr(sql);
+            for (Map<String, Object> item : dbData) {
+                YyskAddressStandardization YyskAddressStandardization = new YyskAddressStandardization();
+                if (item.get("address") != null) {
+                    YyskAddressStandardization.setAddress(item.getOrDefault("address", "").toString().trim());
+                }
+                requestData.add(YyskAddressStandardization);
+            }
+            return requestData;
+        } catch (Exception e) {
+            System.err.println("sql运行异常:" + e);
+            return null;
+        }
+    }
+
+    //   批量修改地址表
+    public void updateDatas(List<YyskAddressStandardization> sjArrDzbzhSjWcbryDzxxList, String tableName) {
+        String sqls = "update " + tableName + " set lat = ?,lon = ?,market = ?, distinguish = ?, street_town = ?, residential_committee = ?" +
+                ", return_address = ? , standard_address = ? ,match_level = ? , update_time = ? where address = ?";
+        try (PreparedStatement preparedStatement = DbConnection.getInstance().connection.prepareStatement(sqls)) {
+            for (YyskAddressStandardization entity : sjArrDzbzhSjWcbryDzxxList) {
+                if (entity.getAddress() != null) {
+                    if (entity.getLat() == null) {
+                        preparedStatement.setNull(1, Types.VARCHAR);
+                    } else {
+                        preparedStatement.setString(1, entity.getLat());
+                    }
+                    if (entity.getLon() == null) {
+                        preparedStatement.setNull(2, Types.VARCHAR);
+                    } else {
+                        preparedStatement.setString(2, entity.getLon());
+                    }
+                    if (entity.getMarket() == null) {
+                        preparedStatement.setNull(3, Types.VARCHAR);
+                    } else {
+                        preparedStatement.setString(3, entity.getMarket());
+                    }
+                    if (entity.getDistinguish() == null) {
+                        preparedStatement.setNull(4, Types.VARCHAR);
+                    } else {
+                        preparedStatement.setString(4, entity.getDistinguish());
+                    }
+                    if (entity.getStreetTown() == null) {
+                        preparedStatement.setNull(5, Types.VARCHAR);
+                    } else {
+                        preparedStatement.setString(5, entity.getStreetTown());
+                    }
+                    if (entity.getResidentialCommittee() == null) {
+                        preparedStatement.setNull(6, Types.VARCHAR);
+                    } else {
+                        preparedStatement.setString(6, entity.getResidentialCommittee());
+                    }
+                    if (entity.getReturnAddress() == null) {
+                        preparedStatement.setNull(7, Types.VARCHAR);
+                    } else {
+                        preparedStatement.setString(7, entity.getReturnAddress());
+                    }
+                    if (entity.getStandardAddress() == null) {
+                        preparedStatement.setNull(8, Types.VARCHAR);
+                    } else {
+                        preparedStatement.setString(8, entity.getStandardAddress());
+                    }
+                    if (entity.getMatchLevel() == null) {
+                        preparedStatement.setNull(9, Types.VARCHAR);
+                    } else {
+                        preparedStatement.setString(9, entity.getMatchLevel());
+                    }
+                    if (entity.getUpdateTime() == null) {
+                        preparedStatement.setNull(10, Types.DATE);
+                    } else {
+                        preparedStatement.setDate(10, new java.sql.Date(entity.getUpdateTime().getTime()));
+                    }
+                    preparedStatement.setString(11, entity.getAddress());
+                    // 将当前的 SQL 语句添加到批量操作中
+                    preparedStatement.addBatch();
+                }
+            }
+            // 执行批量操作
+            int[] updateCounts = preparedStatement.executeBatch();
+            System.out.println("总条数:" + sjArrDzbzhSjWcbryDzxxList.size() + ";更新的记录数: " + updateCounts.length);
+        } catch (SQLException throwables) {
+            System.err.println("------updateError--------------------------------------" + sqls + "更新异常!");
+            throwables.printStackTrace();
+            System.err.println("更新异常" + throwables);
+        }
+    }
+
+    /**
+     * 首先要得到一个Page<T>对象,然后判断是否还有别的数据,有的话接着请求并返回新的Page<T>对象并迭代处理数据
+     * init [0:批量处理;1:初始化]
+     */
+    public void iterativeProcessing(Integer pageSize, Integer init, String tableName) {
+        System.out.println("<<<<<<<<------iterativeProcessing{pageSize:" + pageSize + "}");
+        long startTime = System.currentTimeMillis();
+        if (init == 0) {
+            List<YyskAddressStandardization> listData = getAllDataPage(pageSize, tableName);
+            if (listData != null && listData.size() > 0) {
+//              批量更新处理后的数据
+                updateDatas(runExecutorService(listData), tableName);
+                long endTime = System.currentTimeMillis();
+                System.out.println("处理单批次用时" + (endTime - startTime) / 1000 + "秒!");
+                if (listData.size() > 0) {
+                    iterativeProcessing(pageSize, init, tableName);
+                } else {
+                    System.out.println("<<<<<<<<------任务处理完成!");
+                }
+            } else {
+                System.out.println("<<<<<<<<------任务处理完成!");
+            }
+        } else {
+            String SqlStr = "update " + tableName + " set lat = null,lon = null,market = null, distinguish = null, street_town = null, residential_committee = null , return_address = null , standard_address = null ,match_level = null ,update_time = null where update_time is not null";
+            try {
+                int updateDataSum = DbConnection.getInstance().updateSql(SqlStr);
+                if (updateDataSum < 1) {
+                    System.err.println("------updateError--------------------------------------" + SqlStr + "更新异常!");
+                }
+                System.out.println("<<<<<<<<------任务处理完成!");
+                long endTime = System.currentTimeMillis();
+                System.out.println("处理单批次用时" + (endTime - startTime) / 1000 + "秒!");
+            } catch (Exception e) {
+                System.err.println("更新异常" + e);
+            }
+        }
+    }
+
+    public List<YyskAddressStandardization> runExecutorService(List<YyskAddressStandardization> listData) {
+        // 创建线程池
+        ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
+        List<Future<?>> futures = new ArrayList<>();
+        for (YyskAddressStandardization item : listData) {
+            futures.add(executorService.submit(() -> {
+                List<String> addrList = new ArrayList<>();
+                if (item.getAddress() != null && !item.getAddress().isEmpty()) {
+                    addrList.add(item.getAddress());
+                }
+                if (addrList.size() > 0) {
+                    //  TODO 开始查询
+                    AddressResult addressResult = AddressQueryEngine.getInstance().commonSearchByName(addrList);
+                    if (addressResult == null || addressResult.getData() == null || addressResult.getData().size() < 1) {
+                        item.setMatchLevel("异常");
+                        item.setReturnAddress("未匹配到符合规则的结果");
+                    } else {
+                        try {
+                            for (AddressResult.ContentBean contentBean : addressResult.getData()) {
+                                String resultAddrKey = contentBean.getAddress();
+//                                && AddressTools.isOtherDistrictThanShangHai(resultAddrKey)
+                                if (resultAddrKey != null && contentBean.getLon() != null && contentBean.getLat() != null) {
+                                    String lng = contentBean.getLon() + "";
+                                    String lat = contentBean.getLat() + "";
+                                    if (contentBean.getAdname() != null && !contentBean.getAdname().isEmpty()) {
+                                        item.setStreetTown(contentBean.getAdname());
+                                    } else if (contentBean.getTownJson().getString("name") != null) {
+                                        item.setStreetTown(contentBean.getTownJson().getString("name"));
+                                    } else {
+                                        item.setStreetTown("");
+                                    }
+                                    if (contentBean.getCityname() != null && !contentBean.getCityname().isEmpty()) {
+                                        item.setMarket(contentBean.getCityname());
+                                    } else if (contentBean.getAdJson().getString("name") != null) {
+                                        item.setMarket(contentBean.getAdJson().getString("name"));
+                                    } else {
+                                        item.setMarket("");
+                                    }
+                                    item.setLat(lat);
+                                    item.setLon(lng);
+                                    item.setReturnAddress(resultAddrKey);
+                                    item.setMatchLevel(contentBean.getScore());
+                                    String oldAddress = contentBean.getSearchAddress().replaceAll(item.getMarket(), "").replaceAll(item.getDistinguish(), "").replaceAll(item.getStreetTown(), "");
+                                    if (contentBean.getCjJson() != null && contentBean.getCjJson().containsKey("所属居委")) {
+                                        item.setResidentialCommittee(contentBean.getCjJson().getString("所属居委"));
+                                        oldAddress = contentBean.getCjJson().getString("所属居委") + oldAddress;
+                                    }
+                                    item.setStandardAddress(item.getMarket() + item.getDistinguish() + item.getStreetTown() + oldAddress);
+                                    break;
+                                } else {
+                                    item.setMatchLevel("异常");
+                                    item.setReturnAddress("结果处理异常");
+                                }
+                            }
+                        } catch (Exception e) {
+                            item.setMatchLevel("异常");
+                            System.err.println("查询结果处理异常:" + e);
+                        }
+                    }
+                } else {
+                    item.setMatchLevel("否");
+                }
+                item.setUpdateTime(new Date());
+            }));
+        }
+
+        // 等待所有任务完成
+        for (Future<?> future : futures) {
+            try {
+                future.get();
+            } catch (InterruptedException | ExecutionException e) {
+                System.err.println("线程异常:" + e);
+            }
+        }
+        // 关闭线程池
+        executorService.shutdown();
+        return listData;
+    }
+}

+ 25 - 5
src/main/java/com/skyversation/poiaddr/util/AddressTools.java

@@ -256,10 +256,7 @@ public class AddressTools {
 
         // 松江区
         Set<String> songjiangStreets = new HashSet<>(Arrays.asList(
-                "中山街道", "方松街道", "永丰街道", "岳阳街道",
-                "泗泾镇", "佘山镇", "车墩镇", "新桥镇", "洞泾镇",
-                "九亭镇", "泖港镇", "石湖荡镇", "新浜镇", "叶榭镇",
-                "小昆山镇"
+                "岳阳街道", "永丰街道", "方松街道", "中山街道", "广富林街道", "九里亭街道", "泗泾镇", "佘山镇", "车墩镇", "新桥镇", "洞泾镇", "九亭镇", "泖港镇", "石湖荡镇", "新浜镇", "叶榭镇", "小昆山镇"
         ));
         DISTRICT_STREETS.put("松江区", songjiangStreets);
 
@@ -490,7 +487,8 @@ public class AddressTools {
         for (int i = 0; i < array.size(); i++) {
             JSONObject obj = array.getJSONObject(i);
             obj.put("searchAddress", address);
-            if (obj.containsKey(param) && obj.get(param) != null && !obj.getString(param).trim().isEmpty() && obj.getString(param).contains(Constant.getArea())) {
+//            && obj.getString(param).contains(Constant.getArea())
+            if (obj.containsKey(param) && obj.get(param) != null && !obj.getString(param).trim().isEmpty()) {
 //              得到返回的地址
                 String addr = obj.getString(param);
 //              规则4判断
@@ -576,6 +574,28 @@ public class AddressTools {
         return true;
     }
 
+
+    public static boolean isOtherDistrictThanShangHai(String address) {
+        // 将地址字符串转换为小写,以便进行不区分大小写的比较
+        String lowerCaseAddress = address.toLowerCase();
+        // 列出上海市的其他区(已补充完整)
+        String[] otherDistricts = {"北京市", "天津市", "重庆市",
+                "河北省", "山西省", "辽宁省", "吉林省", "黑龙江省",
+                "江苏省", "浙江省", "安徽省", "福建省", "江西省",
+                "山东省", "河南省", "湖北省", "湖南省", "广东省",
+                "海南省", "四川省", "贵州省", "云南省", "陕西省",
+                "甘肃省", "青海省", "台湾省",
+                "内蒙古自治区", "广西壮族自治区", "西藏自治区",
+                "宁夏回族自治区", "新疆维吾尔自治区",
+                "香港特别行政区", "澳门特别行政区"};
+        for (String district : otherDistricts) {
+            if (lowerCaseAddress.contains(district.toLowerCase()) || lowerCaseAddress.indexOf(district.substring(0, 2)) == 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     /***
      * 其他方法的引用方法,不用管
      * @param input

+ 40 - 5
src/main/java/com/skyversation/poiaddr/util/SerializationUtils.java

@@ -4,14 +4,16 @@ import com.skyversation.poiaddr.entity.SjArrDzbzhSjWcbryDzxx;
 
 import java.io.*;
 import java.util.List;
+import java.util.Map;
 
 public class SerializationUtils {
 
     /**
      * 将 List<T> 序列化并保存到本地文件
-     * @param list 要序列化的 List
+     *
+     * @param list     要序列化的 List
      * @param filePath 保存文件的路径
-     * @param <T> 泛型类型
+     * @param <T>      泛型类型
      */
     public static <T extends Serializable> void serialize(List<T> list, String filePath) {
         try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath))) {
@@ -24,8 +26,9 @@ public class SerializationUtils {
 
     /**
      * 从本地文件中反序列化读取 List<T>
+     *
      * @param filePath 读取文件的路径
-     * @param <T> 泛型类型
+     * @param <T>      泛型类型
      * @return 反序列化后的 List
      */
     @SuppressWarnings("unchecked")
@@ -41,8 +44,40 @@ public class SerializationUtils {
     }
 
     public static void main(String[] args) throws IOException {
-        List<SjArrDzbzhSjWcbryDzxx> listData = deserialize("output/testDataBase_all.ser");
+        test();
+        /*List<SjArrDzbzhSjWcbryDzxx> listData = deserialize("output/testDataBase_all.ser");
 //      将序列化的文件转储为xlsx文件
-        ExcelReaderUtils.writeClassToExcel(listData, "output/allData.xlsx");
+        ExcelReaderUtils.writeClassToExcel(listData, "output/allData.xlsx");*/
+    }
+
+    /**
+     * 读取本地xlsx文件得到List<Map<String,Object>>结果,然后得到所有规范化结果地址字段,然后匹配街镇关键字,并将匹配到的街镇关键字放到新的一列
+     */
+    public static void test() {
+//       街镇关键字
+        String[] towns = new String[]{"岳阳街道", "永丰街道", "方松街道", "中山街道", "广富林街道", "九里亭街道", "泗泾镇", "佘山镇", "车墩镇", "新桥镇", "洞泾镇", "九亭镇", "泖港镇", "石湖荡镇", "新浜镇", "叶榭镇", "小昆山镇"};
+//       根据地址读取xlsx数据
+        try {
+            List<Map<String, Object>> fileDatas = ExcelReaderUtils.readExcel("C:\\Users\\Liumouren\\Desktop\\松江26487数据治理结果数据-sh2000-20250313(1).xlsx");
+//            得到所有规范化结果地址字段
+            for (Map<String, Object> item : fileDatas) {
+                if (item.containsKey("规范化地名地址") && item.get("规范化地名地址") != null && !item.get("规范化地名地址").toString().trim().isEmpty()) {
+                    String address = item.get("规范化地名地址").toString().trim();
+//                    匹配街镇关键字,并将匹配到的街镇关键字放到新的一列
+                    String town = "";
+                    for (String tItem : towns) {
+                        if (address.contains(tItem)) {
+                            town = tItem;
+                            break;
+                        }
+                    }
+                    item.put("所属街镇", town);
+                }
+            }
+//          将新的数据重新保存为一个新的文件
+            ExcelReaderUtils.writeToExcel(fileDatas, "output/松江26487数据治理结果数据.xlsx");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
     }
 }

+ 1 - 1
src/main/resources/application.properties

@@ -29,7 +29,7 @@ spring.servlet.multipart.max-request-size=300MB
 #spring.jpa.hibernate.ddl-auto=update
 #spring.jpa.show-sql=false
 # \u677E\u6C5F\u8857\u9547
-app.area=\u677E\u6C5F
+app.area=\u4E0A\u6D77
 app.town=\u5CB3\u9633\u8857\u9053\u3001\u6C38\u4E30\u8857\u9053\u3001\u65B9\u677E\u8857\u9053\u3001\u4E2D\u5C71\u8857\u9053\u3001\u5E7F\u5BCC\u6797\u8857\u9053\u3001\u4E5D\u91CC\u4EAD\u8857\u9053\u3001\u6CD7\u6CFE\u9547\u3001\u4F58\u5C71\u9547\u3001\u8F66\u58A9\u9547\u3001\u65B0\u6865\u9547\u3001\u6D1E\u6CFE\u9547\u3001\u4E5D\u4EAD\u9547\u3001\u6CD6\u6E2F\u9547\u3001\u77F3\u6E56\u8361\u9547\u3001\u65B0\u6D5C\u9547\u3001\u53F6\u69AD\u9547\u3001\u5C0F\u6606\u5C71\u9547
 # \u878D\u5408\u7248\uFF1A1736930075105|\u5173\u952E\u5B57\uFF1A1742459783686
 app.search_server_id=1742459783686