mapcache 0.1.0 → 0.1.1
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/VERSION +1 -1
- data/bin/mapcache +8 -1
- data/lib/download_manager.rb +9 -8
- data/lib/export_dialog.rb +6 -4
- data/lib/map_panel.rb +6 -6
- data/lib/matrix_manager.rb +13 -4
- data/lib/mgmaps_export.rb +12 -8
- data/lib/mswin/workarounds.rb +13 -0
- data/lib/tile_matrix.rb +73 -73
- metadata +13 -3
- data/TODO +0 -21
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.1
|
data/bin/mapcache
CHANGED
@@ -5,6 +5,13 @@ Dir[File.dirname(__FILE__) + '/../lib/*.rb'].each do |src|
|
|
5
5
|
require src
|
6
6
|
end
|
7
7
|
|
8
|
+
if RUBY_PLATFORM =~ /mswin/
|
9
|
+
require File.dirname(__FILE__) + '/../lib/mswin/workarounds.rb'
|
10
|
+
end
|
11
|
+
|
8
12
|
APP_VERSION = IO.read(File.dirname(__FILE__) + '/../VERSION')
|
9
13
|
|
10
|
-
Wx::App.run
|
14
|
+
Wx::App.run do
|
15
|
+
Wx::Timer.every(100) { Thread.pass } # allow other threads to proceed
|
16
|
+
MapFrame.new
|
17
|
+
end
|
data/lib/download_manager.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
-
require '
|
1
|
+
require 'httpclient'
|
2
2
|
require 'thread'
|
3
|
+
require 'monitor'
|
3
4
|
|
4
5
|
class DownloadManager
|
5
6
|
|
7
|
+
@http = HTTPClient.new
|
8
|
+
@lock = Monitor.new
|
6
9
|
@queue = Queue.new
|
7
10
|
@thread = Thread.new do
|
8
|
-
loop do
|
11
|
+
loop do
|
9
12
|
sleep if @queue.empty?
|
10
13
|
new_thread_from_queue
|
11
14
|
end
|
@@ -29,16 +32,14 @@ class DownloadManager
|
|
29
32
|
FileUtils.mkdir_p dir if !File.exist?(dir)
|
30
33
|
download(tile)
|
31
34
|
tile.load_image
|
32
|
-
@observer.tile_loaded(tile)
|
35
|
+
@lock.synchronize { @observer.tile_loaded(tile) }
|
33
36
|
end
|
34
37
|
end
|
35
38
|
|
36
39
|
def self.download(tile)
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
if res.code == "200"
|
41
|
-
File.open(tile.path, 'wb') {|f| f.write(res.body)}
|
40
|
+
res = @http.get(tile.url, {}, {"User-Agent" => "mapcache"})
|
41
|
+
if res.status == 200
|
42
|
+
File.open(tile.path, 'wb') {|f| f.write(res.content)}
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
data/lib/export_dialog.rb
CHANGED
@@ -7,24 +7,26 @@ class ExportDialog < Wx::Dialog
|
|
7
7
|
def hash_size
|
8
8
|
@hs_choice.string_selection.to_i
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def initialize(parent)
|
12
12
|
super(parent, :title => 'Export')
|
13
13
|
grid = Wx::FlexGridSizer.new(2, 2, 5, 5)
|
14
14
|
|
15
15
|
label = Wx::StaticText.new(self, :label => "Tiles per file")
|
16
16
|
@tpf_choice = Wx::Choice.new(self, :choices => %w(1 8 16 32 64 256))
|
17
|
+
@tpf_choice.selection = 0 # for Windows
|
17
18
|
grid.add(label, 0, Wx::ALIGN_CENTER_VERTICAL|Wx::ALL, 5)
|
18
19
|
grid.add(@tpf_choice, 0, Wx::GROW|Wx::ALL, 5)
|
19
|
-
|
20
|
+
|
20
21
|
label = Wx::StaticText.new(self, :label => "Hash size")
|
21
|
-
@hs_choice = Wx::Choice.new(self, :choices => %w(1 5 11 23 47 97))
|
22
|
+
@hs_choice = Wx::Choice.new(self, :choices => %w(1 5 11 23 47 97))
|
23
|
+
@hs_choice.selection = 0 # for Windows
|
22
24
|
grid.add(label, 0, Wx::ALIGN_CENTER_VERTICAL|Wx::ALL, 5)
|
23
25
|
grid.add(@hs_choice, 0, Wx::GROW|Wx::ALL, 5)
|
24
26
|
|
25
27
|
sizer = Wx::BoxSizer.new(Wx::VERTICAL)
|
26
28
|
sizer.add(grid, 0, Wx::ALL, 5)
|
27
|
-
|
29
|
+
|
28
30
|
button_sizer = create_button_sizer(Wx::OK|Wx::CANCEL)
|
29
31
|
sizer.add(button_sizer, 0, Wx::ALIGN_CENTER_VERTICAL|Wx::ALL, 5)
|
30
32
|
|
data/lib/map_panel.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class MapPanel < Wx::Panel
|
2
|
-
|
2
|
+
|
3
3
|
def initialize(parent, config)
|
4
4
|
super(parent, :style => Wx::NO_BORDER)
|
5
5
|
@pan = false
|
@@ -7,7 +7,7 @@ class MapPanel < Wx::Panel
|
|
7
7
|
@mgr = MatrixManager.new(self.size.width, self.size.height, config)
|
8
8
|
|
9
9
|
evt_paint {|event| draw_map}
|
10
|
-
|
10
|
+
|
11
11
|
evt_size {|event| resize_map(event.size.width, event.size.height) }
|
12
12
|
|
13
13
|
evt_char do |event|
|
@@ -20,7 +20,7 @@ class MapPanel < Wx::Panel
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
evt_left_down do |event|
|
23
|
+
evt_left_down do |event|
|
24
24
|
pan_start(event.x, event.y)
|
25
25
|
event.skip
|
26
26
|
end
|
@@ -48,13 +48,13 @@ class MapPanel < Wx::Panel
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def tile_loaded(tile)
|
51
|
-
|
51
|
+
paint {|dc| @mgr.draw_tile(dc, tile)}
|
52
52
|
end
|
53
53
|
|
54
54
|
private
|
55
55
|
|
56
56
|
def draw_map
|
57
|
-
|
57
|
+
paint_buffered {|dc| @mgr.draw(dc) }
|
58
58
|
end
|
59
59
|
|
60
60
|
def toggle_coverage
|
@@ -118,7 +118,7 @@ class MapPanel < Wx::Panel
|
|
118
118
|
self.cursor = Wx::HOURGLASS_CURSOR
|
119
119
|
yield
|
120
120
|
draw_map
|
121
|
-
self.cursor = Wx::NULL_CURSOR
|
121
|
+
self.cursor = Wx::NULL_CURSOR
|
122
122
|
end
|
123
123
|
|
124
124
|
def about_box
|
data/lib/matrix_manager.rb
CHANGED
@@ -29,7 +29,7 @@ class MatrixManager
|
|
29
29
|
def zoom_in(x, y)
|
30
30
|
if @zoom < MAX_ZOOM
|
31
31
|
@zoom += 1
|
32
|
-
@cov_zoom = zoom + 1 if cov_zoom - zoom < 1
|
32
|
+
@cov_zoom = zoom + 1 if cov_zoom - zoom < 1
|
33
33
|
@offset_x, @left_col = calc_start_and_offset_zoom_in(@left_col, x, @offset_x, @width)
|
34
34
|
@offset_y, @top_row = calc_start_and_offset_zoom_in(@top_row, y, @offset_y, @height)
|
35
35
|
create_matrix
|
@@ -52,6 +52,15 @@ class MatrixManager
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
+
def draw_tile(dc, the_tile)
|
56
|
+
@matrix.each do |col, row, tile|
|
57
|
+
if tile == the_tile
|
58
|
+
tile.draw(dc, TILE_WIDTH * (col - 1) + @offset_x, TILE_WIDTH * (row - 1) + @offset_y)
|
59
|
+
break
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
55
64
|
def toggle_coverage
|
56
65
|
@show_cov = !show_cov
|
57
66
|
recreate_coverage
|
@@ -140,8 +149,8 @@ class MatrixManager
|
|
140
149
|
def calc_start_and_offset_zoom_out(start_idx, cursor_pos, offset, viewport_size)
|
141
150
|
cursor_tile_idx = start_idx + (cursor_pos - offset).to_i / TILE_WIDTH + 1
|
142
151
|
middle_tile_idx = cursor_tile_idx / 2
|
143
|
-
from_edge = ( (cursor_pos - offset).to_i % TILE_WIDTH +
|
144
|
-
(cursor_tile_idx
|
152
|
+
from_edge = ( (cursor_pos - offset).to_i % TILE_WIDTH +
|
153
|
+
((cursor_tile_idx % 2 == 0) ? 0 : TILE_WIDTH) ) / 2
|
145
154
|
calc_offset_and_first_idx(middle_tile_idx, viewport_size, from_edge)
|
146
155
|
end
|
147
156
|
|
@@ -154,7 +163,7 @@ class MatrixManager
|
|
154
163
|
@matrix = TileMatrix.new
|
155
164
|
@matrix[0,0] = get_tile(@left_col, @top_row, @zoom)
|
156
165
|
resize(@width, @height)
|
157
|
-
end
|
166
|
+
end
|
158
167
|
|
159
168
|
def get_tiles(what, which)
|
160
169
|
size = (what == :row ? @matrix.width - 1 : @matrix.height - 1)
|
data/lib/mgmaps_export.rb
CHANGED
@@ -53,16 +53,16 @@ class MGMapsExport
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def self.export_each_file(files)
|
56
|
-
progress = Wx::ProgressDialog.new('Export', 'Processing files...',
|
56
|
+
progress = Wx::ProgressDialog.new('Export', 'Processing files...',
|
57
57
|
files.size, Wx::THE_APP.top_window,
|
58
|
-
Wx::PD_AUTO_HIDE | Wx::PD_APP_MODAL |
|
58
|
+
Wx::PD_AUTO_HIDE | Wx::PD_APP_MODAL |
|
59
59
|
Wx::PD_CAN_ABORT | Wx::PD_REMAINING_TIME)
|
60
60
|
files_done = 0
|
61
61
|
files.each do |file|
|
62
62
|
yield file
|
63
63
|
files_done += 1
|
64
64
|
if !progress.update(files_done)
|
65
|
-
if confirm('Cancel export?')
|
65
|
+
if confirm('Cancel export?')
|
66
66
|
progress.destroy
|
67
67
|
throw :cancelled
|
68
68
|
else
|
@@ -90,7 +90,7 @@ class MGMapsExport
|
|
90
90
|
dest = EXPORT_ROOT + zoomdir + subdir + src.basename
|
91
91
|
FileUtils.mkdir_p dest.dirname
|
92
92
|
FileUtils.cp file, dest
|
93
|
-
end
|
93
|
+
end
|
94
94
|
end
|
95
95
|
|
96
96
|
def self.export_as_mtpf(files, tiles_per_file)
|
@@ -108,12 +108,12 @@ class MGMapsExport
|
|
108
108
|
dest = EXPORT_ROOT + zoomdir + Pathname.new("#{dest_x}_#{dest_y}.mgm")
|
109
109
|
blank_mtpf_file(dest, tiles_per_file) if !File.exists?(dest)
|
110
110
|
add_tile_to_file(src, dest, rel_x, rel_y)
|
111
|
-
end
|
111
|
+
end
|
112
112
|
end
|
113
113
|
|
114
114
|
def self.tpf_xy(tpf)
|
115
115
|
log2 = (Math.log(tpf) / Math.log(2)).to_i
|
116
|
-
if log2
|
116
|
+
if log2 % 2 == 0
|
117
117
|
tpf_x = Math.sqrt(tpf).to_i
|
118
118
|
tpf_y = tpf_x
|
119
119
|
else
|
@@ -129,10 +129,10 @@ class MGMapsExport
|
|
129
129
|
end
|
130
130
|
|
131
131
|
def self.add_tile_to_file(src, dest, rel_x, rel_y)
|
132
|
-
File.open(dest, 'r+') do |file|
|
132
|
+
File.open(dest, 'r+b') do |file|
|
133
133
|
count = file.read(2).unpack('n').first + 1
|
134
134
|
file.seek(0, IO::SEEK_END)
|
135
|
-
file.write(
|
135
|
+
file.write(read_binary(src))
|
136
136
|
pos = file.pos
|
137
137
|
file.rewind
|
138
138
|
file.write [count].pack('n')
|
@@ -143,4 +143,8 @@ class MGMapsExport
|
|
143
143
|
end
|
144
144
|
end
|
145
145
|
|
146
|
+
def self.read_binary(filename)
|
147
|
+
open(filename, "rb") {|io| io.read }
|
148
|
+
end
|
149
|
+
|
146
150
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Wx
|
2
|
+
|
3
|
+
class DC
|
4
|
+
def draw_bitmap(bitmap, x, y, draw_transp)
|
5
|
+
m = MemoryDC.new
|
6
|
+
m.select_object(bitmap)
|
7
|
+
self.blit(x, y, bitmap.width, bitmap.height, m, 0, 0, self.logical_function, draw_transp)
|
8
|
+
m.select_object(Wx::NULL_BITMAP)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
data/lib/tile_matrix.rb
CHANGED
@@ -1,73 +1,73 @@
|
|
1
|
-
class TileMatrix
|
2
|
-
|
3
|
-
def initialize
|
4
|
-
@columns = []
|
5
|
-
end
|
6
|
-
|
7
|
-
def [](col, row)
|
8
|
-
@columns[col][row]
|
9
|
-
end
|
10
|
-
|
11
|
-
def[]=(col, row, value)
|
12
|
-
@columns[col] ||= []
|
13
|
-
@columns[col][row] = value
|
14
|
-
end
|
15
|
-
|
16
|
-
def width
|
17
|
-
@columns.size
|
18
|
-
end
|
19
|
-
|
20
|
-
def height
|
21
|
-
@columns[0].size
|
22
|
-
end
|
23
|
-
|
24
|
-
def each
|
25
|
-
@columns.each_with_index do |row, col_idx|
|
26
|
-
row.each_with_index do |value, row_idx|
|
27
|
-
yield col_idx, row_idx, value
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def shift_left(new_column)
|
33
|
-
@columns.shift
|
34
|
-
@columns.push(new_column)
|
35
|
-
end
|
36
|
-
|
37
|
-
def shift_right(new_column)
|
38
|
-
@columns.delete_at(@columns.length - 1)
|
39
|
-
@columns.unshift(new_column)
|
40
|
-
end
|
41
|
-
|
42
|
-
def shift_up(new_row)
|
43
|
-
@columns.each_with_index do |c, i|
|
44
|
-
c.shift
|
45
|
-
c.push(new_row[i])
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def shift_down(new_row)
|
50
|
-
@columns.each_with_index do |c, i|
|
51
|
-
c.delete_at(c.length - 1)
|
52
|
-
c.unshift(new_row[i])
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def reduce(width, height)
|
57
|
-
@columns.slice!(width..@columns.length - 1)
|
58
|
-
@columns.each do |c|
|
59
|
-
c.slice!(height..c.length - 1)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def add_column(new_column)
|
64
|
-
@columns << new_column
|
65
|
-
end
|
66
|
-
|
67
|
-
def add_row(new_row)
|
68
|
-
@columns.each_with_index do |c, i|
|
69
|
-
c << new_row[i]
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
end
|
1
|
+
class TileMatrix
|
2
|
+
|
3
|
+
def initialize
|
4
|
+
@columns = []
|
5
|
+
end
|
6
|
+
|
7
|
+
def [](col, row)
|
8
|
+
@columns[col][row]
|
9
|
+
end
|
10
|
+
|
11
|
+
def[]=(col, row, value)
|
12
|
+
@columns[col] ||= []
|
13
|
+
@columns[col][row] = value
|
14
|
+
end
|
15
|
+
|
16
|
+
def width
|
17
|
+
@columns.size
|
18
|
+
end
|
19
|
+
|
20
|
+
def height
|
21
|
+
@columns[0].size
|
22
|
+
end
|
23
|
+
|
24
|
+
def each
|
25
|
+
@columns.each_with_index do |row, col_idx|
|
26
|
+
row.each_with_index do |value, row_idx|
|
27
|
+
yield col_idx, row_idx, value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def shift_left(new_column)
|
33
|
+
@columns.shift
|
34
|
+
@columns.push(new_column)
|
35
|
+
end
|
36
|
+
|
37
|
+
def shift_right(new_column)
|
38
|
+
@columns.delete_at(@columns.length - 1)
|
39
|
+
@columns.unshift(new_column)
|
40
|
+
end
|
41
|
+
|
42
|
+
def shift_up(new_row)
|
43
|
+
@columns.each_with_index do |c, i|
|
44
|
+
c.shift
|
45
|
+
c.push(new_row[i])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def shift_down(new_row)
|
50
|
+
@columns.each_with_index do |c, i|
|
51
|
+
c.delete_at(c.length - 1)
|
52
|
+
c.unshift(new_row[i])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def reduce(width, height)
|
57
|
+
@columns.slice!(width..@columns.length - 1)
|
58
|
+
@columns.each do |c|
|
59
|
+
c.slice!(height..c.length - 1)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def add_column(new_column)
|
64
|
+
@columns << new_column
|
65
|
+
end
|
66
|
+
|
67
|
+
def add_row(new_row)
|
68
|
+
@columns.each_with_index do |c, i|
|
69
|
+
c << new_row[i]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mapcache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Valentine Bichkovsky
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
12
|
+
date: 2010-02-09 00:00:00 +02:00
|
13
13
|
default_executable: mapcache
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -22,6 +22,16 @@ dependencies:
|
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: 2.0.1
|
24
24
|
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: httpclient
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
25
35
|
- !ruby/object:Gem::Dependency
|
26
36
|
name: rspec
|
27
37
|
type: :development
|
@@ -43,7 +53,6 @@ extra_rdoc_files:
|
|
43
53
|
files:
|
44
54
|
- MIT-LICENCE
|
45
55
|
- README.rdoc
|
46
|
-
- TODO
|
47
56
|
- VERSION
|
48
57
|
- bin/mapcache
|
49
58
|
- lib/download_manager.rb
|
@@ -52,6 +61,7 @@ files:
|
|
52
61
|
- lib/map_panel.rb
|
53
62
|
- lib/matrix_manager.rb
|
54
63
|
- lib/mgmaps_export.rb
|
64
|
+
- lib/mswin/workarounds.rb
|
55
65
|
- lib/tile.rb
|
56
66
|
- lib/tile_matrix.rb
|
57
67
|
has_rdoc: true
|
data/TODO
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
- менять курсор в зависимости от действий пользователя, использовать "песочные часы" для длительных операций;
|
2
|
-
|
3
|
-
--------------------------
|
4
|
-
|
5
|
-
- возможность выделять области на карте и сохранять эти выделения. Область выделяется кистью в форме квадрата с привязкой к координатной сетке плиток. Размер квадрата можно менять (увеличивать и уменьшать в 2 раза, примерно как кисть в Фотошопе);
|
6
|
-
|
7
|
-
- экспорт для выделенной области;
|
8
|
-
|
9
|
-
- массовое скачивание плиток для выделенной области (возможно, с использованием прокси или с генерацией файла для другой программы скачивания);
|
10
|
-
|
11
|
-
- отображение информации - сколько плиток в очереди на скачивание, сколько выделено, сколько потребуется скачать для текущего выделения, прогресс во время скачивания, сколько всего плиток есть для конкретного зума и т.п.
|
12
|
-
|
13
|
-
--------------------------
|
14
|
-
|
15
|
-
- поддержка различных карт, не только простых GoogleMaps;
|
16
|
-
|
17
|
-
- хранение файлов плиток в одном большом файле (FUSE, tar, zip, ...);
|
18
|
-
|
19
|
-
- запоминане отсутствующих плиток (404), чтобы не пытаться их каждый раз тянуть из сети. Можно отображать на карте другим цветом;
|
20
|
-
|
21
|
-
|