Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/bitlap/geocoding

:globe_with_meridians: 地理编码技术,提供地址标准化和相似度计算。
https://github.com/bitlap/geocoding

address geocoding kotlin segmentation similarity

Last synced: 1 day ago
JSON representation

:globe_with_meridians: 地理编码技术,提供地址标准化和相似度计算。

Awesome Lists containing this project

README

        

[![Project stage](https://img.shields.io/badge/Project%20Stage-Production%20Ready-brightgreen.svg)](https://github.com/bitlap/bitlap/wiki/Project-Stages)
[![Java 8 CI](https://github.com/IceMimosa/geocoding/actions/workflows/java8.yml/badge.svg)](https://github.com/IceMimosa/geocoding/actions/workflows/java8.yml)
[![Maven Central](https://img.shields.io/maven-central/v/org.bitlap/geocoding)](https://central.sonatype.com/artifact/org.bitlap/geocoding)

# 介绍
本项目旨在将不规范(或者连续)的文本地址进行尽可能的**标准化**, 以及对两个地址进行**相似度的计算**。

地理编码技术, 主要分为如下步骤
* 地址标准库
* 地址标准化
* 相似度计算

## pom

```xml


org.bitlap
geocoding
1.3.1

```

# 1. 数据测试

方法调用: `Geocoding` 类
* normalizing: 标准化
* analyze: 解析成分词文档
* similarity: 相似度计算
* similarityWithResult: 相似度计算, 返回包含更多丰富的数据

## 1.1 标准化

```java
>> 输入: 山东青岛市北区山东省青岛市市北区水清沟街道九江路20号大都会3号楼2单元1303
>> 输出:
Address(
provinceId=370000000000, province=山东省,
cityId=370200000000, city=青岛市,
districtId=370203000000, district=市北区,
streetId=370203030000, street=水清沟街道,
townId=null, town=null,
villageId=null, village=null,
road=九江路,
roadNum=20号,
buildingNum=3号楼2单元1303,
text=大都会
)
```

```java
>> 输入: 上海上海宝山区宝山区【新沪路58弄11-802 水韵华庭 】 (水韵华庭附近)
>> 输出:
Address(
provinceId=310000000000, province=上海,
cityId=310100000000, city=上海市,
districtId=310113000000, district=宝山区,
streetId=null, street=null,
townId=null, town=null,
villageId=null, village=null,
road=新沪路,
roadNum=58弄,
buildingNum=11-802,
text=水韵华庭水韵华庭附近
)
```

* 返回的对象解释
* province相关: 省
* city相关: 市
* district相关: 区、县
* street相关: 街道
* town相关: 乡镇
* village相关: 村
* road: 道路
* roadNum: 路号
* buildingNum: 建筑物号
* text: 标准化后为匹配的地址。一般包含小区, 商场名称等信息

> 注: 如果对text的结果不是很满意, 比如出现重复或不准确, 可以通过分词的手段解决

## 1.2 相似度

```java
>> 输入:
浙江金华义乌市南陈小区8幢2号
浙江金华义乌市稠城街道浙江省义乌市宾王路99号后面南陈小区8栋2号
>> 输出:
0.8451542547285166
```

```java
>> 输入:
山东省沂水县四十里堡镇东艾家庄村206号
浙江金华义乌市南陈小区8幢2号
>> 输出:
0.0
```

## 1.3 自定义地址文件设置

```kotlin
// 加载自定义地址文件
val geocoding = GeocodingX("region_2021.dat")

// 添加自定义区县"临平区"
geocoding.addRegionEntry(330113000000, 330100000000, "临平区", RegionType.District, "", true)

// 保存自定义字典文件
geocoding.save("xxx.dat")
```

## 1.4 自定义地址设置

```kotlin
// 100000000000 代表中国的ID
Geocoding.addRegionEntry(88888888, 100000000000, "尼玛省", RegionType.Province)
Geocoding.addRegionEntry(8888888, 88888888, "尼玛市", RegionType.City)
Geocoding.addRegionEntry(888888, 8888888, "泥煤市", RegionType.District)

>> 输入: 中国尼玛省尼玛市泥煤市泥煤大道888号xxx
>> 输出:
Address(
provinceId=88888888, province=尼玛省,
cityId=8888888, city=尼玛市,
districtId=888888, district=泥煤市,
streetId=null, street=null,
townId=null, town=null,
villageId=null, village=null,
road=泥煤大道,
roadNum=888号,
buildingNum=null,
text=xxx
)
```

> Tips: 可以从「国家标准地址库」中获取「父级城市ID」

# 2. 说明

## 2.1 标准地址库
项目目前采用的是 [~~淘宝物流4级地址~~][1] (已过期,可通过淘宝收货地址获取实际调用地址)的标准地址库, 也可以采用`国家的标准地址库` (对应的github库, [中国5级行政区域mysql库][3]).
* [国家标准地址库2023](http://www.stats.gov.cn/sj/tjbz/tjyqhdmhcxhfdm/2023)
* [国家标准地址库2022](http://www.stats.gov.cn/sj/tjbz/tjyqhdmhcxhfdm/2022)
* [国家标准地址库2021](http://www.stats.gov.cn/sj/tjbz/tjyqhdmhcxhfdm/2021)

### 导入中国5级行政区域mysql库注意事项

[参考文档](https://github.com/bitlap/geocoding/blob/master/src/test/java/org/bitlap/geocoding/region/README.md)

## 2.2 标准地址库(兼容本项目)

| 标准库文件 | 描述 | 参考 | 感谢 |
|-----------------|-------------|-------------------------------------------------------------|--------------------------------------------------------------------------------------|
| region_2021.dat | 国家标准地址库2021 | [ISSUE-163](https://github.com/bitlap/geocoding/issues/163) | [TsLenMo](https://github.com/TsLenMo)、[weijiang.lin](https://github.com/linweijiang) |

使用方式:文件下载到`classpath`,使用自定义的`GeocodingX`类即可。

## 2.3 标准化
1. 首先基于正则提取出道路、建筑物号等信息
2. 省市区等匹配
1. 将标准的地址库建立**倒排索引**
2. 将文本从起始位置开始, 采用**最大长度优先**的方式匹配所有词条
3. 对所有匹配结果进行标准行政区域从属关系校验

## 2.4 相似度计算
1. 对输入的两个地址进行标准化
2. 对省市区等信息分配不同的权重
3. 对道路号, 建筑号进行语义处理, 分配权重
4. 对剩余文本(text)使用**IK Analyzer**进行分词
5. 对两个结果集使用**余弦相似度算法**计算相似度

项目参考[address-semantic-search][4],简化了流程,修复了各种不规则错误,使得使用更加方便。

## 感谢

* Python封装库:[casuallyName/Geocoding](https://github.com/casuallyName/Geocoding)

## Release Log

[Change Log](./CHANGES.md)

## LICENSE

MIT

[1]:https://lsp.wuliu.taobao.com/locationservice/addr/output_address_town.do
[3]:https://github.com/kakuilan/china_area_mysql
[4]:https://github.com/liuzhibin-cn/address-semantic-search