# Draw arbitrary polygons and measure the area in the visual scene

Time：2021-11-30

The general measurement function is mainly reflected in two aspects: one is to measure distance, the other is to measure area. Area measurement is to calculate the actual area size through the transformation of geographical coordinate system according to the range drawn by the mouse. Distance measurement is to calculate the actual distance between two points in real time according to the points drawn by the mouse on the map. How do I measure area in a 3D scene? Next, I will draw polygon area at any point of the mouse on thingjs platform, calculate the total drawing length and floor area, and support arbitrary polygon drawing and area measurement in digital twin visualization scene.
Let’s take a look at the implementation effect:

Realization idea
1. First, add a registration event, click the left mouse button to add a point, move the mouse to continuously draw the measurement line segment, and double-click or right-click to end.

``````appClick() {
let _this = this;
//Left click to add node and right click to finish drawing
_this.opts.app.on('SingleClick', function(e) {
if (e.button == 0) {
if (!e.picked) return;
_this.numIndex++;
_this.ePosition = e.pickedPosition;
_this.createPoint(_this.ePosition);
_this.coordinatesArr.push(_this.ePosition);
_this.lineCoor.push(_this.ePosition);
_this.createLine(_this.coordinatesArr);
_this.getDistance();
_this.template =
`<div id="div` + _this.opts.modelNum + _this.numIndex + `" class="card-label card-label` + _this.opts.modelNum + `">
<span class="text">`;
if (_this.lineDistanceAll != null) {
_ this.template += _ This.linedistanceall + ` m ';
} else {
_ this.template += `<span style="color:#f45905; border-right: 1px solid #ccc;margin-right: 5px">` + _ This.planeid + ` < / span > starting point`
}
_this.template +=
`</span>
<span><img id="points` + _this.opts.modelNum + _this.numIndex + `"></span>
</div>`;
_this.boardId = 'div' + _this.opts.modelNum + _this.numIndex;
_this.createCard(_this.regionPoint);
_this.pointsObj = {
id: 'points' + _ this.opts.modelNum + _ This.numindex, // the span tag ID of the top plate of the starting point
parent: 'div' + _ this.opts.modelNum + _ This.numindex, // starting point top div tag ID
coor: _ This.opts.currposition, // starting point coordinates
distance: 0
};
_this.pointsObjArr.push(_this.pointsObj);
_this.cardClick();
} else {
if (_this.coordinatesArr.length < 2) {
_this.destroyAll();
_this.rianleyDom.css('display', 'none');
return;
};
_this.end();
}
_this.rianleyDom.css('display', 'none');
}"," click ");

//Move the mouse to continuously draw the measurement line segment
_this.opts.app.on('MouseMove', function(e) {
if (e.picked) {
_this.ePosition = e.pickedPosition;
_this.pointsArr = [..._this.coordinatesArr, _this.ePosition];
_this.createLine(_this.pointsArr);
_this.line.style.color = '#f88020';
if (_this.pointsArr.length >= 2) {
_this.moveDistance = THING.Math.getDistance(_this.pointsArr[_this.pointsArr.length - 1], _this.pointsArr[_this.pointsArr.length - 2]);
let countNum = 0;
_this.disArr.forEach(v => {
countNum += parseFloat(v);
});
countNum = 1 * parseFloat(countNum).toFixed(2) + 1 * parseFloat(_this.moveDistance).toFixed(2);
_this.rianleyDom.css('display', 'block');
_this.rianleyDom.find('span.value').text(countNum.toFixed(2));
_this.rianleyDom.css('left', e.clientX + 10 + 'px');
_this.rianleyDom.css('top', e.clientY + 'px');
}
}
}, 'move');

//Ends drawing the current survey line segment
_this.opts.app.on('DBLClick', function(ev) {
if (_this.coordinatesArr.length < 2) {
_this.destroyAll();
_this.rianleyDom.css('display', 'none');
return;
};
if (_this.coordinatesArr.length >= 3) {
_this.createPolygon(_this.coordinatesArr);
}
_this.end();
}, 'double click');
}``````

2. Create nodes, line segments and generate measurements? These basic elements determine the starting point and the coordinates of each node. Create parameter groups through nodes and segments, unify the coordinate point set after all mouse clicks, and generate the measured area of irregular graphics.

``````1、 createPoint(ePosition) {
2、  var _this = this;
3、  _this.regionPoint = app.create({
4、  type: 'Sphere',
5、  id: 'points' + _this.opts.modelNum + _this.numIndex,
6、  name: 'points' + _this.opts.modelNum,
8、  widthSegments: 16,
9、  heightSegments: 16,
10. Position: eposition, // sphere coordinates
11、  style: {
12、  color: '#c10000',
13、  roughness: 50,
14、  opacity: 0.8
15、  }
16、  });
17、  }
18、 createLine(coordinates) {
19、  if (this.line) {
20、  this.line.destroy();
21、  }
22、  let id = this.opts.modelNum > 10 ? this.opts.modelNum : '0' + this.opts.modelNum;
23、  this.line = app.create({
24、  type: 'PolygonLine',
25、  name: 'line',
26、  id: 'line' + id,
27、  width: 0.03,
28、  points: coordinates,
29、  style: {
30、  image: '/guide/examples/images/measure/redLine.png',
31、  opacity: 0.9
32、  }
33、  });
34、  }``````

3. The object of area measurement is a polygon feature with geographical coordinates. You need to create a constructor () constructor and set the construction parameters.

``````constructor(option) {
this.opts = option;
this.pointsArr = [this.opts.currPosition]; //  Collection of coordinate points in mouse movement
this.coordinatesArr = [this.opts.currPosition]; //  Store the collection of coordinate points after mouse click
this.ePosition = null; //  Stores the position of the mouse after triggering the event
this.lineCoor = [this.opts.currPosition]; //  Stores the current two coordinate points
this.disArr = []; //  Stores the distance between all coordinate points
this.numIndex = 0; //  Self increasing variable
this.reSetDistance = 0; //  Distance between two points
this.lastStatus = false; //  Judge whether the drawing end value is false, not ended, and true is ended
this.pointsObjArr = []; //  Store the ID and top card ID of all nodes
this.rianleyDom = \$('#marker'); //  Follow the mouse prompts
this.pointCardDom = \$('#pointMarker'); //  Prompt for moving the mouse to the node
this.init();
this.appClick();
}``````

4. After creating a method for measuring polygon area, the area of the selected part will be triggered when drawing is stopped, and then we need to pop up a top card at the end of measurement to display the measured area.

``````createTopCard(position) {
\$('#div3d').append(this.template);
this.polygonCard = document.getElementById(this.boardId);
this.uiTop = app.create({
type: 'UIAnchor',
element: this.polygonCard,
position: [position[0], position[1], position[2]]
});
}``````

Is it very simple to measure polygon area in digital twin visualization scene? Full code stamp official website –https://www.thingjs.com/

## Golden nine silver ten: byte three-sided warp at the front end of a year

background Recently, I also wrote an article in naked CIGolden nine silver ten: Interview sharing at the front of the year, after many days,Finally summoned up the courage to resume the interview, the reason why the byte face is written separately,Because you really need to know some big factory interview experience in advance, the problem […]