coordconver 0.1.4 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -1,264 +1,331 @@
1
- # 坐标转换/Coordconver
2
- [![Build Status](https://travis-ci.org/cheenwe/coordconver.svg?branch=master)](https://travis-ci.org/cheenwe/coordconver)
1
+ # 坐标转换 / Coordconver
3
2
 
4
- - 1.提供了百度坐标(BD-09)、国测局坐标(火星坐标,GCJ-02)、和 地球坐标( WGS-84) 坐标系之间的转换。
3
+ [![CI](https://github.com/cheenwe/coordconver/actions/workflows/ci.yml/badge.svg)](https://github.com/cheenwe/coordconver/actions/workflows/ci.yml)
4
+ [![Gem Version](https://badge.fury.io/rb/coordconver.svg)](https://badge.fury.io/rb/coordconver)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
6
 
6
- - 2.坐标点到经纬度的相互转换
7
+ 一个零依赖的 Ruby 坐标工具库([English](README.en.md)):
7
8
 
8
- - 3.坐标点到地理位置的转换
9
+ 1. **坐标系互转**(纯离线):百度(BD-09)、火星(GCJ-02)、地球(WGS-84),含**厘米级精确逆变换**
10
+ 2. **球面几何**:两点距离、方位角、沿方位角偏移点
11
+ 3. **经纬度 ⇄ 度分秒**、**WKT / GeoJSON** 格式互转
12
+ 4. **高斯-克吕格投影**正反算(CGCS2000 / 北京54 / 西安80 / WGS-84,含 3°/6° 带号换算)
13
+ 5. **地理编码**:百度 / 高德 / 腾讯三家的地址 ⇄ 坐标、IP 定位、高德官方坐标转换 API
14
+ 6. **生产级细节**:多 key 自动轮询与配额摘除、进程内 LRU 缓存、统一错误体系、线程安全
15
+ 7. **命令行工具**:单点/批量转换、CSV、GeoJSON 输出
16
+
17
+ 要求 Ruby >= 2.7。零运行时依赖,仅使用标准库。
18
+
19
+ > **在线试用**(无需安装): https://cheenwe.github.io/coordconver/ —— 纯前端实现,算法与 gem 数值一致。
9
20
 
10
21
  ## 安装
11
22
 
12
- 添加到Gemfile:
23
+ 添加到 Gemfile:
13
24
 
14
25
  ```ruby
15
26
  gem 'coordconver'
16
27
  ```
17
28
 
18
- 执行:
29
+ 执行 `bundle`,或直接安装:
19
30
 
20
- $ bundle
31
+ $ gem install coordconver
21
32
 
22
- 或者只安装该GEM:
33
+ ## 坐标系转换
23
34
 
24
- $ gem install coordconver
35
+ ### 快速上手
25
36
 
37
+ ```ruby
38
+ require 'coordconver'
26
39
 
27
- ## 坐标系转换
40
+ wgs = [121.468738, 31.247138] # WGS-84 (GPS 原始坐标)
41
+ Coordconver.wgs_gcj(*wgs) # => [121.47327833883615, 31.2452165865549] (GCJ-02, 高德/谷歌中国/腾讯)
42
+ Coordconver.wgs_bd(*wgs) # => [121.47980789007566, 31.251157822142243] (BD-09, 百度)
43
+ ```
44
+
45
+ ### 全部转换方法
46
+
47
+ 所有方法支持多种入参与出参:
28
48
 
29
- ### 用法
49
+ ```ruby
50
+ # 入参: (lng, lat) 双参 / Point / [lng, lat] / {lng:, lat:}
51
+ Coordconver.wgs_gcj(121.468738, 31.247138)
52
+ Coordconver.wgs_gcj(Coordconver.point(121.468738, 31.247138))
53
+ Coordconver.wgs_gcj([121.468738, 31.247138])
54
+
55
+ # 出参: 默认 [lng, lat]; as: :hash => {lng:, lat:}; as: :point => Point
56
+ Coordconver.wgs_gcj(121.468738, 31.247138, as: :hash)
57
+ # => {lng: 121.47327833883615, lat: 31.2452165865549}
58
+ ```
30
59
 
31
- 提供6转换方式,传入参数需为**float**类型,如:
32
- >Coordconver.bd_gcj(lng.to_f, lat.to_f)
60
+ | 坐标系 | 转换名称 | 方法 | 语义化别名 |
61
+ | ----- | ----- | ----- | ----- |
62
+ | BD-09 -> GCJ-02 | 百度 -> 谷歌、高德、腾讯 | `Coordconver.bd_gcj(lng, lat)` | `bd09_gcj02` |
63
+ | GCJ-02 -> BD-09 | 谷歌、高德、腾讯 -> 百度 | `Coordconver.gcj_bd(lng, lat)` | `gcj02_bd09` |
64
+ | GCJ-02 -> WGS-84 | 谷歌、高德、腾讯 -> 地球坐标 | `Coordconver.gcj_wgs(lng, lat)` | `gcj02_wgs84` |
65
+ | WGS-84 -> GCJ-02 | 地球坐标 -> 谷歌、高德、腾讯 | `Coordconver.wgs_gcj(lng, lat)` | `wgs84_gcj02` |
66
+ | BD-09 -> WGS-84 | 百度 -> 地球坐标 | `Coordconver.bd_wgs(lng, lat)` | `bd09_wgs84` |
67
+ | WGS-84 -> BD-09 | 地球坐标 -> 百度 | `Coordconver.wgs_bd(lng, lat)` | `wgs84_bd09` |
33
68
 
34
- | 坐标系 | 转换名称 | 方法|
35
- | ----------- | ------- | ----- | --------- |
36
- | BD-09 -> GCJ-02 | 百度 -> 谷歌、高德 | Coordconver.bd_gcj(lng, lat) |
37
- | BD-09 -> WGS-84 | 百度 -> 地球坐标 | Coordconver.bd_wgs(lng, lat) |
38
- | GCJ-02 -> WGS-84 | 谷歌、高德 -> 地球坐标 | Coordconver.gcj_wgs(lng, lat) |
39
- | GCJ-02 -> BD-09 | 谷歌、高德 -> 百度 | Coordconver.gcj_bd(lng, lat) |
40
- | WGS-84 -> BD-09 | 地球坐标 -> 百度 | Coordconver.wgs_bd(lng, lat) |
41
- | WGS-84 -> GCJ-02 | 地球坐标 -> 谷歌、高德 | Coordconver.wgs_gcj(lng, lat) |
69
+ ### 精确逆变换(厘米级)
42
70
 
43
- 示例:
44
- >Coordconver.wgs_bd(121.46873833333332, 31.247138333333336) # => [121.479808223763, 31.25115814844421]
71
+ `gcj_wgs` 是近似逆运算(误差米级)。`gcj_wgs_precise` 用迭代法求解,误差厘米级:
72
+
73
+ ```ruby
74
+ g = Coordconver.wgs_gcj(121.468738, 31.247138)
75
+ Coordconver.gcj_wgs(*g) # => [121.468753, 31.247151] 误差 ~1.6 米
76
+ Coordconver.gcj_wgs_precise(*g) # => [121.468738, 31.247138] 误差 < 1e-7 度 (~1cm)
77
+ Coordconver.bd_wgs_precise(*bd) # 百度坐标同理
78
+ ```
79
+
80
+ ### 批量转换
81
+
82
+ ```ruby
83
+ points = [[121.468738, 31.247138], Coordconver.point(116.481499, 39.990475), { lng: 104.08, lat: 30.65 }]
84
+ Coordconver.transform(points, from: :wgs84, to: :gcj02, as: :hash)
85
+ ```
86
+
87
+ `from`/`to` 支持 `:wgs84` `:gcj02` `:bd09`(及简写 `:wgs` `:gcj` `:bd`,大小写不限)。
45
88
 
46
89
  ### 坐标系说明
47
90
 
48
- #### 百度坐标系 (BD-09)
49
- - 百度标准,百度 SDK,百度地图,Geocoding 使用
91
+ | 坐标系 | 说明 | 使用方 |
92
+ | ----- | ----- | ----- |
93
+ | WGS-84 | 国际标准,GPS/北斗芯片原始坐标 | iOS 原生定位、OSM、海外谷歌地图 |
94
+ | GCJ-02 | 国测局标准(火星坐标),WGS-84 加密所得 | 高德、腾讯、谷歌中国、搜搜、阿里云 |
95
+ | BD-09 | 百度标准,GCJ-02 再次加密所得 | 百度地图、百度 SDK |
50
96
 
51
- #### 火星坐标系 (GCJ-02)
52
- - 中国标准(国测局坐标系),从国行移动设备中定位获取的坐标数据使用这个坐标系, 由中国国家测绘局制订的地理信息系统的坐标系统
97
+ ## 球面几何
53
98
 
54
- - 由WGS84坐标系经加密后的坐标系
99
+ ```ruby
100
+ # 两点球面距离(米), 两点需在同一坐标系下
101
+ Coordconver.distance(116.397428, 39.90923, 121.473701, 31.230416) # => 1068194.1
55
102
 
56
- - 谷歌中国地图, 搜搜中国地图, iOS地图(高德), 搜搜, 阿里云, 高德地图, 腾讯
103
+ # 初始方位角(正北为 0°, 顺时针 0-360°)
104
+ Coordconver.bearing(116.397428, 39.90923, 121.473701, 31.230416) # => 153.04...
57
105
 
58
- #### 地球坐标系 (WGS-84)
59
- - 国际标准, 设备一般包含GPS芯片或者北斗芯片获取的经纬度为WGS84地理坐标系
106
+ # 从起点沿方位角移动指定距离后的坐标
107
+ Coordconver.destination_point(116.397428, 39.90923, 153.0, 100_000)
108
+ # => [116.92357, 39.106734]
60
109
 
61
- - 谷歌地图采用的是WGS84地理坐标系(中国范围除外)
110
+ # 判断坐标是否在中国境外(境外 WGS-84 与 GCJ-02 一致, 转换方法会原样返回)
111
+ Coordconver.out_of_china?(121.47, 31.25) # => false
112
+ ```
62
113
 
63
- - ios的原生定位库, osm
114
+ ## 经纬度与度分秒互转
64
115
 
116
+ ```ruby
117
+ Coordconver.degree(38.65777, 104.08296)
118
+ # => ["38°39′27.97″", "104°4′58.66″"]
65
119
 
66
- ### 相关资料
120
+ Coordconver.undegree("38°39′27.97″", "104°4′58.66″")
121
+ # => [38.657769, 104.082961]
67
122
 
68
- - [各坐标系位置在线查看](http://www.gpsspg.com/maps.htm)
123
+ # 单值转换, 第二个参数控制秒的小数位(默认 2 位, 传 0 可得整数秒)
124
+ Coordconver.cal_degree(38.65777) # => "38°39′27.97″"
69
125
 
70
- - [百度地图转换API](http://lbsyun.baidu.com/jsdemo.htm#a5_2)
126
+ # 解析支持多种写法: 38°39′27.97″ / 38°39′27.97" / 38d39m27.97s / 38:39:27.97
127
+ # 负值按西经/南纬处理
128
+ Coordconver.cal_undegree("-38°39′27.97″") # => -38.657769
129
+ ```
71
130
 
72
- - [高德地图转换API](http://lbs.amap.com/api/webservice/guide/api/convert/#convert)
131
+ ## WKT / GeoJSON
73
132
 
133
+ ```ruby
134
+ Coordconver.parse_wkt("POINT (121.47 31.25)") # => [121.47, 31.25]
135
+ Coordconver.to_wkt(121.47, 31.25) # => "POINT (121.47 31.25)"
74
136
 
75
- ## 坐标点与经纬度转换
137
+ Coordconver.parse_geojson('{"type":"Point","coordinates":[121.47,31.25]}') # => [121.47, 31.25]
138
+ # 也接受 Hash 与 Feature(自动取 geometry)
139
+ Coordconver.to_geojson(121.47, 31.25) # => {"type"=>"Point", "coordinates"=>[121.47, 31.25]}
76
140
 
77
- ### 用法
141
+ # 与坐标系转换自由组合
142
+ Coordconver.wgs_gcj(Coordconver.parse_wkt(wkt), as: :point)
143
+ ```
78
144
 
79
- 提供4种转换方式,传入坐标点需为**float**类型,传入经纬度需为**string**类型。
145
+ ## 高斯-克吕格投影(测绘)
80
146
 
81
- | 转换名称 | 方法|
82
- | ----- | --------- |
83
- | 坐标点转度数 | Coordconver.degree(lng, lat) |
84
- | 单个坐标点转度数 | Coordconver.cal_degree(n) |
85
- | 度数点转坐标点 | Coordconver.undegree(lng_degree, lat_degree) |
86
- | 单个度数转坐标点 | Coordconver.cal_degree(n) |
147
+ 经纬度 ⇄ 高斯平面坐标,支持 CGCS2000 / WGS-84 / 北京54(krassovsky) / 西安80(iag75) 椭球,正反算往返精度优于 1cm:
87
148
 
149
+ ```ruby
150
+ # 正算: 默认 6° 带自动推算中央经线, 东坐标偏移 500km (测绘惯例)
151
+ Coordconver.gauss_kruger(121.47, 31.24, zone_width: 3)
152
+ # => [640045.58, 3458515.34] (3° 带 40 带, 中央经线 120°)
88
153
 
89
- 示例:
154
+ # 指定中央经线 / 椭球
155
+ Coordconver.gauss_kruger(121.47, 31.24, central_meridian: 120, ellipsoid: :krassovsky) # 北京54
90
156
 
91
- >Coordconver.degree(38.65777, 104.08296) # => ["38°39′27″","104°4′58″"]
157
+ # 反算: 中央经线必填
158
+ Coordconver.inverse_gauss_kruger(640045.58, 3458515.34, central_meridian: 120)
159
+ # => [121.47, 31.24]
92
160
 
93
- >Coordconver.undegree("38°39′27.97″","104°4′58.66″") # => [38.65777,104.08296]
161
+ # 带号与中央经线换算
162
+ Coordconver.zone_meridian(121.47) # => [21, 123] (6° 带)
163
+ Coordconver.zone_meridian(121.47, width: 3) # => [40, 120] (3° 带)
164
+ ```
94
165
 
95
- ### 相关资料
96
- 地形图坐标系:我国的地形图采用高斯-克吕格平面直角坐标系。在该坐标系中,横轴:赤道,用Y表示;纵轴:中央经线,用X表示;坐标原点:中央经线与赤道的交点,用0表示。赤道以南为负,以北为正;中央经线以东为正,以西为负。我国位于北半球,故纵坐标均为正值,但为避免中央经度线以西为负值的情况,将坐标纵轴西移500公里。
166
+ ## 命令行工具
97
167
 
98
- 北京54坐标系:1954年我国在北京设立了大地坐标原点,采用克拉索夫斯基椭球体,依此计算出来的各大地控制点的坐标,称为北京54坐标系。
99
- GS84坐标系:即世界通用的经纬度坐标系。
168
+ 安装 gem 后可直接使用 `coordconver` 命令:
100
169
 
101
- 经纬度表示:1884年国际经度会议规定,以通过英国伦敦格林威治天文台子午仪中心的经线为0°经线。从0°经线往东叫东经,往西叫西经,东、西各分180°。习惯上以西经20°和东经160°为分界把地球分为东西两个半球。假如从地轴的正中间将地球切成南北两半,上边的一半叫北半球,下边的一半叫南半球。被切的这个平面,叫赤道面。赤道面与地球表面相交的线叫赤道。纬线从赤道往两极越来越短,到了两极就缩小成一个点了。科学家们把赤道定为0°纬线,从赤道向两极各分为90°,赤道以南叫南纬,赤道以北叫北纬。在计算机或GPS上经纬度经常用度、分、秒和度.度、分.分、秒.秒的混合方式进行表示,度、分、秒间的进制是60进制,度.度、分.分、秒.秒的进制是100进制,换算时一定要注意。可以近似地认为每个纬度之间的距离是不变的111KM,每分间 1.85KM,每秒间31.8M。经度间的距离随纬度增高逐渐减小,可按以下公式计算:
102
- Decimal Degrees = Degrees + minutes/60 + seconds/3600
103
- 例:57°55’56.6″ =57+55/60+56.6/3600=57.9323888888888
104
- 114°65’24.6″=114+65/60+24.6/3600=115.00683333333333
170
+ ```bash
171
+ # 坐标系转换 (wgs2gcj / gcj2wgs / wgs2bd / bd2wgs / gcj2bd / bd2gcj)
172
+ coordconver wgs2gcj 121.468738 31.247138 # => 121.473278,31.245217
173
+ coordconver wgs2gcj 121.468738 31.247138 --json
174
+ coordconver wgs2gcj 121.468738 31.247138 --geojson
105
175
 
176
+ # 度分秒互转
177
+ coordconver dms 38.65777 104.08296
178
+ coordconver dec "38°39′27.97″" "104°4′58.66″"
106
179
 
107
- ## 坐标点与地址转换
180
+ # 距离 / 方位角 / 偏移点
181
+ coordconver dist 116.397428 39.90923 121.473701 31.230416
182
+ coordconver bearing 116.397428 39.90923 121.473701 31.230416 # => 153.04
183
+ coordconver dest 116.397428 39.90923 153 100000
108
184
 
109
- 地理编码/逆地理编码API是一类简单的HTTP接口,提供结构化地址与经纬度之间的相互转化服务。
185
+ # 高斯-克吕格
186
+ coordconver gk 121.47 31.24 --zone3 # => 640045.58,3458515.34
187
+ coordconver invgk 640045.58 3458515.34 --cm 120 # => 121.47,31.24
110
188
 
111
- 该套API免费对外开放,使用API您需先申请对应的API Key,
189
+ # 批量转换: 每行一条 "lng,lat"; --csv 自动跳过表头
190
+ cat points.txt | coordconver wgs2gcj
191
+ cat points.csv | coordconver wgs2gcj --csv
112
192
 
113
- - 百度地图 默认配额6000次/天。
193
+ # 地址 <-> 坐标 (需先配置 key, 见下文)
194
+ coordconver geo --gaode "北京方恒国际中心A座"
195
+ coordconver regeo --baidu 116.322987 39.983424 --cache
196
+ ```
114
197
 
115
- - 高德地图API,企业用户单个Key支持200万次/天,5万次/分钟。
198
+ ## 地址与坐标互转 (百度 / 高德 / 腾讯)
116
199
 
117
- 防止同一key 使用超额, 建议申请多个key使用让系统随机调用。
200
+ 使用前需申请对应平台的 API Key:
118
201
 
119
- ### 用法
202
+ - 百度地图开放平台: https://lbsyun.baidu.com/apiconsole/key (**服务端**类型 AK + IP 白名单;SN 校验类型需配置 `baidu_sn`)
203
+ - 高德开放平台: https://console.amap.com/dev/key/app (**Web 服务**类型)
204
+ - 腾讯位置服务: https://lbs.qq.com/dev/console/application/mine (启用 WebServiceAPI)
120
205
 
121
- ```ruby
122
- Coordconver::Client.new(["百度 ak1","百度 ak2"],["高德 key1"," key2"])
206
+ 百度默认配额 6000 次/天;高德个人认证 5000 次/天,企业单 Key 可达 200 万次/天;腾讯个人 1 万次/天。**支持传入多个 key**:库会自动轮询,并在某个 key 配额超限/无效时自动摘除、切换下一个(冷却 5 分钟后自动恢复)。
123
207
 
124
- Coordconver::Baidu.regeo(116.322987, 39.983424) #百度地图api在线坐标转换地址
208
+ ### 配置
125
209
 
126
- Coordconver::Gaode.regeo(116.480881,39.989410) #高德地图api在线坐标转换地址
210
+ ```ruby
211
+ require 'coordconver'
212
+
213
+ # 推荐: 全局配置块
214
+ Coordconver.configure do |config|
215
+ config.baidu_map_aks = ["百度ak1", "百度ak2"]
216
+ config.gaode_map_keys = ["高德key1", "高德key2"]
217
+ config.tencent_map_keys = ["腾讯key1"]
218
+ # config.baidu_sn = "SN校验密钥" # 仅 AK 类型为"SN校验"时需要
219
+ # config.cache = true # 进程内缓存地理编码结果, 节省配额
220
+ # config.cache_ttl = 3600 # 缓存秒数(默认 3600)
221
+ # config.cache_size = 1024 # 缓存条目上限, LRU 淘汰(默认 1024)
222
+ # config.open_timeout = 5 # 连接超时(秒)
223
+ # config.read_timeout = 10 # 读取超时(秒)
224
+ end
225
+ ```
127
226
 
128
- Coordconver::Gaode.geo("北京方恒国际中心A座") #高德地图api在线地址转换坐标
227
+ 或兼容旧写法:
129
228
 
130
- Coordconver::Baidu.geo("百度大厦") #百度地图api在线地址转换坐标
229
+ ```ruby
230
+ Coordconver::Client.new(["百度ak1", "百度ak2"], ["高德key1"], tencent_map_keys: ["腾讯key1"])
131
231
  ```
132
232
 
133
- 示例:
233
+ 未配置 key 就调用 API 会抛出 `Coordconver::ConfigurationError`,错误信息会提示如何配置。
234
+
235
+ ### 地理编码 (地址 -> 坐标)
134
236
 
135
- >Coordconver::Client.new(["xxxxx],["xxxx"])
237
+ ```ruby
238
+ # 百度 (BD-09), 支持官方可选参数如 city:
239
+ Coordconver::Baidu.geo("百度大厦")["result"]["location"]
240
+ Coordconver::Baidu.geo_location("百度大厦") # => [116.30775539540981, 40.05685561073758]
136
241
 
137
- 1.百度地图转换
138
- [Online API](http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding)
242
+ # 高德 (GCJ-02)
243
+ Coordconver::Gaode.geo_location("北京方恒国际中心A座") # => [116.480724, 39.989584]
139
244
 
245
+ # 腾讯 (GCJ-02)
246
+ Coordconver::Tencent.geo_location("北京市海淀区彩和坊路海淀西大街74号")
247
+ ```
140
248
 
141
- - 地理编码:即地址解析,由详细到街道的结构化地址得到百度经纬度信息
142
- 例如:“北京市海淀区中关村南大街27号”地址解析的结果是“lng:116.31985,lat:39.959836”。
249
+ ### 逆地理编码 (坐标 -> 地址)
143
250
 
144
- >Coordconver::Baidu.geo("百度大厦")["result"]["location"].values # => [116.30775539540981, 40.05685561073758]
251
+ ```ruby
252
+ Coordconver::Baidu.regeo_address(116.322987, 39.983424) # => "北京市海淀区中关村大街27号1101-08室"
253
+ Coordconver::Gaode.regeo_address(116.480881, 39.989410) # => "北京市朝阳区望京街道方恒国际中心B座方恒国际中心"
254
+ Coordconver::Tencent.regeo_address(116.322987, 39.983424)
145
255
 
146
- ```json
147
- {
148
- "status": 0,
149
- "result": {
150
- "location": {
151
- "lng": 116.30775539540981,
152
- "lat": 40.05685561073758
153
- },
154
- "precise": 1,
155
- "confidence": 80,
156
- "level": "商务大厦"
157
- }
158
- }
256
+ # 拿到的是 GPS(WGS-84) 坐标想直接查地址? 先转成对应坐标系:
257
+ gcj = Coordconver.wgs_gcj(lng, lat)
258
+ Coordconver::Gaode.regeo_address(*gcj)
159
259
  ```
160
260
 
161
- - 逆地理编码:即逆地址解析,由百度经纬度信息得到结构化地址信息,例如:“lat:31.325152,lng:120.558957”逆地址解析的结果是“江苏省苏州市虎丘区塔园路318号”。
162
-
163
- >Coordconver::Baidu.regeo(116.32298699999993,39.98342407140365)["result"]["formatted_address"] # => 北京市海淀区中关村大街27号1101-08室
164
-
165
- ```json
166
- {
167
- "status": 0,
168
- "result": {
169
- "location": {
170
- "lng": 116.32298699999993,
171
- "lat": 39.98342407140365
172
- },
173
- "formatted_address": "北京市海淀区中关村大街27号1101-08室",
174
- "business": "中关村,人民大学,苏州街",
175
- "addressComponent": {
176
- "country": "中国",
177
- "country_code": 0,
178
- "province": "北京市",
179
- "city": "北京市",
180
- "district": "海淀区",
181
- "adcode": "110108",
182
- "street": "中关村大街",
183
- "street_number": "27号1101-08室",
184
- "direction": "附近",
185
- "distance": "7"
186
- },
187
- "pois": [],
188
- "poiRegions": [],
189
- "sematic_description": "北京远景国际公寓(中关村店)内0米",
190
- "cityCode": 131
191
- }
192
- }
261
+ 注意坐标系统:百度接口收发 BD-09,高德/腾讯接口收发 GCJ-02;坐标类型可通过选项控制(如百度 `coordtype: "wgs84ll"`、高德 `extensions` 等,详见各家官方文档)。
262
+
263
+ ### IP 定位
193
264
 
265
+ ```ruby
266
+ Coordconver::Baidu.ip # 当前出口 IP (BD-09)
267
+ Coordconver::Tencent.ip("8.8.8.8") # 指定 IP (GCJ-02)
194
268
  ```
195
269
 
196
- 2.高德地图转换
197
-
198
- [API](http://lbs.amap.com/api/webservice/guide/api/georegeo/#geo)
199
-
200
- - 地理编码:将详细的结构化地址转换为高德经纬度坐标,且支持名胜景区、标志性建筑物名称解析为高德经纬度坐标。
201
- 例如:北京市朝阳区阜通东大街6号-->116.480881,39.989410
202
- 天安门-->116.397499,39.908722
203
-
204
- >Coordconver::Gaode.geo("北京方恒国际中心A座")["geocodes"][0]["location"]
205
-
206
- ```json
207
- {
208
- "status" : "1",
209
- "info" : "OK",
210
- "infocode" : "10000",
211
- "count" : "1",
212
- "geocodes" :
213
- [
214
- "0" :
215
- {
216
- "formatted_address" : "北京市朝阳区方恒国际中心|A座",
217
- "province" : "北京市",
218
- "citycode" : "010",
219
- "city" : "北京市",
220
- "district" : "朝阳区",
221
- ...
222
- "location" : "116.480724,39.989584",
223
- "level" : "门牌号"
224
- }
225
- ]
226
- }
270
+ ### 高德官方坐标转换 API
271
+
272
+ ```ruby
273
+ # GPS/百度坐标 -> 高德坐标(官方权威转换, 单次最多 40 点)
274
+ Coordconver::Gaode.convert_location([121.468738, 31.247138], from: :gps)
275
+ # => [[121.473279, 31.245217]]
276
+ Coordconver::Gaode.convert_location([[121.46, 31.24], [116.39, 39.90]], from: :baidu)
227
277
  ```
228
278
 
229
- - 逆地理编码:将经纬度转换为详细结构化的地址,且返回附近周边的POI信息,以及该经纬度所在的POI信息。
230
- 例如:116.480881,39.989410-->北京市朝阳区阜通东大街6号
279
+ ### 错误处理
231
280
 
232
- >conver::Gaode.regeo(116.480881,39.989410)['regeocode']["formatted_address"]
281
+ ```ruby
282
+ begin
283
+ Coordconver::Gaode.regeo_address(116.48, 39.98)
284
+ rescue Coordconver::ConfigurationError => e
285
+ # 未配置 key
286
+ rescue Coordconver::ApiError => e
287
+ # 所有 key 均无效或配额超限 (e.raw 可取到最后一次原始响应)
288
+ rescue Coordconver::NetworkError => e
289
+ # 超时/连接失败/响应非 JSON (网络层已自动重试 3 次)
290
+ rescue Coordconver::Error => e
291
+ # 基类, 兜底
292
+ end
293
+ ```
233
294
 
295
+ 服务端返回的其他业务错误(如地址不存在、参数非法)不抛异常,返回原始 JSON,通过 `status` 字段判断:百度 `status == 0`、高德 `status == "1"`、腾讯 `status == 0` 为成功。
234
296
 
235
- ```json
236
- {
237
- "status" : "1",
238
- "info" : "OK",
239
- "infocode" : "10000",
240
- "regeocode" :
241
- {
242
- "formatted_address" : "北京市朝阳区望京街道方恒国际中心B座方恒国际中心",
243
- ...
244
- }
245
- }
297
+ ## 升级说明 (0.x -> 1.x)
246
298
 
247
- ```
299
+ - 修复 `bd_wgs` 方向 bug(0.x 版本返回的是错误结果),并增加回归测试
300
+ - 百度地理编码升级到 Geocoding API v3(v2 接口已下线),默认走 HTTPS
301
+ - `cal_degree` 默认保留两位小数秒(`cal_degree(n, 0)` 可得旧版整数秒输出)
302
+ - 移除源码中硬编码的 key,调用 API 前必须先配置
303
+ - 支持 Ruby 2.7 ~ 3.4;CI 由 Travis 迁移至 GitHub Actions
304
+ - 1.1.0 起所有转换方法兼容 Point/数组/Hash 入参与 `as:` 出参,多 key 从随机取样改为轮询
248
305
 
306
+ 完整变更见 [CHANGELOG.md](CHANGELOG.md)。
249
307
 
250
308
  ## Development
251
309
 
252
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
310
+ 检出代码后,运行 `bin/setup` 安装依赖,`rake test` 运行测试(全部离线,无需 API key)。
253
311
 
254
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
312
+ 需要在线联调时:
255
313
 
256
- ## Contributing
314
+ ```bash
315
+ COORDCONVER_LIVE_TEST=1 \
316
+ COORDCONVER_BAIDU_AK=你的百度ak \
317
+ COORDCONVER_GAODE_KEY=你的高德key \
318
+ rake test
319
+ ```
257
320
 
258
- Bug reports and pull requests are welcome on GitHub at https://github.com/cheenwe/coordconver.
321
+ 本地安装:`bundle exec rake install`。发布新版本:更新 `lib/coordconver/version.rb` 后执行 `bundle exec rake release`。
259
322
 
323
+ 在线试用页托管在 GitHub Pages(`docs/` 目录)。首次发布需在仓库 Settings -> Pages 将 Source 设为 `Deploy from a branch`,分支选 `master`、目录选 `/docs`。
260
324
 
261
- ## License
325
+ ## Contributing
326
+
327
+ 欢迎提交 Bug 报告和 Pull Request:https://github.com/cheenwe/coordconver
262
328
 
263
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
329
+ ## License
264
330
 
331
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/coordconver.gemspec CHANGED
@@ -1,24 +1,40 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'coordconver/version'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/coordconver/version"
5
4
 
6
5
  Gem::Specification.new do |spec|
7
- spec.name = "coordconver"
8
- spec.version = Coordconver::VERSION
9
- spec.authors = ["chenwei"]
10
- spec.email = ["cheenwe@gmail.com"]
6
+ spec.name = "coordconver"
7
+ spec.version = Coordconver::VERSION
8
+ spec.authors = ["chenwei"]
9
+ spec.email = ["cheenwe@gmail.com"]
10
+
11
+ spec.summary = "百度(BD-09)/火星(GCJ-02)/地球(WGS-84)坐标系互转、球面几何、高斯-克吕格投影, 以及百度/高德/腾讯地理编码"
12
+ spec.description = "纯离线实现百度坐标(BD-09)、国测局坐标(GCJ-02)、地球坐标(WGS-84)互转(含厘米级精确逆变换), 两点距离/方位角/偏移点, 经纬度与度分秒互转, WKT/GeoJSON 互转, 高斯-克吕格投影正反算; 并封装百度/高德/腾讯 Web 服务 API 实现地址与坐标互转, 支持多 key 自动轮询与进程内缓存。附带命令行工具。"
13
+ spec.homepage = "https://github.com/cheenwe/coordconver"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = ">= 2.7"
16
+
17
+ spec.metadata = {
18
+ "allowed_push_host" => "https://rubygems.org",
19
+ "homepage_uri" => spec.homepage,
20
+ "source_code_uri" => "https://github.com/cheenwe/coordconver",
21
+ "changelog_uri" => "https://github.com/cheenwe/coordconver/blob/master/CHANGELOG.md",
22
+ "bug_tracker_uri" => "https://github.com/cheenwe/coordconver/issues",
23
+ "rubygems_mfa_required" => "true"
24
+ }
11
25
 
12
- spec.summary = %q{坐标转换/Coordconver}
13
- spec.description = %q{1.提供了百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换. 2.坐标点到经纬度的相互转换.}
14
- spec.homepage = "https://github.com/cheenwe/coordconver"
15
- spec.license = "MIT"
16
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
- spec.bindir = "exe"
18
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
27
+ files = `git ls-files -z`.split("\x0")
28
+ # 兜底: 尚未纳入 git 追踪的新文件也打包
29
+ files += Dir.glob("{lib/**/*.rb,exe/*,CHANGELOG.md}")
30
+ files.uniq.reject do |f|
31
+ f.match(%r{\A(?:test|spec|features)/}) || !File.exist?(f)
32
+ end
33
+ end
34
+ spec.bindir = "exe"
35
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
19
36
  spec.require_paths = ["lib"]
20
37
 
21
- spec.add_development_dependency "bundler", "~> 1.12"
22
- spec.add_development_dependency "rake", "~> 10.0"
38
+ spec.add_development_dependency "rake", ">= 13.0"
23
39
  spec.add_development_dependency "minitest", "~> 5.0"
24
40
  end