pgRouting / pgrouting

Repository contains pgRouting library. Development branch is "develop", stable branch is "master"
https://pgrouting.org
GNU General Public License v2.0
1.17k stars 367 forks source link

Add support for heading when defining start, end and via points #425

Open woodbri opened 8 years ago

woodbri commented 8 years ago

We need to be able to optionally define heading for start, via, and end points defining a route. The idea is that the route should try to approach/leave these points based on the best fit to the defined heading. Heading can be defined as postGIS st_azimuth() where 0=north, 90=east, etc.

The use case for this to control the direction a travel at these location to control which side of the vehicle is facing the curb. This is an important fact for vehicle routing in cases like: passenger or cargo pick and drop off to avoid crossing the street. Some vehicle like trash collection vehicles can only pickup containers on one side of the vehicle because of mechanism placement.

This would be particularly useful in combination with the turn restrictions to modal real world traffic networks.

woodbri commented 8 years ago

Also see #146

dkastl commented 8 years ago

Good idea with the heading. I first thought it's easier to specify the direction of the network link, but that's difficult when you start with a node.

cvvergara commented 8 years ago

@woodbri The feature request:

But for discussion purposes let's suppose its a new function pgr_withHeading Can you give a tentative signature for the input data?

woodbri commented 8 years ago

It is not a function it would be how we define our inputs. For example:

today we define start, end and vias like:

lat, lon 
vertex
edge, pos

and these could be extended to be:

lat, lon [, heading]
vertex [, heading]
edge, pos [, heading]

with the implication that at the location you would want to be moving in roughly the direction of heading. We might also want some helper functions like:

(edge, pos, heading) = pgr_edgePositionHeading(lat, lon, heading);

so for example if the lat,lon was between a dual highway going north-south, and the heading was 0.0, then it would pick the north bound lane and it the heading were 180.0 it would pick the south bound lane. We can use a heuristic like "order by delta_angle^2 + delta_dist^2 asc limit 1"where angle is degrees and dist is in meters to select the best edge. Another helper function that might be useful is:

angle = pgr_tangentHeading(edge, lat, lon);

that projects the point onto the edge and returns the tangent angle at that point on the edge. Think about a curved exit ramp.

woodbri commented 8 years ago

I know you do not like 'type's and removing them from the function outputs is fine and makes sense. But you can not pass a complex object into a function without declaring it as a type. So we are faced with:

some_function(lat, lon, heading)
some_function(lat[], lon[], heading[])

or using a type:

create type vertex_point (
   lat float8,
   lon float8,
   heading float8
);

some_func( var::vertex_point )
some_func( (lat, lon, heading)::vertex_point );
some_func( array[
  (lat, lon, heading),
  (lat, lon, heading),
  (lat, lon, heading) ]::vertex_point[] );
some_func( func_returning_vertex_point() );

this could also be extend to edge case like:

create type edge_point (
  edge_id bigint,
  position float8,
  heading float8
);

This is much more flexible and object oriented. Again the primary point of these types is for passing complex objects into function where there is not other easy modular way to do this.

Also, heading should be able to be null, and any function receiving one of these types should expect that unless there is a specific reason to enforce that it is not null for a specific function.

cvvergara commented 8 years ago

why not?

some_function( 'select lat, long, heading from edge_table')
cvvergara commented 8 years ago

Because I will be working on pgr_dijkstraViaVertex and pgr_dijkstraViaPoint, I am interested in this issue. but I will open another issue fore each one of them.

woodbri commented 8 years ago
some_function( 'select lat, long, heading from edge_table')

this is not passing an object or an array of objects. It is passing a text string that has to be executed in the function to get the data and do something with it. Data is not always in tables especially if you are writing plpgsql functions. For example, a user of a web application, selects various data points and information from a map, and makes an ajax request to manipulate that data ans return the results. You have 1000's of web users doing this. Do I have to create 1000's of tables to manage it, and so I can pass it to a function, or force my data into some huge awkward sql query to pass to a function?

Also, if I want to store my object in a table, I would pefer to store the object rather an decompose the object into individual columns. Especially, if I need to store and array of objects.

If I represent a route by a random collection of vertex_points, I would like to have:

create table routes (
   id serial,
   points vertex_points[],
   ...
);

Then I can recompute that path trivially by fetching the array points and passing it to the a function. Yes, I know I can do other things, after all it is just programming, but having written many production applications using this model for objects greatly improves readability, maintainability, and makes it fast to develop code.

So, Now that I have expressed why it is good, I think you need to express why you are trying to avoid types for object definition. I already agreed that it makes sense to remove it for function output, but this is a totally different use case.

I also think that there probably are only two types that are needed: 1) like vertex_point(lat, lon, heading) and 2) edge_point(edge_id, position, heading), and heading can be null which would default to the current behavior.

cvvergara commented 8 years ago

so, I am a user: I click on a map 4 times, that gives (lat,lon,heading) for each point,

cvvergara commented 8 years ago

The wiki for this topic by @woodbri https://github.com/pgRouting/pgrouting/wiki/Defining-Vias-with-%28Loc-or-Vertex-or-Edge%29-and-Heading

cvvergara commented 8 years ago

@woodbri Please tell when you are done, so comment can be aftr looking at the whole picture.

cvvergara commented 8 years ago

353 have some comments about "direction"