C#地址分析算法,自动获取地址对应的省市区行政区域编码|C/S开发框架
作者:csframework|C/S框架网  发布日期:2022/03/02 15:02:40

C#地址分析算法,自动获取地址对应的省市区行政区域编码|C/S开发框架

C#地址分析算法,自动获取地址对应的省市区行政区域编码

C# 地址分析算法,返回省市区行政区域编码

C# AddressToCityIDs 类库

C# 全选
/// <summary>
    /// C# 地址分析算法,返回省市区行政区域编码
    /// </summary>
    public class AddressToCityIDs
    {
        //最多返回3级编码,省市区
        private int MAX_CITYS = 3;
        //根节点编码
        private string ROOT_ID = "100000";

        private DataTable data;

        public AddressToCityIDs(DataTable dtCitys)
        {
            this.data = dtCitys;
        }

        /// <summary>
        /// 获取上级区域编号
        /// </summary>
        /// <param name="cityCode"></param>
        /// <returns></returns>
        private string GetParentId(string cityCode)
        {
            var rs = data.Select($"code='{cityCode}'");
            if (rs.Length > 0)
                return rs[0]["parent_id"].ToString();
            else
                return "";
        }

        /// <summary>
        /// 获取指定区域码的所有父级编码
        /// </summary>
        /// <param name="result">返回结果</param>
        /// <param name="cityCode">区域码</param>
        public void GetParentIDs(List<String> result, string cityCode)
        {
            var rs = data.Select($"code='{cityCode}'");

            if (rs.Length > 0)
            {
                result.Add(rs[0]["parent_id"].ToString());

                //匹配子节点
                data.DefaultView.RowFilter = $"code='{rs[0]["parent_id"].ToString()}'";
                var dt = data.DefaultView.ToTable();
                if (dt.Rows.Count > 0)
                {
                    foreach (DataRow R in dt.Rows)
                    {
                        GetParentIDs(result, R["code"].ToString());
                    }
                }
            }

            //不包含根节点
            result.Remove(ROOT_ID);
        }

        /// <summary>
        /// 获取省市名称
        /// </summary>
        /// <param name="codeList">区域编码</param>
        /// <returns></returns>
        public string GetCityName(List<string> codeList)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var s in codeList)
            {
                var rs = data.Select($"code='{s}'");
                if (rs.Length > 0)
                {
                    if (sb.Length == 0)
                        sb.Append(rs[0]["name"].ToString());
                    else
                        sb.Append("-" + rs[0]["name"].ToString());
                }
            }
            return sb.ToString().Trim();
        }

        /// <summary>
        /// 根据地址信息,自动获取行政区域编码
        /// </summary>        
        /// <param name="address">地址信息</param>
        /// <param name="cityIDs">输出3个城市编码,调号隔开</param>
        /// <param name="cityNames">输出3个城市名称,调号隔开</param>
        /// <returns></returns>
        public bool GetCityId(string address, ref string cityIDs, ref string cityNames)
        {
            List<String> ids = new List<string>();

            if (address.IndexOf("/") > 0)
                ids = GetCityIDsByAddress(address, '/', ' ');
            else
                ids = GetCityIDsByAddress(address);

            var result = ids.Take<String>(MAX_CITYS).ToList<String>();

            //返回结果
            cityIDs = String.Join(",", result).Trim();//310000,310100,310116
            cityNames = GetCityName(result);//上海市-市辖区-金山区

            return result.Count > 0;
        }

        /// <summary>
        /// 获取地址区码,地址有分隔符,如:/
        /// </summary>
        /// <param name="address">地址,如:上海市/松江区 松卫北路6700弄沪松五金建材市场3幢</param>
        /// <returns>返回区域码列表,如:310000/310100/310117</returns>
        public List<String> GetCityIDsByAddress(string address, params char[] separator)
        {

            void AddIDs(List<String> ids, DataRow rs)
            {
                List<string> tmp = new List<string>();
                GetParentIDs(tmp, rs["code"].ToString());
                tmp.Add(rs["code"].ToString());

                if (ids.Count == 0 || ids.Exists(e => tmp.IndexOf(e) >= 0))
                {
                    ids.Add(rs["code"].ToString());
                    ids.Add(rs["parent_id"].ToString());
                    ids.Add(GetParentId(rs["parent_id"].ToString()));
                }
            }

            List<String> result = new List<string>();

            //分解地址            
            var list = address.Split(separator, StringSplitOptions.RemoveEmptyEntries).Distinct().ToArray();
            list = list.Distinct().ToArray();//去重,唯一名称

            //有规则,有分隔符号/,如:上海市/上海市/松江区 松卫北路6700弄沪松五金建材市场3幢1*****
            if (list.Length > 1)
            {
                DataRow[] rs;
                foreach (var item in list)
                {
                    rs = data.Select($"name='{item.Trim()}'", "level_type ASC");//匹配名称成功,如:上海市、松江区
                    if (rs.Length == 1)
                    {
                        AddIDs(result, rs[0]);
                    }
                    else if (rs.Length > 1)
                    {
                        foreach (DataRow R in rs)
                        {
                            List<string> tmp = new List<string>();
                            GetParentIDs(tmp, R["code"].ToString());
                            if (result.Exists(e => tmp.IndexOf(e) >= 0))
                            {
                                AddIDs(result, R);
                                break;
                            }
                        }
                    }
                }
            }

            result = result.Where(e => e != "" && e != ROOT_ID).Distinct().OrderBy(x => x).ToList<String>();
            return result;
        }

        /// <summary>
        /// 获取地址区码
        /// </summary>
        /// <param name="address">地址,如:上海市松江区松卫北路6700弄沪松五金建材市场3幢</param>
        /// <returns>返回区域码列表,如:310000/310100/310117</returns>
        public List<String> GetCityIDsByAddress(string address)
        {
            List<String> ids = new List<string>();

            data.DefaultView.Sort = "level_type ASC";

            //枚举所有城市名称,匹配地址
            foreach (DataRow R in data.DefaultView.ToTable().Rows)
            {
                var name = R["name"].ToString();

                //上海市宝山区丰翔路888号
                if (address.IndexOf(name) >= 0)
                {
                    List<string> tmp = new List<string>();
                    GetParentIDs(tmp, R["code"].ToString());
                    tmp.Add(R["code"].ToString());
                    if (ids.Count == 0 || ids.Exists(e => tmp.IndexOf(e) >= 0))
                    {
                        ids.Add(R["code"].ToString());
                        ids.Add(R["parent_id"].ToString());
                        ids.Add(GetParentId(R["parent_id"].ToString()));

                        address = address.Replace(R["name"].ToString(), "");
                    }
                }
            }

            var result = ids.Where(e => e != "" && e != ROOT_ID).Distinct().OrderBy(x => x).ToList<String>();
            return result;
        }

    }

测试案例

C# 全选
 //获取城市区域数据
            DataTable dict = new SyncHelper().GetCityData();
            Console.WriteLine("记录数:" + dict.Rows.Count);

            Test1(dict, "蔡灵波    上海市黄浦区南京东路街道湖滨路150号*****");
            Test1(dict, "上海住豪建筑上海市 青浦区 青浦区徐泾镇龙联 ****");
            Test1(dict, "张家港市塘桥镇南环路阳地钢工地(58号银达*****");
            Test1(dict, "绍兴市隐山府项目部(杨绍线与山阴*****");
            Test1(dict, "黑龙江省双鸭山市宝山区南环路阳地钢工地");
            Test1(dict, "上海市宝山区南环路阳地钢工地");
            Test1(dict, "双鸭山市宝山区南环路阳地钢工地");
            Test1(dict, "邵阳市隆回县报看村");

            Console.WriteLine("------------------------------");

            Test2(dict, "蔡灵波    上海市/黄浦区/南京东路街道 湖滨路150号*****");
            Test2(dict, "上海住豪建筑 上海市/ 青浦区 青浦区徐泾镇龙联 ****");
            Test2(dict, "张家港市/塘桥镇/南环路阳地钢工地(58号银达*****");
            Test2(dict, "绍兴市/隐山府项目部(杨绍线与山阴*****");
            Test2(dict, "黑龙江省/双鸭山市/宝山区 南环路阳地钢工地");
            Test2(dict, "上海市/宝山区/南环路阳地钢工地");
            Test2(dict, "双鸭山市/宝山区/南环路阳地钢工地");
            Test2(dict, "邵阳市/隆回县/报看村");

            Console.ReadKey();

测试结果

C#地址分析算法,自动获取地址对应的省市区行政区域编码|C/S开发框架

C#地址分析算法,自动获取地址对应的省市区行政区域编码|C/S开发框架

C/S框架网|原创精神.创造价值.打造精品


扫一扫加作者微信
C/S框架网作者微信 C/S框架网|原创作品.质量保障.竭诚为您服务
上一篇 下一篇