clwy_china_city 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +31 -0
- data/app/assets/javascripts/china_city/application.js +3 -0
- data/app/assets/javascripts/china_city/jquery.china_city.js +30 -0
- data/app/assets/stylesheets/china_city/application.css +13 -0
- data/app/controllers/china_city/application_controller.rb +4 -0
- data/app/controllers/china_city/data_controller.rb +13 -0
- data/app/helpers/china_city/application_helper.rb +4 -0
- data/app/views/china_city/data/index.html.erb +37 -0
- data/app/views/layouts/china_city/application.html.erb +12 -0
- data/config/routes.rb +4 -0
- data/db/areas.json +190649 -0
- data/db/district_gb2260_taobao.yml +109 -0
- data/lib/china_city.rb +124 -0
- data/lib/china_city/engine.rb +13 -0
- data/lib/china_city/version.rb +3 -0
- data/lib/china_city_tasks.rake +136 -0
- data/spec/controllers/china_city/data_controller_spec.rb +12 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +14 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +35 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +36 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +13 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/features/china_city_spec.rb +69 -0
- data/spec/lib/china_city_spec.rb +64 -0
- data/spec/spec_helper.rb +29 -0
- metadata +292 -0
@@ -0,0 +1,109 @@
|
|
1
|
+
---
|
2
|
+
'130109': '130182'
|
3
|
+
'130110': '130185'
|
4
|
+
'130111': '130124'
|
5
|
+
'130209': '130230'
|
6
|
+
'220113': '220181'
|
7
|
+
'220605': '220625'
|
8
|
+
'220781': '220724'
|
9
|
+
'230110': '230106'
|
10
|
+
'230112': '230181'
|
11
|
+
'320117': '320124'
|
12
|
+
'320118': '320125'
|
13
|
+
'320312': '320323'
|
14
|
+
'320509': '320584'
|
15
|
+
'320707': '320721'
|
16
|
+
'321012': '321088'
|
17
|
+
'321204': '321284'
|
18
|
+
'330603': '330621'
|
19
|
+
'330604': '330682'
|
20
|
+
'340124': '341421'
|
21
|
+
'340181': '341400'
|
22
|
+
'340225': '341422'
|
23
|
+
'340522': '341423'
|
24
|
+
'340523': '341424'
|
25
|
+
'350527': '350527'
|
26
|
+
'360482': '360483'
|
27
|
+
'360703': '360782'
|
28
|
+
'370812': '370882'
|
29
|
+
'370911': '370903'
|
30
|
+
'371003': '371081'
|
31
|
+
'371403': '371421'
|
32
|
+
'371603': '371624'
|
33
|
+
'410311': '410307'
|
34
|
+
'419001': '410881'
|
35
|
+
'420304': '420321'
|
36
|
+
'421303': '421302'
|
37
|
+
'430112': '430122'
|
38
|
+
'440117': '440184'
|
39
|
+
'440118': '440183'
|
40
|
+
'440904': '440903'
|
41
|
+
'441403': '441421'
|
42
|
+
'441803': '441827'
|
43
|
+
'445103': '445121'
|
44
|
+
'445203': '445221'
|
45
|
+
'445303': '445323'
|
46
|
+
'450312': '450322'
|
47
|
+
'469021': '469025'
|
48
|
+
'469022': '469026'
|
49
|
+
'469023': '469027'
|
50
|
+
'469024': '469028'
|
51
|
+
'469029': '469035'
|
52
|
+
'500116': '500381'
|
53
|
+
'500117': '500382'
|
54
|
+
'500118': '500383'
|
55
|
+
'500119': '500384'
|
56
|
+
'500120': '500227'
|
57
|
+
'500151': '500224'
|
58
|
+
'511503': '511522'
|
59
|
+
'511703': '511721'
|
60
|
+
'511803': '511821'
|
61
|
+
'520115': '520151'
|
62
|
+
'520502': '522401'
|
63
|
+
'520521': '522422'
|
64
|
+
'520522': '522423'
|
65
|
+
'520523': '522424'
|
66
|
+
'520524': '522425'
|
67
|
+
'520525': '522426'
|
68
|
+
'520526': '522427'
|
69
|
+
'520527': '522428'
|
70
|
+
'520602': '522201'
|
71
|
+
'520603': '522230'
|
72
|
+
'520621': '522222'
|
73
|
+
'520622': '522223'
|
74
|
+
'520623': '522224'
|
75
|
+
'520624': '522225'
|
76
|
+
'520625': '522226'
|
77
|
+
'520626': '522227'
|
78
|
+
'520627': '522228'
|
79
|
+
'520628': '522229'
|
80
|
+
'530114': '530121'
|
81
|
+
'532503': '532522'
|
82
|
+
'532504': '532526'
|
83
|
+
'532601': '532621'
|
84
|
+
'540202': '542301'
|
85
|
+
'540221': '542322'
|
86
|
+
'540222': '542323'
|
87
|
+
'540223': '542324'
|
88
|
+
'540224': '542325'
|
89
|
+
'540225': '542326'
|
90
|
+
'540226': '542327'
|
91
|
+
'540227': '542328'
|
92
|
+
'540228': '542329'
|
93
|
+
'540229': '542330'
|
94
|
+
'540230': '542331'
|
95
|
+
'540231': '542332'
|
96
|
+
'540232': '542333'
|
97
|
+
'540233': '542334'
|
98
|
+
'540234': '542335'
|
99
|
+
'540235': '542336'
|
100
|
+
'540236': '542337'
|
101
|
+
'540237': '542338'
|
102
|
+
'542431': '542432'
|
103
|
+
'630202': '632123'
|
104
|
+
'630221': '632121'
|
105
|
+
'630222': '632122'
|
106
|
+
'630223': '632126'
|
107
|
+
'630224': '632127'
|
108
|
+
'630225': '632128'
|
109
|
+
'632701': '632721'
|
data/lib/china_city.rb
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "china_city/engine"
|
3
|
+
|
4
|
+
module ChinaCity
|
5
|
+
CHINA = '000000' # 全国
|
6
|
+
PATTERN = /(\d{2})(\d{2})(\d{2})/
|
7
|
+
|
8
|
+
class << self
|
9
|
+
# @options[:show_all] 是否显示港澳台这三处敏感地区
|
10
|
+
def list(parent_id='000000', options = {})
|
11
|
+
parent_id ||= '000000'
|
12
|
+
show_all = options[:show_all] || false
|
13
|
+
|
14
|
+
result = []
|
15
|
+
return result if parent_id.blank?
|
16
|
+
province_id = province(parent_id)
|
17
|
+
city_id = city(parent_id)
|
18
|
+
district_id = district(parent_id)
|
19
|
+
children = data
|
20
|
+
children = children[province_id][:children] if children.has_key?(province_id)
|
21
|
+
children = children[city_id][:children] if children.has_key?(city_id)
|
22
|
+
children = children[district_id][:children] if children.has_key?(district_id)
|
23
|
+
children.each_key do |id|
|
24
|
+
next if (!show_all && children[id][:sensitive_areas])
|
25
|
+
result.push [children[id][:text], id]
|
26
|
+
end
|
27
|
+
|
28
|
+
#sort
|
29
|
+
result.sort! {|a, b| a[1] <=> b[1]}
|
30
|
+
result
|
31
|
+
end
|
32
|
+
|
33
|
+
# @options[:prepend_parent] 是否显示上级区域
|
34
|
+
def get(id, options = {})
|
35
|
+
return '' if id.blank?
|
36
|
+
prepend_parent = options[:prepend_parent] || false
|
37
|
+
children = data
|
38
|
+
return children[id][:text] if children.has_key?(id)
|
39
|
+
province_id = province(id)
|
40
|
+
province_text = children[province_id][:text]
|
41
|
+
children = children[province_id][:children]
|
42
|
+
return "#{prepend_parent ? province_text : ''}#{children[id][:text]}" if children.has_key?(id)
|
43
|
+
city_id = city(id)
|
44
|
+
city_text = children[city_id][:text]
|
45
|
+
children = children[city_id][:children]
|
46
|
+
return "#{prepend_parent ? (province_text + city_text) : ''}#{children[id][:text]}" if children.has_key?(id)
|
47
|
+
district_id = district(id)
|
48
|
+
district_text = children[district_id][:text]
|
49
|
+
children = children[district_id][:children]
|
50
|
+
return "#{prepend_parent ? (province_text + city_text + district_text) : ''}#{children[id][:text]}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def province(code)
|
54
|
+
match(code)[1].ljust(6, '0')
|
55
|
+
end
|
56
|
+
|
57
|
+
def city(code)
|
58
|
+
id_match = match(code)
|
59
|
+
"#{id_match[1]}#{id_match[2]}".ljust(6, '0')
|
60
|
+
end
|
61
|
+
|
62
|
+
def district(code)
|
63
|
+
code[0..5].rjust(6,'0')
|
64
|
+
end
|
65
|
+
|
66
|
+
def data
|
67
|
+
unless @list
|
68
|
+
#{ '440000' =>
|
69
|
+
# {
|
70
|
+
# :text => '广东',
|
71
|
+
# :children =>
|
72
|
+
# {
|
73
|
+
# '440300' =>
|
74
|
+
# {
|
75
|
+
# :text => '深圳',
|
76
|
+
# :children =>
|
77
|
+
# {
|
78
|
+
# '440305' => { :text => '南山' }
|
79
|
+
# }
|
80
|
+
# }
|
81
|
+
# }
|
82
|
+
# }
|
83
|
+
# }
|
84
|
+
@list = {}
|
85
|
+
#@see: https://github.com/cn/GB2260
|
86
|
+
json = JSON.parse(File.read("#{Engine.root}/db/areas.json"))
|
87
|
+
streets = json.values.flatten
|
88
|
+
streets.each do |street|
|
89
|
+
id = street['id']
|
90
|
+
text = street['text']
|
91
|
+
sensitive_areas = street['sensitive_areas'] || false
|
92
|
+
if id.size == 6 # 省市区
|
93
|
+
if id.end_with?('0000') # 省
|
94
|
+
@list[id] = {:text => text, :sensitive_areas => sensitive_areas, :children => {}}
|
95
|
+
elsif id.end_with?('00') # 市
|
96
|
+
province_id = province(id)
|
97
|
+
@list[province_id] = {:text => nil, :children => {}} unless @list.has_key?(province_id)
|
98
|
+
@list[province_id][:children][id] = {:text => text, :sensitive_areas => sensitive_areas, :children => {}}
|
99
|
+
else
|
100
|
+
province_id = province(id)
|
101
|
+
city_id = city(id)
|
102
|
+
@list[province_id] = {:text => text, :sensitive_areas => sensitive_areas, :children => {}} unless @list.has_key?(province_id)
|
103
|
+
@list[province_id][:children][city_id] = {:text => text, :sensitive_areas => sensitive_areas, :children => {}} unless @list[province_id][:children].has_key?(city_id)
|
104
|
+
@list[province_id][:children][city_id][:children][id] = {:text => text, :sensitive_areas => sensitive_areas, :children => {}}
|
105
|
+
end
|
106
|
+
else # 街道
|
107
|
+
province_id = province(id)
|
108
|
+
city_id = city(id)
|
109
|
+
district_id = district(id)
|
110
|
+
@list[province_id] = {:text => text, :sensitive_areas => sensitive_areas, :children => {}} unless @list.has_key?(province_id)
|
111
|
+
@list[province_id][:children][city_id] = {:text => text, :sensitive_areas => sensitive_areas, :children => {}} unless @list[province_id][:children].has_key?(city_id)
|
112
|
+
@list[province_id][:children][city_id][:children][district_id] = {:text => text, :sensitive_areas => sensitive_areas, :children => {}} unless @list[province_id][:children][city_id][:children].has_key?(district_id)
|
113
|
+
@list[province_id][:children][city_id][:children][district_id][:children][id] = {:text => text, :sensitive_areas => sensitive_areas}
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
@list
|
118
|
+
end
|
119
|
+
|
120
|
+
def match(code)
|
121
|
+
code.match(PATTERN)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ChinaCity
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace ChinaCity
|
4
|
+
|
5
|
+
config.generators do |g|
|
6
|
+
g.test_framework :rspec, fixture: false
|
7
|
+
# g.fixture_replacement :factory_girl, dir: 'spec/factories'
|
8
|
+
g.assets false
|
9
|
+
g.helper false
|
10
|
+
g.view_specs false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'GB2260'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
namespace :gem do
|
5
|
+
|
6
|
+
desc '更新 areas.json 数据'
|
7
|
+
task :update_data do
|
8
|
+
# 1. 获取淘宝所有的街道
|
9
|
+
gb2260 = GB2260.new
|
10
|
+
|
11
|
+
provinces = []
|
12
|
+
cities = []
|
13
|
+
districts = []
|
14
|
+
streets = []
|
15
|
+
|
16
|
+
gb2260.provinces.each do |province| # 省
|
17
|
+
gb_cities = gb2260.prefectures(province.code)
|
18
|
+
gb_cities.each do |city| # 市
|
19
|
+
cities << { text:city.name, id: city.code }
|
20
|
+
gb_districts = gb2260.counties(city.code)
|
21
|
+
gb_districts << GB2260::Division.new("#{city.code[0,4]}99", city.name) if gb_districts.empty? # 中山市等没有县级,需要自动补上
|
22
|
+
gb_districts.each do |district| # 区
|
23
|
+
districts << { text: district.name, id: district.code }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
provinces << { text:province.name, id: province.code } unless gb_cities.empty? # 台湾省、香港、澳门没有市
|
27
|
+
end
|
28
|
+
|
29
|
+
map_codes = YAML.load_file("db/district_gb2260_taobao.yml")
|
30
|
+
districts.each do |district|
|
31
|
+
code = district[:id]
|
32
|
+
result = get_remote_streets(map_codes[code] || code)
|
33
|
+
result = [{text: "全境", id: "#{code}001"}] unless result
|
34
|
+
result.each do |tstreet| # 街道
|
35
|
+
street_code = "#{code}#{tstreet[:id][-3,3]}" # 保证编码与区一致
|
36
|
+
streets << {text: tstreet[:text], id: street_code}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
content = JSON.pretty_generate(province: provinces, city: cities, district: districts, street: streets)
|
41
|
+
|
42
|
+
path = File.join("db/areas.json")
|
43
|
+
File.write(path, content)
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "显示国标与淘宝区划代码不匹配的记录."
|
47
|
+
task :list_mismatch_districts do
|
48
|
+
gb2260 = GB2260.new
|
49
|
+
map_codes = YAML.load_file("db/district_gb2260_taobao.yml")
|
50
|
+
map_codes.each do |key, value|
|
51
|
+
division = gb2260.get(key)
|
52
|
+
puts [division.province, division.prefecture, division.county].compact.map(&:name).join('/')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
desc "获取淘宝街道信息."
|
57
|
+
task :list_streets, [:code] do |t, args|
|
58
|
+
code = args.code
|
59
|
+
puts get_streets code
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
desc '处理淘宝区代码与国标不一致的情况,将对应关系保存到 db/district_gb2260_taobao'
|
64
|
+
task :save_district_gb2260_taobao_map do
|
65
|
+
gb2260 = GB2260.new
|
66
|
+
districts = []
|
67
|
+
empty_districts = []
|
68
|
+
|
69
|
+
# 1. 汇总所有区记录
|
70
|
+
gb2260.provinces.each do |province|
|
71
|
+
gb2260.prefectures(province.code).each do |city|
|
72
|
+
data = gb2260.counties(city.code)
|
73
|
+
GB2260::Division.new("#{city.code[0,4]}99", city.name) if data.empty? # 中山市没有县级,需要自动补上
|
74
|
+
data.each do |district|
|
75
|
+
districts << district
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# 2. 获取街道记录
|
81
|
+
# districts.select{|district| district.code.start_with?('1301')}.each do |district|
|
82
|
+
districts.each do |district|
|
83
|
+
result = get_remote_streets(district.code)
|
84
|
+
empty_districts << district unless result
|
85
|
+
end
|
86
|
+
|
87
|
+
# 3. 获取淘宝省市区记录
|
88
|
+
response = HTTParty.get("https://g.alicdn.com/kg/??address/6.0.4/index-min.js?t=1449112049369.js")
|
89
|
+
tdata = response.to_s.sub(/.+return\st=e\}\(\),r=function\(t\)\{var\se=/, '')
|
90
|
+
tdata = tdata.sub(/;\nreturn\st=e\}\(\),c=function\(t\).+/m, '')
|
91
|
+
cities = JSON.parse(tdata)
|
92
|
+
result = {}
|
93
|
+
cities.each do |city|
|
94
|
+
result[city[1][0]] = city[0]
|
95
|
+
end
|
96
|
+
|
97
|
+
# 4. 输出结果
|
98
|
+
map_data = {}
|
99
|
+
empty_districts.each do |district|
|
100
|
+
code = district.code
|
101
|
+
text = district.name
|
102
|
+
next if %w(市辖区 城区 郊区).include?(text)
|
103
|
+
text = text.gsub(/(自治县|市|区|县)$/,'')
|
104
|
+
text = text.gsub(/(黎族苗族|黎族苗族|侗族|土家族苗族|彝族回族苗族|土家族|苗族|回族土族|土族|回族|撒拉族)$/,'')
|
105
|
+
text = '和县' if text == '和'
|
106
|
+
if tid = result[text]
|
107
|
+
map_data[code] = tid
|
108
|
+
else
|
109
|
+
puts text
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
path = "db/district_gb2260_taobao.yml"
|
114
|
+
File.write(path, map_data.to_yaml)
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
def get_streets(code)
|
119
|
+
map_codes = YAML.load_file("db/district_gb2260_taobao.yml")
|
120
|
+
get_remote_streets(map_codes[code] || code)
|
121
|
+
end
|
122
|
+
|
123
|
+
def get_remote_streets(code)
|
124
|
+
l1 = code[0..1].ljust(6,'0')
|
125
|
+
l2 = code[0..3].ljust(6,'0')
|
126
|
+
l3 = code
|
127
|
+
l3 = l2 if l3.end_with?('99') # 特殊处理:县级如果以99结尾,则需要取市级
|
128
|
+
puts "fetching: #{l3}"
|
129
|
+
response = HTTParty.get("https://lsp.wuliu.taobao.com/locationservice/addr/output_address_town_array.do?l1=#{l1}&l2=#{l2}&l3=#{l3}&lang=zh-S&_ksTS=1440400908112_7583")
|
130
|
+
if response.size > 40
|
131
|
+
ret = response[33..-5].split(',').map{|i| i.gsub(/[\[|\]|\"|\']+/,'')}.each_slice(4).to_a
|
132
|
+
ret.map{|i| {text:i[1], id:i[0]}}
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
== README
|
2
|
+
|
3
|
+
This README would normally document whatever steps are necessary to get the
|
4
|
+
application up and running.
|
5
|
+
|
6
|
+
Things you may want to cover:
|
7
|
+
|
8
|
+
* Ruby version
|
9
|
+
|
10
|
+
* System dependencies
|
11
|
+
|
12
|
+
* Configuration
|
13
|
+
|
14
|
+
* Database creation
|
15
|
+
|
16
|
+
* Database initialization
|
17
|
+
|
18
|
+
* How to run the test suite
|
19
|
+
|
20
|
+
* Services (job queues, cache servers, search engines, etc.)
|
21
|
+
|
22
|
+
* Deployment instructions
|
23
|
+
|
24
|
+
* ...
|
25
|
+
|
26
|
+
|
27
|
+
Please feel free to use a different markup language if you do not plan to run
|
28
|
+
<tt>rake doc:app</tt>.
|
data/spec/dummy/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//= require 'jquery'
|
13
|
+
//= require 'china_city/jquery.china_city'
|
14
|
+
//= require_tree .
|