* Object list, API, Display object list, Details Also make node/way/relation translatable, and in different contexts too (e.g. Icelandic needs this). This introduces more stuff that needs to be fixed in ticket 1919.
504 lines
16 KiB
Text
504 lines
16 KiB
Text
page.replace_html :sidebar_title, t('browse.start_rjs.data_frame_title')
|
|
page.replace_html :sidebar_content, :partial => 'start'
|
|
page << <<EOJ
|
|
var browseBoxControl;
|
|
var browseActive;
|
|
var browseMode = "auto";
|
|
var browseBounds;
|
|
var browseFeatureList;
|
|
var browseActiveFeature;
|
|
var browseDataLayer;
|
|
var browseSelectControl;
|
|
var browseObjectList;
|
|
|
|
OpenLayers.Feature.Vector.style['default'].strokeWidth = 3;
|
|
OpenLayers.Feature.Vector.style['default'].cursor = "pointer";
|
|
|
|
function startBrowse() {
|
|
browseActive = true;
|
|
|
|
openSidebar({ onclose: stopBrowse });
|
|
|
|
var vectors = new OpenLayers.Layer.Vector();
|
|
|
|
browseBoxControl = new OpenLayers.Control.DrawFeature(vectors, OpenLayers.Handler.RegularPolygon, {
|
|
handlerOptions: {
|
|
sides: 4,
|
|
snapAngle: 90,
|
|
irregular: true,
|
|
persist: true,
|
|
callbacks: { done: endDrag }
|
|
}
|
|
});
|
|
map.addControl(browseBoxControl);
|
|
|
|
map.events.register("moveend", map, showData);
|
|
map.events.triggerEvent("moveend");
|
|
}
|
|
|
|
function showData() {
|
|
if (browseMode == "auto") {
|
|
if (map.getZoom() >= 15) {
|
|
useMap();
|
|
} else {
|
|
setStatus("#{I18n.t('browse.start_rjs.zoom_or_select')}");
|
|
}
|
|
}
|
|
}
|
|
|
|
function stopBrowse() {
|
|
if (browseActive) {
|
|
browseActive = false;
|
|
|
|
if (browseSelectControl) {
|
|
browseSelectControl.destroy();
|
|
browseSelectControl = null;
|
|
}
|
|
|
|
if (browseBoxControl) {
|
|
browseBoxControl.destroy();
|
|
browseBoxControl = null;
|
|
}
|
|
|
|
if (browseActiveFeature) {
|
|
browseActiveFeature.destroy();
|
|
browseActiveFeature = null;
|
|
}
|
|
|
|
if (browseDataLayer) {
|
|
browseDataLayer.destroy();
|
|
browseDataLayer = null;
|
|
}
|
|
|
|
map.dataLayer.setVisibility(false);
|
|
map.events.unregister("moveend", map, showData);
|
|
}
|
|
}
|
|
|
|
function startDrag() {
|
|
$("browse_select_box").innerHTML='#{I18n.t('browse.start_rjs.drag_a_box')}';
|
|
|
|
browseBoxControl.activate();
|
|
|
|
return false;
|
|
};
|
|
|
|
$("browse_select_box").onclick = startDrag;
|
|
|
|
function useMap() {
|
|
var bounds = map.getExtent();
|
|
var projected = bounds.clone().transform(map.getProjectionObject(), epsg4326);
|
|
|
|
if (!browseBounds || !browseBounds.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));
|
|
|
|
browseBounds = tileBounds;
|
|
getData(tileBounds);
|
|
|
|
browseMode = "auto";
|
|
|
|
$("browse_select_view").style.display = "none";
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
$("browse_select_view").onclick = useMap;
|
|
|
|
function endDrag(bbox) {
|
|
var bounds = bbox.getBounds();
|
|
var projected = bounds.clone().transform(map.getProjectionObject(), epsg4326);
|
|
|
|
browseBoxControl.deactivate();
|
|
browseBounds = projected;
|
|
getData(bounds);
|
|
|
|
browseMode = "manual";
|
|
|
|
$("browse_select_box").innerHTML = "#{I18n.t('browse.start_rjs.manually_select')}";
|
|
$("browse_select_view").style.display = "inline";
|
|
}
|
|
|
|
function displayFeatureWarning() {
|
|
clearStatus();
|
|
|
|
var div = document.createElement("div");
|
|
|
|
var p = document.createElement("p");
|
|
p.appendChild(document.createTextNode("#{I18n.t('browse.start_rjs.loaded_an_area')} " + browseFeatureList.length + " #{I18n.t('browse.start_rjs.browsers')}"));
|
|
div.appendChild(p);
|
|
|
|
var input = document.createElement("input");
|
|
input.type = "submit";
|
|
input.value = "#{I18n.t('browse.start_rjs.load_data')}";
|
|
input.onclick = loadFeatureList;
|
|
div.appendChild(input);
|
|
|
|
$("browse_content").innerHTML = "";
|
|
$("browse_content").appendChild(div);
|
|
}
|
|
|
|
function loadFeatureList() {
|
|
browseDataLayer.addFeatures(browseFeatureList);
|
|
browseDataLayer.events.triggerEvent("loadend");
|
|
|
|
browseFeatureList = [];
|
|
|
|
return false;
|
|
}
|
|
|
|
function customDataLoader(request) {
|
|
if (browseActive) {
|
|
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);
|
|
|
|
browseFeatureList = gml.read(doc);
|
|
|
|
if (!this.maxFeatures || browseFeatureList.length <= this.maxFeatures) {
|
|
loadFeatureList();
|
|
} else {
|
|
displayFeatureWarning();
|
|
}
|
|
}
|
|
}
|
|
|
|
function getData(bounds) {
|
|
var projected = bounds.clone().transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326"));
|
|
var size = projected.getWidth() * projected.getHeight();
|
|
|
|
if (size > 0.25) {
|
|
setStatus("#{I18n.t('browse.start_rjs.unable_to_load')} " + size + " #{I18n.t('browse.start_rjs.must_be_smaller')}");
|
|
} else {
|
|
loadGML("/api/#{API_VERSION}/map?bbox=" + projected.toBBOX());
|
|
}
|
|
}
|
|
|
|
function loadGML(url) {
|
|
setStatus("#{I18n.t('browse.start_rjs.loading')}");
|
|
$("browse_content").innerHTML = "";
|
|
|
|
if (!browseDataLayer) {
|
|
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' }
|
|
}
|
|
})]);
|
|
|
|
browseDataLayer = new OpenLayers.Layer.GML("Data", url, {
|
|
format: OpenLayers.Format.OSM,
|
|
formatOptions: {
|
|
checkTags: true,
|
|
interestingTagsExclude: ['source','source_ref','source:ref','history','attribution','created_by','tiger:county','tiger:tlid','tiger:upload_uuid']
|
|
},
|
|
maxFeatures: 100,
|
|
requestSuccess: customDataLoader,
|
|
displayInLayerSwitcher: false,
|
|
styleMap: new OpenLayers.StyleMap({
|
|
'default': style,
|
|
'select': { strokeColor: '#0000ff', strokeWidth: 8 }
|
|
})
|
|
});
|
|
browseDataLayer.events.register("loadend", browseDataLayer, dataLoaded );
|
|
map.addLayer(browseDataLayer);
|
|
|
|
browseSelectControl = new OpenLayers.Control.SelectFeature(browseDataLayer, { onSelect: onFeatureSelect });
|
|
browseSelectControl.handlers.feature.stopDown = false;
|
|
browseSelectControl.handlers.feature.stopUp = false;
|
|
map.addControl(browseSelectControl);
|
|
browseSelectControl.activate();
|
|
} else {
|
|
browseDataLayer.setUrl(url);
|
|
}
|
|
|
|
browseActiveFeature = null;
|
|
}
|
|
|
|
function dataLoaded() {
|
|
if (browseActive) {
|
|
clearStatus();
|
|
|
|
browseObjectList = document.createElement("div")
|
|
|
|
var heading = document.createElement("p");
|
|
heading.className = "browse_heading";
|
|
heading.appendChild(document.createTextNode("#{I18n.t('browse.start_rjs.object_list.heading')}"));
|
|
browseObjectList.appendChild(heading);
|
|
|
|
var list = document.createElement("ul");
|
|
// Pull in 118n names for node/way/relation
|
|
var typeTranslations = new Array();
|
|
typeTranslations['node'] = "#{I18n.t('browse.start_rjs.object_list.type.node')}"
|
|
typeTranslations['way'] = "#{I18n.t('browse.start_rjs.object_list.type.way')}"
|
|
typeTranslations['relation'] = "#{I18n.t('browse.start_rjs.object_list.type.relation')}"
|
|
|
|
for (var i = 0; i < this.features.length; i++) {
|
|
var feature = this.features[i];
|
|
|
|
// Type, for linking
|
|
var type = featureType(feature);
|
|
var li = document.createElement("li");
|
|
li.appendChild(document.createTextNode(typeTranslations[type] + " "));
|
|
|
|
// 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);
|
|
}
|
|
|
|
browseObjectList.appendChild(list)
|
|
|
|
var link = document.createElement("a");
|
|
link.href = this.url;
|
|
link.appendChild(document.createTextNode("#{I18n.t('browse.start_rjs.object_list.api')}"));
|
|
browseObjectList.appendChild(link);
|
|
|
|
$("browse_content").innerHTML = "";
|
|
$("browse_content").appendChild(browseObjectList);
|
|
}
|
|
}
|
|
|
|
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 (browseMode != "auto") {
|
|
map.setCenter(this.feature.geometry.getBounds().getCenterLonLat());
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function loadObjectList() {
|
|
$("browse_content").innerHTML="";
|
|
$("browse_content").appendChild(browseObjectList);
|
|
|
|
return false;
|
|
}
|
|
|
|
function onFeatureSelect(feature) {
|
|
// Unselect previously selected feature
|
|
if (browseActiveFeature) {
|
|
browseActiveFeature.layer.drawFeature(
|
|
browseActiveFeature,
|
|
browseActiveFeature.layer.styleMap.createSymbolizer(browseActiveFeature, "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 clear it.
|
|
if ($("browse_content").firstChild == browseObjectList) {
|
|
$("browse_content").removeChild(browseObjectList);
|
|
} else {
|
|
$("browse_content").innerHTML = "";
|
|
}
|
|
|
|
// Create a link back to the object list
|
|
var div = document.createElement("div");
|
|
div.style.textAlign = "center";
|
|
div.style.marginBottom = "20px";
|
|
$("browse_content").appendChild(div);
|
|
var link = document.createElement("a");
|
|
link.href = "#";
|
|
link.onclick = loadObjectList;
|
|
link.appendChild(document.createTextNode("#{I18n.t('browse.start_rjs.object_list.back')}"));
|
|
div.appendChild(link);
|
|
|
|
var table = document.createElement("table");
|
|
table.width = "100%";
|
|
table.className = "browse_heading";
|
|
$("browse_content").appendChild(table);
|
|
|
|
var tr = document.createElement("tr");
|
|
table.appendChild(tr);
|
|
|
|
var heading = document.createElement("td");
|
|
heading.appendChild(document.createTextNode(featureNameSelect(feature)));
|
|
tr.appendChild(heading);
|
|
|
|
var td = document.createElement("td");
|
|
td.align = "right";
|
|
tr.appendChild(td);
|
|
|
|
var type = featureType(feature);
|
|
var link = document.createElement("a");
|
|
link.href = "/browse/" + type + "/" + feature.osm_id;
|
|
link.appendChild(document.createTextNode("#{I18n.t('browse.start_rjs.object_list.details')}"));
|
|
td.appendChild(link);
|
|
|
|
var div = document.createElement("div");
|
|
div.className = "browse_details";
|
|
|
|
$("browse_content").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);
|
|
}
|
|
|
|
div.appendChild(ul);
|
|
|
|
var link = document.createElement("a");
|
|
link.href = "/browse/" + type + "/" + feature.osm_id + "/history";
|
|
link.appendChild(document.createTextNode("#{I18n.t('browse.start_rjs.show_history')}"));
|
|
link.onclick = OpenLayers.Function.bind(loadHistory, {
|
|
type: type, feature: feature, link: link
|
|
});
|
|
|
|
div.appendChild(link);
|
|
|
|
// Stash the currently drawn feature
|
|
browseActiveFeature = feature;
|
|
}
|
|
|
|
function loadHistory() {
|
|
this.link.href = "";
|
|
this.link.innerHTML = "#{I18n.t('browse.start_rjs.wait')}";
|
|
|
|
new Ajax.Request("/api/#{API_VERSION}/" + this.type + "/" + this.feature.osm_id + "/history", {
|
|
onComplete: OpenLayers.Function.bind(displayHistory, this)
|
|
});
|
|
|
|
return false;
|
|
}
|
|
|
|
function displayHistory(request) {
|
|
if (browseActiveFeature.osm_id != this.feature.osm_id || $("browse_content").firstChild == browseObjectList) {
|
|
return false;
|
|
}
|
|
|
|
this.link.parentNode.removeChild(this.link);
|
|
|
|
var doc = request.responseXML;
|
|
|
|
var table = document.createElement("table");
|
|
table.width = "100%";
|
|
table.className = "browse_heading";
|
|
$("browse_content").appendChild(table);
|
|
|
|
var tr = document.createElement("tr");
|
|
table.appendChild(tr);
|
|
|
|
var heading = document.createElement("td");
|
|
heading.appendChild(document.createTextNode("#{I18n.t('browse.start_rjs.history_for')} " + featureNameHistory(this.feature)));
|
|
tr.appendChild(heading);
|
|
|
|
var td = document.createElement("td");
|
|
td.align = "right";
|
|
tr.appendChild(td);
|
|
|
|
var link = document.createElement("a");
|
|
link.href = "/browse/" + this.type + "/" + this.feature.osm_id + "/history";
|
|
link.appendChild(document.createTextNode("#{I18n.t('browse.start_rjs.details')}"));
|
|
td.appendChild(link);
|
|
|
|
var div = document.createElement("div");
|
|
div.className = "browse_details";
|
|
|
|
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") || "#{I18n.t('browse.start_rjs.private_user')}";
|
|
var timestamp = nodes[i].getAttribute("timestamp");
|
|
var item = document.createElement("li");
|
|
item.appendChild(document.createTextNode("#{I18n.t('browse.start_rjs.edited_by')} " + user + " #{I18n.t('browse.start_rjs.at_timestamp')} " + timestamp));
|
|
history.appendChild(item);
|
|
}
|
|
div.appendChild(history);
|
|
|
|
$("browse_content").appendChild(div);
|
|
}
|
|
|
|
function featureType(feature) {
|
|
if (feature.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
|
|
return "node";
|
|
} else {
|
|
return "way";
|
|
}
|
|
}
|
|
|
|
function featureNameSelect(feature) {
|
|
if (feature.attributes.name) {
|
|
return feature.attributes.name;
|
|
} else {
|
|
// Pull in 118n names for node/way
|
|
var featureNameSelectTypeTranslations = new Array();
|
|
featureNameSelectTypeTranslations['node'] = "#{I18n.t('browse.start_rjs.object_list.selected.type.node')}"
|
|
featureNameSelectTypeTranslations['way'] = "#{I18n.t('browse.start_rjs.object_list.selected.type.way')}"
|
|
return featureNameSelectTypeTranslations[featureType(feature)] + " " + feature.osm_id;
|
|
}
|
|
}
|
|
|
|
function featureNameHistory(feature) {
|
|
if (feature.attributes.name) {
|
|
return feature.attributes.name;
|
|
} else {
|
|
// Pull in 118n names for node/way
|
|
var featureNameHistoryTypeTranslations = new Array();
|
|
featureNameHistoryTypeTranslations['node'] = "#{I18n.t('browse.start_rjs.object_list.history.type.node')}"
|
|
featureNameHistoryTypeTranslations['way'] = "#{I18n.t('browse.start_rjs.object_list.history.type.way')}"
|
|
return featureNameHistoryTypeTranslations[featureType(feature)] + " " + feature.osm_id;
|
|
}
|
|
}
|
|
|
|
function setStatus(status) {
|
|
$("browse_status").innerHTML = status;
|
|
$("browse_status").style.display = "block";
|
|
}
|
|
|
|
function clearStatus() {
|
|
$("browse_status").innerHTML = "";
|
|
$("browse_status").style.display = "none";
|
|
}
|
|
|
|
function ucFirst(str) {
|
|
return str.substr(0,1).toUpperCase() + str.substr(1,str.length);
|
|
}
|
|
|
|
startBrowse();
|
|
EOJ
|