Created
October 9, 2011 19:11
-
-
Save miletbaker/1274032 to your computer and use it in GitHub Desktop.
Ruby script to scale and crop an image into overlay or map tiles for use with Google Maps API, Javascript for display custom map tiles below.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/ruby -w | |
require 'rubygems' | |
require 'rmagick' | |
require 'fileutils' | |
include Magick | |
ARGV.each do |file| | |
puts "Processing #{file}" | |
# Check file exists | |
unless File::exists?( file ) | |
puts "Image #{file} not found" | |
next | |
end | |
#Setup | |
img_name = File.basename(file, ".jpg") | |
# Load the source image and a little information | |
img = Magick::Image.read(file).first | |
w = img.columns | |
h = img.rows | |
puts "Image #{file} too small (<512x512)" and next unless (h > 512 || w > 512) | |
FileUtils.rm_rf(img_name) if File::directory?(img_name) | |
Dir.mkdir(img_name) | |
# Find the next largest multiple of 256 and the power of 2 | |
dim = w > h ? w : h | |
pow = -1 | |
loop do | |
i = 256*(2**pow+=1) | |
next if i < dim | |
dim = i | |
break | |
end | |
# Resize the source image up to the larger size | |
if (dim > w && dim > h) | |
puts "Resizing image to #{dim}px" | |
# Determine the optimal pixel radius for sharpening | |
img.change_geometry!("#{dim}x#{dim}") { |cols, rows, i| | |
i.resize!(cols, rows) | |
} | |
sharp = ( w/dim > h/dim ? dim/w : dim/h )/2 | |
img = img.sharpen(sharp) | |
end | |
# Build a new square image with a black background, and composite the source image on top of it. | |
master = Magick::Image.new(dim,dim){ self.background_color = "#E4E3DF" } | |
master.composite!(img, Magick::CenterGravity, Magick::OverCompositeOp) | |
img = nil | |
# Create slice layers | |
layer = 0 | |
loop do | |
# Google Maps only allows 19 layers (though I doubt we'll ever reach this point). | |
break if layer > 18 | |
width = 256*(2**layer) | |
break if width > dim | |
Dir.mkdir("#{img_name}/#{layer}", 0775) unless File::directory?("#{img_name}/#{layer}") | |
crop_master = master.clone | |
crop_master.resize!(width, width) | |
max_loop = (width / 256) - 1 | |
(0 .. max_loop).each do |x| | |
(0 .. max_loop).each do |y| | |
crop = crop_master.clone | |
crop.crop!( x*256, crop_master.rows - ((y + 1) * 256), 256, 256) | |
crop.write("#{img_name}/#{layer}/#{x}-#{y}.jpg") | |
crop = nil | |
end | |
end | |
layer+=1 | |
crop_master = nil | |
end | |
master = nil | |
end | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var map; | |
function loadMap(){ | |
var maptiler = new google.maps.ImageMapType({ | |
getTileUrl: function(coord, zoom) { | |
if (coord.x < 0 || (Math.pow(2,zoom)-coord.y-1) < 0 || (Math.pow(2,zoom)-coord.y-1) >= Math.pow(2,zoom) || coord.x >= Math.pow(2,zoom)) | |
return "/system/blank.jpg"; | |
else | |
return "/system/" + map_loc + "/" + zoom + "/" + coord.x + "-" + (Math.pow(2,zoom)-coord.y-1) + ".jpg"; | |
}, | |
tileSize: new google.maps.Size(256, 256), | |
maxZoom: map_max_zoom, | |
minZoom: map_min_zoom, | |
name:'Paris' | |
}); | |
map = new google.maps.Map(document.getElementById("map"), {streetViewControl: false, mapTypeControl: false}); | |
map.mapTypes.set('paris', maptiler); | |
map.setMapTypeId('paris'); | |
map.setCenter(new google.maps.LatLng(map_lat, map_lon)); | |
map.setZoom(map_init_zoom); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment