【问题标题】:Load external JSON file for google maps styling为谷歌地图样式加载外部 JSON 文件
【发布时间】:2017-12-30 10:42:41
【问题描述】:

我目前正在使用this site 制作的 JSON 成功地设置我的谷歌地图样式。此处显示了我的代码示例(尽管实际上有数百行 json 样式):

window.onload = function initMap() {

  var styledMapType = new google.maps.StyledMapType(
    [
      {
        "elementType": "geometry",
        "stylers": [
          {
            "color": "#f5f5f5"
          }
        ]
      },
    ], {name: 'Map'});
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 10,
    center: {lat: 51.529517, lng: 10.058284},
    mapTypeControlOptions: {
      mapTypeIds: ['satellite', 'styled_map']
    }
  });

  // Associate the styled map with the MapTypeId and set it to display.
  map.mapTypes.set('styled_map', styledMapType);
  map.setMapTypeId('styled_map');
}
<html>
  <head>
    <script src="load_maps_works.js"></script>
    <style>
       #map{
        position: absolute;
        top: 100px;
        left: 0;
        bottom: 100px;
        right: 0;
    }
    </style>
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=places&sensor=false"></script>
    </script>
  </head>
  <body>
    <div id="map"></div>
  </body>
</html>

显然,这使我的 javascript 变得一团糟,所以我想将所有 json 样式保存在一个单独的 .json 文件中,javascript 会加载到该文件中。不幸的是,我对此没有太多运气。我试过了:

window.onload = function initMap() {

  function loadJSON(callback) {

    var xobj = new XMLHttpRequest();
        xobj.overrideMimeType("application/json");
    xobj.open('GET', 'http://localhost:8000/style.json', true);
    xobj.onreadystatechange = function () {
          if (xobj.readyState == 4 && xobj.status == "200") {
            callback(xobj.responseText);
          }
    };
    xobj.send(null);
  }

  var loaded_json

  loadJSON(function(response) {
    // This correctly prints out the JSON
    loaded_json = JSON.parse(response);
    console.log(loaded_json)
  });

  // This doesn't
  console.log(loaded_json)

  var styledMapType = new google.maps.StyledMapType(loaded_json, {name: 'Map'});

  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 10,
    center: {lat: 51.529517, lng: 10.058284},
    mapTypeControlOptions: {
      mapTypeIds: ['satellite', 'styled_map']
    }
  });

  //Associate the styled map with the MapTypeId and set it to display.
  map.mapTypes.set('styled_map', styledMapType);
  map.setMapTypeId('styled_map');
}
<html>
  <head>
    <script src="load_maps_broken.js"></script>
    <style>
       #map{
        position: absolute;
        top: 100px;
        left: 0;
        bottom: 100px;
        right: 0;
    }
    </style>
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDO1KU-C6Iy7VhyIJMEPiHNtqhWLmYCl3w&libraries=places&sensor=false"></script>
    </script>
  </head>
  <body>
    <div id="map"></div>
  </body>
</html>

其中style.json 包含:

[
  {
    "elementType": "geometry",
    "stylers": [
      {
        "color": "#ebe3cd"
      }
    ]
  }
]

但这无法将样式应用于地图。

那么,如何应用外部 json 文件(托管在我的服务器上)作为我的 google 地图的样式?真的有这么复杂吗?

【问题讨论】:

  • How do I return the response from an asynchronous call? 的可能副本。请注意,您(可能)现在有两个异步函数(您尚未发布 minimal reproducible example,因此我们无法看到您如何初始化地图),因此您必须处理潜在的竞争条件(地图初始化、样式返回数据)。
  • 我已经用一个完整的工作示例更新了这个问题,其中包含嵌入在 html 中的 json 版本。然后我有一个完整但损坏的 json 外部示例。

标签: javascript json google-maps-api-3


【解决方案1】:

当样式存在时/在哪里,将地图创建移动到loadJSON回调函数中。

live example

code sn-p(请注意,由于 JSON 文件不可用,因此代码 sn-p 无法在 SO 上运行,现场示例 (external link above) 有效):

window.onload = function initMap() {

  function loadJSON(callback) {

    var xobj = new XMLHttpRequest();
    xobj.overrideMimeType("application/json");
    xobj.open('GET', 'style.json', true);
    xobj.onreadystatechange = function() {
      if (xobj.readyState == 4 && xobj.status == "200") {
        callback(xobj.responseText);
      }
    };
    xobj.send(null);
  }

  var loaded_json

  loadJSON(function(response) {
    // This correctly prints out the JSON
    loaded_json = JSON.parse(response);
    console.log(loaded_json)
    var styledMapType = new google.maps.StyledMapType(loaded_json, {
      name: 'Map'
    });

    var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 10,
      center: {
        lat: 51.529517,
        lng: 10.058284
      },
      mapTypeControlOptions: {
        mapTypeIds: ['satellite', 'styled_map']
      }
    });

    //Associate the styled map with the MapTypeId and set it to display.
    map.mapTypes.set('styled_map', styledMapType);
    map.setMapTypeId('styled_map');
    // This doesn't
    console.log(loaded_json)

  });
}
#map {
  position: absolute;
  top: 100px;
  left: 0;
  bottom: 100px;
  right: 0;
}
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDO1KU-C6Iy7VhyIJMEPiHNtqhWLmYCl3w&libraries=places"></script>
<div id="map"> </div>

【讨论】:

    【解决方案2】:

    您需要重新排列代码。在 styledMapType 初始化时,loaded_json 看起来是空的。尝试重新排列代码如下:

    var styledMapType;
    
    var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 10,
      center: {lat: 51.529517, lng: 10.058284},
      mapTypeControlOptions: {
        mapTypeIds: ['satellite', 'styled_map']
      }
    });  
    
    loadJSON(function(response) {
      loaded_json = JSON.parse(response);
      styledMapType = new google.maps.StyledMapType(loaded_json, {name: 'Map'});
    
      map.mapTypes.set('styled_map', styledMapType);
      map.setMapTypeId('styled_map');
    });
    

    【讨论】:

    • 请注意,此代码有一个竞争条件,地图必须在 JSON 之前加载,否则它不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-20
    • 1970-01-01
    • 2014-06-14
    • 2012-11-16
    • 2021-09-27
    相关资源
    最近更新 更多