Quellcode durchsuchen

新增松江地名地址库互联网治理版本

zhanghan vor 2 Monaten
Ursprung
Commit
4aa6a9cd8f

+ 27 - 0
src/main/java/com/skyversation/poiaddr/addquery/AddressQueryEngine.java

@@ -60,6 +60,33 @@ public class AddressQueryEngine {
         return addressResult;
     }
 
+    /***
+     * 市四中心地名搜索
+     * @param address
+     * @return
+     */
+    public AddressResult szxSearchByName(String address){
+        System.out.println("<<<<<<<<<<----------开始四中心互联网地名地址搜索------------>>>>>>>>>>>>>");
+        if(address.startsWith("上海")){
+            address = "上海市" + address;
+        }
+        System.out.println("<<<<<<<<<<---URL: " + address + "--->>>>>>>>>>>>>");
+        ResponseEntity response = AddressNetTools.getInstance().requestGetOrPost(HttpMethod.GET, Constant.SZX_HLW_URL + address, null, null, 0);
+
+        if(response == null){
+            return 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, address);
+        } catch (Exception e){
+            return AddressTools.getInstance().faildQuery(AddressResultEnum.DATA_FROMAT_FAILD, "格式化失败");
+        }
+    }
+
     /***
      * 武大吉奥单条地名搜索
      * @param address

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

@@ -55,6 +55,8 @@ 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";
+    public static final String SZX_HLW_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=";
+
     //    TODO 服务器融合版地名地址接口
 //    public static final String SJ_SZX_SEARCH_BY_NAME = "http://172.30.77.19:8081/openapi/1736930075105";
     //    TODO 关键字模糊搜索服务

+ 175 - 0
src/main/java/com/skyversation/poiaddr/util/AddressMatcher.java

@@ -0,0 +1,175 @@
+package com.skyversation.poiaddr.util;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class AddressMatcher {
+
+    // 静态数据存储省市信息,包含简称映射
+    private static final Map<String, List<String>> PROVINCE_CITY_MAP = new HashMap<>();
+    private static final Map<String, String> ABBREVIATION_PROVINCE_MAP = new HashMap<>();
+    private static final Map<String, String> ABBREVIATION_CITY_MAP = new HashMap<>();
+    private static final Map<String, String> CITY_PROVINCE_MAP = new HashMap<>();
+
+    static {
+        // 初始化数据
+        addProvinceAndCities("北京市", "东城区", "西城区", "朝阳区", "丰台区", "石景山区", "海淀区", "门头沟区", "房山区", "通州区", "顺义区", "昌平区", "大兴区", "怀柔区", "平谷区", "密云区", "延庆区");
+        addProvinceAndCities("天津市", "和平区", "河东区", "河西区", "南开区", "河北区", "红桥区", "东丽区", "西青区", "津南区", "北辰区", "武清区", "宝坻区", "滨海新区", "宁河区", "静海区", "蓟州区");
+        addProvinceAndCities("河北省", "石家庄市", "唐山市", "秦皇岛市", "邯郸市", "邢台市", "保定市", "张家口市", "承德市", "沧州市", "廊坊市", "衡水市");
+        addProvinceAndCities("山西省", "太原市", "大同市", "阳泉市", "长治市", "晋城市", "朔州市", "晋中市", "运城市", "忻州市", "临汾市", "吕梁市");
+        addProvinceAndCities("内蒙古自治区", "呼和浩特市", "包头市", "乌海市", "赤峰市", "通辽市", "鄂尔多斯市", "呼伦贝尔市", "巴彦淖尔市", "乌兰察布市");
+        addProvinceAndCities("辽宁省", "沈阳市", "大连市", "鞍山市", "抚顺市", "本溪市", "丹东市", "锦州市", "营口市", "阜新市", "辽阳市", "盘锦市", "铁岭市", "朝阳市", "葫芦岛市");
+        addProvinceAndCities("吉林省", "长春市", "吉林市", "四平市", "辽源市", "通化市", "白山市", "松原市", "白城市");
+        addProvinceAndCities("黑龙江省", "哈尔滨市", "齐齐哈尔市", "鸡西市", "鹤岗市", "双鸭山市", "大庆市", "伊春市", "佳木斯市", "七台河市", "牡丹江市", "黑河市", "绥化市");
+        addProvinceAndCities("上海市", "黄浦区", "徐汇区", "长宁区", "静安区", "普陀区", "虹口区", "杨浦区", "闵行区", "宝山区", "嘉定区", "浦东新区", "金山区", "松江区", "青浦区", "奉贤区", "崇明区");
+        addProvinceAndCities("江苏省", "南京市", "无锡市", "徐州市", "常州市", "苏州市", "南通市", "连云港市", "淮安市", "盐城市", "扬州市", "镇江市", "泰州市", "宿迁市");
+        addProvinceAndCities("浙江省", "杭州市", "宁波市", "温州市", "嘉兴市", "湖州市", "绍兴市", "金华市", "衢州市", "舟山市", "台州市", "丽水市");
+        addProvinceAndCities("安徽省", "合肥市", "芜湖市", "蚌埠市", "淮南市", "马鞍山市", "淮北市", "铜陵市", "安庆市", "黄山市", "阜阳市", "宿州市", "滁州市", "六安市", "宣城市", "池州市", "亳州市");
+        addProvinceAndCities("福建省", "福州市", "厦门市", "莆田市", "三明市", "泉州市", "漳州市", "南平市", "龙岩市", "宁德市");
+//        addProvinceAndCities("江西省", "南昌市", "景德镇市", "萍乡市", "九江市", "新余市", "鹰潭市", "赣州市", "吉安市", "宜春市", "抚州市", "上饶市");
+        addProvinceAndCities("江西省", "南昌市", "景德镇市", "萍乡市", "九江市", "鹰潭市", "赣州市", "吉安市", "宜春市", "抚州市", "上饶市");
+        addProvinceAndCities("山东省", "济南市", "青岛市", "淄博市", "枣庄市", "东营市", "烟台市", "潍坊市", "济宁市", "泰安市", "威海市", "日照市", "临沂市", "德州市", "聊城市", "滨州市", "菏泽市");
+        addProvinceAndCities("河南省", "郑州市", "开封市", "洛阳市", "平顶山市", "安阳市", "鹤壁市", "新乡市", "焦作市", "濮阳市", "许昌市", "漯河市", "三门峡市", "南阳市", "商丘市", "信阳市", "周口市", "驻马店市");
+        addProvinceAndCities("湖北省", "武汉市", "黄石市", "十堰市", "宜昌市", "襄阳市", "鄂州市", "荆门市", "孝感市", "荆州市", "黄冈市", "咸宁市", "随州市");
+        addProvinceAndCities("湖南省", "长沙市", "株洲市", "湘潭市", "衡阳市", "邵阳市", "岳阳市", "常德市", "张家界市", "益阳市", "郴州市", "永州市", "怀化市", "娄底市");
+//        addProvinceAndCities("广东省", "广州市", "深圳市", "珠海市", "汕头市", "佛山市", "韶关市", "湛江市", "肇庆市", "江门市", "茂名市", "惠州市", "梅州市", "汕尾市", "河源市", "阳江市", "清远市", "东莞市", "中山市", "潮州市", "揭阳市", "云浮市");
+        addProvinceAndCities("广东省", "广州市", "深圳市", "珠海市", "汕头市", "佛山市", "韶关市", "湛江市", "肇庆市", "江门市", "茂名市", "惠州市", "梅州市", "汕尾市", "河源市", "阳江市", "清远市", "东莞市", "潮州市", "揭阳市", "云浮市");
+        addProvinceAndCities("广西自治区", "南宁市", "柳州市", "桂林市", "梧州市", "北海市", "防城港市", "钦州市", "贵港市", "玉林市", "百色市", "贺州市", "河池市", "来宾市", "崇左市");
+        addProvinceAndCities("海南省", "海口市", "三亚市", "三沙市", "儋州市");
+        addProvinceAndCities("重庆市", "万州区", "黔江区", "涪陵区", "渝中区", "大渡口区", "江北区", "沙坪坝区", "九龙坡区", "南岸区", "北碚区", "綦江区", "大足区", "渝北区", "巴南区", "黔江区", "长寿区", "江津区", "合川区", "永川区", "南川区", "璧山区", "铜梁区", "潼南县", "荣昌区", "开州区", "梁平区", "武隆区", "城口县", "丰都县", "垫江县", "忠县", "云阳县", "奉节县", "巫山县", "巫溪县");
+        addProvinceAndCities("四川省", "成都市", "自贡市", "攀枝花市", "泸州市", "德阳市", "绵阳市", "广元市", "遂宁市", "内江市", "乐山市", "南充市", "眉山市", "宜宾市", "广安市", "达州市", "雅安市", "巴中市", "资阳市");
+        addProvinceAndCities("贵州省", "贵阳市", "六盘水市", "遵义市", "安顺市", "毕节市", "铜仁市");
+        addProvinceAndCities("云南省", "昆明市", "曲靖市", "玉溪市", "保山市", "昭通市", "丽江市", "普洱市", "临沧市");
+        addProvinceAndCities("西藏自治区", "拉萨市", "日喀则市", "昌都市", "林芝市", "山南市", "那曲市", "阿里地区");
+        addProvinceAndCities("陕西省", "西安市", "铜川市", "宝鸡市", "咸阳市", "渭南市", "延安市", "汉中市", "榆林市", "安康市", "商洛市");
+        addProvinceAndCities("甘肃省", "兰州市", "嘉峪关市", "金昌市", "白银市", "天水市", "武威市", "张掖市", "平凉市", "酒泉市", "庆阳市", "定西市", "陇南市");
+        addProvinceAndCities("青海省", "西宁市", "海东市");
+        addProvinceAndCities("宁夏自治区", "银川市", "石嘴山市", "吴忠市", "固原市", "中卫市");
+        addProvinceAndCities("新疆自治区", "乌鲁木齐市", "克拉玛依市", "吐鲁番市", "哈密市");
+
+        // 生成简称映射
+        generateAbbreviations();
+        // 生成城市到省份的映射
+        generateCityProvinceMap();
+    }
+
+    private static void addProvinceAndCities(String province, String... cities) {
+        PROVINCE_CITY_MAP.put(province, Arrays.asList(cities));
+    }
+
+    private static void generateAbbreviations() {
+        for (String province : PROVINCE_CITY_MAP.keySet()) {
+            String abbreviation = province.replaceAll("省|市|自治区", "");
+            ABBREVIATION_PROVINCE_MAP.put(abbreviation, province);
+        }
+        for (Map.Entry<String, List<String>> entry : PROVINCE_CITY_MAP.entrySet()) {
+            for (String city : entry.getValue()) {
+                String abbreviation = city.replaceAll("市|区|县", "");
+                ABBREVIATION_CITY_MAP.put(abbreviation, city);
+            }
+        }
+    }
+
+    private static void generateCityProvinceMap() {
+        for (Map.Entry<String, List<String>> entry : PROVINCE_CITY_MAP.entrySet()) {
+            String province = entry.getKey();
+            for (String city : entry.getValue()) {
+                CITY_PROVINCE_MAP.put(city, province);
+            }
+        }
+    }
+
+    /**
+     * 根据输入的地址匹配省和市
+     * @param address 输入的地址
+     * @return 包含省和市的数组,若未匹配到则返回 null
+     */
+    public static String[] matchProvinceAndCity(String address) {
+        // 先尝试匹配完整的省份名称
+        for (String province : PROVINCE_CITY_MAP.keySet()) {
+            if (address.contains(province)) {
+                for (String city : PROVINCE_CITY_MAP.get(province)) {
+                    if (address.contains(city) &&!isPartOfRoadName(address, city)) {
+                        return new String[]{province, city};
+                    }
+                }
+                if (isMunicipality(province)) {
+                    return new String[]{province, province};
+                }
+            }
+        }
+
+        // 尝试匹配省份简称
+        for (Map.Entry<String, String> entry : ABBREVIATION_PROVINCE_MAP.entrySet()) {
+            String abbreviation = entry.getKey();
+            String province = entry.getValue();
+            if (address.contains(abbreviation) &&!isPartOfRoadName(address, abbreviation)) {
+                for (String city : PROVINCE_CITY_MAP.get(province)) {
+                    String cityAbbreviation = city.replaceAll("市", "");
+                    if (address.contains(cityAbbreviation) &&!isPartOfRoadName(address, cityAbbreviation)) {
+                        return new String[]{province, city};
+                    }
+                }
+                if (isMunicipality(province)) {
+                    return new String[]{province, province};
+                }
+            }
+        }
+
+        // 尝试根据城市反向查找省份
+        for (Map.Entry<String, String> entry : ABBREVIATION_CITY_MAP.entrySet()) {
+            String cityAbbreviation = entry.getKey();
+            String city = entry.getValue();
+            if(address.contains("开封")){
+                address.toString();
+            }
+            if (address.contains(cityAbbreviation) &&!isPartOfRoadName(address, cityAbbreviation)) {
+                String province = CITY_PROVINCE_MAP.get(city);
+                if (province != null) {
+                    return new String[]{province, city};
+                }
+            }
+        }
+
+        return null;
+    }
+
+    private static boolean isMunicipality(String province) {
+        return province.equals("北京市") || province.equals("天津市") || province.equals("上海市") || province.equals("重庆市");
+    }
+
+    private static boolean isPartOfRoadName(String address, String name) {
+        boolean is = address.contains(name + "路") || address.contains(name + "大道") || address.contains(name + "街");
+        if(!is){
+            int index = address.indexOf(name) + name.length();
+            if("路道街".contains(address.substring((index + 1) >= address.length() ? address.length() - 1 : (index + 1),
+                    (index + 2) > address.length() ? address.length() : (index + 2)))){
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+
+    public static void main(String[] args) {
+        String address = "石家庄开封南路正定县新疆路123号";
+//        String address = "上海静安南京南路123弄56号B座1204室";
+//        String address = "河北石家庄正定县新疆路123号";
+//        String address = "河北石家庄正定县新疆路123号";
+//        String address = "河北石家庄正定县新疆路123号";
+//        String address = "河北石家庄正定县新疆路123号";
+//        String address = "河北石家庄正定县新疆路123号";
+        String[] result = matchProvinceAndCity(address);
+        if (result != null) {
+            System.out.println("省: " + result[0]);
+            System.out.println("市: " + result[1]);
+        } else {
+            System.out.println("未匹配到省和市");
+        }
+    }
+
+
+}

+ 140 - 1
src/main/java/com/skyversation/poiaddr/util/AddressTools.java

@@ -5,7 +5,17 @@ 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.bean.GeoJsonBean;
+import org.geotools.geojson.geom.GeometryJSON;
+import org.geotools.geometry.jts.JTSFactoryFinder;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.MultiPolygon;
+import org.locationtech.jts.io.ParseException;
+import org.locationtech.jts.io.WKTReader;
+import org.springframework.util.ResourceUtils;
+import org.springframework.util.StringUtils;
+
+import java.io.*;
 import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -291,6 +301,9 @@ public class AddressTools {
      * @return 上海市,松江区,车墩镇,乐都路590号
      */
     public static String[] parseAddressJZ(String address) {
+        if(!StringUtils.hasText(address)){
+            return null;
+        }
         String[] result = new String[4];
         result[0] = "上海市";
 
@@ -712,6 +725,27 @@ public class AddressTools {
         return matchScore >= 0.65 ? matchScore : 0;
     }
 
+    public static List<GeoJsonBean> qxPolygonList = new ArrayList<>();
+    public static List<GeoJsonBean> jzPolygonList = new ArrayList<>();
+    public static List<GeoJsonBean> cjPolygonList = new ArrayList<>();
+    public static List<GeoJsonBean> cjSh2000PolygonList = new ArrayList<>();
+    public static WKTReader reader = new WKTReader(JTSFactoryFinder.getGeometryFactory());
+
+    /***
+     * 初始化上海市84坐标系下的,区划、街镇、村居矢量数据
+     */
+    public void initSHQH(){
+        List<List<GeoJsonBean>> lis = new ArrayList<>();
+        lis.add(qxPolygonList);
+        lis.add(jzPolygonList);
+        lis.add(cjPolygonList);
+        lis.add(cjSh2000PolygonList);
+
+        initPolygon(new String[]{"classpath:geojson/上海市_区县边界.geojson", "classpath:geojson/上海市_乡镇边界.geojson",
+                        "classpath:geojson/上海市_村居边界.geojson", "classpath:geojson/上海市_村居边界_sh2000.geojson"},
+                lis);
+    }
+
     private static class AddressInfo {
         String prefixText;
         String firstNumber;
@@ -722,6 +756,111 @@ public class AddressTools {
         }
     }
 
+    private void initPolygon(String[] path, List<List<GeoJsonBean>> list){
+        for(int j = 0; j < path.length; j ++){
+            BufferedReader br = null;
+            try {
+                File file = ResourceUtils.getFile(path[j]);
+                br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
+                String line = br.readLine();
+                StringBuilder sb = new StringBuilder();
+                while (line != null) {
+                    sb.append(line + "\r\n");
+                    line = br.readLine();
+                }
+                JSONObject json = JSONObject.parseObject(sb.toString());
+
+                JSONArray featrues = json.getJSONArray("features");
+
+                for(int i = 0; i < featrues.size(); i ++){
+                    Map<String, GeoJsonBean> map = new HashMap<>();
+                    JSONObject properties = featrues.getJSONObject(i).getJSONObject("properties");
+                    JSONObject geoJson = new JSONObject();
+                    geoJson.put("type", "MultiPolygon");
+                    geoJson.put("coordinates",
+                            featrues.getJSONObject(i).getJSONObject("geometry").getJSONArray("coordinates"));
+
+                    GeometryJSON geometryJSON = new GeometryJSON();
+                    MultiPolygon multiPolygon = geometryJSON.readMultiPolygon(geoJson.toJSONString());
+                    GeoJsonBean geoJsonBean = new GeoJsonBean();
+                    geoJsonBean.setProperties(properties);
+                    geoJsonBean.setMultiPolygon(multiPolygon);
+                    list.get(j).add(geoJsonBean);
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+                System.out.println("<<<<<<<<------  初始化行政区划报错  ------>>>>>>>>>");
+            }
+        }
+
+        System.out.println("<<<<<<<<------  初始化行政区划完成  ------>>>>>>>>>");
+    }
+
+    public JSONObject isQXInPolygon(double lon, double lat){
+        Geometry point = null;
+        try {
+            point = reader.read("POINT (" + lon + " " + lat + ")");
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+
+        for(GeoJsonBean bean : qxPolygonList){
+            if(bean.getMultiPolygon().contains(point)){
+                return bean.getProperties();
+            }
+        }
+        return null;
+    }
+
+
+    public JSONObject isJZInPolygon(double lon, double lat){
+        Geometry point = null;
+        try {
+            point = reader.read("POINT (" + lon + " " + lat + ")");
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+
+        for(GeoJsonBean bean : jzPolygonList){
+            if(bean.getMultiPolygon().contains(point)){
+                return bean.getProperties();
+            }
+        }
+        return null;
+    }
+
+    public JSONObject isCJInPolygon(double lon, double lat){
+        Geometry point = null;
+        try {
+            point = reader.read("POINT (" + lon + " " + lat + ")");
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+
+        for(GeoJsonBean bean : cjPolygonList){
+            if(bean.getMultiPolygon().contains(point)){
+                return bean.getProperties();
+            }
+        }
+        return null;
+    }
+
+    public JSONObject isCJSH2000InPolygon(double x, double y){
+        Geometry point = null;
+        try {
+            point = reader.read("POINT (" + x + " " + y + ")");
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+
+        for(GeoJsonBean bean : cjSh2000PolygonList){
+            if(bean.getMultiPolygon().contains(point)){
+                return bean.getProperties();
+            }
+        }
+        return null;
+    }
+
 
     /***
      * 去除特殊字符,仅保留中文、数字、字母

+ 2 - 2
src/main/java/com/skyversation/poiaddr/util/net/AddressNetTools.java

@@ -49,8 +49,8 @@ public class AddressNetTools {
     @Async
     public ResponseEntity requestGetOrPost(HttpMethod httpMethod, String url, JSONObject params, Map<String, String> headerMap, Integer ifReloadSize) {
         SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
-        requestFactory.setConnectTimeout(1500);
-        requestFactory.setReadTimeout(1500);
+        requestFactory.setConnectTimeout(50000);
+        requestFactory.setReadTimeout(50000);
         RestTemplate client = new RestTemplate(requestFactory);
         client.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
         HttpHeaders headers = new HttpHeaders();

+ 296 - 0
src/main/java/com/skyversation/poiaddr/util/松江地名地址库治理.java

@@ -0,0 +1,296 @@
+package com.skyversation.poiaddr.util;
+
+
+import com.skyversation.poiaddr.addquery.AddressQueryEngine;
+import com.skyversation.poiaddr.bean.AddressResult;
+import com.skyversation.poiaddr.util.status.AddressResultEnum;
+import org.springframework.util.StringUtils;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class 松江地名地址库治理 {
+
+//    public static String path = "D:\\1.项目\\5. 松江项目\\4. 地名地址\\地名地址库治理数据\\output\\-合并.xlsx";
+//    public static String outPath = "D:\\1.项目\\5. 松江项目\\4. 地名地址\\地名地址库治理数据\\output\\补充-错误";
+
+    // 0-411
+    public static String path = "D:\\1.项目\\5. 松江项目\\4. 地名地址\\地名地址库治理数据\\原始数据\\datas\\yysk_dmdz_address_standardization_200000_";
+    public static String outPath = "D:\\1.项目\\5. 松江项目\\4. 地名地址\\地名地址库治理数据\\output\\yysk_dmdz_address_standardization_200000_result_";
+
+
+    public static void main(String[] args) {
+        松江地名地址库治理 instance = new 松江地名地址库治理();
+//        instance.sjAddressZL(900000, path, outPath, "address");
+        AddressTools.getInstance().initSHQH();
+
+        // 任务总数
+        int totalTasks = 412;
+        // 最大线程数
+        int maxThreads = 6;
+
+        // 创建一个固定大小的线程池
+        ExecutorService executorService = Executors.newFixedThreadPool(maxThreads);
+
+        // 提交任务到线程池
+        for (int i = 0; i < totalTasks; i++) {
+            final int taskId = i;
+            executorService.submit(() -> {
+                // 任务执行
+                System.out.println("<<<<<<------Executing task: " + taskId + " on thread: " + Thread.currentThread().getName() + "------>>>>>>>>");
+                instance.sjAddressZL(30000, path + taskId + ".xlsx", outPath + taskId + ".xlsx", "address");
+            });
+        }
+
+        // 关闭线程池
+        executorService.shutdown();
+    }
+
+    public void sjAddressZL(int threadSize, String path, String outPath, String addressParam){
+
+        List<Map<String, Object>> listAddr = null;
+        try {
+            listAddr = ExcelReaderUtils.readExcel(path);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        int num = 1;
+//        List<Map<String, Object>> lis = new ArrayList<>();
+//        for(Map<String, Object> map : listAddr){
+//            if((map.get("standardAddress") + "").contains("异常") || (map.get("standardAddress") + "").contains("rule_0")){
+//                lis.add(map);
+//            }
+//        }
+//        listAddr.clear();
+//        listAddr.addAll(lis);
+
+        System.out.println("开始进行地名搜索,共《《《" + listAddr.size() + "》》》条数据。。。");
+
+        int size = (listAddr.size() / threadSize) + 1;
+        System.out.println("<<<<<<<   " + size + "     >>>>>>>>>");
+//        ExecutorService executor = Executors.newFixedThreadPool(size);
+        for(int i = 0; i < size; i ++){
+
+            List<Map<String, Object>> list = listAddr.subList(i * threadSize, (i+1)*threadSize > listAddr.size() ? listAddr.size(): (i+1)*threadSize);
+
+//            executor.execute(() ->{
+
+                List<Map<String, Object>> result = new ArrayList<>();
+                for (Map<String, Object> map : list) {
+                    String address = map.get(addressParam) + "";
+
+                    if(StringUtils.hasText(address)){
+                        String[] addr = AddressMatcher.matchProvinceAndCity(address);
+                        if (addr != null && !addr[0].contains("上海")) {// 外地数据,记录省、市
+                            map.put("provinces", addr[0]);
+                            map.put("market", addr[1]);
+                            map.put("distinguish", "");
+                            map.put("streetTown", "");
+                            map.put("residentialCommittee", "");
+
+                            map.put("address", address);
+                            map.put("standardAddress", address);
+                            map.put("returnAddress", "");
+                            map.put("matchLevel", "rule_0");
+                            map.put("lon", "");
+                            map.put("lat", "");
+                            result.add(map);
+                        } else {// 上海市数据
+                            String strs[] = AddressTools.parseAddressJZ(address);
+                            map.put("provinces", strs[0] == null ? "" : strs[0]);
+                            map.put("market", strs[0] == null ? "" : strs[0]);
+                            map.put("distinguish", strs[1] == null ? "" : strs[1]);
+                            map.put("streetTown", strs[2] == null ? "" : strs[2]);
+                            map.put("address", address);
+
+                            if(!StringUtils.hasText(address)){
+                                map.put("provinces", "");
+                                map.put("market", "");
+                                map.put("distinguish", "");
+                                map.put("streetTown", "");
+                                map.put("residentialCommittee", "");
+                                resultYc(map, address, result);
+                            } else {
+                                String addressN = strs[3] == null ? address : strs[3];
+                                if(addressN.startsWith("中山") && !addressN.startsWith("中山街道")){
+                                    addressN = addressN.replace("中山", "中山街道");
+                                }
+                                System.out.println("《《《 查询地址是:  " + addressN + "   》》》");
+
+                                AddressResult addressResult = AddressQueryEngine.getInstance().szxSearchByName(addressN);// 使用四中心接口
+                                if(addressResult == null || addressResult.getData() == null || addressResult.getData().size() < 1){
+                                    addressResult = mutchNet(addressN);
+                                }
+
+                                // 使用高德接口
+                                if(addressResult == null || addressResult.getData() == null || addressResult.getData().size() < 1){
+                                    addressResult = AddressQueryEngine.getInstance().gdV3SearchByName(addressN);
+                                }
+
+                                if (addressResult != null) {
+                                    addressResult.setCode(AddressResultEnum.SZX_SUCCESS);
+                                    addressResult.setMessage("成功");
+                                    addressResult = AddressQueryEngine.getInstance().getCjWgWgwByLoc(addressResult);
+                                    if(addressResult.getData() != null && addressResult.getData().size() > 0 && addressResult.getData().get(0) != null){
+                                        setResult(addressResult, map);
+                                        result.add(map);
+                                    } else {
+                                        resultYc(map, address, result);
+                                    }
+                                } else {
+                                    resultYc(map, address, result);
+                                }
+                            }
+                        }
+                    } else {
+                        map.put("provinces", "");
+                        map.put("market", "");
+                        map.put("distinguish", "");
+                        map.put("streetTown", "");
+                        map.put("residentialCommittee", "");
+                        resultYc(map, address, result);
+                    }
+
+
+//                    if(result.size() % 10000 == 9999){
+//                        System.out.println("<<<<<<<   写入数据,第" + num[0] + " 条    >>>>>>>>>");
+//                        try {
+////                            ExcelReaderUtils.writeToExcel(result, outPath + "880w数据结果-" + num[0] + ".xlsx");
+//                            ExcelReaderUtils.writeToExcel(result, outPath + "-补充-" + num[0] + ".xlsx");
+//                        } catch (IOException e) {
+//                            throw new RuntimeException(e);
+//                        } finally {
+//                            num[0]++;
+//                        }
+//
+//                    }
+                }
+                System.out.println("<<<<<<<   写入数据,第" + num + " 条    >>>>>>>>>");
+                try {
+//                    ExcelReaderUtils.writeToExcel(result, outPath + "880w数据结果-" + num[0] + ".xlsx");
+                    ExcelReaderUtils.writeToExcel(result, outPath);
+                    num++;
+                } catch (IOException e) {
+                    throw new RuntimeException(e);
+                } finally {
+
+                }
+
+//            });
+
+        }
+//        executor.shutdown();
+
+    }
+
+    public AddressResult mutchNet(String addressN){
+        for(int i = 0; i < 5; i ++){
+            AddressResult addressResult = AddressQueryEngine.getInstance().szxSearchByName(addressN);
+            if(addressResult != null)
+                return addressResult;
+        }
+        return null;
+    }
+
+    public void resultYc(Map<String, Object> map, String address, List<Map<String, Object>> result){
+        map.put("residentialCommittee", "");
+        map.put("standardAddress", "");
+        map.put("returnAddress", "");
+        map.put("matchLevel", "异常");
+        map.put("lon", "");
+        map.put("lat", "");
+        result.add(map);
+    }
+
+    public void setResult(AddressResult addressResult, Map<String, Object> map){
+        if (addressResult == null || addressResult.getData() == null || addressResult.getData().size() < 1) {
+            map.put("matchLevel", "异常");
+            map.put("returnAddress", "未匹配到符合规则的结果");
+        } else {
+            try {
+                for (AddressResult.ContentBean contentBean : addressResult.getData()) {
+                    String resultAddrKey = contentBean.getAddress();
+                    if (resultAddrKey != null && contentBean.getLon() != null && contentBean.getLat() != null && AddressTools.isOtherDistrictThanSongJiang2(resultAddrKey)) {
+//                                  去除特殊字符
+                        resultAddrKey = AddressTools.getInstance().deleteStr(contentBean.getAddress());
+//                                  遍历全国省份名称得到省名
+                        map.put("provinces", AddressTools.isOtherDistrictThanShangHai(resultAddrKey));
+//                                  写入街镇数据
+                        if (contentBean.getAdname() != null && !contentBean.getAdname().isEmpty()) {
+                            map.put("streetTown", contentBean.getAdname());
+                        } else if (contentBean.getTownJson() != null && contentBean.getTownJson().getString("name") != null) {
+                            map.put("streetTown", contentBean.getTownJson().getString("name"));
+                        } else {
+                            map.put("streetTown", "");
+                        }
+//                                  写入上海市市名
+                        map.put("market", AddressTools.isOtherDistrictThanShangHai(resultAddrKey));
+//                                  写入区名
+                        if (contentBean.getCityname() != null && !contentBean.getCityname().isEmpty()) {
+                            map.put("distinguish", contentBean.getCityname());
+                        } else if (contentBean.getAdJson() != null && contentBean.getAdJson().getString("name") != null) {
+                            map.put("distinguish", contentBean.getAdJson().getString("name"));
+                        } else {
+                            map.put("distinguish", "");
+                        }
+//                                  写入sh2000坐标系
+                        if(contentBean.getLat() != null && contentBean.getLon() != null){
+//                            double[] coord = CoordTransform2.getInstance().wgs84_to_shcj(contentBean.getLon(), contentBean.getLat());
+//                            map.put("lon", coord[0]);
+//                            map.put("lat", coord[1]);
+                            map.put("lon", contentBean.getLon());
+                            map.put("lat", contentBean.getLat());
+
+                        }
+                        map.put("returnAddress", resultAddrKey);
+                        map.put("matchLevel", contentBean.getScore());
+//                                  判断并写入居委
+                        if (contentBean.getCommunity() != null && !contentBean.getCommunity().isEmpty()) {
+                            map.put("residentialCommittee", contentBean.getCommunity());
+                        } else if (contentBean.getCjJson() != null && contentBean.getCjJson().containsKey("居委_1")) {
+                            map.put("residentialCommittee", contentBean.getCjJson().getString("居委_1"));
+                        } else {
+                            map.put("residentialCommittee", "");
+                        }
+                        String oldAddress = AddressTools.parseAddressJZ(contentBean.getSearchAddress())[3].
+                                replaceAll(map.get("market") + "", "").replaceAll(map.get("distinguish") + "", "").
+                                replaceAll(map.get("streetTown") + "", "").replaceAll(map.get("residentialCommittee") + "", "");
+                        map.put("standardAddress", "" + map.get("market") +  map.get("distinguish") + map.get("streetTown") + AddressQueryEngine.townReplace_ct(oldAddress));
+                        break;
+                    } else {
+                        map.put("matchLevel", "异常");
+                        map.put("returnAddress", "结果处理异常");
+                    }
+                }
+            } catch (Exception e) {
+                map.put("matchLevel", "异常");
+                e.printStackTrace();
+                System.err.println("查询结果处理异常:" + e);
+            }
+        }
+    }
+
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

Datei-Diff unterdrückt, da er zu groß ist
+ 5 - 0
src/main/resources/geojson/上海市_乡镇边界.geojson


Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
src/main/resources/geojson/上海市_区县边界.geojson


Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
src/main/resources/geojson/上海市_村居边界.geojson


Datei-Diff unterdrückt, da er zu groß ist
+ 7 - 0
src/main/resources/geojson/上海市_村居边界_sh2000.geojson


Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.