To try this example, drag and drop either a GeoJSON file or a selection of GeoJSON text onto the map.
For more information about working with the map data layer, see the google.maps.Data class.
Sample GeoJSON
/* Map functions */ var map; function initMap() { // set up the map map = new google.maps.Map(document.getElementById('map'), { center: new google.maps.LatLng(0, 0), zoom: 2 }); } function loadGeoJsonString(geoString) { var geojson = JSON.parse(geoString); map.data.addGeoJson(geojson); zoom(map); } /** * Update a map's viewport to fit each geometry in a dataset * @param {google.maps.Map} map The map to adjust */ function zoom(map) { var bounds = new google.maps.LatLngBounds(); map.data.forEach(function(feature) { processPoints(feature.getGeometry(), bounds.extend, bounds); }); map.fitBounds(bounds); } /** * Process each point in a Geometry, regardless of how deep the points may lie. * @param {google.maps.Data.Geometry} geometry The structure to process * @param {function(google.maps.LatLng)} callback A function to call on each * LatLng point encountered (e.g. Array.push) * @param {Object} thisArg The value of 'this' as provided to 'callback' (e.g. * myArray) */ 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); }); } } /* DOM (drag/drop) functions */ function initEvents() { // set up the drag & drop events var mapContainer = document.getElementById('map'); var dropContainer = document.getElementById('drop-container'); // map-specific events mapContainer.addEventListener('dragenter', showPanel, false); // overlay specific events (since it only appears once drag starts) dropContainer.addEventListener('dragover', showPanel, false); dropContainer.addEventListener('drop', handleDrop, false); dropContainer.addEventListener('dragleave', hidePanel, false); } function showPanel(e) { e.stopPropagation(); e.preventDefault(); document.getElementById('drop-container').style.display = 'block'; return false; } function hidePanel(e) { document.getElementById('drop-container').style.display = 'none'; } function handleDrop(e) { e.preventDefault(); e.stopPropagation(); hidePanel(e); var files = e.dataTransfer.files; if (files.length) { // process file(s) being dropped // grab the file data from each file for (var i = 0, file; file = files[i]; i++) { var reader = new FileReader(); reader.onload = function(e) { loadGeoJsonString(e.target.result); }; reader.onerror = function(e) { console.error('reading failed'); }; reader.readAsText(file); } } else { // process non-file (e.g. text or html) content being dropped // grab the plain text version of the data var plainText = e.dataTransfer.getData('text/plain'); if (plainText) { loadGeoJsonString(plainText); } } // prevent drag event from bubbling further return false; } function initialize() { initMap(); initEvents(); }
<div id="map"></div> <div id="drop-container"><div id="drop-silhouette"></div></div>
/* 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; }
#floating-panel { position: absolute; top: 10px; left: 25%; z-index: 5; background-color: #fff; padding: 5px; border: 1px solid #999; text-align: center; font-family: 'Roboto','sans-serif'; line-height: 30px; padding-left: 10px; }
html { height: 100% } body { height: 100%; margin: 0; padding: 0; overflow: hidden; } #map { height: 100% } #drop-container { display: none; height: 100%; width: 100%; position: absolute; z-index: 1; top: 0px; left: 0px; padding: 20px; background-color: rgba(100, 100, 100, 0.5); } #drop-silhouette { color: white; border: white dashed 8px; height: calc(100% - 56px); width: calc(100% - 56px); background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAAXNSR0IArs4c6QAAAAZiS0dEAGQAZABkkPCsTwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90LHAIvICWdsKwAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAACdklEQVR42u3csU7icBzA8Xp3GBMSeRITH8JHMY7cRMvmVmXoE9TAcJubhjD4ApoiopgqDMWAKAgIcSAiCfxuwhwROVJbkPD9rP23ob8vpZCQKgoAAAAAAAAAAPDYyiK/eNM05bNtr6+vSjgcXiHxDMkE1WpVFvGcfpCVICAIQUAQgoAgBAFBCAKCgCAEAUEIAoIQBAQhCAgCghAEBCEICEIQEIQgIAgIQhAQhCAgCEFAEIKAICAIQUAQgoAgBAFBCDIzhmFINBo9/K6D0XVddnd3ZaneDY7jSCqVcn3SfjyeKRKJbJ2dnYllWbKUl2i5XJaXlxdJJBIy7yDHx8fy9vYm6XR6OWMM3d/fi4hIqVSSWCwmsw5ycHAgrVZLRETOz8+XO8ZQpVJ5H2Y6nRZN0/b9DqLruhSLxfd9MpkMMT6L0uv1JJlMih9BhveJwWDwvv7i4oIY4zw8PIwMtt1uSzweF6+CHB0dSbfbHVmbzWaJMcnj4+OHAd/d3cne3p64DWKapjw/P39Yd3l5SYxpVKvVsYO2LEtUVd2ZNoiu6+I4ztg1V1dXxPAiSq/Xk5OTk0k9pNVqyenp6ch94l+5XI4YbtRqNfHa9fX1t43xcwGa/Nnc3PwdDAY9OZht28rGxgZPvP6KSCSy9fT09OUrw7ZtPqa8jFKv113HuLm5IYbXVFXdcRPl9vaWGH5GaTQaU8fI5/PE8JumafvNZvO/MQqFAjFmJRqNHk6Ksqgx5vr1zzAM2d7edr3/6uqqsra2NnZbp9NR+v2+62OHQqG5zObXPIMEAgFlfX3dl2N79btl1viTA0FAEIKAIAQBAAAAAAAAsMz+Ai1bUgo6ebm8AAAAAElFTkSuQmCC'); background-repeat: no-repeat; background-position: center; }
<!-- Replace the value of the key parameter with your own API key. --> <script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initialize"> </script>
Try it yourself
You can experiment with this code in JSFiddle by clicking the <>
icon in the
top-right corner of the code window.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1.0" /> <title>Data Layer: Drag and Drop GeoJSON</title> <style> <span class="metadata-marker" style="display: none;" data-region_tag="css"></span> html { height: 100% } body { height: 100%; margin: 0; padding: 0; overflow: hidden; } #map { height: 100% } #drop-container { display: none; height: 100%; width: 100%; position: absolute; z-index: 1; top: 0px; left: 0px; padding: 20px; background-color: rgba(100, 100, 100, 0.5); } #drop-silhouette { color: white; border: white dashed 8px; height: calc(100% - 56px); width: calc(100% - 56px); background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAAXNSR0IArs4c6QAAAAZiS0dEAGQAZABkkPCsTwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90LHAIvICWdsKwAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAACdklEQVR42u3csU7icBzA8Xp3GBMSeRITH8JHMY7cRMvmVmXoE9TAcJubhjD4ApoiopgqDMWAKAgIcSAiCfxuwhwROVJbkPD9rP23ob8vpZCQKgoAAAAAAAAAAPDYyiK/eNM05bNtr6+vSjgcXiHxDMkE1WpVFvGcfpCVICAIQUAQgoAgBAFBCAKCgCAEAUEIAoIQBAQhCAgCghAEBCEICEIQEIQgIAgIQhAQhCAgCEFAEIKAICAIQUAQgoAgBAFBCDIzhmFINBo9/K6D0XVddnd3ZaneDY7jSCqVcn3SfjyeKRKJbJ2dnYllWbKUl2i5XJaXlxdJJBIy7yDHx8fy9vYm6XR6OWMM3d/fi4hIqVSSWCwmsw5ycHAgrVZLRETOz8+XO8ZQpVJ5H2Y6nRZN0/b9DqLruhSLxfd9MpkMMT6L0uv1JJlMih9BhveJwWDwvv7i4oIY4zw8PIwMtt1uSzweF6+CHB0dSbfbHVmbzWaJMcnj4+OHAd/d3cne3p64DWKapjw/P39Yd3l5SYxpVKvVsYO2LEtUVd2ZNoiu6+I4ztg1V1dXxPAiSq/Xk5OTk0k9pNVqyenp6ch94l+5XI4YbtRqNfHa9fX1t43xcwGa/Nnc3PwdDAY9OZht28rGxgZPvP6KSCSy9fT09OUrw7ZtPqa8jFKv113HuLm5IYbXVFXdcRPl9vaWGH5GaTQaU8fI5/PE8JumafvNZvO/MQqFAjFmJRqNHk6Ksqgx5vr1zzAM2d7edr3/6uqqsra2NnZbp9NR+v2+62OHQqG5zObXPIMEAgFlfX3dl2N79btl1viTA0FAEIKAIAQBAAAAAAAAsMz+Ai1bUgo6ebm8AAAAAElFTkSuQmCC'); background-repeat: no-repeat; background-position: center; } </style> </head> <body> <span class="metadata-marker" style="display: none;" data-region_tag="html-body"></span> <div id="map"></div> <div id="drop-container"><div id="drop-silhouette"></div></div> <script> <span class="metadata-marker" style="display: none;" data-region_tag="script-body"></span> /* Map functions */ var map; function initMap() { // set up the map map = new google.maps.Map(document.getElementById('map'), { center: new google.maps.LatLng(0, 0), zoom: 2 }); } function loadGeoJsonString(geoString) { var geojson = JSON.parse(geoString); map.data.addGeoJson(geojson); zoom(map); } /** * Update a map's viewport to fit each geometry in a dataset * @param {google.maps.Map} map The map to adjust */ function zoom(map) { var bounds = new google.maps.LatLngBounds(); map.data.forEach(function(feature) { processPoints(feature.getGeometry(), bounds.extend, bounds); }); map.fitBounds(bounds); } /** * Process each point in a Geometry, regardless of how deep the points may lie. * @param {google.maps.Data.Geometry} geometry The structure to process * @param {function(google.maps.LatLng)} callback A function to call on each * LatLng point encountered (e.g. Array.push) * @param {Object} thisArg The value of 'this' as provided to 'callback' (e.g. * myArray) */ 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); }); } } /* DOM (drag/drop) functions */ function initEvents() { // set up the drag & drop events var mapContainer = document.getElementById('map'); var dropContainer = document.getElementById('drop-container'); // map-specific events mapContainer.addEventListener('dragenter', showPanel, false); // overlay specific events (since it only appears once drag starts) dropContainer.addEventListener('dragover', showPanel, false); dropContainer.addEventListener('drop', handleDrop, false); dropContainer.addEventListener('dragleave', hidePanel, false); } function showPanel(e) { e.stopPropagation(); e.preventDefault(); document.getElementById('drop-container').style.display = 'block'; return false; } function hidePanel(e) { document.getElementById('drop-container').style.display = 'none'; } function handleDrop(e) { e.preventDefault(); e.stopPropagation(); hidePanel(e); var files = e.dataTransfer.files; if (files.length) { // process file(s) being dropped // grab the file data from each file for (var i = 0, file; file = files[i]; i++) { var reader = new FileReader(); reader.onload = function(e) { loadGeoJsonString(e.target.result); }; reader.onerror = function(e) { console.error('reading failed'); }; reader.readAsText(file); } } else { // process non-file (e.g. text or html) content being dropped // grab the plain text version of the data var plainText = e.dataTransfer.getData('text/plain'); if (plainText) { loadGeoJsonString(plainText); } } // prevent drag event from bubbling further return false; } function initialize() { initMap(); initEvents(); } </script> <script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initialize"></script> </body> </html>