Class: PolyMaps::Renderer

Inherits:
Object
  • Object
show all
Defined in:
lib/poly_maps.rb

Instance Method Summary collapse

Constructor Details

#initialize(country_code, regions, relationship_name, onclick_handler, polygon_limit = nil) ⇒ Renderer

Returns a new instance of Renderer.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/poly_maps.rb', line 26

def initialize(country_code, regions, relationship_name, onclick_handler, polygon_limit = nil)
   unless (country = YAML.load_file(File.join(File.dirname(__FILE__), '/country_centers_and_zooms.yml'))[country_code])
    puts "Polymaps Unsupported country code: #{country_code}"
    return nil
   end
   
  output = ""
  country_zoom = country['google_zoom']
  @legend_items = []
  
  # Create a country polygon to check that drawn points are not incorrectly geocoded
  output += "var country_points = #{country['borders_polygon']};\n"
   output += "var pts = [];\n"
   output += "for (var i = 0; i < country_points.length; i++) {\n"
   output += "  pts[i] = new GLatLng(country_points[i][0],country_points[i][1]);\n"
   output += "}\n"
   output += "var country_polygon = new GPolygon(pts,\"#000000\",1,1,\"#{country['fill_color']}\",0.5,{clickable:false});\n"
  output += "var country_zoom = #{country_zoom};\n"
   output += "map.setCenter(new GLatLng(#{country['center_latitude']}, #{country['center_longitude']}), country_zoom);\n"
  if country_zoom < 4
    output += "var min_area_sqm = 2000000000;\n"
    output += "var circle_radius = 110000;\n"
  elsif country_zoom < 6
    output += "var min_area_sqm = 1500000000;\n"
    output += "var circle_radius = 50000;\n"
  elsif country_zoom < 9
    output += "var min_area_sqm = 250000000;\n"
    output += "var circle_radius = 7000;\n"
  else
    output += "var min_area_sqm = 1500000;\n"
    output += "var circle_radius = 3000;\n"
  end
  
  # Create an array with point locations for all regions
  output += "var regions = ["
  region_js = []
  regions.each_with_index do |region, index|
    points = eval("region.#{relationship_name}")
    next if points.empty?
    @legend_items << LegendItem.new(nil, region)
    next if polygon_limit and index >= polygon_limit
    points_js = []
    points.each do |point|
      points_js << "[#{point.lat},#{point.lng}]"
    end
    onclick = "null"
    unless onclick_handler.nil? or onclick_handler == ""
      js = eval("\"#{onclick_handler}\"")
      onclick = "function() { #{js}; }"
    end
    region_js[region_js.length] =  "[#{onclick},[#{points_js.join(',')}]]"
  end    
  output += region_js.join(",")
  output += "];\n"

  # Save the colors used
  hex_colors = ['#3399cc','#669900','#9966cc','#ff3300','#ff00ff','#ff9900','#cc99cc','#ffff00']
  color_index = 0
  @legend_items.each_with_index do |legend_item, index|
    legend_item.color = (polygon_limit and index >= polygon_limit)? "" : hex_colors[color_index]
    color_index = (color_index == hex_colors.length-1)? 0 : color_index + 1
  end
  hex_colors_js = hex_colors.collect{|c| "'#{c}'"}.join(',')
  
  # Use JavaScript to loop through each region and add a polygon to the map
   output += "var hex_colors = [#{hex_colors_js}];\n"
   output += "var color_index = 0;\n"
   output += "for(var i = 0; i < regions.length; i++) {\n"
   output += "  region = regions[i];\n"
   output += "  hex_color = hex_colors[color_index]\n"
   output += "  color_index = (color_index == hex_colors.length-1)? 0 : color_index + 1;\n"
   output += "  var polygon = null;\n"
   output += "  var region_bounds = new GLatLngBounds();\n"
   output += "  var points_js = region[1];\n"
   output += "  var pts = [];\n"
   output += "  for (var j = 0; j < points_js.length; j++) {\n"
   output += "    lat_lng = new GLatLng(points_js[j][0],points_js[j][1]);\n"
   output += "    if (country_polygon.Contains(lat_lng)) {\n"
   output += "      pts[pts.length] = lat_lng;\n"
   output += "      region_bounds.extend(lat_lng);\n"
   output += "    }\n"
   output += "  }\n"
   output += "  var region_polygon = new GPolygon(pts,hex_color,1,1,hex_color,0.5);\n"
   output += "  if (region_polygon.getArea() < min_area_sqm) {\n"
   output += "     polygon = GPolygon.Circle(region_bounds.getCenter(), circle_radius, hex_color, 1, 1, hex_color, 0.5);\n"
   output += "   } else {\n"
   output += "    polygon = calculateConvexHull(map, pts, hex_color);\n"
   output += "   }\n"
   output += "  GEvent.addListener(polygon, 'mouseover', mouseover_cursor);\n"
   output += "   if (region[0] != null) {\n"
   output += "    GEvent.addListener(polygon, 'click', region[0]);\n"
   output += "   }\n"
   output += "  map.addOverlay(polygon);\n"
   output += "}\n"
  
  @map_js = output
end

Instance Method Details

#jsObject



13
14
15
# File 'lib/poly_maps.rb', line 13

def js
  @map_js
end

#legend_itemsObject



17
18
19
# File 'lib/poly_maps.rb', line 17

def legend_items
  @legend_items
end

#library_jsObject



21
22
23
24
# File 'lib/poly_maps.rb', line 21

def library_js
  # Write the neccessary JavaScript library stuff for circles etc.
  IO.read(File.join(File.dirname(__FILE__), '/poly_maps.js'))
end