Map hard, map fast.
For our third Hackathon, we focused on our map and place data. One of the projects has already made its way to production: standardizing place name casing and address formatting. We think the rest will find their way shortly with a bit more polish.
Neighborhoods and Region Highlighting
Regions have always been a big part of our map, but they have traditionally been political—countries and states. We’ve recently added support for non-political regions—e.g. “Cape Cod” or “Florida Keys” or “Route 66”—and decided to take a look at how easily we could add neighborhoods. We were able to find Cincinnati neighborhood shape data at CAGIS and put together a
rake task that pulls that data down, imports it, and makes it a searchable region.
I’ve also always wanted to be able to highlight regions on the map, so that searching for a region would present the region with a visual boundary. It turns out this plays very nicely with neighborhood regions. Once a region is activated via our map search, we drop a multipolygon representing the neighborhood on the map and apply a filter to the active search to only return results inside that multipolygon.
You can see highlighting of states, parks, and tourism regions in action in the below screencast.
And here’s an example with experimental neighborhood data.
One of the primary factors we consider when returning results in our map search and POI discovery is engagement—how often our users visit or rate places. In general this has worked very well for us as it ensures we’re surfacing high-interest POIs. However, one place this practice doesn’t always work well is when we surface POIs along a trip route that contains waypoints that are high-engagement cities, e.g. San Francisco to Los Angeles. We wanted to find a way to reduce the “barbell effect,” in which the POIs return along the route are clustered in those high-engagement cities, in order to surface places along the route. So we found a way.
Our first cut at improving POI spread breaks up the polyline that represents trip route into five segments. We then generate a polygon for each of those segments by calculating the general slope of the segment, determining the rough angle for the segment, and extrapolating the points that would appear at the edge of the polygon were we to buffer out the entire polyline. We then take advantage of Elasticsearch’s
msearch to perform all the queries at once. You can see this in action in the below screencast. The browser on the left is our production site; the browser on the right is a staging environment the “spread” fix.
We have long supported the geolocation API so users can find themselves on the map, start a trip from wherever they are, etc. Unfortunately, using the geolocation API isn’t always the best experience—it’s a three-step process: the user clicks a geolocation button, we ask for permission, then update the UI if the user grants permission.
In order to get this down to a no-step process with zero interaction from the user, we took a swing at using an IP geolocation DB to infer where a user is located. We got the IP address’ geolocation, then did a quick query against our DB to find the nearest large population center. We were quickly able to put this to use, pre-filling our Welcome Launcher and map state URLs. We’ve got more than a few others ideas on how we can utilize this.
R.I.P. Pin Sprites
We currently use two image sprites for our map pins: one for our “large” category and waypoint pins and another for our small pins. Our UI developer, Chris, has had his eyes on Mapbox’s divIcon for a while, so we let him loose. By the end of the day, he had most of our pins rendered with markup, an SVG, and some CSS. With a bit more refactoring and polish, this will free us up to do things with our map pins like badging, dynamic iconography, and a million other things that have made us say “Wouldn’t it be nice…” Our Long Internal Nightmare of being restricted by an image sprite will soon be over.