Kaynağa Gözat

添加地址解析Web API项目

luocaiyang 8 ay önce
ebeveyn
işleme
392b727107

+ 13 - 0
AddressPaser/.config/dotnet-tools.json

@@ -0,0 +1,13 @@
+{
+  "version": 1,
+  "isRoot": true,
+  "tools": {
+    "dotnet-ef": {
+      "version": "9.0.1",
+      "commands": [
+        "dotnet-ef"
+      ],
+      "rollForward": false
+    }
+  }
+}

+ 28 - 0
AddressPaser/AddressPaser.csproj

@@ -0,0 +1,28 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <Nullable>enable</Nullable>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <GenerateDocumentationFile>True</GenerateDocumentationFile>
+    <UserSecretsId>ed9c8d39-9770-4a86-93f6-0cfa6377eff8</UserSecretsId>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\trieTree\trieTree.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <None Update="data\area_code_2024.csv">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Update="Properties\launchSettings.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+  </ItemGroup>
+
+</Project>

+ 6 - 0
AddressPaser/AddressPaser.http

@@ -0,0 +1,6 @@
+@AddressPaser_HostAddress = http://localhost:5241
+
+GET {{AddressPaser_HostAddress}}/weatherforecast/
+Accept: application/json
+
+###

+ 75 - 0
AddressPaser/Controllers/AddressController.cs

@@ -0,0 +1,75 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using trieTree.xiaoshi.sz.com;
+
+namespace AddressPaser.Controllers
+{
+    [Route("api/[controller]/[action]")]
+    [ApiController]
+    public class AddressController : ControllerBase
+    {
+        private readonly AddressUtility parser;
+
+        public AddressController(AddressUtility mySingleton)
+        {
+            parser = mySingleton;
+        }
+
+        [HttpGet(Name = "Paser")]
+        public ResponseResult<Address> Paser(string Address)
+        {
+            try
+            {
+                List<string>? strings = parser.Paser(Address);
+
+                if (strings != null)
+                {
+                    ResponseResult<Address> ret = new ResponseResult<Address>();
+                    ret.Status = 200;
+                    ret.Message = string.Empty;
+                    ret.Result = new Address();
+
+                    ret.Result.OriginalAddress = Address;
+
+                    if (strings.Count > 0)
+                    {
+                        ret.Result.Province = strings[0];
+                    }
+
+                    if (strings.Count > 1)
+                    {
+                        ret.Result.City = strings[1];
+                    }
+
+                    if (strings.Count > 2)
+                    {
+                        ret.Result.Area = strings[2];
+                    }
+
+                    return ret;
+                }
+                else
+                {
+                    ResponseResult<Address> ret = new ResponseResult<Address>();
+                    ret.Status = 500;
+                    ret.Message = "解析地址没有得到结果,请确认给出的地址是否正确!";
+                    ret.Result = new Address();
+                    ret.Result.OriginalAddress = Address;
+
+                    return ret;
+                }
+            }
+            catch (Exception ex)
+            {
+                ResponseResult<Address> ret = new ResponseResult<Address>();
+                ret.Status = 500;
+                ret.Message = $"解析地址出错[{ex.Message}]";
+                ret.Result = new Address();
+                ret.Result.OriginalAddress = Address;
+
+                return ret;
+            }
+
+        }
+    }
+}

+ 32 - 0
AddressPaser/Program.cs

@@ -0,0 +1,32 @@
+using trieTree.xiaoshi.sz.com;
+
+var builder = WebApplication.CreateBuilder(args);
+
+// Add services to the container.
+
+builder.Services.AddControllers();
+// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
+builder.Services.AddEndpointsApiExplorer();
+builder.Services.AddSwaggerGen();
+
+// 添加服务到依赖注入容器
+builder.Services.AddSingleton<AddressUtility>();
+
+// 配置HTTP请求管道
+// ...
+
+var app = builder.Build();
+
+// Configure the HTTP request pipeline.
+
+app.UseSwagger();
+app.UseSwaggerUI();
+
+
+app.UseHttpsRedirection();
+
+app.UseAuthorization();
+
+app.MapControllers();
+
+app.Run();

+ 41 - 0
AddressPaser/Properties/launchSettings.json

@@ -0,0 +1,41 @@
+{
+  "$schema": "http://json.schemastore.org/launchsettings.json",
+  "iisSettings": {
+    "windowsAuthentication": false,
+    "anonymousAuthentication": true,
+    "iisExpress": {
+      "applicationUrl": "http://*:28082",
+      "sslPort": 44307
+    }
+  },
+  "profiles": {
+    "http": {
+      "commandName": "Project",
+      "dotnetRunMessages": true,
+      "launchBrowser": true,
+      "launchUrl": "swagger",
+      "applicationUrl": "http://*:5241",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      }
+    },
+    "https": {
+      "commandName": "Project",
+      "dotnetRunMessages": true,
+      "launchBrowser": true,
+      "launchUrl": "swagger",
+      "applicationUrl": "https://*:7198;http://*:5241",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      }
+    },
+    "IIS Express": {
+      "commandName": "IISExpress",
+      "launchBrowser": true,
+      "launchUrl": "swagger",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      }
+    }
+  }
+}

+ 34 - 0
AddressPaser/ResponseAddress.cs

@@ -0,0 +1,34 @@
+namespace AddressPaser
+{
+    public class Address
+    {
+        /// <summary>
+        /// 省/直辖市/自治区
+        /// </summary>
+        public string? Province { get; set; }
+
+        /// <summary>
+        /// 市
+        /// </summary>
+        public string? City { get; set; }
+
+        /// <summary>
+        /// 区县
+        /// </summary>
+        public string? Area { get; set; }
+
+        /// <summary>
+        /// 原始地址
+        /// </summary>
+        public string? OriginalAddress {  get; set; } 
+    }
+
+    public class ResponseResult<T>
+    {
+        public int Status { get; set; }
+
+        public string? Message { get; set; }
+
+        public T? Result { get; set; }
+    }
+}

+ 8 - 0
AddressPaser/appsettings.Development.json

@@ -0,0 +1,8 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft.AspNetCore": "Warning"
+    }
+  }
+}

+ 9 - 0
AddressPaser/appsettings.json

@@ -0,0 +1,9 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft.AspNetCore": "Warning"
+    }
+  },
+  "AllowedHosts": "*"
+}

Dosya farkı çok büyük olduğundan ihmal edildi
+ 665650 - 0
AddressPaser/data/area_code_2024.csv


BIN
AddressPaser/data/tree.bin


BIN
AddressPaser/data/tree.bin.key


+ 0 - 1
testtrieTree/Program.cs

@@ -5,7 +5,6 @@ using System.IO;
 using System.Reflection.Metadata;
 using System.Runtime.CompilerServices;
 using System.Text.Json;
-using testtrieTree;
 using trieTree.xiaoshi.sz.com;
 using static System.Runtime.InteropServices.JavaScript.JSType;
 

+ 4 - 0
testtrieTree/testtrieTree.csproj

@@ -8,6 +8,10 @@
   </PropertyGroup>
 
   <ItemGroup>
+    <Compile Remove="utility.cs" />
+  </ItemGroup>
+
+  <ItemGroup>
     <ProjectReference Include="..\IPRS.xiaoshi.sz.com\IPRS.xiaoshi.sz.com.csproj" />
     <ProjectReference Include="..\trieTree\trieTree.csproj" />
   </ItemGroup>

+ 7 - 1
trieTree.xiaoshi.sz.com.sln

@@ -7,7 +7,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "testtrieTree", "testtrieTre
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "trieTree", "trieTree\trieTree.csproj", "{1BF5913A-0217-44E0-8B6E-7A30687FEBF2}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IPRS.xiaoshi.sz.com", "IPRS.xiaoshi.sz.com\IPRS.xiaoshi.sz.com.csproj", "{3728188A-69C0-47FB-A97F-E64774AC9A05}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IPRS.xiaoshi.sz.com", "IPRS.xiaoshi.sz.com\IPRS.xiaoshi.sz.com.csproj", "{3728188A-69C0-47FB-A97F-E64774AC9A05}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddressPaser", "AddressPaser\AddressPaser.csproj", "{E2C76304-6368-459F-8BD3-D7C44E94C1E5}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -27,6 +29,10 @@ Global
 		{3728188A-69C0-47FB-A97F-E64774AC9A05}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{3728188A-69C0-47FB-A97F-E64774AC9A05}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{3728188A-69C0-47FB-A97F-E64774AC9A05}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E2C76304-6368-459F-8BD3-D7C44E94C1E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E2C76304-6368-459F-8BD3-D7C44E94C1E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E2C76304-6368-459F-8BD3-D7C44E94C1E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E2C76304-6368-459F-8BD3-D7C44E94C1E5}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 503 - 0
trieTree/utility.cs

@@ -0,0 +1,503 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.Text;
+using System.Threading.Tasks;
+using trieTree.xiaoshi.sz.com;
+
+namespace trieTree.xiaoshi.sz.com
+{
+    public class AddressUtility
+    {
+        trieTree tree = new trieTree();
+        private Hashtable keyAddress = new Hashtable();
+        public AddressUtility() {
+
+            string filePath = "data/tree.bin";
+
+            if (File.Exists(filePath))
+            {
+                tree.Load(filePath);
+            }
+            else
+            {
+                string csvFile = "data/area_code_2024.csv";
+                using (StreamReader sr = new StreamReader(csvFile))
+                {
+                    while (!sr.EndOfStream)
+                    {
+                        string line = sr.ReadLine();
+                        string[] values = line.Split(',');
+
+                        //if (!keyAddress.ContainsKey(values[0]))
+                        //{
+                        //    keyAddress.Add(values[0], values[1]);
+                        //}
+
+                        switch (values[2])
+                        {
+                            case "1":
+                                tree.AddWord(values[1], values[0] + values[1]);
+
+                                if (values[1].EndsWith("市") || values[1].EndsWith("省"))
+                                    tree.AddWord(values[1].Substring(0, values[1].Length - 1), values[0] + values[1]);
+
+                                if (values[1].EndsWith("自治区"))
+                                    tree.AddWord(values[1].Substring(0, values[1].Length - 3), values[0] + values[1]);
+
+                                break;
+                            case "2":
+                                if (values[1] != "市辖区"
+                                    && values[1] != "省直辖县级行政区划"
+                                    && values[1] != "县"
+                                    && values[1] != "自治区直辖县级行政区划")
+                                {
+                                    tree.AddWord(values[1], values[0] + values[1]);
+                                    if (values[1].EndsWith("市") || values[1].EndsWith("盟"))
+                                    {
+                                        tree.AddWord(values[1].Substring(0, values[1].Length - 1), values[0] + values[1]);
+                                    }
+
+                                    if (values[1].EndsWith("地区"))
+                                    {
+                                        tree.AddWord(values[1].Substring(0, values[1].Length - 2), values[0] + values[1]);
+                                    }
+                                    #region 特殊市级名称
+                                    //朝鲜族自治州 
+                                    //阿坝藏族羌族自治州 
+                                    //甘孜藏族自治州
+                                    //凉山彝族自治州
+                                    //黔西南布依族苗族自治州
+                                    //黔东南苗族侗族自治州
+                                    //黔南布依族苗族自治州
+                                    //楚雄彝族自治州
+                                    //红河哈尼族彝族自治州
+                                    //文山壮族苗族自治州
+                                    //西双版纳傣族自治州
+                                    //大理白族自治州
+                                    //德宏傣族景颇族自治州
+                                    //怒江傈僳族自治州
+                                    //临夏回族自治州
+                                    //甘南藏族自治州
+                                    //海北藏族自治州
+                                    //黄南藏族自治州
+                                    //海南藏族自治州
+                                    //果洛藏族自治州
+                                    //玉树藏族自治州
+                                    //海西蒙古族藏族自治州
+                                    //昌吉回族自治州
+                                    //博尔塔拉蒙古自治州
+                                    //巴音郭楞蒙古自治州
+                                    //克孜勒苏柯尔克孜自治州
+                                    //伊犁哈萨克自治州
+                                    #endregion
+
+                                }
+                                break;
+
+                            case "3":
+
+                                tree.AddWord(values[1], values[0] + values[1]);
+                                if (values[1].EndsWith("旗") || values[1].EndsWith("市") || (values[1].EndsWith("区") && !values[1].EndsWith("地区")) || (values[1].EndsWith("县") && !values[1].EndsWith("自治县")))
+                                {
+                                    if (values[1].Length > 2)
+                                    {
+                                        tree.AddWord(values[1].Substring(0, values[1].Length - 1), values[0] + values[1]);
+                                    }
+
+                                }
+
+                                if (values[1].EndsWith("地区"))
+                                {
+                                    if (values[1].Length > 3)
+                                        tree.AddWord(values[1].Substring(0, values[1].Length - 2), values[0] + values[1]);
+                                }
+
+                                if (values[1].EndsWith("自治县"))
+                                {
+                                    if (values[1].Length > 4)
+                                        tree.AddWord(values[1].Substring(0, values[1].Length - 3), values[0] + values[1]);
+                                }
+                                #region 特殊区县级名称
+                                //和布克赛尔蒙古自治县
+                                //察布查尔锡伯自治县
+                                //塔什库尔干塔吉克自治县
+                                //焉耆回族自治县
+                                //木垒哈萨克自治县
+                                #endregion
+
+                                break;
+
+                            case "4":
+                                if (!values[1].Contains("直辖"))
+                                {
+                                    tree.AddWord(values[1], values[0] + values[1]);
+
+                                }
+                                break;
+
+                            case "5":
+                                //break;
+                                tree.AddWord(values[1], values[0] + values[1]);
+
+                                if (values[1].EndsWith("居委会") || values[1].EndsWith("生活区"))
+                                {
+                                    if (values[1].Length > 4)
+                                    {
+                                        tree.AddWord(values[1].Substring(0, values[1].Length - 3), values[0] + values[1]);
+                                    }
+                                }
+
+                                if (values[1].EndsWith("村委会"))
+                                {
+                                    //if (values[1].Length > 4)
+                                    //{
+                                    //    tree.AddWord(values[1].Substring(0, values[1].Length - 3), values[0] + values[1]);
+                                    //}
+                                    tree.AddWord(values[1].Substring(0, values[1].Length - 2), values[0] + values[1]);
+
+                                }
+
+                                if (values[1].EndsWith("居民委员会"))
+                                {
+                                    //if (values[1].Length > 6)
+                                    //{
+                                    //    tree.AddWord(values[1].Substring(0, values[1].Length - 5), values[0] + values[1]);
+                                    //}
+                                }
+
+                                break;
+                            default:
+                                break;
+                        }
+                        //tree.AddWord(values[1],values[0]);
+                    }
+                }
+
+                tree.AddWord("工业园区", "320576000000苏州工业园区");
+                tree.AddWord("高新区", "320505000000虎丘区");
+                tree.AddWord("科技城", "320505000000虎丘区");
+                tree.AddWord("芙蓉村", "320412106003芙蓉社区居委会(含芙蓉村村委)");
+                tree.AddWord("芙蓉社区", "320412106003芙蓉社区居委会(含芙蓉村村委)");
+                tree.AddWord("襄樊", "420600000000襄阳市");
+                tree.AddWord("襄樊市", "420600000000襄阳市");
+                tree.AddWord("四方区", "370203000000市北区");
+
+                Console.WriteLine(DateTime.Now);
+                tree.Save(filePath);
+            }
+
+            
+
+        }
+        public List<string>? Paser(string address)
+        {
+            List<List<string>> list = new List<List<string>>();
+            int i = 0;
+            bool shenAdded = false;
+            bool shiAdded = false;
+            bool quxianAdded = false;
+            
+            while (i < address.Length)
+            {
+                int temIndex = 0;
+                treeNode treeNode = tree.maxPrif(address.Substring(i), out temIndex);
+                if (treeNode != null)
+                {
+                    //list.Add(treeNode.EndValues);
+                    //Console.WriteLine($"{address.Substring(i,temIndex)},{i},{temIndex + i}");
+                    foreach (string key in treeNode.EndValues)
+                    {
+                        string strId = key.Substring(0,12);
+                        if (strId.EndsWith("0000000000"))
+                        {
+                            if (!shenAdded)
+                            {
+                                addkeyToResult(key, list);
+                                shenAdded = true;
+                            }
+                            continue;
+                        }
+
+                        if (strId.EndsWith("00000000") )
+                        {
+                            if (!shiAdded)
+                            {
+                                addkeyToResult(key, list);
+                                shiAdded = true;
+                            }
+                            continue;
+                        }
+
+                        //if (strId.EndsWith("000000"))
+                        //{
+                        //    if (!quxianAdded)
+                        //    {
+                        //        addkeyToResult(key, list);
+                        //        quxianAdded = true;
+                        //    }
+                        //    continue;
+                        //}
+
+                        addkeyToResult(key, list);
+
+                        //Console.WriteLine($"\t{key}");
+                    }
+                    i = i+ temIndex;
+                }
+
+                i++;
+            }
+
+            
+            List<string>? retList = null;
+
+            //int maxLength =0;
+            //foreach (List<string> strings in list)
+            //{
+            //    if(strings.Count > maxLength && IncludeShenShi(strings))
+            //    {
+            //        maxLength = strings.Count; 
+
+            //        retList = strings;
+            //    }
+            //}
+
+
+
+
+            double maxResult =0;
+            foreach (List<string> strings in list)
+            {
+                double temResult = CalResult(strings);
+                if(temResult > maxResult)
+                {
+                    maxResult = temResult;
+                    retList = strings;
+                }
+            }
+
+            if (retList != null)
+            {
+                retList.Sort();
+            }
+
+
+            return tree.formatAddress(retList);
+        }
+
+        private double CalResult(List<string> list)
+        {
+            double result = 0;
+            foreach (string str in list)
+            {
+                string value = str.Substring(0, 12);
+                if (value.EndsWith("0000000000"))
+                {
+                    result += 1.2;
+                }
+                else
+                {
+                    if (value.EndsWith("00000000"))
+                    {
+                        result += 1.1;
+                    }
+                    else
+                    {
+                        if (value.EndsWith("000000"))
+                        {
+                            result += 0.9;
+                        }
+                        else
+                        {
+                            if (value.EndsWith("000"))
+                            {
+                                result += 0.6;
+                            }
+                            else
+                            {
+                                result += 0.4;
+                            }
+                        }
+                    }
+                }
+            }
+            return result;
+        }
+
+        private bool IncludeShenShi(List<string> strings)
+        {
+            foreach (string key in strings)
+            {
+                string value = key.Substring(0, 12);
+                if(value.EndsWith("0000000000") || value.EndsWith("00000000"))
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        
+        public bool Search(string str)
+        {
+            return tree.Search(str, out _);
+        }
+
+        private void addkeyToResult(string key, List<List<string>> list)
+        {
+            if(list != null)
+            {
+                if (list.Count > 0) { 
+                    bool isAdded = false;
+                    List<List<string>> strings1 = new List<List<string>>();
+                    
+                    foreach (List<string> item in list)
+                    {
+                        List<string> tempList = new List<string>();
+                        foreach (string key2 in item)
+                        {
+                            if(isSub(key2, key))
+                            {
+                                if (!tempList.Contains(key2))
+                                {
+                                    tempList.Add(key2);
+                                }
+                            }
+                        }
+
+                        if (tempList.Count > 0)
+                        {
+                            if (tempList.Count == item.Count)
+                            {
+                                if (!item.Contains(key))
+                                {
+                                    item.Add(key);
+                                }
+
+                                isAdded = true;
+                                break;
+
+                            }
+                            else
+                            {
+                                tempList.Add(key);
+                                strings1.Add(tempList);
+                                //isAdded = true;
+                            }
+
+                            
+                        }
+                        
+
+                    }
+
+                    if (!isAdded)
+                    {
+                        if (strings1.Count > 0)
+                        {
+                            List<string> strings2 = new List<string>();
+                            int lstLength = 0;
+                            foreach(List<string> lst in strings1)
+                            {
+                                if (lstLength < lst.Count)
+                                {
+                                    lstLength = lst.Count;
+                                    strings2 = lst;
+                                }
+                            }
+
+                            list.Add(strings2);
+                        }
+                        else
+                        {
+                            List<string> strings = new List<string>() { key };
+                            list.Add(strings);
+                        }
+                            
+                    }
+                }
+                else
+                {
+                    List<string> strings = new List<string>() { key};
+                    list.Add(strings);
+                }
+            }
+            else
+            {
+                throw new Exception("list不能未空!");
+            }
+        }
+
+        private bool isSub(string key2, string key)
+        {
+            if (key2 != null && key != null)
+            {
+                string s1 = TrimRightZero(key2.Substring(0, 12));
+                string s2 = TrimRightZero(key.Substring(0, 12));
+
+                return (s1.StartsWith(s2) || s2.StartsWith(s1));
+            }
+
+            return false;
+        }
+
+        private string TrimRightZero(string str)
+        {
+            if (string.IsNullOrEmpty(str))
+            {
+                return str;
+            }
+            else
+            {
+                string str1= str.Substring(0, 2);
+                string str2 = str.Substring(2, 2);
+                string str3 = str.Substring(4, 2);
+                string str4 = str.Substring(6, 3); 
+                string str5 = str.Substring(9, 3);
+
+                if (str5 != "000")
+                {
+                    return str1 + str2 +str3 +str4 + str5;
+                }
+                else
+                {
+                    if(str4 != "000")
+                    {
+                        return str1+str2 +str3 +str4 ;
+                    }
+                    else
+                    {
+                        if(str3 != "00")
+                        {
+                            return str1 + str2 + str3 ;
+                        }
+                        else
+                        {
+                            if(str2 != "00")
+                            {
+                                return str1 + str2 ;
+                            }
+                            else
+                            {
+                                return str1 ;
+                            }
+                        }
+                    }
+                }
+                //for (int i = str.Length - 1; i >= 0; i--)
+                //{
+                //    if (str[i] != '0')
+                //    {
+                //        return str.Substring(0, i+1);
+                //    }
+                //}
+
+                //return "";
+            }
+        }
+    }
+}