Realization of Closed and Unclosed Lines in Network Design

Friends, have you encountered some of the following problems when designing the network: 1. Find a closed polyline segment or a closed border in a bunch of line segments or polyline segments. 2. Combine multiple line segments connecting endpoints (within a safe distance) into a polyline segment. 3. The synthesized line segments are classified based on closed borders and non-closed borders. 4. Collect their coordinate information and use it. If so, take a good look at the article shared with you below.

copy code

/*

* [Looking for a closed border] by Autumn Leaf Blog http://www.mizuiren.com/497.html

* linesPoints can be a set of line coordinate points [[{x:1,y:2},{x:2,y:3}],[{x:4,y:2},{x:6,y:7 },{x:4,y:2}]]

* linesPoints can also be a collection of dom objects for lines [document.querySelectorAll('polyline/line')];

* tolerance: safety distance

* */

function findCloseLine(linesPoints, tolerance) {

   var pointArrs = linesPoints;

   tolerance = tolerance || 0;//Interval, the distance between two points is considered to be connected

   if (!Array.isArray(linesPoints[0])) {//If the array element is not an object, it will be processed according to the dom object

      pointArrs = [];

      if(!Array.isArray(linesPoints )) {//If it is a dom collection, convert it into an array

         linesPoints = [].slice.call(linesPoints);

      }

      if (!tolerance) {

         tolerance = linesPoints[0].getAttribute('stroke-width');//Interval takes the width of the first line

      }

      var points, match, xy, xys;

      linesPoints.forEach(function (line) {//Convert their paths into coordinate objects

         points = line.getAttribute('points') || line.getAttribute('d');

         if (!points) {

            return;

         }

         match = points.match(/\-?\d+(\.\d+)?.*?\d+(\.\d+)?/g);

         xys = [];

         match.forEach(function (item) {

            xy = item.match(/(\-?\d+(\.\d+)?).*?(\-?\d+(\.\d+)?)/);

            xys.push({

               x: +xy[1],

               y: +xy[3]

            });

         });

         pointArrs.push(xys);

      });

   }

   var closed = [], hadSearchIndexs = [], notClosed = [], combinePoint = [], hadCombinePoint;

   pointArrs.forEach(function (_points, index) {

      if (getDistance(_points[0], _points[_points.length - 1]) <= tolerance) {

         closed.push(_points);

         hadSearchIndexs.push(index);

         return;

      }

      combinePoint = [];

      hadCombinePoint = findNextConect(index, _points[0], 'begin');//Find the connection point of the line head

      if (!hadCombinePoint) {

         hadCombinePoint = findNextConect(index, _points[_points.length - 1], 'end');//Find the connection point at the end of the line

      }

      if (hadCombinePoint) {//If the join point is found

         if (getDistance(hadCombinePoint[0], hadCombinePoint[hadCombinePoint.length - 1]) <= tolerance) {

            closed.push(hadCombinePoint);

         } else {

            notClosed.push(hadCombinePoint);

         }

      } else {//If the connection point is not found

         hadCombinePoint === '' || notClosed.push(_points);//hadCombinePoint is '' (that is, it has been connected or the current line segment) is not included in the non-closed collection

      }

      hadSearchIndexs.push(index);

   });

 

   //Take an endpoint to calculate the distance from the endpoints of other line segments to determine whether they are connected. If they are connected, merge their coordinates together to form a complete line

   function findNextConect(currentIndex, point, beginOrEnd) {

      var hadConected, connectPoint, currentLine, _thisLinePoints;

      var combinePoint = [];

      _infun(currentIndex, point, beginOrEnd);

 

      function connectAction(beginOrEnd1, beginOrEnd2, waitConnectLine, index) {

         if (beginOrEnd1 === beginOrEnd2) {

            _thisLinePoints = _thisLinePoints.reverse();

         }

         _action(beginOrEnd1, waitConnectLine);

         hadConected = true;

         hadSearchIndexs.push(index);

         _infun(currentIndex, connectPoint, beginOrEnd1);

 

         function isRepeatPoint(begin, end) {

            var endLastIndex = end.length - 1;

            return end[endLastIndex].x === begin[0].x && end[endLastIndex].y === begin[0].y;

         }

 

         function _action(beginOrEnd, waitConnectLine) {

            if (beginOrEnd === 'begin') {

               if (isRepeatPoint(waitConnectLine, _thisLinePoints)) {

                  _thisLinePoints.pop();

               }

               combinePoint = _thisLinePoints.concat(waitConnectLine);

               pointArrs[currentIndex] = combinePoint;

               connectPoint = combinePoint[0];

            } else {

               if (isRepeatPoint(_thisLinePoints, waitConnectLine)) {

                  _thisLinePoints.shift();

               }

               combinePoint = waitConnectLine.concat(_thisLinePoints);

               pointArrs[currentIndex] = combinePoint;

               connectPoint = combinePoint[combinePoint.length - 1];

            }

         }

 

      }

 

      function _infun(currentIndex, point, beginOrEnd) {

         var waitConnectLine = pointArrs[currentIndex];

         if (waitConnectLine) {

            for (var i = 0; i < pointArrs.length; i++) {

               _thisLinePoints = JSON.parse(JSON.stringify(pointArrs[i]));//Clone the object, because it needs to be deleted later

               if (i === currentIndex) {

                  continue;

               }

               if (hadSearchIndexs.indexOf(currentIndex) > -1) {

                  currentLine = '';

                  continue;

               }

               if (hadSearchIndexs.indexOf(i) > -1) {

                  continue;

               }

               if (getDistance(_thisLinePoints[0], point) <= tolerance) {

                  connectAction(beginOrEnd, 'begin', waitConnectLine, i);

                  break;

               } else if (getDistance(_thisLinePoints[_thisLinePoints.length - 1], point) <= tolerance) {

                  connectAction(beginOrEnd, 'end', waitConnectLine, i);

                  break;

               }

            }

         }

      }

 

      if (combinePoint.length) {

         return combinePoint;

      } else {

         return currentLine;

      }

   }

 

   // Calculate the distance between two points

   function getDistance(p1, p2) {

      return Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));

   }

 

   var category = {//Return the collection of classification coordinate points of closed border and non-closed border

      closed: closed,

      notClosed: notClosed

   }

   return category;

}

//transfer:

findCloseLine([document.querySelectorAll('polyline')], 10);

copy code

The above is what I brought to you today.

 

Guess you like

Origin blog.csdn.net/weixin_43955838/article/details/86714224