--- /dev/null
+class BrowseController < ApplicationController
+ before_filter :authorize_web
+ layout 'site'
+
+ def start
+ end
+
+ def index
+ @nodes = Node.find(:all, :order => "timestamp DESC", :limit=> 20)
+ end
+
+ def relation
+ begin
+ @relation = Relation.find(params[:id])
+
+ @name = @relation.tags['name'].to_s
+ if @name.length == 0:
+ @name = "#" + @relation.id.to_s
+ end
+
+ @title = 'Relation | ' + (@name)
+ @next = Relation.find(:first, :order => "id ASC", :conditions => [ "visible = true AND id > :id", { :id => @relation.id }] )
+ @prev = Relation.find(:first, :order => "id DESC", :conditions => [ "visible = true AND id < :id", { :id => @relation.id }] )
+ rescue ActiveRecord::RecordNotFound
+ render :nothing => true, :status => :not_found
+ end
+ end
+
+ def relation_history
+ begin
+ @relation = Relation.find(params[:id])
+
+ @name = @relation.tags['name'].to_s
+ if @name.length == 0:
+ @name = "#" + @relation.id.to_s
+ end
+
+ @title = 'Relation History | ' + (@name)
+ rescue ActiveRecord::RecordNotFound
+ render :nothing => true, :status => :not_found
+ end
+ end
+
+ def way
+ begin
+ @way = Way.find(params[:id])
+
+ @name = @way.tags['name'].to_s
+ if @name.length == 0:
+ @name = "#" + @way.id.to_s
+ end
+
+ @title = 'Way | ' + (@name)
+ @next = Way.find(:first, :order => "id ASC", :conditions => [ "visible = true AND id > :id", { :id => @way.id }] )
+ @prev = Way.find(:first, :order => "id DESC", :conditions => [ "visible = true AND id < :id", { :id => @way.id }] )
+ rescue ActiveRecord::RecordNotFound
+ render :nothing => true, :status => :not_found
+ end
+ end
+
+ def way_history
+ begin
+ @way = Way.find(params[:id])
+
+ @name = @way.tags['name'].to_s
+ if @name.length == 0:
+ @name = "#" + @way.id.to_s
+ end
+
+ @title = 'Way History | ' + (@name)
+ rescue ActiveRecord::RecordNotFound
+ render :nothing => true, :status => :not_found
+ end
+ end
+
+ def node
+ begin
+ @node = Node.find(params[:id])
+
+ @name = @node.tags_as_hash['name'].to_s
+ if @name.length == 0:
+ @name = "#" + @node.id.to_s
+ end
+
+ @title = 'Node | ' + (@name)
+ @next = Node.find(:first, :order => "id ASC", :conditions => [ "visible = true AND id > :id", { :id => @node.id }] )
+ @prev = Node.find(:first, :order => "id DESC", :conditions => [ "visible = true AND id < :id", { :id => @node.id }] )
+ rescue ActiveRecord::RecordNotFound
+ render :nothing => true, :status => :not_found
+ end
+ end
+
+ def node_history
+ begin
+ @node = Node.find(params[:id])
+
+ @name = @node.tags_as_hash['name'].to_s
+ if @name.length == 0:
+ @name = "#" + @node.id.to_s
+ end
+
+ @title = 'Node History | ' + (@name)
+ rescue ActiveRecord::RecordNotFound
+ render :nothing => true, :status => :not_found
+ end
+ end
+end
--- /dev/null
+module BrowseHelper
+end
el1['timestamp'] = self.timestamp.xmlschema
return el1
end
+
+ def tags_as_hash
+ hash = {}
+ Tags.split(self.tags) do |k,v|
+ hash[k] = v
+ end
+ hash
+ end
end
--- /dev/null
+<% if obj.visible %>
+<%= render :partial => 'map', :locals => { :type => type, :id => obj.id } %>
+<% else %>
+Deleted
+<% end %>
+<ul>
+<% if obj.visible %>
+<li><%= link_to h("API"), :controller => type, :action => "read", :id => obj.id %></li>
+<% end %>
+<li><%= link_to h("History"), :controller => "old_" + type, :action => "history", :id => obj.id %>
+ (<%= link_to h("HTML"), :action => type+"_history", :id => obj.id %>)</li>
+</ul>
+<%= render :partial => 'common_editedby', :locals => { :obj => obj } %>
--- /dev/null
+Last edited: <%= h(obj.timestamp) %>
+<% if obj.user.data_public %>
+by <%= link_to h(obj.user.display_name), :controller => 'user', :action => 'view' , :display_name => obj.user.display_name %>
+<% end %>
--- /dev/null
+<%= javascript_include_tag '/openlayers/OpenLayers.js' %>
+<%= javascript_include_tag '/openlayers/OpenStreetMap.js' %>
+<%= javascript_include_tag 'map.js' %>
+<div style="float:right">
+<div id="small_map" style="width:250px; height: 300px; border: solid 1px black">
+</div>
+<script type="text/javascript">
+ function init() {
+ var obj_type = '<%= type %>';
+ var obj_id = <%= id %>;
+ var url = "/api/<%= "#{API_VERSION}" %>/<%= type %>/<%= id %>";
+ if (obj_type != "node") {
+ url += "/full";
+ }
+ var map = createMap('small_map', {controls: [new OpenLayers.Control.Navigation()]});
+ var osm_layer = new OpenLayers.Layer.GML("OSM", url, {format: OpenLayers.Format.OSM, projection: new OpenLayers.Projection("EPSG:4326")});
+ osm_layer.events.register("loadend", osm_layer, function() {
+ $("loading").innerHTML = "";
+ if (this.features.length) {
+ var extent = this.features[0].geometry.getBounds();
+ for (var i = 1; i < this.features.length; i++) {
+ extent.extend(this.features[i].geometry.getBounds());
+ }
+ if (extent) {
+ this.map.zoomToExtent(extent);
+ } else {
+ this.map.zoomToMaxExtent();
+ }
+ var center = getMapCenter();
+ $("larger_map").href = '/?lat='+center.lat+'&lon='+center.lon+'&zoom='+this.map.getZoom();
+ $("larger_map").innerHTML = "View Larger Map";
+ } else {
+ $("small_map").style.display = "none";
+ }
+ })
+ map.addLayer(osm_layer);
+ osm_layer.loadGML();
+ osm_layer.loaded = true;
+}
+window.onload = init;
+</script>
+<span id="loading">Loading...</span>
+<a id="larger_map" href=""></a>
+</div>
--- /dev/null
+<tr>
+ <td><%= link_to member.member_id.to_s, :action => member.member_type, :id => member.member_id %></td>
+ <td><%= h(member.member_type) %></td>
+ <td><%= h(member.member_role) %></td>
+</tr>
--- /dev/null
+<div style="float:right; text-align:center; width: 250px;">
+<% if @prev %>
+<
+<%= link_to @prev.id.to_s, :action => type, :id => @prev.id %>
+<% end %>
+<% if @prev and @next %>
+|
+<% end %>
+<% if @next %>
+<%= link_to @next.id.to_s, :action => type, :id => @next.id %>
+>
+<% end %>
+</div>
--- /dev/null
+<% if members.length != 0 %>
+<h3>Members</h3>
+<table id="keyvalue" cellpadding="3">
+ <tr>
+ <th>ID</th>
+ <th>Type</th>
+ <th>Role</th>
+ </tr>
+ <%= render :partial => 'member', :collection => members %>
+</table>
+<% end %>
--- /dev/null
+<div style="padding:0px 10px">
+ <div style="text-align: center">
+ <p style="margin-top: 10px">
+ <a id="use_map" display="hidden" href="#">View Data For Current Map View</a>
+ <br />
+ <a id='drag_box' href="#">Manually select a different area</a>
+ </p>
+</div>
+<div id="status"></div>
+<div id="object">
+</div>
+</div>
--- /dev/null
+<tr>
+ <td><%= h(tag[0]) %></td><td><%= h(tag[1]) %></td>
+</tr>
+
--- /dev/null
+<% if tags.length != 0 %>
+<h3>Tags</h3>
+<table id="keyvalue" cellpadding="3">
+ <tr>
+ <th>Key</th>
+ <th>Value</th>
+ </tr>
+ <%= render :partial => 'tag', :collection => tags %>
+</table>
+<% end %>
--- /dev/null
+<h2><%= @nodes.length %> Recently Changed Nodes</h2>
+<ul>
+<% @nodes.each do |node|
+ name = node.tags_as_hash['name'].to_s
+ if name.length == 0:
+ name = "(No name)"
+ end
+ name = name + " - " + node.id.to_s
+%>
+ <li><%= link_to h(name), :action => "node", :id => node.id %></li>
+<% end %>
+</ul>
--- /dev/null
+<%= render :partial => 'navigation', :locals => { :type => "node" } %>
+<h2>Node Browser: <%= h(@name) %></h2>
+<%= render :partial => 'common', :locals => { :obj => @node, :type => "node" } %>
+<%= render :partial => 'tag_table', :locals => { :tags => @node.tags_as_hash } %>
+<% if @node.ways.length != 0 %>
+ <br style="clear:both" />
+ <div style="float:right; width: 250px;">
+ <h2>Part of:</h2>
+ <ul>
+ <% @node.ways.each do |way| %>
+ <li> <%= link_to "Way " + way.id.to_s, :action => "way", :id => way.id.to_s %> </li>
+ <% end %>
+ </ul>
+ </div>
+<% end %>
--- /dev/null
+<h2>Node History: <%= h(@name) %></h2>
+<%= render :partial => 'common', :locals => { :obj => @node, :type => "node" } %>
+<h2>Hisorical Versions</h2>
+<% @node.old_nodes.reverse.each do |node| %>
+<%= render :partial => 'common_editedby', :locals => { :obj => node } %>
+<%= render :partial => 'tag_table', :locals => { :tags => node.tags_as_hash } %>
+<hr />
+<% end %>
--- /dev/null
+<%= render :partial => 'navigation', :locals => { :type => "relation" } %>
+<h2>Relation Browser: <%= h(@name) %></h2>
+<%= render :partial => 'common', :locals => { :obj => @relation, :type => "relation" } %>
+<%= render :partial => 'tag_table', :locals => { :tags => @relation.tags } %>
+<%= render :partial => 'relation_members', :locals => { :members => @relation.relation_members } %>
--- /dev/null
+<h2>Relation History: <%= h(@name) %></h2>
+<%= render :partial => 'common', :locals => { :obj => @relation, :type => "relation" } %>
+<h2>Hisorical Versions</h2>
+<% @relation.old_relations.reverse.each do |relation| %>
+<%= render :partial => 'common_editedby', :locals => { :obj => relation } %>
+<%= render :partial => 'tag_table', :locals => { :tags => relation.tags } %>
+<%= render :partial => 'relation_members', :locals => { :members => relation.old_members } %>
+<hr />
+<% end %>
--- /dev/null
+page.replace_html :sidebar_title, 'Data'
+page.replace_html :sidebar_content, :partial => 'start'
+page << <<EOJ
+
+ var gml, sf, objList, currentFeature, featureList, mode = "auto", currentBounds, browsing;
+ OpenLayers.Feature.Vector.style['default'].strokeWidth = 3;
+ OpenLayers.Feature.Vector.style['default'].cursor = "pointer";
+
+ function start() {
+ openSidebar({ onclose: stopBrowse });
+ var vectors = new OpenLayers.Layer.Vector();
+
+ box = new OpenLayers.Control.DrawFeature(vectors, OpenLayers.Handler.RegularPolygon, {
+ handlerOptions: {
+ sides: 4,
+ snapAngle: 90,
+ irregular: true,
+ persist: true,
+ callbacks: { done: endDrag }
+ }
+ });
+ map.addControl(box);
+ map.events.register("moveend", map, showData);
+ map.events.triggerEvent("moveend");
+ map.dataLayer.stopBrowse = stopBrowse;
+ browsing = true;
+ }
+
+ function showData() {
+ if (mode == "manual") { return; }
+ if (map.getZoom() >= 15) {
+ useMap();
+ } else {
+ $("status").innerHTML = "Zoom in or Select an area of the map to view.";
+ }
+ }
+
+ function stopBrowse() {
+ if (browsing) {
+ browsing = false;
+ map.dataLayer.stopBrowse = null;
+ if (gml) {
+ gml.destroy();
+ gml = null;
+ }
+ if (sf) {
+ sf.destroy();
+ sf = null;
+ }
+ if (box) {
+ box.destroy();
+ box = null;
+ }
+ if (currentFeature) {
+ currentFeature.destroy();
+ currentFeature = null;
+ }
+ map.dataLayer.setVisibility(false);
+ map.events.unregister("moveend", map, showData);
+ }
+ }
+
+ function startDrag() {
+ $("drag_box").innerHTML='Drag a box on the map to select an area';
+ box.activate();
+ return false;
+ };
+ $("drag_box").onclick = startDrag;
+
+ function useMap() {
+ var bounds = map.getExtent();
+ var projected = bounds.clone().transform(map.getProjectionObject(), epsg4326);
+ if (!currentBounds || !currentBounds.containsBounds(projected)) {
+ var center = bounds.getCenterLonLat();
+ var tileWidth = bounds.getWidth() * 1.2;
+ var tileHeight = bounds.getHeight() * 1.2;
+ var tileBounds =
+ new OpenLayers.Bounds(center.lon - (tileWidth / 2),
+ center.lat - (tileHeight / 2),
+ center.lon + (tileWidth / 2),
+ center.lat + (tileHeight / 2));
+
+ currentBounds = tileBounds;
+ getData(tileBounds);
+ mode = "auto";
+ $("use_map").style.display="none";
+ }
+ return false;
+ }
+ $("use_map").onclick = useMap;
+
+ function endDrag(bbox) {
+ var bounds = bbox.getBounds();
+ box.deactivate();
+ currentBounds = bounds;
+ getData(bounds);
+ $("drag_box").innerHTML = "Manually select a different area";
+ mode = "manual";
+ $("use_map").style.display="inline";
+ }
+
+ function displayFeatureWarning() {
+ $("status").innerHTML = "";
+ var div = document.createElement("div");
+ var p = document.createElement("p");
+ p.appendChild(document.createTextNode("You have loaded an area which contains " + featureList.length + " features. In general, some browsers may not cope well with displaying this quantity of data. Generally, browsers work best at displaying less than 100 features at a time: doing anything else may make your browser slow/unresponsive. If you are sure you want to display this data, you may do so by clicking the button below."));
+ div.appendChild(p);
+ var input = document.createElement("input");
+ input.type = "submit";
+ input.value = "Load Data";
+ input.onclick = loadFeatureList;
+ div.appendChild(input);
+ $("object").innerHTML="";
+ $("object").appendChild(div);
+ }
+
+ function loadFeatureList() {
+ gml.addFeatures(featureList);
+ gml.events.triggerEvent("loadend");
+ return false;
+ }
+
+ function customDataLoader(request) {
+ if (!browsing) { return; }
+ var doc = request.responseXML;
+
+ if (!doc || !doc.documentElement) {
+ doc = request.responseText;
+ }
+
+ var options = {};
+
+ OpenLayers.Util.extend(options, this.formatOptions);
+ if (this.map && !this.projection.equals(this.map.getProjectionObject())) {
+ options.externalProjection = this.projection;
+ options.internalProjection = this.map.getProjectionObject();
+ }
+
+ var gml = this.format ? new this.format(options) : new OpenLayers.Format.GML(options);
+ var features = gml.read(doc);
+ if (!this.maxFeatures || features.length <= this.maxFeatures) {
+ this.addFeatures(features);
+ this.events.triggerEvent("loadend");
+ featureList = [];
+ } else {
+ featureList = features;
+ displayFeatureWarning();
+ }
+ }
+
+ function getData(bounds) {
+
+ bounds.transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326"));
+ var size = bounds.getWidth() * bounds.getHeight();
+ if (size > 0.25) {
+ $("status").innerHTML = "Unable to load: Bounding box size of " + size + " is too large. (Must be smaller than 0.25)<br />";
+ return;
+ }
+
+ var url = "/api/0.5/map?bbox="+bounds.toBBOX();
+
+ loadGML(url);
+ }
+ function loadGML(url) {
+ $("status").innerHTML = "Loading...";
+ $("object").innerHTML = "";
+ if (!gml) {
+ var style = new OpenLayers.Style();
+ style.addRules([new OpenLayers.Rule(
+ {'symbolizer':
+ {"Polygon": {'fillColor': '#ff0000', 'strokeColor': '#ff0000'},
+ "Line": {'fillColor': '#ffff00', 'strokeColor': '#000000', strokeOpacity: '0.4'},
+ "Point": {'fillColor': '#00ff00', 'strokeColor': '#00ff00'}}
+ }
+ )]);
+ gml = new OpenLayers.Layer.GML("Data",url,
+ {format: OpenLayers.Format.OSM, formatOptions: {checkTags: true},
+ maxFeatures: 100, requestSuccess: customDataLoader,
+ displayInLayerSwitcher: false,
+ styleMap: new OpenLayers.StyleMap({'default': style, 'select': {'strokeColor': '#0000ff', strokeWidth: 8}})
+ }
+ );
+ gml.events.register("loadend", gml, dataLoaded );
+ map.addLayer(gml);
+
+ sf = new OpenLayers.Control.SelectFeature(gml, {'onSelect': onFeatureSelect});
+ sf.handler.stopDown = false;
+ sf.handler.stopUp = false;
+ map.addControl(sf);
+ sf.activate();
+
+ } else {
+ gml.setUrl(url);
+ }
+
+ currentFeature = null;
+ }
+ function dataLoaded() {
+ if (!browsing) { return; }
+ $("status").innerHTML = "Loaded."
+
+ objList = document.createElement("div")
+
+ list = document.createElement("ul");
+ for (var i = 0; i < this.features.length; i++) {
+ var feature = this.features[i];
+
+ // Type, for linking
+ var type ="way";
+ if (feature.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
+ type = "node";
+ }
+ var nice_name = type.substr(0,1).toUpperCase() + type.substr(1,type.length);
+ var li = document.createElement("li");
+ li.appendChild(document.createTextNode(nice_name + " "));
+
+ // Link, for viewing in the tab
+ var link = document.createElement("a");
+ link.href = "/browse/" + type + "/" + feature.osm_id;
+ var name = feature.attributes.name || feature.osm_id;
+ link.appendChild(document.createTextNode(name));
+ link.feature = feature;
+ link.onclick = OpenLayers.Function.bind(viewFeatureLink, link);
+ li.appendChild(link);
+
+ list.appendChild(li);
+ }
+ objList.appendChild(list)
+ var link = document.createElement("a");
+ link.href = this.url;
+ link.appendChild(document.createTextNode("API"));
+ objList.appendChild(link)
+ $("object").innerHTML = "";
+ $("object").appendChild(objList);
+
+ }
+
+ function viewFeatureLink() {
+ var layer = this.feature.layer;
+ for (var i = 0; i < layer.selectedFeatures.length; i++) {
+ var f = layer.selectedFeatures[i];
+ layer.drawFeature(f, layer.styleMap.createSymbolizer(f, "default"));
+ }
+ onFeatureSelect(this.feature);
+ if (mode != "auto") {
+ map.setCenter(this.feature.geometry.getBounds().getCenterLonLat());
+ }
+ return false;
+ }
+
+ function loadObjList() {
+ $("object").innerHTML="";
+ $("object").appendChild(objList);
+ return false;
+ }
+
+ function onFeatureSelect(feature) {
+ // Unselect previously selected feature
+ if (currentFeature) {
+ currentFeature.layer.drawFeature(
+ currentFeature, currentFeature.layer.styleMap.createSymbolizer(currentFeature, "default")
+ );
+ }
+
+ // Redraw in selected style
+ feature.layer.drawFeature(
+ feature, feature.layer.styleMap.createSymbolizer(feature, "select")
+ );
+
+ // If the current object is the list, don't innerHTML="", since that could clar it.
+ if ($("object").firstChild == objList) {
+ $("object").removeChild(objList);
+ } else {
+ $("object").innerHTML = "";
+ }
+
+ // Create a link back to the object list
+ var div = document.createElement("div");
+ var link = document.createElement("a");
+ link.href="#";
+ link.onclick = loadObjList;
+ link.appendChild(document.createTextNode("Back to Object List"));
+ div.appendChild(link)
+ $("object").appendChild(div);
+
+ var type = "way";
+ if (feature.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
+ type = "node";
+ }
+
+ var link = document.createElement("a");
+ link.href = "/browse/"+type+"/"+feature.osm_id;
+ link.appendChild(document.createTextNode("Database entry for " + feature.osm_id));
+
+ var div = document.createElement("div");
+ div.style.marginTop = "20px"
+ div.appendChild(link);
+
+ $("object").appendChild(div);
+
+ // Now the list of attributes
+ var ul = document.createElement("ul");
+ for (var key in feature.attributes) {
+ var li = document.createElement("li");
+ var b = document.createElement("b");
+ b.appendChild(document.createTextNode(key));
+ li.appendChild(b);
+ li.appendChild(document.createTextNode(": " + feature.attributes[key]));
+ ul.appendChild(li);
+ }
+
+ $("object").appendChild(ul);
+
+ var link = document.createElement("a");
+ link.href = "/browse/"+type+"/"+feature.osm_id+"/history";
+ link.appendChild(document.createTextNode("History"));
+ ul.appendChild(li);
+ link.onclick = OpenLayers.Function.bind(loadHistory, {type: type, feature: feature, link: link});
+
+ $("object").appendChild(link);
+
+ // Stash the currently drawn feature
+ currentFeature = feature;
+ }
+ function loadHistory() {
+ this.link.href = "";
+ this.link.innerHTML = "Wait...";
+ new Ajax.Request("/api/0.5/"+this.type+"/"+this.feature.osm_id+"/history", {onComplete: OpenLayers.Function.bind(displayHistory, this)});
+ return false;
+ }
+ function displayHistory(request) {
+ if (currentFeature.osm_id != this.feature.osm_id || $("object").firstChild == objList) {
+ return false;
+ }
+ this.link.parentNode.removeChild(this.link);
+ var doc = request.responseXML;
+ var div = document.createElement("div");
+ var h3 = document.createElement("h3");
+ h3.appendChild(document.createTextNode("History"));
+ div.appendChild(h3);
+ var nodes = doc.getElementsByTagName(this.type);
+ var history = document.createElement("ul");
+ for (var i = nodes.length - 1; i >= 0; i--) {
+ var user = nodes[i].getAttribute("user") || "private user";
+ var timestamp = nodes[i].getAttribute("timestamp");
+ var item = document.createElement("li");
+ item.appendChild(document.createTextNode("Edited by " + user + " at " + timestamp));
+ history.appendChild(item);
+ }
+ div.appendChild(history);
+ var link = document.createElement("a");
+ link.appendChild(document.createTextNode("History entry for " + this.feature.osm_id));
+ link.href = "/browse/"+this.type+"/"+this.feature.osm_id+"/history";
+ div.appendChild(link);
+ $("object").appendChild(div);
+ }
+
+ start();
+EOJ
--- /dev/null
+<%= render :partial => 'navigation', :locals => { :type => "way" } %>
+<h2>Way Browser: <%= h(@name) %></h2>
+<%= render :partial => 'common', :locals => { :obj => @way, :type => "way" } %>
+<%= render :partial => 'tag_table', :locals => { :tags => @way.tags } %>
+
+<% if @way.nodes.length != 0 %>
+ <br style="clear:both" />
+ <div style="float:right; width: 250px;">
+ <h2>Parts:</h2>
+ <ul>
+ <% @way.nodes.each do |node| %>
+ <li> <%= link_to "Node " + node.id.to_s, :action => "node", :id => node.id.to_s %> </li>
+ <% end %>
+ </ul>
+ </div>
+<% end %>
--- /dev/null
+<h2>Way History: <%= h(@name) %></h2>
+<%= render :partial => 'common', :locals => { :obj => @way, :type => "way" } %>
+<h2>Hisorical Versions</h2>
+<% @way.old_ways.reverse.each do |way| %>
+<%= render :partial => 'common_editedby', :locals => { :obj => way } %>
+<%= render :partial => 'tag_table', :locals => { :tags => way.tags } %>
+<hr />
+<% end %>
# http://dev.mysql.com/doc/refman/5.0/en/old-client.html
development:
adapter: mysql
- database: openstreetmap
- username: openstreetmap
- password: openstreetmap
+ database: osm
+ user: root
host: localhost
# Warning: The database defined as 'test' will be erased and
map.connect "api/#{API_VERSION}/amf", :controller =>'amf', :action =>'talk'
map.connect "api/#{API_VERSION}/swf/trackpoints", :controller =>'swf', :action =>'trackpoints'
+ # Data browsing
+ map.connect '/browse/start', :controller => 'browse', :action => 'start'
+ map.connect '/browse', :controller => 'browse', :action => 'index'
+ map.connect '/browse/way/:id', :controller => 'browse', :action => 'way', :id => /\d+/
+ map.connect '/browse/way/:id/history', :controller => 'browse', :action => 'way_history', :id => /\d+/
+ map.connect '/browse/node/:id', :controller => 'browse', :action => 'node', :id => /\d+/
+ map.connect '/browse/node/:id/history', :controller => 'browse', :action => 'node_history', :id => /\d+/
+ map.connect '/browse/relation/:id', :controller => 'browse', :action => 'relation', :id => /\d+/
+ map.connect '/browse/relation/:id/history', :controller => 'browse', :action => 'relation_history', :id => /\d+/
+
# web site
map.connect '/', :controller => 'site', :action => 'index'
return "/openlayers/";
}
-function createMap(divName) {
+function createMap(divName, options) {
+ if (!options) { options = {} }
map = new OpenLayers.Map(divName, {
- controls: [
+ controls: options.controls || [
new OpenLayers.Control.ArgParser(),
new OpenLayers.Control.Attribution(),
new OpenLayers.Control.LayerSwitcher(),
new OpenLayers.Control.ScaleLine()
],
units: "m",
- maxResolution: 156543,
+ maxResolution: 156543.0339,
numZoomLevels: 20
});
wrapDateLine: true
});
map.addLayer(maplint);
+ var data = new OpenLayers.Layer.Data("Data", {'visibility': false});
+ map.addLayer(data);
+ map.dataLayer = data;
var numZoomLevels = Math.max(mapnik.numZoomLevels, osmarender.numZoomLevels);
markers = new OpenLayers.Layer.Markers("Markers", {
initialize: function(name, url, options) {
options = OpenLayers.Util.extend({
attribution: "Data by <a href='http://openstreetmap.org/'>OpenStreetMap</a>",
- maxExtent: new OpenLayers.Bounds(-20037508,-20037508,20037508,20037508),
- maxResolution: 156543,
+ maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
+ maxResolution: 156543.0339,
units: "m",
projection: "EPSG:900913",
transitionEffect: "resize"
CLASS_NAME: "OpenLayers.Layer.OSM.Maplint"
});
+
+OpenLayers.Layer.Data = OpenLayers.Class(OpenLayers.Layer, {
+ setVisibility: function(vis) {
+ var oldvis = this.visibility;
+ OpenLayers.Layer.prototype.setVisibility.apply(this, arguments);
+ if (!this.map) { return; }
+ if (vis && !oldvis) {
+ new Ajax.Request('/browse/start', {asynchronous:true, evalScripts:true});
+ } else {
+ if (this.stopBrowse) {
+ this.stopBrowse();
+ closeSidebar();
+ }
+ }
+ }
+});
-a {
+a m
color: #0000ff;
text-decoration: none;
}