Measure.js 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215
  1. import * as THREE from "../../libs/three.js/build/three.module.js";
  2. import {TextSprite} from "../TextSprite.js";
  3. import {Utils} from "../utils.js";
  4. import Label from "./Label.js";
  5. import {LineDraw} from "../utils/DrawUtil";
  6. import math from "./math.js";
  7. import DepthBasicMaterial from "../materials/DepthBasicMaterial.js";
  8. import Sprite from '../viewer/Sprite'
  9. import {config} from '../settings'
  10. import {ctrlPolygon} from './ctrlPolygon'
  11. let texLoader = new THREE.TextureLoader()
  12. let color = new THREE.Color(config.measure.lineColor)
  13. let textColor = new THREE.Color(config.measure.textColor)
  14. let highLightColor = new THREE.Color(config.measure.highLightColor)
  15. var markerMats;
  16. var lineMats;
  17. var planeMats
  18. const markerSizeInfo = {
  19. minSize : 25 , maxSize : 65, nearBound : 0.2, farBound : 4,
  20. }
  21. const labelSizeInfo = {width2d:200}
  22. const mainLabelProp = {
  23. backgroundColor: {r: color.r*255, g: color.g*255, b: color.b*255, a:config.measure.labelOpacity},
  24. textColor: {r: textColor.r*255, g: textColor.g*255, b: textColor.b*255, a: 1.0},
  25. fontsize:16,
  26. useDepth : true ,
  27. renderOrder : 5
  28. }
  29. const subLabelProp = {
  30. backgroundColor: {r: 255, g: 255, b: 255, a:1},
  31. textColor: {r: 0, g: 0, b:0, a: 1.0},
  32. fontsize:14,
  33. renderOrder : 4
  34. }
  35. const angle = THREE.Math.degToRad(5);//显示水平垂直辅助线的最小角度
  36. const guideShowMinAngle = {min: angle, max: Math.PI/2 - angle}
  37. export class Measure extends ctrlPolygon{
  38. constructor (prop) {
  39. prop.dimension = '2d'
  40. super('measure',prop);
  41. this.constructor.counter = (this.constructor.counter === undefined) ? 0 : this.constructor.counter + 1;
  42. this.name = this.measureType + this.constructor.counter //'Measure_' + this.constructor.counter;
  43. this.color = new THREE.Color(config.measure.lineColor)//new THREE.Color(0xff0000);
  44. this.markerLabels = [];
  45. this.edgeLabels = [];
  46. this.angleLabels = [];
  47. this.coordinateLabels = [];
  48. this.area = {value:0,string:''}
  49. if(this.closed/* this.showArea */){
  50. this.areaLabel = this.createAreaLabel();
  51. this.add(this.areaLabel)
  52. }
  53. //add:
  54. if(this.maxMarkers > 2 || this.faceDirection){
  55. this.createGuideLine();
  56. }
  57. if(this.measureType == 'Distance'){
  58. this.createHorVerGuideLine()
  59. }
  60. this.selectStates = {}
  61. this.setUnitSystem(prop.unit || viewer.unitConvert.UnitService.defaultSystem)
  62. viewer.setObjectLayers(this, 'measure' )
  63. //addMarkers:
  64. this.initData(prop)
  65. this.points_datasets || (this.points_datasets = []) //存每个点是哪个数据集
  66. this.addEventListener('marker_dropped',(e)=>{
  67. this.updateDatasetBelong()
  68. })
  69. this.addEventListener('isVisible', ()=>{
  70. viewer.mapViewer.dispatchEvent({type:'content_changed'})
  71. })
  72. }
  73. updateDatasetBelong(){//更新所属数据集
  74. let old = this.datasetId
  75. let maxCount = {id:null,count:0}
  76. let datasets = {}
  77. this.points_datasets.forEach(e=>{
  78. if(e == void 0)return
  79. if(datasets[e]){
  80. datasets[e] ++
  81. }else{
  82. datasets[e] = 1
  83. }
  84. })
  85. for(let i in datasets) {
  86. if(datasets[i]>maxCount.count){
  87. maxCount = {id:i, count:datasets[i]}
  88. }
  89. }
  90. this.datasetId = maxCount.count > 0 ? maxCount.id : null
  91. if(this.datasetId != old){
  92. this.dispatchEvent({type:'changeDatasetId'})
  93. if(this.datasetId == void 0){
  94. this.dataset_points = null //可能为空或[null,null...]
  95. }else{
  96. this.dataset_points = this.points.map(e=>{
  97. return Potree.Utils.datasetPosTransform({toDataset:true,datasetId:this.datasetId, position:e.clone()})
  98. })
  99. }
  100. }
  101. }
  102. transformByPointcloud(){//每次移动点云 or 加载测量线时要获取一下当前position
  103. if(this.datasetId == void 0)return
  104. this.points = this.dataset_points.map(e=>{
  105. return Potree.Utils.datasetPosTransform({fromDataset:true, datasetId:this.datasetId, position:e.clone()})
  106. })
  107. this.getPoint2dInfo(this.points)
  108. this.update(true)
  109. this.setSelected(false)//隐藏edgelabel
  110. }
  111. update(ifUpdateMarkers) {
  112. super.update(ifUpdateMarkers)
  113. if(this.showCoordinates && this.points.length>0){
  114. let position = this.points[0];
  115. this.markers[0].position.copy(position);
  116. { // coordinate labels
  117. let coordinateLabel = this.coordinateLabels[0];
  118. let lonlat = viewer.transform.lonlatToLocal.inverse(position.toArray())
  119. let EPSG4550 = viewer.transform.lonlatTo4550.forward(lonlat)
  120. let pos = [
  121. position.toArray(),
  122. lonlat,
  123. EPSG4550
  124. ]
  125. //let msg = position.toArray().map(p => Utils.addCommas(p.toFixed(2))).join(" / ");
  126. let msg = pos.map(a=>
  127. a.map(p => Utils.addCommas(p.toFixed(10))).join(", ")
  128. ).join("<br>")
  129. coordinateLabel.setText(msg);
  130. coordinateLabel.setPos(position)
  131. coordinateLabel.setVisible(true)//this.showCoordinates;
  132. }
  133. return
  134. }
  135. let setEdgeLabel = (label,p1,p2,distance)=>{//设置label位置和字
  136. let center = new THREE.Vector3().addVectors(p1,p2).multiplyScalar(0.5);
  137. label.setPos(center)
  138. distance = distance == void 0 ? p1.distanceTo(p2) : distance;
  139. var text = viewer.unitConvert.convert(distance, 'distance', void 0, this.unitSystem, 0.1 , true)//distance要传0.1 这个factor
  140. label.setText(text)
  141. return distance
  142. }
  143. let lastIndex = this.points.length - 1;
  144. for (let index = 0; index <= lastIndex; index++) {
  145. let nextIndex = (index + 1 > lastIndex) ? 0 : index + 1;
  146. let previousIndex = (index === 0) ? lastIndex : index - 1;
  147. let point = this.points[index];
  148. let nextPoint = this.points[nextIndex];
  149. let previousPoint = this.points[previousIndex];
  150. if(this.showDistances){ // edge labels
  151. let edgeLabel = this.edgeLabels[index];
  152. let distance = point.distanceTo(nextPoint)
  153. edgeLabel.shouldVisi = (index < lastIndex || this.isRect || this.closed && !this.isNew /* && this.points.length > 2 */) && distance>0
  154. /* this.closed || */edgeLabel.setVisible(edgeLabel.shouldVisi)
  155. if(edgeLabel.visible){
  156. setEdgeLabel(edgeLabel,point,nextPoint,distance)
  157. }
  158. }
  159. }
  160. if(this.measureType == 'Distance' && this.points.length>1){//设置水平垂直辅助线
  161. var pTop, pBtm
  162. if(this.points[0].z > this.points[1].z ){
  163. pTop = this.points[0];
  164. pBtm = this.points[1];
  165. }else{
  166. pTop = this.points[1];
  167. pBtm = this.points[0];
  168. }
  169. let projectPos = new THREE.Vector3(pTop.x, pTop.y, pBtm.z);//两条guideline的交点
  170. {//倾斜角度太小的时候不显示
  171. let tan = pTop.distanceTo(projectPos) / pBtm.distanceTo(projectPos)
  172. let angle = Math.atan(tan);
  173. this.shouldShowHorVerGuide = angle > guideShowMinAngle.min && angle < guideShowMinAngle.max
  174. }
  175. LineDraw.updateLine(this.verGuideEdge, [pTop, projectPos])
  176. LineDraw.updateLine(this.horGuideEdge, [pBtm, projectPos])
  177. setEdgeLabel(this.verEdgeLabel,pTop,projectPos)
  178. setEdgeLabel(this.horEdgeLabel,pBtm,projectPos)
  179. this.verGuideEdge.visible = this.horGuideEdge.visible = this.shouldShowHorVerGuide
  180. this.verEdgeLabel.visible = this.horEdgeLabel.visible = this.shouldShowHorVerGuide
  181. }
  182. if(this.showArea && this.point2dInfo){ // update area
  183. /* if(this.points.length>2){
  184. this.area = {value:0};
  185. this.areaLabel.setVisible(false)
  186. }else{ */
  187. let area = Math.abs(math.getArea(this.point2dInfo.points2d))//this.getArea();
  188. let msg = viewer.unitConvert.convert(area, 'area', void 0, this.unitSystem/* , 0.1 */ )
  189. this.area = {value:area, string:msg}
  190. this.areaLabel.setPos(this.center);
  191. this.areaLabel.setText(msg);
  192. this.areaLabel.setVisible(true)
  193. //}
  194. }
  195. };
  196. addHoverEvent(){ //当非isNew时才添加事件
  197. super.addHoverEvent()
  198. this.edges.forEach(edge=>{
  199. let mouseover = (e) => {this.setSelected(true, 'edge')};
  200. let mouseleave = (e) => {this.setSelected(false, 'edge')};
  201. edge.addEventListener('mouseover', mouseover);
  202. edge.addEventListener('mouseleave', mouseleave);
  203. })
  204. }
  205. addMarker (o={}) {
  206. let marker = new Sprite({mat:this.getMarkerMaterial('default'), sizeInfo: markerSizeInfo, name:"measure_point"} )
  207. viewer.setObjectLayers(marker, 'measure' )
  208. marker.renderOrder = 3
  209. marker.markerSelectStates = {}
  210. let edge
  211. { // edges
  212. edge = LineDraw.createFatLine( [
  213. 0, 0, 0,
  214. 0, 0, 0,
  215. ],{material:this.getLineMat('edgeDefault')} )
  216. viewer.setObjectLayers(edge, 'measure' )
  217. }
  218. super.addMarker({point:o.point, marker:marker, edge})
  219. if(this.showEdges){ // edge labels
  220. const edgeLabel = this.createEdgeLabel('edgeLabel', !this.closed)
  221. this.edgeLabels.push(edgeLabel);
  222. }
  223. if(this.showCoordinates){ // coordinate labels
  224. let coordinateLabel = new Label({
  225. className:'measure_pointPos',
  226. camera: viewer.scene.getActiveCamera()
  227. })
  228. coordinateLabel.setVisible(false)
  229. this.coordinateLabels.push(coordinateLabel);
  230. }
  231. let event = {
  232. type: 'marker_added',
  233. measurement: this,
  234. marker: marker
  235. };
  236. this.dispatchEvent(event);
  237. //this.setMarker(this.points.length - 1, point);
  238. this.update()//更新一下倒数第二条线
  239. return marker;//add
  240. };
  241. editStateChange(state){ //主要针对edgeLabels显示切换,编辑时显示
  242. super.editStateChange(state)
  243. if(!state){
  244. this.editStateTimer = setTimeout(()=>{
  245. if(!this.isEditing){
  246. this.dispatchEvent({type:'editStateChange',state:false})
  247. this.setEdgesDisplay(false)
  248. }
  249. },100)
  250. }else{
  251. if(!this.isEditing){
  252. this.dispatchEvent({type:'editStateChange',state:true})
  253. this.setEdgesDisplay(true)
  254. clearTimeout(this.editStateTimer)
  255. }
  256. }
  257. this.isEditing = state
  258. }
  259. setMarkerSelected(marker, state, hoverObject){
  260. //console.warn(marker.id , state, hoverObject)
  261. marker.markerSelectStates[hoverObject] = state
  262. let absoluteState = false
  263. for(var i in marker.markerSelectStates){
  264. if(marker.markerSelectStates[i]){
  265. absoluteState = true; break;
  266. }
  267. }
  268. if(absoluteState){
  269. marker.material = this.getMarkerMaterial('select')
  270. }else{
  271. marker.material = this.getMarkerMaterial('default')
  272. }
  273. marker.selected = absoluteState
  274. viewer.mapViewer.emit('content_changed')
  275. }
  276. setEdgesDisplay(state, ignoreGuideLine){
  277. this.closed && this.edgeLabels.forEach(e=>e.setVisible(!!(state && e.shouldVisi)) )
  278. if(!ignoreGuideLine && this.measureType == 'Distance'){
  279. this.horEdgeLabel.visible = this.verEdgeLabel.visible = this.horGuideEdge.visible = this.verGuideEdge.visible = !!(state && this.shouldShowHorVerGuide)
  280. }
  281. }
  282. setSelected(state, hoverObject){//add
  283. hoverObject && (this.selectStates[hoverObject] = state)
  284. let absoluteState = false
  285. for(var i in this.selectStates){
  286. if(this.selectStates[i]){
  287. absoluteState = true; break;
  288. }
  289. }
  290. if(absoluteState){
  291. this.markers.forEach(e=>this.setMarkerSelected(e,true,'selectAll' ) )
  292. this.edges.forEach(e=>e.material = this.getLineMat('edgeSelect') )
  293. this.areaPlane && (this.areaPlane.material = planeMats.selected)
  294. //this.areaLabel && this.areaLabel.elem.addClass('highLight')
  295. //this.closed || this.edgeLabels.forEach(e=>e.elem.addClass('highLight') )
  296. this.setEdgesDisplay(true, hoverObject=="screenshot")
  297. this.areaLabel && setLabelHightState(this.areaLabel, true)
  298. this.closed || this.edgeLabels.forEach(e=>setLabelHightState(e, true) )
  299. }else{
  300. this.markers.forEach(e=>this.setMarkerSelected(e,false,'selectAll' ))
  301. this.edges.forEach(e=>e.material = this.getLineMat('edgeDefault') )
  302. this.areaPlane && (this.areaPlane.material = planeMats.default)
  303. this.setEdgesDisplay(false, hoverObject=="screenshot")
  304. //this.areaLabel && this.areaLabel.elem.removeClass('highLight')
  305. //this.closed || this.edgeLabels.forEach(e=>e.elem.removeClass('highLight') )
  306. this.areaLabel && setLabelHightState(this.areaLabel, false)
  307. this.closed || this.edgeLabels.forEach(e=>setLabelHightState(e, false) )
  308. }
  309. this.selected = absoluteState
  310. viewer.mapViewer.emit('content_changed')
  311. if(hoverObject != 'byList'){
  312. this.bus && this.bus.emit('highlight', this.selected)//列表高亮
  313. }
  314. }
  315. removeMarker(index ){
  316. super.removeMarker(index)
  317. this.points_datasets.splice(index, 1);
  318. this.dataset_points && this.dataset_points.splice(index, 1)
  319. this.coordinateLabels.splice(index, 1);
  320. let edgeIndex = index//(index === 0) ? 0 : (index - 1);
  321. if(this.edgeLabels[edgeIndex]){
  322. this.edgeLabels[edgeIndex].dispose()
  323. this.edgeLabels.splice(edgeIndex, 1);
  324. }
  325. this.update();
  326. this.dispatchEvent({type: 'marker_removed', measurement: this});
  327. }
  328. setPosition(index, position) {
  329. super.setPosition(index, position)
  330. let event = {
  331. type: 'marker_moved',
  332. measure: this,
  333. index: index,
  334. position: position.clone()
  335. };
  336. this.dispatchEvent(event);
  337. }
  338. dispose(){//add
  339. var labels = this.edgeLabels.concat(this.coordinateLabels)
  340. this.areaLabel && labels.push(this.areaLabel)
  341. labels.forEach(e=>e.dispose())
  342. super.dispose()
  343. }
  344. getTotalDistance () {
  345. if (this.points.length === 0) {
  346. return 0;
  347. }
  348. let distance = 0;
  349. for (let i = 1; i < this.points.length; i++) {
  350. let prev = this.points[i - 1];
  351. let curr = this.points[i];
  352. let d = prev.distanceTo(curr);
  353. distance += d;
  354. }
  355. if (this.closed && this.points.length > 1) {
  356. let first = this.points[0];
  357. let last = this.points[this.points.length - 1];
  358. let d = last.distanceTo(first);
  359. distance += d;
  360. }
  361. return distance;
  362. }
  363. getAngleBetweenLines (cornerPoint, point1, point2) {
  364. let v1 = new THREE.Vector3().subVectors(point1, cornerPoint);
  365. let v2 = new THREE.Vector3().subVectors(point2, cornerPoint);
  366. // avoid the error printed by threejs if denominator is 0
  367. const denominator = Math.sqrt( v1.lengthSq() * v2.lengthSq() );
  368. if(denominator === 0){
  369. return 0;
  370. }else{
  371. return v1.angleTo(v2);
  372. }
  373. };
  374. getAngle (index) {
  375. if (this.points.length < 3 || index >= this.points.length) {
  376. return 0;
  377. }
  378. let previous = (index === 0) ? this.points[this.points.length - 1] : this.points[index - 1];
  379. let point = this.points[index];
  380. let next = this.points[(index + 1) % (this.points.length)];
  381. return this.getAngleBetweenLines(point, previous, next);
  382. }
  383. getCenter(/* update */){
  384. if(this.points.length>=3){
  385. return this.center.clone()
  386. }else if(this.points.length == 2){
  387. return this.points[0].clone().add((this.points[1])).multiplyScalar(0.5)
  388. }else return this.points[0].clone()
  389. }
  390. // updateAzimuth(){
  391. // // if(this.points.length !== 2){
  392. // // return;
  393. // // }
  394. // // const azimuth = this.azimuth;
  395. // // const [p0, p1] = this.points;
  396. // // const r = p0.distanceTo(p1);
  397. // }
  398. createGuideLine(){//add 辅助线
  399. var guideLine = LineDraw.createFatLine([
  400. 0, 0, 0,
  401. 0, 0, 0,
  402. ],{material:this.getLineMat('guide')} )
  403. guideLine.visible = false
  404. this.guideLine = guideLine
  405. this.add(guideLine);
  406. }
  407. createHorVerGuideLine(){//创建水平与垂直辅助线,仅距离测量有。
  408. var verGuideEdge = LineDraw.createFatLine([
  409. 0, 0, 0,
  410. 0, 0, 0,
  411. ],{material:this.getLineMat('guide')} )
  412. verGuideEdge.visible = false
  413. this.verGuideEdge = verGuideEdge
  414. var horGuideEdge = LineDraw.createFatLine([
  415. 0, 0, 0,
  416. 0, 0, 0,
  417. ],{material:this.getLineMat('guide')} )
  418. horGuideEdge.visible = false
  419. this.horGuideEdge = horGuideEdge
  420. this.add(this.verGuideEdge);
  421. this.add(this.horGuideEdge);
  422. //label:
  423. this.verEdgeLabel = this.createEdgeLabel('verGuideEdge')
  424. this.horEdgeLabel = this.createEdgeLabel('horGuideEdge')
  425. }
  426. createEdgeLabel(name, hasHoverEvent){
  427. const edgeLabel = new TextSprite(
  428. $.extend(hasHoverEvent ? mainLabelProp : subLabelProp,{sizeInfo: labelSizeInfo, name:name||'edgeLabel'})
  429. )
  430. if(hasHoverEvent){
  431. edgeLabel.addEventListener('mouseover',()=>{
  432. this.setSelected(true, 'edgeLabel')
  433. })
  434. edgeLabel.addEventListener('mouseleave',()=>{
  435. this.setSelected(false, 'edgeLabel')
  436. })
  437. edgeLabel.addEventListener('click',()=>{
  438. viewer.focusOnObject(this, 'measure')
  439. })
  440. }
  441. edgeLabel.visible = false
  442. viewer.setObjectLayers(edgeLabel, 'measure' )
  443. this.add(edgeLabel)
  444. return edgeLabel
  445. }
  446. createAreaLabel(){
  447. /* const areaLabel = new Label({
  448. className:'measure_area',
  449. })
  450. areaLabel.elem.on('mouseover',()=>{
  451. this.setSelected(true, 'areaLabel')
  452. })
  453. areaLabel.elem.on('mouseout',()=>{
  454. this.setSelected(false, 'areaLabel')
  455. }) */
  456. const areaLabel = new TextSprite(
  457. $.extend(mainLabelProp,{sizeInfo: labelSizeInfo, name:'areaLabel_'} )
  458. )
  459. areaLabel.addEventListener('mouseover',()=>{
  460. this.setSelected(true, 'areaLabel')
  461. })
  462. areaLabel.addEventListener('mouseleave',()=>{
  463. this.setSelected(false, 'areaLabel')
  464. })
  465. areaLabel.addEventListener('click',()=>{
  466. viewer.focusOnObject(this, 'measure')
  467. })
  468. viewer.setObjectLayers(areaLabel, 'measure' )
  469. areaLabel.visible = false
  470. return areaLabel;
  471. }
  472. getMarkerMaterial(type) {
  473. if(!markerMats){
  474. markerMats = {
  475. default: new DepthBasicMaterial({
  476. transparent: !0,
  477. opacity: 1,
  478. map: texLoader.load(Potree.resourcePath+'/textures/pic_point32.png' ),
  479. useDepth:true
  480. }),
  481. select: new DepthBasicMaterial({
  482. transparent: !0,
  483. opacity: 1,
  484. map: texLoader.load(Potree.resourcePath+'/textures/pic_point_s32.png'/* , null, null, { antialias: false } */),
  485. }),
  486. }
  487. Measure.markerMats = markerMats
  488. }
  489. return markerMats[type]
  490. }
  491. getLineMat(type) {
  492. if(!Measure.lineMats){
  493. Measure.lineMats = {
  494. edgeDefault: LineDraw.createFatLineMat({
  495. color: color,
  496. dashSize: 0.5,
  497. gapSize: 0.2,
  498. lineWidth: config.measure.lineWidth,
  499. useDepth :true,
  500. dashWithDepth :true, // 只在被遮住的部分显示虚线,因为实线容易挡住label
  501. dashed :true,
  502. dashSize : 0.04,
  503. gapSize: 0.04,
  504. }),
  505. edgeSelect: LineDraw.createFatLineMat({
  506. color: highLightColor,//'#f0ff00',
  507. dashSize: 0.5,
  508. gapSize: 0.2,
  509. lineWidth: config.measure.lineWidth
  510. }),
  511. guide: LineDraw.createFatLineMat({
  512. color:config.measure.guideLineColor,
  513. dashSize: 0.1,
  514. gapSize: 0.02,
  515. dashed: true,
  516. lineWidth: config.measure.lineWidth
  517. })
  518. }
  519. }
  520. return Measure.lineMats[type]
  521. }
  522. createAreaPlane(){
  523. planeMats || (planeMats = {
  524. default: new DepthBasicMaterial({
  525. color:color,
  526. side:THREE.DoubleSide,
  527. opacity:0.2,
  528. transparent:true,
  529. useDepth:true
  530. }),
  531. selected: new DepthBasicMaterial({
  532. color:color,
  533. side:THREE.DoubleSide,
  534. opacity:0.3,
  535. transparent:true
  536. })
  537. },Measure.planeMats = planeMats)
  538. return super.createAreaPlane(planeMats.default)
  539. }
  540. raycast (raycaster, intersects) {
  541. for (let i = 0; i < this.points.length; i++) {
  542. let marker = this.markers[i];
  543. marker.raycast(raycaster, intersects);
  544. }
  545. // recalculate distances because they are not necessarely correct
  546. // for scaled objects.
  547. // see https://github.com/mrdoob/three.js/issues/5827
  548. // TODO: remove this once the bug has been fixed
  549. for (let i = 0; i < intersects.length; i++) {
  550. let I = intersects[i];
  551. I.distance = raycaster.ray.origin.distanceTo(I.point);
  552. }
  553. intersects.sort(function (a, b) { return a.distance - b.distance; });
  554. };
  555. transformData(prop){
  556. if(prop.measureType == 'Point'){
  557. prop.showCoordinates = true,
  558. prop.closed = true,
  559. prop.maxMarkers = 1,
  560. prop.minMarkers = 1
  561. }else if(prop.measureType == 'Distance'){
  562. prop.showDistances = true,
  563. prop.closed = false,
  564. prop.showEdges = true,
  565. prop.maxMarkers = 2,
  566. prop.minMarkers = 2
  567. }else if(prop.measureType == 'Ver Distance'){
  568. prop.showDistances = true,
  569. prop.closed = false,
  570. prop.showEdges = true,
  571. prop.maxMarkers = 2,
  572. prop.minMarkers = 2,
  573. prop.faceDirection = "vertical"
  574. prop.unableDragAtMap = true
  575. }else if(prop.measureType == 'Hor Distance'){
  576. prop.showDistances = true,
  577. prop.closed = false,
  578. prop.showEdges = true,
  579. prop.maxMarkers = 2,
  580. prop.minMarkers = 2,
  581. prop.faceDirection = "horizontal"
  582. }else if(prop.measureType == 'Area'){
  583. prop.showDistances = true,
  584. prop.showArea = true,
  585. prop.showEdges = true,
  586. prop.closed = true,
  587. prop.minMarkers = 3
  588. }else if(prop.measureType == 'Hor Area'){
  589. prop.showDistances = true,
  590. prop.showArea = true,
  591. prop.showEdges = true,
  592. prop.closed = true,
  593. prop.minMarkers = 3
  594. prop.faceDirection = "horizontal"
  595. }else if(prop.measureType == 'Ver Area'){
  596. prop.showDistances = true,
  597. prop.showArea = true,
  598. prop.showEdges = true,
  599. prop.closed = true,
  600. prop.minMarkers = 3
  601. prop.faceDirection = "vertical"
  602. prop.unableDragAtMap = true
  603. }else if(prop.measureType == 'Rect Area'){
  604. prop.showDistances = true,
  605. prop.showArea = true,
  606. prop.showEdges = true,
  607. prop.closed = true,
  608. prop.minMarkers = 4
  609. prop.maxMarkers = 4
  610. }else if(prop.measureType == 'Hor Rect Area'){
  611. prop.showDistances = true,
  612. prop.showArea = true,
  613. prop.showEdges = true,
  614. prop.closed = true,
  615. prop.minMarkers = 4
  616. prop.maxMarkers = 4
  617. prop.isRect = true
  618. prop.faceDirection = "horizontal"
  619. }else if(prop.measureType == 'Ver Rect Area'){
  620. prop.showDistances = true,
  621. prop.showArea = true,
  622. prop.showEdges = true,
  623. prop.closed = true,
  624. prop.minMarkers = 4
  625. prop.maxMarkers = 4
  626. prop.isRect = true
  627. prop.faceDirection = "vertical"
  628. prop.unableDragAtMap = true
  629. }
  630. }
  631. setUnitSystem(unitSystem){
  632. //console.log(this.name +':' +this.unitSystem)
  633. if(unitSystem != this.unitSystem){
  634. if(unitSystem == "metric"){
  635. }else if(unitSystem == 'imperial'){
  636. }
  637. this.unitSystem = unitSystem
  638. this.update()
  639. }
  640. }
  641. reDraw(restMarkerCount=0){//重新开始画
  642. super.reDraw(restMarkerCount)
  643. if(this.measureType == 'Distance'){
  644. this.shouldShowHorVerGuide = false
  645. this.setEdgesDisplay(false)
  646. }
  647. if(this.showArea){
  648. this.area = {value:0};
  649. this.areaLabel && this.areaLabel.setVisible(false)
  650. }
  651. }
  652. /* get showCoordinates () {
  653. return this._showCoordinates;
  654. }
  655. set showCoordinates (value) {
  656. this._showCoordinates = value;
  657. this.update();
  658. }
  659. get showAngles () {
  660. return this._showAngles;
  661. }
  662. set showAngles (value) {
  663. this._showAngles = value;
  664. this.update();
  665. }
  666. get showCircle () {
  667. return this._showCircle;
  668. }
  669. set showCircle (value) {
  670. this._showCircle = value;
  671. this.update();
  672. }
  673. get showAzimuth(){
  674. return this._showAzimuth;
  675. }
  676. set showAzimuth(value){
  677. this._showAzimuth = value;
  678. this.update();
  679. }
  680. get showEdges () {
  681. return this._showEdges;
  682. }
  683. set showEdges (value) {
  684. this._showEdges = value;
  685. this.update();
  686. }
  687. get showHeight () {
  688. return this._showHeight;
  689. }
  690. set showHeight (value) {
  691. this._showHeight = value;
  692. this.update();
  693. }
  694. get showArea () {
  695. return this._showArea;
  696. }
  697. set showArea (value) {
  698. this._showArea = value;
  699. this.update();
  700. }
  701. get closed () {
  702. return this._closed;
  703. }
  704. set closed (value) {
  705. this._closed = value;
  706. this.update();
  707. }
  708. get showDistances () {
  709. return this._showDistances;
  710. }
  711. set showDistances (value) {
  712. this._showDistances = value;
  713. this.update();
  714. } */
  715. }
  716. function setLabelHightState(label, state){
  717. if(state){
  718. //label.backgroundColor = {r: highLightColor.r*255, g: highLightColor.g*255, b: highLightColor.b*255, a:1},
  719. label.backgroundColor.a = 1
  720. label.sprite.material.useDepth = false;
  721. }else{
  722. //label.backgroundColor = mainLabelProp.backgroundColor
  723. label.backgroundColor.a = config.measure.labelOpacity
  724. label.sprite.material.useDepth = true
  725. }
  726. label.updateTexture()
  727. //label.sprite.material.needsUpdate = true
  728. }
  729. function createCircleRadiusLabel(){
  730. const circleRadiusLabel = new TextSprite("");
  731. circleRadiusLabel.setTextColor({r: 140, g: 250, b: 140, a: 1.0});
  732. circleRadiusLabel.setBorderColor({r: 0, g: 0, b: 0, a: 1.0});
  733. circleRadiusLabel.setBackgroundColor({r: 0, g: 0, b: 0, a: 1.0});
  734. circleRadiusLabel.fontsize = 16;
  735. circleRadiusLabel.material.depthTest = false;
  736. circleRadiusLabel.material.opacity = 1;
  737. circleRadiusLabel.visible = false;
  738. return circleRadiusLabel;
  739. }
  740. function createCircleRadiusLine(){
  741. /* const lineGeometry = new LineGeometry();
  742. lineGeometry.setPositions([
  743. 0, 0, 0,
  744. 0, 0, 0,
  745. ]);
  746. const lineMaterial = new LineMaterial({
  747. color: 0xff0000,
  748. lineWidth: 2,
  749. resolution: new THREE.Vector2(1000, 1000),
  750. gapSize: 1,
  751. dashed: true,
  752. });
  753. lineMaterial.depthTest = false;
  754. const circleRadiusLine = new Line2(lineGeometry, lineMaterial);*/
  755. var circleRadiusLine = LineDraw.createFatLine([
  756. 0, 0, 0,
  757. 0, 0, 0,
  758. ],{
  759. color:0xff0000,
  760. dashSize: 0.5,
  761. gapSize: 0.2,
  762. lineWidth: config.measure.lineWidth
  763. })
  764. circleRadiusLine.visible = false;
  765. return circleRadiusLine;
  766. }
  767. function createCircleLine(){
  768. const coordinates = [];
  769. let n = 128;
  770. for(let i = 0; i <= n; i++){
  771. let u0 = 2 * Math.PI * (i / n);
  772. let u1 = 2 * Math.PI * (i + 1) / n;
  773. let p0 = new THREE.Vector3(
  774. Math.cos(u0),
  775. Math.sin(u0),
  776. 0
  777. );
  778. let p1 = new THREE.Vector3(
  779. Math.cos(u1),
  780. Math.sin(u1),
  781. 0
  782. );
  783. coordinates.push(
  784. ...p0.toArray(),
  785. ...p1.toArray(),
  786. );
  787. }
  788. /* const geometry = new LineGeometry();
  789. geometry.setPositions(coordinates);
  790. const material = new LineMaterial({
  791. color: 0xff0000,
  792. dashSize: 5,
  793. gapSize: 2,
  794. lineWidth: 2,
  795. resolution: new THREE.Vector2(1000, 1000),
  796. });
  797. material.depthTest = false;
  798. const circleLine = new Line2(geometry, material);
  799. circleLine.visible = false;
  800. circleLine.computeLineDistances();*/
  801. var circleLine = LineDraw.createFatLine(coordinates,{
  802. color: 0xff0000,
  803. dashSize: 0.5,
  804. gapSize: 0.2,
  805. lineWidth: config.measure.lineWidth
  806. })
  807. return circleLine;
  808. }
  809. /* function createCircleCenter(){
  810. const sg = new THREE.markerGeometry(1, 32, 32);
  811. const sm = new THREE.MeshNormalMaterial();
  812. const circleCenter = new THREE.Mesh(sg, sm);
  813. circleCenter.visible = false;
  814. return circleCenter;
  815. } */
  816. function createLine(){
  817. const line = LineDraw.createFatLine([
  818. 0, 0, 0,
  819. 0, 0, 0,
  820. ],{
  821. color: 0xff0000,
  822. dashSize: 0.5,
  823. gapSize: 0.2,
  824. lineWidth: config.measure.lineWidth
  825. })
  826. return line;
  827. }
  828. function createCircle(){
  829. const coordinates = [];
  830. let n = 128;
  831. for(let i = 0; i <= n; i++){
  832. let u0 = 2 * Math.PI * (i / n);
  833. let u1 = 2 * Math.PI * (i + 1) / n;
  834. let p0 = new THREE.Vector3(
  835. Math.cos(u0),
  836. Math.sin(u0),
  837. 0
  838. );
  839. let p1 = new THREE.Vector3(
  840. Math.cos(u1),
  841. Math.sin(u1),
  842. 0
  843. );
  844. coordinates.push(
  845. ...p0.toArray(),
  846. ...p1.toArray(),
  847. );
  848. }
  849. var line = LineDraw.createFatLine(coordinates,{
  850. color: 0xff0000,
  851. dashSize: 0.5,
  852. gapSize: 0.2,
  853. lineWidth: config.measure.lineWidth
  854. })
  855. return line;
  856. }
  857. /* function createAzimuth(){
  858. const azimuth = {
  859. label: null,
  860. center: null,
  861. target: null,
  862. north: null,
  863. centerToNorth: null,
  864. centerToTarget: null,
  865. centerToTargetground: null,
  866. targetgroundToTarget: null,
  867. circle: null,
  868. node: null,
  869. };
  870. const sg = new THREE.markerGeometry(1, 32, 32);
  871. const sm = new THREE.MeshNormalMaterial();
  872. {
  873. const label = new TextSprite("");
  874. label.setTextColor({r: 140, g: 250, b: 140, a: 1.0});
  875. label.setBorderColor({r: 0, g: 0, b: 0, a: 1.0});
  876. label.setBackgroundColor({r: 0, g: 0, b: 0, a: 1.0});
  877. label.fontsize = 16;
  878. label.material.depthTest = false;
  879. label.material.opacity = 1;
  880. azimuth.label = label;
  881. }
  882. azimuth.center = new THREE.Mesh(sg, sm);
  883. azimuth.target = new THREE.Mesh(sg, sm);
  884. azimuth.north = new THREE.Mesh(sg, sm);
  885. azimuth.centerToNorth = createLine();
  886. azimuth.centerToTarget = createLine();
  887. azimuth.centerToTargetground = createLine();
  888. azimuth.targetgroundToTarget = createLine();
  889. azimuth.circle = createCircle();
  890. azimuth.node = new THREE.Object3D();
  891. azimuth.node.add(
  892. azimuth.centerToNorth,
  893. azimuth.centerToTarget,
  894. azimuth.centerToTargetground,
  895. azimuth.targetgroundToTarget,
  896. azimuth.circle,
  897. azimuth.label,
  898. azimuth.center,
  899. azimuth.target,
  900. azimuth.north,
  901. );
  902. return azimuth;
  903. } */
  904. /*
  905. */