/geoLibChina

经纬度转省市区县乡镇离线包,采用空间查询算法,速度快(单线程5w次/s),省市区县100%准确率。

Primary LanguageJava

ChinaGeoLib

修改自: https://github.com/deng0515001/lnglat2Geo, 非常感谢原作者的贡献.修改点如下:

  1. 使用java完全重写Scala代码,原因如下
    1. 作为lib,java和scala依赖是单项的,Scala程序员可以看懂java,但是java程序员不一定能看懂Scala
    2. 作为lib库,需要考虑库的精简,他引入了Scala的runtime,将会带来额外的jar包依赖
    3. GeoTrans的标准API并不是可以无缝提供给java端使用(部分API java无法调用,因为有很多scala的特性)
    4. scala语法糖很舒服,但是进行代码cr能发现很多带有性能风险的用法,以及Scala函数式上代码结构不清晰(简写大括号、同函数if-else分支深度过多等)
  2. 数据文件格式变化
    1. 删除java的Serializable进行数据序列化的方法,工程实践上他从来不是稳定可靠的方式
      1. 当遇到字节码降级的时候,他会反序列化失败(如android 语法脱糖过程)
      2. 可能由于jvm实现具体细节导致不稳定
      3. 效率和性能并不是最优
      4. lib库混淆时,他会反序列化失败
    2. 文件模型即内存模型:线性hash表,线段数据加载到内存即为map对象,不需要进行一次全数据库解析构建,使得数据启动加载时间由40s减少到500ms
    3. 报文大小优化:目前数据包大小4.1M,原作者项目80M
      1. Leb128和zip
      2. 多边形精度模糊:作者使用level 12的s2进行多边形描述,但是其数据包中多边形线段数据的精度远高于level 12,导致大量点位是不需要的。本代码则会在构建数据包的时候模糊到level 12
      3. 不再支持乡镇、街道、商圈等功能,原作者的数据方案是全数据遍历,故用户自己根据自己的业务来实现这些功能可能更加合理。所以进一步减少了数据大小
  3. 核心算法的变化:本质核心算法依然flow原作者,但是做了一些改动
    1. 避免大量元组转换,这是Scala喜欢的,但是在阅读代码的时候真的是很难读懂这些元组的含义
    2. s2点位缓存:原作者缓存点位数据没有解释其来源,本仓库则根据我的理解预先产生缓存点位,让缓存点位命中算法闭环
    3. 基于模糊字符串相似度判定的文本地址归一化能力(地址转经纬度)
  4. 其他
    1. 依赖精简:除开必要的Google S2,不再依赖任意lib库
    2. 代码量精简:仅存6个功能性java代码文件
    3. 数据资源验证和转换:多边形数据打包检查多边形方向、模糊和调整s2 level