Google Maps - France departments data layer

WIP: inspiration: https://france-geojson.gregoiredavid.fr/

by katalin_2003

HTML

<!DOCTYPE html>
<html>

  <head>
    <title>Data Layer: Drag and Drop GeoJSON</title>
    <link href="https://unpkg.com/[email protected]/dist/material-components-web.css" rel="stylesheet" />
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />

    <!-- jsFiddle will insert css and js -->
  </head>

  <body>
    <div id="container">
      <div id="map"></div>
      <div id="sidebar" class="mdc-typography">
        <div class="file" draggable="true" data-value="0">
          <span class="material-icons">text_snippet</span>
          <div class="filename">polygons.geojson</div>
        </div>
        <div class="file" draggable="true" data-value="1">
          <span class="material-icons">text_snippet</span>
          <div class="filename">points.geojson</div>
        </div>
        <div class="file" draggable="true" data-value="2">
          <span class="material-icons">text_snippet</span>
          <div class="filename">polyline.geojson</div>
        </div>
		
		<div id="info-block"></div>
		
      </div>
    </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=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initialize&libraries=&v=weekly&channel=2" async></script> -->
	
	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&region=FR&language=fr&libraries=&v=weekly&channel=2"></script>
	
  </body>

</html>

CSS

html {
  height: 100%;
}

body {
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

#map {
  height: 100%;
}

#map.over {
  opacity: 0.5;
  background-color: rgba(100, 100, 100, 0.5);
}

#sidebar {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: auto;
}

.file {
  display: flex;
  flex-flow: column;
  margin-top: 1em;
  cursor: move;
  text-align: center;
}

.file:hover .material-icons {
  color: darkorange;
}

.file:hover .filename {
  font-weight: bold;
}

.file .material-icons {
  font-size: 50px;
  color: orange;
}

.file .material-icons:hover {
  color: darkorange;
}

.file .filename {
  margin-top: 0.5em;
  font-size: 20px;
  color: #333333;
}

/* Optional: Makes the sample page fill the window. */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#container {
  height: 100%;
  display: flex;
}

#sidebar {
  flex-basis: 15rem;
  flex-grow: 1;
  padding: 1rem;
  max-width: 30rem;
  height: 100%;
  box-sizing: border-box;
  overflow: auto;
}

#map {
  flex-basis: 0;
  flex-grow: 4;
  height: 100%;
}

JavaScript

let map;
var infoBlock = document.getElementById('info-block');

function initMap() {
  // set up the map
  map = new google.maps.Map(document.getElementById("map"), {
    center: new google.maps.LatLng(46.227638, 2.213749),
    zoom: 4,
	mapTypeId: 'terrain'
  });


  // CSA: get data from the geojson file, on hover
  map.data.addListener('mouseover', function(event) {
    console.log(event.feature.getProperty('code') + ' - ' + event.feature.getProperty('nom'));
	var depCode = event.feature.getProperty('code');
    var depName = event.feature.getProperty('nom');
    (depName == undefined) ? "" : infoBlock.innerHTML = "<b>" + depCode + "</b> - <b>" + depName + "</b>";
  });

}

function loadGeoJsonString(geoString) {
  try {
    const geojson = JSON.parse(geoString);
    map.data.addGeoJson(geojson);
  } catch (e) {
    alert("Not a GeoJSON file!");
  }
  zoom(map);
}

/**
 * Update a map's viewport to fit each geometry in a dataset
 */
function zoom(map) {
  const bounds = new google.maps.LatLngBounds();
  map.data.forEach((feature) => {
    const geometry = feature.getGeometry();

    // csa
    //console.log(feature.i.nom);

    if (geometry) {
      processPoints(geometry, bounds.extend, bounds);
    }
  });
  map.fitBounds(bounds);
}

/**
 * Process each point in a Geometry, regardless of how deep the points may lie.
 */
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((g) => {
      processPoints(g, callback, thisArg);
    });
  }
}

/* DOM (drag/drop) functions */
function initEvents() {
  [...document.getElementsByClassName("file")].forEach((fileElement) => {
    fileElement.addEventListener(
      "dragstart",
      (e) => {
        e.dataTransfer.setData(
          "text/plain",
         ...