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.