cartocss_helper 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,148 @@
1
+ require_relative 'visualise_changes_diff_from_images'
2
+ require_relative 'git'
3
+ require_relative 'downloader'
4
+
5
+ module CartoCSSHelper
6
+ class VisualDiff
7
+ def self.visualise_changes_synthethic_test(tags, type, on_water, zlevel_range, old_branch, new_branch)
8
+ tags = VisualDiff.remove_magic_from_tags(tags)
9
+ on_water_string = ''
10
+ if on_water
11
+ on_water_string = ' on water'
12
+ end
13
+ header = "#{ VisualDiff.dict_to_pretty_tag_list(tags) } #{ type }#{ on_water_string }"
14
+ puts "visualise_changes_synthethic_test <#{header}> #{old_branch} -> #{new_branch}"
15
+ Git.checkout(old_branch)
16
+ old = VisualDiff.collect_images_for_synthethic_test(tags, type, on_water, zlevel_range)
17
+ Git.checkout(new_branch)
18
+ new = VisualDiff.collect_images_for_synthethic_test(tags, type, on_water, zlevel_range)
19
+ VisualDiff.pack_image_sets old, new, header, old_branch, new_branch, 200
20
+ end
21
+
22
+ def self.remove_magic_from_tags(tags)
23
+ magicless_tags = Hash.new
24
+ tags.each {|key, value|
25
+ if value == :any
26
+ value = 'any tag value'
27
+ end
28
+ magicless_tags[key]=value
29
+ }
30
+ return magicless_tags
31
+ end
32
+
33
+ def self.collect_images_for_synthethic_test(tags, type, on_water, zlevel_range)
34
+ collection = []
35
+ zlevel_range.each { |zlevel|
36
+ scene = Scene.new(tags, zlevel, on_water, type)
37
+ collection.push(ImageForComparison.new(scene.get_image_filename, "z#{zlevel}"))
38
+ }
39
+ return collection
40
+ end
41
+
42
+ class RealDataSource
43
+ def initialize(latitude, longitude, wanted_download_bbox_size)
44
+ wanted_download_bbox_size = [wanted_download_bbox_size, 0.001].max
45
+ wanted_download_bbox_size = [wanted_download_bbox_size, 0.400].min #0.5 is too big for Utrecht
46
+ @download_bbox_size = wanted_download_bbox_size
47
+ @latitude = latitude
48
+ @longitude = longitude
49
+ @data_filename = Downloader.download_osm_data_for_location(@latitude, @longitude, @download_bbox_size)
50
+ @loaded = false
51
+ end
52
+
53
+ def load
54
+ if !@loaded
55
+ puts "\tloading data into database"
56
+ DataFileLoader.load_data_into_database(@data_filename)
57
+ puts "\tgenerating images"
58
+ @loaded = true
59
+ end
60
+ end
61
+
62
+ def get_timestamp
63
+ f = File.new(@data_filename)
64
+ return f.mtime.to_i
65
+ end
66
+ end
67
+
68
+ def self.visualise_changes_on_real_data(tags, type, wanted_latitude, wanted_longitude, zlevels, old_branch, new_branch)
69
+ #special support for following tag values: :any_value
70
+ header = "#{ VisualDiff.dict_to_pretty_tag_list(tags) } #{type} #{ wanted_latitude } #{ wanted_longitude } #{zlevels}"
71
+ puts "visualise_changes_on_real_data <#{header}> #{old_branch} -> #{new_branch}"
72
+ latitude, longitude = Downloader.locate_element_with_given_tags_and_type tags, type, wanted_latitude, wanted_longitude
73
+ download_bbox_size = VisualDiff.scale_inverse zlevels.min, 0.03, 14
74
+ source = RealDataSource.new(latitude, longitude, download_bbox_size)
75
+ Git.checkout old_branch
76
+ old = VisualDiff.collect_images_for_real_data_test(tags, type, latitude, longitude, zlevels, source)
77
+ Git.checkout new_branch
78
+ new = VisualDiff.collect_images_for_real_data_test(tags, type, latitude, longitude, zlevels, source)
79
+ header = "#{ VisualDiff.dict_to_pretty_tag_list(tags) } #{type} #{ wanted_latitude } #{ wanted_longitude } #{zlevels}"
80
+ VisualDiff.pack_image_sets old, new, header, old_branch, new_branch, 400
81
+ end
82
+
83
+ def self.scale_inverse(zlevel, reference_value, reference_zlevel)
84
+ return VisualDiff.scale reference_zlevel, reference_value, zlevel
85
+ end
86
+
87
+ def self.scale(zlevel, reference_value, reference_zlevel)
88
+ diff = zlevel - reference_zlevel
89
+ rescaler = 2.0**diff
90
+ return reference_value*rescaler
91
+ end
92
+
93
+ def self.collect_images_for_real_data_test(tags, type, latitude, longitude, zlevels, source)
94
+ collection = []
95
+ zlevels.each { |zlevel|
96
+ image_size_for_16_zoom_level = 1000
97
+ image_size = (VisualDiff.scale zlevel, image_size_for_16_zoom_level, 16)
98
+ mutiplier = 1000
99
+ image_size = (image_size*mutiplier).to_int
100
+ render_bbox_size = 0.015
101
+ wanted_image_size = 400
102
+ ratio = 1.0*image_size/(wanted_image_size*mutiplier)
103
+ image_size /= ratio
104
+ render_bbox_size /= ratio
105
+ image_size /= mutiplier
106
+ image_size = image_size.to_i
107
+ if image_size!=wanted_image_size
108
+ puts VisualDiff.scale zlevel, image_size_for_16_zoom_level, 16
109
+ puts zlevel
110
+ puts image_size
111
+ puts wanted_image_size
112
+ puts ratio
113
+ raise "#{image_size} mismatches #{wanted_image_size}"
114
+ end
115
+ filename = "#{CartoCSSHelper::Configuration.get_path_to_folder_for_branch_specific_cache+"#{tags.to_a.to_s} #{type} #{latitude} #{longitude} #{zlevel}zlevel #{image_size}px #{source.get_timestamp}.png"}"
116
+ if !File.exists?(filename)
117
+ source.load
118
+ Scene.run_tilemill_export_image(latitude, longitude, zlevel, render_bbox_size, image_size, filename)
119
+ end
120
+ collection.push(ImageForComparison.new(filename, "z#{zlevel}"))
121
+ }
122
+ return collection
123
+ end
124
+
125
+ def self.pack_image_sets(old, new, header, old_branch, new_branch, image_size)
126
+ old_branch = old_branch.gsub(/[\x00\/\\:\*\?\"<>\|]/, '_')
127
+ new_branch = new_branch.gsub(/[\x00\/\\:\*\?\"<>\|]/, '_')
128
+ filename_sufix = "#{ old_branch } -> #{ new_branch }"
129
+ filename = CartoCSSHelper::Configuration.get_path_to_folder_for_output + "#{header} #{filename_sufix}.png"
130
+ diff = FullSetOfComparedImages.new(old, new, header, filename, image_size)
131
+ diff.save
132
+ end
133
+ def self.dict_to_pretty_tag_list(dict)
134
+ result = ''
135
+ dict.to_a.each { |tag|
136
+ if result != ''
137
+ result << '; '
138
+ end
139
+ value = "'#{tag[1]}'"
140
+ if tag[1] == :any_value
141
+ value = '{any value}'
142
+ end
143
+ result << "#{tag[0]}=#{value}"
144
+ }
145
+ return result
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,70 @@
1
+ # encoding: UTF-8
2
+ require 'open3'
3
+
4
+ module CartoCSSHelper
5
+ end
6
+ require_relative 'cartocss_helper/tag_lister.rb'
7
+ require_relative 'cartocss_helper/visualise_changes_image_generation.rb'
8
+ require_relative 'cartocss_helper/downloader.rb'
9
+ require_relative 'cartocss_helper/data_file_handling.rb'
10
+ require_relative 'cartocss_helper/validator.rb'
11
+ require_relative 'cartocss_helper/git.rb'
12
+ include CartoCSSHelper::Validator
13
+ include CartoCSSHelper::Git
14
+
15
+ module CartoCSSHelper
16
+ def self.test_tag_on_real_data(tags, zlevels, old_branch, new_branch)
17
+ ['node', 'closed_way', 'way'].each {|type|
18
+ test_tag_on_real_data_for_this_type(tags, zlevels, old_branch, new_branch, type)
19
+ }
20
+ end
21
+
22
+ def self.test_tag_on_real_data_for_this_type(tags, zlevels, old_branch, new_branch, type)
23
+ #special support for following tag values: :any_value
24
+ krakow_latitude = 50.1
25
+ krakow_longitude = 19.9
26
+ CartoCSSHelper::VisualDiff.visualise_changes_on_real_data(tags, type, krakow_latitude, krakow_longitude, zlevels, old_branch, new_branch)
27
+ japan_latitude = 36.1
28
+ japan_longitude = 140.7
29
+ CartoCSSHelper::VisualDiff.visualise_changes_on_real_data(tags, type, japan_latitude, japan_longitude, zlevels, old_branch, new_branch)
30
+ russia_latitude = 54.8
31
+ russia_longitude = 31.7
32
+ CartoCSSHelper::VisualDiff.visualise_changes_on_real_data(tags, type, russia_latitude, russia_longitude, zlevels, old_branch, new_branch)
33
+ mecca_latitude = 21.3
34
+ mecca_longitude = 39.5
35
+ CartoCSSHelper::VisualDiff.visualise_changes_on_real_data(tags, type, mecca_latitude, mecca_longitude, zlevels, old_branch, new_branch)
36
+ georgia_latitude = 41.4
37
+ georgia_longitude = 44.5
38
+ CartoCSSHelper::VisualDiff.visualise_changes_on_real_data(tags, type, georgia_latitude, georgia_longitude, zlevels, old_branch, new_branch)
39
+ london_latitude = 51.5
40
+ london_longitude = -0.1
41
+ CartoCSSHelper::VisualDiff.visualise_changes_on_real_data(tags, type, london_latitude, london_longitude, zlevels, old_branch, new_branch)
42
+ #TODO: solve problems with respons to big to store in memory
43
+ #utrecht_latitude = 52.09
44
+ #utrecht_longitude = 5.11
45
+ #CartoCSSHelper::VisualDiff.visualise_changes_on_real_data(tags, type, utrecht_latitude, utrecht_longitude, zlevels, old_branch, new_branch)
46
+ rural_uk_latitude = 53.2
47
+ rural_uk_longitude = -1.8
48
+ CartoCSSHelper::VisualDiff.visualise_changes_on_real_data(tags, type, rural_uk_latitude, rural_uk_longitude, zlevels, old_branch, new_branch)
49
+ end
50
+
51
+ def self.add_common_secondary_tags(tags)
52
+ return tags.merge({'name' => 'ÉÉÉÉÉÉ ÉÉÉÉÉÉ ÉÉÉÉÉÉ', 'ref' => '1', 'ele' => '8000', 'operator' => 'operator ÉÉ ÉÉ ÉÉ', 'brand' => 'brand ÉÉ ÉÉ ÉÉ ÉÉ'})
53
+ end
54
+
55
+ def self.test(tags, new_branch, old_brach='master', test_on_water=false, zlevels=Configuration.get_min_z..Configuration.get_max_z)
56
+ puts "processing #{VisualDiff.dict_to_pretty_tag_list(tags)}"
57
+ syn_tags = add_common_secondary_tags(tags)
58
+ ['node', 'closed_way', 'way'].each {|type|
59
+ CartoCSSHelper::VisualDiff.visualise_changes_synthethic_test(syn_tags, type, test_on_water, zlevels, old_brach, new_branch)
60
+ }
61
+ test_tag_on_real_data(tags, zlevels, old_brach, new_branch)
62
+ end
63
+
64
+ def self.probe(tags, new_branch, old_brach='master',test_on_water=false, zlevels=Configuration.get_min_z..Configuration.get_max_z)
65
+ syn_tags = add_common_secondary_tags(tags)
66
+ ['node', 'closed_way', 'way'].each {|type|
67
+ CartoCSSHelper::VisualDiff.visualise_changes_synthethic_test(syn_tags, type, test_on_water, zlevels, old_brach, new_branch)
68
+ }
69
+ end
70
+ end
data/license.txt ADDED
@@ -0,0 +1,9 @@
1
+ This software and associated documentation files (the "Software") is
2
+ released under the CC0 Public Domain Dedication, version 1.0, as
3
+ published by Creative Commons. To the extent possible under law, the
4
+ author(s) have dedicated all copyright and related and neighboring
5
+ rights to the Software to the public domain worldwide. The Software is
6
+ distributed WITHOUT ANY WARRANTY.
7
+ If you did not receive a copy of the CC0 Public Domain Dedication
8
+ along with the Software, see
9
+ <http://creativecommons.org/publicdomain/zero/1.0/>
data/readme.md ADDED
@@ -0,0 +1,25 @@
1
+ ##CartoCSS Helper
2
+
3
+ It is a tool making development of CartoCSS styles more efficient. Automates actions necessary to produce test images and validates style. Loading data using osm2pgsql, rendering with TileMill, obtaining test data from overpass turbo.
4
+
5
+ Proper testing of map rendering requires testing covering mutiple situations. Doing it manually means preparing test data and locating places with applicable real data, loading map data into database, then moving viewport of TileMill to check every data location across multiple zoom levels. It is painfully slow.
6
+
7
+ Fortunately it is possible to automate it almost entirely. With this tool testing new rendering change requires only specification of tag combination that should be tested and type of element.
8
+
9
+ It is work in progress, major problems that should be solved include:
10
+
11
+ * Lack of documentation
12
+ * Executing git checkout commands on map style git repository during normal script operation (https://github.com/matkoniecz/CartoCSSHelper/issues/9)
13
+ * Current rendering method is obnoxiously slow. (https://github.com/matkoniecz/CartoCSSHelper/issues/1)
14
+
15
+ ###Example
16
+
17
+ `require cartocss_helper`
18
+ `tags = {'landuse' => 'village_green', 'tourism' => 'attraction'}`
19
+ `CartoCSSHelper.test tags, 'master', 'v2.28.1'`
20
+
21
+ Runs quick test for specified tag combination rendering only this element, followed by locating multiple places across globe where such tags are used. For each test case images are produced both for current `master` branch and release `v2.28.1` across multiple zoom levels. Finally tool generates before/after comparisons for each case. Some of generated images were used in https://github.com/gravitystorm/openstreetmap-carto/issues/1371.
22
+
23
+ ###Automated stuff
24
+
25
+ [![Code Climate](https://codeclimate.com/github/mkoniecz/CartoCSSHelper/badges/gpa.svg)](https://codeclimate.com/github/mkoniecz/CartoCSSHelper)
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cartocss_helper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mateusz Konieczny
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-04-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rest-client
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.7.3
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.7.3
30
+ - !ruby/object:Gem::Dependency
31
+ name: sys-filesystem
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 1.1.4
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.1.4
46
+ - !ruby/object:Gem::Dependency
47
+ name: rmagick
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 2.13.4
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.13.4
62
+ description: Tool to make development of CartoCSS styles more efficient. Automates
63
+ actions necessary to produce test images and validates style. Loading data using
64
+ osm2pgsql, rendering with TileMill, obtaining test data from overpass turbo.
65
+ email:
66
+ - matkoniecz@gmail.com
67
+ executables: []
68
+ extensions: []
69
+ extra_rdoc_files: []
70
+ files:
71
+ - lib/cartocss_helper.rb
72
+ - lib/cartocss_helper/visualise_changes_image_generation.rb
73
+ - lib/cartocss_helper/tag_lister.rb
74
+ - lib/cartocss_helper/image_generator.rb
75
+ - lib/cartocss_helper/validator.rb
76
+ - lib/cartocss_helper/downloader.rb
77
+ - lib/cartocss_helper/git.rb
78
+ - lib/cartocss_helper/heuristic.rb
79
+ - lib/cartocss_helper/visualise_changes_diff_from_images.rb
80
+ - lib/cartocss_helper/configuration.rb
81
+ - lib/cartocss_helper/style_specific/style_specific.rb
82
+ - lib/cartocss_helper/style_specific/default_osm_style.rb
83
+ - lib/cartocss_helper/data_file_handling.rb
84
+ - license.txt
85
+ - readme.md
86
+ homepage: https://github.com/matkoniecz/CartoCSSHelper
87
+ licenses:
88
+ - CC0
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: 1.8.23
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 1.8.23
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: Tool to make development of CartoCSS styles more efficient.
111
+ test_files: []