显示加载屏幕,直到使用 Google 地图设置 geojson 数据标记的样式

Show loading screen until geojson data markers' style are set using Google maps

我想让地图在每个标记都以正确的样式出现后可见。

我正在使用自定义标记图标,这就是设置标记样式需要花费大量时间的原因。

loadGeoJson 有回调,但我希望地图在 setStyle 完成时显示,而不是 loadGeoJson。我想,我应该以某种方式对 setStyle 事件进行回调。 不幸的是,我也找不到处理 idle 和 tilesloaded google 地图事件的解决方法。


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/

自定义标记只有几张图片,但加载时间仍然有点长。

看起来判断图标何时出现在地图上的方法是将 onload 事件侦听器附加到图标图像,然后在它们全部加载后删除 "loading" 指示。

请注意,下面的代码假设所有功能都有自定义图标,如果有些功能没有自定义图标,计算会变得更加复杂。

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,
    }
}

proof of concept

代码片段:

#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.....&#160;&#160;&#160; please wait!<br /></div>
<div id="map"></div>


<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&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>