1 //= require templates/browse/feature
2 //= require templates/browse/feature_list
3 //= require templates/browse/feature_history
5 $(document).ready(function () {
6 $("#show_data").click(function (e) {
7 $.ajax({ url: $(this).attr('href'), success: function (sidebarHtml) {
8 startBrowse(sidebarHtml);
13 function startBrowse(sidebarHtml) {
15 var browseMode = "auto";
17 var browseFeatureList;
18 var browseActiveFeature;
20 var browseSelectControl;
22 var areasHidden = false;
24 OpenLayers.Feature.Vector.style['default'].strokeWidth = 3;
25 OpenLayers.Feature.Vector.style['default'].cursor = "pointer";
27 map.dataLayer.active = true;
29 $("#sidebar_title").html(I18n.t('browse.start_rjs.data_frame_title'));
30 $("#sidebar_content").html(sidebarHtml);
34 var vectors = new OpenLayers.Layer.Vector();
36 browseBoxControl = new OpenLayers.Control.DrawFeature(vectors, OpenLayers.Handler.RegularPolygon, {
44 browseBoxControl.handler.callbacks.done = endDrag;
45 map.addControl(browseBoxControl);
47 map.events.register("moveend", map, updateData);
48 map.events.triggerEvent("moveend");
50 $("#browse_select_view").click(useMap);
52 $("#browse_select_box").click(startDrag);
54 $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.hide_areas'));
55 $("#browse_hide_areas_box").toggle(hideAreas, showAreas);
57 function updateData() {
58 if (browseMode == "auto") {
59 if (map.getZoom() >= 15) {
62 setStatus(I18n.t('browse.start_rjs.zoom_or_select'));
67 $("#sidebar").one("closed", function () {
68 if (map.dataLayer.active) {
69 map.dataLayer.active = false;
71 if (browseSelectControl) {
72 browseSelectControl.destroy();
73 browseSelectControl = null;
76 if (browseBoxControl) {
77 browseBoxControl.destroy();
78 browseBoxControl = null;
81 if (browseActiveFeature) {
82 browseActiveFeature.destroy();
83 browseActiveFeature = null;
86 if (browseDataLayer) {
87 browseDataLayer.destroy();
88 browseDataLayer = null;
91 map.dataLayer.setVisibility(false);
92 map.events.unregister("moveend", map, updateData);
96 function startDrag() {
97 $("#browse_select_box").html(I18n.t('browse.start_rjs.drag_a_box'));
99 browseBoxControl.activate();
104 function useMap(reload) {
105 var bounds = map.getExtent();
106 var projected = unproj(bounds);
108 if (!browseBounds || !browseBounds.containsBounds(projected)) {
109 var center = bounds.getCenterLonLat();
110 var tileWidth = bounds.getWidth() * 1.2;
111 var tileHeight = bounds.getHeight() * 1.2;
112 var tileBounds = new OpenLayers.Bounds(center.lon - (tileWidth / 2),
113 center.lat - (tileHeight / 2),
114 center.lon + (tileWidth / 2),
115 center.lat + (tileHeight / 2));
117 browseBounds = tileBounds;
118 getData(tileBounds, reload);
122 $("#browse_select_view").hide();
128 function hideAreas() {
129 $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.show_areas'));
136 function showAreas() {
137 $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.hide_areas'));
144 function endDrag(bbox) {
145 var bounds = bbox.getBounds();
146 var projected = unproj(bounds);
148 browseBoxControl.deactivate();
149 browseBounds = projected;
152 browseMode = "manual";
154 $("#browse_select_box").html(I18n.t('browse.start_rjs.manually_select'));
155 $("#browse_select_view").show();
158 function displayFeatureWarning(count, limit, callback) {
161 var div = document.createElement("div");
163 var p = document.createElement("p");
164 p.appendChild(document.createTextNode(I18n.t("browse.start_rjs.loaded_an_area_with_num_features", { num_features: count, max_features: limit })));
167 var input = document.createElement("input");
168 input.type = "submit";
169 input.value = I18n.t('browse.start_rjs.load_data');
170 input.onclick = callback;
171 div.appendChild(input);
173 $("#browse_content").html("");
174 $("#browse_content").append(div);
177 function customDataLoader(resp, options) {
178 if (map.dataLayer.active) {
179 var request = resp.priv;
180 var doc = request.responseXML;
182 if (!doc || !doc.documentElement) {
183 doc = request.responseText;
186 resp.features = this.format.read(doc);
188 if (!this.maxFeatures || resp.features.length <= this.maxFeatures) {
189 options.callback.call(options.scope, resp);
191 displayFeatureWarning(resp.features.length, this.maxFeatures, function () {
192 options.callback.call(options.scope, resp);
198 function getData(bounds, reload) {
199 var projected = unproj(bounds);
200 var size = projected.getWidth() * projected.getHeight();
202 if (size > OSM.MAX_REQUEST_AREA) {
203 setStatus(I18n.t("browse.start_rjs.unable_to_load_size", { max_bbox_size: OSM.MAX_REQUEST_AREA, bbox_size: size }));
205 loadData("/api/" + OSM.API_VERSION + "/map?bbox=" + projected.toBBOX(), reload);
209 function loadData(url, reload) {
210 setStatus(I18n.t('browse.start_rjs.loading'));
212 $("#browse_content").empty();
214 var formatOptions = {
216 interestingTagsExclude: ['source','source_ref','source:ref','history','attribution','created_by','tiger:county','tiger:tlid','tiger:upload_uuid']
219 if (areasHidden) formatOptions.areaTags = [];
221 if (!browseDataLayer || reload) {
222 var style = new OpenLayers.Style();
224 style.addRules([new OpenLayers.Rule({
226 Polygon: { fillColor: '#ff0000', strokeColor: '#ff0000' },
227 Line: { fillColor: '#ffff00', strokeColor: '#000000', strokeOpacity: '0.4' },
228 Point: { fillColor: '#00ff00', strokeColor: '#00ff00' }
232 if (browseDataLayer) browseDataLayer.destroyFeatures();
235 * Modern browsers are quite happy showing far more than 100 features in
236 * the data browser, so increase the limit to 2000 by default, but keep
237 * it restricted to 500 for IE8 and 100 for older IEs.
239 var maxFeatures = 2000;
242 if (navigator.appVersion < 8) {
244 } else if (navigator.appVersion < 9) {
249 browseDataLayer = new OpenLayers.Layer.Vector("Data", {
251 new OpenLayers.Strategy.Fixed()
253 protocol: new OpenLayers.Protocol.HTTP({
255 format: new OpenLayers.Format.OSM(formatOptions),
256 maxFeatures: maxFeatures,
257 handleRead: customDataLoader
259 projection: new OpenLayers.Projection("EPSG:4326"),
260 displayInLayerSwitcher: false,
261 styleMap: new OpenLayers.StyleMap({
263 'select': { strokeColor: '#0000ff', strokeWidth: 8 }
266 browseDataLayer.events.register("loadend", browseDataLayer, dataLoaded );
267 map.addLayer(browseDataLayer);
269 browseSelectControl = new OpenLayers.Control.SelectFeature(browseDataLayer, { onSelect: onFeatureSelect });
270 browseSelectControl.handlers.feature.stopDown = false;
271 browseSelectControl.handlers.feature.stopUp = false;
272 map.addControl(browseSelectControl);
273 browseSelectControl.activate();
275 browseDataLayer.destroyFeatures();
276 browseDataLayer.refresh({ url: url });
279 browseActiveFeature = null;
282 function dataLoaded() {
283 if (this.map.dataLayer.active) {
287 for (var i = 0; i < this.features.length; i++) {
288 var feature = this.features[i];
290 typeName: featureTypeName(feature),
291 url: "/browse/" + featureType(feature) + "/" + feature.osm_id,
292 name: featureName(feature),
297 browseObjectList = $(JST["templates/browse/feature_list"]({
299 url: this.protocol.url
306 function viewFeatureLink() {
307 var feature = browseDataLayer.getFeatureById($(this).data("feature-id"));
308 var layer = feature.layer;
310 for (var i = 0; i < layer.selectedFeatures.length; i++) {
311 var f = layer.selectedFeatures[i];
312 layer.drawFeature(f, layer.styleMap.createSymbolizer(f, "default"));
315 onFeatureSelect(feature);
317 if (browseMode != "auto") {
318 map.setCenter(feature.geometry.getBounds().getCenterLonLat());
324 function loadObjectList() {
325 $("#browse_content").html(browseObjectList);
326 $("#browse_content").find("a[data-feature-id]").click(viewFeatureLink);
331 function onFeatureSelect(feature) {
332 // Unselect previously selected feature
333 if (browseActiveFeature) {
334 browseActiveFeature.layer.drawFeature(
336 browseActiveFeature.layer.styleMap.createSymbolizer(browseActiveFeature, "default")
340 // Redraw in selected style
341 feature.layer.drawFeature(
342 feature, feature.layer.styleMap.createSymbolizer(feature, "select")
345 // If the current object is the list, don't innerHTML="", since that could clear it.
346 if ($("#browse_content").firstChild == browseObjectList) {
347 $("#browse_content").removeChild(browseObjectList);
349 $("#browse_content").empty();
352 $("#browse_content").html(JST["templates/browse/feature"]({
353 name: featureNameSelect(feature),
354 url: "/browse/" + featureType(feature) + "/" + feature.osm_id,
355 attributes: feature.attributes
358 $("#browse_content").find("a.browse_show_list").click(loadObjectList);
359 $("#browse_content").find("a.browse_show_history").click(loadHistory);
361 // Stash the currently drawn feature
362 browseActiveFeature = feature;
365 function loadHistory() {
366 $(this).attr("href", "").text(I18n.t('browse.start_rjs.wait'));
368 var feature = browseActiveFeature;
371 url: "/api/" + OSM.API_VERSION + "/" + featureType(feature) + "/" + feature.osm_id + "/history",
372 success: function (xml) {
373 if (browseActiveFeature != feature || $("#browse_content").firstChild == browseObjectList) {
380 var nodes = xml.getElementsByTagName(featureType(feature));
381 for (var i = nodes.length - 1; i >= 0; i--) {
383 user: nodes[i].getAttribute("user") || I18n.t('browse.start_rjs.private_user'),
384 timestamp: nodes[i].getAttribute("timestamp")
388 $("#browse_content").append(JST["templates/browse/feature_history"]({
389 name: featureNameHistory(feature),
390 url: "/browse/" + featureType(feature) + "/" + feature.osm_id,
399 function featureType(feature) {
400 if (feature.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
407 function featureTypeName(feature) {
408 if (featureType(feature) == "node") {
409 return I18n.t('browse.start_rjs.object_list.type.node');
410 } else if (featureType(feature) == "way") {
411 return I18n.t('browse.start_rjs.object_list.type.way');
415 function featureName(feature) {
416 var lang = $('html').attr('lang');
417 if (feature.attributes['name:' + lang]) {
418 return feature.attributes['name:' + lang];
419 } else if (feature.attributes.name) {
420 return feature.attributes.name;
422 return feature.osm_id;
426 function featureNameSelect(feature) {
427 var lang = $('html').attr('lang');
428 if (feature.attributes['name:' + lang]) {
429 return feature.attributes['name:' + lang];
430 } else if (feature.attributes.name) {
431 return feature.attributes.name;
432 } else if (featureType(feature) == "node") {
433 return I18n.t("browse.start_rjs.object_list.selected.type.node", { id: feature.osm_id });
434 } else if (featureType(feature) == "way") {
435 return I18n.t("browse.start_rjs.object_list.selected.type.way", { id: feature.osm_id });
439 function featureNameHistory(feature) {
440 var lang = $('html').attr('lang');
441 if (feature.attributes['name:' + lang]) {
442 return feature.attributes['name:' + lang];
443 } else if (feature.attributes.name) {
444 return feature.attributes.name;
445 } else if (featureType(feature) == "node") {
446 return I18n.t("browse.start_rjs.object_list.history.type.node", { id: feature.osm_id });
447 } else if (featureType(feature) == "way") {
448 return I18n.t("browse.start_rjs.object_list.history.type.way", { id: feature.osm_id });
452 function setStatus(status) {
453 $("#browse_status").html(status);
454 $("#browse_status").show();
457 function clearStatus() {
458 $("#browse_status").html("");
459 $("#browse_status").hide();