linked
linked

Reputation: 1278

Google Maps with counties overlay?

I have no experience working with Google Maps, but I'd like to embed a "Choose your county" map in my webapp. My app only targets California, so it only needs to support one state, but I can't find any easy way to do this (without manually drawing overlay polygons for all the county lines).

I assumed I'd easily be able to find examples of "Choose your county"-style interfaces on Google somehow, but the only thing I found was this -- http://maps.huge.info/county.htm -- and I'm leaning towards hitting their API to pull the geometry for the whole state if I can't find a better option.

Does anyone have any experience or insight to help make this a little easier?

Upvotes: 20

Views: 34121

Answers (3)

IdusOrtus
IdusOrtus

Reputation: 1136

Update: Google Maps for JavaScript API can now easily import geoJSON data and there is at least one online tool for converting shapefiles to geoJSON format. Shapefiles for counties can be obtained for $0.00 from many sources online, including the US Census Bureau.

<!doctype html>
<!--
 @license
 Copyright 2019 Google LLC. All Rights Reserved.
 SPDX-License-Identifier: Apache-2.0
-->
<html>
  <head>
    <title>Data Layer: Counties</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <link rel="stylesheet" type="text/css" href="./gmap-counties.css" />
    <script type="module" src="./gmap-counties.js"></script>

  </head>
  <body>
    <div id="map" style="width:50%;height:50%"></div>

    <!-- 
   https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=---------&callback=initMap"
      defer
    ></script>
  </body>
</html>
/**
 * @license
 * Copyright 2019 Google LLC. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */
let map;

function initMap() {
  map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: { lat: 43.87, lng: -91.22 },
    disableDefaultUI: true,
    mapId:'15ee2ec694f3133q', //optional
  });
//   // NOTE: This uses cross-domain XHR, and may not work on older browsers.
//   map.data.loadGeoJson(
//     "https://storage.googleapis.com/mapsdevsite/json/google.json",
//   );
// // Load GeoJSON from local file
// map.data.loadGeoJson('./data/counties.geojson');

  // Load GeoJSON & apply styling
  map.data.loadGeoJson('./data/counties.geojson', null, function(features) {
    // Styling for the GeoJSON layer
    map.data.setStyle({
      fillColor: '#FED8B1',
      strokeColor: 'red',
      strokeWeight: 0.05
    });
  });
}

window.initMap = initMap;  

Link to Gist for counties data if you don't want to bother with conversion ->

./data/counties.geojson

Include the following CSS to hide the buttons at the bottom right of the map.

.gm-style-cc {
  display: none;
}

Upvotes: 0

Daniel Vassallo
Daniel Vassallo

Reputation: 344511

The Google Maps API does not provide county polygons, or any other predefined borders of states or countries. Therefore the main issue here is obtaining the polygon data.

A polygon on the Google Maps API is defined by constructing an array of LatLng objects (assuming you're using the v3 API):

var bermudaTriangleCoords = [
  new google.maps.LatLng(25.774252, -80.190262),
  new google.maps.LatLng(18.466465, -66.118292),
  new google.maps.LatLng(32.321384, -64.757370),
  new google.maps.LatLng(25.774252, -80.190262)
];    

Then you would use this array to construct a Polygon object:

var bermudaTriangle = new google.maps.Polygon({
  paths: bermudaTriangleCoords,
  strokeColor: '#FF0000',
  strokeOpacity: 0.8,
  strokeWeight: 2,
  fillColor: '#FF0000',
  fillOpacity: 0.35
});

And finally show it on the map by calling the setMap() method:

bermudaTriangle.setMap(map);    // Assuming map is your google.maps.Map object

If you keep a reference to your Polygon object, you can also hide it by passing null to the setMap() method:

bermudaTriangle.setMap(null); 

Therefore you could consider building a JavaScript object with a property name for each county. This will allow you to fetch the polygon objects from the name of the counties in O(1) (constant time), without having to iterate through all the collection. Consider the following example:

// Let's start with an empty object:
var counties = {    
};

// Now let's add a county polygon:
counties['Alameda'] = new google.maps.Polygon({
  paths: [
    // This is not real data:
    new google.maps.LatLng(25.774252, -80.190262),
    new google.maps.LatLng(18.466465, -66.118292),
    new google.maps.LatLng(32.321384, -64.757370),
    new google.maps.LatLng(25.774252, -80.190262)
    // ...
  ],
  strokeColor: '#FF0000',
  strokeOpacity: 0.8,
  strokeWeight: 2,
  fillColor: '#FF0000',
  fillOpacity: 0.3
});

// Next county:
counties['Alpine'] = new google.maps.Polygon({
  // Same stuff
});

// And so on...

The counties object will be our data store. When a user searches for "El Dorado" you can simply show the polygon as follows:

counties['El Dorado'].setMap(map);

If you keep a reference to the previously searched county, you can also call setMap(null) to hide the previous polygon:

var userInput = 'El Dorado';
var latestSearch = null;

// Check if the county exists in our data store:
if (counties.hasOwnProperty(userInput)) {
  // It does - So hide the previous polygon if there was one:
  if (latestSearch) {
    latestSearch.setMap(null);
  }
  // Show the polygon for the searched county:
  latestSearch = counties[userInput].setMap(map);
}
else {
  alert('Error: The ' + userInput + ' county was not found');
}

I hope this gets you going in the right direction.

Upvotes: 36

RedPeasant
RedPeasant

Reputation: 544

Google Fusion Tables now links to State, County, and Congressional District data for all of the US.

The geometry field of the fusion table contains a Polygon element for the given object. Their state boundaries polygons (and to a lesser extent the counties) look a little low resolution in a few places, but it may be good enough for you and should be relatively easy to grab.

Upvotes: 18

Related Questions