Find the nearest point on a road from a specific address in Ruby and show in Google map

Ly Channa
3 min readJun 15, 2019

Last weekend I was exploring a solution to a daily problem of one of my friends to see how can technology help make life easier.

If you happen to travel from city to city using public transportations and you are not at the edge of where the fleet departs, you might have the same issue as him.

To show the problem better, let’s assume Mr. Jorge’s location is represented in the map as a person marker. The pink line string in the map shows the road where the fleet travels, and the direction of travel is from Top (Phnom Penh, the capital of Cambodia) to Bottom (“Kampot” just another city). We will solve the problem by coordinating both driver and Jorge a consensus point where the two can find each other — Jorge will be suggested to go and wait and point B (on the road ) and the driver knows that he will need to pick Jorge up at point B too.

There is a solution in some of Geospatial databases, for example in PostGIS, but it does not fit 100% to the problem and the data is loaded in memory making calculation with programing( I use Ruby in this case ) more ideal.

You can find something similar in PostGIS’s here: https://postgis.net/docs/ST_ClosestPoint.html

Identifying inputs

Before solving the problem let’s assume the following:

  • We have data to draw line string as a route on the map from Phnom Penh to Kampot. The data is a set of points(lat, lon) — an array of point
  • The locations of users ( in this case just Jorge’s location ) — a point
  • We need some routing API to make a real distance and travel time for Jorge — technically we can calculate the point on the road that is the shortest line from Jorge to the road but in reality, Jorge will not be able to travel from his current point by straight line
  • Instead of routing users from his address to the point of a straight line on the road, we need to find point B where travel duration and time are more convenient for Jorge.

In the end result, point B will be suggested for both Jorge and the driver.

Requirements

  • Rubyonrails ( but can be ruby with any other frameworks, or even with other programming languages)
  • Lib geos. Geos is the defacto geometry lib written in C++ that powers most of the geo operation in many engines including PostGIS.
  • Ruby gem ‘rgeo’ and ‘ffi-geos’ that allow us access communicate to geos lib.
  • Google API key that is map and routing enable.
  • The points that form line string for the road that the fleet supposes to travel on.
  • One or more locations of user to route to the road.

Full source code can be found here: https://gist.github.com/channainfo/05bf1d9c7beccdf87cb29b7b1ba6def2

Conclusion

Doing geometry operation with geos is straight forward and not required to use PostGIS. There are a lot of things that can be done with Geos.

From this problem, the solution above can be applied to other use cases like GPS coordination adjustment to fix the wrong GPS precision ( Well known as snap to road).

The driver can coordinate with his passengers in a more predictable and efficient in terms of cost and time. For the passengers side, it eliminates the burden of informing the driver and making his trip more pleasant and predictable. Jorge will be happier to travel via public transportations.

If you have any other use cases please share. Let’s get right on this.

--

--

Ly Channa

Highly skilled: REST API, OAuth2, OpenIDConnect, SSO, TDD, RubyOnRails, CI/CD, Infrastruct as Code, AWS.