The Making of the “Where to Vote Green” Tool

After I built the Find your Green Candidate tool a couple of weeks ago, the next step was to expand this into a full-fledged Where to Vote Green tool (or, if you prefer, Où voter Vert).

From building the candidate-finder I already had a ready-made source of information about which civic addresses on Prince Edward Island are in which electoral districts and polls; because I wanted to be able to provide driving directions to polling stations, I added a latitude and longitude column to this table so that, for each address, there’s a row that include street number, street name, community, district, poll and geolocation:

Detail from civic address database showing new latitude and longitude columns

Next I needed information on the advance and regular polling stations for each of the 240 polling divisions. Finding no open data source for this information, I manually mangled the Elections PEI 2019 Provincial General Election Polling Location page into a database table. Because the civic addresses on that page were in various formats, I had to do some manual normalization, looking up each civic address in the civic address database, and transcribing the proper address, latitude and longitude for each (some districts use the same polling station for every poll, so, thankfully, I didn’t have to do this 240 times).

Once I’d done this, I had a complete record for each poll; here’s the data for my own poll, District 12, Poll 6, for example:

  • District Number: 12    
  • District Name: Charlottetown — Victoria Park    
  • Poll Number: 6    
  • Poll Name: DORCHESTER    
  • Advance Poll Location: Charlottetown Event Grounds    
  • Advance Poll Address: 360 GRAFTON ST, CHARLOTTETOWN    
  • Advance Poll Geolocation: 46.24121, -63.11709
  • Regular Poll Location: Central Christian Church
  • Regular Poll Address: 223 KENT ST, CHARLOTTETOWN    
  • Regular Poll Geolocation: 46.23809, -63.12490

There’s 2,400 pieces of information altogether, and it all needed to be double-checked against Elections PEI’s data; fortunately there was a volunteer down at HQ who was able to apply a second pair of eyes to this.

With all that I had everything I needed to create a tool to allow voters to enter their civic address and get information about their candidate: the rest of the work involved designing the tool itself, ensuring that it works on both desktop and mobile, ensuring it’s fast enough to be useful, and that the results are presented clearly.

The tool works by watching the address field for the “keyup” event, and sending the current contents of the field to an API I created to look up the address; the API returns the first 4 civic addresses that match what it receives, as a chunk of HTML; for example, it the API receives 100 PRINCE it returns:

<ul id="addresslist"><li class="oneaddress" id="eyJzdHJlZXRfbm8iOiIxMDAiLCJzdHJlZXRfbm0iOiJQUklOQ0UgU1QiLCJjb21tX25tIjoiQ0hBUkxPVFRFVE9XTiIsImxhdGl0dWRlIjoiNDYuMjM1ODQiLCJsb25naXR1ZGUiOiItNjMuMTI0MDgiLCJkaXN0X25vIjoiMTIiLCJkaXN0cmljdCI6IkNoYXJsb3R0ZXRvd24gLSBWaWN0b3JpYSBQYXJrIiwicG9sbF9ubyI6IjYiLCJjYW5kaWRhdGUiOiJLYXJsYSBCZXJuYXJkIiwidXJsIjoiaHR0cHM6XC9cL3d3dy5ncmVlbnBhcnR5LnBlLmNhXC9rYXJsYWJlcm5hcmRfZDEyIiwicGhvdG8iOiJzbWFsbGVyX2thcmxhX2Jlcm5hcmQucG5nIiwiYWR2YW5jZSI6IkNoYXJsb3R0ZXRvd24gRXZlbnQgR3JvdW5kcyIsImFkdmFuY2VfYWRkcmVzcyI6IjM2MCBHUkFGVE9OIFNULCBDSEFSTE9UVEVUT1dOIiwiYWR2YW5jZV9sYXRpdHVkZSI6IjQ2LjI0MTIxIiwiYWR2YW5jZV9sb25naXR1ZGUiOiItNjMuMTE3MDkiLCJwb2xsaW5nIjoiQ2VudHJhbCBDaHJpc3RpYW4gQ2h1cmNoIiwicG9sbGluZ19hZGRyZXNzIjoiMjIzIEtFTlQgU1QsIENIQVJMT1RURVRPV04iLCJwb2xsaW5nX2xhdGl0dWRlIjoiNDYuMjM4MDkiLCJwb2xsaW5nX2xvbmdpdHVkZSI6Ii02My4xMjQ5MCJ9">100 PRINCE ST, CHARLOTTETOWN</li></ul>

The HTML ID of each list item returned is a base64-encoded JSON object of all the information we need to display for that address; in this case, base64-decoding the ID returns:

{
  "street_no": "100",
  "street_nm": "PRINCE ST",
  "comm_nm": "CHARLOTTETOWN",
  "latitude": "46.23584",
  "longitude": "-63.12408",
  "dist_no": "12",
  "district": "Charlottetown - Victoria Park",
  "poll_no": "6",
  "candidate": "Karla Bernard",
  "url": "https://www.greenparty.pe.ca/karlabernard_d12",
  "photo": "smaller_karla_bernard.png",
  "advance": "Charlottetown Event Grounds",
  "advance_address": "360 GRAFTON ST, CHARLOTTETOWN",
  "advance_latitude": "46.24121",
  "advance_longitude": "-63.11709",
  "polling": "Central Christian Church",
  "polling_address": "223 KENT ST, CHARLOTTETOWN",
  "polling_latitude": "46.23809",
  "polling_longitude": "-63.12490"
}

(I base64-encode the object not for obfuscation nor network efficiency, but simply because it’s a handy way of moving the JSON back and forth packed inside a string; there are, I’m certain, much better ways of doing this).

When the voter clicks on one of the list items, the JSON gets used to display the information in a readable format.

You can see this all in operation in this short video clip (or you can try the tool out for yourself!):