Update July 31, 2008
The current version is now hosted and documented on github.
Getting Started
Install the latest version of the plugin:
./script/plugin install http://www.sourcepole.ch/svn/plugins/map_layers/trunk
Create a controller and a view
./script/generate controller Map index
Initialization of the map
Add the map viewer initialization to the index action in the controller:
@map = MapLayers::Map.new("map") do |map, page|
page << map.add_layer(MapLayers::GOOGLE)
page << map.zoom_to_max_extent()
end
Add this to the head of your view:
<%= map_layers_includes :google => "ABQIAAAA3HdfrnxFAPWyY-aiJUxmqRTJQa0g3IQ9GZqIMmInSLzwtGDKaBQ0KYLwBEKSM7F9gCevcsIf6WPuIQ" %>
Put a map in the body your view:
<div id="map" style="width: 512px; height: 256px;"></div>
<%= @map.to_html %>
Test your basic map with localhost:3000/map
Multiple layers
Add a second layer and some more controls in the controller action:
@map = MapLayers::Map.new("map") do |map, page|
page << map.add_layer(MapLayers::GOOGLE)
page << map.add_layer(MapLayers::YAHOO_HYBRID)
page << map.add_control(Control::LayerSwitcher.new)
page << map.add_control(Control::Permalink.new('permalink'))
page << map.add_control(Control::MousePosition.new)
page << map.zoom_to_max_extent()
end
Add the Yahoo Javascript library to the includes:
<%= map_layers_includes :google => "ABQIAAAA3HdfrnxFAPWyY-aiJUxmqRTJQa0g3IQ9GZqIMmInSLzwtGDKaBQ0KYLwBEKSM7F9gCevcsIf6WPuIQ", :yahoo => "euzuro-openlayers" %>
There are many more predefined layer types available: GOOGLE_SATELLITE, GOOGLE_HYBRID, GOOGLE_PHYSICAL, VE_ROAD, VE_AERIAL, VE_HYBRID, YAHOO, YAHOO_SATELLITE, YAHOO_HYBRID, MULTIMAP, OPENSTREETMAP, NASA_GLOBAL_MOSAIC, WORLDWIND, WORLDWIND_URBAN, WORLDWIND_BATHY
To include all Javascript APIs, insert your API keys in the following statement:
<%= map_layers_includes :google => "ABQIAAAA3HdfrnxFAPWyY-aiJUxmqRTJQa0g3IQ9GZqIMmInSLzwtGDKaBQ0KYLwBEKSM7F9gCevcsIf6WPuIQ", :multimap => "metacarta_04", :virtualearth => true, :yahoo => "euzuro-openlayers" %>
Updating the map
Now we want to add some simple markers in an Ajax action. First we add a link in the view:
<%= link_to_remote "Add marker", :url => { :action => "add_marker" } %>
This requires including the prototype library:
<%= javascript_include_tag 'prototype' %>
Then we include a marker layer in the map. Put this after the add_map_layer statements in the controller:
page.assign("markers", Layer::Markers.new('Markers'))
page << map.addLayer(:markers)
and then we implement the Ajax action:
def add_marker
render :update do |page|
@markers = JsVar.new('markers')
page << @markers.add_marker(OpenLayers::Marker.new(OpenLayers::LonLat.new(rand*50,rand*50)))
end
end
For accessing the marker layer in the Ajax action, we declare a Javascript variable with page.assign
and access the variable later with the JsVar
wrapper.
Publish your own data
Create a model:
./script/generate model --skip-timestamps --skip-fixture Place placeName:string countryCode:string postalCode:string lat:float lng:float
rake db:migrate
Import some places:
./script/runner "Geonames::Postalcode.search('Sidney').each { |pc| Place.create(pc.attributes.slice('placeName', 'postalCode', 'countryCode', 'lat', 'lng')) }"
Add a new controller with a map_layer:
class PlacesController < ApplicationController
map_layer :place, :text => :placeName
end
And add a layer to the map:
page << map.addLayer(Layer::GeoRSS.new("GeoRSS", "/places/georss"))
Other types of served layers:
page << map.add_layer(Layer::GML.new("Places KML", "/places/kml", {:format=> JsExpr.new("OpenLayers.Format.KML")}))
page << map.add_layer(Layer::WFS.new("Places WFS", "/places/wfs", {:typename => "places"}, {:featureClass => JsExpr.new("OpenLayers.Feature.WFS")}))
Spatial database support
Using a spatial database requires GeoRuby and the Spatial Adapter for Rails:
sudo gem install georuby
ruby script/plugin install svn://rubyforge.org/var/svn/georuby/SpatialAdapter/trunk/spatial_adapter
Install spatial functions in your DB (e.g. Postgis 8.1):
DB=map_layers_dev
createlang plpgsql $DB
psql -d $DB -q -f /usr/share/postgresql-8.1-postgis/lwpostgis.sql
Create a model:
./script/generate model --skip-timestamps --skip-fixture WeatherStation name:string geom:point
rake db:migrate
Import some station:
./script/runner "Geonames::Weather.weather(:north => 44.1, :south => -9.9, :east => -22.4, :west => 55.2).each { |st| WeatherStation.create(:name => st.stationName, :geom => Point.from_x_y(st.lng, st.lat)) }"
Add a new controller with a map_layer:
class WeatherStationsController < ApplicationController
map_layer :weater_stations, :geometry => :geom
end
And add a WFS layer to the map:
page << map.add_layer(Layer::WFS.new("Weather Stations", "/weather_stations/wfs", {:typename => "weather_stations"}, {:featureClass => JsExpr.new("OpenLayers.Feature.WFS")}))
License
The MapLayers plugin for Rails is released under the MIT license.
Support
For any questions, enhancement proposals, bug notifications or corrections visit rubyforge.org/projects/map-layers or send a mail to
pka at sourcepole.ch
Copyright (c) 2008 Pirmin Kalberer, Sourcepole AG