clwy_china_city 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +31 -0
  4. data/app/assets/javascripts/china_city/application.js +3 -0
  5. data/app/assets/javascripts/china_city/jquery.china_city.js +30 -0
  6. data/app/assets/stylesheets/china_city/application.css +13 -0
  7. data/app/controllers/china_city/application_controller.rb +4 -0
  8. data/app/controllers/china_city/data_controller.rb +13 -0
  9. data/app/helpers/china_city/application_helper.rb +4 -0
  10. data/app/views/china_city/data/index.html.erb +37 -0
  11. data/app/views/layouts/china_city/application.html.erb +12 -0
  12. data/config/routes.rb +4 -0
  13. data/db/areas.json +190649 -0
  14. data/db/district_gb2260_taobao.yml +109 -0
  15. data/lib/china_city.rb +124 -0
  16. data/lib/china_city/engine.rb +13 -0
  17. data/lib/china_city/version.rb +3 -0
  18. data/lib/china_city_tasks.rake +136 -0
  19. data/spec/controllers/china_city/data_controller_spec.rb +12 -0
  20. data/spec/dummy/README.rdoc +28 -0
  21. data/spec/dummy/Rakefile +6 -0
  22. data/spec/dummy/app/assets/javascripts/application.js +14 -0
  23. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  24. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  25. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  26. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  27. data/spec/dummy/bin/bundle +3 -0
  28. data/spec/dummy/bin/rails +4 -0
  29. data/spec/dummy/bin/rake +4 -0
  30. data/spec/dummy/config.ru +4 -0
  31. data/spec/dummy/config/application.rb +35 -0
  32. data/spec/dummy/config/boot.rb +5 -0
  33. data/spec/dummy/config/database.yml +25 -0
  34. data/spec/dummy/config/environment.rb +5 -0
  35. data/spec/dummy/config/environments/development.rb +29 -0
  36. data/spec/dummy/config/environments/production.rb +80 -0
  37. data/spec/dummy/config/environments/test.rb +36 -0
  38. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  39. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  40. data/spec/dummy/config/initializers/inflections.rb +16 -0
  41. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  42. data/spec/dummy/config/initializers/secret_token.rb +13 -0
  43. data/spec/dummy/config/initializers/session_store.rb +3 -0
  44. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  45. data/spec/dummy/config/locales/en.yml +23 -0
  46. data/spec/dummy/config/routes.rb +4 -0
  47. data/spec/dummy/public/404.html +58 -0
  48. data/spec/dummy/public/422.html +58 -0
  49. data/spec/dummy/public/500.html +57 -0
  50. data/spec/dummy/public/favicon.ico +0 -0
  51. data/spec/dummy/script/rails +6 -0
  52. data/spec/features/china_city_spec.rb +69 -0
  53. data/spec/lib/china_city_spec.rb +64 -0
  54. data/spec/spec_helper.rb +29 -0
  55. 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'
@@ -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,3 @@
1
+ module ChinaCity
2
+ VERSION = "0.0.6"
3
+ 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,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe ChinaCity::DataController do
4
+
5
+ describe "GET 'show'" do
6
+ it "returns http success" do
7
+ get 'show', id: '000000', use_route: 'china_city'
8
+ response.should be_success
9
+ end
10
+ end
11
+
12
+ 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>.
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Dummy::Application.load_tasks
@@ -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 .