mapknitter-exporter 0.0.2
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.
- checksums.yaml +7 -0
- data/lib/cartagen.rb +67 -0
- data/lib/mapknitter-exporter.rb +2 -0
- data/lib/mapknitterExporter.rb +378 -0
- metadata +46 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: f6396f65106739795c21f41cdbf09f5b83f304ba
|
|
4
|
+
data.tar.gz: 5e376ff010e5e8de275f189ede66ec06fcbadd1e
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: d68a28de27755f50174dd36584a2d3a4e6f20f2b79bbd2ac4e788a36157ea6ba7f1d2d0161fa7fad26ec8848af2dfe275e7340047de788e2dd214c2b80ce9e15
|
|
7
|
+
data.tar.gz: 0c5c5172b613dae3e347aa47b6644d6bfe0fe133ec839dccf97cab71fcbec97ab6bfe69fed0daebc6858d21c003671e0e4c0f72f05052a095ddb064f4409d01b
|
data/lib/cartagen.rb
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
class Cartagen
|
|
2
|
+
|
|
3
|
+
def self.chop_word(string)
|
|
4
|
+
word = string.split(' ')[0]
|
|
5
|
+
string.slice!(word+' ')
|
|
6
|
+
word
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.spherical_mercator_lon_to_x(lon,scale=10000)
|
|
10
|
+
(lon*scale)/180
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.spherical_mercator_x_to_lon(x,scale=10000)
|
|
14
|
+
(x/scale)*180
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.spherical_mercator_lat_to_y(lat,scale=10000)
|
|
18
|
+
#180/Math::PI * Math.log(Math.tan(Math::PI/4+lat*(Math::PI/180)/2)) * scale_factor
|
|
19
|
+
y = Math.log(Math.tan((90 + lat) * Math::PI / 360)) / (Math::PI / 180)
|
|
20
|
+
y * scale / 180
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.spherical_mercator_y_to_lat(y,scale=10000)
|
|
24
|
+
#180/Math::PI * (2 * Math.atan(Math.exp(y/scale_factor*Math::PI/180)) - Math::PI/2)
|
|
25
|
+
lat = (y / scale) * 180
|
|
26
|
+
180/Math::PI * (2 * Math.atan(Math.exp(lat * Math::PI / 180)) - Math::PI / 2)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# collects coastline ways into collected_way relations;
|
|
30
|
+
# see http://wiki.openstreetmap.org/wiki/Relations/Proposed/Collected_Ways
|
|
31
|
+
def self.collect_ways(features)
|
|
32
|
+
# collected_ways variable unused review this function
|
|
33
|
+
collected_ways = []
|
|
34
|
+
nodes = {}
|
|
35
|
+
features['osm']['node'].each do |node|
|
|
36
|
+
nodes[node['id']] = node
|
|
37
|
+
end
|
|
38
|
+
features['osm']['way'].each do |way|
|
|
39
|
+
if way['tag']
|
|
40
|
+
coastline = false
|
|
41
|
+
way['tag'].each do |tag|
|
|
42
|
+
if tag['k'] == 'natural' && tag['v'] == 'coastline'
|
|
43
|
+
coastline = true
|
|
44
|
+
break
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
if coastline
|
|
48
|
+
relation = {}
|
|
49
|
+
relation['way'] = []
|
|
50
|
+
relation['way'] << way
|
|
51
|
+
# are a way's nodes ordered? yes.
|
|
52
|
+
# check each way to see if it has a first or last node in common with 'way'
|
|
53
|
+
features['osm']['way'].each do |subway|
|
|
54
|
+
if subway['nd'].first['ref'] == nodes[way['nd'].first['ref']] || subway['nd'].first['ref'] == nodes[way['nd'].last['ref']] || subway['nd'].last['ref'] == nodes[way['nd'].first['ref']] || subway['nd'].last['ref'] == nodes[way['nd'].last['ref']]
|
|
55
|
+
# we have a match!
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
break
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
require 'mapknitter-exporter'
|
|
2
|
+
require 'cartagen'
|
|
3
|
+
require 'open3'
|
|
4
|
+
|
|
5
|
+
class MapKnitterExporter
|
|
6
|
+
|
|
7
|
+
def self.ulimit
|
|
8
|
+
# use ulimit to restrict to 7200 CPU seconds and 5gb virtual memory, and 5gB file storage:
|
|
9
|
+
#"ulimit -t 7200 && ulimit -v 5000000 && ulimit -f 5000000 && "
|
|
10
|
+
"ulimit -t 14400 && ulimit -v 5000000 && ulimit -f 10000000 && nice -n 19 "
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.get_working_directory(path)
|
|
14
|
+
"public/warps/#{path}-working/"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.warps_directory(path)
|
|
18
|
+
"public/warps/#{path}/"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.delete_temp_files(path)
|
|
22
|
+
system('rm -r ' + get_working_directory(path))
|
|
23
|
+
system('rm ' + warps_directory(path) + '*.png')
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
########################
|
|
27
|
+
## Run on each image:
|
|
28
|
+
|
|
29
|
+
# pixels per meter = pxperm
|
|
30
|
+
def self.generate_perspectival_distort(pxperm, id, nodes_array, image_file_name, img_url, height, width, root = "https://mapknitter.org")
|
|
31
|
+
require 'net/http'
|
|
32
|
+
|
|
33
|
+
# everything in -working/ can be deleted;
|
|
34
|
+
# this is just so we can use the files locally outside of s3
|
|
35
|
+
working_directory = get_working_directory(id)
|
|
36
|
+
Dir.mkdir(working_directory) unless (File.exists?(working_directory) && File.directory?(working_directory))
|
|
37
|
+
local_location = "#{working_directory}#{id}-#{image_file_name}"
|
|
38
|
+
|
|
39
|
+
directory = warps_directory(id)
|
|
40
|
+
Dir.mkdir(directory) unless (File.exists?(directory) && File.directory?(directory))
|
|
41
|
+
completed_local_location = directory+id.to_s+'.png'
|
|
42
|
+
|
|
43
|
+
# everything -masked.png can be deleted
|
|
44
|
+
masked_local_location = directory+id.to_s+'-masked.png'
|
|
45
|
+
# everything -mask.png can be deleted
|
|
46
|
+
mask_location = directory+id.to_s+'-mask.png'
|
|
47
|
+
#completed_local_location = directory+id.to_s+'.tif'
|
|
48
|
+
# know everything -unwarped can be deleted
|
|
49
|
+
geotiff_location = directory+id.to_s+'-geo-unwarped.tif'
|
|
50
|
+
# everything -geo WITH AN ID could be deleted, but there is a feature request to preserve these
|
|
51
|
+
warped_geotiff_location = directory+id.to_s+'-geo.tif'
|
|
52
|
+
|
|
53
|
+
northmost = nodes_array.first[:lat]
|
|
54
|
+
southmost = nodes_array.first[:lat]
|
|
55
|
+
westmost = nodes_array.first[:lon]
|
|
56
|
+
eastmost = nodes_array.first[:lon]
|
|
57
|
+
|
|
58
|
+
nodes_array.each do |node|
|
|
59
|
+
northmost = node[:lat] if node[:lat] > northmost
|
|
60
|
+
southmost = node[:lat] if node[:lat] < southmost
|
|
61
|
+
westmost = node[:lon] if node[:lon] < westmost
|
|
62
|
+
eastmost = node[:lon] if node[:lon] > eastmost
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# puts northmost.to_s+','+southmost.to_s+','+westmost.to_s+','+eastmost.to_s
|
|
66
|
+
|
|
67
|
+
scale = 20037508.34
|
|
68
|
+
y1 = pxperm*Cartagen.spherical_mercator_lat_to_y(northmost,scale)
|
|
69
|
+
x1 = pxperm*Cartagen.spherical_mercator_lon_to_x(westmost,scale)
|
|
70
|
+
y2 = pxperm*Cartagen.spherical_mercator_lat_to_y(southmost,scale)
|
|
71
|
+
x2 = pxperm*Cartagen.spherical_mercator_lon_to_x(eastmost,scale)
|
|
72
|
+
# puts x1.to_s+','+y1.to_s+','+x2.to_s+','+y2.to_s
|
|
73
|
+
|
|
74
|
+
# should determine if it's stored in s3 or locally:
|
|
75
|
+
if (img_url.slice(0,4) == 'http')
|
|
76
|
+
Net::HTTP.start('s3.amazonaws.com') { |http|
|
|
77
|
+
#Net::HTTP.start('localhost') { |http|
|
|
78
|
+
puts (img_url)
|
|
79
|
+
resp = http.get(img_url)
|
|
80
|
+
open(local_location, "wb") { |file|
|
|
81
|
+
file.write(resp.body)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else
|
|
85
|
+
require "fileutils"
|
|
86
|
+
FileUtils.cp(img_url, local_location)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
points = ""
|
|
90
|
+
maskpoints = ""
|
|
91
|
+
coordinates = ""
|
|
92
|
+
first = true
|
|
93
|
+
|
|
94
|
+
#EXIF orientation values:
|
|
95
|
+
#Value 0th Row 0th Column
|
|
96
|
+
#1 top left side
|
|
97
|
+
#2 top right side
|
|
98
|
+
#3 bottom right side
|
|
99
|
+
#4 bottom left side
|
|
100
|
+
#5 left side top
|
|
101
|
+
#6 right side top
|
|
102
|
+
#7 right side bottom
|
|
103
|
+
#8 left side bottom
|
|
104
|
+
|
|
105
|
+
rotation = (`identify -format %[exif:Orientation] #{local_location}`).to_i
|
|
106
|
+
#stdin, stdout, stderr = Open3.popen3('identify -format %[exif:Orientation] #{local_location}')
|
|
107
|
+
#rotation = stdout.readlines.first.to_s.to_i
|
|
108
|
+
#puts stderr.readlines
|
|
109
|
+
|
|
110
|
+
if rotation == 6
|
|
111
|
+
puts 'rotated CCW'
|
|
112
|
+
source_corners = source_corners = [[0,height],[0,0],[width,0],[width,height]]
|
|
113
|
+
elsif rotation == 8
|
|
114
|
+
puts 'rotated CW'
|
|
115
|
+
source_corners = [[width,0],[width,height],[0,height],[0,0]]
|
|
116
|
+
elsif rotation == 3
|
|
117
|
+
puts 'rotated 180 deg'
|
|
118
|
+
source_corners = [[width,height],[0,height],[0,0],[width,0]]
|
|
119
|
+
else
|
|
120
|
+
source_corners = [[0,0],[width,0],[width,height],[0,height]]
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
maxdimension = 0
|
|
124
|
+
|
|
125
|
+
nodes_array.each do |node|
|
|
126
|
+
corner = source_corners.shift
|
|
127
|
+
nx1 = corner[0]
|
|
128
|
+
ny1 = corner[1]
|
|
129
|
+
nx2 = -x1+(pxperm*Cartagen.spherical_mercator_lon_to_x(node[:lon],scale))
|
|
130
|
+
ny2 = y1-(pxperm*Cartagen.spherical_mercator_lat_to_y(node[:lat],scale))
|
|
131
|
+
|
|
132
|
+
points = points + ' ' unless first
|
|
133
|
+
maskpoints = maskpoints + ' ' unless first
|
|
134
|
+
points = points + nx1.to_s + ',' + ny1.to_s + ' ' + nx2.to_i.to_s + ',' + ny2.to_i.to_s
|
|
135
|
+
maskpoints = maskpoints + nx2.to_i.to_s + ',' + ny2.to_i.to_s
|
|
136
|
+
first = false
|
|
137
|
+
# we need to find an origin; find northwestern-most point
|
|
138
|
+
coordinates = coordinates+' -gcp '+nx2.to_s+', '+ny2.to_s+', '+node[:lon].to_s + ', ' + node[:lat].to_s
|
|
139
|
+
|
|
140
|
+
# identify largest dimension to set canvas size for ImageMagick:
|
|
141
|
+
maxdimension = nx1.to_i if maxdimension < nx1.to_i
|
|
142
|
+
maxdimension = ny1.to_i if maxdimension < ny1.to_i
|
|
143
|
+
maxdimension = nx2.to_i if maxdimension < nx2.to_i
|
|
144
|
+
maxdimension = ny2.to_i if maxdimension < ny2.to_i
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# close mask polygon:
|
|
148
|
+
maskpoints = maskpoints + ' '
|
|
149
|
+
nx2 = -x1+(pxperm*Cartagen.spherical_mercator_lon_to_x(nodes_array.first[:lon], scale))
|
|
150
|
+
ny2 = y1-(pxperm*Cartagen.spherical_mercator_lat_to_y(nodes_array.first[:lat], scale))
|
|
151
|
+
maskpoints = maskpoints + nx2.to_i.to_s + ',' + ny2.to_i.to_s
|
|
152
|
+
|
|
153
|
+
height = (y1-y2).to_i.to_s
|
|
154
|
+
width = (-x1+x2).to_i.to_s
|
|
155
|
+
|
|
156
|
+
# http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=11319
|
|
157
|
+
# http://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=8764
|
|
158
|
+
# read about equalization
|
|
159
|
+
# -equalize
|
|
160
|
+
# -contrast-stretch 0
|
|
161
|
+
|
|
162
|
+
imageMagick = "convert "
|
|
163
|
+
imageMagick += "-contrast-stretch 0 "
|
|
164
|
+
imageMagick += local_location+" "
|
|
165
|
+
imageMagick += "-crop "+maxdimension.to_i.to_s+"x"+maxdimension.to_i.to_s+"+0+0! "
|
|
166
|
+
imageMagick += "-flatten "
|
|
167
|
+
imageMagick += "-distort Perspective '"+points+"' "
|
|
168
|
+
imageMagick += "-flatten "
|
|
169
|
+
if width > height
|
|
170
|
+
imageMagick += "-crop "+width+"x"+width+"+0+0\! "
|
|
171
|
+
else
|
|
172
|
+
imageMagick += "-crop "+height+"x"+height+"+0+0\! "
|
|
173
|
+
end
|
|
174
|
+
imageMagick += "+repage "
|
|
175
|
+
imageMagick += completed_local_location
|
|
176
|
+
puts imageMagick
|
|
177
|
+
system(self.ulimit+imageMagick)
|
|
178
|
+
|
|
179
|
+
# create a mask (later we can blur edges here)
|
|
180
|
+
imageMagick2 = 'convert +antialias '
|
|
181
|
+
if width > height
|
|
182
|
+
imageMagick2 += "-size "+width+"x"+width+" "
|
|
183
|
+
else
|
|
184
|
+
imageMagick2 += "-size "+height+"x"+height+" "
|
|
185
|
+
end
|
|
186
|
+
# attempt at blurred edges in masking, but I've given up, as gdal_merge doesn't seem to respect variable-opacity alpha channels
|
|
187
|
+
imageMagick2 += ' xc:none -draw "fill black stroke red stroke-width 30 polyline '
|
|
188
|
+
imageMagick2 += maskpoints + '" '
|
|
189
|
+
imageMagick2 += ' -alpha set -channel A -transparent red -blur 0x8 -channel R -evaluate set 0 +channel '+mask_location
|
|
190
|
+
#imageMagick2 += ' xc:none -draw "fill black stroke none polyline '
|
|
191
|
+
#imageMagick2 += maskpoints + '" '
|
|
192
|
+
#imageMagick2 += ' '+mask_location
|
|
193
|
+
puts imageMagick2
|
|
194
|
+
system(self.ulimit+imageMagick2)
|
|
195
|
+
|
|
196
|
+
imageMagick3 = 'composite '+mask_location+' '+completed_local_location+' -compose DstIn -alpha Set '+masked_local_location
|
|
197
|
+
puts imageMagick3
|
|
198
|
+
system(self.ulimit+imageMagick3)
|
|
199
|
+
|
|
200
|
+
gdal_translate = "gdal_translate -of GTiff -a_srs EPSG:4326 "+coordinates+' -co "TILED=NO" '+masked_local_location+' '+geotiff_location
|
|
201
|
+
puts gdal_translate
|
|
202
|
+
system(self.ulimit+gdal_translate)
|
|
203
|
+
|
|
204
|
+
#gdalwarp = 'gdalwarp -srcnodata "255" -dstnodata 0 -cblend 30 -of GTiff -t_srs EPSG:4326 '+geotiff_location+' '+warped_geotiff_location
|
|
205
|
+
gdalwarp = 'gdalwarp -of GTiff -t_srs EPSG:4326 '+geotiff_location+' '+warped_geotiff_location
|
|
206
|
+
puts gdalwarp
|
|
207
|
+
system(self.ulimit+gdalwarp)
|
|
208
|
+
|
|
209
|
+
# deletions could happen here; do it in distinct method so we can run it independently
|
|
210
|
+
delete_temp_files(id)
|
|
211
|
+
|
|
212
|
+
[x1,y1]
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
########################
|
|
216
|
+
## Run on maps:
|
|
217
|
+
|
|
218
|
+
# distort all warpables, returns upper left corner coords in x,y
|
|
219
|
+
def self.distort_warpables(scale, images, export, id)
|
|
220
|
+
|
|
221
|
+
puts '> generating geotiffs of each warpable in GDAL'
|
|
222
|
+
lowest_x = 0
|
|
223
|
+
lowest_y = 0
|
|
224
|
+
all_coords = []
|
|
225
|
+
current = 0
|
|
226
|
+
images.each do |image|
|
|
227
|
+
current += 1
|
|
228
|
+
|
|
229
|
+
## TODO: refactor to generate static status file:
|
|
230
|
+
export.status = 'warping '+current.to_s+' of '+images.length.to_s
|
|
231
|
+
puts 'warping '+current.to_s+' of '+images.length.to_s
|
|
232
|
+
export.save
|
|
233
|
+
##
|
|
234
|
+
|
|
235
|
+
img_coords = generate_perspectival_distort(
|
|
236
|
+
scale,
|
|
237
|
+
id,
|
|
238
|
+
image[:nodes_array],
|
|
239
|
+
image[:filename],
|
|
240
|
+
image[:url],
|
|
241
|
+
image[:height],
|
|
242
|
+
image[:width]
|
|
243
|
+
)
|
|
244
|
+
puts '- '+img_coords.to_s
|
|
245
|
+
all_coords << img_coords
|
|
246
|
+
lowest_x = img_coords.first if (img_coords.first < lowest_x || lowest_x == 0)
|
|
247
|
+
lowest_y = img_coords.last if (img_coords.last < lowest_y || lowest_y == 0)
|
|
248
|
+
end
|
|
249
|
+
[lowest_x, lowest_y, all_coords]
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# generate a tiff from all warpable images in this set
|
|
253
|
+
def self.generate_composite_tiff(coords, origin, placed_warpables, id, ordered)
|
|
254
|
+
directory = "public/warps/#{id}/"
|
|
255
|
+
composite_location = directory + id.to_s + '-geo.tif'
|
|
256
|
+
geotiffs = ''
|
|
257
|
+
minlat = nil
|
|
258
|
+
minlon = nil
|
|
259
|
+
maxlat = nil
|
|
260
|
+
maxlon = nil
|
|
261
|
+
placed_warpables.each do |warpable|
|
|
262
|
+
warpable[:nodes_array].each do |n|
|
|
263
|
+
minlat = n[:lat] if minlat == nil || n[:lat] < minlat
|
|
264
|
+
minlon = n[:lon] if minlon == nil || n[:lon] < minlon
|
|
265
|
+
maxlat = n[:lat] if maxlat == nil || n[:lat] > maxlat
|
|
266
|
+
maxlon = n[:lon] if maxlon == nil || n[:lon] > maxlon
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
first = true
|
|
270
|
+
if ordered != true
|
|
271
|
+
# sort by area; this would be overridden by a provided order
|
|
272
|
+
warpables = placed_warpables.sort{|a,b|b.poly_area <=> a.poly_area}
|
|
273
|
+
end
|
|
274
|
+
warpables.each do |warpable|
|
|
275
|
+
wid = warpable[:id].to_s
|
|
276
|
+
geotiffs += ' '+directory+wid+'-geo.tif'
|
|
277
|
+
if first
|
|
278
|
+
gdalwarp = "gdalwarp -s_srs EPSG:3857 -te #{minlon} #{minlat} #{maxlon} #{maxlat} #{directory}#{wid}-geo.tif #{directory}#{id}-geo.tif"
|
|
279
|
+
first = false
|
|
280
|
+
else
|
|
281
|
+
gdalwarp = "gdalwarp #{directory}#{wid}-geo.tif #{directory}#{id}-geo.tif"
|
|
282
|
+
end
|
|
283
|
+
puts gdalwarp
|
|
284
|
+
system(self.ulimit+gdalwarp)
|
|
285
|
+
end
|
|
286
|
+
composite_location
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# generates a tileset at root/public/tms/<id>/
|
|
290
|
+
# root is something like https://mapknitter.org
|
|
291
|
+
def self.generate_tiles(key, id, root)
|
|
292
|
+
key = "AIzaSyAOLUQngEmJv0_zcG1xkGq-CXIPpLQY8iQ" if key == "" # ugh, let's clean this up!
|
|
293
|
+
key = key || "AIzaSyAOLUQngEmJv0_zcG1xkGq-CXIPpLQY8iQ"
|
|
294
|
+
gdal2tiles = "gdal2tiles.py -k --s_srs EPSG:3857 -t #{id} -g #{key} public/warps/#{id}/#{id}-geo.tif public/tms/#{id}/"
|
|
295
|
+
puts gdal2tiles
|
|
296
|
+
system(self.ulimit+gdal2tiles)
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# zips up tiles at public/tms/<id>.zip;
|
|
300
|
+
def self.zip_tiles(id)
|
|
301
|
+
rmzip = "cd public/tms/ && rm #{id}.zip && cd ../../"
|
|
302
|
+
system(rmzip)
|
|
303
|
+
zip = "cd public/tms/ && #{self.ulimit} zip -rq #{id}.zip #{id}/ && cd ../../"
|
|
304
|
+
system(zip)
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# generates a tileset at public/tms/<id>/
|
|
308
|
+
def self.generate_jpg(id, root)
|
|
309
|
+
imageMagick = "convert -background white -flatten public/warps/#{id}/#{id}-geo.tif #{root}/public/warps/#{id}/#{id}.jpg"
|
|
310
|
+
system(self.ulimit+imageMagick)
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
# runs the above map functions while maintaining a record of state in an Export model;
|
|
314
|
+
# we'll be replacing the export model state with a flat status file
|
|
315
|
+
def self.run_export(user_id, resolution, export, id, root, placed_warpables, key)
|
|
316
|
+
export.user_id = user_id if user_id
|
|
317
|
+
export.status = 'starting'
|
|
318
|
+
export.tms = false
|
|
319
|
+
export.geotiff = false
|
|
320
|
+
export.zip = false
|
|
321
|
+
export.jpg = false
|
|
322
|
+
export.save
|
|
323
|
+
|
|
324
|
+
directory = "#{root}/public/warps/#{id}/"
|
|
325
|
+
stdin, stdout, stderr = Open3.popen3('rm -r '+directory.to_s)
|
|
326
|
+
puts stdout.readlines
|
|
327
|
+
puts stderr.readlines
|
|
328
|
+
stdin, stdout, stderr = Open3.popen3("rm -r #{root}/public/tms/#{id}")
|
|
329
|
+
puts stdout.readlines
|
|
330
|
+
puts stderr.readlines
|
|
331
|
+
|
|
332
|
+
puts '> averaging scales; resolution: ' + resolution.to_s
|
|
333
|
+
pxperm = 100/(resolution).to_f # pixels per meter
|
|
334
|
+
puts '> scale: ' + pxperm.to_s + 'pxperm'
|
|
335
|
+
|
|
336
|
+
puts '> distorting warpables'
|
|
337
|
+
|
|
338
|
+
origin = self.distort_warpables(pxperm, placed_warpables, export, id)
|
|
339
|
+
warpable_coords = origin.pop
|
|
340
|
+
|
|
341
|
+
export.status = 'compositing'
|
|
342
|
+
export.save
|
|
343
|
+
|
|
344
|
+
puts '> generating composite tiff'
|
|
345
|
+
composite_location = self.generate_composite_tiff(warpable_coords,origin,placed_warpables,id,false) # no ordering yet
|
|
346
|
+
|
|
347
|
+
info = (`identify -quiet -format '%b,%w,%h' #{composite_location}`).split(',')
|
|
348
|
+
puts info
|
|
349
|
+
|
|
350
|
+
if info[0] != ''
|
|
351
|
+
export.geotiff = true
|
|
352
|
+
export.size = info[0]
|
|
353
|
+
export.width = info[1]
|
|
354
|
+
export.height = info[2]
|
|
355
|
+
export.cm_per_pixel = 100.0000/pxperm
|
|
356
|
+
export.status = 'tiling'
|
|
357
|
+
export.save
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
puts '> generating tiles'
|
|
361
|
+
export.tms = true if self.generate_tiles(key, id, root)
|
|
362
|
+
export.status = 'zipping tiles'
|
|
363
|
+
export.save
|
|
364
|
+
|
|
365
|
+
puts '> zipping tiles'
|
|
366
|
+
export.zip = true if self.zip_tiles(id)
|
|
367
|
+
export.status = 'creating jpg'
|
|
368
|
+
export.save
|
|
369
|
+
|
|
370
|
+
puts '> generating jpg'
|
|
371
|
+
export.jpg = true if self.generate_jpg(id, root)
|
|
372
|
+
export.status = 'complete'
|
|
373
|
+
export.save
|
|
374
|
+
|
|
375
|
+
export.status
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: mapknitter-exporter
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Jeffrey Warren
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2019-04-14 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: The GDAL/ImageMagick-based exporter system from MapKnitter
|
|
14
|
+
email: jeff@unterbahn.com
|
|
15
|
+
executables: []
|
|
16
|
+
extensions: []
|
|
17
|
+
extra_rdoc_files: []
|
|
18
|
+
files:
|
|
19
|
+
- lib/cartagen.rb
|
|
20
|
+
- lib/mapknitter-exporter.rb
|
|
21
|
+
- lib/mapknitterExporter.rb
|
|
22
|
+
homepage: http://rubygems.org/gems/mapknitter-exporter
|
|
23
|
+
licenses:
|
|
24
|
+
- GPLv3
|
|
25
|
+
metadata: {}
|
|
26
|
+
post_install_message:
|
|
27
|
+
rdoc_options: []
|
|
28
|
+
require_paths:
|
|
29
|
+
- lib
|
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
31
|
+
requirements:
|
|
32
|
+
- - ">="
|
|
33
|
+
- !ruby/object:Gem::Version
|
|
34
|
+
version: '0'
|
|
35
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0'
|
|
40
|
+
requirements: []
|
|
41
|
+
rubyforge_project:
|
|
42
|
+
rubygems_version: 2.6.14.4
|
|
43
|
+
signing_key:
|
|
44
|
+
specification_version: 4
|
|
45
|
+
summary: The GDAL/ImageMagick-based exporter system from MapKnitter
|
|
46
|
+
test_files: []
|