Показывать экран загрузки до тех пор, пока стиль маркеров данных geojson не будет установлен с помощью карт Google

#javascript #google-maps-api-3

#javascript #google-maps-api-3

Вопрос:

Я хотел бы сделать карту видимой, как только каждый маркер будет в ней с соответствующим стилем.

Я использую пользовательские значки маркеров, поэтому настройка стиля маркеров занимает много времени.

У loadGeoJson есть обратный вызов, но я хочу, чтобы карта отображалась при выполнении setStyle, а не loadGeoJson. Я думаю, каким-то образом я должен выполнить обратный вызов для события setStyle. К сожалению, я также не смог найти обходной путь для событий idle и tilesloaded Google map.

 
function initMap() {
   var map = new google.maps.Map(document.getElementById('map'), {
        center: { lat: -1.54108, lng: 37.759902 },
        zoom: 5,
    });
   map.data.loadGeoJson(GEOJSON);
   map.data.setStyle(styleFeature);
}
//////////////////////////////////////////////////
function styleFeature(feature) {
    var icon = {
        url: feature.getProperty('icon'), //logos come from google drive
        scaledSize: new google.maps.Size(30, 30),
        origin: new google.maps.Point(0, 0),
        anchor: new google.maps.Point(0, 30)
    };
    var chain = feature.getProperty('chain');

    return {
        icon: icon,
        title: chain,
        visible: true

    }    
};


  

Вот рабочий пример проблемы: https://jsfiddle.net/6bznm32v

В нем всего несколько изображений для пользовательских маркеров, но все еще требуется немного времени для загрузки.

Ответ №1:

Похоже, что способ определить, когда значки появятся на карте, заключается в том, чтобы прикрепить onload прослушиватели событий к изображениям значков, а затем удалить указание «загрузка», как только все они будут загружены.

Обратите внимание, что приведенный ниже код предполагает, что все функции имеют пользовательские значки, вычисление усложняется, если некоторые из них этого не делают.

 var featuresToBeStyled;  // number of features in the GeoJSON file
map.data.loadGeoJson('https://api.myjson.com/bins/bdmco', {}, function(features) {
  console.log("loadGeoJson complete, " features.length " features");
  featuresToBeStyled=features.length;
});
var iconsLoaded = 0;  // icons whose images have loaded
function styleFeature(feature) {
    var img = new Image();
    img.onload = (function(idx, feature) {
      return function () {
         var timeImage = performance.now();
         iconsLoaded  ;
         if (iconsLoaded==featuresToBeStyled)
           document.getElementById('loaddiv').style.display="none";
      }
    })(styledFeatures,feature);
    img.src = feature.getProperty('icon');
    var icon = {
        url: feature.getProperty('icon'), 
        scaledSize: new google.maps.Size(30, 30),
        origin: new google.maps.Point(0, 0),
        anchor: new google.maps.Point(0, 30)
    };
    var amenity = feature.getProperty('amenity');
    return {
        icon: icon,
        title: amenity,
        visible: true,
    }
}
  

доказательство концепции

фрагмент кода:

 #map {
  height: 100%;
}

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#loaddiv {
  BORDER-RIGHT: #785e4f 4px groove;
  PADDING-RIGHT: 20px;
  BORDER-TOP: #785e4f 4px groove;
  PADDING-LEFT: 20px;
  FONT-WEIGHT: bold;
  Z-INDEX: 100;
  FILTER: alpha(opacity=75);
  LEFT: 260px;
  PADDING-BOTTOM: 20px;
  MARGIN-LEFT: auto;
  BORDER-LEFT: #785e4f 4px groove;
  WIDTH: 250px;
  MARGIN-RIGHT: auto;
  PADDING-TOP: 20px;
  BORDER-BOTTOM: #785e4f 4px groove;
  POSITION: absolute;
  TOP: 150px;
  BACKGROUND-COLOR: #FFFFFF;
  /* BACKGROUND-COLOR: #e7b047; */
  TEXT-ALIGN: center;
  opacity: .75
}  
 <div id="loaddiv">Loading.....amp;#160;amp;#160;amp;#160; please wait!<br /></div>
<div id="map"></div>


<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qkamp;callback=initMap">
</script>
<script type="text/javascript">
  var map;
  var featuresToBeStyled;
  var initialLoad = performance.now();

  function initMap() {
    map = new google.maps.Map(document.getElementById('map'), {
      zoom: 3,
      center: {
        lat: -1.54108,
        lng: 37.759902
      }
    });
    // NOTE: This uses cross-domain XHR, and may not work on older browsers.
    map.data.loadGeoJson('https://api.myjson.com/bins/bdmco', {}, function(features) {
      console.log("loadGeoJson complete, "   features.length   " features");
      featuresToBeStyled = features.length;
    });
    map.data.setStyle(styleFeature); //just once this is done I would like to show the map. Until it is not, I would like to show a loading screen
  }
  var iconsLoaded = 0;

  function styleFeature(feature) {
    var img = new Image();
    img.onload = (function(feature) {
      return function() {
        var timeImage = performance.now();
        iconsLoaded  ;
        if (iconsLoaded == featuresToBeStyled)
          document.getElementById('loaddiv').style.display = "none";
      }
    })(feature);
    img.src = feature.getProperty('icon');
    var icon = {
      url: feature.getProperty('icon'),
      scaledSize: new google.maps.Size(30, 30),
      origin: new google.maps.Point(0, 0),
      anchor: new google.maps.Point(0, 30)
    };
    var amenity = feature.getProperty('amenity');
    return {
      icon: icon,
      title: amenity,
      visible: true,
    }
  }
</script>