|
| 1 | + |
| 2 | +[](https://github.com/IceMimosa/geocoding/actions/workflows/java8.yml) |
| 3 | + |
| 4 | +# 介绍 |
| 5 | +本项目旨在将不规范(或者连续)的文本地址进行尽可能的**标准化**, 以及对两个地址进行**相似度的计算**。 |
| 6 | + |
| 7 | +地理编码技术, 主要分为如下步骤 |
| 8 | + * 地址标准库 |
| 9 | + * 地址标准化 |
| 10 | + * 相似度计算 |
| 11 | + |
| 12 | +## pom |
| 13 | + |
| 14 | +```xml |
| 15 | +<dependencies> |
| 16 | + <dependency> |
| 17 | + <groupId>io.patamon.geocoding</groupId> |
| 18 | + <artifactId>geocoding</artifactId> |
| 19 | + <version>1.1.6</version> |
| 20 | + </dependency> |
| 21 | +</dependencies> |
| 22 | + |
| 23 | +<repositories> |
| 24 | + <repository> |
| 25 | + <id>geocoding</id> |
| 26 | + <name>github release repository</name> |
| 27 | + <url>https://maven.pkg.github.com/IceMimosa/geocoding</url> |
| 28 | + </repository> |
| 29 | +</repositories> |
| 30 | +``` |
| 31 | + |
| 32 | +> PS: 需要申请github token才能访问, [Authenticating to GitHub Packages](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry#authenticating-to-github-packages). 比如在 `~/.m2/settings.xml` 添加如下, [token申请地址](https://github.com/settings/tokens) |
| 33 | +
|
| 34 | +```xml |
| 35 | +<servers> |
| 36 | + <server> |
| 37 | + <id>geocoding</id> |
| 38 | + <username>[YOUR_NAME]</username> |
| 39 | + <password>[YOUR_TOKEN]</password> |
| 40 | + </server> |
| 41 | +<servers> |
| 42 | +``` |
| 43 | + |
| 44 | + |
| 45 | +# 1. 数据测试 |
| 46 | + |
| 47 | +方法调用: `Geocoding` 类 |
| 48 | + * normalizing: 标准化 |
| 49 | + * analyze: 解析成分词文档 |
| 50 | + * similarity: 相似度计算 |
| 51 | + * similarityWithResult: 相似度计算, 返回包含更多丰富的数据 |
| 52 | + |
| 53 | +## 1.1 标准化 |
| 54 | + |
| 55 | +```java |
| 56 | +>> 输入: 山东青岛市北区山东省青岛市市北区水清沟街道九江路20号大都会3号楼2单元1303 |
| 57 | +>> 输出: |
| 58 | +Address( |
| 59 | + provinceId=370000000000, province=山东省, |
| 60 | + cityId=370200000000, city=青岛市, |
| 61 | + districtId=370203000000, district=市北区, |
| 62 | + streetId=370203030000, street=水清沟街道, |
| 63 | + townId=null, town=null, |
| 64 | + villageId=null, village=null, |
| 65 | + road=九江路, |
| 66 | + roadNum=20号, |
| 67 | + buildingNum=3号楼2单元1303, |
| 68 | + text=大都会 |
| 69 | +) |
| 70 | +``` |
| 71 | + |
| 72 | +```java |
| 73 | +>> 输入: 上海上海宝山区宝山区【新沪路58弄11-802 水韵华庭 】 (水韵华庭附近) |
| 74 | +>> 输出: |
| 75 | +Address( |
| 76 | + provinceId=310000000000, province=上海, |
| 77 | + cityId=310100000000, city=上海市, |
| 78 | + districtId=310113000000, district=宝山区, |
| 79 | + streetId=null, street=null, |
| 80 | + townId=null, town=null, |
| 81 | + villageId=null, village=null, |
| 82 | + road=新沪路, |
| 83 | + roadNum=58弄, |
| 84 | + buildingNum=11-802, |
| 85 | + text=水韵华庭水韵华庭附近 |
| 86 | +) |
| 87 | +``` |
| 88 | + |
| 89 | +* 返回的对象解释 |
| 90 | + * province相关: 省 |
| 91 | + * city相关: 市 |
| 92 | + * district相关: 区、县 |
| 93 | + * street相关: 街道 |
| 94 | + * town相关: 乡镇 |
| 95 | + * village相关: 村 |
| 96 | + * road: 道路 |
| 97 | + * roadNum: 路号 |
| 98 | + * buildingNum: 建筑物号 |
| 99 | + * text: 标准化后为匹配的地址。一般包含小区, 商场名称等信息 |
| 100 | + |
| 101 | +> 注: 如果对text的结果不是很满意, 比如出现重复或不准确, 可以通过分词的手段解决 |
| 102 | +
|
| 103 | +## 1.2 相似度 |
| 104 | + |
| 105 | +```java |
| 106 | +>> 输入: |
| 107 | + 浙江金华义乌市南陈小区8幢2号 |
| 108 | + 浙江金华义乌市稠城街道浙江省义乌市宾王路99号后面南陈小区8栋2号 |
| 109 | +>> 输出: |
| 110 | + 0.8451542547285166 |
| 111 | +``` |
| 112 | + |
| 113 | +```java |
| 114 | +>> 输入: |
| 115 | + 山东省沂水县四十里堡镇东艾家庄村206号 |
| 116 | + 浙江金华义乌市南陈小区8幢2号 |
| 117 | +>> 输出: |
| 118 | + 0.0 |
| 119 | +``` |
| 120 | + |
| 121 | +## 1.3 自定义地址设置 |
| 122 | + |
| 123 | +```kotlin |
| 124 | +// 100000000000 代表中国的ID |
| 125 | +Geocoding.addRegionEntry(88888888, 100000000000, "尼玛省", RegionType.Province) |
| 126 | +Geocoding.addRegionEntry(8888888, 88888888, "尼玛市", RegionType.City) |
| 127 | +Geocoding.addRegionEntry(888888, 8888888, "泥煤市", RegionType.District) |
| 128 | + |
| 129 | +>> 输入: 中国尼玛省尼玛市泥煤市泥煤大道888号xxx |
| 130 | +>> 输出: |
| 131 | +Address( |
| 132 | + provinceId=88888888, province=尼玛省, |
| 133 | + cityId=8888888, city=尼玛市, |
| 134 | + districtId=888888, district=泥煤市, |
| 135 | + streetId=null, street=null, |
| 136 | + townId=null, town=null, |
| 137 | + villageId=null, village=null, |
| 138 | + road=泥煤大道, |
| 139 | + roadNum=888号, |
| 140 | + buildingNum=null, |
| 141 | + text=xxx |
| 142 | +) |
| 143 | +``` |
| 144 | + |
| 145 | +> Tips: 可以从「国家标准地址库」中获取「父级城市ID」 |
| 146 | +
|
| 147 | +# 2. 说明 |
| 148 | + |
| 149 | +## 2.1 标准地址库 |
| 150 | +项目目前采用的是 [淘宝物流4级地址][1] 的标准地址库, 也可以采用[国家的标准地址库][2] (对应的github库, [中国5级行政区域mysql库][3]). |
| 151 | + |
| 152 | +### 导入中国5级行政区域mysql库注意事项 |
| 153 | + |
| 154 | +[参考文档](https://github.com/bitlap/geocoding/blob/master/src/test/java/org/bitlap/geocoding/region/README.md) |
| 155 | + |
| 156 | +## 2.2 标准化 |
| 157 | +1. 首先基于正则提取出道路、建筑物号等信息 |
| 158 | +2. 省市区等匹配 |
| 159 | + 1. 将标准的地址库建立**倒排索引** |
| 160 | + 2. 将文本从起始位置开始, 采用**最大长度优先**的方式匹配所有词条 |
| 161 | + 3. 对所有匹配结果进行标准行政区域从属关系校验 |
| 162 | + |
| 163 | +## 2.3 相似度计算 |
| 164 | +1. 对输入的两个地址进行标准化 |
| 165 | +2. 对省市区等信息分配不同的权重 |
| 166 | +3. 对道路号, 建筑号进行语义处理, 分配权重 |
| 167 | +4. 对剩余文本(text)使用**IK Analyzer**进行分词 |
| 168 | +5. 对两个结果集使用**余弦相似度算法**计算相似度 |
| 169 | + |
| 170 | + |
| 171 | +项目参考[address-semantic-search][4],简化了流程,修复了各种不规则错误,使得使用更加方便。 |
| 172 | + |
| 173 | +## 感谢 |
| 174 | + |
| 175 | +* Python封装库:[casuallyName/Geocoding](https://github.com/casuallyName/Geocoding) |
| 176 | + |
| 177 | + |
| 178 | +## Release Log |
| 179 | + |
| 180 | +* 1.1.3 |
| 181 | + * 新增自定义地址设置 |
| 182 | +* 1.1.4 |
| 183 | + * 修复一些匹配错误的bug |
| 184 | +* 1.1.6 |
| 185 | + * 升级地址库和包版本, 修复一些匹配错误的地址 |
| 186 | +* 1.2.0 |
| 187 | + - geocoding项目转移到组织:bitlap/geocoding |
| 188 | + |
| 189 | +[1]:https://lsp.wuliu.taobao.com/locationservice/addr/output_address_town.do |
| 190 | +[2]:http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2015/index.html |
| 191 | +[3]:https://github.com/kakuilan/china_area_mysql |
| 192 | +[4]:https://github.com/liuzhibin-cn/address-semantic-search |
0 commit comments