Objective
The construction and popularization of low-carbon industrial park is an important measure to promote low-carbon transformation in China, and the energy and carbon emission control platform of low-carbon industrial park is the key link in the construction of low-carbon industrial park. How to collect, measure and calculate the energy of the enterprise in the park, and how to monitor the energy consumption and carbon emissions in real time, involving a number of technical fields, strong professional. Its data is not only accurate, but also true and reliable (verifiable, traceable). This is the core task of the construction of "control platform" in low-carbon industrial park, and it is also one of the main problems needing urgent solution in the construction of China's industrial park.
This GIF shows a 2D 3D combination of low-carbon industrial park Energy Monitoring system, mainly for each building and the park's overall water, electricity and other usage of real-time monitoring.
Code Implementation Build Scenario
It is not difficult to create a 3D low-carbon industrial park scene, but how do you display both the 3D and the the scene on the same interface? This is a very useful way to make cool effects in many situations.
The entire low-carbon industrial park scene is built on the 2D, we know that HTML to the DOM elements to set the image can only use the traditional raster bitmap, but if it is afraid that the image is stretched to cause the image blurred or distorted results, with JSON format vector pictures to achieve is the best, Raster bitmaps can cause problems such as blurred graphics and jagged lines when stretched or zoomed out. Vector images, which are described by dots, lines, and polygons, maintain consistent accuracy in the case of infinitely magnified and reduced images.
First I set up a 2D scene to place our JSON vectors, using HT. The Default.xhrload function deserializes the JSON vector background graph onto the GV, which has two nodes in addition to node as the background, such as the larger of the red line frame, which is used to install the 3D scene, while the smaller node of the right border is Used to place another GV (temporarily not available, later need to add similar form form functions, so I need a fixed position):
function (text) { dm.deserialize (text); // deserializing data to a data model gv.addtodom (); // Add the scene to the Body });
This 2D scene is set up as part of the background, then look at how to offload 3D scenes on the basis of the 2D scene.
Adding 3D scenes in 2D
Adding 3D to 2D is also very easy, and the question is how to make the 3D scene adapt to the 2D scene scale and pan, so that the 3D scene remains in a fixed position in the 2D scene? I do this by listening to the properties of the GV and hearing the properties of zoom, translate, and so on, to automatically layout the 3D scene:
varG3dinfo = Create3d (' G3dnode ')); Gv.mp (function(e) {//monitoring GV's attribute change events if(E.property = = = ' Zoom ' | | e.property = = ' TranslateX ' | | e.property = = ' Translatey ') {layout (g3dinfo); }});functionLayout (info) {varRect = Info.node.getRect (),//gets the rectangular area of the node that the scene relies onZoom = Gv.getzoom (),//gets the zoom value of the current GVtx = GV.TX (),//gets the horizontal translation value of the current GVty = Gv.ty ();//Gets the vertical translation value of the current GV //The size of the dependent nodes is scaled based on the zoom zoom valueRect.x *=Zoom, Rect.y*=Zoom, Rect.width*=Zoom, Rect.height*=Zoom; varx = Rect.x +TX, y= Rect.y +Ty; //set up scene auto layout if(info.g3d) info.g3d.layout (x, Y, Rect.width, rect.height);}
Sharp-eyed's classmates should have noticed, I did not write the declaration of the Create3d function, in terms of the effect, this method simply deserializes the scene JSON sheet into the 3D scene, and appends an object info to the variables of the node and 3D scene that the scene relies on:
functionCreate3d (tag) {varG3d =NewHt.graph3d.Graph3dView ();//Components varDatamodel = g3d.dm ();//get the data container for a 3D sceneGv.getview (). AppendChild (G3d.getview ());//Adding a 2D scene to a scenarioHt. Default.xhrload (' scenes/. JSON ',function(text) {//loading JSON vector drawings for 3D scenesDatamodel.deserialize (text);//deserializing data to a data model }); //Stop the propagation of an event to prevent it from being dispatched to another Document nodeG3d.getview (). AddEventListener (' MouseDown ',function(e) {e.stoppropagation ()}); G3d.getview (). AddEventListener (' MouseWheel ',function(e) {e.stoppropagation ()}); if(Isfirefox=navigator.useragent.indexof ("Firefox") > 0) {G3d.getview (). AddEventListener (' Dommousescroll ',function(e) {e.stoppropagation ()}); } varinfo ={g3d:g3d, Node:dm.getDataByTag (tag),}; returninfo;}
There are many similarities between the 3D and the mouse events, but we do not want the 2D scene to change while the 3D scene is being manipulated, so the mouse press and the wheel event propagation are forbidden in the above code.
Building Information Display
One of the features of the low-carbon industrial Park Monitoring system: Click on the building to move to a more appropriate location, and the top of the building displays a panel to display information about the current building. Here I directly created a node, by setting the node's Shape3d property to Billboard can be displayed as a "patch", the panel is very useful, first it has only one face, in the 3D scene if you need a large number of nodes to display data, it is recommended to use this billboard type, very provincial performance.
//Create a display panel above the buildingvarBillboard =Newht. Node (); Billboard.setscalex (2);//enlarges the X-axis of the node by twice TimesBillboard.setscaletall (2);//enlarges the Y-axis of the node by twice TimesBillboard.s ({' Shape3d ': ' Billboard ',//This type is a patch' Shape3d.image ': ' Symbols/nodeform.json ',//set the display picture of the patch as a vector picture' Shape3d.autorotate ':true,//always facing the camera' Shape3d.vector.dynamic ':true,//set up vector graphics' 3d.visible ':false//not visible}); Billboard.settag (' Billboard ');//set the tag unique property of a nodeDatamodel.add (Billboard);//to add a node to a data container
By clicking on a different building, the information Panel is displayed above the currently clicked Building, and the billboard is controlled according to different selection conditions:
Datamodel.sm (). MS (function(e) {//Monitor selected change events if(E.kind = = = ' Set ' | | e.kind = = = ' Append ') {//set Check and append selectedBillboard.s (' 3d.visible ',true); vardata = Datamodel.sm (). LD ();//gets the last node currently selected if(!data)return; BILLBOARD.P3 (Data.getposition (). x, Data.gettall ()+ $, data.getposition (). y);//sets the location of the billboard to the top of the currently selected node } Else if(E.kind = = = ' Remove ') {//Check Remove vardata = Datamodel.sm (). LD ();//gets the currently last selected node if(data) {billboard.setposition (Data.getposition (). x, Data.getposition (). y); Billboard.setelevation (Data.gettall ()+ 200); } ElseBillboard.s (' 3d.visible ',false); } Else if(E.kind = = = ' Clear ') Billboard.s (' 3d.visible ',false);//clears all selected settings billboard not visible});
(See other examples)
As for clicking on a building, pushing from the current line of sight to the node position is through the FlyTo function, this function in 6.2.2 version has three parameters, parameter one is the target node, parameter two is animation, parameter three is the eye and the target node center distance calculation, such as the following code settings 0.5, which means that the eye dynamically calculates the distance in the above direction to fit the target into the screen 0.5. The information panel shows the name of the building that is currently clicked, and I set the DisplayName property on the corresponding building when I design the drawing for the 3D scene, and the current display is displayed according to this displayName.
G3D.MI (function(e) {//Add an interactive event listener if(E.kind = = = ' Clickdata ')) {G3d.flyto (E.data,true, 0.5);//position the eye and center from the current position to the target node the second parameter is full screen if 1. 6.2.2 version above has this method varName =E.data.getdisplayname (); //Since models cannot be grouped together in 3D, I use an append-select method to resolveDatamodel.each (function(node) {if(Node.getdisplayname ()!== name)return;//I set the same type of node to the same displayNameDatamodel.sm (). appendselection (node); }) }});
So, just one billboard, how do we make this billboard show different information according to the different buildings? This time the advantages of vector icons One more, by the vector icon in a part of the data binding data dynamic changes, this way I few words is not complete, I simply mention how to achieve, the rest can go to the official website of the data binding manual to access relevant information and specific implementation.
In front of the billboard set a Shape3d.image property, set the picture is Nodeform.json, this JSON has four lines of text display, the top of the text to display the name of the currently clicked building.
According to the manual we know that the data binding format is divided into two types, one binding function type and the other binding string type, as follows:
That is, if HT does not define the attributes we need, or if there are multiple identical attributes on a vector graph that need to be changed to different values, you can customize the properties by attr, and here's what I'm using:
"Text": { "func": "[email protected]", "value": "Sprint fitness College student Hostel"}
Once data binding is complete, we only need to change the business properties of the node that currently references this JSON vector icon based on this binding data:
// different buildings show different content billboard.a (' Buildingname ', name), billboard.a (' electricusage ', (Math.random () *300 ). toFixed (2)); Billboard.a (' waterusage ', (Math.random () *300). toFixed (2)); Billboard.a (' gasusage ', (Math.random () *300). ToFixed (2));
Right data display
3D scene creation is complete, then how to add to the 3D above the right two data display panel? Here I am. Added another 2D scene on the node in the previous 2D JSON scene where it has been positioned to display the overall scene data. Since there are two information panels on the GV, I have added two nodes directly to the Graphview and added the nodes to this Graphview Datamodel data container, and the rest of the sections I will not explain anymore are the basic code:
functionCREATEGV (tag) {varG2d =NewHt.graph.GraphView ();//2D Topology Scenario varDatamodel = g2d.dm ();//Gets the data container for the current topology scenarioGv.getview (). AppendChild (G2d.getview ());//Add this topology scenario to the underlying background mapG2d.setinteractors ([]);//clear the interaction on this component //adding two nodes to a topology scenario varnode =Newht. Node (); Node.setimage (' Symbols/form.json '); Node.setposition (0, 0); Datamodel.add (node); varNode1 =Newht. Node (); Node1.setimage (' Symbols/form1.json '); Node1.setposition (0, Dm.getdatabytag (tag). GetHeight ()/3);Datamodel.add (Node1); G2d.fitcontent (); SetInterval (function() {//dynamic change of form forms dataNode.a (' Electricuse ', (Math.random () *300). ToFixed (2)); Node.a (' Wateruse ', (Math.random () *300). ToFixed (2)); Node.a (' Gasuse ', (Math.random () *300). ToFixed (2)); Node.a (' Tempuse ', (Randomnumboth (10, 40)) + '); Node.a (' Wetuse ', (Math.floor ((Math.random () *100)) + "); }, 3000); varinfo ={g2d:g2d, Node:dm.getDataByTag (tag)}returninfo;}
Above, the entire low-carbon industrial park monitoring System to achieve the end of all, there are problems or suggestions can give me a message, thank you!
Monitoring system of low-carbon industrial park based on HTML5 WebGL