I ran into a problem where shapely.intersection cuts a LineString into a MultiLinestring with lots of short lines instead of a simple LineString. The intersection is made between a circle (Polygon) and a LineString. The python code is simple:
intersection = shapely.intersection(line, circle)
The original LineString contains duplicate points, since it is a GPS track going back and forth the same way:
The black circle intersects with the blue line (GPS track). The red line is the result.
These are the sub Lines of the intersection separated a bit to visualize it better: 
Here I separated the points of the original GPS track so it is easier to see that it goes back the same way: 
This is the intersection:
{ "type": "Feature", "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 8.987437, 60.710481 ], [ 8.987753, 60.710386 ] ], [ [ 8.987753, 60.710386 ], [ 8.987975, 60.710381 ], [ 8.98801, 60.710381 ] ], [ [ 8.98801, 60.710381 ], [ 8.988991, 60.709666 ] ], [ [ 8.988991, 60.709666 ], [ 8.989304, 60.709225 ] ], [ [ 8.98801, 60.710381 ], [ 8.987753, 60.710386 ] ] ] }, "properties": { "stroke": "#ff0000", "stroke-width": 2, "stroke-opacity": 1 }, "id": 2 } As you can see the last point of a sub LineString and the first point of the next sub LineString are the same. These were duplicate points of the original LineString. The duplicate points belong there because the track goes back the same way as it came. Here is the full geojson file to visualize in geojson.io:
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "LineString", "coordinates": [ [ 8.985738, 60.712983 ], [ 8.985523, 60.712769 ], [ 8.985278, 60.712175 ], [ 8.985441, 60.711763 ], [ 8.985674, 60.711554 ], [ 8.986364, 60.711158 ], [ 8.986783, 60.71076 ], [ 8.986913, 60.710638 ], [ 8.987753, 60.710386 ], [ 8.987975, 60.710381 ], [ 8.98801, 60.710381 ], [ 8.988991, 60.709666 ], [ 8.989304, 60.709225 ], [ 8.988991, 60.709666 ], [ 8.98801, 60.710381 ], [ 8.987753, 60.710386 ], [ 8.986913, 60.710638 ], [ 8.986364, 60.711158 ], [ 8.985674, 60.711554 ], [ 8.985427, 60.711546 ], [ 8.985205, 60.711582 ], [ 8.985061, 60.711618 ], [ 8.984823, 60.711663 ], [ 8.984621, 60.711681 ], [ 8.984332, 60.711681 ], [ 8.98412, 60.71166 ], [ 8.983526, 60.711579 ], [ 8.982879, 60.711582 ] ] }, "properties": { "stroke": "#0000a0", "stroke-width": 2, "stroke-opacity": 1 }, "id": 0 }, { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [ [ [ 8.993146, 60.708983 ], [ 8.993075, 60.708632 ], [ 8.992866, 60.708294 ], [ 8.992526, 60.707983 ], [ 8.992069, 60.707711 ], [ 8.991512, 60.707487 ], [ 8.990876, 60.707321 ], [ 8.990187, 60.707219 ], [ 8.989469, 60.707184 ], [ 8.988752, 60.707219 ], [ 8.988063, 60.707321 ], [ 8.987427, 60.707487 ], [ 8.98687, 60.707711 ], [ 8.986413, 60.707983 ], [ 8.986073, 60.708294 ], [ 8.985864, 60.708632 ], [ 8.985793, 60.708983 ], [ 8.985864, 60.709334 ], [ 8.986073, 60.709671 ], [ 8.986413, 60.709982 ], [ 8.98687, 60.710255 ], [ 8.987427, 60.710478 ], [ 8.988062, 60.710644 ], [ 8.988752, 60.710747 ], [ 8.989469, 60.710781 ], [ 8.990187, 60.710747 ], [ 8.990876, 60.710644 ], [ 8.991512, 60.710478 ], [ 8.992069, 60.710255 ], [ 8.992526, 60.709982 ], [ 8.992866, 60.709671 ], [ 8.993075, 60.709334 ], [ 8.993146, 60.708983 ] ] ] }, "properties": {}, "id": 1 }, { "type": "Feature", "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 8.987437, 60.710481 ], [ 8.987753, 60.710386 ] ], [ [ 8.987753, 60.710386 ], [ 8.987975, 60.710381 ], [ 8.98801, 60.710381 ] ], [ [ 8.98801, 60.710381 ], [ 8.988991, 60.709666 ] ], [ [ 8.988991, 60.709666 ], [ 8.989304, 60.709225 ] ], [ [ 8.98801, 60.710381 ], [ 8.987753, 60.710386 ] ] ] }, "properties": { "stroke": "#ff0000", "stroke-width": 2, "stroke-opacity": 1 }, "id": 2 } ] }
I couldn't figure out why this happens and how I can avoid it. Simply merging the MultiLineString to a LineString is no option, because it can contain legitimate MultiLineString segments if the track leaves the circle, but reenters later on. Then multiple LineStrings inside of a MultiLineString are desired. But not the MultiLineString due to the duplicate points.
This should be a reproducable example in Python 3.7, Shapely 2.0.2:
import shapely line = shapely.linestrings([ [ 8.985738, 60.712983 ], [ 8.985523, 60.712769 ], [ 8.985278, 60.712175 ], [ 8.985441, 60.711763 ], [ 8.985674, 60.711554 ], [ 8.986364, 60.711158 ], [ 8.986783, 60.71076 ], [ 8.986913, 60.710638 ], [ 8.987753, 60.710386 ], [ 8.987975, 60.710381 ], [ 8.98801, 60.710381 ], [ 8.988991, 60.709666 ], [ 8.989304, 60.709225 ], [ 8.988991, 60.709666 ], [ 8.98801, 60.710381 ], [ 8.987753, 60.710386 ], [ 8.986913, 60.710638 ], [ 8.986364, 60.711158 ], [ 8.985674, 60.711554 ], [ 8.985427, 60.711546 ], [ 8.985205, 60.711582 ], [ 8.985061, 60.711618 ], [ 8.984823, 60.711663 ], [ 8.984621, 60.711681 ], [ 8.984332, 60.711681 ], [ 8.98412, 60.71166 ], [ 8.983526, 60.711579 ], [ 8.982879, 60.711582 ] ]) circle = shapely.polygons([ [ 8.993146, 60.708983 ], [ 8.993075, 60.708632 ], [ 8.992866, 60.708294 ], [ 8.992526, 60.707983 ], [ 8.992069, 60.707711 ], [ 8.991512, 60.707487 ], [ 8.990876, 60.707321 ], [ 8.990187, 60.707219 ], [ 8.989469, 60.707184 ], [ 8.988752, 60.707219 ], [ 8.988063, 60.707321 ], [ 8.987427, 60.707487 ], [ 8.98687, 60.707711 ], [ 8.986413, 60.707983 ], [ 8.986073, 60.708294 ], [ 8.985864, 60.708632 ], [ 8.985793, 60.708983 ], [ 8.985864, 60.709334 ], [ 8.986073, 60.709671 ], [ 8.986413, 60.709982 ], [ 8.98687, 60.710255 ], [ 8.987427, 60.710478 ], [ 8.988062, 60.710644 ], [ 8.988752, 60.710747 ], [ 8.989469, 60.710781 ], [ 8.990187, 60.710747 ], [ 8.990876, 60.710644 ], [ 8.991512, 60.710478 ], [ 8.992069, 60.710255 ], [ 8.992526, 60.709982 ], [ 8.992866, 60.709671 ], [ 8.993075, 60.709334 ], [ 8.993146, 60.708983 ] ]) intersection = shapely.intersection(line, circle) 



