coordconver 0.1.3 → 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.
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coordconver
4
+ module Geo
5
+ # 多 key 智能轮询: round-robin 取 key, 请求失败(配额超限/无效)时摘除该 key,
6
+ # 冷却时间过后自动恢复。线程安全。
7
+ class KeyPool
8
+ # 被摘除 key 的冷却时长(秒), 覆盖"每秒/每日配额超限"两类场景
9
+ COOLDOWN = 300
10
+
11
+ def initialize
12
+ @mutex = Mutex.new
13
+ @index = {}
14
+ @disabled_at = {}
15
+ end
16
+
17
+ # 轮询取下一个可用 key; 全部处于冷却期时抛出 ApiError
18
+ def next_key(provider, keys)
19
+ @mutex.synchronize do
20
+ purge_expired(Time.now)
21
+ enabled = keys.reject { |k| @disabled_at[[provider, k]] }
22
+ if enabled.empty?
23
+ raise ApiError, "所有 #{provider} key 均不可用(配额超限或无效), 请更换或补充 key"
24
+ end
25
+
26
+ @index[provider] = (@index[provider] ||= -1) + 1
27
+ enabled[@index[provider] % enabled.size]
28
+ end
29
+ end
30
+
31
+ def mark_bad(provider, key)
32
+ @mutex.synchronize { @disabled_at[[provider, key]] = Time.now }
33
+ end
34
+
35
+ def disabled?(provider, key)
36
+ @mutex.synchronize do
37
+ purge_expired(Time.now)
38
+ !@disabled_at[[provider, key]].nil?
39
+ end
40
+ end
41
+
42
+ def reset!
43
+ @mutex.synchronize do
44
+ @index.clear
45
+ @disabled_at.clear
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def purge_expired(now)
52
+ @disabled_at.reject! { |_, t| now - t > COOLDOWN }
53
+ end
54
+
55
+ class << self
56
+ def instance
57
+ @instance ||= new
58
+ end
59
+
60
+ def next_key(provider, keys)
61
+ instance.next_key(provider, keys)
62
+ end
63
+
64
+ def mark_bad(provider, key)
65
+ instance.mark_bad(provider, key)
66
+ end
67
+
68
+ def disabled?(provider, key)
69
+ instance.disabled?(provider, key)
70
+ end
71
+
72
+ def reset!
73
+ instance.reset!
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coordconver
4
+ module Geo
5
+ # 腾讯位置服务 WebService API
6
+ # 申请 key: https://lbs.qq.com/dev/console/application/mine (启用 WebServiceAPI)
7
+ # 坐标为 GCJ-02; 逆地理编码 location 参数为 "lat,lng" 顺序
8
+ module Tencent
9
+ extend self
10
+
11
+ # 视为"key 无效/配额超限"的状态码, 触发自动轮换下一个 key
12
+ # 110 请求来源未被授权 112 IP未被授权 120 每秒调用量超限 121 日调用量超限 199 key结构错误
13
+ KEY_ERROR_STATUSES = [110, 112, 120, 121, 199].freeze
14
+
15
+ # 地理编码: 结构化地址 -> 坐标 (GCJ-02)
16
+ # Coordconver::Tencent.geo("北京市海淀区彩和坊路海淀西大街74号")["result"]["location"]
17
+ # 支持可选参数: region(城市), get_poi, ...
18
+ def geo(address, options = {})
19
+ params = { address: address }.merge(options)
20
+ request("/geocoder/v1/", params)
21
+ end
22
+
23
+ # 逆地理编码: 坐标 (GCJ-02) -> 结构化地址
24
+ # Coordconver::Tencent.regeo(116.322987, 39.983424)["result"]["address"]
25
+ def regeo(lng, lat, options = {})
26
+ params = {
27
+ location: "#{lat},#{lng}", # 腾讯接口为 lat,lng 顺序
28
+ get_poi: 0
29
+ }.merge(options)
30
+ request("/geocoder/v1/", params)
31
+ end
32
+
33
+ # IP 定位: IP -> 城市 + 坐标 (GCJ-02)
34
+ def ip(ip = nil)
35
+ params = {}
36
+ params[:ip] = ip unless ip.nil? || ip.empty?
37
+ request("/location/v1/ip", params)
38
+ end
39
+
40
+ # 便捷方法: 地址 -> [lng, lat] (GCJ-02), 解析失败返回 nil
41
+ def geo_location(address, options = {})
42
+ loc = geo(address, options).dig("result", "location")
43
+ loc && [loc["lng"], loc["lat"]]
44
+ end
45
+
46
+ # 便捷方法: 坐标 -> 地址字符串 (GCJ-02), 解析失败返回 nil
47
+ def regeo_address(lng, lat, options = {})
48
+ result = regeo(lng, lat, options).dig("result") || {}
49
+ result.dig("formatted_addresses", "recommend") || result["address"]
50
+ end
51
+
52
+ private
53
+
54
+ def request(path, params)
55
+ Api.call(
56
+ provider: :tencent,
57
+ url: base_url + path,
58
+ params: params,
59
+ key_param: :key,
60
+ bad_result: ->(r) { KEY_ERROR_STATUSES.include?(r["status"].to_i) }
61
+ )
62
+ end
63
+
64
+ def base_url
65
+ Configuration.settings[:tencent_base_url].sub(%r{/\z}, "")
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ # 高斯-克吕格投影(横轴墨卡托)正反算, 以及 3°/6° 带号与中央经线换算。
4
+ # 适用于 CGCS2000 / 北京54 / 西安80 / WGS-84 椭球, 精度毫米级。
5
+ #
6
+ # 经 Coordconver.extend(Projection) 挂载:
7
+ # Coordconver.gauss_kruger(121.47, 31.24) # => [x东坐标, y北坐标]
8
+ # Coordconver.inverse_gauss_kruger(543_000, 3_456_000, central_meridian: 120)
9
+ # Coordconver.zone_meridian(121.47, width: 3) # => [40, 120]
10
+ module Coordconver
11
+ module Projection
12
+ extend self
13
+
14
+ # 椭球参数: a 长半轴(米), rf 扁率倒数
15
+ ELLIPSOIDS = {
16
+ cgcs2000: [6_378_137.0, 298.257_222_101],
17
+ wgs84: [6_378_137.0, 298.257_223_563],
18
+ krassovsky: [6_378_245.0, 298.3], # 北京54
19
+ iag75: [6_378_140.0, 298.257] # 西安80
20
+ }.freeze
21
+
22
+ # 高斯-克吕格正算: 经纬度 -> 平面坐标 [东坐标 x, 北坐标 y] (米)
23
+ # central_meridian: 中央经线(度), 缺省按 zone_width 自动推算
24
+ # zone_width: 3 或 6 (度), 仅在未指定 central_meridian 时使用
25
+ # false_easting: 东坐标偏移(米), 默认 500_000 (测绘惯例, 保证 x 为正)
26
+ # ellipsoid: :cgcs2000 / :wgs84 / :krassovsky(北京54) / :iag75(西安80)
27
+ def gauss_kruger(lng, lat, central_meridian: nil, zone_width: 6,
28
+ ellipsoid: :cgcs2000, false_easting: 500_000, false_northing: 0)
29
+ a, f = ellipsoid_params(ellipsoid)
30
+ cm = central_meridian || zone_meridian(lng, width: zone_width)[1]
31
+ e2 = f * (2 - f)
32
+ ep2 = e2 / (1 - e2)
33
+
34
+ p = deg2rad(lat)
35
+ dl = deg2rad(lng - cm)
36
+ sin_p = Math.sin(p)
37
+ cos_p = Math.cos(p)
38
+ tan_p = Math.tan(p)
39
+
40
+ n = a / Math.sqrt(1 - e2 * sin_p * sin_p)
41
+ t = tan_p * tan_p
42
+ c = ep2 * cos_p * cos_p
43
+ aa = dl * cos_p
44
+ m = meridional_arc(p, a, e2)
45
+
46
+ x = false_easting + n * (aa +
47
+ (1 - t + c) * aa**3 / 6 +
48
+ (5 - 18 * t + t * t + 72 * c - 58 * ep2) * aa**5 / 120)
49
+ y = false_northing + m + n * tan_p * (aa**2 / 2 +
50
+ (5 - t + 9 * c + 4 * c * c) * aa**4 / 24 +
51
+ (61 - 58 * t + t * t + 600 * c - 330 * ep2) * aa**6 / 720)
52
+ [x.round(4), y.round(4)]
53
+ end
54
+
55
+ # 高斯-克吕格反算: 平面坐标 -> 经纬度 [lng, lat]
56
+ # central_meridian 必填(反算无法从 x, y 推出投影带)
57
+ def inverse_gauss_kruger(x, y, central_meridian:, ellipsoid: :cgcs2000,
58
+ false_easting: 500_000, false_northing: 0)
59
+ a, f = ellipsoid_params(ellipsoid)
60
+ e2 = f * (2 - f)
61
+ ep2 = e2 / (1 - e2)
62
+
63
+ m = y - false_northing
64
+ mu = m / (a * (1 - e2 / 4 - 3 * e2**2 / 64 - 5 * e2**3 / 256))
65
+ e1 = (1 - Math.sqrt(1 - e2)) / (1 + Math.sqrt(1 - e2))
66
+
67
+ p1 = footpoint_latitude(mu, e1)
68
+ sin_p1 = Math.sin(p1)
69
+ cos_p1 = Math.cos(p1)
70
+ tan_p1 = Math.tan(p1)
71
+
72
+ c1 = ep2 * cos_p1 * cos_p1
73
+ t1 = tan_p1 * tan_p1
74
+ n1 = a / Math.sqrt(1 - e2 * sin_p1 * sin_p1)
75
+ r1 = a * (1 - e2) / (1 - e2 * sin_p1 * sin_p1)**1.5
76
+ d = (x - false_easting) / n1
77
+
78
+ p = p1 - (n1 * tan_p1 / r1) * (d**2 / 2 -
79
+ (5 + 3 * t1 + 10 * c1 - 4 * c1 * c1 - 9 * ep2) * d**4 / 24 +
80
+ (61 + 90 * t1 + 298 * c1 + 45 * t1 * t1 - 252 * ep2 - 3 * c1 * c1) * d**6 / 720)
81
+ l = (d -
82
+ (1 + 2 * t1 + c1) * d**3 / 6 +
83
+ (5 - 2 * c1 + 28 * t1 - 3 * c1 * c1 + 8 * ep2 + 24 * t1 * t1) * d**5 / 120) / cos_p1
84
+
85
+ [rad2deg(l + deg2rad(central_meridian)), rad2deg(p)].map { |v| v.round(9) }
86
+ end
87
+
88
+ # 带号与中央经线: zone_meridian(121.47) => [21, 123], zone_meridian(121.47, width: 3) => [40, 120]
89
+ def zone_meridian(lng, width: 6)
90
+ raise ArgumentError, "带宽仅支持 3 或 6 度" unless [3, 6].include?(width)
91
+
92
+ zone = width == 6 ? (lng / 6).floor + 1 : (lng / 3).round
93
+ [zone, width == 6 ? zone * 6 - 3 : zone * 3]
94
+ end
95
+
96
+ private
97
+
98
+ def ellipsoid_params(name)
99
+ params = ELLIPSOIDS[name.to_s.downcase.to_sym]
100
+ raise ArgumentError, "未知椭球: #{name.inspect} (支持 #{ELLIPSOIDS.keys.join(', ')})" unless params
101
+
102
+ [params[0], 1.0 / params[1]]
103
+ end
104
+
105
+ # 子午线弧长
106
+ def meridional_arc(p, a, e2)
107
+ a * ((1 - e2 / 4 - 3 * e2**2 / 64 - 5 * e2**3 / 256) * p -
108
+ (3 * e2 / 8 + 3 * e2**2 / 32 + 45 * e2**3 / 1024) * Math.sin(2 * p) +
109
+ (15 * e2**2 / 256 + 45 * e2**3 / 1024) * Math.sin(4 * p) -
110
+ (35 * e2**3 / 3072) * Math.sin(6 * p))
111
+ end
112
+
113
+ # 底点纬度迭代
114
+ def footpoint_latitude(mu, e1)
115
+ mu + (3 * e1 / 2 - 27 * e1**3 / 32) * Math.sin(2 * mu) +
116
+ (21 * e1**2 / 16 - 55 * e1**4 / 32) * Math.sin(4 * mu) +
117
+ (151 * e1**3 / 96) * Math.sin(6 * mu) +
118
+ (1097 * e1**4 / 512) * Math.sin(8 * mu)
119
+ end
120
+
121
+ def deg2rad(deg)
122
+ deg * Math::PI / 180.0
123
+ end
124
+
125
+ def rad2deg(rad)
126
+ rad * 180.0 / Math::PI
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "json"
5
+
6
+ module Coordconver
7
+ module Utils
8
+ # 轻量 HTTP 客户端, 仅依赖标准库。
9
+ # 网络层失败(超时/连接错误/非 2xx)会自动重试, 重试耗尽后抛出 Coordconver::NetworkError。
10
+ class Http
11
+ DEFAULT_OPEN_TIMEOUT = 5
12
+ DEFAULT_READ_TIMEOUT = 10
13
+ DEFAULT_RETRY_TIMES = 3
14
+ RETRY_BASE_SLEEP = 0.5
15
+
16
+ HTTP_VERB_MAP = {
17
+ get: Net::HTTP::Get,
18
+ post: Net::HTTP::Post,
19
+ put: Net::HTTP::Put,
20
+ delete: Net::HTTP::Delete
21
+ }.freeze
22
+
23
+ DEFAULT_HEADERS = {
24
+ "user-agent" => "coordconver/#{Coordconver::VERSION} (+https://github.com/cheenwe/coordconver)",
25
+ "accept" => "application/json"
26
+ }.freeze
27
+
28
+ RETRYABLE_ERRORS = [
29
+ Net::OpenTimeout, Net::ReadTimeout, Errno::ECONNRESET,
30
+ Errno::ECONNREFUSED, Errno::ETIMEDOUT, SocketError, EOFError
31
+ ].freeze
32
+
33
+ def initialize(method, url, params: nil, body: nil, headers: {})
34
+ method = method.to_s.downcase.to_sym
35
+ raise ArgumentError, "不支持的 HTTP method: #{method}" unless HTTP_VERB_MAP.key?(method)
36
+
37
+ @uri = URI(url)
38
+ @uri.query = build_query(params) if params && !params.empty?
39
+ @method = method
40
+ @body = body
41
+ @headers = headers
42
+ end
43
+
44
+ def send_request
45
+ attempts = 0
46
+ begin
47
+ attempts += 1
48
+ perform
49
+ rescue *RETRYABLE_ERRORS => e
50
+ raise NetworkError, "#{@uri.host} 请求失败: #{e.class}: #{e.message}" if attempts >= DEFAULT_RETRY_TIMES
51
+
52
+ sleep(RETRY_BASE_SLEEP * (2**(attempts - 1)))
53
+ retry
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def perform
60
+ opts = {
61
+ use_ssl: @uri.scheme == "https",
62
+ open_timeout: open_timeout,
63
+ read_timeout: read_timeout
64
+ }
65
+ Net::HTTP.start(@uri.host, @uri.port, **opts) do |http|
66
+ response = http.request(build_request)
67
+ unless response.is_a?(Net::HTTPSuccess)
68
+ raise NetworkError, "#{@uri.host} 返回 HTTP #{response.code}"
69
+ end
70
+
71
+ response
72
+ end
73
+ end
74
+
75
+ def build_request
76
+ request = HTTP_VERB_MAP[@method].new(@uri)
77
+ request.initialize_http_header(DEFAULT_HEADERS.merge(@headers))
78
+ request.body = @body.to_json if @body
79
+ request
80
+ end
81
+
82
+ def build_query(params)
83
+ URI.encode_www_form(params)
84
+ end
85
+
86
+ def open_timeout
87
+ configured = Coordconver::Geo::Configuration.configured? && Coordconver::Geo::Configuration.settings[:open_timeout]
88
+ configured || DEFAULT_OPEN_TIMEOUT
89
+ end
90
+
91
+ def read_timeout
92
+ configured = Coordconver::Geo::Configuration.configured? && Coordconver::Geo::Configuration.settings[:read_timeout]
93
+ configured || DEFAULT_READ_TIMEOUT
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coordconver
4
+ module Utils
5
+ module Request
6
+ extend self
7
+
8
+ def get(url, params: nil, headers: {})
9
+ send_request(:get, url, params: params, headers: headers)
10
+ end
11
+
12
+ def post(url, body: nil, headers: {})
13
+ send_request(:post, url, body: body, headers: headers)
14
+ end
15
+
16
+ def put(url, body: nil, headers: {})
17
+ send_request(:put, url, body: body, headers: headers)
18
+ end
19
+
20
+ def delete(url, params: nil, headers: {})
21
+ send_request(:delete, url, params: params, headers: headers)
22
+ end
23
+
24
+ def send_request(method, url, params: nil, body: nil, headers: {})
25
+ raw_response = Http.new(
26
+ method.to_sym,
27
+ url,
28
+ params: params,
29
+ body: body,
30
+ headers: headers
31
+ ).send_request
32
+
33
+ parse_body(raw_response.body)
34
+ rescue JSON::ParserError => e
35
+ raise NetworkError, "响应不是合法 JSON: #{e.message}"
36
+ end
37
+
38
+ def parse_body(body)
39
+ JSON.parse(body)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Coordconver
2
- VERSION = "0.1.3"
4
+ VERSION = "1.1.0"
3
5
  end
data/lib/coordconver.rb CHANGED
@@ -1,8 +1,33 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "coordconver/version"
4
+ require "coordconver/errors"
2
5
  require "coordconver/coordconver"
3
6
  require "coordconver/degree"
7
+ require "coordconver/formats"
8
+ require "coordconver/projection"
9
+ require "coordconver/geo/configuration"
10
+ require "coordconver/geo/key_pool"
11
+ require "coordconver/geo/cache"
12
+ require "coordconver/geo/api"
13
+ require "coordconver/geo/client"
14
+ require "coordconver/geo/baidu"
15
+ require "coordconver/geo/gaode"
16
+ require "coordconver/geo/tencent"
17
+ require "coordconver/utils/http"
18
+ require "coordconver/utils/request"
4
19
 
5
20
  module Coordconver
6
- include Coordconver
7
- include Degree
21
+ # 坐标系转换/距离/方位角等方法已直接定义在 Coordconver 单例上,
22
+ # 如 Coordconver.wgs_gcj(lng, lat) / Coordconver.distance(...) / Coordconver.bearing(...)
23
+ extend Degree
24
+ extend Formats
25
+ extend Projection
26
+
27
+ # 便捷常量别名, 兼容 Coordconver::Baidu / Coordconver::Gaode 等用法
28
+ Baidu = Geo::Baidu
29
+ Gaode = Geo::Gaode
30
+ Tencent = Geo::Tencent
31
+ Client = Geo::Client
32
+ Configuration = Geo::Configuration
8
33
  end
metadata CHANGED
@@ -1,43 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coordconver
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - chenwei
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-12-12 00:00:00.000000000 Z
11
+ date: 2026-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: bundler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.12'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.12'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: rake
29
15
  requirement: !ruby/object:Gem::Requirement
30
16
  requirements:
31
- - - "~>"
17
+ - - ">="
32
18
  - !ruby/object:Gem::Version
33
- version: '10.0'
19
+ version: '13.0'
34
20
  type: :development
35
21
  prerelease: false
36
22
  version_requirements: !ruby/object:Gem::Requirement
37
23
  requirements:
38
- - - "~>"
24
+ - - ">="
39
25
  - !ruby/object:Gem::Version
40
- version: '10.0'
26
+ version: '13.0'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: minitest
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -52,33 +38,59 @@ dependencies:
52
38
  - - "~>"
53
39
  - !ruby/object:Gem::Version
54
40
  version: '5.0'
55
- description: 1.提供了百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换. 2.坐标点到经纬度的相互转换.
41
+ description: 纯离线实现百度坐标(BD-09)、国测局坐标(GCJ-02)、地球坐标(WGS-84)互转(含厘米级精确逆变换), 两点距离/方位角/偏移点,
42
+ 经纬度与度分秒互转, WKT/GeoJSON 互转, 高斯-克吕格投影正反算; 并封装百度/高德/腾讯 Web 服务 API 实现地址与坐标互转, 支持多 key
43
+ 自动轮询与进程内缓存。附带命令行工具。
56
44
  email:
57
45
  - cheenwe@gmail.com
58
- executables: []
46
+ executables:
47
+ - coordconver
59
48
  extensions: []
60
49
  extra_rdoc_files: []
61
50
  files:
51
+ - ".github/workflows/ci.yml"
62
52
  - ".gitignore"
63
- - ".travis.yml"
53
+ - CHANGELOG.md
64
54
  - CODE_OF_CONDUCT.md
65
55
  - Gemfile
66
56
  - LICENSE.txt
57
+ - README.en.md
67
58
  - README.md
68
59
  - Rakefile
69
60
  - bin/console
70
- - bin/coordconver
71
61
  - bin/setup
72
62
  - coordconver.gemspec
63
+ - docs/cc-algorithms.js
64
+ - docs/index.html
65
+ - exe/coordconver
73
66
  - lib/coordconver.rb
74
67
  - lib/coordconver/coordconver.rb
75
68
  - lib/coordconver/degree.rb
69
+ - lib/coordconver/errors.rb
70
+ - lib/coordconver/formats.rb
71
+ - lib/coordconver/geo/api.rb
72
+ - lib/coordconver/geo/baidu.rb
73
+ - lib/coordconver/geo/cache.rb
74
+ - lib/coordconver/geo/client.rb
75
+ - lib/coordconver/geo/configuration.rb
76
+ - lib/coordconver/geo/gaode.rb
77
+ - lib/coordconver/geo/key_pool.rb
78
+ - lib/coordconver/geo/tencent.rb
79
+ - lib/coordconver/projection.rb
80
+ - lib/coordconver/utils/http.rb
81
+ - lib/coordconver/utils/request.rb
76
82
  - lib/coordconver/version.rb
77
83
  homepage: https://github.com/cheenwe/coordconver
78
84
  licenses:
79
85
  - MIT
80
- metadata: {}
81
- post_install_message:
86
+ metadata:
87
+ allowed_push_host: https://rubygems.org
88
+ homepage_uri: https://github.com/cheenwe/coordconver
89
+ source_code_uri: https://github.com/cheenwe/coordconver
90
+ changelog_uri: https://github.com/cheenwe/coordconver/blob/master/CHANGELOG.md
91
+ bug_tracker_uri: https://github.com/cheenwe/coordconver/issues
92
+ rubygems_mfa_required: 'true'
93
+ post_install_message:
82
94
  rdoc_options: []
83
95
  require_paths:
84
96
  - lib
@@ -86,16 +98,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
86
98
  requirements:
87
99
  - - ">="
88
100
  - !ruby/object:Gem::Version
89
- version: '0'
101
+ version: '2.7'
90
102
  required_rubygems_version: !ruby/object:Gem::Requirement
91
103
  requirements:
92
104
  - - ">="
93
105
  - !ruby/object:Gem::Version
94
106
  version: '0'
95
107
  requirements: []
96
- rubyforge_project:
97
- rubygems_version: 2.5.1
98
- signing_key:
108
+ rubygems_version: 3.1.6
109
+ signing_key:
99
110
  specification_version: 4
100
- summary: 坐标转换/Coordconver
111
+ summary: 百度(BD-09)/火星(GCJ-02)/地球(WGS-84)坐标系互转、球面几何、高斯-克吕格投影, 以及百度/高德/腾讯地理编码
101
112
  test_files: []
data/.travis.yml DELETED
@@ -1,8 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.3.1
5
- before_install: gem install bundler -v 1.12.5
6
-
7
- script:
8
- - bundle exec rake test
data/bin/coordconver DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require "coordconver"
3
-
4
- puts Coordconver.wgs84_bd09(ARGV[0],ARGV[1] )