2

I'm wondering if there is any suitable algorithm that can I use to calculate line complexity index (or indicator)? By "line complexity" I mean how many bends (direction changes) that line contains and how sharp they are.

I want to use that index to correct driving speed of road network segments. Lots of road segments in my dataset have speed defined according to road type, which is not even close to the real achievable speed. For example, mountain pass road has a speed limit of 90kph, but in real life, 60kph is more realistic due to curvature of that road.

I'm primarily interested in a solution for PostGIS/PostgreSQL.

The best solution i have come up so far is something like this:

st_area(st_polygonize(st_union(st_simplify(geom, 10), geom)) / st_length(geom)

It calculates how much space (area) per unit of length is between the original and simplified version of geometry. Bigger index means more complex shape, thus bigger speed penalty. Simplification threshold (10 in my example) was chosen by trial and error, also how it will be applied to adjust speed is not clear at this point.

Is this feasible, or is there a better approach?

  • 1
    You could compare line length to euclidian distance from startpoint to endpoint. But that might be over simplifying it – BERA Sep 12 at 8:12
  • I don't have a solution, but maybe an idea to build on if you would also be willing to work with QGIS: you could try to measure angles at each vertex with the expression-editor and the angle_at_vertex function. You could add all the values (be aware how to deal with positive and negative values) and relate the result to the total length. Like this you get a measure for the sinuosity of the road. Of course, you could simple calculate the proportion of total road-length to the length of a straight line from the beginning to the end (first to last vertex) of your line. – babel Sep 12 at 8:12
  • And still another approach, depending on how detailed your data is: simply count the number of vertices (per distance): a straight-line section will contain much less vertices than a curved road. For other solutions, google for sinuosity and the tool you want to use (i.e. PostGIS/PostgreSQL) – babel Sep 12 at 8:19
  • as an addition to the sinuosity; you should be able to use ST_SetEffectiveArea to derive statistics about a lines per-vertex curvature; it's a common simplification method, but it's values can be used to measure curvature properties. – ThingumaBob Sep 12 at 9:36
1

I don't know a simple way to do this, you will need extra step. The first step would be to brake your line into parts that are in the same direction (left or right angles). Then for each of your parts you can assesed its "complexity" for exemple by comparing its length to the length of the line first_point - last_point (I've seen a paper that called that "move ability" but in a different context). Finally the idea is to combine the complexities of the parts factor their length to get the complexity of the whole line.

But of course you also need to take into account the junction between the parts. But that's not the main problem, you need to be more precise. If you have a very big curve maybe you will go back near your start in the end and have a very bad "complexity" but at a normal speed it will easily pass without slowing down.

So in fact, because you care about the speed in curve, what's you actually interested in is more lateral acceleration. If you fix a realistic lateral acceleration for a normal car (let's say 300 mG, it's not a max but something everybody do) it would correspond at 90km/h at 13.48° in your road. So if you have a sharper road, you can predict that you will need to be slower. So in fact, if you look at the nodes of your lines, and you get the angle, with some formula you can get the maximum speed you can go to your realistic lateral acceleration.

Of course it's a little more complicated because between nodes there is a segment a straight line, so you need to take that into account too. Typically you should cut long segments like that to be sure that you will not consider a segment as a curve (and say you will be slow on it) where it's actually a kilometer long straight line. And to be really precise the way you cut it should take into account the expected speed here (the speeder you go the longer your segment parts would be).

As you can see, this is a complicated problem that needs a dedicated study. I've done a version of it that suited my needs, and the result is more than a thousand lines of SQL (it does some other thinks too, and that's for a whole country, but that's the main objective). It depends on how precise you want to be. The main thing to remember is that it's not only a geometry problem, because it also depend of the scale of the road (versus the speed you want to go on it). The same angle does not mean the same speed if you multiply your segments size by two. The lateral acceleration is actually what you try to predict here, so a general geometry index will always be at best biased.

  • Great insight into that problem, thanks! I want to find driving time for N closest police patrols. It is not necessary to be super accurate, it serves only as a hint to the operator which one patrol to pick for a current event, which (to be honest) is picked by "feel" for most of the time. Operators know their areas the best, so they are spot on in most of the cases ;) – DavidP Sep 13 at 7:10
  • Great to know it's for something usefull :) For just an insight, maybe you can look into ST_LineInterpolatePoint, and do something like get a point each, say, 100m, create a line with these points, and do the same thing with something like 50m. Finally you compare the 2 length and you get a ratio a little more robust than just total length / start-end. Of course you need to adapt the 100m and 50m parameters to fits your needs, it depends of the type of roads you have. – robin loche Sep 13 at 7:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.