1 OSM.initializeDataLayer = function (map) {
2 let dataLoader, loadedBounds;
3 const dataLayer = map.dataLayer;
5 dataLayer.isWayArea = function () {
9 dataLayer.on("click", function (e) {
13 dataLayer.on("add", function () {
14 map.fire("overlayadd", { layer: this });
15 map.on("moveend", updateData);
19 dataLayer.on("remove", function () {
20 if (dataLoader) dataLoader.abort();
22 map.off("moveend", updateData);
23 $("#browse_status").empty();
24 map.fire("overlayremove", { layer: this });
27 function updateData() {
28 const bounds = map.getBounds();
29 if (!loadedBounds || !loadedBounds.contains(bounds)) {
34 function displayFeatureWarning(num_features, add, cancel) {
35 $("#browse_status").html(
36 $("<div class='p-3'>").append(
37 $("<div class='d-flex'>").append(
38 $("<h2 class='flex-grow-1 text-break'>")
39 .text(OSM.i18n.t("browse.start_rjs.load_data")),
41 $("<button type='button' class='btn-close'>")
42 .attr("aria-label", OSM.i18n.t("javascripts.close"))
44 $("<p class='alert alert-warning'>")
45 .text(OSM.i18n.t("browse.start_rjs.feature_warning", { num_features })),
46 $("<input type='submit' class='btn btn-primary d-block mx-auto'>")
47 .val(OSM.i18n.t("browse.start_rjs.load_data"))
51 function displayLoadError(message, close) {
52 $("#browse_status").html(
53 $("<div class='p-3'>").append(
54 $("<div class='d-flex'>").append(
55 $("<h2 class='flex-grow-1 text-break'>")
56 .text(OSM.i18n.t("browse.start_rjs.load_data")),
58 $("<button type='button' class='btn-close'>")
59 .attr("aria-label", OSM.i18n.t("javascripts.close"))
61 $("<p class='alert alert-warning'>")
62 .text(OSM.i18n.t("browse.start_rjs.feature_error", { message: message }))));
66 const bounds = map.getBounds();
67 const url = "/api/" + OSM.API_VERSION + "/map.json?bbox=" + bounds.toBBoxString();
70 * Modern browsers are quite happy showing far more than 100 features in
71 * the data browser, so increase the limit to 4000.
73 const maxFeatures = 4000;
75 if (dataLoader) dataLoader.abort();
77 $("#layers-data-loading").remove();
79 const spanLoading = $("<span>")
80 .attr("id", "layers-data-loading")
81 .attr("class", "spinner-border spinner-border-sm ms-1")
82 .attr("role", "status")
83 .html("<span class='visually-hidden'>" + OSM.i18n.t("browse.start_rjs.loading") + "</span>")
84 .appendTo($("#label-layers-data"));
86 dataLoader = new AbortController();
87 fetch(url, { signal: dataLoader.signal })
89 if (response.ok) return response.json();
90 const status = response.statusText || response.status;
91 if (response.status !== 400) throw new Error(status);
92 return response.text().then(text => {
93 throw new Error(text || status);
96 .then(function (data) {
97 dataLayer.clearLayers();
99 const features = dataLayer.buildFeatures(data);
101 function addFeatures() {
102 $("#browse_status").empty();
103 dataLayer.addData(features);
104 loadedBounds = bounds;
107 function cancelAddFeatures() {
108 $("#browse_status").empty();
111 if (features.length < maxFeatures) {
114 displayFeatureWarning(features.length, addFeatures, cancelAddFeatures);
117 if (map._objectLayer) {
118 map._objectLayer.bringToFront();
123 .catch(function (error) {
124 if (error.name === "AbortError") return;
126 displayLoadError(error?.message, () => {
127 $("#browse_status").empty();
133 spanLoading.remove();
137 function onSelect(layer) {
138 OSM.router.route("/" + layer.feature.type + "/" + layer.feature.id);