土方量计算,或者叫填挖方计算,体积计算,Skyline在很早的版本中就提供了这个的功能。
目前的软件版本,不仅仅可以对地形修改对象进行土方量计算,还可以在FLY工程中导入DEM数字高程模型数据,计算不同DEM数据之间的土方量变化情况。
这里摘取了针对地形修改对象的土方量计算代码,请大家鉴赏。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>剖切指定位置的三维模型</title> <script type="text/javascript"> // ------------------------------------------------------ // 若加载其他工程文件,可以修改下面一行中fly文件地址 var flyurl = "E:\2018\DEMO\Default0726.fly"; // ------------------------------------------------------ function LoadFly() { var sg = CreateSGObj(); sg.Open(flyurl); } window.setTimeout("LoadFly()", 1000); function StartCal() { var SGWorld = CreateSGObj(); var oid = SGWorld.ProjectTree.FindItem("New Modify Terrain ##5175551"); CalculateList(oid, null); } function CalculateList(value, geometry) { var SGWorld = CreateSGObj(); var volumeGeometry; var ModifyObj = SGWorld.ProjectTree.GetObject(value); if (geometry == null) volumeGeometry = ModifyObj.Geometry; else volumeGeometry = geometry; var origVisability = SGWorld.ProjectTree.GetVisibility(value); SGWorld.ProjectTree.SetVisibility(value, false); calculateVolume(volumeGeometry, 2, 3, 0, ModifyObj.TreeItem.Name); SGWorld.ProjectTree.SetVisibility(value, true); calculateVolume(volumeGeometry, 2, 3, 1, ModifyObj.TreeItem.Name); SGWorld.ProjectTree.SetVisibility(value, origVisability); } var gAreaUnitFactor = 1; var gVolumeUnitFactor = 1; var gAreaUnit = ""; var gVolumeUnit = ""; var gQuaryResolution = 1024; var gVolumeResultHTML = ""; //------------- // calculateVolume function calculateVolume(geometry, type, altitudeType, phase, ObjName) { var SGWorld = CreateSGObj(); //debugger //var htmlStr; //htmlStr = SGLang.i18n("PrepareClaculation"); //SGWorld.Window.ShowMessageBarText(htmlStr, 1, -1); //var qualityStep = ResolutionsArray[$("#DensityID").val()]; var qualityStep = 10; var polygonGeometry = geometry.Clone(); // to enable edit geometry (ref) when geometry type is RelativeToPivot. Navon. var envelope = polygonGeometry.Envelope; // Multi polygon evnelope (min/max) var MinX = Math.min(envelope.Rings(0).Points(0).x, envelope.Rings(0).Points(2).x); var MaxX = Math.max(envelope.Rings(0).Points(0).x, envelope.Rings(0).Points(2).x); var MinY = Math.min(envelope.Rings(0).Points(0).y, envelope.Rings(0).Points(2).y); var MaxY = Math.max(envelope.Rings(0).Points(0).y, envelope.Rings(0).Points(2).y); var stepX = Math.abs(MaxX - MinX) / gQuaryResolution; var stepY = Math.abs(MaxY - MinY) / gQuaryResolution; // calculate cell 2D size var cellPos0 = SGWorld.Creator.CreatePosition(MinX, MaxY, 0, 3, 0, 0, 0, 1); var cellPos1 = SGWorld.Creator.CreatePosition(MinX, MaxY - stepY, 0, 3, 0, 0, 0, 1); var cellPos2 = SGWorld.Creator.CreatePosition(MinX + stepX, MaxY, 0, 3, 0, 0, 0, 1); var cellWidth = cellPos0.DistanceTo(cellPos1) * qualityStep; var cellArea = cellPos0.DistanceTo(cellPos1) * cellPos0.DistanceTo(cellPos2) * qualityStep * qualityStep * gAreaUnitFactor; if (phase == 0) { // For now we call this query several times because of an engine bug!!! gElevationBufferBefore = SGWorld.Analysis.QueryElevationBuffer(MinX, MaxY, stepX, stepY, gQuaryResolution, gQuaryResolution).toArray(); // MaxX - MinX, MaxY - MinY); gElevationBufferBefore = SGWorld.Analysis.QueryElevationBuffer(MinX, MaxY, stepX, stepY, gQuaryResolution, gQuaryResolution).toArray(); // MaxX - MinX, MaxY - MinY); gElevationBufferBefore = SGWorld.Analysis.QueryElevationBuffer(MinX, MaxY, stepX, stepY, gQuaryResolution, gQuaryResolution).toArray(); // MaxX - MinX, MaxY - MinY); } else { // For now we call this query several times because of an engine bug!!! gElevationBufferAfter = SGWorld.Analysis.QueryElevationBuffer(MinX, MaxY, stepX, stepY, gQuaryResolution, gQuaryResolution).toArray(); // MaxX - MinX, MaxY - MinY); gElevationBufferAfter = SGWorld.Analysis.QueryElevationBuffer(MinX, MaxY, stepX, stepY, gQuaryResolution, gQuaryResolution).toArray(); // MaxX - MinX, MaxY - MinY); gElevationBufferAfter = SGWorld.Analysis.QueryElevationBuffer(MinX, MaxY, stepX, stepY, gQuaryResolution, gQuaryResolution).toArray(); // MaxX - MinX, MaxY - MinY); //// var group; //var drawObjects = $("#showObjectsID").is(':checked') ? true : false; //if (drawObjects) { // CreateLayer(cellWidth * 100, ObjName); // var result = featureLayerStyles["ImageLabel"](cellWidth / 40, abspath() + "/img/point.png"); // ,"[Color]"); //} //group = SGWorld.ProjectTree.CreateGroup( SGLang.i18n("ToolName"), ""); var VolumeAdded = 0; var VolumeRemoved = 0; for (i = qualityStep / 2; i < gQuaryResolution; i = i + qualityStep) { for (j = qualityStep / 2; j < gQuaryResolution; j = j + qualityStep) { var x = MinX + i * stepX; var y = MaxY - j * stepY; var objColor = "#000000"; var volumeType = 0; var pointGeometry = SGWorld.Creator.GeometryCreator.CreatePointGeometry([x, y, 0]); if (polygonGeometry.SpatialRelation.Intersects(pointGeometry)) { var elevationDiff = gElevationBufferAfter[j * gQuaryResolution + i] - gElevationBufferBefore[j * gQuaryResolution + i]; var volumeDiff = cellArea * elevationDiff * gVolumeUnitFactor; if (elevationDiff > 0) { // Added volumeType = 1; VolumeAdded += Math.abs(volumeDiff); objColor = 65280; // "#00ff00"; // green } else if (elevationDiff < 0) { // Removed volumeType = 2; VolumeRemoved += Math.abs(volumeDiff); objColor = 255; // "#ff0000"; // red } else { volumeType = 0; objColor = 0; // "#000000"; // black } //if (drawObjects) { // && i % ObjInterval == 0 && j % ObjInterval == 0) { // var pos = SGWorld.Creator.CreatePosition(x, y, gElevationBufferAfter[j * gQuaryResolution + i], 3, 0, 0, 0, 1); // gLayer.FeatureGroups.Point.CreateFeature([pos.X, pos.Y, pos.Altitude], volumeType + ";" + cellArea.toFixed(3) + ";" + volumeDiff.toFixed(3) + ";" + objColor); // //SGWorld.Creator.CreateSphere(pos, 2, 0, objColor, objColor, 2, group, "sphere"); //} } // if intersect } // for j if (i % 10 == 0) { var progress = (i / gQuaryResolution) * 100; htmlStr = SGLang.i18n("calculatingVolume") + ObjName + ": " + progress.toFixed(0) + "%"; SGWorld.Window.ShowMessageBarText(htmlStr, 1, -1); } } // for i SGWorld.Window.HideMessageBarText(); gVolumeResultHTML += "<br/><u>" + ObjName + ":</u><br/>" + "objectVolumeAdded" + "<b>" + VolumeAdded.toFixed(3) + "</b> " + gVolumeUnit + " <br/> " + "objectVolumeRemoved" + "<b>" + VolumeRemoved.toFixed(3) + "</b> " + gVolumeUnit + "<br/>"; //gTotalVolumeAdded += VolumeAdded; //gTotalVolumeRemoved += VolumeRemoved; alert(gVolumeResultHTML); //if (drawObjects) // gLayer.Save(); } // phase return true; } // SGWorld70 function CreateSGObj() { try { var obj = document.getElementById("SGWorld"); if (obj == null) { obj = document.createElement('object'); obj.setAttribute("name", "SGWorld"); obj.setAttribute("id", "SGWorld"); obj.style.height = "1px"; obj.style.width = "1px"; obj.setAttribute("classid", "CLSID:3A4F919C-65A8-11D5-85C1-0001023952C1"); document.body.appendChild(obj); } return obj; } catch (e) { alert(e); } } </script> </head> <body style="margin: 0px; border: 0px;"> <div id="top"> <div> <input id="Button1" type="button" value="分析" style="position:absolute;top:6px;right:100px;" onclick="StartCal()" /> </div> </div> <div style="position: absolute; top: 50px; bottom: 0px; 100%; background-color: black; margin: 0px; border: 0px; margin-top: 3px;"> <object id="TerraExplorerInformationWindow" classid="CLSID:3a4f9193-65a8-11d5-85c1-0001023952c1" style="margin-left: 3px; 19%; height: 99%;"></object> <object id="TerraExplorer3DWindow" classid="CLSID:3a4f9192-65a8-11d5-85c1-0001023952c1" style=" 80%; height: 99%;"></object> </div> </body> </html>