/** * Copyright (c) 2011-2018 by Andrew Mustun. All rights reserved. * * This file is part of the QCAD project. * * QCAD is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * QCAD is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with QCAD. */ include("scripts/EAction.js"); include("scripts/simple.js"); include("scripts/Layer/Layer.js"); include("scripts/Common/DrawPM.js") function PM() { this.newEntityData = new Array(); this.newFZEntityData = new Array(); this.ratio = 1.0; this.csvData = new Array(); this.csvCoor = new Array(); this.csvR = new Array(); this.csvls = new Array(); //圆心坐标 this.centerO = new Array(); this.CurHuanheTArr = new Array(); this.primePointArr = new Array(); // 里程距离(用于计算百里标和公里标) this.mileage = 0.0; } PM.includeBasePath = includeBasePath; PM.prototype.interface = function (fileName) { try { this.fileName = fileName.substring(0, fileName.lastIndexOf(".")) + ".csv";; var ok0 = this.convert(this.fileName); if (ok0 == true) { EAction.handleUserMessage("optimize success!!!"); var fileNamePM = fileName.replace(/.\w+$/i, "_op.pm"); // 绘制PM var filePM = new DrawPM(fileNamePM, this.ratio, 3); filePM.applyDrawing(); if (true) { var tmp = RSettings.getStringValue("OpenDisplayFile/PMFile", ""); RSettings.setValue("OpenDisplayFile/PMFile", tmp + "," + fileNamePM); } this.cvFile = this.fileName.substring(0, this.fileName.lastIndexOf(".")) + "_op.pm"; var ok = this.readTxt(this.cvFile); if (ok) { var tmp = RSettings.getStringValue("OpenDisplayFile/PMFile", ""); RSettings.setValue("OpenDisplayFile/PMFile", tmp + "," + this.cvFile); } } } catch (error) { EAction.handleUserMessage("eooro: " + error.toString()); } } PM.prototype.convert = function (fileName) { var process = new QProcess; EAction.handleUserMessage("starting optimize " + fileName); // 后台运行 // process.start(PM.includeBasePath + "/railway_horizontal_sw_V1-background.exe -f " + fileName + " -e " + PM.includeBasePath); // 阻塞运行 EAction.handleUserMessage(PM.includeBasePath + "/railway_horizontal_sw_V1.exe -f " + fileName + " -e " + PM.includeBasePath); process.setProgram(PM.includeBasePath + "/railway_horizontal_sw_V1.exe"); var args = []; var input1 = " -f "; args.push(input1); var input2 = fileName; args.push(input2); var input3 = " -e "; args.push(input3); var input4 = PM.includeBasePath; args.push(input4); process.setArguments(args); process.start(); process.waitForStarted(-1); //等待程序启动 process.waitForFinished(-1);//等待程序关闭 return true; }; PM.prototype.applyOperation = function (preview) { // 添加图层 var layername = this.cvFile; addLayerToView(layername.toString(), "white", "CONTINUOUS", RLineweight.Weight025, 1); setCurrentLayer(layername.toString()); var colorReady = new Array( [ new RColor(255, 0, 0), new RColor(255, 0, 0), new RColor(160, 32, 240), new RColor(0, 255, 0), ] // , // [ // new RColor(128, 0, 128), // new RColor(77, 255, 77), // new RColor(200, 96, 255), // new RColor(160, 32, 240), // ], // [ // new RColor(255, 153, 77), // new RColor(255, 153, 77), // new RColor(128, 255, 255), // new RColor(0, 255, 255), // ], // [ // new RColor(77, 255, 255), // new RColor(77, 255, 255), // new RColor(255, 255, 128), // new RColor(255, 255, 0), // ], // [ // new RColor(148, 121, 253), // new RColor(148, 121, 253), // new RColor(255, 192, 128), // new RColor(255, 165, 0), // ] ); var colorIndex = Math.floor(Math.random() * colorReady.length); var selectedArray = colorReady[colorIndex]; var YQXColor = selectedArray[0]; var ZXColor = selectedArray[1]; var HHQXColor = selectedArray[2]; var FZXColor = selectedArray[3]; var jdIndx = 1; var lastType = 0; for (var i = 0; i < this.newEntityData.length; i++) { if (1 == this.newEntityData[i][8]) { var TempEntityData = new Array(); TempEntityData.push([this.newEntityData[i][0], this.newEntityData[i][1]]); TempEntityData.push([this.newEntityData[i][2], this.newEntityData[i][3]]); addPolylinetoView(TempEntityData, false, false, 1, ZXColor); // EAction.handleUserMessage(this.newEntityData[i].toString()); this.mileage_line( lastType, new Array(this.newEntityData[i][0], this.newEntityData[i][1]), new Array(this.newEntityData[i][2], this.newEntityData[i][3]), ZXColor, true ); } else if (3 == this.newEntityData[i][8]) { //-1:右曲线,1:左曲线 其中右曲线因为是逆时针(角度由大到小),需要画出对应的反向弧 lyz // EAction.handleUserMessage(this.newEntityData[i].toString()); if (1 == this.newEntityData[i][7]) { addArctoView(this.newEntityData[i][0], this.newEntityData[i][1], this.newEntityData[i][4], this.newEntityData[i][5], this.newEntityData[i][6], false, 1, YQXColor); } else if (-1 == this.newEntityData[i][7]) { addArctoView(this.newEntityData[i][0], this.newEntityData[i][1], this.newEntityData[i][4], this.newEntityData[i][5], this.newEntityData[i][6], true, 1, YQXColor); } this.mileage_circle( lastType, new Array(this.newEntityData[i][0], this.newEntityData[i][1]), this.newEntityData[i][4], this.newEntityData[i][5], this.newEntityData[i][6], true, YQXColor, true ); } else { //-1:右曲线,1:左曲线 其中右曲线因为是逆时针(角度由大到小),需要画出对应的反向弧 lyz // EAction.handleUserMessage(this.newEntityData[i].toString()); if (1 == this.newEntityData[i][7]) { addArctoView(this.newEntityData[i][0], this.newEntityData[i][1], this.newEntityData[i][4], this.newEntityData[i][5], this.newEntityData[i][6], false, 1, HHQXColor); } else if (-1 == this.newEntityData[i][7]) { addArctoView(this.newEntityData[i][0], this.newEntityData[i][1], this.newEntityData[i][4], this.newEntityData[i][5], this.newEntityData[i][6], true, 1, HHQXColor); } this.mileage_circle( lastType, new Array(this.newEntityData[i][0], this.newEntityData[i][1]), this.newEntityData[i][4], this.newEntityData[i][5], this.newEntityData[i][6], true, YQXColor, lastType != this.newEntityData[i][8] ); } lastType = this.newEntityData[i][8]; } //绘制辅助线,1为辅助线起点,2为焦点点,3为辅助线终点 for (var i = 0; i < this.newFZEntityData.length;) { var TempLineData = new Array(); if (i < this.newFZEntityData.length && this.newFZEntityData[i][2] == 1) { TempLineData.push([this.newFZEntityData[i][0], this.newFZEntityData[i][1]]); } if (i + 1 < this.newFZEntityData.length && this.newFZEntityData[i + 1][2] == 2) { TempLineData.push([this.newFZEntityData[i + 1][0], this.newFZEntityData[i + 1][1]]); addCircleToView(this.newFZEntityData[i + 1][0], this.newFZEntityData[i + 1][1], 0.5, 1, FZXColor); } if (i + 2 < this.newFZEntityData.length && this.newFZEntityData[i + 2][2] == 3) { TempLineData.push([this.newFZEntityData[i + 2][0], this.newFZEntityData[i + 2][1]]); } // 计算角度 this.calDeg([this.newFZEntityData[i][0], this.newFZEntityData[i][1]], [this.newFZEntityData[i + 1][0], this.newFZEntityData[i + 1][1]], [this.newFZEntityData[i + 2][0], this.newFZEntityData[i + 2][1]], jdIndx); jdIndx = jdIndx + 1; addPolylinetoView(TempLineData, false, false, 1, FZXColor); i = i + 3; } EAction.handleUserMessage("save csv file start!"); // var fname = this.fileName.substring(0,this.fileName.lastIndexOf("."))+".csv"; var fname = this.fileName.substring(0, this.fileName.lastIndexOf(".")) + "_op.csv"; var file = new QFile(fname); if (file.exists()) { //如果文件存在执行的操作,此处为空,因为文件不可能存在 } file.open(makeQIODeviceOpenMode(QIODevice.WriteOnly, QIODevice.Text)); var out = new QTextStream(file); //写表头 out.writeString("JD_x,JD_y,R,ls\n"); //写数据 for (i = 0; i < this.csvCoor.length; i++) { if (i == 0 || i == this.csvCoor.length - 1) { out.writeString(this.csvCoor[i][0] + "," + this.csvCoor[i][1] + "," + 0 + "," + 0 + "\n"); } else { out.writeString(this.csvCoor[i][0] + "," + this.csvCoor[i][1] + "," + this.csvR[i - 1] + "," + this.csvls[i - 1] + "\n"); } } out.flush(); //写完数据需要关闭文件 file.close(); EAction.handleUserMessage("save csv file success!"); var di = getAssignDocumentInterface(1); if (!isNull(di)) { // di.regenerateScenes(); di.autoZoom(); } return true; }; PM.prototype.readTxt = function (file) { var reader = new QFile(file); var flags = makeQIODeviceOpenMode(QIODevice.ReadOnly, QIODevice.Text); if (!reader.open(flags)) { EAction.handleUserWarning("cannot open file: " + file); return; } //每次都去文件中的一行,然后输出读取到的字符串lyz var ts = new QTextStream(reader); setUtf8Codec(ts); //定义初始值 lyz var pLineNo = 0; var LineStartPointX = 0.0; var LineStartPointY = 0.0; var CurCurveStartPointX = 0.0; var CurCurveStartPointY = 0.0; var CurCurveEndPointX = 0.0; var CurCurveEndPointY = 0.0; var CurCurveZ = 0; var CurCurveS = 0.0; var CurCurveRO = 0.0; var CurCurveRD = 0.0; var CurCurveType = 0; var CurCurveStartZH = 0.0; var CurCurveEndZH = 0.0; var CurCurveStartAngle = 0.0; var CurCurveEndAngle = 0.0; var CurHuanheT = 0.0; var CurCurveCenterPointX = 0.0; var CurCurveCenterPointY = 0.0; var DeltaS = 5.0;//缓和曲线取样点间隔 var TempFZData = new Array();//临时辅助线 liyz //当读取出现错误(返回 -1)或者读取到的字符数为 0 时,结束读取 lyz do { var textLine = ts.readLine().trim(); //EAction.handleUserWarning(textLine); textLine = textLine.replace(/[\t]+/g, " ").replace(/[\s]+/g, " "); textLine = textLine.replace(/\r\n/g, ""); //EAction.handleUserMessage(textLine); var fields = textLine.split(" "); // Reserved: ',&[' & ';&[' if (fields.length < 4 || pLineNo < 1 /*|| pLineNo >10*/) { // With two extra fields > pLineNo++; continue; } // End with two extra if (pLineNo == 1) { // EAction.handleUserMessage("LineCurveTotalNum: " + fields[0]); } else if (pLineNo == 2) { // EAction.handleUserMessage("LineStartLinkMode: " + fields[0]); // EAction.handleUserMessage("LineStartZH: " + fields[1]); // EAction.handleUserMessage("LineStartXY: " + fields[4] + "," + fields[5]); //添加线路起点坐标 lyz LineStartPointX = parseFloat(fields[4]); LineStartPointY = parseFloat(fields[5]); //用曲线入口X1,Y1作为起始位置 lyz CurCurveStartPointX = parseFloat(fields[4]); CurCurveStartPointY = parseFloat(fields[5]); //用桩号/公里标作为起始位置 lyz // CurCurveStartPointX = parseFloat(fields[1]); // CurCurveStartPointY = 0.0; this.csvCoor.push([fields[4], fields[5]]); } else if ((pLineNo - 3) % 3 == 0) { // EAction.handleUserMessage("Curve Z: " + fields[0]); // EAction.handleUserMessage("Curve S: " + fields[2]); // EAction.handleUserMessage("Curve T: " + fields[3]); // EAction.handleUserMessage("Curve RO: " + fields[4]); // EAction.handleUserMessage("Curve RD: " + fields[5]); // EAction.handleUserMessage("Curve Type: " + fields[6]); CurCurveZ = parseInt(fields[0]); CurCurveS = Math.abs(parseFloat(fields[2])); CurHuanheT = parseFloat(fields[3]); CurCurveRO = parseFloat(fields[4]); CurCurveRD = parseFloat(fields[5]); CurCurveType = parseInt(fields[6]); } else if ((pLineNo - 3) % 3 == 1) { //EAction.handleUserMessage("Curve Z:" + fields[0]); //EAction.handleUserMessage("Curve S:" + fields[2]); //EAction.handleUserMessage("Curve RO:" + fields[2]); //EAction.handleUserMessage("Curve RD:" + fields[2]); } else if ((pLineNo - 3) % 3 == 2) { // EAction.handleUserMessage("Curve StartZH: " + fields[0]); // EAction.handleUserMessage("Curve EndZH: " + fields[1]); // EAction.handleUserMessage("Curve StartAngle: " + fields[2]); // EAction.handleUserMessage("Curve EndAngle: " + fields[3]); CurCurveStartZH = parseFloat(fields[0]); CurCurveEndZH = parseFloat(fields[1]); CurCurveStartAngle = parseFloat(fields[2]); CurCurveEndAngle = parseFloat(fields[3]); if (1 == CurCurveType) { //确定直线的起始和终止点 lyz CurCurveEndPointX = CurCurveStartPointX + Math.abs(CurCurveS) * Math.cos(CurCurveStartAngle); CurCurveEndPointY = CurCurveStartPointY + Math.abs(CurCurveS) * Math.sin(CurCurveStartAngle); this.newEntityData.push([CurCurveStartPointX / parseFloat(this.ratio), CurCurveStartPointY / parseFloat(this.ratio), CurCurveEndPointX / parseFloat(this.ratio), CurCurveEndPointY / parseFloat(this.ratio), 0, 0, 0, CurCurveZ, CurCurveType]); } else if (21 == CurCurveType || 22 == CurCurveType) { ////确定直缓和及缓和直曲线的起始和终止点 lyz //var CurCurveStartAngleByCenter = 0.0; //var CurCurveEndAngleByCenter = 0.0; //var TempCurveR = Math.abs(CurCurveS) / Math.abs(CurCurveEndAngle - CurCurveStartAngle); //if (CurCurveZ == 1) { // CurCurveStartAngleByCenter = rad2deg(CurCurveStartAngle) - 90; // CurCurveEndAngleByCenter = rad2deg(CurCurveEndAngle) - 90; //} else if (CurCurveZ == -1) { // CurCurveStartAngleByCenter = rad2deg(CurCurveStartAngle) + 90; // CurCurveEndAngleByCenter = rad2deg(CurCurveEndAngle) + 90; //} //CurCurveCenterPointX = CurCurveStartPointX - TempCurveR * Math.cos(deg2rad(CurCurveStartAngleByCenter)); //CurCurveCenterPointY = CurCurveStartPointY - TempCurveR * Math.sin(deg2rad(CurCurveStartAngleByCenter)); //CurCurveEndPointX = CurCurveCenterPointX + TempCurveR * Math.cos(deg2rad(CurCurveEndAngleByCenter)); //CurCurveEndPointY = CurCurveCenterPointY + TempCurveR * Math.sin(deg2rad(CurCurveEndAngleByCenter)); //this.newEntityData.push([CurCurveCenterPointX / parseFloat(this.ratio), CurCurveCenterPointY / parseFloat(this.ratio), 0, 0, TempCurveR / parseFloat(this.ratio), // CurCurveStartAngleByCenter, CurCurveEndAngleByCenter, CurCurveZ, CurCurveType]); this.CurHuanheTArr.push(CurHuanheT); if (CurCurveZ == 1) { CurCurveStartAngleByCenter = rad2deg(CurCurveStartAngle) - 90; CurCurveEndAngleByCenter = rad2deg(CurCurveEndAngle) - 90; } else if (CurCurveZ == -1) { CurCurveStartAngleByCenter = rad2deg(CurCurveStartAngle) + 90; CurCurveEndAngleByCenter = rad2deg(CurCurveEndAngle) + 90; } var CurCurveDeltaR = Math.abs(CurCurveRD - CurCurveRO); // EAction.handleUserMessage("Curve CurCurveDeltaR: " + CurCurveDeltaR.toString()); var TempStartPointX = CurCurveStartPointX; var TempStartPointY = CurCurveStartPointY; var TempEndPointX = 0; var TempEndPointY = 0; var TempCenterPointX = 0; var TempCenterPointY = 0; var TempStartAngleByCenter = CurCurveStartAngleByCenter; var TempEndAngleByCenter = 0.0; var TempCurveR = 0; //插值求解缓和曲线:计算每个分段曲线(用圆弧或者线段都可以,此处用圆弧)的半径、起始角度、终止角度及圆心,再将分段曲线拟合成缓和曲线,liyz for (var j = 0; j < CurCurveS; j = j + DeltaS) { if (21 == CurCurveType) { TempCurveR = CurCurveRO - (j / CurCurveS) * CurCurveDeltaR; } else { TempCurveR = CurCurveRO + (j / CurCurveS) * CurCurveDeltaR; } // EAction.handleUserMessage("Curve TempCurveR: " + TempCurveR.toString()); if (1 == CurCurveZ) { TempEndAngleByCenter = TempStartAngleByCenter + rad2deg(DeltaS / TempCurveR); } else { TempEndAngleByCenter = TempStartAngleByCenter - rad2deg(DeltaS / TempCurveR); } TempCenterPointX = TempStartPointX - TempCurveR * Math.cos(deg2rad(TempStartAngleByCenter)); TempCenterPointY = TempStartPointY - TempCurveR * Math.sin(deg2rad(TempStartAngleByCenter)); TempEndPointX = TempCenterPointX + TempCurveR * Math.cos(deg2rad(TempEndAngleByCenter)); TempEndPointY = TempCenterPointY + TempCurveR * Math.sin(deg2rad(TempEndAngleByCenter)); this.newEntityData.push([TempCenterPointX / parseFloat(this.ratio), TempCenterPointY / parseFloat(this.ratio), 0, 0, TempCurveR / parseFloat(this.ratio), TempStartAngleByCenter, TempEndAngleByCenter, CurCurveZ, CurCurveType]); //存储临时辅助线数据 if (21 == CurCurveType && j == 0) { TempFZData.push([TempStartPointX, TempStartPointY, CurCurveStartAngle, 1, CurCurveZ]); this.csvls.push(Math.abs(CurCurveS)); } else if (22 == CurCurveType && j + DeltaS >= CurCurveS) { TempFZData.push([TempEndPointX, TempEndPointY, CurCurveEndAngle, 3, CurCurveZ]); } TempStartPointX = TempEndPointX; TempStartPointY = TempEndPointY; TempStartAngleByCenter = TempEndAngleByCenter; if (j + DeltaS >= CurCurveS) { CurCurveEndPointX = TempEndPointX; CurCurveEndPointY = TempEndPointY; } } } else if (3 == CurCurveType) { //确定圆曲线的起始和终止点 lyz var CurCurveStartAngleByCenter = 0.0; var CurCurveEndAngleByCenter = 0.0; if (CurCurveZ == 1) { CurCurveStartAngleByCenter = rad2deg(CurCurveStartAngle) - 90; CurCurveEndAngleByCenter = rad2deg(CurCurveEndAngle) - 90; } else if (CurCurveZ == -1) { CurCurveStartAngleByCenter = rad2deg(CurCurveStartAngle) + 90; CurCurveEndAngleByCenter = rad2deg(CurCurveEndAngle) + 90; } CurCurveCenterPointX = CurCurveStartPointX - CurCurveRO * Math.cos(deg2rad(CurCurveStartAngleByCenter)); CurCurveCenterPointY = CurCurveStartPointY - CurCurveRO * Math.sin(deg2rad(CurCurveStartAngleByCenter)); CurCurveEndPointX = CurCurveCenterPointX + CurCurveRO * Math.cos(deg2rad(CurCurveEndAngleByCenter)); CurCurveEndPointY = CurCurveCenterPointY + CurCurveRO * Math.sin(deg2rad(CurCurveEndAngleByCenter)); this.newEntityData.push([CurCurveCenterPointX / parseFloat(this.ratio), CurCurveCenterPointY / parseFloat(this.ratio), 0, 0, CurCurveRO / parseFloat(this.ratio), CurCurveStartAngleByCenter, CurCurveEndAngleByCenter, CurCurveZ, CurCurveType]); var Rl = abs(deg2rad(CurCurveEndAngleByCenter - CurCurveStartAngleByCenter) * CurCurveRO); this.centerO.push([CurCurveCenterPointX, CurCurveCenterPointY, Rl, (CurCurveEndAngleByCenter - CurCurveStartAngleByCenter)]); this.csvR.push(CurCurveRO); } CurCurveStartPointX = CurCurveEndPointX; CurCurveStartPointY = CurCurveEndPointY; // this.primePointArr.push([CurCurveType, CurCurveStartPointX, CurCurveStartPointY, CurCurveEndZH, CurCurveEndAngle]); } // EAction.handleUserMessage("\n"); pLineNo++; } while (!ts.atEnd()); //处理辅助线点信息 liyz for (var j = 0; j < TempFZData.length - 1; j++) { if (1 == TempFZData[j][3] && 3 == TempFZData[j + 1][3]) { this.newFZEntityData.push([TempFZData[j][0] / parseFloat(this.ratio), TempFZData[j][1] / parseFloat(this.ratio), TempFZData[j][3]]); //计算辅助线交点值 liyz var k_1 = Math.tan(TempFZData[j][2]); var b_1 = TempFZData[j][1] - TempFZData[j][0] * k_1; var k_2 = Math.tan(TempFZData[j + 1][2]); var b_2 = TempFZData[j + 1][1] - TempFZData[j + 1][0] * k_2; var TempJDX = (b_2 - b_1) / (k_1 - k_2); var TempJDY = k_1 * TempJDX + b_1; this.newFZEntityData.push([TempJDX / parseFloat(this.ratio), TempJDY / parseFloat(this.ratio), 2]); this.csvCoor.push([TempJDX / parseFloat(this.ratio), TempJDY / parseFloat(this.ratio)]); this.newFZEntityData.push([TempFZData[j + 1][0] / parseFloat(this.ratio), TempFZData[j + 1][1] / parseFloat(this.ratio), TempFZData[j + 1][3]]); } } // EAction.handleUserMessage("newFZEntityData: " + this.newFZEntityData.toString()); this.applyOperation(); reader.close(); return true; }; PM.prototype.calDeg = function (A, B, C, jdIndx) { var JD_x = B[0]; var JD_y = B[1]; var C_x = this.centerO[jdIndx - 1][0]; var C_y = this.centerO[jdIndx - 1][1]; // 计算向量AB与x轴的夹角 var angleRad = Math.atan2(JD_y - C_y, JD_x - C_x); // 将弧度转换为角度 var angleDeg = rad2deg(angleRad); // 保证角度在0到360度之间 if (angleDeg < 0) { angleDeg += 360.0; } // 相对JD的向圆心的偏移量 var drift_x = Math.cos(deg2rad(angleDeg)); var drift_y = Math.sin(deg2rad(angleDeg)); // JD文本的旋转角度 var angle_vertical = 0; if (0 <= angleDeg && angleDeg < 90) { drift_x = - Math.abs(drift_x); drift_y = - Math.abs(drift_y); angle_vertical = - (90 - angleDeg % 90); } else if (90 <= angleDeg && angleDeg < 180) { drift_x = Math.abs(drift_x); drift_y = - Math.abs(drift_y); angle_vertical = angleDeg % 90; } else if (180 <= angleDeg && angleDeg < 270) { drift_x = Math.abs(drift_x); drift_y = Math.abs(drift_y); angle_vertical = - (90 - angleDeg % 90); } else { drift_x = - Math.abs(drift_x); drift_y = Math.abs(drift_y); angle_vertical = angleDeg % 90; } if (angleDeg > 180) { // 标注文本方向始终是JD向内的方向 angle_vertical = angle_vertical + 180; } // 交点和圆心的的连线 // addLineToView([JD_x, JD_y], [C_x, C_y], 1); // EAction.handleUserMessage("jdIndx: " + jdIndx.toString() + ", angleDeg:" + angleDeg.toString() + ",angleDeg % 90:" + (angleDeg % 90).toString()+ ",angle_vertical:" + angle_vertical.toString()); // JD标注 addSimpleTextToView("JD" + jdIndx.toString(), [JD_x - 20 * drift_x - 10, JD_y - 20 * drift_y], 15, angle_vertical, "Standard", RS.VAlignTop, RS.HAlignLeft, false, false, 1); // 圆心和JD连接与圆的交叉点 var cross_x = C_x - this.csvR[jdIndx - 1] * drift_x; var cross_y = C_y - this.csvR[jdIndx - 1] * drift_y; // 标注和交叉点的距离 var distance = 150; var angle = this.centerO[jdIndx - 1][3]; var textArray = new Array(); textArray.push("JD" + jdIndx.toString()); // textArray.push("az-" + this.centerO[jdIndx - 1][3].toString()); var deg = Math.floor(angle); var min = Math.floor((angle - deg) * 60); var sec = Math.floor(((angle - deg) * 60 - min) * 60); textArray.push("az-" + deg.toString() + "°" + min.toString() + "'" + sec.toString() + "''"); textArray.push("R-" + this.csvR[jdIndx - 1].toString()); textArray.push("l-" + this.csvls[jdIndx - 1].toString()); textArray.push("T-" + (round(this.CurHuanheTArr[jdIndx - 1] * 1000) / 1000).toString()); textArray.push("L-" + (round(this.centerO[jdIndx - 1][2] * 1000) / 1000).toString()); for (var i = 0; i < textArray.length; i++) { var text_x = (distance + 25 * i) * drift_x + cross_x; var text_y = (distance + 25 * i) * drift_y + cross_y; addSimpleTextToView(textArray[i], [text_x, text_y], 15, angle_vertical, "Standard", RS.VAlignTop, RS.HAlignLeft, false, false, 1); } return true; }; PM.prototype.drawPrimeTxt = function () { var digree = rad2deg(this.primePointArr[i][4]) + 90; if (1 == this.primePointArr[i][0]) { addSimpleTextToView("ZH +" + this.primePointArr[i][3].toString(), [this.primePointArr[i][1] + 1, this.primePointArr[i][2]], 15, digree, "Standard", RS.VAlignTop, RS.HAlignLeft, false, false, 1); } else if (21 == this.primePointArr[i][0]) { addSimpleTextToView("HY +" + this.primePointArr[i][3].toString(), [this.primePointArr[i][1] + 1, this.primePointArr[i][2]], 15, digree, "Standard", RS.VAlignTop, RS.HAlignLeft, false, false, 1); } else if (3 == this.primePointArr[i][0]) { addSimpleTextToView("YH +" + this.primePointArr[i][3].toString(), [this.primePointArr[i][1] + 1, this.primePointArr[i][2]], 15, digree, "Standard", RS.VAlignTop, RS.HAlignLeft, false, false, 1); } else { addSimpleTextToView("HZ +" + this.primePointArr[i][3].toString(), [this.primePointArr[i][1] + 1, this.primePointArr[i][2]], 15, digree, "Standard", RS.VAlignTop, RS.HAlignLeft, false, false, 1); } }; PM.prototype.compute_offset = function (origin, target) { var origin_x = origin[0]; var origin_y = origin[1]; var target_x = target[0]; var target_y = target[1]; // 计算向量AB与x轴的夹角 var angleRad = Math.atan2(origin_y - target_y, origin_x - target_x); // 将弧度转换为角度 var angleDeg = rad2deg(angleRad); // 保证角度在0到360度之间 if (angleDeg < 0) { angleDeg += 360.0; } // target向origin偏移量 var drift_x = Math.cos(deg2rad(angleDeg)); var drift_y = Math.sin(deg2rad(angleDeg)); // JD文本的旋转角度 var vertical_angle = 0; var vertical_drift_x = 0; var vertical_drift_y = 0; if (0 <= angleDeg && angleDeg < 90) { drift_x = -Math.abs(drift_x); drift_y = -Math.abs(drift_y); vertical_angle = -(90 - (angleDeg % 90)); vertical_drift_x = Math.abs(Math.cos(deg2rad(vertical_angle))); vertical_drift_y = - Math.abs(Math.sin(deg2rad(vertical_angle))); } else if (90 <= angleDeg && angleDeg < 180) { drift_x = Math.abs(drift_x); drift_y = -Math.abs(drift_y); vertical_angle = angleDeg % 90; vertical_drift_x = Math.abs(Math.cos(deg2rad(vertical_angle))); vertical_drift_y = Math.abs(Math.sin(deg2rad(vertical_angle))); } else if (180 <= angleDeg && angleDeg < 270) { drift_x = Math.abs(drift_x); drift_y = Math.abs(drift_y); vertical_angle = -(90 - (angleDeg % 90)); vertical_drift_x = Math.abs(Math.cos(deg2rad(vertical_angle))); vertical_drift_y = - Math.abs(Math.sin(deg2rad(vertical_angle))); } else { drift_x = -Math.abs(drift_x); drift_y = Math.abs(drift_y); vertical_angle = angleDeg % 90; vertical_drift_x = Math.abs(Math.cos(deg2rad(vertical_angle))); vertical_drift_y = Math.abs(Math.sin(deg2rad(vertical_angle))); } return new Array(drift_x, drift_y, angleDeg, vertical_drift_x, vertical_drift_y, vertical_angle); }; PM.prototype.mileage_line = function (CurCurveType, origin, target, ZXColor, isPrime) { var origin_x = origin[0]; var origin_y = origin[1]; var target_x = target[0]; var target_y = target[1]; var distance = Math.sqrt(Math.pow(target_x - origin_x, 2) + Math.pow(target_y - origin_y, 2)); var distanceNext = 100 - (this.mileage % 100); if (isPrime && 0 !== this.mileage) { var angle_prime = this.compute_offset(origin, target)[5]; if (1 == CurCurveType) { addSimpleTextToView("ZH +" + (round(this.mileage % 1000 * 1000) / 1000).toString(), [origin_x, origin_y], 15, angle_prime + 90, "Standard", RS.VAlignTop, RS.HAlignLeft, false, false, 1); } else if (21 == CurCurveType) { addSimpleTextToView("HY +" + (round(this.mileage % 1000 * 1000) / 1000).toString(), [origin_x, origin_y], 15, angle_prime + 90, "Standard", RS.VAlignTop, RS.HAlignLeft, false, false, 1); } else if (3 == CurCurveType) { addSimpleTextToView("YH +" + (round(this.mileage % 1000 * 1000) / 1000).toString(), [origin_x, origin_y], 15, angle_prime + 90, "Standard", RS.VAlignTop, RS.HAlignLeft, false, false, 1); } else { addPolylinetoView(new Array([origin_x, origin_y], [origin_x + 150 * Math.cos(deg2rad(angle_prime)), origin_y + 150 * Math.sin(deg2rad(angle_prime))]), false, false, 1, ZXColor); var origin_text_x = origin_x + 18 * Math.abs(Math.cos(deg2rad(angle_prime + 90))) + 15 * Math.cos(deg2rad(angle_prime)); var origin_text_y = origin_y + 18 * Math.abs(Math.sin(deg2rad(angle_prime + 90))) + 15 * Math.sin(deg2rad(angle_prime)); addSimpleTextToView("HZ +" + (round(this.mileage % 1000 * 1000) / 1000).toString(), [origin_text_x, origin_text_y], 15, angle_prime, "Standard", RS.VAlignTop, RS.HAlignLeft, false, false, 1); } } if (distance < distanceNext) { // 不足下一个百米标的位置直接返回 this.mileage += distance; return; } this.mileage += distanceNext; var offset = this.compute_offset(origin, target); var offset_x = offset[0]; var offset_y = offset[1]; var angle = offset[2]; var offset_vertical_x = offset[3]; var offset_vertical_y = offset[4]; var angle_vertical = offset[5]; // 下一个百米标的坐标 var x = origin_x + distanceNext * offset_x; var y = origin_y + distanceNext * offset_y; // addPolylinetoView(new Array([x, y], [x - 20 * offset_vertical_x, y - 20 * offset_vertical_y]), false, false, 0, ZXColor); // addPolylinetoView(new Array([x, y], [x + 20 * offset_vertical_x, y + 20 * offset_vertical_y]), false, false, 0, ZXColor); var text = this.mileage % 1000 == 0 ? "K " + this.mileage / 1000 : (this.mileage / 100) % 10; // EAction.handleUserMessage("--mileage_line: " + this.mileage.toString() + ", angle: " + angle.toString() + ", angle_vertical: " + angle_vertical.toString()); // EAction.handleUserMessage("--mileage_line: offset_vertical_x: " + offset_vertical_x.toString() + ", offset_vertical_y: " + offset_vertical_y.toString()); addPolylinetoView(new Array([x, y], [x + 10 * offset_vertical_x, y + 10 * offset_vertical_y]), false, false, 1, ZXColor); addSimpleTextToView(text.toString(), [x + 20 * offset_vertical_x, y + 20 * offset_vertical_y], 15, angle_vertical, "Standard", RS.VAlignTop, RS.HAlignLeft, false, false, 1); // var isReverse = angle > 90 && angle < 270; // addPolylinetoView(new Array([x, y], [x + (isReverse?1:-1) * 10 * offset_vertical_x, y + (isReverse?1:-1) * 10 * offset_vertical_y]), false, false, 0, ZXColor); // addSimpleTextToView(text.toString(), [x + (isReverse?1:-1) * 20 * offset_vertical_x, y + (isReverse?1:-1) * 20 * offset_vertical_y], 15, isReverse ? angle-90 : angle, "Standard" , RS.VAlignTop, RS.HAlignLeft, false, false, 0); this.mileage_line(CurCurveType, new Array(x, y), target, ZXColor, false); }; PM.prototype.mileage_circle = function (CurCurveType, center, radius, startAngle, endAngle, reversed, ZXColor, isPrime) { var center_x = center[0]; var center_y = center[1]; var angle_gap = startAngle - endAngle; var distance = radius * deg2rad(Math.abs(angle_gap)); var distanceNext = 100 - (this.mileage % 100); if (isPrime && 0 !== this.mileage) { var prime_offset_x = Math.abs(Math.cos(deg2rad(startAngle))); var prime_offset_y = Math.abs(Math.sin(deg2rad(startAngle))); var tmp_startAngle = (startAngle + 360) % 360; if (tmp_startAngle <= 90) { prime_offset_x = prime_offset_x; prime_offset_y = prime_offset_y; } else if (tmp_startAngle > 90 && tmp_startAngle <= 180) { prime_offset_x = - prime_offset_x; prime_offset_y = prime_offset_y; } else if (tmp_startAngle > 180 && tmp_startAngle <= 270) { prime_offset_x = - prime_offset_x; prime_offset_y = - prime_offset_y; } else { prime_offset_x = prime_offset_x; prime_offset_y = - prime_offset_y; } var prime_x = center_x + radius * prime_offset_x; var prime_y = center_y + radius * prime_offset_y; var angle_prime = this.compute_offset(new Array(prime_x, prime_y), new Array(center_x, center_y))[5]; var reverse_prime = angle_prime > 0 && angle_prime < 90; var angle_prime_text = reverse_prime ? angle_prime - 90 : angle_prime + 90; // EAction.handleUserMessage("---mileage: " + this.mileage.toString()+",angle_prime_text:"+angle_prime_text.toString()); addPolylinetoView(new Array([prime_x, prime_y], [prime_x + 150 * Math.cos(deg2rad(angle_prime_text)), prime_y + 150 * Math.sin(deg2rad(angle_prime_text))]), false, false, 1, ZXColor); var prime_text_x = prime_x + 18 * Math.abs(Math.cos(deg2rad(angle_prime_text + 90))) + 15 * Math.cos(deg2rad(angle_prime_text)); var prime_text_y = prime_y + 18 * Math.abs(Math.sin(deg2rad(angle_prime_text + 90))) + 15 * Math.sin(deg2rad(angle_prime_text)); if (1 == CurCurveType) { addSimpleTextToView("ZH +" + (round(this.mileage % 1000 * 1000) / 1000).toString(), [prime_text_x, prime_text_y], 15, angle_prime_text, "Standard", RS.VAlignTop, RS.HAlignLeft, false, false, 1); } else if (21 == CurCurveType) { addSimpleTextToView("HY +" + (round(this.mileage % 1000 * 1000) / 1000).toString(), [prime_text_x, prime_text_y], 15, angle_prime_text, "Standard", RS.VAlignTop, RS.HAlignLeft, false, false, 1); } else if (3 == CurCurveType) { addSimpleTextToView("YH +" + (round(this.mileage % 1000 * 1000) / 1000).toString(), [prime_text_x, prime_text_y], 15, angle_prime_text, "Standard", RS.VAlignTop, RS.HAlignLeft, false, false, 1); } else { addSimpleTextToView("HZ +" + (round(this.mileage % 1000 * 1000) / 1000).toString(), [prime_text_x, prime_text_y], 15, angle_prime_text, "Standard", RS.VAlignTop, RS.HAlignLeft, false, false, 1); } } if (distance < distanceNext) { // 不足下一个百米标的位置直接返回 this.mileage += distance; return; } this.mileage += distanceNext; var newAngle = startAngle + (angle_gap > 0 ? -1 : 1) * rad2deg(distanceNext / radius); var new_offset_x = Math.abs(Math.cos(deg2rad(newAngle))); var new_offset_y = Math.abs(Math.sin(deg2rad(newAngle))); // 计算坐标偏移方向 var tmp_angle = (newAngle + 360) % 360; if (tmp_angle <= 90) { new_offset_x = new_offset_x; new_offset_y = new_offset_y; } else if (tmp_angle > 90 && tmp_angle <= 180) { new_offset_x = - new_offset_x; new_offset_y = new_offset_y; } else if (tmp_angle > 180 && tmp_angle <= 270) { new_offset_x = - new_offset_x; new_offset_y = - new_offset_y; } else { new_offset_x = new_offset_x; new_offset_y = - new_offset_y; } var new_x = center_x + radius * new_offset_x; var new_y = center_y + radius * new_offset_y; // 开始画线 var offset = this.compute_offset(new Array(new_x, new_y), new Array(center_x, center_y)); var offset_x = offset[0]; var offset_y = offset[1]; var angle = offset[3]; var angle_vertical = offset[5]; // addPolylinetoView(new Array([new_x, new_y], [new_x - 20 * offset_x, new_y - 20 * offset_y]), false, false, 0, ZXColor); // addPolylinetoView(new Array([new_x, new_y], [new_x + 20 * offset_x, new_y + 20 * offset_y]), false, false, 0, ZXColor); var text = this.mileage % 1000 == 0 ? "K " + this.mileage / 1000 : (this.mileage / 100) % 10; var isReverse = tmp_angle > 90 && tmp_angle < 270; // EAction.handleUserMessage("--mileage_circle: " + this.mileage.toString() + ", tmp_angle: " + tmp_angle.toString() + ",angle: " + angle.toString() + ", angle_vertical: " + angle_vertical.toString()); // EAction.handleUserMessage("--mileage_circle: offset_x: " + offset_x.toString() + ", offset_y: " + offset_y.toString()); addPolylinetoView(new Array([new_x, new_y], [new_x + (isReverse ? 1 : -1) * 10 * offset_x, new_y + (isReverse ? 1 : -1) * 10 * offset_y]), false, false, 1, ZXColor); addSimpleTextToView(text.toString(), [new_x + (isReverse ? 1 : -1) * 20 * offset_x, new_y + (isReverse ? 1 : -1) * 20 * offset_y], 15, isReverse ? tmp_angle - 180 : tmp_angle, "Standard", RS.VAlignTop, RS.HAlignLeft, false, false, 1); // addPolylinetoView(new Array([new_x, new_y], [new_x + 10 * offset_x, new_y + 10 * offset_y]), false, false, 0, ZXColor); // addSimpleTextToView(text.toString(), [new_x + 20 * offset_x, new_y + 20 * offset_y], 15, isReverse ? angle_vertical + 270 :angle_vertical-90, "Standard" , RS.VAlignTop, RS.HAlignLeft, false, false, 0); this.mileage_circle(CurCurveType, center, radius, newAngle, endAngle, reversed, ZXColor, false); };