ByteMuse.com

The code and musings of @ChrisPolis

About Posts Contact

How Centrally Located are U.S. State Capitals?

April 16th, 2014

There are lots of interesting Voronoi diagrams floating around the internet. This one shows redrawn state borders as a function of their capitals. This got me to thinking - how centrally located are state capitals?


Capitals are BLACK · Geographic centers(centroids) are GREEN · Population centers are RED
Sacramento, CA: 123.6 Mi to Chowchilla · 246.1 Mi to Shafter

View Source Hide Source

#
buildMap = (error, stateData, centerData) ->
  width  = $('.container').width()
  height = width * 0.6
  ptRad  = if width > 500 then 2.5 else 1.5

  #
  for state in centerData
    state.capital  = [parseFloat(state.cap_long), parseFloat(state.cap_lat)]
    state.pop_cen  = [parseFloat(state.pop_long), parseFloat(state.pop_lat)]
    state.geo_cen  = [parseFloat(state.cent_long), parseFloat(state.cent_lat)]
    state.pop_dist = d3.geo.distance(state.capital, state.pop_cen) * 3959
    state.geo_dist = d3.geo.distance(state.capital, state.geo_cen) * 3959
    state.feature = stateData.features.filter((d) ->
      d.properties.name == state.state)[0]

  #
  projection = d3.geo.albersUsa()
    .scale     width * 1.3
    .translate [width/2, height/2]
  path = d3.geo.path().projection(projection)

  #
  svg = d3.select('#capitals-vis').append('svg')
    .attr 'width', width
    .attr 'height', height
  states     = svg.append('g').attr('id', 'states')
  capitals   = svg.append('g').attr('id', 'capitals')
  geoCenters = svg.append('g').attr('id', 'geo-centers')
  popCenters = svg.append('g').attr('id', 'pop-centers')
  popPaths   = svg.append('g').attr('id', 'pop-paths')
  geoPaths   = svg.append('g').attr('id', 'geo-paths')

  #
  states.selectAll('path')
    .data(centerData)
    .enter().append('path')
      .attr 'd', (d) -> path(d.feature)
      .on 'mouseover', (d) ->
        d3.select('.state-name').text "#{d.cap_name}, #{d.abbrev}:"
        d3.select('.geo-center').html "<b>#{d.geo_dist.toFixed(1)} Mi</b> to #{d.cent_name}"
        d3.select('.pop-center').html "<b>#{d.pop_dist.toFixed(1)} Mi</b> to #{d.pop_name}"
  popPaths.selectAll('path')
    .data(centerData).enter()
    .append('path')
      .attr 'd', (d) ->
        path
          type: 'LineString'
          coordinates: [d.capital, d.pop_cen]
  geoPaths.selectAll('path')
    .data(centerData).enter()
    .append('path')
      .attr 'd', (d) ->
        path
          type: 'LineString'
          coordinates: [d.capital, d.geo_cen]

  #
  capitals.selectAll('circle')
    .data(centerData).enter()
    .append('circle')
      .attr 'cx', (d) -> projection(d.capital)[0]
      .attr 'cy', (d) -> projection(d.capital)[1]
      .attr 'r', ptRad
  geoCenters.selectAll('circle')
    .data(centerData).enter()
    .append('circle')
      .attr 'cx', (d) -> projection(d.geo_cen)[0]
      .attr 'cy', (d) -> projection(d.geo_cen)[1]
      .attr 'r', ptRad
  popCenters.selectAll('circle')
    .data(centerData).enter()
    .append('circle')
      .attr 'cx', (d) -> projection(d.pop_cen)[0]
      .attr 'cy', (d) -> projection(d.pop_cen)[1]
      .attr 'r', ptRad

queue()
  .defer d3.json, '/us_states.json'
  .defer d3.csv , '/state_centers.csv'
  .await buildMap


Data compiled from US Census Bureau (2010 data), Wikipedia.
Nearest towns calculated with Ruby geocoder gem and Google Geocoding API. View data.


Tweet
Capitals preview

© Chris Polis, 2012 - 2016

GitHub · Twitter · LinkedIn · Stack Overflow · Quora