Bill Cheatham
Bill Cheatham

Reputation: 11917

Load external JSON file for google maps styling

I'm currently succesfully styling my google maps using the JSON as made by this site. An example of my code is shown here (though in reality there are many hundreds of lines of json styling):

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>

Obviously this makes a big mess of my javascript, so I would like to keep all the json styling in a separate .json file, which the javascript loads in. Unfortunately I haven't had much luck with this. I've tried:

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>

Where style.json contains:

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

But this fails to apply the styling to the map.

So how can I apply an external json file (hosted on my server) to be the styling for my google maps? Is it really as complex as all this?

Upvotes: 0

Views: 3340

Answers (2)

geocodezip
geocodezip

Reputation: 161334

Move the map creation into the loadJSON callback function when/where the styles exist.

live example

code snippet (note that the code snippet won't work on SO as the JSON file isn't available, the live example (external link above) works):

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>

Upvotes: 2

eNVy
eNVy

Reputation: 487

You need to rearrange your code. It looks like the loaded_json is empty at the time the styledMapType is initialized. Try rearranging code as below:

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');
});

Upvotes: 0

Related Questions