This example allows you to drag and drop either a GeoJSON file or a selection of GeoJSON text onto the map.
For more information about how to work 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; background-color: rgba(100, 100, 100, 0.5); } #drop-silhouette { color: white; border: white dashed 8px; height: calc(100% - 15px); width: calc(100% - 15px); 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>
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;
background-color: rgba(100, 100, 100, 0.5);
}
#drop-silhouette {
color: white;
border: white dashed 8px;
height: calc(100% - 15px);
width: calc(100% - 15px);
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>
<div id="map"></div>
<div id="drop-container"><div id="drop-silhouette"></div></div>
<script>
/* 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>