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 && response.status !== 509) 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);