Loading geographic map data and drawing maps is pretty easy to do with two Ruby tools – ruby-shapelib (to load the map data) and RImageMagick (to create the drawings).
I didn’t see any tutorials or sample code, so I’m posting this sample as is – it will draw every shape part of every shape in a given shape file. Note this code does not perform any geographic projections.
require 'rubygems' require 'RMagick' require 'rvg/rvg' require 'shapelib' include ShapeLib include Magick USSTATES_SHAPEFILE="/Users/jkk/projects/shapelib/statesp020/statesp020.shp" OUTFILE="/Users/jkk/projects/shapelib/test.png" def drawshape shape, canvas #each shape can have multiple shape parts... #iterate over each shape part in this shape - 0.upto(shape.part_start.length-1) do |index| part_begin = shape.part_start[index] unless shape.part_start[index+1].nil? then part_end = shape.part_start[index+1]-1 else part_end=-1 end #NOTE we're assuming all the parts are polygons for now... #draw a polygon with the current subset of the xvals and yvals point arrays canvas.polygon(shape.xvals.slice(part_begin..part_end),shape.yvals.slice(part_begin..part_end)).styles(:fill =>"green",:stroke=>"black",:stroke_width=>0.01) end end #create a viewbox with lat/long coordinate space in the correct range def create_canvas rvg, shapefile width = shapefile.maxbound[0] -shapefile.minbound[0] height = shapefile.maxbound[1] -shapefile.minbound[1] #puts "viewport #{shapefile.minbound[0]},#{shapefile.minbound[1]} - width= #{width} height= #{height}" #invert the y axis so "up" is bigger and map the coordinate space to the shape's bounding box canvas = rvg.translate(0,rvg.height).scale(1,-1).viewbox(shapefile.minbound[0],shapefile.minbound[1],width,height).preserve_aspect_ratio('xMinYMin', 'meet') end shapefile = ShapeFile.open(USSTATES_SHAPEFILE,"rb") #create a new RVG object rvg = RVG.new(1000,100) rvg.background_fill='white' canvas = create_canvas rvg, shapefile shapefile.each { |shape| drawshape(shape,canvas) } shapefile.close rvg.draw.write(OUTFILE)
I’m using the US State boundary file from the national atlas website.
One thought on “Loading and drawing maps with Ruby”