rubypostgisgeosrgeo

How to find the Closest point of a line string to a given location - rgeo


My point coordinates are in geographic coordinate systems. They are in memory. I need to find the nearest point on the line string to a given point using RGeo library from Ruby.

My scenario is the points are drawn in googlemap as polyline as road representation, and the location is the position of my vehicle. I need a shortest way to reach the road.

There are solutions in PostGIS but my data is in memory and I don't want to use Postgresql to serve just for this purpose.

I am checking RGeo gem but could not find any clue related to this.

[Edited]

enter image description here

enter image description here

Ref: https://postgis.net/docs/ST_ClosestPoint.html


Solution

  • It's described in details here: https://groups.google.com/forum/#!topic/rgeo-users/e1FgzpPISs8

    # Create a Geos factory that uses the ffi interface
    factory = RGeo::Geos.factory(:native_interface => :ffi)
    
    # Create your polyline and point A using that ffi-backed factory.
    # You can create the objects directly using the factory, or cast objects to the
    # factory, whatever is the easiest way for you to get objects that are attached
    # to the ffi factory.
    polyline = factory.line_string( ... )
    point = factory.point( ... )
    
    # Objects that are attached to an ffi-geos factory provide access, via the
    # fg_geom method, to low-level objects that understand the ffi-geos api.
    # This is not really documented well, but it's a stable api that you can use.
    low_level_polyline = polyline.fg_geom
    low_level_point = point.fg_geom
    
    # Now invoke the low-level libgeos calls.
    # This first method, "project", gives you the distance "along" the linestring
    # where it comes closest to the given point.
    dist = low_level_polyline.project(low_level_point)
    # This second method, "interpolate", takes a distance "along" the linestring,
    # and returns the actual point on the linestring.
    low_level_closest_point = low_level_polyline.interpolate(dist)
    
    # Finally, wrap the low-level result in an RGeo point object
    closest_point = factory.wrap_fg_geom(low_level_closest_point)