I’m not a golfer. When I grew up, golf was a rich person’s game. Average Joes like me couldn’t afford to play golf. Things have changed. My boys are golfers. I’m just their geek dad, a Free Software nerd and OpenStreetMap obsessive who takes them places. Golf can still be a rich person’s game, but it doesn’t have to be. The rich kids just have more equipment.
One such piece of equipment is GPS assistance. A little custom-made gadget that knows about golf courses and the features and layout of each hole and assists with things like choosing your club and your line based on where you are and where you need to get to. This, to someone like me, sounds like a challenge. We have this data (or where we don’t, we can create it). So, ahead of the first round of the 2015 Derbyshire Futures Tour, I set about mapping the course.
Actually mapping the course, the holes and their features from the Bing imagery was a breeze. But when I got to thinking about how the software would work, I came up short. My idea was something like this:
- The golf club is represented by an area (
leisure=golf_course
;name=Name of Club
) - Each course at a club is represented by a relation (
type=golf_course
;name=Name of Club, Name of Course
). - The relation groups all the ways tagged
golf=hole
, and theref
tag on each way represents the hole number. - The tee boxes (
golf=tee
) and greens (golf=green
) are also tagged usingref
for the hole number. - Bunkers are tagged (
golf=bunker
,natural=sand
); water hazards (golf=water_hazard
;natural=water
); lateral water hazards (golf=lateral_water_hazard
;natural=water
); fairways (golf=fairway
); and woods (natural=wood
) and individual trees (natural=tree
). - Search for a course. This would search Nominatim or similar for relations of
type=golf_course
that closely match what the user searched for. This could even be automated as a first step, so the user just has to select the course from a list. - Download the data for the course, render it, show distance to the hole, recommended club, etc. Record strokes and distances. The sky’s the limit here.
But there’s a problem: tee boxes, fairways and greens are associated with a hole on a course, which is part of a club - but that’s not represented in the data. We only have a link from the course relation to its holes - there’s nothing linking a tee box to a hole or a green to a hole, and there’s nothing linking bunkers and trees to the course. Now for downloading the data, this is not necessarily a problem, as we can figure out the bounding box. But when it comes to “show me an overview of the first hole” then it becomes:
- Select the first item of
role=hole
in the relation. - Look at its
ref
tag. - Select all ways in our bounding box with the same
ref
tag (and probablygolf=tee
, etc.) - Figure out the hole’s bounding box.
- Select anything else in that bounding box.
- Render.
If instead we had a hierarchy of relations, we could do:
- Select the first item of
role=hole
in the relation. - Select the child relations for
role=tee
,role=fairway
,role=green
, etc. - Figure out the hole’s bounding box.
- Select anything else in that bounding box.
- Render.
It’s only one step less, but by iterating over the child relations, all the related ways are selected explicitly, rather than having to iterate over every way we’ve downloaded and discard most of them. I think this would make for more coherent data and more performant applications.