Country boundries using Google Map API v3

Solution 1:

See this similar question: Google Maps V3: Draw German State Polygons?

The Natural Earth Data Set in FusionTables has country polygons available in it. You can style them as you like.

I used it to create this example: http://www.geocodezip.com/v3_FusionTablesLayer_worldmap_linkto.html

Here is an example that uses a KmlLayer: http://www.geocodezip.com/v3_GoogleEx_layer-kml_world_countries_simple.html

code snippet:

var kmlLayer = null;
var map = null;

function openIW(layerEvt) {
  if (layerEvt.row) {
    var content = layerEvt.row['admin'].value;
  } else if (layerEvt.featureData) {
    var content = layerEvt.featureData.name;
  }
  document.getElementById('info').innerHTML = "you clicked on:<br>" + content;
}

function initialize() {
  var chicago = new google.maps.LatLng(36.4278, -15.9);
  var myOptions = {
    zoom: 0,
    center: chicago,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }

  map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

  google.maps.event.addListener(map, "click", function() {
    document.getElementById('info').innerHTML = "";
  });


  kmlLayer = new google.maps.KmlLayer('http://www.geocodezip.com/geoxml3_test/world_countries_kml.xml', {
    preserveViewport: true,
    suppressInfoWindows: true
  });
  kmlLayer.setMap(map);

  google.maps.event.addListener(kmlLayer, 'click', openIW);
}
google.maps.event.addDomListener(window, 'load', initialize);
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<table>
  <tr>
    <td>
      <div id="map_canvas" style="height:200px; width:300px;"></div>
    </td>
    <td>
      <div id="info"></div>
    </td>
  </tr>
</table>

Solution 2:

If you want more control over the displayed boundaries, I suggest using google.maps.Data layer instead of Fusion Tables. Fusion tables and Fusion Layer has their limitations, for example on the World Map in geocodezip's example you can see, that if you zoom out the map, the boundaries will collapse to points. With Data Layer you can style specific boundaries, or hide them. Fusion Layer allows only conditional style changes. You can also add your own click, mouseover, mouseout listeners, you can change the boundary layer on the fly and more. Of course sometimes Fusion Layer is better alternative, for example if you have data contained in Fusion Tables, but if you want more control Data Layer is more than worthy alternative.

In my next working example I show World Country and US States boundaries rendered using Data Layeras example. You can of course use your own boundary files. If you don't have GeoJson version available (only Shapefiles or KML files), you can convert them to GeoJson using utilities like mapshaper (simply run: mapshaper -i myshp.shp -o format=geojson out.geo.json)

var map = null;
  var my_boundaries = {};
  var data_layer;
  var info_window;

  //initialize map on document ready
  $(document).ready(function(){
  	var latlng = new google.maps.LatLng(40.723080, -73.984340); //you can use any location as center on map startup
  	var myOptions = {
  		zoom: 2,
  		center: latlng,
  		mapTypeControl: true,
  		mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
  		navigationControl: true,
  		mapTypeId: google.maps.MapTypeId.ROADMAP
  	};
  	map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
  	google.maps.event.addListener(map, 'click', function(){
  		if(info_window){
  			info_window.setMap(null);
  			info_window = null;
  		}
  	});
	
	$('#boundary_load_select').change(function(){
		if($(this).val()==1){
			loadBoundariesFromGeoJson("https://raw.githubusercontent.com/matej-pavla/Google-Maps-Examples/master/BoundariesExample/geojsons/world.countries.geo.json");
		}else{
			loadBoundariesFromGeoJson("https://raw.githubusercontent.com/matej-pavla/Google-Maps-Examples/master/BoundariesExample/geojsons/us.states.geo.json");
		}
	});
	loadBoundariesFromGeoJson("https://raw.githubusercontent.com/matej-pavla/Google-Maps-Examples/master/BoundariesExample/geojsons/world.countries.geo.json");
  });

  function initializeDataLayer(){
	if(data_layer){
		data_layer.forEach(function(feature) {
		    data_layer.remove(feature);
		});
		data_layer = null;
	}
	data_layer = new google.maps.Data({map: map}); //initialize data layer which contains the boundaries. It's possible to have multiple data layers on one map
  	data_layer.setStyle({ //using set style we can set styles for all boundaries at once
  		fillColor: 'white',
  		strokeWeight: 1,
  		fillOpacity: 0.1
  	});

  	data_layer.addListener('click', function(e) { //we can listen for a boundary click and identify boundary based on e.feature.getProperty('boundary_id'); we set when adding boundary to data layer
  		var boundary_id = e.feature.getProperty('boundary_id');
  		var boundary_name = "NOT SET";
  		if(boundary_id && my_boundaries[boundary_id] && my_boundaries[boundary_id].name) boundary_name = my_boundaries[boundary_id].name;
  		if(info_window){
  			info_window.setMap(null);
  			info_window = null;
  		}
  		info_window = new google.maps.InfoWindow({
  			content: '<div>You have clicked a boundary: <span style="color:red;">' + boundary_name + '</span></div>',
  			size: new google.maps.Size(150,50),
  			position: e.latLng, map: map
  		});
  	});
	
	data_layer.addListener('mouseover', function(e) {
		data_layer.overrideStyle(e.feature, {
			strokeWeight: 3,
			strokeColor: '#ff0000'
		});
	});
	
	data_layer.addListener('mouseout', function(e) {
		data_layer.overrideStyle(e.feature, {
			strokeWeight: 1,
			strokeColor: ''
		});
	});
  }

  function loadBoundariesFromGeoJson(geo_json_url){
	initializeDataLayer();
  	$.getJSON(geo_json_url, function(data){
  		if(data.type == "FeatureCollection"){ //we have a collection of boundaries in geojson format
  			if(data.features){
  				for(var i = 0; i < data.features.length; i++){
					var boundary_id = i + 1;
  					var new_boundary = {};
  					if(!data.features[i].properties) data.features[i].properties = {}; 
					data.features[i].properties.boundary_id = boundary_id; //we will use this id to identify boundary later when clicking on it
  					data_layer.addGeoJson(data.features[i], {idPropertyName: 'boundary_id'});
					new_boundary.feature = data_layer.getFeatureById(boundary_id);
  					if(data.features[i].properties.name) new_boundary.name = data.features[i].properties.name;
					if(data.features[i].properties.NAME) new_boundary.name = data.features[i].properties.NAME;
  					my_boundaries[boundary_id] = new_boundary;
  				}
  			}
			if(my_boundaries[24]){ //just an example, that you can change styles of individual boundary
				data_layer.overrideStyle(my_boundaries[24].feature, {
					fillColor: '#0000FF',
					fillOpacity: 0.9
				});
			}
  		}
  	});
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("maps", "3",{other_params:"sensor=false"});
</script>
<body style="margin:0px; padding:0px;" >
	<select id="boundary_load_select">
		<option value="1">Load World Boundaries</option>
		<option value="2">Load US States Boundaries</option>
	</select>
	<div id="map_canvas" style="height:400px; width:500px;"></div>
</body>