Search code examples
javascriptvue.jsgoogle-mapsopenstreetmapgeojson

Import GeoJson to GoogleMap


I read answers, documentations here and there But I think I need more guidance when It comes to polygons. Here's what I need to do,

  • Import city boundaries from GeoJson file
  • Draw the polygon boundaries on my map using its coordinates

Link to the GeoJson file - https://nominatim.openstreetmap.org/details.php?osmtype=R&osmid=3705576&class=boundary&addressdetails=1&hierarchy=0&group_hierarchy=1&polygon_geojson=1&format=json

As in the below code I tried map.data.loadGeoJson() here's the Uncaught error , message: "not a Feature or FeatureCollection" name: "InvalidValueError"

export default {
  data() {
    return {
      //Maps
      center: { lat: 45.508, lng: -73.587 },
      markers: [],
      map:null,
    };
  },

  mounted() {
    this.initMap();
  },

  methods: {
        
    initMap() {
      // Create the map.
      this.map = new google.maps.Map(document.getElementById("map"), {
        zoom: 12,
        center: { lat: 37.910076, lng: -122.065186 },
      });
      //Set boundaries*********************************Where I'm stucked********************************    

     this.map.data.loadGeoJson(
    "https://nominatim.openstreetmap.org/details.php?osmtype=R&osmid=3705576&class=boundary&addressdetails=1&hierarchy=0&group_hierarchy=1&polygon_geojson=1&format=json"
     );

      
    },

    
}

Solution

  • The type in the return data needs to be "Feature" (currently it is "administrative").

    Loading the data, modifying it, then loading the modified JSON into the DataLayer works for me:

      // request data
      $.ajax({
        url: "https://nominatim.openstreetmap.org/details.php?osmtype=R&osmid=3705576&class=boundary&addressdetails=1&hierarchy=0&group_hierarchy=1&polygon_geojson=1&format=json",
      }).done(function(data) {
        // modify the type to that expected by the DataLayer
        data.type = "Feature";
        map.data.addGeoJson(data);
      });
    

    proof of concept fiddle

    screenshot of resulting map

    code snippet:

    let map;
    
    function initMap() {
      map = new google.maps.Map(document.getElementById("map"), {
        zoom: 4,
        center: {
          lat: -28,
          lng: 137
        },
      });
      // zoom to show all the features
      var bounds = new google.maps.LatLngBounds();
      map.data.addListener('addfeature', function(e) {
        processPoints(e.feature.getGeometry(), bounds.extend, bounds);
        map.fitBounds(bounds);
      });
      $.ajax({
        url: "https://nominatim.openstreetmap.org/details.php?osmtype=R&osmid=3705576&class=boundary&addressdetails=1&hierarchy=0&group_hierarchy=1&polygon_geojson=1&format=json",
      }).done(function(data) {
        data.type = "Feature";
        map.data.addGeoJson(data);
      });
    
    }
    
    function processPoints(geometry, callback, thisArg) {
      if (geometry instanceof google.maps.LatLng) {
        callback.call(thisArg, geometry);
      } else if (geometry instanceof google.maps.Data.Point) {
        callback.call(thisArg, geometry.get());
      } else {
        geometry.getArray().forEach(function(g) {
          processPoints(g, callback, thisArg);
        });
      }
    }
    /* Always set the map height explicitly to define the size of the div
           * element that contains the map. */
    
    #map {
      height: 100%;
    }
    
    
    /* Optional: Makes the sample page fill the window. */
    
    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <!DOCTYPE html>
    <html>
    
    <head>
      <title>Data Layer: Simple</title>
      <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
      <!-- jsFiddle will insert css and js -->
    </head>
    
    <body>
      <div id="map"></div>
    
      <!-- Async script executes immediately and must be after any DOM elements used in callback. -->
      <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=&v=weekly" async></script>
    </body>
    
    </html>