Each year Entelect hosts a pretty cool year-end function for all the staff. They find a venue that can accommodate the whole company and then spend lots of dosh on catering, drinks and activities. They go all out and really try make it fun day for everyone with various activies like mini golf, massages, water slides, board games, driving range etc. However they never tell anyone where it is!!
As part of the surprise and to keep people safe they strongly encourage the use of the busses provided to get the people to the venue from our various offices and other public points. Keeping the venue a secret also discourages people from driving because they can’t plan for the day, but I always like to know where I am going! The Social Committee does publish the locations of where the busses will leave from (and return to) as well as the estimated distances from each location to the venue. This allows people to plan their day and manages expectations. It also allows me to guess the location! (Insert evil laugh here!!!)
Using this distance information as well as the company size, some social engineering and previous experience of what Entelect likes to do, I try and narrow down the list of possible venues. My first attempt was in 2014 and while I didn’t manage to find the venue, I guessed the general area correctly. For the 2014 attempt I spent most of my budgeted time learning the Google Maps API, how mapping applied to geography and coming up with an algorithm to create driving distance polygons.
For the first pass I used the provided distance to generate circles around each starting location. Then I divided up those circles in degrees of arc, and the more segments I created the more accurate the final picture would be. I usually started with 0, 30, 60, 90 …. all the way to 360 degrees. On each of these angles I can draw a line from the start point to the circumference of the circle as the crow flies. These are the radius lines on which to calculate the routes.
Using each of these radius lines of the circle, I would then get the Directions API to provide the driving directions from the start location to the point on the circumference of the circle in line with this arc radius - call this the Circle Endpoint.
The route returned would include a total driving distance.
- If this distance was over the quoted distance, I would then choose a new route endpoint that was the midpoint between the start location and the Circle Endpoint.
- If this distance was too short compared to the quoted distance, I would then choose a new route endpoint that was between the current route endpoint and the Circle Endpoint.
I would continue this process until I had narrowed down the driving distance to within a few percentage points of the quoted distance or until I had exceeded a set number of attempts. Then I would move on to the next angle in the circle until I had completed the full circle.
At the end of the process I would be left with a series of end points all hopefully near to the quoted distance. Joining these points in order of angle produces a driving distance polygon for this start location. Repeating the process for each start location allows me to create multiple overlapping polygons which provides a smaller area (and more accurate) for me to search.
In 2014 I only had 2 starting points but I knew the rough direction of where we were going, based on some initial assumptions. After the day I plugged in the coordinates that were SMSed to the people driving to the venue (the yellow point in the simulation) and I think I got pretty close!
By the time of 2015 YEF Entelect had gotten bigger which meant more buses and 4 starting points. I also had some insider knowledge that there would be water activities so I focused on areas that had rivers or dams near them.
I improved on the 2014 efforts to allow specifying the angle increment between start and end angles, which allowed more radius lines in areas of interest. Since the Directions API is limited (at the time of writing, 2500 requests per day) I had to find a way to save results after each run. I added some hacky options to allow saving the generated data so I could run the polygon generation in batches, and then reload the full polygon afterwards.
For the 2015 efforts I also had to contend with biased distance information, as the Social Committee had decided it was no fun if someone guessed the location! After much trial and error (and some snooping he he he), I managed to narrow it down to 3 possible locations (the 3 yellow points on the map), which I provided to the Committee.
Shown below is the The Waterfront Country Lodge (also trading as the Vaal River Country Lodge), with a 2.5 radius yellow circle around it.
The points listed have the following distance measurements:
- HQ: quoted: 87 km, actual: 86.97 km
- Clearwater Mall: 84 km, actual: 85.196 km
- Centurion Mall: 128 km, actual: 126.488 km
That seems pretty close hey? On the day it turned out I was correct! And boy it was a good party!
When the 2016 YEF rolled around I was ready. I was prepared. I was going to win again! I started with the rough polygon generation and based on previous years narrowed my search down to somewhere near or around Hartbeespoort. I then started increasing the angle of resolution in the direction of Hartbeespoort, and upgraded the viewer with a bunch of tweaks. I added separate colours for each polygon, so as to see the overlap better, as well as better saving of the generated data. At the same time I wanted to try a different web/UI library so I added the Foundation framework.
I also cleaned up the code quite a bit and refactored out the MapApp related functions as I wanted to now check the validity of my guesses. I added a function to check the route distances and created the tables showing the quoted vs actual distance for each start point/possible venue pair.
I shared my first 3 guesses around Hartbeespoort with the Social Committee and got a “Thanks for trying, but NO!” for my efforts. And then a little bird whispered in ear that the venue was around Bronkhorstspruit. Cue frantic coding, polygon changes and googling from me to find possible locations. But to no avail… These 3 locations were also a dud. At that point I had run out of time to find the venue, and when the day of the YEF arrived I was a bit disappointed that I had not managed to locate the venue. However it turns out my initial guesses were in very close proximity. One crucial mistake I made was only considering places that had rivers or dams nearby, when I should have considered the possibility of swimming pools as well!
In writing this blog post I tightened up the raw data, re-worked the display a bit and added in the venue as a estimated location. Working back from the known location, I can see that I wasn’t too far off, and I think this method has definite viability in the future. However it helps if you are not deliberately misled! :)
The distances below vary too much for me to be confident that I was given original data!
For 2017 I will be ready and waiting! Some future features would be to highlight the rows in the distance tables to indicate which locations are within range or not, and even perhaps to try include Google Places API to try and provide possible locations in the area. At some point in the future I would like to turn some of these ideas into an actual application. I think there is real value for various people in being able to generate driving distance polygons from different locations, for instance franchise stores planning on where to open their next store.
If you have any comments, feedback or questions please get in touch.