To use this example, drag and drop a GeoJSON file or files from your computer on to the map above. You can also drag text or HTML GeoJSON content from another website or from the sample below.
View this example full screen or check out the reference documentation for google.maps.Data.
/* Map functions */
var map;
function initMap() {
// set up the map
map = new google.maps.Map(document.getElementById('map-canvas'), {
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-canvas');
var dropContainer = document.getElementById('drop-container');
// first on common events
[mapContainer, dropContainer].forEach(function(container) {
container.addEventListener('drop', handleDrop, false);
container.addEventListener('dragover', showPanel, false);
});
// then map-specific events
mapContainer.addEventListener('dragstart', showPanel, false);
mapContainer.addEventListener('dragenter', showPanel, false);
// then the overlay specific events (since it only appears once drag starts)
dropContainer.addEventListener('dragend', hidePanel, 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;
}
google.maps.event.addDomListener(window, 'load', function() {
initMap();
initEvents();
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<title>Drag and Drop GeoJSON</title>
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0; overflow: hidden; }
#map-canvas { 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>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<script type="text/javascript">
/* Map functions */
var map;
function initMap() {
// set up the map
map = new google.maps.Map(document.getElementById('map-canvas'), {
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-canvas');
var dropContainer = document.getElementById('drop-container');
// first on common events
[mapContainer, dropContainer].forEach(function(container) {
container.addEventListener('drop', handleDrop, false);
container.addEventListener('dragover', showPanel, false);
});
// then map-specific events
mapContainer.addEventListener('dragstart', showPanel, false);
mapContainer.addEventListener('dragenter', showPanel, false);
// then the overlay specific events (since it only appears once drag starts)
dropContainer.addEventListener('dragend', hidePanel, 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;
}
google.maps.event.addDomListener(window, 'load', function() {
initMap();
initEvents();
});
</script>
</head>
<body>
<div id="map-canvas"></div>
<div id="drop-container"><div id="drop-silhouette"></div></div>
</body>
</html>