Skip to content

Instantly share code, notes, and snippets.

@systemed
Last active May 22, 2021 17:55
Show Gist options
  • Save systemed/3a3394f7ea29c3cef68069cc2206b74f to your computer and use it in GitHub Desktop.
Save systemed/3a3394f7ea29c3cef68069cc2206b74f to your computer and use it in GitHub Desktop.
Profile Mapnik styles
# Mapnik style profiler
# ruby style_profiler.rb /usr/local/share/maps/style/stylesheet.xml coloured_relief,hillshade,relief,combined_relief 8.1948 46.8982 8.4502 47.0753
require '/usr/local/share/ruby/ffi-mapnik/lib/ffi-mapnik.rb'
require 'nokogiri'
require 'proj4'
require 'benchmark'
xml_fn = ARGV[0]
Mapnik.register_datasources("/usr/local/lib/mapnik/input")
Mapnik.register_fonts("/usr/local/share/maps/style/fonts")
doc = Nokogiri::XML(File.open(xml_fn))
print "Layers are "
puts doc.search("Layer").collect { |l| l['name'] }.join(', ')
if ARGV.length==1 then exit end
# Calculate bbox
proj = Proj4::Projection.new(["init=epsg:3857"])
pt1 = proj.forward( Proj4::Point.new(deg2rad(ARGV[2].to_f),deg2rad(ARGV[3].to_f)) )
pt2 = proj.forward( Proj4::Point.new(deg2rad(ARGV[4].to_f),deg2rad(ARGV[5].to_f)) )
outbox = Mapnik::Bounds.new(pt1.x,pt1.y,pt2.x,pt2.y)
ratio = (pt2.x-pt1.x) / (pt2.y-pt1.y)
dx = 2000
dy = (2000/ratio).to_i
puts "Dimensions are #{dx}x#{dy}"
# Run an untimed pass to pre-warm the database
map = Mapnik::Map.new(10,10)
print "Loading: "; puts Benchmark.measure { map.load(xml_fn) }
print "Resizing: "; puts Benchmark.measure { map.resize(dx,dy) }
print "Zooming: "; puts Benchmark.measure { map.zoom_to(outbox) }
print "Warming up: "; puts Benchmark.measure { map.to_file("output.png") }
puts `ls -la output.png`
# Now run five passes to get the standard timing
print "Running x5: "; puts Benchmark.measure { 5.times { map.to_file("output.png") } }
map.free
# Knock out the requested layers
puts "Knocking out layers"
without = ARGV[1].split(',')
doc.search("Layer").each do |layer|
if without.include?(layer['name']) then layer['status'] = 'off' end
end
File.write("/tmp/knocked_out.xml", doc.to_xml)
# Finally, run with the layers knocked out
map = Mapnik::Map.new(10,10)
map.load("/tmp/knocked_out.xml")
map.resize(dx,dy)
map.zoom_to(outbox)
print "Running x5: "; puts Benchmark.measure { 5.times { map.to_file("output2.png") } }
map.free
BEGIN {
def deg2rad(deg); deg*Proj4::DEG_TO_RAD end
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment