12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487 |
- import * as THREE from "../../../../libs/three.js/build/three.module.js";
- import {TextSprite} from "../TextSprite.js";
- import {Utils} from "../../../utils.js";
- import Label from "../Label.js";
- import {LineDraw} from "../../utils/DrawUtil.js";
- import math from "../../utils/math.js";
- import DepthBasicMaterial from "../../materials/DepthBasicMaterial.js";
- import Sprite from '../Sprite.js'
- import {config} from '../../settings.js'
- import {ctrlPolygon} from './ctrlPolygon.js'
-
- let texLoader = new THREE.TextureLoader()
- let defaultColor = new THREE.Color(config.measure.default.color);
- let highlightColor = new THREE.Color(config.measure.highlight.color);
- let color = new THREE.Color(config.measure.color)
- let textColor = new THREE.Color(config.measure.textColor)
- var markerMats = {}
- var lineMats ;
- var planeMats
-
-
-
- const lineDepthInfo = {
- clipDistance : 4,//消失距离
- occlusionDistance: 1,//变为backColor距离
- }
- const planeDepthInfo = {
- clipDistance : 30,//消失距离
- occlusionDistance: 4,//变为backColor距离
- maxOcclusionFactor:0.3,
- maxClipFactor:0.1
- }
-
- const textSizeRatio = math.linearClamp(window.innerWidth * window.innerHeight , 360*720, 1920*1080, 0.75, 1) //pc字显示大一些
-
- const markerSizeInfo = {
- minSize : 30*2 , maxSize : 65*2, nearBound : 0.2, farBound : 4,
- }
- const labelSizeInfo = {width2d:190}
- const mainLabelProp = {
- //backgroundColor: {r: defaultColor.r*255, g: defaultColor.g*255, b: defaultColor.b*255, a:config.measure.default.opacity},
- backgroundColor: {r: 0, g: 0, b: 0, a:0},
- textColor: {r: textColor.r*255, g: textColor.g*255, b: textColor.b*255, a: 1.0},
- textBorderColor: {r:255, g: 255, b:255, a: 1.0},
- textBorderThick:3,
- fontsize: 15 * textSizeRatio,
- borderRadius : 12, margin:{x:20,y:4},
- renderOrder : 5, pickOrder:5,
- disToLine:-0.15,
-
- useDepth : true ,
- // 2023.10 尽量不让数字被挡住
- clipDistance : 50,//消失距离
- occlusionDistance: 10,//变为backColor距离
- maxOcclusionFactor:0.2,
- maxClipFactor:0.1
-
- }
-
-
- const subLabelProp = {
- backgroundColor: {r: 255, g: 255, b: 255, a:config.measure.default.opacity},
- textColor: {r: 0.3, g: 0.3, b:0.3, a: 1.0},
- fontsize:15 * textSizeRatio, borderRadius : 12, margin:{x:20,y:4},
- renderOrder : 4, pickOrder:4,
- }
- const angle = THREE.Math.degToRad(5);//显示水平垂直辅助线的最小角度
- const guideShowMinAngle = {min: angle, max: Math.PI/2 - angle}
-
-
-
- export class Measure extends ctrlPolygon{
- constructor (prop) {
- prop.dimension = '2d'
-
- super('measure',prop);
- this.constructor.counter = (this.constructor.counter === undefined) ? 0 : this.constructor.counter + 1;
-
-
- this.name = this.measureType + this.constructor.counter //'Measure_' + this.constructor.counter;
- //this.color = '#FF4399'
- this.color = new THREE.Color(this.color)
-
- this.markerLabels = [];
- this.edgeLabels = [];
- this.angleLabels = [];
- this.coordinateLabels = [];
- this.area = {value:0,string:''}
-
-
- if( this.showArea ){
- this.areaLabel = this.createAreaLabel();
- this.add(this.areaLabel)
- }
-
-
- //add:
- if(this.atPlane || this.faceDirection){ //是一个平面上的话
- if(this.guideLinePoints){
- this.createGuideLines()
- }else{
- this.createGuideLine();
- }
- }
- if(this.measureType == 'Distance' /* || this.measureType.includes('MulDistance') */){
- this.createHorVerGuideLine()
- }
-
-
-
- this.selectStates = {}
-
- this.setUnitSystem(prop.unit || viewer.unitConvert.UnitService.defaultSystem)
- Potree.Utils.setObjectLayers(this, 'measure' )
-
- //addMarkers:
-
- this.initData(prop)
-
-
- this.points_datasets || (this.points_datasets = []) //存每个点是哪个数据集
-
- //这版应该没多数据集,不需要更新这个:
- /* this.addEventListener('marker_dropped',(e)=>{
- this.updateDatasetBelong(e.index)
- }) */
-
- this.addEventListener('isVisible', ()=>{
- viewer.mapViewer && viewer.mapViewer.dispatchEvent({type:'content_changed'})
- })
-
- }
-
-
-
- initData(prop){
- let makeIt = super.initData(prop)
- if(makeIt){
- this.edges.forEach(edge=>{edge.dispatchEvent('addHoverEvent') })
- }else{
- this.failBuilded = true
- }
- }
-
-
- updateDatasetBelong(changeIndex){//更新所属数据集
-
- if(Potree.settings.editType == "merge"){//无地图
- /* this.dataset_points = this.points.map((e,i)=>{
- return Potree.Utils.datasetPosTransform({toDataset:true, datasetId:this.points_datasets[i], position:e.clone()})
- }) */
- this.dataset_points[changeIndex] = Potree.Utils.datasetPosTransform({toDataset:true, datasetId:this.points_datasets[changeIndex], position:this.points[changeIndex].clone()})
-
-
- return
- }
-
-
-
-
- let old = this.datasetId
-
- let maxCount = {id:null,count:0}
- let datasets = {}
-
- this.points_datasets.forEach(e=>{
- if(e == void 0)return
- if(datasets[e]){
- datasets[e] ++
- }else{
- datasets[e] = 1
- }
- })
- for(let i in datasets) {
- if(datasets[i]>maxCount.count){
- maxCount = {id:i, count:datasets[i]}
- }
- }
- this.datasetId = maxCount.count > 0 ? maxCount.id : null
-
- //if(this.datasetId != old){
- //this.dispatchEvent({type:'changeDatasetId'})
- if(this.datasetId == void 0){
- this.dataset_points = null //可能为空或[null,null...]
- }else{
-
- this.dataset_points = this.points.map(e=>{
- return Potree.Utils.datasetPosTransform({toDataset:true,datasetId:this.datasetId, position:e.clone()})
- })
- }
- //}
- }
-
-
-
-
- transformByPointcloud(){//每次移动点云 or 加载测量线时要获取一下当前position //有地图时
- if(this.datasetId == void 0)return
- this.points = this.dataset_points.map(e=>{
- return Potree.Utils.datasetPosTransform({fromDataset:true, datasetId:this.datasetId, position:e.clone()})
- })
-
- this.getPoint2dInfo(this.points)
- this.update({ifUpdateMarkers:true})
- this.setSelected(false)//隐藏edgelabel
-
- }
-
- update(options={}) {
- super.update(options)
-
- if(this.showCoordinates && this.points.length>0){
- let position = this.points[0];
-
- this.markers[0].position.copy(position);
- { // coordinate labels
- let coordinateLabel = this.coordinateLabels[0];
-
- let lonlat = viewer.transform.lonlatToLocal.inverse(position.toArray())
- let EPSG4550 = viewer.transform.lonlatTo4550.forward(lonlat)
- let pos = [
- position.toArray(),
- lonlat,
- EPSG4550
- ]
- //let msg = position.toArray().map(p => Utils.addCommas(p.toFixed(2))).join(" / ");
- let msg = pos.map(a=>
- a.map(p => Utils.addCommas(p.toFixed(10))).join(", ")
- ).join("<br>")
- coordinateLabel.setText(msg);
- coordinateLabel.setPos(position)
- coordinateLabel.setVisible(true)//this.showCoordinates;
- }
- return
- }
-
-
- /* viewer.addEventListener('camera_changed',(e)=>{
- if(e.changeInfo.positionChanged){
- setLabelPos()
- }
- }) */
-
-
- let setEdgeLabel = (label,p1,p2,distance)=>{//设置label位置和字
- this.setEdgeLabelPos(label,p1,p2)
-
- distance = distance == void 0 ? p1.distanceTo(p2) : distance;
- var text = this.labelText || viewer.unitConvert.convert(distance, 'distance', Potree.settings.precision , this.unitSystem, 0.001 , true, true)//distance要传0.1 这个factor
- label.setText(text)
-
- }
-
-
- let lastIndex = this.points.length - 1;
- for (let index = 0; index <= lastIndex; index++) {
-
- let nextIndex = (index + 1 > lastIndex) ? 0 : index + 1;
- let previousIndex = (index === 0) ? lastIndex : index - 1;
- //if(!this.closed && nextIndex == 0 )break; //add
-
- let point = this.points[index];
- let nextPoint = this.points[nextIndex];
- let previousPoint = this.points[previousIndex];
-
- if(this.showDistances || this.labelText){ // edge labels
- let edgeLabel = this.edgeLabels[index];
- let distance = this.labelText || point.distanceTo(nextPoint)
- edgeLabel.shouldVisi = (this.labelText || distance>0) && (index < lastIndex || this.isRect || this.closed && !this.isNew )
- /* this.closed || */edgeLabel.setVisible(edgeLabel.shouldVisi)
- if(edgeLabel.shouldVisi){
- this.lineDir = new THREE.Vector3().subVectors(point,nextPoint).normalize() //[point,nextPoint]
-
- setEdgeLabel(edgeLabel,point,nextPoint,distance)
-
- }
-
- }
- }
-
-
- if(this.measureType == 'Distance' && this.points.length>1){//设置水平垂直辅助线
- var pTop, pBtm
- if(this.points[0].z > this.points[1].z ){
- pTop = this.points[0];
- pBtm = this.points[1];
- }else{
- pTop = this.points[1];
- pBtm = this.points[0];
- }
- let projectPos = new THREE.Vector3(pTop.x, pTop.y, pBtm.z);//两条guideline的交点
-
- {//倾斜角度太小的时候不显示
- let tan = pTop.distanceTo(projectPos) / pBtm.distanceTo(projectPos)
- let angle = Math.atan(tan);
-
- this.shouldShowHorVerGuide = angle > guideShowMinAngle.min && angle < guideShowMinAngle.max
- }
-
-
- LineDraw.updateLine(this.verGuideEdge, [pTop, projectPos])
- LineDraw.updateLine(this.horGuideEdge, [pBtm, projectPos])
- setEdgeLabel(this.verEdgeLabel,pTop,projectPos)
- setEdgeLabel(this.horEdgeLabel,pBtm,projectPos)
-
- this.verGuideEdge.visible = this.horGuideEdge.visible = this.shouldShowHorVerGuide
- this.verEdgeLabel.visible = this.horEdgeLabel.visible = this.shouldShowHorVerGuide
- }
-
-
- if(this.showArea && this.point2dInfo){ // update area
- /* if(this.points.length>2){
- this.area = {value:0};
- this.areaLabel.setVisible(false)
- }else{ */
- let area = Math.abs(math.getArea(this.point2dInfo.points2d))//this.getArea();
- let msg = viewer.unitConvert.convert(area, 'area', Potree.settings.precision, this.unitSystem/* , 0.1 */ )
- this.area = {value:area, string:msg}
-
- this.areaLabel.setPos(this.center);
- this.areaLabel.setText(msg);
- this.areaLabel.setVisible(true)
- //}
- }
-
- };
- setEdgeLabelPos(label,p1,p2){ //调整label的位置,使倾斜后看起来在线的中心,而不要挡住端点
- let center = new THREE.Vector3().addVectors(p1,p2).multiplyScalar(0.5);
-
- if(this.lineDir && this.lineDir.length() > 0){
- if(viewer.mainViewport.camera.type == 'OrthographicCamera'){
- label.setPos(center)
- }else{
- //根据视线和线的夹角(后又加入相机和两个端点距离差)来决定标签偏移位置。+
- let eyePos = viewer.mainViewport.camera.position;
- let dir = viewer.mainViewport.view.direction //new THREE.Vector3().subVectors(center,eyePos).normalize()
-
- /*let centerDir = new THREE.Vector3().subVectors(center,eyePos).normalize()
- if(centerDir.dot(dir)<0){//中点在相机后方,就不设置
- label.setPos(center)
- return
- } */
- let cos = dir.dot(this.lineDir)
- let nearPoint = cos > 0 ? p2 : p1 //近端点。
- let far = cos > 0 ? p1 : p2 //远端点。
- let nearPointDir = new THREE.Vector3().subVectors(nearPoint,eyePos)//.normalize()
- //使label在中点和近端点中变化, 近端点可能到了相机后方,需要投影到相机所在平面上
- if(nearPointDir.dot(dir)<0){//近端点到了相机后方,前移。
- //let hfov = cameraLight.getHFOVForCamera(viewer.mainViewport.camera , true ); //暂且只看水平fov
- //if(nearPointDir.dot(dir)<Math.cos(hfov/2)){//近端点在镜头外,前移。 --但是这个就得把点转化成在镜头边缘而非左右两边(camDirPlane上)
- let ray = new THREE.Raycaster()
- ray.set(nearPoint, cos>0?this.lineDir:this.lineDir.clone().negate())
- let camDirPlane = new THREE.Plane().setFromNormalAndCoplanarPoint(dir, eyePos)
- nearPoint = ray.ray.intersectPlane(camDirPlane, new THREE.Vector3())
- if(!nearPoint){//线是垂直的,视线是水平的时候
- return label.setPos(center)
- }
- }
-
-
- //防止离远了之后也偏移很多,但远了之后相机到端点vec和到中点的vec的夹角接近,不需要怎么偏移的。
- let dis1 = nearPoint.distanceToSquared(eyePos)
- let dis2 = far.distanceToSquared(eyePos)
- let diff = Math.abs(dis1/dis2)
- diff<1 && (diff = 1/diff)
- diff = math.linearClamp(diff,0, 30, 0,1 )
-
-
-
- let efficiency = 0.7; // 0-1 数值越高,r越容易接近1或-1,label越容易在倾斜后靠近近端点。
- //let r = 0.5*efficiency*cos + 0.5
- let r = 0.5*efficiency*diff*cos + 0.5
- r = THREE.Math.clamp(r,0.1,0.9)
-
- //视线越接近线的方向,标签应该越往近端点偏移,防止看起来几乎在远端。
- if(cos > 0){
- center = p1.clone().multiplyScalar(1-r).add(nearPoint.clone().multiplyScalar(r)); //label在线上滑动,使尽量保持在视觉中心
- }else{
- center = nearPoint.clone().multiplyScalar(1-r).add(p2.clone().multiplyScalar(r)); //label在线上滑动,使尽量保持在视觉中心
- }
-
- label.setPos(center)
- }
-
-
- //归零
- this.orient2dInfo = null
- this.markers.forEach(e=>e.needsUpdate=true)
- }else{
-
- label.setPos(center)
- }
-
-
- }
-
-
- addMarker (o={}) {
-
- let marker = new Sprite({mat:this.getMarkerMaterial('default'), sizeInfo: markerSizeInfo, name:"measure_point"} )
- Potree.Utils.setObjectLayers(marker, 'measure' )
- marker.pickOrder = marker.renderOrder = 3
- marker.markerSelectStates = {}
- marker.addEventListener('startDragging',(e)=>{
- if(e.drag.dragViewport.name == 'MainView')viewer.inputHandler.dispatchEvent( {type: 'isMeasuring',v:true, cause:'startDragging'})
- })
- marker.addEventListener('drop',(e)=>{
- viewer.inputHandler.dispatchEvent({type: 'isMeasuring', v:false, cause:'stopDragging'} )
- })
- marker.measure = this
- let edge
- { // edges
- edge = LineDraw.createFatLine( [ ],{material:this.getLineMat('edgeDefault')} )
- edge.pickOrder = 0
- Potree.Utils.setObjectLayers(edge, 'measure' )
-
- let addHoverEvent = ()=>{ //当非isNew时才添加事件
-
- let mouseover = (e) => {this.setSelected(true, 'edge')};
- let mouseleave = (e) => {this.setSelected(false, 'edge')};
-
- edge.addEventListener('mouseover', mouseover);
- edge.addEventListener('mouseleave', mouseleave);
- edge.removeEventListener('addHoverEvent', addHoverEvent);
-
- //2023.10.25add:
- edge.addEventListener('click',()=>{
- if(!this.isNew) this.focus()
- })
- }
- edge.addEventListener('addHoverEvent', addHoverEvent);
- }
-
- super.addMarker({point:o.point, marker:marker, edge})
-
-
- if(this.showEdges){ // edge labels
- const edgeLabel = this.createEdgeLabel('edgeLabel', !this.closed)
- edgeLabel.measure = this
- this.edgeLabels.push(edgeLabel);
-
- }
-
- if(this.showCoordinates){ // coordinate labels
- let coordinateLabel = new Label({
- className:'measure_pointPos',
- camera: viewer.scene.getActiveCamera()
- })
- coordinateLabel.setVisible(false)
- this.coordinateLabels.push(coordinateLabel);
-
- }
-
-
-
-
-
- let event = {
- type: 'marker_added',
- measurement: this,
- marker: marker
- };
- this.dispatchEvent(event);
- //this.setMarker(this.points.length - 1, point);
- this.update()//更新一下倒数第二条线
- return marker;//add
- };
-
-
- editStateChange(state){ //主要针对edgeLabels显示切换,编辑时显示
- super.editStateChange(state)
- if(!state){
- this.editStateTimer = setTimeout(()=>{
- if(!this.isEditing){
- this.dispatchEvent({type:'editStateChange',state:false})
- this.setEdgesDisplay(false)
- this.areaPlane && Potree.Utils.updateVisible(this.areaPlane, 'intersectLastLine', true)
- this.areaLabel && Potree.Utils.updateVisible(this.areaLabel, 'intersectLastLine', true)
- }
- },100)
- }else{
- if(!this.isEditing){
- this.dispatchEvent({type:'editStateChange',state:true})
- this.setEdgesDisplay(true)
- clearTimeout(this.editStateTimer)
- }
- }
- this.isEditing = state
- viewer.dispatchEvent({type:'MeasureDragChange',state})
- }
-
-
- setMarkerSelected(marker, state, hoverObject){
-
- //console.warn(marker.id , state, hoverObject)
-
- marker.markerSelectStates[hoverObject] = state
- let absoluteState = false
- for(var i in marker.markerSelectStates){
- if(marker.markerSelectStates[i] == 'hover'){
- absoluteState = true; break;
- }
- }
- if(absoluteState){
- marker.material = this.getMarkerMaterial('select')
- }else{
- marker.material = this.getMarkerMaterial('default')
- }
-
- marker.selected = absoluteState
-
- viewer.mapViewer && viewer.mapViewer.dispatchEvent('content_changed')
- viewer.dispatchEvent('content_changed')
- }
-
-
-
- setEdgesDisplay(state, ignoreGuideLine){
- this.closed && this.edgeLabels.forEach(e=>e.setVisible(!!(state && e.shouldVisi)) )
-
- if(!ignoreGuideLine && this.measureType == 'Distance'){
- this.horEdgeLabel.visible = this.verEdgeLabel.visible = this.horGuideEdge.visible = this.verGuideEdge.visible = !!(state && this.shouldShowHorVerGuide)
- }
- }
-
-
- setSelected(state, hoverObject){//add
- //console.log('setSelected', state, hoverObject)
- hoverObject && (this.selectStates[hoverObject] = state)
- let absoluteState = false
- for(var i in this.selectStates){
- if(this.selectStates[i]){
- absoluteState = true; break;
- }
- }
-
-
- if(absoluteState){
- this.markers.forEach(e=>this.setMarkerSelected(e, 'hover', 'selectAll' ) )
-
- this.edges.forEach(e=>e.material = this.getLineMat('edgeSelect') )
-
- this.areaPlane && (this.areaPlane.material = planeMats.selected)
-
-
- //this.areaLabel && this.areaLabel.elem.addClass('highLight')
- //this.closed || this.edgeLabels.forEach(e=>e.elem.addClass('highLight') )
- this.setEdgesDisplay(true, hoverObject=="screenshot")
-
- this.areaLabel && this.setLabelHightState(this.areaLabel, true)
- this.closed || this.edgeLabels.forEach(e=>this.setLabelHightState(e, true) )
-
- }else{
- this.markers.forEach(e=>this.setMarkerSelected(e, 'unhover', 'selectAll' ))
- this.edges.forEach(e=>e.material = this.getLineMat('edgeDefault') )
- this.areaPlane && (this.areaPlane.material = planeMats.default)
- this.setEdgesDisplay(false, hoverObject=="screenshot")
- //this.areaLabel && this.areaLabel.elem.removeClass('highLight')
- //this.closed || this.edgeLabels.forEach(e=>e.elem.removeClass('highLight') )
- this.areaLabel && this.setLabelHightState(this.areaLabel, false)
- this.closed || this.edgeLabels.forEach(e=>this.setLabelHightState(e, false) )
-
- }
-
- this.selected = absoluteState
-
- if(hoverObject != 'byList'){
- //this.bus && this.bus.emit('highlight', this.selected)
- this.dispatchEvent({type:'highlight',state:this.selected})//列表高亮
- }
-
- viewer.dispatchEvent('content_changed')
- viewer.mapViewer && viewer.mapViewer.dispatchEvent('content_changed')
- }
-
-
-
-
- setLabelHightState(label, state){
- if(state){
- let color = new THREE.Color(Potree.config.measure.highlight.color)
- //label.sprite.material.opacity = config.measure.highlight.opacity
-
- //label.setBackgroundColor({r:255*color.r, g:255*color.g, b:255*color.b, a:config.measure.highlight.opacity})
-
- label.sprite.material.useDepth = false;
- //label.textColor = {r: this.color.r*255, g: this.color.g*255, b: this.color.b*255, a: 1}
- }else{
- //label.setBackgroundColor({r: this.color.r*255, g: this.color.g*255, b: this.color.b*255, a:config.measure.default.opacity})
-
- label.sprite.material.useDepth = true
- //label.sprite.material.opacity = 0.98
- //label.textColor = {r: 255, g: 255, b: 255, a: 1}
-
- }
- label.updateTexture()
- }
-
-
-
-
-
-
-
- removeMarker(index ){
- super.removeMarker(index)
-
- this.points_datasets.splice(index, 1);
- this.dataset_points && this.dataset_points.splice(index, 1)
- this.coordinateLabels.splice(index, 1);
-
- let edgeIndex = index//(index === 0) ? 0 : (index - 1);
- if(this.edgeLabels[edgeIndex]){
- this.edgeLabels[edgeIndex].dispose()
- this.edgeLabels.splice(edgeIndex, 1);
- }
-
- this.update();
- this.dispatchEvent({type: 'marker_removed', measurement: this});
- }
-
- setPosition(index, position) {
- super.setPosition(index, position)
-
- //相连的点的箭头也要更新方向
- this.markers[(index + this.points.length - 1) % this.points.length].waitUpdate()
- this.markers[(index + this.points.length + 1) % this.points.length].waitUpdate()
-
- let event = {
- type: 'marker_moved',
- measure: this,
- index: index,
- position: position.clone()
- };
- this.dispatchEvent(event);
-
- }
-
- dispose(){//add
- var labels = this.edgeLabels.concat(this.coordinateLabels)
- this.areaLabel && labels.push(this.areaLabel)
- labels.forEach(e=>e.dispatchEvent({type:'dispose'}))
- super.dispose()
- }
-
-
- getTotalDistance () {
- if (this.points.length === 0) {
- return 0;
- }
- let distance = 0;
- for (let i = 1; i < this.points.length; i++) {
- let prev = this.points[i - 1];
- let curr = this.points[i];
- let d = prev.distanceTo(curr);
- distance += d;
- }
- if (this.closed && this.points.length > 1) {
- let first = this.points[0];
- let last = this.points[this.points.length - 1];
- let d = last.distanceTo(first);
- distance += d;
- }
- return distance;
- }
- getAngleBetweenLines (cornerPoint, point1, point2) {
- let v1 = new THREE.Vector3().subVectors(point1, cornerPoint);
- let v2 = new THREE.Vector3().subVectors(point2, cornerPoint);
- // avoid the error printed by threejs if denominator is 0
- const denominator = Math.sqrt( v1.lengthSq() * v2.lengthSq() );
- if(denominator === 0){
- return 0;
- }else{
- return v1.angleTo(v2);
- }
- };
- getAngle (index) {
- if (this.points.length < 3 || index >= this.points.length) {
- return 0;
- }
- let previous = (index === 0) ? this.points[this.points.length - 1] : this.points[index - 1];
- let point = this.points[index];
- let next = this.points[(index + 1) % (this.points.length)];
- return this.getAngleBetweenLines(point, previous, next);
- }
-
- getCenter(/* update */){
- if(this.closed){
- return this.center.clone()
- }else{
- let center = this.points.reduce(function(total, currentValue ){
- return total.add(currentValue)
- }, new THREE.Vector3 )
-
- center.multiplyScalar(1/this.points.length)
- return center //求不出重心呜呜
- }
-
- }
-
- // updateAzimuth(){
- // // if(this.points.length !== 2){
- // // return;
- // // }
- // // const azimuth = this.azimuth;
- // // const [p0, p1] = this.points;
- // // const r = p0.distanceTo(p1);
-
- // }
-
-
-
-
- createGuideLine(){//add 辅助线
- var guideLine = LineDraw.createFatLine([ ],{material:this.getLineMat('guide')} )
- guideLine.visible = false
- this.guideLine = guideLine
- this.add(guideLine);
- }
- createHorVerGuideLine(){//创建水平与垂直辅助线,仅距离测量有。
- var verGuideEdge = LineDraw.createFatLine([ ],{material:this.getLineMat('guide')} )
- verGuideEdge.visible = false
- this.verGuideEdge = verGuideEdge
- verGuideEdge.name = 'verGuideEdge'
-
- var horGuideEdge = LineDraw.createFatLine([ ],{material:this.getLineMat('guide')} )
- horGuideEdge.visible = false
- horGuideEdge.name = 'horGuideEdge'
- this.horGuideEdge = horGuideEdge
-
- this.add(this.verGuideEdge);
- this.add(this.horGuideEdge);
-
-
- //label:
- this.verEdgeLabel = this.createEdgeLabel('verGuideEdge')
- this.horEdgeLabel = this.createEdgeLabel('horGuideEdge')
- }
-
-
- createGuideLines(){//add 固定点垂线的辅助线 可以多段
- var guideLine = LineDraw.createFatLine(this.guideLinePoints ,{material:this.getLineMat('guide')} )
- this.guideLine = guideLine //暂时也叫这个名字
- this.add(guideLine);
- }
- updateGuideLines(){
- this.guideLine.updateLine(this.guideLine, this.guideLinePoints)
- }
-
-
- focus({dontMoveCamera=false}={}){
- if(this.clickSelected)return
- if(Potree.settings.displayMode == 'showPanos')dontMoveCamera = true //2023.10.24 新需求:点击后不移动,否则经常跳到别的点。且在app上会反应一秒才选中。
-
- if(!dontMoveCamera){
- let dontChangeCamDir = viewer.mainViewport.camera.type == 'OrthographicCamera' /* && math.closeTo( viewer.mainViewport.view.pitch , -1.57079632) */ // 不改角度
- viewer.focusOnObject(this, 'measure', null, {dontChangeCamDir})
- }
-
- this.setSelected(true, 'focus')
- this.dispatchEvent({type:'selected', state:true})
- this.clickSelected = true
- //viewer.dispatchEvent({type:'selectMeasure', measure:this})
- let cancelSelect = ()=>{
- this.clickSelected = false
- this.removeEventListener('cancelSelect', cancelSelect)
- viewer.removeEventListener('global_click', cancelSelect)
- this.setSelected(false, 'focus')
- this.dispatchEvent({type:'selected', state:false})
- return {stopContinue:true}//不要flytopano
- }
- setTimeout(()=>{
- this.addEventListener('cancelSelect', cancelSelect)
- viewer.addEventListener('global_click', cancelSelect,{importance:10})
- },10)
- }
-
-
-
- createEdgeLabel(name, hasHoverEvent){
-
- //mainLabelProp.backgroundColor = {r: this.color.r*255, g: this.color.g*255, b: this.color.b*255, a:config.measure.default.opacity}
-
-
- const edgeLabel = new TextSprite(
- $.extend(hasHoverEvent ? mainLabelProp : subLabelProp,{
- sizeInfo: labelSizeInfo, name:name||'edgeLabel',
-
- })
- )
- if(hasHoverEvent){
- edgeLabel.addEventListener('mouseover',()=>{
- this.setSelected(true, 'edgeLabel')
- })
- edgeLabel.addEventListener('mouseleave',()=>{
- this.setSelected(false, 'edgeLabel')
- })
- edgeLabel.addEventListener('click',()=>{
- if(!this.isNew) this.focus()
- })
- //edgeLabel.sprite.material.opacity = config.measure.default.opacity
- }
- edgeLabel.visible = false
- edgeLabel.sprite.material.depthTestWhenPick = true
-
-
-
- Potree.Utils.setObjectLayers(edgeLabel, 'measure' )
- this.add(edgeLabel)
- return edgeLabel
- }
-
- createAreaLabel(){
- /* const areaLabel = new Label({
- className:'measure_area',
-
- })
- areaLabel.elem.on('mouseover',()=>{
- this.setSelected(true, 'areaLabel')
- })
- areaLabel.elem.on('mouseout',()=>{
- this.setSelected(false, 'areaLabel')
- }) */
-
-
- const areaLabel = new TextSprite(
- $.extend({}, mainLabelProp,{sizeInfo: labelSizeInfo, name:'areaLabel', fontsize:16*textSizeRatio} )
- )
-
- areaLabel.addEventListener('mouseover',()=>{
- this.setSelected(true, 'areaLabel')
- })
- areaLabel.addEventListener('mouseleave',()=>{
- this.setSelected(false, 'areaLabel')
- })
- areaLabel.addEventListener('click',()=>{
- if(!this.isNew) this.focus()
- })
- Potree.Utils.setObjectLayers(areaLabel, 'measure' )
- areaLabel.setVisible(false)
-
- return areaLabel;
-
-
- }
-
- getMarkerMaterial(type){
- let color = this.color.getHexString()
- if(!markerMats[type + color]){
-
- markerMats['default' + color] = new DepthBasicMaterial($.extend({},lineDepthInfo,{
- transparent: !0,
- opacity: 1,
- //map: texLoader.load(Potree.resourcePath+'/textures/pic_point_s32.png' ),
- map: texLoader.load(Potree.resourcePath+'/textures/arrows_l_32.png' ),
- useDepth:true,
- replaceColor:this.color,
- beReplacedRed: 0.184, //0.18431372
- mapColorReplace:true,
- })),
- markerMats['select' + color] = new DepthBasicMaterial($.extend({},lineDepthInfo,{
- transparent: !0,
- opacity: 1,
- map: texLoader.load(Potree.resourcePath+'/textures/arrows_l_32.png' ),
- //useDepth:true ,
- replaceColor: new THREE.Color(Potree.config.measure.highlight.color) ,
- beReplacedRed: 0.184, //0.18431372
- mapColorReplace:true
- }))
- }
- return markerMats[type + color]
-
- }
-
-
-
-
- getLineMat(type) {
-
- if(!lineMats) Measure.lineMats = lineMats = {
- guide: LineDraw.createFatLineMat({
- color:config.measure.guide.color,
- dashSize: 0.1,
- gapSize: 0.02,
- dashed: true,
- lineWidth: 2
- })
- }
-
-
-
-
- let color = this.color.getHexString()
- if(!lineMats['edgeDefault'+color]){
- lineMats['edgeDefault'+color] = LineDraw.createFatLineMat(Object.assign({}, lineDepthInfo, {
- color: this.color,
- lineWidth: config.measure.lineWidth,
- useDepth :true,
- dashWithDepth :true, // 只在被遮住的部分显示虚线,因为实线容易挡住label
- dashed :true,
- dashSize : 0.04,
- gapSize: 0.04,
- transparent: true,
- opacity: config.measure.default.opacity,
- depthTestWhenPick:true,
- }))
- lineMats['edgeSelect'+color] = LineDraw.createFatLineMat(Object.assign({}, lineDepthInfo,{
- color: Potree.config.measure.highlight.color ,
- dashSize: 0.5,
- gapSize: 0.2,
- lineWidth: config.measure.lineWidth ,
- transparent: true,
- opacity: config.measure.highlight.opacity
- }))
- }
-
-
- if(type != 'guide'){
- return Measure.lineMats[type+color]
- }else return Measure.lineMats[type]
-
-
-
-
- }
-
-
- createAreaPlane(){
- planeMats || (planeMats = {
- default: new DepthBasicMaterial( $.extend({},planeDepthInfo,{
- color:color,
- side:THREE.DoubleSide,
- opacity:0.2,
- transparent:true,
- useDepth:true
- })),
- selected: new THREE.MeshBasicMaterial({
- color: color ,
- side:THREE.DoubleSide,
- opacity:0.3,
- transparent:true,
- })
- },Measure.planeMats = planeMats)
- return super.createAreaPlane(planeMats.default)
- }
-
-
- raycast (raycaster, intersects) {
- for (let i = 0; i < this.points.length; i++) {
- let marker = this.markers[i];
- marker.raycast(raycaster, intersects);
- }
- // recalculate distances because they are not necessarely correct
- // for scaled objects.
- // see https://github.com/mrdoob/three.js/issues/5827
- // TODO: remove this once the bug has been fixed
- for (let i = 0; i < intersects.length; i++) {
- let I = intersects[i];
- I.distance = raycaster.ray.origin.distanceTo(I.point);
- }
- intersects.sort(function (a, b) { return a.distance - b.distance; });
- };
-
-
-
- transformData(prop){
- if(prop.measureType == 'Point'){
- prop.showCoordinates = true,
- prop.closed = true,
- prop.maxMarkers = 1,
- prop.minMarkers = 1
- }else if(prop.measureType == 'Distance'){
- prop.showDistances = true,
- prop.showEdges = true,
- prop.maxMarkers = 2,
- prop.minMarkers = 2
- }else if(prop.measureType == 'MulDistance'){//new
- prop.showDistances = true,
- prop.showEdges = true,
- prop.minMarkers = 2
- }else if(prop.measureType == 'Ver MulDistance'){
- prop.showDistances = true,
- prop.atPlane = true,
- prop.showEdges = true,
- prop.minMarkers = 2
- prop.faceDirection = "vertical"
- prop.unableDragAtMap = true
- }else if(prop.measureType == 'Hor MulDistance'){
- prop.showDistances = true,
- prop.atPlane = true,
- prop.showEdges = true,
- prop.minMarkers = 2
- prop.faceDirection = "horizontal"
- }else if(prop.measureType == 'Ver Distance'){
- prop.showDistances = true,
- prop.showEdges = true,
- prop.maxMarkers = 2,
- prop.minMarkers = 2,
- prop.faceDirection = "vertical"
- prop.unableDragAtMap = true
- }else if(prop.measureType == 'Hor Distance'){
- prop.showDistances = true,
- prop.showEdges = true,
- prop.maxMarkers = 2,
- prop.minMarkers = 2,
- prop.faceDirection = "horizontal"
- }else if(prop.measureType == "Hor LINE with Text"){ //add
- prop.showEdges = true,
- prop.maxMarkers = 2,
- prop.minMarkers = 2,
- prop.faceDirection = "horizontal"
-
- }else if(prop.measureType == 'Area'){
- prop.showDistances = true,
- prop.atPlane = true,
- prop.showEdges = true,
- prop.closed = true,
- prop.minMarkers = 3
- }else if(prop.measureType == 'Hor Area'){
- prop.showDistances = true,
- prop.atPlane = true,
- prop.showEdges = true,
- prop.closed = true,
- prop.minMarkers = 3
- prop.faceDirection = "horizontal"
-
- }else if(prop.measureType == 'Ver Area'){
- prop.showDistances = true,
- prop.atPlane = true,
- prop.showEdges = true,
- prop.closed = true,
- prop.minMarkers = 3
- prop.faceDirection = "vertical"
- prop.unableDragAtMap = true
- }else if(prop.measureType == 'Rect Area'){
- prop.showDistances = true,
- prop.atPlane = true,
- prop.showEdges = true,
- prop.closed = true,
- prop.minMarkers = 4
- prop.maxMarkers = 4
- }else if(prop.measureType == 'Hor Rect Area'){
- prop.showDistances = true,
- prop.atPlane = true,
- prop.showEdges = true,
- prop.closed = true,
- prop.minMarkers = 4
- prop.maxMarkers = 4
- prop.isRect = true
- prop.faceDirection = "horizontal"
- }else if(prop.measureType == 'Ver Rect Area'){
- prop.showDistances = true,
- prop.atPlane = true,
- prop.showEdges = true,
- prop.closed = true,
- prop.minMarkers = 4
- prop.maxMarkers = 4
- prop.isRect = true
- prop.faceDirection = "vertical"
- prop.unableDragAtMap = true
- }
- if(prop.atPlane && prop.closed){ //atPlane在同一平面上
- prop.showArea = true
- }
-
-
- super.transformData(prop)
-
-
-
- }
- setUnitSystem(unitSystem){
- //console.log(this.name +':' +this.unitSystem)
- if(unitSystem != this.unitSystem){
- if(unitSystem == "metric"){
-
- }else if(unitSystem == 'imperial'){
-
- }
- this.unitSystem = unitSystem
- this.update()
- }
- }
- reDraw(restMarkerCount=0){//重新开始画
- super.reDraw(restMarkerCount)
- if(this.measureType == 'Distance'){
- this.shouldShowHorVerGuide = false
- this.setEdgesDisplay(false)
- }
- if(this.showArea){
- this.area = {value:0};
- this.areaLabel && this.areaLabel.setVisible(false)
- }
- viewer.inputHandler.dispatchEvent( {type:'isMeasuring', v:true, cause:'reDraw'} )
-
- }
-
- /* get showCoordinates () {
- return this._showCoordinates;
- }
- set showCoordinates (value) {
- this._showCoordinates = value;
- this.update();
- }
- get showAngles () {
- return this._showAngles;
- }
- set showAngles (value) {
- this._showAngles = value;
- this.update();
- }
- get showCircle () {
- return this._showCircle;
- }
- set showCircle (value) {
- this._showCircle = value;
- this.update();
- }
- get showAzimuth(){
- return this._showAzimuth;
- }
- set showAzimuth(value){
- this._showAzimuth = value;
- this.update();
- }
- get showEdges () {
- return this._showEdges;
- }
- set showEdges (value) {
- this._showEdges = value;
- this.update();
- }
- get showHeight () {
- return this._showHeight;
- }
- set showHeight (value) {
- this._showHeight = value;
- this.update();
- }
- get showArea () {
- return this._showArea;
- }
- set showArea (value) {
- this._showArea = value;
- this.update();
- }
- get closed () {
- return this._closed;
- }
- set closed (value) {
- this._closed = value;
- this.update();
- }
- get showDistances () {
- return this._showDistances;
- }
- set showDistances (value) {
- this._showDistances = value;
- this.update();
- } */
- }
- function createCircleRadiusLabel(){
- const circleRadiusLabel = new TextSprite("");
- circleRadiusLabel.setTextColor({r: 140, g: 250, b: 140, a: 1.0});
- circleRadiusLabel.setBorderColor({r: 0, g: 0, b: 0, a: 1.0});
- circleRadiusLabel.setBackgroundColor({r: 0, g: 0, b: 0, a: 1.0});
- circleRadiusLabel.fontsize = 16;
- circleRadiusLabel.material.depthTest = false;
- circleRadiusLabel.material.opacity = 1;
- circleRadiusLabel.visible = false;
-
- return circleRadiusLabel;
- }
- function createCircleRadiusLine(){
- /* const lineGeometry = new LineGeometry();
- lineGeometry.setPositions([
- 0, 0, 0,
- 0, 0, 0,
- ]);
- const lineMaterial = new LineMaterial({
- color: 0xff0000,
- lineWidth: 2,
- resolution: new THREE.Vector2(1000, 1000),
- gapSize: 1,
- dashed: true,
- });
- lineMaterial.depthTest = false;
- const circleRadiusLine = new Line2(lineGeometry, lineMaterial);*/
-
- var circleRadiusLine = LineDraw.createFatLine([ ],{
- color:0xff0000,
- dashSize: 0.5,
- gapSize: 0.2,
- lineWidth: config.measure.lineWidth
- })
- circleRadiusLine.visible = false;
- return circleRadiusLine;
- }
- function createCircleLine(){
- const coordinates = [];
- let n = 128;
- for(let i = 0; i <= n; i++){
- let u0 = 2 * Math.PI * (i / n);
- let u1 = 2 * Math.PI * (i + 1) / n;
- let p0 = new THREE.Vector3(
- Math.cos(u0),
- Math.sin(u0),
- 0
- );
- let p1 = new THREE.Vector3(
- Math.cos(u1),
- Math.sin(u1),
- 0
- );
- coordinates.push(
- p0,
- p1
- );
- }
- /* const geometry = new LineGeometry();
- geometry.setPositions(coordinates);
- const material = new LineMaterial({
- color: 0xff0000,
- dashSize: 5,
- gapSize: 2,
- lineWidth: 2,
- resolution: new THREE.Vector2(1000, 1000),
- });
- material.depthTest = false;
- const circleLine = new Line2(geometry, material);
- circleLine.visible = false;
- circleLine.computeLineDistances();*/
- var circleLine = LineDraw.createFatLine(coordinates,{
- color: 0xff0000,
- dashSize: 0.5,
- gapSize: 0.2,
- lineWidth: config.measure.lineWidth
- })
- return circleLine;
- }
- /* function createCircleCenter(){
- const sg = new THREE.markerGeometry(1, 32, 32);
- const sm = new THREE.MeshNormalMaterial();
-
- const circleCenter = new THREE.Mesh(sg, sm);
- circleCenter.visible = false;
- return circleCenter;
- } */
- function createLine(){
-
- const line = LineDraw.createFatLine([ ],{
- color: 0xff0000,
- dashSize: 0.5,
- gapSize: 0.2,
- lineWidth: config.measure.lineWidth
- })
-
-
-
- return line;
- }
- function createCircle(){
- const coordinates = [];
- let n = 128;
- for(let i = 0; i <= n; i++){
- let u0 = 2 * Math.PI * (i / n);
- let u1 = 2 * Math.PI * (i + 1) / n;
- let p0 = new THREE.Vector3(
- Math.cos(u0),
- Math.sin(u0),
- 0
- );
- let p1 = new THREE.Vector3(
- Math.cos(u1),
- Math.sin(u1),
- 0
- );
- coordinates.push(
- p0,
- p1
- );
- }
-
- var line = LineDraw.createFatLine(coordinates,{
- color: 0xff0000,
- dashSize: 0.5,
- gapSize: 0.2,
- lineWidth: config.measure.lineWidth
- })
- return line;
- }
- Measure.markerMats = markerMats;
- /* function createAzimuth(){
- const azimuth = {
- label: null,
- center: null,
- target: null,
- north: null,
- centerToNorth: null,
- centerToTarget: null,
- centerToTargetground: null,
- targetgroundToTarget: null,
- circle: null,
- node: null,
- };
- const sg = new THREE.markerGeometry(1, 32, 32);
- const sm = new THREE.MeshNormalMaterial();
- {
- const label = new TextSprite("");
- label.setTextColor({r: 140, g: 250, b: 140, a: 1.0});
- label.setBorderColor({r: 0, g: 0, b: 0, a: 1.0});
- label.setBackgroundColor({r: 0, g: 0, b: 0, a: 1.0});
- label.fontsize = 16;
- label.material.depthTest = false;
- label.material.opacity = 1;
- azimuth.label = label;
- }
- azimuth.center = new THREE.Mesh(sg, sm);
- azimuth.target = new THREE.Mesh(sg, sm);
- azimuth.north = new THREE.Mesh(sg, sm);
- azimuth.centerToNorth = createLine();
- azimuth.centerToTarget = createLine();
- azimuth.centerToTargetground = createLine();
- azimuth.targetgroundToTarget = createLine();
- azimuth.circle = createCircle();
- azimuth.node = new THREE.Object3D();
- azimuth.node.add(
- azimuth.centerToNorth,
- azimuth.centerToTarget,
- azimuth.centerToTargetground,
- azimuth.targetgroundToTarget,
- azimuth.circle,
- azimuth.label,
- azimuth.center,
- azimuth.target,
- azimuth.north,
- );
- return azimuth;
- } */
- /*
-
- */
|