diff --git a/libs/kimath/include/geometry/shape_line_chain.h b/libs/kimath/include/geometry/shape_line_chain.h
index dae2782bf5..919b67daac 100644
--- a/libs/kimath/include/geometry/shape_line_chain.h
+++ b/libs/kimath/include/geometry/shape_line_chain.h
@@ -298,6 +298,11 @@ public:
     int ShapeCount() const;
 
 
+    /**
+     * Remove the duplicate points from the line chain.
+    */
+    void RemoveDuplicatePoints();
+
     /**
      * Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
      *
diff --git a/libs/kimath/src/geometry/shape_line_chain.cpp b/libs/kimath/src/geometry/shape_line_chain.cpp
index 819501b421..538a71bfa3 100644
--- a/libs/kimath/src/geometry/shape_line_chain.cpp
+++ b/libs/kimath/src/geometry/shape_line_chain.cpp
@@ -2087,6 +2087,68 @@ double SHAPE_LINE_CHAIN::Area( bool aAbsolute ) const
 }
 
 
+void SHAPE_LINE_CHAIN::RemoveDuplicatePoints()
+{
+    std::vector<VECTOR2I> pts_unique;
+    std::vector<std::pair<ssize_t, ssize_t>> shapes_unique;
+
+    // Always try to keep at least 2 points otherwise, we're not really a line
+    if( PointCount() < 3 )
+    {
+        return;
+    }
+    else if( PointCount() == 3 )
+    {
+        if( m_points[0] == m_points[1] )
+            Remove( 1 );
+
+        return;
+    }
+
+    int i = 0;
+
+    while( i < PointCount() )
+    {
+        int j = i + 1;
+
+        // We can eliminate duplicate vertices as long as they are part of the same shape, OR if
+        // one of them is part of a shape and one is not.
+        while( j < PointCount() && m_points[i] == m_points[j] &&
+               ( m_shapes[i] == m_shapes[j] ||
+                 m_shapes[i] == SHAPES_ARE_PT ||
+                 m_shapes[j] == SHAPES_ARE_PT ) )
+        {
+            j++;
+        }
+
+        std::pair<ssize_t,ssize_t> shapeToKeep = m_shapes[i];
+
+        if( shapeToKeep == SHAPES_ARE_PT )
+            shapeToKeep = m_shapes[j - 1];
+
+        assert( shapeToKeep.first < static_cast<int>( m_arcs.size() ) );
+        assert( shapeToKeep.second < static_cast<int>( m_arcs.size() ) );
+
+        pts_unique.push_back( CPoint( i ) );
+        shapes_unique.push_back( shapeToKeep );
+
+        i = j;
+    }
+
+    m_points.clear();
+    m_shapes.clear();
+
+    for( size_t ii = 0; ii < pts_unique.size(); ++ii )
+    {
+        const VECTOR2I p0 = pts_unique[ii];
+
+        m_points.push_back( p0 );
+        m_shapes.push_back( shapes_unique[ii] );
+    }
+}
+
+
+
 void SHAPE_LINE_CHAIN::Simplify( int aMaxError )
 {
     if( PointCount() < 3 )
diff --git a/pcbnew/router/pns_node.cpp b/pcbnew/router/pns_node.cpp
index cb71b95cd0..6f971e2c56 100644
--- a/pcbnew/router/pns_node.cpp
+++ b/pcbnew/router/pns_node.cpp
@@ -1085,7 +1085,7 @@ const LINE NODE::AssembleLine( LINKED_ITEM* aSeg, int* aOriginSegmentIndex,
     }
 
     // Remove duplicate verts, but do NOT remove colinear segments here!
-    pl.Line().Simplify( false );
+    pl.Line().RemoveDuplicatePoints();
 
     // TODO: maintain actual segment index under simplification system
     if( aOriginSegmentIndex && *aOriginSegmentIndex >= pl.SegmentCount() )