DrawTools.js 228 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384
  1. /**
  2. * 创建者:王成
  3. * 操作系统:MAC
  4. * 创建日期:2022年11月10日
  5. * 描述:该类主要是绘制工具 提供各种绘制方法
  6. */
  7. /* 引入Cesium */
  8. import * as Cesium from 'cesium';
  9. /* 引入地理工具箱 */
  10. import * as turf from '@turf/turf'
  11. /* 扩展数组方法 */
  12. /**
  13. * 获取数组最后一个元素
  14. */
  15. Array.prototype.last = function() {
  16. if (this === undefined || this.length === undefined || this.length === 0) return undefined;
  17. return this[this.length - 1];
  18. }
  19. /**
  20. * 获取数组第一个元素
  21. */
  22. Array.prototype.first = function() {
  23. if (this === undefined || this.length === undefined || this.length === 0) return undefined;
  24. return this[0];
  25. }
  26. /**
  27. * 设置编辑点类型
  28. * @ignore 生成方法时不对外公开
  29. * @param {options} options 配置项
  30. * @param {DrawTools.EditPointType} options.type 类型
  31. * @param {Number} options.index 索引
  32. */
  33. Cesium.Entity.prototype.setEditType = function(options) {
  34. this._editType = options;
  35. }
  36. /**
  37. * 获取编辑点类型
  38. * @ignore 生成方法时不对外公开
  39. * @return {DrawTools.EditPointType} 编辑点类型
  40. */
  41. Cesium.Entity.prototype.getEditType = function() {
  42. return this._editType;
  43. }
  44. /**
  45. * 设置实体挂接的数据类型
  46. * @ignore 生成方法时不对外公开
  47. * @param {DrawTools.DrawType} entityType 实体挂接的数据类型
  48. */
  49. Cesium.Entity.prototype.setEntityType = function(entityType) {
  50. this._entityType = entityType;
  51. }
  52. /**
  53. * 获取实体挂接的数据类型
  54. * @ignore 生成方法时不对外公开
  55. * @@return {DrawTools.DrawType} 实体挂接的数据类型
  56. */
  57. Cesium.Entity.prototype.getEntityType = function(entityType) {
  58. return this._entityType;
  59. }
  60. /**
  61. * 设置实体是否可编辑
  62. * @ignore 生成方法时不对外公开
  63. * @param {Boolean} isEdit 是否可编辑
  64. */
  65. Cesium.Entity.prototype.setIsEdit = function(isEdit) {
  66. this._isEdit = isEdit;
  67. }
  68. /**
  69. * 获取实体是否可编辑
  70. * @ignore 生成方法时不对外公开
  71. * @return {Boolean} isEdit
  72. */
  73. Cesium.Entity.prototype.getIsEdit = function() {
  74. return this._isEdit;
  75. }
  76. /**
  77. * 设置附加参数
  78. * @ignore 生成方法时不对外公开
  79. * @param {JSON} params 参数
  80. */
  81. Cesium.Entity.prototype.setParams = function(params) {
  82. this._params = params;
  83. }
  84. /**
  85. * 获取附加参数
  86. * @ignore 生成方法时不对外公开
  87. */
  88. Cesium.Entity.prototype.getParams = function() {
  89. return this._params;
  90. }
  91. /**
  92. * 绑定实体
  93. * @ignore 生成方法时不对外公开
  94. * @param {Cesium.Entity} entity 绑定的实体
  95. */
  96. Cesium.Entity.prototype.bindEntity = function(entity) {
  97. this._bindEntity = entity;
  98. }
  99. /**
  100. * 获取绑定的实体
  101. * @ignore 生成方法时不对外公开
  102. * @return {Cesium.Entity}
  103. */
  104. Cesium.Entity.prototype.getBindEntity = function() {
  105. return this._bindEntity;
  106. }
  107. /**
  108. * 类
  109. */
  110. class DrawTools {
  111. /**
  112. * 默认初始化
  113. * @ignore 生成方法时不对外公开
  114. * @param {Object} viewer 三维场景
  115. * @param {JSON} options [配置项]
  116. * @param {Boolean} options.isDrawPoint 是否绘标记点
  117. * @param {Boolean} options.isRetainDrawPoint 绘制完成,是否保留绘制点
  118. * @param {DrawTools.SketchIconType} options.iconType 点图标类型
  119. */
  120. constructor(viewer, options) {
  121. /* 赋值三维视图 */
  122. this._viewer = viewer;
  123. /* 初始化 */
  124. this._init(options);
  125. }
  126. /**
  127. * 静态方法 初始化并获取属性编辑参数
  128. */
  129. static initEditPropertyParams() {
  130. return {
  131. id: undefined, //用于标识及传递当前编辑的实体类型 内容为DrawTools.DrawType
  132. height: 20, //用于高度标识 如墙、房屋等 或OD线的中间顶点高度
  133. bottomHeight: 0, //用于标识底部高度值 如 墙、房屋等
  134. color: 'rgba(255,0,255,0.8)', //用于颜色标识
  135. direction: 'horizontal', //用于动态方向 取值为horizontal/vertical
  136. order: '-', //用于标识动态流动方向 取值范围为+/-
  137. count: 2, //用于标识动态子元素的数量
  138. text: '', //用于标识文本
  139. lineWidth: 0, //用于标识线宽
  140. power: 0.25, //用于标识发光度[0-1]
  141. outlineWidth: 0, //用于标识描边线宽度
  142. outlineColor: 'rgba(255,0,255,0.8)', //用于标识描边线颜色
  143. videoUrl: '', //用于标识视频播放地址
  144. duration: 1500, //默认播放速度
  145. odlineHeight: 1000, //OD线的弧顶高度
  146. odlineCount: 50, //OD线的插值数量
  147. }
  148. }
  149. /**
  150. * 初始化
  151. * @ignore 生成方法时不对外公开
  152. * @param {JSON} options [配置项]
  153. * @param {Boolean} options.isDrawPoint 是否绘标记点
  154. * @param {Boolean} options.isRetainDrawPoint 绘制完成,是否保留绘制点
  155. * @param {DrawTools.SketchIconType} options.iconType 点图标类型
  156. */
  157. _init(options) {
  158. /* 开启地形检测 必须开启 否则会导致获取地形高度时异常 导致鼠标移动时位置哆嗦 */
  159. this._viewer.scene.globe.depthTestAgainstTerrain = true;
  160. /* 取消地图右键点击事件 */
  161. this._viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType
  162. .LEFT_DOUBLE_CLICK);
  163. /* 创建的临时实体的名称 该名称通用 为了后期统一删除 */
  164. this._sketchEntityName = this._guid();
  165. /* 用DataSource方式管理绘制的Entity 实现工具分离 */
  166. let dataSource = new Cesium.CustomDataSource(this._sketchEntityName);
  167. this._viewer.dataSources.add(dataSource);
  168. /* 实体数据集 */
  169. this._entities = dataSource.entities;
  170. this._pointEntitys = [];
  171. /* 草图工具绘制的点图片 */
  172. this._sketchPointImage = undefined;
  173. /* 点图标 */
  174. this._iconNormal =
  175. 'data:image/png;base64,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';
  176. this._iconBlue =
  177. 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3ZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQ1IDc5LjE2MzQ5OSwgMjAxOC8wOC8xMy0xNjo0MDoyMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDozNjZmZDYyMy02NmE4LWYzNDUtODc4MC00YmMwY2IzZWM4OTMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MkEyMUE1MDg3NTAyMTFFREI0RUY4MjBCRjRGRDc0QUIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MkEyMUE1MDc3NTAyMTFFREI0RUY4MjBCRjRGRDc0QUIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTkgKFdpbmRvd3MpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OWFmM2ZiODktNzQ4OS1kMDRkLTkyNzUtZDM5MWNhYzYwMGE1IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjM2NmZkNjIzLTY2YTgtZjM0NS04NzgwLTRiYzBjYjNlYzg5MyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pv/grmkAAAhxSURBVHjazFoLUFVFGN49597LBdFUEpEQI0IpyxIfqU1ZkY/pNZg1RZlWY2lW4yMncxq18oHZ0+lhOaWZUo0zPjIr8W1NiubI+AxBIkRQQsQE7us8tv3P7qGL7gXOPRdzZ3bmcnf3+7/v/Lv/+f/lYkIIMpur2yBktQVO5yM7LRybIvsOFKFGCeHyQz/dFO2Ousflcg6UJSlVlqVEjHEMjNMH5tE0vVLT9ZJAQNnn9fm3d+9z3xEYioR9bNcjW9Z8Gtv35l7PUAFjnU5HLytrFUU9TgV9XXD4+PJhoyfV2/GIFO4TGD8my1lVuGXSHYNuPdyhfbv5VkVAgzWwFjAACzAvp0fwoV++uz6lxzXLolzOW1AEmz+gHCwtq3i2z52Pn2jtlgvXI1LpgQ0jeqYm74y0CGiACdjUxkir3KxMlsoKNj6WmNAlV5Kk9qiNGmBTG6vAlhV+rd1aUuGeNSNSeiSuolGo2X1cdDogbThQ79h21CMfP6NKtR4dw/edYiTSK8GhZ/aO0R7KiFV7dnPpzeFQXkppWeWY9MGj8+ifektbqzVC8KbVH6UNHdJvOw2nHUIB7vrDI89df861p0SRsUSjuiSzB4qxyYzx0TVEdBUNTnVqs7I6B4beEKOFwqThuu7X/IJ7hj/yYlGoM9NqIakpSVH7t67c3C4muq8IyKcQ9EpuddSK3xqcSHJR7g7WsSkCm8+YiSEgRuU9gMbd3k5578kufrcTC8U0eLwF/e99anhJ6Sm/HSHSid/Xv5CclJAjAjlXr+GHP6x07z9JZCSDCBfzBJapBomJabJfdKqFCiGa4RkQgrQA6p+MtbVTEn2dY2XhUz956szM6wdkLRFtsVZFrReeeaRTQte46aIxT4DgrA9ABJKRw42QTLsjimqATgUZwpxNO/0OGz3KmMvWuBFgABZgimwBB+ASbtSSp0zIHutyOuNEg9NW/e06UE49YRBi5LFB2NxaMoQg5iGJfza+Y+MwlwlmogALMIXpD+UAXIBTOEKi4rt0zg51sFft8TjN7YQbnzrbVpeeD8Q+w3fYFCQba9ha5kHABGyRTcrlCeBkVQjO/Wxeb3rA00WDb62rcbHzAARML0hBAloK+lyQ4TEHx2B4BragUS69vl06/6aLnk6LQuQ+vdMyRQMHT/ql/D9VGfEQi00PGFDYwqsP8/AsMQyJbTvABhuiFb3TU+8Otb1CCXFd1SF2gGhg/f56Bw4+B9iCJ0J5Bv93fgAbbIimd7yq/UDgZklITLQ7RTSwp9grs7MgBYXYMEQ0OTtBWBR7d5FX+NQ5J0tCHG63K0GYglSpkrklGkXY1GGKMbdo8d+qkBfn5LB0RpwOeDlc2mo9NNYHbyOMIuCRptvNsCGqXxgnS2dEoslhxMrgSDXOSbL0HlFVzSv6vlMMJigorWGpnJ2ymzRdTrENGxY4NSeE+PwBYQ3ds6tDN1IewvvFRMLQwTBMPB2lxTuEaTvnRKwI0S/U1ZeLBganRWtGwteYAOoR8EgQFsUe3DNamNpzTroVIWp1TW2xaCCrf6xKzDScaP89SRKGGBLkCSMjVo1aZRS1IZrOOalWhCgHjxTvEw3ckhylD7rOobF6ghZJphhk1TO80DK8Yab1KgJssCHMKhgnxYqQQM7i5bv9AaVONDh7VFzAqCWMekLhRZIFzzQWWLzIMjAY3qwsii2+YakDTsDNkkdoRVZbXHLyN9EglKdjh8QoUBSBcaIDEYU91cbtRi7yUFCF2OgBha9lBRZg3nWjuPQFLsDJqkfAtfWfr1jzDSHiR/zuk/GBjO5YQyqtQDU/5WYKCjo/Oicd/JmPw1xYA2sBA7AAM8RFBAEuwMnqYTei3Q95vx47U1VzTJj3uDBZNzXRl9EdUTE+SshnECJcFPOWwraNxj0GYo3OyLM1PgQYgAWYIlvAAbgAp3AKK6XyTPXZ56bOm0f3p/BFFEdr7LwZSd5xQ9wKUukUo/u4h8SdecCHzPmwdtOMJF9ciHodbE+cvmA+cAm1rVoSAsD1m3fmH127cfvSUJOiXRh98nS8/8dpXb0DknWNKB5qzsOIKlwYdIULpWMwB+ZunNrVC2tDeQIa2P552+4jfFsROxd0sbRfm5/31dyMPumZLQWkwsqA9EOTCzqCzdTGvKB7MCNWTU9s/oIOWsHh41tvGz5uNv34Fxdi64IOvNaxQ/t2aXvzVixKTUnqezkSRBqhCm4bMW7GhboGuJw7H+qQW7nEBoALFPCvOx8cP+toYUl+W4v4o6h0L9iiNkvBdnNXplYvsSEtOFddc75owLCxc6jLd7aVCMDulzlmDtgCm6FSEju38RAxztJUumTkoy+9faqyqjDSIgDzgezJi6gN+P9Is1HKjpBGz9T+U1cy+ulXZ9XU/lMRKRGABZjUEyeseCJcIY1i6BY4NmHagjlen/+CXREUow6wADMcEeEKQTxxq96wadfvCz9cvpBuBSVcEbCWYuQAFmCGSgrbSojx0qW9KmfxV5u/zP1+MTEqI6vlCNFhLWAAFsdEl1sIvIAgdTn98muL1mzZtXe1VYCtv+xbDWsBg2OR/0OIKaaB9ooHsqcsoXt8h4Uwu+P+xyfD/zwqOIatHw7YFQJvVthSUICVDxs9Kae0rOJwS2vKyk8fgbmwhq/V7fKwLYSLgWLoPLz9s59//c3mwjKMPTZ+5hswl6ceWiQ4REQIF2OE5QOHCo9NfCVndoPHW3vxHPgOxmAOzOVr0BUlhIuB0Hn2+5937p/77hcLgsMyfF7wwbKFMAZz+Fx0RQoJDsvvL8ndYYZlM8y+8/HKbXbDbKgW8ftd+qQJLQcglFZCaE3qFn81wogEh1mYE/F74bb64RnFAm/DDwy6mPdrkJLzKGfLpsj+vwIMACSZzfDJFmOPAAAAAElFTkSuQmCC';
  178. this._iconGreen =
  179. 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3ZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQ1IDc5LjE2MzQ5OSwgMjAxOC8wOC8xMy0xNjo0MDoyMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDozNjZmZDYyMy02NmE4LWYzNDUtODc4MC00YmMwY2IzZWM4OTMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MjI1NDIwOUU3NTAyMTFFRDk0MTJGQzhGMTFCQkREODIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MjI1NDIwOUQ3NTAyMTFFRDk0MTJGQzhGMTFCQkREODIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTkgKFdpbmRvd3MpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OWFmM2ZiODktNzQ4OS1kMDRkLTkyNzUtZDM5MWNhYzYwMGE1IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjM2NmZkNjIzLTY2YTgtZjM0NS04NzgwLTRiYzBjYjNlYzg5MyIv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';
  180. this._iconViolet =
  181. 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3ZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQ1IDc5LjE2MzQ5OSwgMjAxOC8wOC8xMy0xNjo0MDoyMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDozNjZmZDYyMy02NmE4LWYzNDUtODc4MC00YmMwY2IzZWM4OTMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MzFDREU3Mjk3NTAyMTFFREE4MThDODBGNzMxNDBCQzEiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MzFDREU3Mjg3NTAyMTFFREE4MThDODBGNzMxNDBCQzEiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTkgKFdpbmRvd3MpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OWFmM2ZiODktNzQ4OS1kMDRkLTkyNzUtZDM5MWNhYzYwMGE1IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjM2NmZkNjIzLTY2YTgtZjM0NS04NzgwLTRiYzBjYjNlYzg5MyIv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';
  182. /* 图片资源 */
  183. this._image_arrow_forward =
  184. 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAAgCAYAAABkS8DlAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA4FpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQ4IDc5LjE2NDAzNiwgMjAxOS8wOC8xMy0wMTowNjo1NyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDplMWFmZGVkNi00MTJhLTc5NDAtYjQxMC04NDExNjRiMzQ0ODciIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QTA3MThEMzhCMjc3MTFFRDg1ODdDNkY4OTc4ODRCRjUiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QTA3MThEMzdCMjc3MTFFRDg1ODdDNkY4OTc4ODRCRjUiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIxLjAgKFdpbmRvd3MpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6YjI3YWU1YjEtZmRkMy0wOTQyLWIyMzUtMDFkYWY3YTJlNGUyIiBzdFJlZjpkb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6YWUwMWJjYWItYzAxZS04YTQyLTg4MjAtNDU1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';
  185. this._image_arrow_reverse =
  186. 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAAgCAYAAABkS8DlAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA4FpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQ4IDc5LjE2NDAzNiwgMjAxOS8wOC8xMy0wMTowNjo1NyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDplMWFmZGVkNi00MTJhLTc5NDAtYjQxMC04NDExNjRiMzQ0ODciIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QThBQTYyN0ZCMjc2MTFFREIzM0E4RjQ4Q0YwQTgyMzgiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QThBQTYyN0VCMjc2MTFFREIzM0E4RjQ4Q0YwQTgyMzgiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIxLjAgKFdpbmRvd3MpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6YmIzYjdkNGEtYmQwYi04YjRjLTkwNmQtMTRhMTNkNjEwZWUxIiBzdFJlZjpkb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6YWUwMWJjYWItYzAxZS04YTQyLTg4MjAtNDU1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';
  187. this._image_h_l_r =
  188. 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAAgCAYAAABkS8DlAAABIklEQVR4nO3WbQuCMBiG0dn//80tiAp6WT4zi+A+54vTTdMKuZZ20Y/H2/is9/r+aFxdNz5/qa7t1/Gr+dlj79ZX5mrnvz93p+3T9zKznbnnynW/OPfwnLXP/v2xqXvolXv8dH7Ld7Vhvs+cf/2v/d/vd3dfq8/0zbm1a1d/18L2o3fIzHbtnVi51p5zK8f6q3Xj8cza8XjrusH+oQEAcQQAAAQSAAAQSAAAQCABAACBBAAABBIAABBIAABAIAEAAIEEAAAEEgAAEEgAAEAgAQAAgQQAAAQSAAAQSAAAQCABAACBBAAABBIAABBIAABAIAEAAIEEAAAEEgAAEEgAAEAgAQAAgQQAAAQSAAAQSAAAQCABAACBBAAABBIAAJCmtXYCutDwWwUr9cEAAAAASUVORK5CYII=';
  189. this._image_h_r_l =
  190. 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAAgCAYAAABkS8DlAAAAAXNSR0IArs4c6QAAAFBlWElmTU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAACAKADAAQAAAABAAAAIAAAAACVLBWUAAABWWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgoZXuEHAAAC90lEQVR4Ae3WzVbbMBAG0PzBgcOa93/M7nCj2F8zUUILdDmXjWTNSLauBMz+19vbstvvl139+c5zza39sd7hUNe99mveZ/3dbs3/LF7W3j/IXbZ5hzI/Yzf7TXxux/fPY3n+W+wrOfP3Zs5P26wXk22d/bzenJf8jNf82h/73XLOh7KeS51b++fEw/R8uQfzetvzsubmbtyuPXLmteo6W/9Qv2lZ7te4fde6l6xT52Ysbf22jK3t+o7j8frdt/H1HTWe96RdY+v8OnfrX84u45kznrPm6Cde2/THnPRrW/vjK+e8OT6e61j6OZcaH/ZbfDvXy+/Qsc5Jv55TxtKOWNY/t39+bx/NSV6dk3VGrM4Zu/2fsbFW/Ou69RvGO2rOFlvq2Pwdc2w8Z/0tdpqeL/HTab0/iaWd1xt5iaWd587PyXt6evyOOT939LP8jCcv66d9fn78nsSH2cvLv3OS//p6mzvmJza3Izb+D64/ae/zR/zR3IyN+MfH/fz39+tY9j9yv9//6pw57+45/xvOfzv9ECBAgAABAt0EFADdTtx+CRAgQIDAWUAB4BoQIECAAIGGAgqAhoduywQIECBAQAHgDhAgQIAAgYYCCoCGh27LBAgQIEBAAeAOECBAgACBhgIKgIaHbssECBAgQEAB4A4QIECAAIGGAgqAhoduywQIECBAQAHgDhAgQIAAgYYCCoCGh27LBAgQIEBAAeAOECBAgACBhgIKgIaHbssECBAgQEAB4A4QIECAAIGGAgqAhoduywQIECBAQAHgDhAgQIAAgYYCCoCGh27LBAgQIEBAAeAOECBAgACBhgIKgIaHbssECBAgQEAB4A4QIECAAIGGAgqAhoduywQIECBAQAHgDhAgQIAAgYYCCoCGh27LBAgQIEBAAeAOECBAgACBhgIKgIaHbssECBAgQEAB4A4QIECAAIGGAgqAhoduywQIECBAQAHgDhAgQIAAgYYCCoCGh27LBAgQIEBAAeAOECBAgACBhgK/AX08dE/3SOoSAAAAAElFTkSuQmCC';
  191. this._image_v_b_t =
  192. 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAAgCAYAAABkS8DlAAADcklEQVR4nO3di27bMAyFYdpWLuv2/o+aJfFFgxOp5VjKdjDM6rD/A4KkbZyhwIBzTMluE/s+CAAA+J/EIH1/SL9ws/KLR/5rAADwZb2S4zHIMBzVN9YOzh8QN74XAAD8HTmLt2Z3Ns3PId7vR/MB9oPihtcAAGBfOq9Lr3WOR/0Icrt5BaAxb14rAwAA4OsUAC/HPxWAk4i0hSmAF/iT8zMAALCvnNXtQiHwwn/O8WkuAGdTALy1hFhoEQAAoA5ver+W4aoAXK8UAAAA/j1/UgDGED8mAHYZQB/ofYBQAgAAqMIL/qXN/L+F/6MAyPX6TUS6lQLgPYQCAABAFaUCsJbjY3oMQS4XXQDaFwoAywAAANRRCv6lApDP/odHAYi3Wy4A3YYCMFEAAACozgv9tUn+qApAnycA4cUCMFEAAACoxgv+LQVgSI8Q5OdPWwDawoE2/CcKAAAAVZTC3zuRn5wC0M0F4LuIHJx9AHb3/2TCnwIAAEAdugC0zmtRWW4LwP0xAYjPCcAhTQHswZ9uHOAUAQAAsC971t8WLunXBeD97H9+X14COBT2Adj1flsCKAAAAOzPC35vGcBb/291ATguFIBS8FMAAACoo1QASpP8993/7wUgLQGcUgEICxMAHfojVwIAAFCNLQDdCwUgPDcBXi5vqQAcCgUgOsFv9wIAAID9NE74ezf1swXgnt7X6CWAo7oh0FIBGLkSAACAqvJGPxv+paX8UW8AnH+Q7wR4NhsBvQIwqgnASAEAAKAaO/7fUgB6lfEx3wnwbDYCLhWAkQIAAEBVXgHwbuufc3xQ9/xJBeB6PacCcFooAF74jxQAAACqWAp/fVdfXQD6lO+PE/ggH0sA+koAUQdKOpACAADA1/BKARC1AbDNpSDE5wQgXwrYpQKwNgEYKQAAAFRTKgD27/roCYC+1f84TwDOZg9AMAfa9f+BCQAAAFW16iqAYJ717YBzjg9qiX96/jng2+2Uzv6PqgSUJgCDKQHcDRAAgP3Zs/9gvvY2Abb6ioC5AOTgP5vw17p0QKueKQAAANThFYCgzvytLn2dpwHHEO/3tfCX9P2ggr8zlwICAIB9NGb8vxT8OsePefw/XxIYpO9/mJ3/S/LGgqDW/ikAAADsp9kQ+J45v9/S9+NcALaGv5X/4W77IQAAoLI3EWl/AQ/TsX9wLtbWAAAAAElFTkSuQmCC';
  193. this._image_v_t_b =
  194. 'data:image/png;base64,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';
  195. /* 存储的点集合 */
  196. this._sketchTempPoints = []; //临时点集合 主要为了存储鼠标移动事件临时存储点
  197. this._sketchPoints = []; //正式点集合 主要为了绘制正式图形
  198. this._sketchOutputPoints = []; //输出点集合 主要为了存储输出的经纬度坐标点集合
  199. this._sketchWallHeights = []; //墙的高度点集合
  200. /* 当前绘制的实体 */
  201. this._drawEntity = undefined;
  202. /* 点线标注 */
  203. this._lineLabel = undefined;
  204. this._polygonLabel = undefined;
  205. /* 配置是否绘制点 */
  206. if (options && options.isDrawPoint) this._isDrawPoint = options.isDrawPoint;
  207. else this._isDrawPoint = false;
  208. /* 配置绘制完成是否保留绘制点 */
  209. if (options && options.isRetainDrawPoint) this._isRetainDrawPoint = options.isRetainDrawPoint;
  210. else this._isRetainDrawPoint = false;
  211. /* 通用参数集合 */
  212. this._param = {
  213. lineWidth: 3, //线宽度
  214. lineColor: 'rgba(0,255,0,0.75)', //线颜色
  215. outlineWidth: 2, //边框宽度
  216. outlineColor: 'rgba(255,255,255,1)', //边框颜色
  217. polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
  218. wallHeight: 30, //高度 墙、房屋
  219. power: 0.25, //发光强度
  220. odlineHeight: 1000, //OD线弧顶高度
  221. odlineCount: 50, //OD线插值数量
  222. text: '金田产业集团', //立体广告默认文字
  223. duration: 1500, //动画播放速度
  224. count: 1, //动态流动 展示数量
  225. direction_h: 'horizontal', //水平方向
  226. direction_v: 'vertical', //垂直方向
  227. order_add: '+', //正向
  228. order_minus: '-', //反向
  229. houseColor: 'rgba(0,255,0,0.95)' //房屋默认填充颜色
  230. }
  231. /* 设置点符号类型 */
  232. if (options && options.iconType) {
  233. switch (options.iconType) {
  234. case DrawTools.IconType.Normal:
  235. this._sketchPointImage = this._iconNormal;
  236. break;
  237. case DrawTools.IconType.Blue:
  238. this._sketchPointImage = this._iconBlue;
  239. break;
  240. case DrawTools.IconType.Green:
  241. this._sketchPointImage = this._iconGreen;
  242. break;
  243. case DrawTools.IconType.Violet:
  244. this._sketchPointImage = this._iconViolet;
  245. break;
  246. default:
  247. this._sketchPointImage = this._iconNormal;
  248. break;
  249. }
  250. } else {
  251. this._sketchPointImage = this._iconNormal;
  252. }
  253. /* 获取画布的宽度和高度 */
  254. this._canvasWidth = this._viewer.scene.canvas.width;
  255. this._canvasHeight = this._viewer.scene.canvas.height;
  256. }
  257. /**
  258. * 弧度转度
  259. * @ignore 生成方法时不对外公开
  260. * @param {Number} arc 弧度
  261. * @return {Number} 角度
  262. */
  263. _arcToDegree(arc) {
  264. return arc / Math.PI * 180;
  265. }
  266. /**
  267. * 普通颜色值转换为Cesium颜色
  268. * @ignore 生成方法时不对外公开
  269. * @param {int} red 红色[0~255]
  270. * @param {int} green 绿色[0~255]
  271. * @param {int} blue 蓝色[0~255]
  272. * @param {int} alpha 透明度[0~1]
  273. * @return {Cesium.Color} Cesium格式的颜色
  274. */
  275. _toColor(red, green, blue, alpha) {
  276. let normalColor = new Cesium.Color(0, 0, 0, 1.0);
  277. if (typeof red != 'number') return normalColor;
  278. if (typeof green != 'number') return normalColor;
  279. if (typeof blue != 'number') return normalColor;
  280. if (typeof alpha != 'number') return normalColor;
  281. if (red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255 || alpha < 0 || alpha > 1)
  282. return normalColor;
  283. return new Cesium.Color(red / 255.0, green / 255.0, blue / 255.0, alpha);
  284. }
  285. /**
  286. * 通过颜色数组转换为Cesium颜色
  287. * @ignore 生成方法时不对外公开
  288. * @param {Array} array 颜色数组
  289. * @return {Cesium.Color} Cesium格式的颜色
  290. */
  291. _toColorFromArray(array) {
  292. if (!array || array.length === undefined || array.length === 0) return new Cesium.Color(255 / 255.0, 255 /
  293. 255.0, 255 / 255.0, 1.0);
  294. let r = 255,
  295. g = 255,
  296. b = 255,
  297. a = 1.0;
  298. if (array.length === 1) {
  299. r = parseInt(array[0]);
  300. } else if (array.length === 2) {
  301. r = parseInt(array[0]);
  302. g = parseInt(array[1]);
  303. } else if (array.length === 3) {
  304. r = parseInt(array[0]);
  305. g = parseInt(array[1]);
  306. b = parseInt(array[2]);
  307. } else if (array.length >= 4) {
  308. r = parseInt(array[0]);
  309. g = parseInt(array[1]);
  310. b = parseInt(array[2]);
  311. a = parseFloat(array[3]);
  312. }
  313. return new Cesium.Color(r / 255.0, g / 255.0, b / 255.0, a);
  314. }
  315. /**
  316. * 刷新场景 刷新一帧
  317. * @ignore 生成方法时不对外公开
  318. */
  319. _updateScene() {
  320. this._viewer.scene.requestRender();
  321. }
  322. /**
  323. * 根据地形或实景或模型检测当前屏幕位置的世界坐标系位置
  324. * @ignore 生成方法时不对外公开
  325. * @param {JSON} screenPosition 屏幕坐标
  326. * @param {Number} screenPosition.x 屏幕坐标x
  327. * @param {Number} screenPosition.y 屏幕坐标y
  328. * @return {JSON} 位置信息{x,y,z}
  329. */
  330. _getScreenClickPosition(screenPosition) {
  331. let resCartesian = undefined;
  332. let ray = this._viewer.scene.camera.getPickRay(screenPosition);
  333. let position = this._viewer.scene.globe.pick(ray, this._viewer.scene);
  334. let cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position);
  335. if (Cesium.defined(position)) {
  336. resCartesian = {
  337. x: position.x,
  338. y: position.y,
  339. z: position.z,
  340. }
  341. }
  342. return resCartesian;
  343. }
  344. /**
  345. * 根据地形或实景或模型检测当前屏幕位置的经纬度及高度
  346. * @ignore 生成方法时不对外公开
  347. * @param {JSON} screenPoint 屏幕坐标
  348. * @param {Number} screenPoint.x 屏幕坐标x
  349. * @param {Number} screenPoint.y 屏幕坐标y
  350. * @return {JSON} 位置信息{lng,lat,height}
  351. */
  352. _getScreenClickPositionAndHeight(screenPoint) {
  353. var lng = undefined,
  354. lat = undefined,
  355. height = undefined;
  356. /* 从相机位置到 windowPosition 处的像素创建射线在世界坐标系中 */
  357. var ray = this._viewer.scene.camera.getPickRay(screenPoint);
  358. /* 找到射线与渲染的地球表面之间的交点 */
  359. var position = this._viewer.scene.globe.pick(ray, this._viewer.scene);
  360. /* 获取地理位置的制图表达 */
  361. var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position);
  362. cartographic = Cesium.Cartographic.fromCartesian(position);
  363. /* 查询屏幕位置的要素 */
  364. var feature = this._viewer.scene.pick(screenPoint);
  365. if (feature === undefined && Cesium.defined(cartographic)) {
  366. lng = this._arcToDegree(cartographic.longitude);
  367. lat = this._arcToDegree(cartographic.latitude);
  368. height = cartographic.height;
  369. } else {
  370. var cartesian = this._viewer.scene.pickPosition(screenPoint);
  371. if (Cesium.defined(cartesian)) {
  372. var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
  373. if (Cesium.defined(cartographic)) {
  374. lng = this._arcToDegree(cartographic.longitude);
  375. lat = this._arcToDegree(cartographic.latitude);
  376. height = cartographic.height;
  377. }
  378. }
  379. }
  380. /* 返回结果 */
  381. return {
  382. lng: lng,
  383. lat: lat,
  384. height: height,
  385. }
  386. }
  387. /**
  388. * 屏幕位置转换为经纬度位置及空间位置
  389. * @ignore 生成方法时不对外公开
  390. * @param {Cesium.Cartesian2} screenPosition 屏幕位置
  391. * @return {JSON} 经纬度位置及空间位置
  392. */
  393. _transfromFromScreenPoint(screenPosition) {
  394. /* 根据屏幕位置获取经度、纬度和高度信息 */
  395. let location = this._getScreenClickPositionAndHeight(screenPosition);
  396. if (location.lng != undefined) {
  397. /* 经纬度位置转换为三维坐标 */
  398. var cartesian = Cesium.Cartesian3.fromDegrees(location.lng, location.lat, location
  399. .height);
  400. /* 返回 */
  401. return {
  402. gLocation: location,
  403. sLocation: cartesian,
  404. }
  405. } else {
  406. /* 返回 */
  407. return {
  408. gLocation: undefined,
  409. sLocation: undefined,
  410. }
  411. }
  412. }
  413. /**
  414. * 根据Entity的名称批量删除Entity
  415. * @ignore 生成方法时不对外公开
  416. * @param {String} entityName 实体名称
  417. */
  418. _removeEntityByName(entityName) {
  419. /* 获取实体集合 */
  420. var entities = this._entities;
  421. /* 如果不存在实体集合或集合中没有数据 则返回 */
  422. if (!entities || !entities.values) return;
  423. var delEntitys = [];
  424. /* 循环获取当前集合中的所有实体 */
  425. for (var i = 0; i < entities.values.length; i++) {
  426. if (entities.values[i].name == entityName) {
  427. delEntitys.push(entities.values[i]);
  428. }
  429. }
  430. /* 删除符合条件的所有实体 */
  431. for (var i = 0; i < delEntitys.length; i++) {
  432. entities.remove(delEntitys[i]);
  433. }
  434. /* 更新场景 */
  435. this._updateScene();
  436. }
  437. /**
  438. * 移除实体
  439. * @ignore 生成方法时不对外公开
  440. * @param {Cesium.Entity} objEntity 实体
  441. */
  442. _removeEntityByObject(objEntity) {
  443. if (!Cesium.defined(objEntity)) return;
  444. this._entities.remove(objEntity);
  445. }
  446. /**
  447. * 绘制点
  448. * @ignore 生成方法时不对外公开
  449. * @param {Cesium.Cartesian3} coord 坐标
  450. * @param {String} label [点上面显示的文字标注]
  451. */
  452. _createPoint(coord, label) {
  453. let _self = this;
  454. /* 创建点实体 */
  455. let entity = new Cesium.Entity({
  456. name: _self._sketchEntityName + "_Point",
  457. position: coord,
  458. billboard: {
  459. image: _self._sketchPointImage,
  460. horizontalOrigin: Cesium.HorizontalOrigin.center,
  461. verticalOrigin: Cesium.VerticalOrigin.bottom,
  462. scale: 0.5,
  463. pixelOffset: new Cesium.Cartesian2(0, -11),
  464. disableDepthTestDistance: Number.POSITIVE_INFINITY,
  465. }
  466. });
  467. /* 判断是否需要绘制文字 */
  468. if (label) {
  469. entity.label = {
  470. text: label,
  471. font: '12px sans-serif',
  472. fillColor: this._toColor(255, 255, 255, 1.0),
  473. outlineColor: this._toColor(0, 154, 94, 1.0),
  474. style: Cesium.LabelStyle.FILL_AND_OUTLINE,
  475. outlineWidth: 1.0,
  476. verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
  477. pixelOffset: new Cesium.Cartesian2(0, -28),
  478. showBackground: true,
  479. backgroundColor: this._toColor(0, 0, 0, 0.6),
  480. disableDepthTestDistance: Number.POSITIVE_INFINITY,
  481. }
  482. }
  483. /* 加入集合中 */
  484. this._entities.add(entity);
  485. /* 加入点集合数组中 */
  486. this._pointEntitys.push(entity);
  487. this._updateScene();
  488. }
  489. /**
  490. * 删除全部点
  491. * @ignore 生成方法时不对外公开
  492. */
  493. _removePointEntitys() {
  494. /* 清除所有绘制的点实体 */
  495. this._removeEntityByName(this._sketchEntityName + "_Point");
  496. /* 清除用于临时存储的点实体集合 */
  497. this._pointEntitys = [];
  498. }
  499. /**
  500. * 调用更新椭圆中心点位置信息
  501. * @ignore 生成方法时不对外公开
  502. * @return {Cesium.Cartesian3}
  503. */
  504. _callUpdaeEllipseCenterPosition() {
  505. let _self = this;
  506. return function() {
  507. let point1cartographic = Cesium.Cartographic.fromCartesian(_self
  508. ._sketchTempPoints[0]);
  509. let point2cartographic = Cesium.Cartographic.fromCartesian(_self
  510. ._sketchTempPoints[1]);
  511. _self._sketchEllipseCenterPosition = Cesium.Cartesian3.fromDegrees(Cesium.Math.toDegrees(
  512. point1cartographic
  513. .longitude), Cesium.Math.toDegrees(point1cartographic
  514. .latitude),
  515. point2cartographic.height);
  516. return _self._sketchEllipseCenterPosition;
  517. }
  518. }
  519. /**
  520. * 圆半径变更回调
  521. * @ignore 生成方法时不对外公开
  522. * @param {Array<Cesium.Cartesian3>} positions 位置数据点集合
  523. */
  524. _callUpdateEllipseMinorAxis(positions) {
  525. let _self = this;
  526. return function() {
  527. if (positions === undefined || positions.length === undefined || positions.length < 2) {
  528. _self._sketchEllipseRadius = 0;
  529. } else {
  530. let point1cartographic = Cesium.Cartographic.fromCartesian(positions[0]);
  531. let point2cartographic = Cesium.Cartographic.fromCartesian(positions[1]);
  532. /* 计算距离 */
  533. let geodesic = new Cesium.EllipsoidGeodesic();
  534. geodesic.setEndPoints(point1cartographic, point2cartographic);
  535. _self._sketchEllipseRadius = geodesic.surfaceDistance;
  536. if (_self._sketchEllipseRadius <= 0) _self._sketchEllipseRadius = 1;
  537. }
  538. return _self._sketchEllipseRadius;
  539. }
  540. }
  541. /**
  542. * 圆的边界变更回调
  543. * @ignore 生成方法时不对外公开
  544. * @param {Array<Cesium.Cartesian3>} positions 圆的点数据集合
  545. */
  546. _callEllipseOutlineCoordinate(positions) {
  547. let _self = this;
  548. return function() {
  549. let positionCenter = positions[0];
  550. let positionRotate = positions[1];
  551. _self._ellipseOutlineCoordinates = [];
  552. for (let angle = 5; angle < 360;) {
  553. let newPosition = _self._rotatedPointByAngle(positionRotate, positionCenter, angle);
  554. _self._ellipseOutlineCoordinates.push(newPosition);
  555. angle = angle + 5;
  556. }
  557. _self._ellipseOutlineCoordinates.push(_self._ellipseOutlineCoordinates[0]);
  558. return _self._ellipseOutlineCoordinates;
  559. }
  560. }
  561. /**
  562. * position_A绕position_B逆时针旋转angle度(角度)得到新点
  563. * @ignore 生成方法时不对外公开
  564. * @param {Cesium.Cartesian3} position_A 动点
  565. * @param {Cesium.Cartesian3} position_B 中心点
  566. * @param {Number} angle 旋转角度
  567. */
  568. _rotatedPointByAngle(position_A, position_B, angle) {
  569. //以B点为原点建立局部坐标系(东方向为x轴,北方向为y轴,垂直于地面为z轴),得到一个局部坐标到世界坐标转换的变换矩阵
  570. var localToWorld_Matrix = Cesium.Transforms.eastNorthUpToFixedFrame(position_B);
  571. //求世界坐标到局部坐标的变换矩阵
  572. var worldToLocal_Matrix = Cesium.Matrix4.inverse(localToWorld_Matrix, new Cesium.Matrix4());
  573. //B点在局部坐标的位置,其实就是局部坐标原点
  574. var localPosition_B = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, position_B, new Cesium
  575. .Cartesian3());
  576. //A点在以B点为原点的局部的坐标位置
  577. var localPosition_A = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, position_A, new Cesium
  578. .Cartesian3());
  579. //根据数学公式A点逆时针旋转angle度后在局部坐标系中的x,y,z位置
  580. var new_x = localPosition_A.x * Math.cos(Cesium.Math.toRadians(angle)) + localPosition_A.y * Math.sin(Cesium
  581. .Math.toRadians(angle));
  582. var new_y = localPosition_A.y * Math.cos(Cesium.Math.toRadians(angle)) - localPosition_A.x * Math.sin(Cesium
  583. .Math.toRadians(angle));
  584. var new_z = localPosition_A.z;
  585. //最后应用局部坐标到世界坐标的转换矩阵求得旋转后的A点世界坐标
  586. return Cesium.Matrix4.multiplyByPoint(localToWorld_Matrix, new Cesium.Cartesian3(new_x, new_y, new_z),
  587. new Cesium.Cartesian3());
  588. }
  589. /**
  590. * 矩形坐标更新回调
  591. * @ignore 生成方法时不对外公开
  592. * @param {Array<Cesium.Cartesian3>} positions 坐标数据集合
  593. */
  594. _callUpdateRectangleCoordinates(positions) {
  595. let _self = this;
  596. return function() {
  597. /* 对坐标进行转换 */
  598. let g0 = Cesium.Ellipsoid.WGS84.cartesianToCartographic(positions[0]);
  599. let g1 = Cesium.Ellipsoid.WGS84.cartesianToCartographic(positions[1]);
  600. /* 获取转换 */
  601. let lng0 = Cesium.Math.toDegrees(g0.longitude);
  602. let lat0 = Cesium.Math.toDegrees(g0.latitude);
  603. let lng1 = Cesium.Math.toDegrees(g1.longitude);
  604. let lat1 = Cesium.Math.toDegrees(g1.latitude);
  605. _self._rectangleCoordinates = [0, 0, 1, 1];
  606. if (lng0 < lng1) {
  607. _self._rectangleCoordinates[0] = lng0;
  608. _self._rectangleCoordinates[2] = lng1;
  609. } else {
  610. _self._rectangleCoordinates[0] = lng1;
  611. _self._rectangleCoordinates[2] = lng0;
  612. }
  613. if (lat0 < lat1) {
  614. _self._rectangleCoordinates[1] = lat0;
  615. _self._rectangleCoordinates[3] = lat1;
  616. } else {
  617. _self._rectangleCoordinates[1] = lat1;
  618. _self._rectangleCoordinates[3] = lat0;
  619. }
  620. let rectangle = Cesium.Rectangle.fromDegrees(_self._rectangleCoordinates[0], _self
  621. ._rectangleCoordinates[1],
  622. _self._rectangleCoordinates[2], _self._rectangleCoordinates[3]);
  623. /* 计算并返回矩形的边界线坐标数组 */
  624. let res = _self._calculateRectangleOutlineCoordinates(rectangle);
  625. _self._rectangleOutlineCoordinates = res.cPoints;
  626. _self._sketchOutputPoints = res.gPoints;
  627. return rectangle;
  628. }
  629. }
  630. /**
  631. * 计算矩形的外围坐标串
  632. * @ignore 生成方法时不对外公开
  633. * @param {Cesium.Rectangle} rectangle 矩形
  634. * @return {Array<Cesium.Cartesian3>} 坐标串集合
  635. */
  636. _calculateRectangleOutlineCoordinates(rectangle) {
  637. /* 计算东南角 */
  638. let south_east = Cesium.Rectangle.southeast(rectangle);
  639. let se = Cesium.Cartographic.toCartesian(south_east);
  640. /* 计算西南角 */
  641. let south_west = Cesium.Rectangle.southwest(rectangle);
  642. let sw = Cesium.Cartographic.toCartesian(south_west);
  643. /* 计算东北角 */
  644. let north_east = Cesium.Rectangle.northeast(rectangle);
  645. let ne = Cesium.Cartographic.toCartesian(north_east);
  646. /* 计算西北角 */
  647. let north_west = Cesium.Rectangle.northwest(rectangle);
  648. let nw = Cesium.Cartographic.toCartesian(north_west);
  649. /* 经纬度坐标数组 */
  650. let gPoints = [];
  651. gPoints.push({
  652. lng: Cesium.Math.toDegrees(south_west.longitude),
  653. lat: Cesium.Math.toDegrees(south_west.latitude),
  654. height: south_west.height,
  655. });
  656. gPoints.push({
  657. lng: Cesium.Math.toDegrees(south_east.longitude),
  658. lat: Cesium.Math.toDegrees(south_east.latitude),
  659. height: south_east.height,
  660. });
  661. gPoints.push({
  662. lng: Cesium.Math.toDegrees(north_east.longitude),
  663. lat: Cesium.Math.toDegrees(north_east.latitude),
  664. height: north_east.height,
  665. });
  666. gPoints.push({
  667. lng: Cesium.Math.toDegrees(north_west.longitude),
  668. lat: Cesium.Math.toDegrees(north_west.latitude),
  669. height: north_west.height,
  670. });
  671. gPoints.push({
  672. lng: Cesium.Math.toDegrees(south_west.longitude),
  673. lat: Cesium.Math.toDegrees(south_west.latitude),
  674. height: south_west.height,
  675. });
  676. /* 返回坐标串 */
  677. return {
  678. cPoints: [sw, se, ne, nw, sw],
  679. gPoints: gPoints,
  680. };
  681. }
  682. /**
  683. * 矩形外边框轮廓线回调
  684. * @ignore 生成方法时不对外公开
  685. */
  686. _callUpdateRectangleOutlineCoordinates() {
  687. let _self = this;
  688. return function() {
  689. return _self._rectangleOutlineCoordinates;
  690. }
  691. }
  692. /**
  693. * 文字材质
  694. * @ignore 生成方法时不对外公开
  695. * @param {JSON} options 配置项
  696. * @param {String} options.text 文字内容
  697. * @param {String} options.color 文字颜色 rgba(r,g,b,a)
  698. */
  699. _materialTextImageProperty(options) {
  700. this._canvasId = 'canvasJt';
  701. /* 获取画布 */
  702. let canvasObj = document.getElementById(this._canvasId);
  703. /* 如果画布已经存在则删除 */
  704. if (canvasObj != null) {
  705. document.body.removeChild(canvasObj);
  706. }
  707. /* 创建画布 */
  708. canvasObj = document.createElement('canvas');
  709. canvasObj.id = this._canvasId;
  710. /* 设置画布尺寸 */
  711. canvasObj.setAttribute('width', '1024px');
  712. canvasObj.setAttribute('height', '256px');
  713. /* 加入画布 */
  714. document.body.appendChild(canvasObj);
  715. /* 获取上下文绘制 */
  716. let context = canvasObj.getContext('2d');
  717. context.fillStyle = options.color === undefined ? 'rgba(255,0,0,1)' : options.color;
  718. context.font = 'bold 240px 微软雅黑';
  719. context.textAlign = 'left';
  720. context.textBaseline = 'bottom';
  721. context.fillText(options.text, 12, 250, 1000);
  722. /* 创建材质 */
  723. let textMaterial = new Cesium.ImageMaterialProperty({
  724. image: canvasObj,
  725. transparent: true,
  726. });
  727. textMaterial._param = {
  728. color: context.fillStyle,
  729. text: options.text,
  730. }
  731. /* 返回材质 */
  732. return textMaterial;
  733. }
  734. /**
  735. * 颜色材质
  736. * @ignore 生成方法时不对外公开
  737. * @param {JSON} options 配置项
  738. * @param {String} options.color 文字颜色 rgba(r,g,b,a)
  739. */
  740. _materialColorProperty(options) {
  741. let mColor = 'rgba(0,255,0,1)';
  742. if (options !== undefined && options.color !== undefined) mColor = options.color;
  743. /* 创建材质 */
  744. let colorMaterial = new Cesium.ColorMaterialProperty(Cesium.Color.fromCssColorString(mColor));
  745. colorMaterial._param = {
  746. color: mColor,
  747. }
  748. /* 返回材质 */
  749. return colorMaterial;
  750. }
  751. /**
  752. * 箭头线材质
  753. * @ignore 生成方法时不对外公开
  754. * @param {JSON} options 配置项
  755. * @param {String} options.color 线的颜色 rgba(r,g,b,a)
  756. */
  757. _materialPolylineArrowProperty(options) {
  758. let mColor = 'rgba(0,255,0,1)';
  759. if (options !== undefined && options.color !== undefined) mColor = options.color;
  760. /* 创建材质 */
  761. let colorMaterial = new Cesium.PolylineArrowMaterialProperty(Cesium.Color.fromCssColorString(mColor));
  762. colorMaterial._param = {
  763. color: mColor,
  764. }
  765. /* 返回材质 */
  766. return colorMaterial;
  767. }
  768. /**
  769. * 发光线材质
  770. * @ignore 生成方法时不对外公开
  771. * @param {JSON} options 配置项
  772. * @param {String} options.color 线的颜色 rgba(r,g,b,a)
  773. * @param {Number} options.power 发光强度 0~1
  774. */
  775. _materialPolylineGlowProperty(options) {
  776. let mColor = 'rgba(0,255,0,1)';
  777. if (options !== undefined && options.color !== undefined) mColor = options.color;
  778. let power = 0.25;
  779. if (options !== undefined && options.power !== undefined && typeof(options.power) === 'number') power =
  780. options.power;
  781. /* 创建材质 */
  782. let colorMaterial = new Cesium.PolylineGlowMaterialProperty({
  783. color: Cesium.Color.fromCssColorString(mColor),
  784. glowPower: power,
  785. });
  786. colorMaterial._param = {
  787. color: mColor,
  788. power: power,
  789. }
  790. /* 返回材质 */
  791. return colorMaterial;
  792. }
  793. /**
  794. * 描边线材质
  795. * @ignore 生成方法时不对外公开
  796. * @param {JSON} options 配置项
  797. * @param {String} options.color 线的颜色 rgba(r,g,b,a)
  798. * @param {String} options.outlineColor 描边线的颜色 rgba(r,g,b,a)
  799. * @param {Number} options.outlineWidth 描边线的宽度
  800. */
  801. _materialPolylineOutlineProperty(options) {
  802. let mColor = 'rgba(0,255,0,1)';
  803. let outlineColor = 'rgba(255,255,255,1.0)';
  804. let outlineWidth = 1.2;
  805. if (options !== undefined && options.color !== undefined) mColor = options.color;
  806. if (options !== undefined && options.outlineColor !== undefined) outlineColor = options.outlineColor;
  807. if (options !== undefined && options.outlineWidth !== undefined && typeof(options.outlineWidth) ===
  808. 'number')
  809. outlineWidth = options.outlineWidth;
  810. /* 创建材质 */
  811. let colorMaterial = new Cesium.PolylineOutlineMaterialProperty({
  812. color: Cesium.Color.fromCssColorString(mColor),
  813. outlineColor: Cesium.Color.fromCssColorString(outlineColor),
  814. outlineWidth: outlineWidth,
  815. });
  816. colorMaterial._param = {
  817. color: mColor,
  818. outlineColor: outlineColor,
  819. outlineWidth: outlineWidth,
  820. }
  821. /* 返回材质 */
  822. return colorMaterial;
  823. }
  824. /**
  825. * 清理资源
  826. * @ignore 生成方法时不对外公开
  827. * @param {Boolean} isAll 是否删除已经绘制的全部实体
  828. */
  829. _clear(isAll) {
  830. if (isAll != undefined && isAll === true) {
  831. this._removeEntityByName(this._sketchEntityName);
  832. this._removePointEntitys();
  833. }
  834. /* 重置数组变量 */
  835. this._sketchTempPoints = [];
  836. this._sketchPoints = [];
  837. this._sketchOutputPoints = [];
  838. this._sketchWallHeights = [];
  839. /* 重置编辑实体 */
  840. this._drawEntity = undefined;
  841. }
  842. }
  843. /**
  844. * 设置方法
  845. */
  846. Object.assign(DrawTools.prototype, {
  847. /**
  848. * �����������置点击点显示�����标记
  849. * @param {JSNO} options 配置项
  850. * @param {String} options.lineLabel 线点文字标注
  851. * @param {String} options.polygonLabel 面点文字标注
  852. */
  853. setLabel: function(options) {
  854. if (!options) {
  855. options = {
  856. lineLabel: undefined,
  857. polygonLabel: undefined,
  858. }
  859. }
  860. if (options.lineLabel) this._lineLabel = options.lineLabel;
  861. if (options.polygonLabel) this._lineLabel = options.polygonLabel;
  862. }
  863. })
  864. /**
  865. * 事件相关
  866. */
  867. Object.assign(DrawTools.prototype, {
  868. /**
  869. * 注册鼠标左键点击事件
  870. * @ignore 生成方法时不对外公开
  871. * @param {Cesium.ScreenSpaceEventHandler} handler 事件句柄
  872. * @param {Function} callChange 回调callChange(event)
  873. */
  874. _registerLeftClickEvent: function(handler, callChange) {
  875. let _self = this;
  876. if (!handler) return;
  877. handler.setInputAction(function(event) {
  878. /* 锁定点击事件 以免和移动事件冲突 */
  879. _self._lock = true;
  880. clearTimeout(_self._timer);
  881. _self._timer = setTimeout(function() {
  882. if (callChange) callChange(event);
  883. /* 解除锁定 */
  884. _self._lock = false;
  885. }, 200);
  886. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  887. },
  888. /**
  889. * 注册鼠标左键双击事件
  890. * @ignore 生成方法时不对外公开
  891. * @param {Cesium.ScreenSpaceEventHandler} handler 事件句柄
  892. * @param {Function} callChange 回调callChange(event)
  893. */
  894. _registerLeftDoubleClickEvent: function(handler, callChange) {
  895. let _self = this;
  896. if (!handler) return;
  897. handler.setInputAction(function(event) {
  898. clearTimeout(_self._timer);
  899. /* 解除锁定 */
  900. _self._lock = false;
  901. if (callChange) callChange(event);
  902. }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
  903. },
  904. /**
  905. * 注册鼠标移动事件
  906. * @ignore 生成方法时不对外公开
  907. * @param {Cesium.ScreenSpaceEventHandler} handler 事件句柄
  908. * @param {Function} callChange 回调callChange(event)
  909. */
  910. _registerMouseMoveEvent: function(handler, callChange) {
  911. let _self = this;
  912. if (!handler) return;
  913. handler.setInputAction(function(event) {
  914. if (_self._lock === undefined || _self._lock === false) {
  915. if (callChange) callChange(event);
  916. }
  917. }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  918. },
  919. /**
  920. * 注册鼠标右键点击事件
  921. * @ignore 生成方法时不对外公开
  922. * @param {Cesium.ScreenSpaceEventHandler} handler 事件句柄
  923. * @param {Function} callChange ���调callChange(event)
  924. */
  925. _registerRightClickEvent: function(handler, callChange) {
  926. if (!handler) return;
  927. handler.setInputAction(function(event) {
  928. if (callChange) callChange(event);
  929. }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  930. },
  931. /**
  932. * 注册鼠标左键按下事件
  933. * @ignore 生成方法时不对外公开
  934. * @param {Cesium.ScreenSpaceEventHandler} handler 事件句柄
  935. * @param {Function} callChange 回调callChange(event)
  936. */
  937. _registerLeftDownEvent: function(handler, callChange) {
  938. if (!handler) return;
  939. handler.setInputAction(function(event) {
  940. if (callChange) callChange(event);
  941. }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
  942. },
  943. /**
  944. * 注册鼠标左键抬起事件
  945. * @ignore 生成方法时不对外公开
  946. * @param {Cesium.ScreenSpaceEventHandler} handler 事件句柄
  947. * @param {Function} callChange 回调callChange(event)
  948. */
  949. _registerLeftUpEvent: function(handler, callChange) {
  950. if (!handler) return;
  951. handler.setInputAction(function(event) {
  952. if (callChange) callChange(event);
  953. }, Cesium.ScreenSpaceEventType.LEFT_UP);
  954. },
  955. /**
  956. * 清除事件
  957. * @ignore 生成方法时不对外公开
  958. * @param {Cesium.ScreenSpaceEventHandler} handler
  959. */
  960. _clearEvent: function(handler) {
  961. /* 清理事件的同时 彻底清理提示标签 */
  962. this._endTooltip();
  963. if (!handler) return;
  964. /* 干掉事件句柄 释放资源 */
  965. handler.destroy();
  966. handler = null;
  967. },
  968. })
  969. /**
  970. * 绘制的具体实现方法
  971. */
  972. Object.assign(DrawTools.prototype, {
  973. /**
  974. * 创建贴地线
  975. * @ignore 生成方法时不对外公开
  976. * @param {DrawTools.PolylineType} polylineType 线类型
  977. */
  978. _createPolyline: function(polylineType) {
  979. let _self = this;
  980. /* 初始化一个实体参数变量 */
  981. let entityParam = DrawTools.initEditPropertyParams();
  982. let polylineWidth = _self._param.lineWidth;
  983. /* 创建普通线材质 */
  984. let polylineMaterial = this._materialColorProperty({
  985. color: _self._param.lineColor,
  986. });
  987. entityParam.id = DrawTools.DrawType.Polyline;
  988. if (polylineType !== undefined && polylineType === DrawTools.PolylineType.ArrowsPolyline) {
  989. polylineMaterial = this._materialPolylineArrowProperty({
  990. color: _self._param.lineColor,
  991. });
  992. polylineWidth = _self._param.lineWidth * 3;
  993. /* 设置实体参数 */
  994. entityParam.color = _self._param.lineColor;
  995. entityParam.id = DrawTools.DrawType.ArrowPolyline;
  996. } else if (polylineType !== undefined && polylineType === DrawTools.PolylineType.GrowPolyline) {
  997. polylineMaterial = this._materialPolylineGlowProperty({
  998. color: _self._param.lineColor,
  999. power: _self._param.power,
  1000. })
  1001. polylineWidth = _self._param.lineWidth * 3;
  1002. /* 设置实体参数 */
  1003. entityParam.color = _self._param.lineColor;
  1004. entityParam.power = _self._param.power;
  1005. entityParam.id = DrawTools.DrawType.GrowPolyline;
  1006. } else if (polylineType !== undefined && polylineType === DrawTools.PolylineType.OutlinePolyline) {
  1007. polylineMaterial = this._materialPolylineOutlineProperty({
  1008. color: _self._param.lineColor,
  1009. outlineColor: _self._param.outlineColor,
  1010. outlineWidth: _self._param.outlineWidth
  1011. });
  1012. polylineWidth = _self._param.lineWidth * 2;
  1013. /* 设置实体参数 */
  1014. entityParam.color = _self._param.lineColor;
  1015. entityParam.outlineColor = _self._param.outlineColor;
  1016. entityParam.outlineWidth = _self._param.outlineWidth;
  1017. entityParam.id = DrawTools.DrawType.OutlinePolyline;
  1018. } else if (polylineType !== undefined && polylineType === DrawTools.PolylineType.DynamicPolyline) {
  1019. polylineMaterial = new WallMaterialProperty({
  1020. viewer: _self._viewer,
  1021. trailImage: _self._image_h_l_r,
  1022. duration: _self._param.duration,
  1023. color: Cesium.Color.fromCssColorString(_self._param.lineColor),
  1024. param: {
  1025. direction: _self._param.direction_h,
  1026. count: _self._param.count,
  1027. order: _self._param.order_minus,
  1028. },
  1029. });
  1030. polylineWidth = _self._param.lineWidth;
  1031. /* 设置实体参数 */
  1032. entityParam.color = _self._param.lineColor;
  1033. entityParam.duration = _self._param.duration;
  1034. entityParam.direction = _self._param.direction_h;
  1035. entityParam.count = _self._param.count;
  1036. entityParam.order = _self._param.order_minus;
  1037. entityParam.id = DrawTools.DrawType.DynamicPolyline;
  1038. }
  1039. /* 设置实体通用参数 */
  1040. entityParam.lineWidth = polylineWidth;
  1041. /* 创建贴地线 */
  1042. let entityPolyline = new Cesium.Entity({
  1043. name: _self._sketchEntityName,
  1044. polyline: {
  1045. show: true,
  1046. positions: new Cesium.CallbackProperty(function() {
  1047. return _self._sketchTempPoints;
  1048. }, false),
  1049. material: polylineMaterial,
  1050. width: polylineWidth,
  1051. clampToGround: true, //开启贴地 如果有模型则贴模型
  1052. }
  1053. })
  1054. /* 渲染贴地线 */
  1055. this._drawEntity = this._entities.add(entityPolyline);
  1056. /* 挂接参数到实体上 */
  1057. this._drawEntity.setParams(entityParam);
  1058. },
  1059. /**
  1060. * 更新贴地线
  1061. * @ignore 生成方法时不对外公开
  1062. * @param {Boolean} isEdit [是否可编辑] 可选
  1063. */
  1064. _updatePolyline: function(isEdit) {
  1065. /* 更新数据 */
  1066. this._drawEntity.polyline.positions = this._sketchPoints;
  1067. /* 设置实体类型 */
  1068. this._drawEntity.setEntityType(DrawTools.DrawType.Polyline);
  1069. /* 设置是否可编辑 */
  1070. if (isEdit != undefined && isEdit === true) {
  1071. /* 删除所有的临时点 忽略是否保留设置 */
  1072. this._removePointEntitys();
  1073. this._setEntityIsEdit(this._drawEntity);
  1074. }
  1075. },
  1076. /**
  1077. * 创建空间线
  1078. * @ignore 生成方法时不对外公开
  1079. */
  1080. _createSpatialPolyline: function() {
  1081. let _self = this;
  1082. /* 初始化一个实体参数变量 */
  1083. let entityParam = DrawTools.initEditPropertyParams();
  1084. /* 创建空间线材质 */
  1085. let lineMaterial = this._materialColorProperty({
  1086. color: _self._param.lineColor,
  1087. })
  1088. /* 设置实体参数 */
  1089. entityParam.id = DrawTools.DrawType.SpatialLine;
  1090. entityParam.color = _self._param.lineColor;
  1091. entityParam.lineWidth = _self._param.lineWidth;
  1092. /* 创建空间线实体 */
  1093. let entity = new Cesium.Entity({
  1094. name: _self._sketchEntityName,
  1095. polyline: {
  1096. show: true,
  1097. positions: new Cesium.CallbackProperty(function() {
  1098. return _self._sketchTempPoints;
  1099. }, false),
  1100. material: lineMaterial,
  1101. width: _self._param.lineWidth,
  1102. clampToGround: false, //由于是空间线禁止贴地或贴模型
  1103. }
  1104. })
  1105. /* 加入集合 */
  1106. this._drawEntity = this._entities.add(entity);
  1107. /* 挂接实体参数 */
  1108. this._drawEntity.setParams(entityParam);
  1109. },
  1110. /**
  1111. * 更新空间线
  1112. * @ignore 生成方法时不对外公开
  1113. * @param {Boolean} isEdit [是否可编辑] 可选
  1114. */
  1115. _updateSpatialPolyline: function(isEdit) {
  1116. this._drawEntity.polyline.positions = this._sketchPoints;
  1117. this._drawEntity.setEntityType(DrawTools.DrawType.SpatialLine);
  1118. /* 设置是否可编辑 */
  1119. if (isEdit != undefined && isEdit === true) {
  1120. /* 删除所有的临时点 忽略是否保留设置 */
  1121. this._removePointEntitys();
  1122. this._setEntityIsEdit(this._drawEntity);
  1123. }
  1124. },
  1125. /**
  1126. * 绘制面
  1127. * @ignore 生成方法时不对外公开
  1128. * @param {DrawTools.PolygonType} polygonType 面类型
  1129. */
  1130. _createPolygon: function(polygonType) {
  1131. let _self = this;
  1132. /* 初始化一个实体参数变量 */
  1133. let entityParam = DrawTools.initEditPropertyParams();
  1134. /* 创建面材质 */
  1135. let polygonMaterial = this._materialColorProperty({
  1136. color: _self._param.polygonColor,
  1137. })
  1138. /* 创建线材质 */
  1139. let lineMaterial = this._materialColorProperty({
  1140. color: _self._param.outlineColor,
  1141. })
  1142. /* 创建贴地面 */
  1143. let entityPolygon = new Cesium.Entity({
  1144. name: _self._sketchEntityName,
  1145. polygon: {
  1146. show: true,
  1147. hierarchy: new Cesium.CallbackProperty(function() {
  1148. return {
  1149. positions: _self._sketchTempPoints,
  1150. };
  1151. }, false),
  1152. material: polygonMaterial,
  1153. classificationType: Cesium.ClassificationType.BOTH,
  1154. },
  1155. polyline: {
  1156. show: true,
  1157. positions: new Cesium.CallbackProperty(function() {
  1158. return _self._sketchTempPoints;
  1159. }, false),
  1160. material: lineMaterial,
  1161. width: _self._param.outlineWidth,
  1162. clampToGround: true, //开启贴地 如果有模型则贴模型
  1163. }
  1164. })
  1165. /* 设置实体参数 */
  1166. entityParam.color = _self._param.polygonColor;
  1167. entityParam.outlineColor = _self._param.outlineColor;
  1168. entityParam.outlineWidth = _self._param.outlineWidth;
  1169. /* 渲染贴地面 */
  1170. this._drawEntity = this._entities.add(entityPolygon);
  1171. if (polygonType === undefined || polygonType === DrawTools.PolygonType.NormalPolygon) {
  1172. this._drawEntity.setEntityType(DrawTools.DrawType.Polygon);
  1173. entityParam.id = DrawTools.DrawType.Polygon;
  1174. } else if (polygonType != undefined && polygonType === DrawTools.PolygonType.HousePolygon) {
  1175. this._drawEntity.setEntityType(DrawTools.DrawType.House);
  1176. entityParam.id = DrawTools.DrawType.HousePolygon;
  1177. }
  1178. /* 设置实体参数 */
  1179. this._drawEntity.setParams(entityParam);
  1180. },
  1181. /**
  1182. * 创建正式面
  1183. * @ignore 生成方法时不对外公开
  1184. * @param {Boolean} isEdit [是否可编辑] 可选
  1185. */
  1186. _updatePolygon: function(isEdit) {
  1187. let _self = this;
  1188. /* 创建房屋材质 */
  1189. let houseMaterial = this._materialColorProperty({
  1190. color: _self._param.houseColor,
  1191. })
  1192. /* 获取实体类型 */
  1193. let entityType = this._drawEntity.getEntityType();
  1194. if (entityType === DrawTools.DrawType.Polygon) {
  1195. /* 更新数据 */
  1196. this._drawEntity.polygon.hierarchy = {
  1197. positions: _self._sketchPoints,
  1198. };
  1199. this._drawEntity.polyline.positions = this._sketchPoints;
  1200. } else if (entityType === DrawTools.DrawType.House) {
  1201. /* 删除原来创建的实体 */
  1202. this._removeEntityByObject(this._drawEntity);
  1203. /* 创建房屋的高度 */
  1204. let height = parseFloat(this._sketchOutputPoints[0].height);
  1205. let houseHeight = height + parseInt(_self._param.wallHeight);
  1206. /* 创建一个房屋实体 */
  1207. let houseEntity = new Cesium.Entity({
  1208. name: _self._sketchEntityName,
  1209. polygon: {
  1210. show: true,
  1211. hierarchy: {
  1212. positions: _self._sketchPoints,
  1213. },
  1214. extrudedHeight: houseHeight,
  1215. material: houseMaterial,
  1216. },
  1217. })
  1218. /* 渲染实体 */
  1219. this._drawEntity = this._entities.add(houseEntity);
  1220. /* 设置实体类型 */
  1221. this._drawEntity.setEntityType(entityType);
  1222. /* 房屋附加属性 */
  1223. let entityParam = this._drawEntity.getParams();
  1224. entityParam.height = _self._param.wallHeight;
  1225. entityParam.bottomHeight = height;
  1226. entityParam.color = _self._param.houseColor;
  1227. this._drawEntity.setParams(entityParam);
  1228. }
  1229. /* 设置是否可编辑 */
  1230. if (isEdit != undefined && isEdit === true) {
  1231. /* 删除所有的临时点 忽略是否保留设置 */
  1232. this._removePointEntitys();
  1233. this._setEntityIsEdit(this._drawEntity);
  1234. }
  1235. },
  1236. /**
  1237. * 创建矩形
  1238. * @ignore 生成方法时不对外公开
  1239. */
  1240. _createRectangle: function() {
  1241. let _self = this;
  1242. /* 初始化一个实体参数变量 */
  1243. let entityParam = DrawTools.initEditPropertyParams();
  1244. /* 创建面材质 */
  1245. let rectMaterial = this._materialColorProperty({
  1246. color: _self._param.polygonColor,
  1247. });
  1248. /* 创建线材质 */
  1249. let lineMaterial = this._materialColorProperty({
  1250. color: _self._param.outlineColor,
  1251. })
  1252. /* 创建贴地矩形 */
  1253. let entityRectangle = new Cesium.Entity({
  1254. name: _self._sketchEntityName,
  1255. polyline: {
  1256. show: true,
  1257. positions: new Cesium.CallbackProperty(_self
  1258. ._callUpdateRectangleOutlineCoordinates(),
  1259. false),
  1260. material: lineMaterial,
  1261. width: _self._param.outlineWidth,
  1262. clampToGround: true, //开启贴地 如果有模型则贴模型
  1263. },
  1264. rectangle: {
  1265. show: true,
  1266. coordinates: new Cesium.CallbackProperty(_self._callUpdateRectangleCoordinates(
  1267. _self
  1268. ._sketchTempPoints),
  1269. false),
  1270. material: rectMaterial,
  1271. classificationType: Cesium.ClassificationType.BOTH,
  1272. },
  1273. });
  1274. /* 设置实体属性 */
  1275. entityParam.id = DrawTools.DrawType.Rectangle;
  1276. entityParam.color = _self._param.polygonColor;
  1277. entityParam.outlineColor = _self._param.outlineColor;
  1278. entityParam.outlineWidth = _self._param.outlineWidth;
  1279. /* 贴地矩形渲染 */
  1280. this._drawEntity = this._entities.add(entityRectangle);
  1281. /* 挂接实体属性 */
  1282. this._drawEntity.setParams(entityParam);
  1283. },
  1284. /**
  1285. * 更新矩形
  1286. * @ignore 生成方法时不对外公开
  1287. * @param {Boolean} isEdit [是否可编辑] 可选
  1288. */
  1289. _updateRectangle(isEdit) {
  1290. let _self = this;
  1291. /* 更新贴地矩形数据 */
  1292. this._drawEntity.polyline.positions = this._rectangleOutlineCoordinates;
  1293. let coordinates = this._rectangleCoordinates;
  1294. this._drawEntity.rectangle.coordinates = Cesium.Rectangle.fromDegrees(coordinates[0], coordinates[
  1295. 1], coordinates[2], coordinates[3]);
  1296. /* 设置实体类型 */
  1297. this._drawEntity.setEntityType(DrawTools.DrawType.Rectangle);
  1298. /* 设置是否可编辑 */
  1299. if (isEdit != undefined && isEdit === true) {
  1300. this._setEntityIsEdit(this._drawEntity);
  1301. }
  1302. },
  1303. /**
  1304. * 创建贴地圆
  1305. * @ignore 生成方法时不对外公开
  1306. * @param {Cesium.Cartesian3} centerPosition 圆的中心点位置
  1307. */
  1308. _createCircle: function(centerPosition, circleType) {
  1309. let _self = this;
  1310. /* 初始化一个实体参数变量 */
  1311. let entityParam = DrawTools.initEditPropertyParams();
  1312. /* 创建颜色材质 */
  1313. let circleMaterial = this._materialColorProperty({
  1314. color: _self._param.polygonColor,
  1315. });
  1316. /* 创建线材质 */
  1317. let lineMaterial = this._materialColorProperty({
  1318. color: _self._param.outlineColor,
  1319. })
  1320. /* 如果是动态圆 创建动态圆材质 */
  1321. if (circleType != undefined && circleType === DrawTools.CircleType.DynamicCircle) {
  1322. circleMaterial = new CircleMaterialProperty({
  1323. viewer: _self._viewer,
  1324. duration: _self._param.duration,
  1325. color: Cesium.Color.fromCssColorString(_self._param.polygonColor),
  1326. count: _self._param.count,
  1327. });
  1328. }
  1329. /* 存储椭圆中心点位置 */
  1330. this._sketchEllipseCenterPosition = centerPosition.clone();
  1331. /* 创建贴地圆 */
  1332. let entityCircle = new Cesium.Entity({
  1333. name: _self._sketchEntityName,
  1334. position: centerPosition,
  1335. ellipse: {
  1336. show: true,
  1337. semiMinorAxis: new Cesium.CallbackProperty(_self._callUpdateEllipseMinorAxis(
  1338. _self
  1339. ._sketchTempPoints), false),
  1340. semiMajorAxis: new Cesium.CallbackProperty(_self._callUpdateEllipseMinorAxis(
  1341. _self
  1342. ._sketchTempPoints), false),
  1343. material: circleMaterial,
  1344. classificationType: Cesium.ClassificationType.BOTH,
  1345. },
  1346. });
  1347. if (circleType === undefined || circleType === DrawTools.CircleType.ColorCircle) {
  1348. entityCircle.polyline = {
  1349. show: true,
  1350. positions: new Cesium.CallbackProperty(_self._callEllipseOutlineCoordinate(
  1351. _self._sketchTempPoints), false),
  1352. material: lineMaterial,
  1353. width: _self._param.outlineWidth,
  1354. clampToGround: true, //开启贴地 如果有模型则贴模型
  1355. };
  1356. }
  1357. /* 渲染贴地圆 */
  1358. this._drawEntity = this._entities.add(entityCircle);
  1359. /* 设置实体类型 */
  1360. if (circleType === undefined || circleType === DrawTools.CircleType.ColorCircle) {
  1361. this._drawEntity.setEntityType(DrawTools.DrawType.Circle);
  1362. /* 设置实体属性 */
  1363. entityParam.id = DrawTools.DrawType.Circle;
  1364. entityParam.color = _self._param.polygonColor;
  1365. entityParam.outlineColor = _self._param.outlineColor;
  1366. entityParam.outlineWidth = _self._param.outlineWidth;
  1367. } else if (circleType != undefined && circleType === DrawTools.CircleType.DynamicCircle) {
  1368. this._drawEntity.setEntityType(DrawTools.DrawType.DynamicCircle);
  1369. /* 设置实体属性 */
  1370. entityParam.id = DrawTools.DrawType.DynamicCircle;
  1371. entityParam.color = _self._param.polygonColor;
  1372. entityParam.duration = _self._param.duration;
  1373. entityParam.count = _self._param.count;
  1374. }
  1375. /* 挂接实体属性 */
  1376. this._drawEntity.setParams(entityParam);
  1377. },
  1378. /**
  1379. * 更新贴地圆
  1380. * @ignore 生成方法时不对外公开
  1381. * @param {Boolean} isEdit [是否可编辑] 可选
  1382. */
  1383. _updateCircle(isEdit) {
  1384. let _self = this;
  1385. /* 更新贴地圆数据 */
  1386. this._drawEntity.position = this._sketchEllipseCenterPosition;
  1387. if (this._drawEntity.polyline != undefined) {
  1388. this._drawEntity.polyline.positions = this._ellipseOutlineCoordinates;
  1389. }
  1390. this._drawEntity.ellipse.semiMajorAxis = this._sketchEllipseRadius;
  1391. this._drawEntity.ellipse.semiMinorAxis = this._sketchEllipseRadius;
  1392. /* 设置是否可编辑 */
  1393. if (isEdit != undefined && isEdit === true) {
  1394. this._setEntityIsEdit(this._drawEntity);
  1395. }
  1396. },
  1397. /**
  1398. * 绘制墙
  1399. * @ignore 生成方法时不对外公开
  1400. * @param {DrawTools.WallType} wallType 墙的类型
  1401. */
  1402. _createWall: function(wallType) {
  1403. let _self = this;
  1404. /* 初始化一个实体参数变量 */
  1405. let entityParam = DrawTools.initEditPropertyParams();
  1406. /* 颜色墙材质 */
  1407. let wallMaterial = this._materialColorProperty({
  1408. color: _self._param.polygonColor,
  1409. });
  1410. /* 设置实体属性 */
  1411. entityParam.color = _self._param.polygonColor;
  1412. if (wallType !== undefined && wallType === DrawTools.WallType.TextWall) {
  1413. wallMaterial = this._materialTextImageProperty({
  1414. color: _self._param.polygonColor,
  1415. text: _self._param.text,
  1416. });
  1417. /* 设置实体属性 */
  1418. entityParam.text = _self._param.text;
  1419. entityParam.color = _self._param.polygonColor;
  1420. } else if (wallType !== undefined && wallType === DrawTools.WallType.DynamicWall) {
  1421. /* 动态墙材质 */
  1422. wallMaterial = new WallMaterialProperty({
  1423. viewer: _self._viewer,
  1424. trailImage: _self._image_v_t_b,
  1425. duration: _self._param.duration,
  1426. color: Cesium.Color.fromCssColorString(_self._param.polygonColor),
  1427. param: {
  1428. count: _self._param.count,
  1429. direction: _self._param.direction_v,
  1430. order: _self._param.order_minus
  1431. }
  1432. });
  1433. /* 设置实体属性 */
  1434. entityParam.color = _self._param.polygonColor;
  1435. entityParam.duration = _self._param.duration;
  1436. entityParam.direction = _self._param.direction_v;
  1437. entityParam.count = _self._param.count;
  1438. entityParam.order = _self._param.order_minus;
  1439. }
  1440. /* 创建墙 */
  1441. let normalWall = new Cesium.Entity({
  1442. name: _self._sketchEntityName,
  1443. wall: {
  1444. show: true,
  1445. positions: new Cesium.CallbackProperty(function() {
  1446. return _self._sketchTempPoints;
  1447. }, false),
  1448. minimumHeights: new Cesium.CallbackProperty(function() {
  1449. return _self._sketchWallHeights;
  1450. }, false),
  1451. maximumHeights: new Cesium.CallbackProperty(function() {
  1452. _self._sketchWallMaxHeights = [];
  1453. for (let i = 0; i < _self._sketchWallHeights.length; i++) {
  1454. _self._sketchWallMaxHeights.push(_self._sketchWallHeights[i] + _self
  1455. ._param.wallHeight);
  1456. }
  1457. return _self._sketchWallMaxHeights;
  1458. }, false),
  1459. material: wallMaterial,
  1460. }
  1461. });
  1462. /* 渲染墙 */
  1463. this._drawEntity = this._entities.add(normalWall);
  1464. /* 设置实体通用属性 */
  1465. entityParam.height = this._param.wallHeight;
  1466. /* 设置实体类型 */
  1467. if (wallType === undefined || wallType === DrawTools.WallType.ColorWall) {
  1468. this._drawEntity.setEntityType(DrawTools.DrawType.NormalWall);
  1469. /* 设置实体属性 */
  1470. entityParam.id = DrawTools.DrawType.NormalWall;
  1471. } else if (wallType !== undefined && wallType === DrawTools.WallType.DynamicWall) {
  1472. this._drawEntity.setEntityType(DrawTools.DrawType.DynamicWall);
  1473. /* 设置实体属性 */
  1474. entityParam.id = DrawTools.DrawType.DynamicWall;
  1475. } else if (wallType !== undefined && wallType === DrawTools.WallType.TextWall) {
  1476. this._drawEntity.setEntityType(DrawTools.DrawType.TextWall);
  1477. /* 设置实体属性 */
  1478. entityParam.id = DrawTools.DrawType.TextWall;
  1479. }
  1480. /* 挂接实体属性 */
  1481. this._drawEntity.setParams(entityParam);
  1482. },
  1483. /**
  1484. * 更新墙
  1485. * @ignore 生成方法时不对外公开
  1486. * @param {Boolean} isEdit [是否可编辑]可选
  1487. */
  1488. _updateWall: function(isEdit) {
  1489. /* 获取三个数组的长度 */
  1490. let hLength = this._sketchWallHeights.length;
  1491. let mhLength = this._sketchWallMaxHeights.length;
  1492. let pLength = this._sketchPoints.length;
  1493. if (hLength === mhLength && hLength - pLength === 1) {
  1494. /* 移除最后一个高度点 */
  1495. this._sketchWallHeights.pop();
  1496. this._sketchWallMaxHeights.pop();
  1497. /* 设置并停止墙的动态属性 */
  1498. this._drawEntity.wall.positions = this._sketchPoints;
  1499. this._drawEntity.wall.minimumHeights = this._sketchWallHeights;
  1500. this._drawEntity.wall.maximumHeights = this._sketchWallMaxHeights;
  1501. /* 设置是否可编辑 */
  1502. if (isEdit != undefined && isEdit === true) {
  1503. /* 删除所有的临时点 忽略是否保留设置 */
  1504. this._removePointEntitys();
  1505. this._setEntityIsEdit(this._drawEntity);
  1506. }
  1507. } else {
  1508. this._console(hLength, mhLength, pLength);
  1509. }
  1510. },
  1511. /**
  1512. * 创建视频墙
  1513. * @ignore 生成方法时不对外公开
  1514. */
  1515. _createVideoWall: function() {
  1516. let _self = this;
  1517. /* 绘制面 干掉事件 */
  1518. let entityWall = new Cesium.Entity({
  1519. name: _self._sketchEntityName,
  1520. position: _self._sketchOutputPoints[0],
  1521. wall: {
  1522. show: true,
  1523. positions: new Cesium.CallbackProperty(function() {
  1524. let pt0 = _self._sketchOutputPoints[0];
  1525. let pt1 = _self._sketchOutputPoints[1];
  1526. /* 视频墙的位置集合 */
  1527. _self._wallPositions = [];
  1528. _self._wallPositions.push(Cesium.Cartesian3.fromDegrees(pt0.lng, pt0
  1529. .lat,
  1530. pt0.height));
  1531. _self._wallPositions.push(Cesium.Cartesian3.fromDegrees(pt1.lng, pt1
  1532. .lat,
  1533. pt0.height));
  1534. return _self._wallPositions;
  1535. }, false),
  1536. maximumHeights: new Cesium.CallbackProperty(function() {
  1537. _self._sketchWallHeights = [];
  1538. let pt = _self._sketchOutputPoints[0];
  1539. _self._sketchWallHeights.push(pt.height);
  1540. _self._sketchWallHeights.push(pt.height);
  1541. return _self._sketchWallHeights;
  1542. }, false),
  1543. minimumHeights: new Cesium.CallbackProperty(function() {
  1544. _self._sketchWallMaxHeights = [];
  1545. let pt = _self._sketchOutputPoints[1];
  1546. _self._sketchWallMaxHeights.push(pt.height);
  1547. _self._sketchWallMaxHeights.push(pt.height);
  1548. return _self._sketchWallMaxHeights;
  1549. }, false),
  1550. material: Cesium.Color.fromCssColorString(_self._param.polygonColor),
  1551. outline: true,
  1552. outlineColor: Cesium.Color.fromCssColorString(_self._param.outlineColor),
  1553. outlineWidth: _self._param.outlineWidth * 10,
  1554. }
  1555. });
  1556. /* 渲染视频墙 */
  1557. _self._drawEntity = _self._entities.add(entityWall);
  1558. },
  1559. /**
  1560. * 更新视频墙
  1561. * @ignore 生成方法时不对外公开
  1562. */
  1563. _updateVideoWall: function(isEdit) {
  1564. /* 初始化一个实体参数变量 */
  1565. let entityParam = DrawTools.initEditPropertyParams();
  1566. entityParam.id = DrawTools.DrawType.VideoWall;
  1567. /* 查找视频画布 */
  1568. let videoElement = document.getElementById('wallVideo');
  1569. if (videoElement !== null) {
  1570. document.body.removeChild(videoElement);
  1571. }
  1572. videoElement = document.createElement("video");
  1573. videoElement.id = 'wallVideo';
  1574. videoElement.setAttribute('crossorigin', 'anonymous'); //必须设置 为了防止跨域调用网络视频导致播放失败
  1575. videoElement.setAttribute("width", "1024px");
  1576. videoElement.setAttribute("height", "256px");
  1577. videoElement.setAttribute("controls", "controls");
  1578. videoElement.setAttribute("src",
  1579. "https://lf3-cdn-tos.bytescm.com/obj/eden-cn/lmeh7pfuho/campus/campus_intro_20200522.mp4");
  1580. videoElement.setAttribute("loop", "loop");
  1581. videoElement.play();
  1582. document.body.appendChild(videoElement);
  1583. /* 更新数据 */
  1584. this._drawEntity.wall.positions = this._wallPositions;
  1585. this._drawEntity.wall.minimumHeights = this._sketchWallHeights;
  1586. this._drawEntity.wall.maximumHeights = this._sketchWallMaxHeights;
  1587. /* 设置高度参数 */
  1588. entityParam.height = this._sketchWallMaxHeights[0] - this._sketchWallHeights[0];
  1589. this._drawEntity.wall.material = videoElement;
  1590. /* 删除点 */
  1591. this._removePointEntitys();
  1592. /* 设置实体类型 */
  1593. this._drawEntity.setEntityType(DrawTools.DrawType.VideoWall);
  1594. entityParam.videoUrl =
  1595. 'https://lf3-cdn-tos.bytescm.com/obj/eden-cn/lmeh7pfuho/campus/campus_intro_20200522.mp4';
  1596. entityParam.id = DrawTools.DrawType.VideoWall;
  1597. /* 挂接实体属性 */
  1598. this._drawEntity.setParams(entityParam);
  1599. /* 设置是否可编辑 */
  1600. if (isEdit != undefined && isEdit === true) {
  1601. this._setEntityIsEdit(this._drawEntity);
  1602. }
  1603. },
  1604. /**
  1605. * 计算OD线的中间点
  1606. * @ignore 生成方法时不对外公开
  1607. * @param {Cesium.Cartesian3} strPoint 起始点
  1608. * @param {Cesium.Cartesian3} endPoint 终止点
  1609. * @param {Number} height 最大高度
  1610. * @param {Number} count 内插点数
  1611. */
  1612. _calculateOdlinePositios: function(strPoint, endPoint, height, count) {
  1613. let pt1 = this._cartesian3ToGeo(strPoint);
  1614. let pt2 = this._cartesian3ToGeo(endPoint);
  1615. //方程 y=-(4h/L^2)*x^2+h h:顶点高度 L:横纵间距较大者
  1616. var h = height && height < 1000 ? height : 1000;
  1617. var L = Math.abs(pt1.longitude - pt2.longitude) > Math.abs(pt1.latitude - pt2.latitude) ?
  1618. Math.abs(pt1.longitude - pt2.longitude) : Math.abs(pt1.latitude - pt2.latitude);
  1619. var num = count && count > 50 ? count : 50;
  1620. var result = [];
  1621. var tempResult = []; //临时数组
  1622. var dlt = L / num;
  1623. var addHeight = pt1.height > pt2.height ? pt1.height : pt2.height;
  1624. var maxHeight = addHeight + h;
  1625. var minHeight1 = pt1.height;
  1626. var minHeight2 = pt2.height;
  1627. if (Math.abs(pt1.longitude - pt2.longitude) > Math.abs(pt1.latitude - pt2
  1628. .latitude)) { //以lon为基准
  1629. var delLat = (pt2.latitude - pt1.latitude) / num;
  1630. if (pt1.longitude - pt2.longitude > 0) {
  1631. dlt = -dlt;
  1632. }
  1633. for (var i = 1; i < num; i++) {
  1634. var tempH = h - Math.pow((-0.5 * L + Math.abs(dlt) * i), 2) * 4 * h / Math.pow(L, 2);
  1635. var lon = pt1.longitude + dlt * i;
  1636. var lat = pt1.latitude + delLat * i;
  1637. var alt = undefined;
  1638. if (Math.abs(dlt) * i == 0.5 * L) {
  1639. alt = maxHeight;
  1640. } else if (Math.abs(dlt) * i < 0.5 * L) {
  1641. //说明是抛物线左侧
  1642. alt = ((maxHeight - minHeight1) / h) * tempH + minHeight1;
  1643. } else {
  1644. //说明是抛物线右侧
  1645. alt = ((maxHeight - minHeight2) / h) * tempH + minHeight2;
  1646. }
  1647. tempResult.push([lon, lat, alt]);
  1648. }
  1649. } else { //以lat为基准
  1650. var delLon = (pt2.longitude - pt1.longitude) / num;
  1651. if (pt1.latitude - pt2.latitude > 0) {
  1652. dlt = -dlt;
  1653. }
  1654. for (var i = 1; i < num; i++) {
  1655. var tempH = h - Math.pow((-0.5 * L + Math.abs(dlt) * i), 2) * 4 * h / Math.pow(L, 2);
  1656. var lon = pt1.longitude + delLon * i;
  1657. var lat = pt1.latitude + dlt * i;
  1658. var alt = undefined;
  1659. if (Math.abs(dlt) * i == 0.5 * L) {
  1660. alt = maxHeight;
  1661. } else if (Math.abs(dlt) * i < 0.5 * L) {
  1662. //说明是抛物线左侧
  1663. alt = ((maxHeight - minHeight1) / h) * tempH + minHeight1;
  1664. } else {
  1665. //说明是抛物线右侧
  1666. alt = ((maxHeight - minHeight2) / h) * tempH + minHeight2;
  1667. }
  1668. tempResult.push([lon, lat, alt]);
  1669. }
  1670. }
  1671. /* 对结果进行处理 */
  1672. result.push([pt1.longitude, pt1.latitude, pt1.height]);
  1673. for (var i = 0; i < tempResult.length; i++) {
  1674. result.push(tempResult[i]);
  1675. }
  1676. result.push([pt2.longitude, pt2.latitude, pt2.height]);
  1677. /* 对结果进行转换 */
  1678. let results = [];
  1679. for (let i = 0; i < result.length; i++) {
  1680. results.push(Cesium.Cartesian3.fromDegrees(result[i][0], result[i][1], result[i][2]));
  1681. }
  1682. return results;
  1683. },
  1684. /**
  1685. * 创建OD线
  1686. * @ignore 生成方法时不对外公开
  1687. * @param {Boolean} isFirst 是否第一次
  1688. */
  1689. _createOdline: function(isFirst) {
  1690. let _self = this;
  1691. /* 如果初次创建 创建一个父实体*/
  1692. if (isFirst !== undefined && isFirst === true) {
  1693. let fatherEntity = new Cesium.Entity({
  1694. name: this._sketchEntityName,
  1695. });
  1696. this._odlineFatherEntity = this._entities.add(fatherEntity);
  1697. /* 初始化一个实体参数变量 */
  1698. let entityParam = DrawTools.initEditPropertyParams();
  1699. entityParam.id = DrawTools.DrawType.OdLine;
  1700. entityParam.color = _self._param.polygonColor;
  1701. entityParam.duration = _self._param.duration;
  1702. entityParam.direction = _self._param.direction_h;
  1703. entityParam.count = _self._param.count;
  1704. entityParam.order = _self._param.order_add;
  1705. entityParam.odlineHeight = _self._param.odlineHeight;
  1706. entityParam.odlineCount = _self._param.odlineCount;
  1707. entityParam.lineWidth = _self._param.lineWidth * 3;
  1708. /* 为父实体设置参数 保存该OD线集合的必要参数 */
  1709. this._odlineFatherEntity.setParams(entityParam);
  1710. /* 创建一个临时集合 方便回退删除 */
  1711. this._odlineEntitys = [];
  1712. }
  1713. /* 从父节点获取必要参数 */
  1714. let faterParam = this._odlineFatherEntity.getParams();
  1715. /* 创建OD线材质 */
  1716. let odLineMaterial = new WallMaterialProperty({
  1717. viewer: _self._viewer,
  1718. trailImage: _self._image_arrow_reverse,
  1719. duration: faterParam.duration,
  1720. color: Cesium.Color.fromCssColorString(faterParam.color),
  1721. param: {
  1722. direction: faterParam.direction,
  1723. count: faterParam.count,
  1724. order: faterParam.order,
  1725. },
  1726. });
  1727. /* 创建OD线 */
  1728. let entity = new Cesium.Entity({
  1729. name: _self._sketchEntityName,
  1730. parent: this._odlineFatherEntity,
  1731. polyline: {
  1732. show: true,
  1733. positions: new Cesium.CallbackProperty(function() {
  1734. let center = _self._sketchTempPoints[0];
  1735. let endPoint = _self._sketchTempPoints[_self._sketchTempPoints.length -
  1736. 1];
  1737. let results = _self._calculateOdlinePositios(center, endPoint, parseInt(
  1738. faterParam.odlineHeight),
  1739. parseInt(faterParam.odlineCount));
  1740. return results;
  1741. }, false),
  1742. material: odLineMaterial,
  1743. width: faterParam.lineWidth,
  1744. clampToGround: false, //由于是空间线禁止贴地或贴模型
  1745. }
  1746. })
  1747. /* 加入集合 */
  1748. this._drawEntity = this._entities.add(entity);
  1749. },
  1750. /**
  1751. * 更新OD线
  1752. * @ignore 生成方法时不对外公开
  1753. * @param {Boolean} isLast 是否是最后一个
  1754. * @param {Boolean} isEdit 是否为可编辑
  1755. */
  1756. _updateOdline: function(isLast, isEdit) {
  1757. if (isLast !== undefined && isLast === true) {
  1758. if (isEdit !== undefined && isEdit === true) {
  1759. this._drawEntity.setEntityType(DrawTools.DrawType.OdLine);
  1760. this._setEntityIsEdit(this._drawEntity);
  1761. this._drawEntity.parent.setIsEdit(true);
  1762. }
  1763. } else {
  1764. let params = this._drawEntity.parent.getParams();
  1765. let center = this._sketchTempPoints[0];
  1766. let endPoint = this._sketchTempPoints[this._sketchTempPoints.length -
  1767. 1];
  1768. let results = this._calculateOdlinePositios(center, endPoint, parseInt(params.odlineHeight),
  1769. parseInt(params.odlineCount));
  1770. this._drawEntity.polyline.positions = results;
  1771. this._drawEntity.setEntityType(DrawTools.DrawType.OdLine);
  1772. this._odlineEntitys.push(this._drawEntity);
  1773. if (isEdit !== undefined && isEdit === true) {
  1774. this._drawEntity.setIsEdit(true);
  1775. }
  1776. }
  1777. },
  1778. /**
  1779. * 生成GUID随机数
  1780. * @ignore 生成方法时不对外公开
  1781. */
  1782. _guid() {
  1783. function S4() {
  1784. return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
  1785. }
  1786. return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
  1787. },
  1788. /**
  1789. * 输出消息
  1790. * @ignore 生成方法时不对外公开
  1791. * @param {Object} res
  1792. */
  1793. _console(...rest) {
  1794. console.log('===>>>', rest);
  1795. }
  1796. })
  1797. /**
  1798. * 对外方法
  1799. */
  1800. Object.assign(DrawTools.prototype, {
  1801. /**
  1802. * 鼠标双击结束提示事件
  1803. * @param {Cesium.Cartesian2} position 位置
  1804. */
  1805. _drawMovingDoubleTooltip(position) {
  1806. this._updateTooltip('左键单击绘制,右键单击撤销<br>左键双击结束绘制', position);
  1807. },
  1808. /**
  1809. * 鼠标单击结束提示事件
  1810. * @param {Cesium.Cartesian2} position 位置
  1811. */
  1812. _drawMovingSimpleTooltip(position) {
  1813. this._updateTooltip('左键单击结束绘制', position);
  1814. },
  1815. /**
  1816. * 移除最后绘制的一个点元素
  1817. */
  1818. _removeLastDrawPointEntity() {
  1819. let lastPointEntity = this._pointEntitys.last();
  1820. if (lastPointEntity !== undefined) {
  1821. this._removeEntityByObject(lastPointEntity);
  1822. this._pointEntitys.pop();
  1823. }
  1824. },
  1825. /**
  1826. * 绘制点工具
  1827. * @ignore 生成方法时不对外公开
  1828. * @param {Object} handler 事件句柄
  1829. * @param {JSON} options 配置项
  1830. * @param {Function} [options.onComplete(cPoint, gPoint)] 完成回调 可选
  1831. * @param {Function} [options.onError(message)] 错误回到 可选
  1832. */
  1833. _sketchDrawPoint(handler, options) {
  1834. let _self = this;
  1835. /* 注册鼠标左键点击事件 */
  1836. this._registerLeftClickEvent(handler, function(event) {
  1837. /* 识别屏幕位置 */
  1838. // let loc = _self._transfromFromScreenPoint(event.position);
  1839. // if (!Cesium.defined(loc.sLocation)) return;
  1840. let scene = _self._viewer.scene;
  1841. if (scene.mode !== Cesium.SceneMode.MORPHING) {
  1842. var pickedObject = scene.pick(event.position);
  1843. if (scene.pickPositionSupported && Cesium.defined(pickedObject)) {
  1844. var cartesian = scene.pickPosition(event.position);
  1845. if (Cesium.defined(cartesian)) {
  1846. var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
  1847. var lng = Cesium.Math.toDegrees(cartographic.longitude);
  1848. var lat = Cesium.Math.toDegrees(cartographic.latitude);
  1849. var height = cartographic.height; //模型高度
  1850. _self._sketchOutputPoints.push({
  1851. lng: lng,
  1852. lat: lat,
  1853. height: height
  1854. })
  1855. }
  1856. _self._createPoint(cartesian, '点');
  1857. _self._sketchPoints.push(cartesian.clone());
  1858. if (_self._sketchPoints.length >= 2) {
  1859. _self._createVideoWall();
  1860. /* 干掉事件句柄 释放资源 */
  1861. _self._clearEvent(handler);
  1862. }
  1863. }
  1864. }
  1865. /* 监听输出 */
  1866. if (options.onComplete) options.onComplete(loc.sLocation, loc.gLocation);
  1867. })
  1868. },
  1869. /**
  1870. * 绘制多点
  1871. * @ignore 生成方法时不对外公开
  1872. * @param {Object} handler 事件句柄
  1873. * @param {JSON} options 配置项
  1874. * @param {Function} [options.onAdded(cPoinit,gPoint)] 添加回调 可选
  1875. * @param {Function} [options.onUndo()] 撤销回调 可选
  1876. * @param {Function} [options.onComplete(cPoints,gPoints)] 完成回调 可选
  1877. * @param {Function} [options.onError(message)] 错误回调 可选
  1878. */
  1879. _sketchDrawMultiplePoint(handler, options) {
  1880. let _self = this;
  1881. /* 注册鼠标左键点击事件 */
  1882. this._registerLeftClickEvent(handler, function(event) {
  1883. /* 识别屏幕位置 */
  1884. let loc = _self._transfromFromScreenPoint(event.position);
  1885. if (!Cesium.defined(loc.sLocation)) return;
  1886. /* 绘制点 */
  1887. if (_self._isDrawPoint) {
  1888. _self._createPoint(loc.sLocation, _self._lineLabel);
  1889. }
  1890. _self._sketchPoints.push(loc.sLocation);
  1891. _self._sketchOutputPoints.push(loc.gLocation);
  1892. /* 监听输出 */
  1893. if (options.onAdded) options.onAdded(loc.sLocation, loc.gLocation);
  1894. })
  1895. /* 注册鼠标右键事件 */
  1896. this._registerRightClickEvent(handler, function(event) {
  1897. if (_self._sketchPoints.length > 0) {
  1898. _self._sketchPoints.pop();
  1899. _self._sketchOutputPoints.pop();
  1900. if (options.onUndo) options.onUndo();
  1901. }
  1902. })
  1903. /* 注册鼠标左键双击事件 */
  1904. this._registerLeftDoubleClickEvent(handler, function(event) {
  1905. /* 干掉事件句柄 释放资源 */
  1906. _self._clearEvent(handler);
  1907. /* 回调 */
  1908. if (options.onComplete) options.onComplete(_self._sketchPoints, _self._sketchOutputPoints);
  1909. })
  1910. },
  1911. /**
  1912. * 绘制贴地线
  1913. * @ignore 生成方法时不对外公开
  1914. * @param {Object} handler 事件句柄
  1915. * @param {JSON} options 配置项
  1916. * @param {Boolean} isEdit 是否可编辑 可选 默认可编辑
  1917. * @param {DrawTools.PolylineType} options.polylineType 线的类型 可选
  1918. * @param {Function} [options.onAdded(cPoints,gPoints)] 添加回调 可选
  1919. * @param {Function} [options.onMoving(cPoint)] 移动回调 可选
  1920. * @param {Function} [options.onUndo()] 撤销回调 可选
  1921. * @param {Function} [options.onComplete(cPoints,gPoints)] 完成回调 可选
  1922. * @param {Function} [options.onError(message)] 错误回调 可选
  1923. */
  1924. _sketchDrawPolyline(handler, options) {
  1925. let _self = this;
  1926. /* 注册鼠标左键点击事件 */
  1927. this._registerLeftClickEvent(handler, function(event) {
  1928. /* 识别屏幕位置 */
  1929. let loc = _self._transfromFromScreenPoint(event.position);
  1930. if (!Cesium.defined(loc.sLocation)) return;
  1931. /* 绘制参考点 */
  1932. if (_self._isDrawPoint) {
  1933. _self._createPoint(loc.sLocation, _self._lineLabel);
  1934. }
  1935. /* 第一点击的时候绘制线 */
  1936. if (_self._sketchTempPoints.length === 0) {
  1937. _self._createPolyline(options.polylineType);
  1938. _self._sketchTempPoints.push(loc.sLocation.clone());
  1939. }
  1940. _self._sketchTempPoints.push(loc.sLocation);
  1941. /* 存储正式绘制点集合 */
  1942. _self._sketchPoints.push(loc.sLocation.clone());
  1943. /* 存储输出经纬度点集合 */
  1944. _self._sketchOutputPoints.push(loc.gLocation);
  1945. /* 监听输出 */
  1946. if (options.onAdded) options.onAdded(_self._sketchPoints, _self
  1947. ._sketchOutputPoints);
  1948. })
  1949. /* 注册鼠标移动事件 */
  1950. this._registerMouseMoveEvent(handler, function(event) {
  1951. /* 识别屏幕位置 */
  1952. let loc = _self._transfromFromScreenPoint(event.endPosition);
  1953. if (!Cesium.defined(loc.sLocation)) return;
  1954. if (_self._sketchTempPoints.length > 1) {
  1955. /* 标签提示 */
  1956. _self._drawMovingDoubleTooltip(event.endPosition);
  1957. _self._sketchTempPoints.pop();
  1958. _self._sketchTempPoints.push(loc.sLocation);
  1959. /* 监听输出 */
  1960. if (options.onMoving) options.onMoving(loc.sLocation);
  1961. }
  1962. });
  1963. /* 注册鼠标右键点击事件 */
  1964. this._registerRightClickEvent(handler, function(event) {
  1965. if (_self._sketchTempPoints.length > 2) {
  1966. /* 移除正式点最有一个元素 */
  1967. _self._sketchPoints.pop();
  1968. /* 移除临时点倒数第二个元素 */
  1969. _self._sketchTempPoints.splice(_self._sketchTempPoints.length - 2, 1);
  1970. /* 如果绘制了点 则删除最后一个 */
  1971. if (_self._isDrawPoint) {
  1972. _self._removeLastDrawPointEntity();
  1973. }
  1974. if (options.onUndo) options.onUndo();
  1975. }
  1976. });
  1977. /* 注册鼠标左键双击事件 */
  1978. this._registerLeftDoubleClickEvent(handler, function(event) {
  1979. if (_self._sketchPoints.length < 2) {
  1980. if (options.onError) options.onError('点数少于两个,禁止结束绘制!');
  1981. return;
  1982. }
  1983. /* 更新贴地线 */
  1984. _self._updatePolyline(options.isEdit);
  1985. /* 删除标记点 */
  1986. if (!_self._isRetainDrawPoint) _self._removePointEntitys();
  1987. /* 干掉事件句柄 释放资源*/
  1988. _self._clearEvent(handler);
  1989. /* 监听输出 */
  1990. if (options.onComplete) options.onComplete(_self._sketchPoints, _self
  1991. ._sketchOutputPoints);
  1992. })
  1993. },
  1994. /**
  1995. * 绘制空间线工具
  1996. * @ignore 生成方法时不对外公开
  1997. * @param {Object} handler 事件句柄
  1998. * @param {JSON} options 配置项
  1999. * @param {Boolean} isEdit 是否可编辑 可选 默认可编辑
  2000. * @param {Function} [options.onAdded(cPoints,gPoints)] 添加回调 可选
  2001. * @param {Function} [options.onMoving(cPoint)] 移动回调 可选
  2002. * @param {Function} [options.onUndo()] 撤销回调 可选
  2003. * @param {Function} [options.onComplete(cPoints,gPoints)] 完成回调 可选
  2004. * @param {Function} [options.onError(message)] 错误回到 可选
  2005. */
  2006. _sketchDrawSpatialPolyline(handler, options) {
  2007. let _self = this;
  2008. /* 注册鼠标左键单击事件 */
  2009. this._registerLeftClickEvent(handler, function(event) {
  2010. /* 识别屏幕位置 */
  2011. let loc = _self._transfromFromScreenPoint(event.position);
  2012. if (!Cesium.defined(loc.sLocation)) return;
  2013. /* 绘制点 */
  2014. if (_self._isDrawPoint) {
  2015. _self._createPoint(loc.sLocation, _self._lineLabel);
  2016. }
  2017. /* 第一点击的时候绘制线 */
  2018. if (_self._sketchTempPoints.length === 0) {
  2019. _self._createSpatialPolyline();
  2020. _self._sketchTempPoints.push(loc.sLocation.clone());
  2021. }
  2022. _self._sketchTempPoints.push(loc.sLocation);
  2023. /* 存储正式绘制点集合 */
  2024. _self._sketchPoints.push(loc.sLocation.clone());
  2025. /* 存储输出经纬度点集合 */
  2026. _self._sketchOutputPoints.push(loc.gLocation);
  2027. /* 监听输出 */
  2028. if (options.onAdded) options.onAdded(_self._sketchPoints, _self._sketchOutputPoints);
  2029. })
  2030. /* 注册鼠标移动事件 */
  2031. this._registerMouseMoveEvent(handler, function(event) {
  2032. /* 识别屏幕位置 */
  2033. let loc = _self._transfromFromScreenPoint(event.endPosition);
  2034. if (!Cesium.defined(loc.sLocation)) return;
  2035. if (_self._sketchTempPoints.length > 1) {
  2036. /* 标签提示 */
  2037. _self._drawMovingDoubleTooltip(event.endPosition);
  2038. _self._sketchTempPoints.pop();
  2039. _self._sketchTempPoints.push(loc.sLocation);
  2040. /* 监听输出 */
  2041. if (options.onMoving) options.onMoving(loc.sLocation);
  2042. }
  2043. })
  2044. /* 注册鼠标左键双击事件 */
  2045. this._registerLeftDoubleClickEvent(handler, function(event) {
  2046. if (_self._sketchPoints.length < 2) {
  2047. if (options.onError) options.onError('绘制点少于2个,禁止结束绘制!');
  2048. return;
  2049. }
  2050. /* 绘制正式空间线 */
  2051. _self._updateSpatialPolyline(options.isEdit);
  2052. /* 删除标记点 */
  2053. _self._removePointEntitys();
  2054. /* 干掉事件句柄 释放资源*/
  2055. _self._clearEvent(handler);
  2056. /* 监听输出 */
  2057. if (options.onComplete) options.onComplete(_self._sketchPoints, _self
  2058. ._sketchOutputPoints);
  2059. })
  2060. /* 注册鼠标右键单击事件 */
  2061. this._registerRightClickEvent(handler, function(event) {
  2062. if (_self._sketchTempPoints.length > 2) {
  2063. _self._removeLastDrawPointEntity();
  2064. /* 移除正式点最有一个元素 */
  2065. _self._sketchPoints.pop();
  2066. /* 移除临时点倒数第二个元素 */
  2067. _self._sketchTempPoints.splice(_self._sketchTempPoints.length - 2, 1);
  2068. if (options.onUndo) options.onUndo();
  2069. }
  2070. });
  2071. },
  2072. /**
  2073. * 绘制OD线工具
  2074. * @ignore 生成方法时不对外公开
  2075. * @param {Object} handler 事件句柄
  2076. * @param {JSON} options 配置项
  2077. * @param {Boolean} isEdit 是否可编辑 可选 默认可编辑
  2078. * @param {Function} [options.onAdded(cPoints,gPoints)] 添加回调 可选
  2079. * @param {Function} [options.onMoving(cPoint)] 移动回调 可选
  2080. * @param {Function} [options.onUndo()] 撤销回调 可选
  2081. * @param {Function} [options.onComplete(cPoints,gPoints)] 完成回调 可选
  2082. * @param {Function} [options.onError(message)] 错误回到 可选
  2083. */
  2084. _sketchDrawOdline(handler, options) {
  2085. let _self = this;
  2086. /* 注册鼠标左键单击事件 */
  2087. this._registerLeftClickEvent(handler, function(event) {
  2088. /* 识别屏幕位置 */
  2089. let loc = _self._transfromFromScreenPoint(event.position);
  2090. if (!Cesium.defined(loc.sLocation)) return;
  2091. /* 绘制点 */
  2092. if (_self._isDrawPoint) {
  2093. _self._createPoint(loc.sLocation, _self._lineLabel);
  2094. }
  2095. /* 第一点击的时候绘制线 */
  2096. if (_self._sketchTempPoints.length === 0) {
  2097. _self._createOdline(true);
  2098. _self._sketchTempPoints.push(loc.sLocation.clone());
  2099. } else {
  2100. _self._updateOdline(false, options.isEdit);
  2101. _self._createOdline();
  2102. }
  2103. _self._sketchTempPoints.push(loc.sLocation);
  2104. /* 存储正式绘制点集合 */
  2105. _self._sketchPoints.push(loc.sLocation.clone());
  2106. /* 存储输出经纬度点集合 */
  2107. _self._sketchOutputPoints.push(loc.gLocation);
  2108. /* 监听输出 */
  2109. if (options.onAdded) options.onAdded(_self._sketchPoints, _self._sketchOutputPoints);
  2110. })
  2111. /* 注册鼠标移动事件 */
  2112. this._registerMouseMoveEvent(handler, function(event) {
  2113. /* 识别屏幕位置 */
  2114. let loc = _self._transfromFromScreenPoint(event.endPosition);
  2115. if (!Cesium.defined(loc.sLocation)) return;
  2116. if (_self._sketchTempPoints.length > 1) {
  2117. /* 标签提示 */
  2118. _self._drawMovingDoubleTooltip(event.endPosition);
  2119. _self._sketchTempPoints.pop();
  2120. _self._sketchTempPoints.push(loc.sLocation);
  2121. /* 监听输出 */
  2122. if (options.onMoving) options.onMoving(loc.sLocation);
  2123. }
  2124. })
  2125. /* 注册鼠标左键双击事件 */
  2126. this._registerLeftDoubleClickEvent(handler, function(event) {
  2127. if (_self._sketchPoints.length < 2) {
  2128. if (options.onError) options.onError('绘制点少于2个,禁止结束绘制!');
  2129. return;
  2130. }
  2131. /* 绘制正式OD线 */
  2132. _self._removeEntityByObject(_self._drawEntity);
  2133. _self._updateOdline(true, options.isEdit);
  2134. /* 删除标记点 */
  2135. _self._removePointEntitys();
  2136. /* 干掉事件句柄 释放资源*/
  2137. _self._clearEvent(handler);
  2138. /* 监听输出 */
  2139. if (options.onComplete) options.onComplete(_self._sketchPoints, _self
  2140. ._sketchOutputPoints);
  2141. })
  2142. /* 注册鼠标右键单击事件 */
  2143. this._registerRightClickEvent(handler, function(event) {
  2144. if (_self._odlineEntitys.length > 0) {
  2145. _self._removeLastDrawPointEntity();
  2146. _self._removeEntityByObject(_self._odlineEntitys.last());
  2147. if (options.onUndo) options.onUndo();
  2148. }
  2149. });
  2150. },
  2151. /**
  2152. * 绘制贴地面工具
  2153. * @ignore 生成方法时不对外公开
  2154. * @param {Object} handler 事件句柄
  2155. * @param {JSON} options 配置项
  2156. * @param {Boolean} isEdit 是否可编辑 可选 默认可编辑
  2157. * @param {DrawTools.PolygonType} options.polygonType 绘制面类型 可选
  2158. * @param {Function} [options.onAdded(cPoints,gPoints)] 添加回调 可选
  2159. * @param {Function} [options.onMoving(cPoint)] 移动回调 可选
  2160. * @param {Function} [options.onUndo()] 撤销回调 可选
  2161. * @param {Function} [options.onComplete(cPoints,gPoints)] 完成回调 可选
  2162. * @param {Function} [options.onError(message)] 错误回到 可选
  2163. */
  2164. _sketchDrawPolygon(handler, options) {
  2165. let _self = this;
  2166. /* 注册鼠标左键点击事件 */
  2167. this._registerLeftClickEvent(handler, function(event) {
  2168. /* 识别屏幕位置 */
  2169. let loc = _self._transfromFromScreenPoint(event.position);
  2170. if (!Cesium.defined(loc.sLocation)) return;
  2171. /* 绘制点 */
  2172. if (_self._isDrawPoint) {
  2173. _self._createPoint(loc.sLocation, _self._lineLabel);
  2174. }
  2175. /* 当点数为0时绘制线和面 */
  2176. if (_self._sketchTempPoints.length === 0) {
  2177. _self._createPolygon(options.polygonType);
  2178. _self._sketchTempPoints.push(loc.sLocation.clone());
  2179. }
  2180. _self._sketchTempPoints.push(loc.sLocation);
  2181. /* 存储正式绘制点集合 */
  2182. _self._sketchPoints.push(loc.sLocation.clone());
  2183. /* 存储输出经纬度点集合 */
  2184. _self._sketchOutputPoints.push(loc.gLocation);
  2185. /* 监听输出 */
  2186. if (options.onAdded) options.onAdded(_self._sketchPoints, _self._sketchOutputPoints);
  2187. });
  2188. /* 注册鼠标移动事件 */
  2189. this._registerMouseMoveEvent(handler, function(event) {
  2190. /* 识别屏幕位置 */
  2191. let loc = _self._transfromFromScreenPoint(event.endPosition);
  2192. if (!Cesium.defined(loc.sLocation)) return;
  2193. if (_self._sketchTempPoints.length > 1) {
  2194. /* 标签提示 */
  2195. _self._drawMovingDoubleTooltip(event.endPosition);
  2196. _self._sketchTempPoints.pop();
  2197. _self._sketchTempPoints.push(loc.sLocation);
  2198. /* 监听输出 */
  2199. if (options.onMoving) options.onMoving(loc.sLocation);
  2200. }
  2201. });
  2202. /* 注册鼠标右键单击事件 */
  2203. this._registerRightClickEvent(handler, function(event) {
  2204. if (_self._sketchTempPoints.length > 2) {
  2205. /* 移除正式点最有一个元素 */
  2206. _self._sketchPoints.pop();
  2207. /* 移除临时点倒数第二个元素 */
  2208. _self._sketchTempPoints.splice(_self._sketchTempPoints.length - 2, 1);
  2209. /* 如果绘制了点 则删除最后一个 */
  2210. if (_self._isDrawPoint) {
  2211. _self._removeLastDrawPointEntity();
  2212. }
  2213. if (options.onUndo) options.onUndo();
  2214. }
  2215. });
  2216. /* 注册鼠标左键双击事件 */
  2217. this._registerLeftDoubleClickEvent(handler, function(event) {
  2218. if (_self._sketchPoints.length < 3) {
  2219. if (options.onError) options.onError('点数少于3个,禁止结束绘制!');
  2220. return;
  2221. }
  2222. /* 更新贴地面 */
  2223. _self._updatePolygon(options.isEdit);
  2224. /* 删除标记点 */
  2225. if (!_self._isRetainDrawPoint) _self._removePointEntitys();
  2226. /* 干掉事件句柄 释放资源*/
  2227. _self._clearEvent(handler);
  2228. /* 监听输出 */
  2229. if (options.onComplete) options.onComplete(_self._sketchPoints, _self
  2230. ._sketchOutputPoints);
  2231. })
  2232. },
  2233. /**
  2234. * 绘制贴地圆工具
  2235. * @ignore 生成方法时不对外公开
  2236. * @param {Object} handler 事件句柄
  2237. * @param {JSON} options 配置项
  2238. * @param {Boolean} isEdit 是否可编辑 可选 默认可编辑
  2239. * @param {DrawTools.CircleType} options.circleType 绘制圆的类型 可选
  2240. * @param {Function} [options.onAdded(center)] 添加回调 可选
  2241. * @param {Function} [options.onComplete(center,radius)] 完成回调 可选
  2242. * @param {Function} [options.onError(message)] 错误回到 可选
  2243. */
  2244. _sketchDrawCircle: function(handler, options) {
  2245. let _self = this;
  2246. /* 注册鼠标左键单击事件 */
  2247. this._registerLeftClickEvent(handler, function(event) {
  2248. if (_self._sketchTempPoints.length === 0) {
  2249. /* 识别屏幕位置 */
  2250. let loc = _self._transfromFromScreenPoint(event.position);
  2251. if (!Cesium.defined(loc.sLocation)) return;
  2252. /* 绘制点 */
  2253. if (_self._isDrawPoint) {
  2254. _self._createPoint(loc.sLocation, '起点');
  2255. }
  2256. /* 添加数据 */
  2257. _self._sketchTempPoints.push(loc.sLocation.clone());
  2258. _self._sketchTempPoints.push(loc.sLocation); //凑数的
  2259. /* 存储正式绘制点集合 */
  2260. _self._sketchPoints.push(loc.sLocation.clone());
  2261. /* 存储经纬度 */
  2262. _self._sketchOutputPoints.push(loc.gLocation);
  2263. /* 创建圆 */
  2264. _self._createCircle(loc.sLocation, options.circleType);
  2265. /* 监听输出 */
  2266. if (options.onAdded) options.onAdded(loc.sLocation);
  2267. } else {
  2268. /* 删除标记点 */
  2269. _self._removePointEntitys();
  2270. /* 删除临时圆 */
  2271. _self._removeEntityByObject(_self._sketchTempCircle);
  2272. /* 更新圆 */
  2273. _self._updateCircle(options.isEdit);
  2274. /* 干掉事件句柄 释放资源*/
  2275. _self._clearEvent(handler);
  2276. /* 回调返回 */
  2277. if (options.onComplete) options.onComplete(_self._sketchOutputPoints[0], _self
  2278. ._sketchEllipseRadius);
  2279. }
  2280. });
  2281. /* 注册鼠标移动事件 */
  2282. this._registerMouseMoveEvent(handler, function(event) {
  2283. /* 如果还未创建圆 则直接返回 */
  2284. if (_self._sketchTempPoints.length <= 0) return;
  2285. /* 标签提示 */
  2286. _self._drawMovingSimpleTooltip(event.endPosition);
  2287. /* 获取空间位置 */
  2288. var cartesian = _self._viewer.scene.pickPosition(event.endPosition);
  2289. /* 如果获取点失败 则直接返回 */
  2290. if (cartesian == undefined) return;
  2291. _self._sketchTempPoints.pop();
  2292. _self._sketchTempPoints.push(cartesian);
  2293. })
  2294. },
  2295. /**
  2296. * 绘制贴地矩形工具
  2297. * @ignore 生成方法时不对外公开
  2298. * @param {Object} handler 事件句柄
  2299. * @param {JSON} options 配置项
  2300. * @param {Boolean} isEdit 是否可编辑 可选 默认可编辑
  2301. * @param {Function} [options.onAdded(cPoint)] 添加回调 可选
  2302. * @param {Function} [options.onComplete(points)] 完成回调 可选
  2303. */
  2304. _sketchDrawRectangle: function(handler, options) {
  2305. let _self = this;
  2306. /* 注册鼠标左键单击事件 */
  2307. this._registerLeftClickEvent(handler, function(event) {
  2308. if (_self._sketchTempPoints.length === 0) {
  2309. /* 识别屏幕位置 */
  2310. let loc = _self._transfromFromScreenPoint(event.position);
  2311. if (!Cesium.defined(loc.sLocation)) return;
  2312. /* 绘制点 */
  2313. if (_self._isDrawPoint) {
  2314. _self._createPoint(loc.sLocation, '起点');
  2315. }
  2316. /* 添加数据 */
  2317. _self._sketchTempPoints.push(loc.sLocation);
  2318. _self._sketchTempPoints.push(loc.sLocation); //凑数的
  2319. /* 存储正式绘制点集合 */
  2320. _self._sketchPoints.push(loc.gLocation);
  2321. /* 创建矩形 */
  2322. _self._createRectangle();
  2323. /* 回调 */
  2324. if (options.onAdded) options.onAdded(loc.sLocation);
  2325. } else {
  2326. /* 删除标记点 */
  2327. _self._removePointEntitys();
  2328. /* 删除临时矩形 */
  2329. _self._removeEntityByObject(_self._sketchTempRectangle);
  2330. /* 创建正式矩形 */
  2331. _self._updateRectangle(options.isEdit);
  2332. /* 干掉事件句柄 释放资源*/
  2333. handler.destroy();
  2334. handler = null;
  2335. /* 回调返回 */
  2336. if (options.onComplete) options.onComplete(_self._sketchOutputPoints);
  2337. }
  2338. });
  2339. /* 挂接鼠标移动事件 */
  2340. this._registerMouseMoveEvent(handler, function(event) {
  2341. /* 如果还未创矩形 则直接返回 */
  2342. if (_self._sketchTempPoints.length < 1) return;
  2343. /* 标签提示 */
  2344. _self._drawMovingSimpleTooltip(event.endPosition);
  2345. /* 识别屏幕位置 */
  2346. let loc = _self._transfromFromScreenPoint(event.endPosition);
  2347. if (!Cesium.defined(loc.sLocation)) return;
  2348. _self._sketchTempPoints.pop();
  2349. _self._sketchTempPoints.push(loc.sLocation);
  2350. });
  2351. },
  2352. /**
  2353. * 绘制墙
  2354. * @ignore 生成方法时不对外公开
  2355. * @param {Object} handler 事件句柄
  2356. * @param {JSON} options 配置项
  2357. * @param {Boolean} options.isEdit [是否可编辑 可选]
  2358. * @param {DrawTools.WallType} options.wallType [绘制墙的类型 可选]
  2359. * @param {Function} [options.onMoving(cPoint)] 移动回调 可选
  2360. * @param {Function} [options.onComplete(positions)] 完成回调 可选
  2361. * @param {Function} [options.onError(message)] 错误回到 可选
  2362. */
  2363. _sketchDrawWall: function(handler, options) {
  2364. let _self = this;
  2365. /* 注册鼠标左键点击事件 */
  2366. this._registerLeftClickEvent(handler, function(event) {
  2367. /* 识别屏幕位置 */
  2368. let loc = _self._transfromFromScreenPoint(event.position);
  2369. if (!Cesium.defined(loc.sLocation)) return;
  2370. /* 绘制点 */
  2371. if (_self._isDrawPoint) {
  2372. _self._createPoint(loc.sLocation, _self._lineLabel);
  2373. }
  2374. /* 第一点击的时候绘制线 */
  2375. if (_self._sketchTempPoints.length === 0) {
  2376. _self._createWall(options.wallType);
  2377. _self._sketchTempPoints.push(loc.sLocation.clone());
  2378. /* 存储墙的高度点集合 */
  2379. _self._sketchWallHeights.push(loc.gLocation.height);
  2380. }
  2381. _self._sketchTempPoints.push(loc.sLocation);
  2382. _self._sketchWallHeights.push(loc.gLocation.height);
  2383. /* 存储正式绘制点集合 */
  2384. _self._sketchPoints.push(loc.sLocation.clone());
  2385. })
  2386. /* 注册鼠标移动事件 */
  2387. this._registerMouseMoveEvent(handler, function(event) {
  2388. /* 识别屏幕位置 */
  2389. let loc = _self._transfromFromScreenPoint(event.endPosition);
  2390. if (!Cesium.defined(loc.sLocation)) return;
  2391. if (_self._sketchTempPoints.length > 1) {
  2392. /* 标签提示 */
  2393. _self._drawMovingDoubleTooltip(event.endPosition);
  2394. _self._sketchTempPoints.pop();
  2395. _self._sketchTempPoints.push(loc.sLocation);
  2396. _self._sketchWallHeights.pop();
  2397. _self._sketchWallHeights.push(loc.gLocation.height);
  2398. }
  2399. });
  2400. /* 注册鼠标右键点击事件 */
  2401. this._registerRightClickEvent(handler, function(event) {
  2402. if (_self._sketchTempPoints.length > 2) {
  2403. /* 移除正式点最有一个元素 */
  2404. _self._sketchPoints.pop();
  2405. /* 移除临时点倒数第二个元素 */
  2406. _self._sketchTempPoints.splice(_self._sketchTempPoints.length - 2, 1);
  2407. /* 移除临时高度点倒数第二个元素 */
  2408. _self._sketchWallHeights.splice(_self._sketchWallHeights.length - 2, 1);
  2409. /* 如果绘制了点 则删除最后一个 */
  2410. if (_self._isDrawPoint) {
  2411. _self._removeLastDrawPointEntity();
  2412. }
  2413. }
  2414. });
  2415. /* 注册鼠标左键双击事件 */
  2416. this._registerLeftDoubleClickEvent(handler, function(event) {
  2417. if (_self._sketchPoints.length < 2) {
  2418. if (options.onError) options.onError('点数少于两个,禁止结束绘制!');
  2419. return;
  2420. }
  2421. /* 更新墙属性 */
  2422. _self._updateWall(options.isEdit);
  2423. /* 删除标记点 */
  2424. if (!_self._isRetainDrawPoint) _self._removePointEntitys();
  2425. /* 干掉事件句柄 释放资源*/
  2426. _self._clearEvent(handler);
  2427. })
  2428. },
  2429. /**
  2430. * 绘制视频墙
  2431. * @ignore 生成方法时不对外公开
  2432. * @param {Object} handler 事件句柄
  2433. * @param {JSON} options 配置项
  2434. * @param {Boolean} options.isEdit [是否可编辑 可选]
  2435. * @param {Function} [options.onMoving(cPoint)] 移动回调 可选
  2436. * @param {Function} [options.onComplete(positions)] 完成回调 可选
  2437. * @param {Function} [options.onError(message)] 错误回到 可选
  2438. */
  2439. _sketchDrawVideoWall: function(handler, options) {
  2440. let _self = this;
  2441. /* 注册鼠标左键点击事件 */
  2442. this._registerLeftClickEvent(handler, function(event) {
  2443. /* 识别屏幕位置 */
  2444. let loc = _self._transfromFromScreenPoint(event.position);
  2445. if (!Cesium.defined(loc.sLocation)) return;
  2446. /* 绘制点 */
  2447. if (_self._isDrawPoint) {
  2448. _self._createPoint(loc.sLocation, _self._lineLabel);
  2449. }
  2450. /* 第一点击的时候绘制 */
  2451. if (_self._sketchOutputPoints.length === 0) {
  2452. _self._sketchOutputPoints.push(loc.gLocation);
  2453. _self._sketchOutputPoints.push(loc.gLocation);
  2454. _self._createVideoWall();
  2455. } else {
  2456. _self._updateVideoWall(options.isEdit);
  2457. _self._clearEvent(handler);
  2458. }
  2459. // _self._removeCoorinateAxis();
  2460. // _self._createCoordinateAxis(loc.sLocation);
  2461. // _self._clearEvent(handler);
  2462. })
  2463. /* 注册鼠标移动事件 */
  2464. this._registerMouseMoveEvent(handler, function(event) {
  2465. /* 识别屏幕位置 */
  2466. let loc = _self._transfromFromScreenPoint(event.endPosition);
  2467. if (!Cesium.defined(loc.sLocation)) return;
  2468. if (_self._sketchOutputPoints.length > 1) {
  2469. /* 标签提示 */
  2470. _self._drawMovingSimpleTooltip(event.endPosition);
  2471. _self._sketchOutputPoints.pop();
  2472. _self._sketchOutputPoints.push(loc.gLocation);
  2473. }
  2474. });
  2475. },
  2476. /**
  2477. * 启用绘制
  2478. * @param {DrawTools.DrawType} type 绘制类型
  2479. * @param {JSON} options 回调集合
  2480. * @param {Boolean} [isEdit] 是否可编辑 可选 默认不可编辑
  2481. * @param {Function} [options.onAdded] 添加回调 可选 子方法自定义
  2482. * @param {Function} [options.onMoving] 移动回调 可选 子方法自定义
  2483. * @param {Function} [options.onUndo] 撤销回调 可选 子方法自定义
  2484. * @param {Function} [options.onComplete] 完成回调 可选 子方法自定义
  2485. * @param {Function} [options.onError] 错误回调 可选 子方法自定义
  2486. */
  2487. draw: function(type, options) {
  2488. /* 定义自身 */
  2489. let _self = this;
  2490. /* 初始化 */
  2491. this._clear();
  2492. /* 注册事件 */
  2493. _self._drawEventHandler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
  2494. _self._beginTooltip('左键单击绘制', undefined);
  2495. /* 分类型注册事件 */
  2496. switch (type) {
  2497. case DrawTools.DrawType.Point: //绘制点
  2498. _self._sketchDrawPoint(_self._drawEventHandler, options);
  2499. break;
  2500. case DrawTools.DrawType.Polyline: //绘制贴地线
  2501. options.polylineType = DrawTools.PolylineType.NormalPolyline;
  2502. _self._sketchDrawPolyline(_self._drawEventHandler, options);
  2503. break;
  2504. case DrawTools.DrawType.ArrowPolyline: //绘制箭头线
  2505. options.polylineType = DrawTools.PolylineType.ArrowsPolyline;
  2506. _self._sketchDrawPolyline(_self._drawEventHandler, options);
  2507. break;
  2508. case DrawTools.DrawType.DynamicPolyline: //绘制流动线
  2509. options.polylineType = DrawTools.PolylineType.DynamicPolyline;
  2510. _self._sketchDrawPolyline(_self._drawEventHandler, options);
  2511. break;
  2512. case DrawTools.DrawType.GrowPolyline: //绘制发光线
  2513. options.polylineType = DrawTools.PolylineType.GrowPolyline;
  2514. _self._sketchDrawPolyline(_self._drawEventHandler, options);
  2515. break;
  2516. case DrawTools.DrawType.OutlinePolyline: //绘制描边线
  2517. options.polylineType = DrawTools.PolylineType.OutlinePolyline;
  2518. _self._sketchDrawPolyline(_self._drawEventHandler, options);
  2519. break;
  2520. case DrawTools.DrawType.Polygon: //绘制贴地面
  2521. options.polygonType = DrawTools.PolygonType.NormalPolygon;
  2522. _self._sketchDrawPolygon(_self._drawEventHandler, options);
  2523. break;
  2524. case DrawTools.DrawType.SpatialLine: //绘制空间线
  2525. _self._sketchDrawSpatialPolyline(_self._drawEventHandler, options);
  2526. break;
  2527. case DrawTools.DrawType.Circle: //绘制贴地圆
  2528. options.circleType = DrawTools.CircleType.ColorCircle;
  2529. _self._sketchDrawCircle(_self._drawEventHandler, options);
  2530. break;
  2531. case DrawTools.DrawType.Rectangle: //绘制矩形
  2532. _self._sketchDrawRectangle(_self._drawEventHandler, options);
  2533. break;
  2534. case DrawTools.DrawType.NormalWall: //绘制普通墙
  2535. options.wallType = DrawTools.WallType.ColorWall;
  2536. _self._sketchDrawWall(_self._drawEventHandler, options);
  2537. break;
  2538. case DrawTools.DrawType.DynamicWall: //绘制动态墙
  2539. options.wallType = DrawTools.WallType.DynamicWall;
  2540. _self._sketchDrawWall(_self._drawEventHandler, options);
  2541. break;
  2542. case DrawTools.DrawType.TextWall: //绘制文字墙
  2543. options.wallType = DrawTools.WallType.TextWall;
  2544. _self._sketchDrawWall(_self._drawEventHandler, options);
  2545. break;
  2546. case DrawTools.DrawType.DynamicCircle: //绘制扩散圆
  2547. options.circleType = DrawTools.CircleType.DynamicCircle;
  2548. _self._sketchDrawCircle(_self._drawEventHandler, options);
  2549. break;
  2550. case DrawTools.DrawType.House: //绘制房屋
  2551. options.polygonType = DrawTools.PolygonType.HousePolygon;
  2552. _self._sketchDrawPolygon(_self._drawEventHandler, options);
  2553. break;
  2554. case DrawTools.DrawType.VideoWall:
  2555. _self._sketchDrawVideoWall(_self._drawEventHandler, options);
  2556. break;
  2557. case DrawTools.DrawType.OdLine:
  2558. _self._sketchDrawOdline(_self._drawEventHandler, options);
  2559. break;
  2560. }
  2561. },
  2562. /**
  2563. * 清理资源
  2564. */
  2565. Clear: function() {
  2566. /* 清理全部绘制内容 */
  2567. this._clear(true);
  2568. /* 结束编辑状态 */
  2569. this._unActivateEdit();
  2570. /* 删除坐标轴 */
  2571. this._removeCoorinateAxis();
  2572. },
  2573. /**
  2574. * 初始化
  2575. */
  2576. sketchInit: function() {
  2577. this._clear(false);
  2578. }
  2579. })
  2580. /**
  2581. * 鼠标跟随标签相关
  2582. */
  2583. Object.assign(DrawTools.prototype, {
  2584. /**
  2585. * 提示标签初始化
  2586. * @ignore 生成方法时不对外公开
  2587. * @param {String} text 显示的文本内���
  2588. * @param {JSON} mousePosition 鼠标位置
  2589. */
  2590. _tooltipInit: function(text, mousePosition) {
  2591. let _self = this;
  2592. this._tooltipId = 'tooltipSketchmodel';
  2593. let tooltipObj = document.getElementById(this._tooltipId);
  2594. if (tooltipObj === null) {
  2595. tooltipObj = document.createElement('div');
  2596. tooltipObj.id = this._tooltipId;
  2597. document.body.appendChild(tooltipObj);
  2598. let divStyle = '';
  2599. divStyle += "top: 30px;";
  2600. divStyle += "left: 30px;";
  2601. divStyle += "position: absolute;";
  2602. divStyle += "display: flex;";
  2603. divStyle += "align-items: center;";
  2604. divStyle += "width: 12x0px;";
  2605. divStyle += "height: auto;";
  2606. divStyle += "background-color: rgba(0, 0, 0, 0.65);";
  2607. divStyle += "border-radius: 5px;";
  2608. divStyle += "color: rgb(255, 255, 255);";
  2609. divStyle += "font-size: 12px;";
  2610. divStyle += "font-family: 'Alimama_ShuHeiTi_Bold';";
  2611. divStyle += "padding: 8px;";
  2612. divStyle += "border:solid 1px rgb(255,0,0);";
  2613. tooltipObj.setAttribute('style', divStyle);
  2614. }
  2615. if (text != undefined) tooltipObj.innerHTML = text;
  2616. if (mousePosition === undefined) {
  2617. /* 挂接鼠标移动事件 */
  2618. document.onmousemove = function(event) {
  2619. if (event.clientX < 100 || event.clientX > _self._canvasWidth - 100 || event.clientY <
  2620. 100 ||
  2621. event.clientY > _self._canvasHeight - 100) {
  2622. tooltipObj.style.display = 'none';
  2623. } else {
  2624. tooltipObj.style.display = 'flex';
  2625. tooltipObj.style.left = (event.clientX + 10) + 'px';
  2626. tooltipObj.style.top = (event.clientY - tooltipObj.offsetHeight / 2) + 'px';
  2627. }
  2628. }
  2629. } else {
  2630. if (mousePosition.x < 100 || mousePosition.x > _self._canvasWidth - 100 || mousePosition.y <
  2631. 100 ||
  2632. mousePosition.y > _self._canvasHeight - 100) {
  2633. tooltipObj.style.display = 'none';
  2634. } else {
  2635. tooltipObj.style.display = 'flex';
  2636. tooltipObj.style.left = (mousePosition.x + 10) + 'px';
  2637. tooltipObj.style.top = (mousePosition.y - tooltipObj.offsetHeight / 2) + 'px';
  2638. }
  2639. }
  2640. },
  2641. /**
  2642. * 移除提示标签
  2643. * @ignore 生成方法时不对外公开
  2644. */
  2645. _tooltipRemove: function() {
  2646. let tooltipObj = document.getElementById(this._tooltipId);
  2647. if (tooltipObj != null) {
  2648. document.body.removeChild(tooltipObj);
  2649. }
  2650. },
  2651. /**
  2652. * 设置提示标签文本
  2653. * @ignore 生成方法时不对外公开
  2654. * @param {String} text 文本
  2655. * @param {JSON} mousePosition 鼠标位置
  2656. */
  2657. _tooltipSetText: function(text, mousePosition) {
  2658. let tooltipObj = document.getElementById(this._tooltipId);
  2659. if (tooltipObj != null) {
  2660. if (text != undefined) tooltipObj.innerHTML = text;
  2661. if (mousePosition != undefined) {
  2662. if (mousePosition.x < 100 || mousePosition.x > this._canvasWidth - 100 || mousePosition.y <
  2663. 100 ||
  2664. mousePosition.y > this._canvasHeight - 100) {
  2665. tooltipObj.style.display = 'none';
  2666. } else {
  2667. tooltipObj.style.display = 'flex';
  2668. tooltipObj.style.left = (mousePosition.x + 10) + 'px';
  2669. tooltipObj.style.top = (mousePosition.y - tooltipObj.offsetHeight / 2) + 'px';
  2670. }
  2671. }
  2672. }
  2673. },
  2674. /**
  2675. * 设置鼠标为十字样式
  2676. * @ignore 生成方法时不对外公开
  2677. */
  2678. _setMousePointerStyle: function() {
  2679. document.querySelector('body').style.cursor = 'crosshair';
  2680. },
  2681. /**
  2682. * 恢复鼠标指针为默认样式
  2683. * @ignore 生成方法时不对外公开
  2684. */
  2685. _setMouseDefaultStyle: function() {
  2686. document.querySelector('body').style.cursor = 'default';
  2687. },
  2688. /**
  2689. * 启用标签
  2690. * @ignore 不公开
  2691. * @param {String} text 标签文字
  2692. * @param {Cesium.Cartesian2} position 鼠标位置
  2693. */
  2694. _beginTooltip(text, position) {
  2695. this._tooltipInit(text, position);
  2696. this._setMousePointerStyle();
  2697. },
  2698. /**
  2699. * 更新标签标签
  2700. * @ignore 不公开
  2701. * @param {String} text 标签文字
  2702. * @param {Cesium.Cartesian2} position 鼠标位置
  2703. */
  2704. _updateTooltip(text, position) {
  2705. this._tooltipSetText(text, position);
  2706. },
  2707. /**
  2708. * 结束标签
  2709. * @ignore 不公开
  2710. */
  2711. _endTooltip() {
  2712. this._tooltipRemove();
  2713. this._setMouseDefaultStyle();
  2714. }
  2715. })
  2716. /**
  2717. * 拖拽坐标轴相关
  2718. */
  2719. Object.assign(DrawTools.prototype, {
  2720. /**
  2721. * 创建单个坐标轴
  2722. * @ignore 生成方法时不对外公开
  2723. * @param {Array<Cesium.Cartesian3>} positions 坐标集合
  2724. * @param {String} color 坐标轴颜色 rgba(r,g,b,a)
  2725. * @param {String} axisEntityId 坐标轴实体的Id
  2726. */
  2727. _createSingleCoordinateAxisArrow(positions, color, axisEntityId) {
  2728. let _self = this;
  2729. /* 创建坐标轴 */
  2730. let coordinateAxisEntity = new Cesium.Entity({
  2731. id: axisEntityId,
  2732. name: _self._coordinateAxisEntityName,
  2733. position: positions[0],
  2734. polyline: {
  2735. positions: positions,
  2736. width: 10.0,
  2737. material: _self._materialPolylineArrowProperty({
  2738. color: color,
  2739. })
  2740. }
  2741. })
  2742. /* 设置类型 */
  2743. coordinateAxisEntity.setEditType({
  2744. type: DrawTools.EditPointType.CoordinateAxis,
  2745. });
  2746. /* 渲染坐标轴 */
  2747. return this._entities.add(coordinateAxisEntity);
  2748. },
  2749. /**
  2750. * 平移目标点
  2751. * @ignore 生成方法时不对外公开
  2752. * @param {Cesium.Cartesian3} originPosition 参考点
  2753. * @param {Cesium.Cartesian3} translateCartesian 平移距离
  2754. * @return {Cesium.Cartesian3}
  2755. */
  2756. _getTranslatePostion: function(originPosition, translateCartesian) {
  2757. let transform = Cesium.Transforms.eastNorthUpToFixedFrame(originPosition); //东-北-上参考系构造出4*4的矩阵
  2758. let m = new Cesium.Matrix4();
  2759. Cesium.Matrix4.setTranslation(
  2760. Cesium.Matrix4.IDENTITY,
  2761. translateCartesian,
  2762. m
  2763. ); //构造平移矩阵
  2764. let modelMatrix = Cesium.Matrix4.multiply(transform, m, transform); //将当前位置矩阵乘以平移矩阵得到平移之后的位置矩阵
  2765. let outPosition = new Cesium.Cartesian3(0, 0, 0);
  2766. Cesium.Matrix4.getTranslation(modelMatrix, outPosition); //从位置矩阵中取出坐标信息
  2767. return outPosition;
  2768. },
  2769. /**
  2770. * 创建3个坐标轴
  2771. * @ignore 生成方法时不对外公开
  2772. * @param {Cesium.Cartesian3} position 坐标轴中心点位置
  2773. */
  2774. _createCoordinateAxis: function(position) {
  2775. /* 创建坐标轴之前先移除已创建的坐标轴 */
  2776. this._removeCoorinateAxis();
  2777. let _self = this;
  2778. /* 坐标轴的Id */
  2779. this._coordinateAxisEntityId_x = 'coordinateAxisId_x';
  2780. this._coordinateAxisEntityId_y = 'coordinateAxisId_y';
  2781. this._coordinateAxisEntityId_z = 'coordinateAxisId_z';
  2782. /* 坐标轴的名称 */
  2783. this._coordinateAxisEntityName = "coordinateAxisEntity";
  2784. /* 创建X轴 */
  2785. let translateCartesian = new Cesium.Cartesian3(150, 0, 0); //单位为米
  2786. let endPosition = this._getTranslatePostion(position, translateCartesian);
  2787. const xPos = [position, endPosition];
  2788. this._coordinateEntity_x = this._createSingleCoordinateAxisArrow(xPos, 'rgba(0,255,0,1.0)', this
  2789. ._coordinateAxisEntityId_x);
  2790. /* 给坐标轴绑定编辑实体 */
  2791. this._coordinateAxisBindEntity(this._coordinateEntity_x);
  2792. /* 创建Y轴 */
  2793. translateCartesian = new Cesium.Cartesian3(0, 150, 0); //单位为
  2794. endPosition = this._getTranslatePostion(position, translateCartesian);
  2795. const yPos = [position, endPosition];
  2796. this._coordinateEntity_y = this._createSingleCoordinateAxisArrow(yPos, 'rgba(0,0,255,1.0)', this
  2797. ._coordinateAxisEntityId_y);
  2798. /* 给坐标轴绑定编辑实体 */
  2799. this._coordinateAxisBindEntity(this._coordinateEntity_y);
  2800. /* 创建Z轴 */
  2801. translateCartesian = new Cesium.Cartesian3(0, 0, 150); //单位为
  2802. endPosition = this._getTranslatePostion(position, translateCartesian);
  2803. const zPos = [position, endPosition];
  2804. this._coordinateEntity_z = this._createSingleCoordinateAxisArrow(zPos, 'rgba(255,0,0,1.0)', this
  2805. ._coordinateAxisEntityId_z);
  2806. /* 给坐标轴绑定编辑实体 */
  2807. this._coordinateAxisBindEntity(this._coordinateEntity_z);
  2808. /* 注册坐标轴事件 */
  2809. this._eventCoorinateAxis = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
  2810. this._registerLeftDownEvent(this._eventCoorinateAxis, function(event) {
  2811. _self._coorinateAxisMouseDown(event);
  2812. });
  2813. this._registerMouseMoveEvent(this._eventCoorinateAxis, function(event) {
  2814. _self._coorinateAxisMouseMove(event);
  2815. });
  2816. this._registerLeftUpEvent(this._eventCoorinateAxis, function(event) {
  2817. _self._coorinateAxisMouseUp(event);
  2818. });
  2819. this._registerRightClickEvent(this._eventCoorinateAxis, function(event) {
  2820. _self._removeCoorinateAxis();
  2821. });
  2822. },
  2823. /**
  2824. * 给坐标轴绑定编辑的实体
  2825. * @ignore 生成方法时不对外公开
  2826. * @param {Cesium.Entity} axisEntity 轴实体
  2827. */
  2828. _coordinateAxisBindEntity: function(axisEntity) {
  2829. if (this._editEntity === undefined) return;
  2830. /* 获取当前编辑的实体类型 */
  2831. let editEntityType = this._editEntity.getEntityType();
  2832. if (editEntityType === undefined) return;
  2833. if (editEntityType === DrawTools.DrawType.VideoWall) {
  2834. axisEntity.bindEntity(this._editEntity);
  2835. }
  2836. },
  2837. /**
  2838. * 坐标轴鼠标按下事件
  2839. * @ignore 生成方法时不对外公开
  2840. * @param {Cesium.Event} event 事件
  2841. */
  2842. _coorinateAxisMouseDown: function(event) {
  2843. let _self = this;
  2844. let feature = this._viewer.scene.pick(event.position);
  2845. if (feature === undefined) return;
  2846. if (feature.id != undefined && feature.id instanceof Cesium.Entity) {
  2847. this._viewer.scene.screenSpaceCameraController.enableRotate = false;
  2848. if (feature.id.getEditType() === undefined) return;
  2849. let entityType = feature.id.getEditType().type;
  2850. if (entityType !== DrawTools.EditPointType.CoordinateAxis) return;
  2851. this._editCoorinateAxis = feature.id;
  2852. this._editCoorinateAxis.polyline.width = 15;
  2853. /* 设置坐标移动起始点 */
  2854. this._coordinateAxisMoveStartPosition = this._viewer.scene.camera.pickEllipsoid(event.position,
  2855. this._viewer.scene.globe.ellipsoid);
  2856. this._coordinateAxisMoveStartScreen = event.position;
  2857. this._coorinateAxisPosition = this._editCoorinateAxis.position._value;
  2858. /* 设置动态 */
  2859. this._coordinateEntity_x.polyline.positions = new Cesium.CallbackProperty(function() {
  2860. let translateCartesian = new Cesium.Cartesian3(150, 0, 0); //单位为米
  2861. let endPosition = _self._getTranslatePostion(_self._coorinateAxisPosition,
  2862. translateCartesian);
  2863. return [_self._coorinateAxisPosition, endPosition];
  2864. }, false);
  2865. this._coordinateEntity_y.polyline.positions = new Cesium.CallbackProperty(function() {
  2866. let translateCartesian = new Cesium.Cartesian3(0, 150, 0); //单位为米
  2867. let endPosition = _self._getTranslatePostion(_self._coorinateAxisPosition,
  2868. translateCartesian);
  2869. return [_self._coorinateAxisPosition, endPosition];
  2870. }, false);
  2871. this._coordinateEntity_z.polyline.positions = new Cesium.CallbackProperty(function() {
  2872. let translateCartesian = new Cesium.Cartesian3(0, 0, 150); //单位为米
  2873. let endPosition = _self._getTranslatePostion(_self._coorinateAxisPosition,
  2874. translateCartesian);
  2875. return [_self._coorinateAxisPosition, endPosition];
  2876. }, false);
  2877. /* 激活平移实体 */
  2878. this._coordinateAxisActivateEditEntity(this._editCoorinateAxis);
  2879. }
  2880. },
  2881. /**
  2882. * 坐标轴鼠标移动事件
  2883. * @ignore 生成方法时不对外公开
  2884. * @param {Cesium.Event} event 事件
  2885. */
  2886. _coorinateAxisMouseMove: function(event) {
  2887. if (!Cesium.defined(this._editCoorinateAxis)) return;
  2888. let position = this._viewer.scene.camera.pickEllipsoid(event.endPosition,
  2889. this._viewer.scene.globe.ellipsoid);
  2890. if (!position) return;
  2891. let strGeo = this._cartesian3ToGeo(this._coordinateAxisMoveStartPosition);
  2892. let endGeo = this._cartesian3ToGeo(position);
  2893. let entityId = this._editCoorinateAxis.id;
  2894. let entityPosition = this._editCoorinateAxis.position._value;
  2895. let entityGeo = this._cartesian3ToGeo(entityPosition);
  2896. let heightDifference = 0;
  2897. if (entityId === this._coordinateAxisEntityId_x) {
  2898. let difference = strGeo.longitude - endGeo.longitude;
  2899. entityGeo.longitude = entityGeo.longitude - difference;
  2900. } else if (entityId === this._coordinateAxisEntityId_y) {
  2901. let difference = strGeo.latitude - endGeo.latitude;
  2902. entityGeo.latitude = entityGeo.latitude - difference;
  2903. } else if (entityId === this._coordinateAxisEntityId_z) {
  2904. heightDifference = event.endPosition.y - this._coordinateAxisMoveStartScreen.y;
  2905. heightDifference = heightDifference * 0.5;
  2906. entityGeo.height = entityGeo.height - heightDifference;
  2907. }
  2908. this._coorinateAxisPosition = Cesium.Cartesian3.fromDegrees(entityGeo.longitude, entityGeo
  2909. .latitude, entityGeo.height);
  2910. this._moveEditEntityByCoordinateAxis(entityPosition, this._coorinateAxisPosition, heightDifference);
  2911. },
  2912. /**
  2913. * 坐标轴鼠标抬起事件
  2914. * @ignore 生成方法时不对外公开
  2915. * @param {Cesium.Event} event 事件
  2916. */
  2917. _coorinateAxisMouseUp: function(event) {
  2918. this._viewer.scene.screenSpaceCameraController.enableRotate = true;
  2919. if (this._editCoorinateAxis !== undefined) {
  2920. this._editCoorinateAxis.polyline.width = 10;
  2921. /* 确定最终位置 */
  2922. let translateCartesian = new Cesium.Cartesian3(150, 0, 0); //单位为米
  2923. let endPosition = this._getTranslatePostion(this._coorinateAxisPosition, translateCartesian);
  2924. this._coordinateEntity_x.polyline.positions = [this._coorinateAxisPosition, endPosition];
  2925. translateCartesian = new Cesium.Cartesian3(0, 150, 0); //单位为米
  2926. endPosition = this._getTranslatePostion(this._coorinateAxisPosition, translateCartesian);
  2927. this._coordinateEntity_y.polyline.positions = [this._coorinateAxisPosition, endPosition]
  2928. translateCartesian = new Cesium.Cartesian3(0, 0, 150); //单位为米
  2929. endPosition = this._getTranslatePostion(this._coorinateAxisPosition, translateCartesian);
  2930. this._coordinateEntity_z.polyline.positions = [this._coorinateAxisPosition, endPosition];
  2931. this._coordinateEntity_x.position = this._coorinateAxisPosition;
  2932. this._coordinateEntity_y.position = this._coorinateAxisPosition;
  2933. this._coordinateEntity_z.position = this._coorinateAxisPosition;
  2934. /* 结束并更新坐标轴绑定的实体 */
  2935. this._coordinateAxisUpdateEditEntity(this._editCoorinateAxis);
  2936. this._editCoorinateAxis = undefined;
  2937. }
  2938. },
  2939. /**
  2940. * 通过移动坐标轴移动编辑实体
  2941. * @ignore 生成方法时不对外公开
  2942. * @param {Cesium.Cartesian3} strPosition 起始位置
  2943. * @param {Cesium.Cartesian3} endPosition 终止位置
  2944. * @param {Number} heightDifference 高度差
  2945. */
  2946. _moveEditEntityByCoordinateAxis: function(strPosition, endPosition, heightDifference) {
  2947. /* 计算平移距离 */
  2948. let movePosition = Cesium.Cartesian3.subtract(endPosition, strPosition, new Cesium.Cartesian3());
  2949. for (let i = 0; i < this._moveInitPositions.length; i++) {
  2950. let moveResult = Cesium.Cartesian3.add(this._moveInitPositions[i], movePosition, new Cesium
  2951. .Cartesian3());
  2952. this._moveUpdatePositions[i] = moveResult.clone();
  2953. }
  2954. for (let i = 0; i < this._moveInitHeights.length; i++) {
  2955. this._moveUpdateHeights[i] = parseFloat(this._moveInitHeights[i]) + heightDifference * (-1);
  2956. }
  2957. },
  2958. /**
  2959. * 激活当前拖拽的坐标轴关联的实体
  2960. * @ignore 生成方法时不对外公开
  2961. * @param {Cesium.Entity} moveAxisEntity 当前拖拽的坐标轴
  2962. */
  2963. _coordinateAxisActivateEditEntity: function(moveAxisEntity) {
  2964. let _self = this;
  2965. /* 获取坐标轴绑定的实体 */
  2966. let bindEntity = moveAxisEntity.getBindEntity();
  2967. if (bindEntity === undefined) return;
  2968. let bindEntityType = bindEntity.getEntityType();
  2969. if (bindEntityType === DrawTools.DrawType.VideoWall) {
  2970. /* 初始数据集合 */
  2971. let wall = bindEntity.wall;
  2972. this._moveInitPositions = wall.positions._value;
  2973. this._moveInitHeights = wall.minimumHeights._value;
  2974. this._moveInitHeight = wall.maximumHeights._value[0] - wall.minimumHeights._value[0];
  2975. /* 平面移动数据点 */
  2976. this._moveUpdatePositions = [];
  2977. for (let i = 0; i < this._moveInitPositions.length; i++) {
  2978. this._moveUpdatePositions.push(this._moveInitPositions[i].clone());
  2979. }
  2980. /* 设置属性回调变更 */
  2981. wall.positions = new Cesium.CallbackProperty(function() {
  2982. return _self._moveUpdatePositions;
  2983. }, false);
  2984. /* 高度移动点 */
  2985. this._moveUpdateHeights = [];
  2986. for (let i = 0; i < this._moveInitHeights.length; i++) {
  2987. this._moveUpdateHeights.push(this._moveInitHeights[i]);
  2988. }
  2989. /* 设置属性回调变更 */
  2990. wall.minimumHeights = new Cesium.CallbackProperty(function() {
  2991. return _self._moveUpdateHeights;
  2992. }, false);
  2993. wall.maximumHeights = new Cesium.CallbackProperty(function() {
  2994. let maxHeights = [];
  2995. for (let i = 0; i < _self._moveUpdateHeights.length; i++) {
  2996. maxHeights.push(parseFloat(_self._moveUpdateHeights[i]) + _self
  2997. ._moveInitHeight);
  2998. }
  2999. return maxHeights;
  3000. }, false);
  3001. }
  3002. },
  3003. /**
  3004. * 更新当前坐标轴绑定的实体
  3005. * @ignore 生成方法时不对外公开
  3006. * @param {Cesium.Entity} moveAxisEntity 当前拖拽的坐标轴
  3007. */
  3008. _coordinateAxisUpdateEditEntity: function(moveAxisEntity) {
  3009. /* 获取坐标轴绑定的实体 */
  3010. let bindEntity = moveAxisEntity.getBindEntity();
  3011. if (bindEntity === undefined) return;
  3012. let bindEntityType = bindEntity.getEntityType();
  3013. if (bindEntityType === DrawTools.DrawType.VideoWall) {
  3014. /* 初始数据机 */
  3015. let wall = bindEntity.wall;
  3016. /* 更新属性 */
  3017. wall.positions = this._moveUpdatePositions;
  3018. wall.minimumHeights = this._moveUpdateHeights;
  3019. let maxHeights = [];
  3020. for (let i = 0; i < this._moveUpdateHeights.length; i++) {
  3021. maxHeights.push(parseFloat(this._moveUpdateHeights[i]) + this._moveInitHeight);
  3022. }
  3023. wall.maximumHeights = maxHeights;
  3024. }
  3025. },
  3026. /**
  3027. * 计算实体转换后的方向
  3028. * @ignore 生成方法时不对外公开
  3029. * @param {Cesium.Entity} entity 实体
  3030. * @param {JSON} options 配置项
  3031. * @param {Number} options.x 绕X轴旋转 度
  3032. * @param {Number} options.y 绕Y轴旋转 度
  3033. * @param {Number} options.z 绕Z轴旋转 度
  3034. */
  3035. _coordinateCalculateEntityOrientation: function(entity, options) {
  3036. /* 获取实体的位置 */
  3037. let position = entity.position._value;
  3038. /* 获取实体的朝向 */
  3039. let orientation = entity.orientation === undefined ? new Cesium.Cartesian3(0, 0, 0) : entity
  3040. .orientation._value;
  3041. /* 根据方向、朝向和缩放计算4*4矩阵 */
  3042. let transform = Cesium.Matrix4.fromTranslationQuaternionRotationScale(position, orientation,
  3043. new Cesium.Cartesian3(1, 1, 1), new Cesium.Matrix4());
  3044. /* 计算3个轴的3*3旋转矩阵 */
  3045. let _rotateX = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(options.x));
  3046. let _rotateY = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(options.y));
  3047. let _rotateZ = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(options.z));
  3048. /* 计算4*4旋转矩阵 */
  3049. transform = Cesium.Matrix4.multiplyByMatrix3(transform, _rotateX, transform);
  3050. transform = Cesium.Matrix4.multiplyByMatrix3(transform, _rotateY, transform);
  3051. transform = Cesium.Matrix4.multiplyByMatrix3(transform, _rotateZ, transform);
  3052. /* 4*4旋转矩阵转换为3*3旋转矩阵 */
  3053. let m3 = Cesium.Matrix4.getRotation(transform, new Cesium.Matrix3());
  3054. /* 转换旋转矩阵转换为齐次坐标 */
  3055. let resOrientation = new Cesium.Quaternion();
  3056. Cesium.Quaternion.fromRotationMatrix(m3, resOrientation);
  3057. return resOrientation;
  3058. },
  3059. /**
  3060. * 移除坐标轴
  3061. * @ignore 生成方法时不对外公开
  3062. */
  3063. _removeCoorinateAxis: function() {
  3064. if (this._coordinateAxisEntityName !== undefined) {
  3065. this._removeEntityByName(this._coordinateAxisEntityName);
  3066. }
  3067. if (this._eventCoorinateAxis !== undefined) {
  3068. this._clearEvent(this._eventCoorinateAxis);
  3069. this._eventCoorinateAxis = undefined;
  3070. }
  3071. }
  3072. });
  3073. /**
  3074. * 实体编辑相关方法
  3075. */
  3076. Object.assign(DrawTools.prototype, {
  3077. /**
  3078. * 设置实体可编辑,编辑的实体必须包含编辑类型
  3079. * @ignore 生成方法时不对外公开
  3080. * @param {Cesium.Entity} entity 编辑的实体
  3081. */
  3082. _setEntityIsEdit(entity) {
  3083. let _self = this;
  3084. /* 设置实体要素可编辑 */
  3085. entity.setIsEdit(true);
  3086. /* 先撤销编辑 */
  3087. this._unActivateEdit();
  3088. /* 激活编辑 并显示属性编辑框 */
  3089. this._sendShowPropertyDialog(entity);
  3090. /* 注册统一事件 用于单击拾取实体 */
  3091. let handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
  3092. this._registerLeftClickEvent(handler, function(event) {
  3093. /* 只要点击 就清除选中状态 */
  3094. _self._unActivateEdit();
  3095. let feature = _self._viewer.scene.pick(event.position);
  3096. if (feature !== undefined && feature.id instanceof Cesium.Entity) {
  3097. _self._sendShowPropertyDialog(feature.id);
  3098. }
  3099. })
  3100. },
  3101. /**
  3102. * 打开实体编辑对话框
  3103. * @ignore 生成方法时不对外公开
  3104. * @param {Cesium.Entity} entity
  3105. */
  3106. _sendShowPropertyDialog(entity) {
  3107. /* 获取可编辑实体的类型 */
  3108. let editEntityType = entity.getEntityType();
  3109. if (entity.getIsEdit() === undefined || entity.getIsEdit() === false ||
  3110. editEntityType === undefined) {
  3111. /* 选择的实体不可编辑 */
  3112. this._unActivateEdit();
  3113. return;
  3114. }
  3115. /* 编辑属性 */
  3116. let editProperty = entity.getParams();
  3117. if (editEntityType === DrawTools.DrawType.OdLine) {
  3118. editProperty = entity.parent.getParams();
  3119. }
  3120. this._console('选择实体的属性', editProperty);
  3121. if (editProperty !== undefined && this.onEditProperty !== undefined) {
  3122. this.onEditProperty(editProperty);
  3123. }
  3124. this._activateEdit(entity);
  3125. },
  3126. /**
  3127. * 删除当前编辑实体
  3128. */
  3129. removeEditEntity() {
  3130. if (this._editEntity !== undefined) {
  3131. this._console('移除实体', this._editEntity);
  3132. let entityType = this._editEntity.getEntityType();
  3133. if (entityType === DrawTools.DrawType.OdLine) {
  3134. let fatherEntityId = this._editEntity.parent.id;
  3135. let removeEntitys = [];
  3136. for (let entity of this._entities.values) {
  3137. if (entity.parent !== undefined && entity.parent.id === fatherEntityId) {
  3138. removeEntitys.push(entity);
  3139. }
  3140. }
  3141. for (let removeEntity of removeEntitys) {
  3142. this._removeEntityByObject(removeEntity);
  3143. }
  3144. } else {
  3145. this._removeEntityByObject(this._editEntity);
  3146. }
  3147. this._unActivateEdit();
  3148. this._editEntity = undefined;
  3149. }
  3150. },
  3151. /**
  3152. * 更新当前编辑的实体属性
  3153. * @param {JSON} params
  3154. */
  3155. updateEditEntityProperty: function(params) {
  3156. let _self = this;
  3157. if (this._editEntity === undefined) return;
  3158. if (this._editEntity.getIsEdit() === undefined || this._editEntity.getIsEdit() === false) return;
  3159. let editEntityType = this._editEntity.getEntityType();
  3160. if (editEntityType === undefined) return;
  3161. if (editEntityType === DrawTools.DrawType.NormalWall || editEntityType === DrawTools.DrawType
  3162. .DynamicWall || editEntityType === DrawTools.DrawType.TextWall) {
  3163. this._updateWallProperty(params);
  3164. } else if (editEntityType === DrawTools.DrawType.Circle || editEntityType === DrawTools.DrawType
  3165. .DynamicCircle) {
  3166. this._updateCircleProperty(params);
  3167. } else if (editEntityType === DrawTools.DrawType.House) {
  3168. this._updateHouseProperty(params);
  3169. } else if (editEntityType === DrawTools.DrawType.VideoWall) {
  3170. this._updateVideoWallProperty(params);
  3171. } else if (editEntityType === DrawTools.DrawType.Polyline) {
  3172. this._updatePolylineProperty(params);
  3173. } else if (editEntityType === DrawTools.DrawType.Polygon) {
  3174. this._updatePolygonProperty(params);
  3175. } else if (editEntityType === DrawTools.DrawType.Rectangle) {
  3176. this._updateRectangleProperty(params);
  3177. } else if (editEntityType === DrawTools.DrawType.SpatialLine) {
  3178. this._updateSpatialPolylineProperty(params);
  3179. } else if (editEntityType === DrawTools.DrawType.OdLine) {
  3180. this._updateOdlineProperty(params);
  3181. }
  3182. },
  3183. /**
  3184. * 更新OD线属性
  3185. * @ignore 不公开方法
  3186. * @param {Object} params
  3187. */
  3188. _updateOdlineProperty(params) {
  3189. let _self = this;
  3190. /* 获取父实体Id */
  3191. let fatherEntity = this._editEntity.parent;
  3192. /* 当前编辑OD线集合 */
  3193. this._editOdlineEntities = [];
  3194. /* 循环集合寻找符合条件的实体 */
  3195. for (let entity of this._entities.values) {
  3196. if (entity.parent !== undefined && entity.parent.id === fatherEntity.id) {
  3197. this._editOdlineEntities.push(entity);
  3198. }
  3199. }
  3200. let meterialImage = this._image_arrow_reverse;
  3201. if (params.order === this._param.order_add) {
  3202. meterialImage = this._image_arrow_reverse;
  3203. } else if (params.order === this._param.order_minus) {
  3204. meterialImage = this._image_arrow_forward;
  3205. }
  3206. /* 创建OD线材质 */
  3207. let odLineMaterial = new WallMaterialProperty({
  3208. viewer: _self._viewer,
  3209. trailImage: meterialImage,
  3210. duration: params.duration,
  3211. color: Cesium.Color.fromCssColorString(params.color),
  3212. param: {
  3213. direction: params.direction,
  3214. count: params.count,
  3215. order: params.order,
  3216. },
  3217. });
  3218. /* 循环处理需要编辑的实体 */
  3219. for (let entity of this._editOdlineEntities) {
  3220. entity.polyline.material = odLineMaterial;
  3221. /* 获取OD线的位置 */
  3222. let positions = entity.polyline.positions._value;
  3223. let strPoint = positions.first();
  3224. let endPoint = positions.last();
  3225. let newPositios = this._calculateOdlinePositios(strPoint, endPoint, parseInt(params.odlineHeight),
  3226. parseInt(params.odlineCount));
  3227. /* 设置OD线新位置 */
  3228. entity.polyline.positions = newPositios;
  3229. entity.polyline.width = parseInt(params.lineWidth);
  3230. }
  3231. /* 重置材质 */
  3232. fatherEntity.setParams(params);
  3233. },
  3234. /**
  3235. * 更新空间线属性
  3236. * @ignore 不公开方法
  3237. * @param {Object} params
  3238. */
  3239. _updateSpatialPolylineProperty(params) {
  3240. let material = this._editEntity.polyline.material;
  3241. let newMaterial = undefined;
  3242. if (material instanceof Cesium.ColorMaterialProperty) {
  3243. newMaterial = this._materialColorProperty({
  3244. color: params.color,
  3245. });
  3246. }
  3247. /* 设置材质 */
  3248. if (newMaterial !== undefined) this._editEntity.polyline.material = newMaterial;
  3249. this._editEntity.polyline.width = parseFloat(params.lineWidth);
  3250. /* 重新关联墙实体的属性 */
  3251. this._editEntity.setParams(params);
  3252. },
  3253. /**
  3254. * 更新矩形属性
  3255. * @ignore 不公开方法
  3256. * @param {Object} params
  3257. */
  3258. _updateRectangleProperty(params) {
  3259. let material = this._editEntity.rectangle.material;
  3260. if (material instanceof Cesium.ColorMaterialProperty) {
  3261. let newMaterial = this._materialColorProperty({
  3262. color: params.color,
  3263. });
  3264. this._editEntity.rectangle.material = newMaterial;
  3265. }
  3266. if (this._editEntity.polyline !== undefined) {
  3267. let newMaterial = this._materialColorProperty({
  3268. color: params.outlineColor,
  3269. });
  3270. this._editEntity.polyline.material = newMaterial;
  3271. this._editEntity.polyline.width = parseFloat(params.outlineWidth);
  3272. }
  3273. /* 重新关联墙实体的属性 */
  3274. this._editEntity.setParams(params);
  3275. },
  3276. /**
  3277. * 更新面的属性
  3278. * @ignore 不公开方法
  3279. * @param {Object} params
  3280. */
  3281. _updatePolygonProperty(params) {
  3282. let material = this._editEntity.polygon.material;
  3283. if (material instanceof Cesium.ColorMaterialProperty) {
  3284. let newMaterial = this._materialColorProperty({
  3285. color: params.color,
  3286. });
  3287. this._editEntity.polygon.material = newMaterial;
  3288. }
  3289. if (this._editEntity.polyline !== undefined) {
  3290. let newMaterial = this._materialColorProperty({
  3291. color: params.outlineColor,
  3292. });
  3293. this._editEntity.polyline.material = newMaterial;
  3294. this._editEntity.polyline.width = parseFloat(params.outlineWidth);
  3295. }
  3296. /* 重新关联墙实体的属性 */
  3297. this._editEntity.setParams(params);
  3298. },
  3299. /**
  3300. * 更新线的属性
  3301. * @ignore 不公开方法
  3302. * @param {Object} params
  3303. */
  3304. _updatePolylineProperty(params) {
  3305. let material = this._editEntity.polyline.material;
  3306. let newMaterial = undefined;
  3307. if (material instanceof Cesium.ColorMaterialProperty) {
  3308. newMaterial = this._materialColorProperty({
  3309. color: params.color,
  3310. });
  3311. } else if (material instanceof Cesium.PolylineArrowMaterialProperty) {
  3312. newMaterial = this._materialPolylineArrowProperty({
  3313. color: params.color,
  3314. });
  3315. } else if (material instanceof WallMaterialProperty) {
  3316. /* 设置方向对应图片 */
  3317. let materialImage = this._image_h_l_r;
  3318. if (params.order === this._param.order_minus) {
  3319. materialImage = this._image_h_r_l;
  3320. } else if (params.order === this._param.order_add) {
  3321. materialImage = this._image_h_l_r;
  3322. }
  3323. newMaterial = new WallMaterialProperty({
  3324. viewer: this._viewer,
  3325. trailImage: materialImage,
  3326. duration: params.duration,
  3327. color: Cesium.Color.fromCssColorString(params.color),
  3328. param: {
  3329. count: parseInt(params.count),
  3330. direction: params.direction,
  3331. order: params.order,
  3332. }
  3333. });
  3334. } else if (material instanceof Cesium.PolylineGlowMaterialProperty) {
  3335. newMaterial = this._materialPolylineGlowProperty({
  3336. color: params.color,
  3337. power: parseFloat(params.power),
  3338. })
  3339. } else if (material instanceof Cesium.PolylineOutlineMaterialProperty) {
  3340. newMaterial = this._materialPolylineOutlineProperty({
  3341. color: params.color,
  3342. outlineWidth: parseFloat(params.outlineWidth),
  3343. outlineColor: params.outlineColor,
  3344. })
  3345. }
  3346. /* 设置材质 */
  3347. if (newMaterial !== undefined) this._editEntity.polyline.material = newMaterial;
  3348. this._editEntity.polyline.width = params.lineWidth;
  3349. /* 重新关联墙实体的属性 */
  3350. this._editEntity.setParams(params);
  3351. },
  3352. /**
  3353. * 更新房屋属性
  3354. * @ignore 不公开方法
  3355. * @param {Object} params
  3356. */
  3357. _updateHouseProperty(params) {
  3358. let entityParams = this._editEntity.getParams();
  3359. let polygonMaterial = this._editEntity.polygon.material;
  3360. if (polygonMaterial instanceof Cesium.ColorMaterialProperty) {
  3361. let material = this._materialColorProperty({
  3362. color: params.color,
  3363. });
  3364. /* 设置材质 */
  3365. this._editEntity.polygon.material = material;
  3366. /* 设置高度 */
  3367. this._editEntity.polygon.extrudedHeight = parseFloat(params.height) + parseFloat(
  3368. entityParams.bottomHeight);
  3369. /* 重新关联墙实体的属性 */
  3370. this._editEntity.setParams(params);
  3371. }
  3372. },
  3373. /**
  3374. * 更新圆的属性
  3375. * @ignore 不公开方法
  3376. * @param {Object} params
  3377. */
  3378. _updateCircleProperty(params) {
  3379. let circleMaterial = this._editEntity.ellipse.material;
  3380. if (circleMaterial instanceof CircleMaterialProperty) {
  3381. let material = new CircleMaterialProperty({
  3382. viewer: this._viewer,
  3383. duration: params.duration,
  3384. color: Cesium.Color.fromCssColorString(params.color),
  3385. count: parseFloat(params.count),
  3386. });
  3387. this._editEntity.ellipse.material = material;
  3388. } else if (circleMaterial instanceof Cesium.ColorMaterialProperty) {
  3389. let material = this._materialColorProperty({
  3390. color: params.color,
  3391. });
  3392. this._editEntity.ellipse.material = material;
  3393. if (this._editEntity.polyline !== undefined) {
  3394. let newMaterial = this._materialColorProperty({
  3395. color: params.outlineColor,
  3396. });
  3397. this._editEntity.polyline.material = newMaterial;
  3398. this._editEntity.polyline.width = parseFloat(params.outlineWidth);
  3399. }
  3400. }
  3401. /* 重新关联墙实体的属性 */
  3402. this._editEntity.setParams(params);
  3403. },
  3404. /**
  3405. * 更新视频墙的属性
  3406. * @ignore 不公开方法
  3407. * @param {Object} params
  3408. */
  3409. _updateVideoWallProperty(params) {
  3410. /* 查找视频画布 */
  3411. let videoElement = document.getElementById('wallVideo');
  3412. if (videoElement !== null) {
  3413. document.body.removeChild(videoElement);
  3414. }
  3415. videoElement = document.createElement("video");
  3416. videoElement.id = 'wallVideo';
  3417. videoElement.setAttribute('crossorigin', 'anonymous'); //必须设置 为了防止跨域调用网络视频导致播放失败
  3418. videoElement.setAttribute("width", "1024px");
  3419. videoElement.setAttribute("height", "256px");
  3420. videoElement.setAttribute("controls", "controls");
  3421. videoElement.setAttribute("src", params.videoUrl);
  3422. videoElement.setAttribute("loop", "loop");
  3423. videoElement.play();
  3424. document.body.appendChild(videoElement);
  3425. /* 更新数据 */
  3426. let minimumHeights = this._drawEntity.wall.minimumHeights._value;
  3427. /* 更新最大高度 */
  3428. let maximumHeights = [];
  3429. for (let i = 0; i < minimumHeights.length; i++) {
  3430. maximumHeights.push(minimumHeights[i] + parseFloat(params.height));
  3431. }
  3432. this._drawEntity.wall.maximumHeights = maximumHeights;
  3433. this._drawEntity.wall.material = videoElement;
  3434. /* 重新关联墙实体的属性 */
  3435. this._editEntity.setParams(params);
  3436. },
  3437. /**
  3438. * 更新墙的属性
  3439. * @ignore 不公开方法
  3440. * @param {Object} params
  3441. */
  3442. _updateWallProperty(params) {
  3443. let minHeights = this._editEntity.wall.minimumHeights._value;
  3444. let maxHeights = [];
  3445. for (let i = 0; i < minHeights.length; i++) {
  3446. maxHeights.push(minHeights[i] + parseFloat(params.height));
  3447. }
  3448. /* 设置墙的最大高度 */
  3449. this._editEntity.wall.maximumHeights = maxHeights;
  3450. /* 更改存储墙的最大高度的数组 */
  3451. this._sketchWallMaxHeights = maxHeights;
  3452. /* 根据传入的参数id判断需什么材质 */
  3453. let wallMaterial = this._editEntity.wall.material;
  3454. if (wallMaterial instanceof Cesium.ImageMaterialProperty) {
  3455. let material = this._materialTextImageProperty({
  3456. color: params.color,
  3457. text: params.text,
  3458. });
  3459. this._editEntity.wall.material = material;
  3460. } else if (wallMaterial instanceof WallMaterialProperty) {
  3461. /* 判断使用的照片 */
  3462. let materialImage = this._image_h_l_r;
  3463. if (params.direction === this._param.direction_h && params.order === this._param.order_add) {
  3464. materialImage = this._image_h_l_r;
  3465. } else if (params.direction === this._param.direction_h && params.order === this._param.order_add) {
  3466. materialImage = this._image_h_r_l;
  3467. } else if (params.direction === this._param.direction_v && params.order === this._param
  3468. .order_minus) {
  3469. materialImage = this._image_v_t_b;
  3470. } else if (params.direction === this._param.direction_v && params.order === this._param.order_add) {
  3471. materialImage = this._image_v_b_t;
  3472. }
  3473. let material = new WallMaterialProperty({
  3474. viewer: this._viewer,
  3475. trailImage: materialImage,
  3476. duration: params.duration,
  3477. color: Cesium.Color.fromCssColorString(params.color),
  3478. param: {
  3479. count: parseFloat(params.count),
  3480. direction: params.direction,
  3481. order: params.order
  3482. }
  3483. });
  3484. this._editEntity.wall.material = material;
  3485. } else if (wallMaterial instanceof Cesium.ColorMaterialProperty) {
  3486. let material = this._materialColorProperty({
  3487. color: params.color,
  3488. });
  3489. this._editEntity.wall.material = material;
  3490. }
  3491. /* 重新关联墙实体的属性 */
  3492. this._editEntity.setParams(params);
  3493. },
  3494. /**
  3495. * 旋转实体
  3496. * @param {JSON} options 配置项
  3497. * @param {Number} options.x 绕X轴旋转 度
  3498. * @param {Number} options.y 绕Y轴旋转 度
  3499. * @param {Number} options.z 绕Z轴旋转 度
  3500. */
  3501. rotationEntity(options) {
  3502. if (this._editEntity === undefined) return;
  3503. let orientation = this._coordinateCalculateEntityOrientation(this._editEntity, options);
  3504. },
  3505. /**
  3506. * 获取实体可编辑数据
  3507. * @ignore 生成方法时不对外公开
  3508. * @param {Cesium.Entity} entity 实体
  3509. * @return {Array<Cesium.Cartesian3>} positions
  3510. */
  3511. _getEntityEditData: function(entity) {
  3512. if (entity instanceof Cesium.Entity) {
  3513. /* 获取实体的类型 */
  3514. let editEntityType = entity.getEntityType();
  3515. if (editEntityType === DrawTools.DrawType.Polyline || editEntityType === DrawTools.DrawType
  3516. .SpatialLine) {
  3517. return entity.polyline.positions._value;
  3518. } else if (editEntityType === DrawTools.DrawType.Polygon || editEntityType === DrawTools
  3519. .DrawType.House) {
  3520. let positions = entity.polygon.hierarchy._value.positions;
  3521. /* 判断是否需要加上终点 */
  3522. if (positions[0].x !== positions[positions.length - 1].x) {
  3523. positions.push(positions[0].clone());
  3524. }
  3525. return positions;
  3526. } else if (editEntityType === DrawTools.DrawType.Rectangle) {
  3527. let rect = entity.rectangle.coordinates._value;
  3528. /* 计算西北角的位置 */
  3529. let gNw = Cesium.Rectangle.northwest(rect);
  3530. if (gNw.height <= 0) {
  3531. let height = this._queryHeightFromGeo(Cesium.Math.toDegrees(gNw.longitude), Cesium.Math
  3532. .toDegrees(gNw.latitude));
  3533. gNw.height = height;
  3534. }
  3535. let cNw = Cesium.Cartesian3.fromRadians(gNw.longitude, gNw.latitude, gNw.height);
  3536. /* 计算东南角位置 */
  3537. let gSe = Cesium.Rectangle.southeast(rect);
  3538. if (gSe.height <= 0) {
  3539. let height = this._queryHeightFromGeo(Cesium.Math.toDegrees(gSe.longitude), Cesium.Math
  3540. .toDegrees(gSe.latitude));
  3541. gSe.height = height;
  3542. }
  3543. let cSe = Cesium.Cartesian3.fromRadians(gSe.longitude, gSe.latitude, gSe.height);
  3544. /* 组合坐标数组 */
  3545. return [cNw, cSe];
  3546. } else if (editEntityType === DrawTools.DrawType.Circle || editEntityType === DrawTools.DrawType
  3547. .DynamicCircle) {
  3548. /* 圆中心点位置 */
  3549. let centerPosition = entity.position._value;
  3550. /* 获取圆的半径 */
  3551. let radius = entity.ellipse.semiMajorAxis._value;
  3552. let cbPoint = this._calculateCircleBoundaryPoint(centerPosition, radius);
  3553. return [centerPosition, cbPoint];
  3554. } else if (editEntityType === DrawTools.DrawType.NormalWall || editEntityType === DrawTools
  3555. .DrawType.DynamicWall || editEntityType === DrawTools.DrawType.TextWall) {
  3556. /* 存储墙的最大高度和最小高度数组 */
  3557. this._sketchWallHeights = [];
  3558. this._sketchWallMaxHeights = [];
  3559. let minHeights = entity.wall.minimumHeights._value;
  3560. let maxHeights = entity.wall.maximumHeights._value;
  3561. for (let i = 0; i < minHeights.length; i++) {
  3562. this._sketchWallHeights.push(minHeights[i]);
  3563. this._sketchWallMaxHeights.push(maxHeights[i]);
  3564. }
  3565. return entity.wall.positions._value;
  3566. } else if (editEntityType === DrawTools.DrawType.VideoWall) {
  3567. let positions = entity.wall.positions._value;
  3568. return [positions[0].clone()];
  3569. } else {
  3570. return [];
  3571. }
  3572. } else {
  3573. return [];
  3574. }
  3575. },
  3576. /**
  3577. * 根据圆的中心点和半径计算边界点坐标位置
  3578. * @ignore 生成方法时不对外公开
  3579. * @param {Cesium.Cartesian3} centerPosition 圆的中心点位置
  3580. * @param {Number} radius 半径
  3581. * @return {Cesium.Cartesian3} boundaryPosition 边界点位置
  3582. */
  3583. _calculateCircleBoundaryPoint: function(centerPosition, radius) {
  3584. let gCenter = Cesium.Ellipsoid.WGS84.cartesianToCartographic(centerPosition);
  3585. /* 计算边界线上的点坐标 */
  3586. let cPoint = turf.point([Cesium.Math.toDegrees(gCenter.longitude), Cesium.Math.toDegrees(
  3587. gCenter.latitude)]);
  3588. let boundaryPoint = turf.destination(cPoint, radius / 1000, 90, {
  3589. units: 'kilometers'
  3590. }).geometry.coordinates;
  3591. /* 查询高度创建边界点 */
  3592. let height = this._queryHeightFromGeo(boundaryPoint[0], boundaryPoint[1]);
  3593. let cbPoint = Cesium.Cartesian3.fromDegrees(boundaryPoint[0], boundaryPoint[1], height);
  3594. return cbPoint;
  3595. },
  3596. /**
  3597. * 根据一组点计算中心点位置
  3598. * @ignore 生成方法时不对外公开
  3599. * @param {Array<Cesium.Cartesian3>} positions 点集合
  3600. */
  3601. _calculateCenterPosition: function(positions) {
  3602. if (positions === undefined || positions.length === 0) return undefined;
  3603. else if (positions.length === 1) {
  3604. return positions[0];
  3605. } else if (positions.length === 2) {
  3606. let pt0 = this._cartesian3ToGeo(positions[0]);
  3607. let pt1 = this._cartesian3ToGeo(positions[1]);
  3608. let point0 = turf.point([pt0.longitude, pt0.latitude]);
  3609. let point1 = turf.point([pt1.longitude, pt1.latitude]);
  3610. let center = turf.midpoint(point0, point1).geometry.coordinates;
  3611. /* 查询高度 */
  3612. let height = this._queryHeightFromGeo(center[0], center[1]);
  3613. /* 返回 */
  3614. return Cesium.Cartesian3.fromDegrees(center[0], center[1], height);
  3615. } else {
  3616. let geoPoints = [
  3617. []
  3618. ];
  3619. for (let i = 0; i < positions.length; i++) {
  3620. /* 将世界坐标转换为经纬度坐标 */
  3621. let geoPoint = this._cartesian3ToGeo(positions[i]);
  3622. geoPoints[0].push([geoPoint.longitude, geoPoint.latitude]);
  3623. }
  3624. geoPoints[0].push(geoPoints[0][0]);
  3625. /* 创建区域 */
  3626. let polygon = turf.polygon(geoPoints);
  3627. /* 计算中心点 */
  3628. let center = turf.centerOfMass(polygon).geometry.coordinates;
  3629. /* 查询高度 */
  3630. let height = this._queryHeightFromGeo(center[0], center[1]);
  3631. /* 返回 */
  3632. return Cesium.Cartesian3.fromDegrees(center[0], center[1], height);
  3633. }
  3634. },
  3635. /**
  3636. * 计算转换后的位置,根据角度和距离计算转换后的位置
  3637. * @ignore 生成方法时不对外公开
  3638. * @param {Cesium.Cartesian3} position 待转换位置
  3639. * @param {Number} distance 距离<距离的表示单位在options中配置>
  3640. * @param {Number} bearing 角度
  3641. * @param {JSON} options 配置项
  3642. * @return {Cesium.Cartesian3} 转换后的位置
  3643. */
  3644. _calculateTransformPosition: function(position, distance, bearing, options) {
  3645. /* 将移动点转换为经纬度格式 */
  3646. let geoPoint = this._cartesian3ToGeo(position);
  3647. /* 根据点的角度度 距离计算移动后的位置 */
  3648. let point = turf.point([geoPoint.longitude, geoPoint.latitude]);
  3649. let resPoint = turf.destination(point, distance, bearing, options).geometry
  3650. .coordinates;
  3651. /* 根据经纬度查询高度 该步骤耗时 且容易出错 */
  3652. let height = geoPoint.height;
  3653. if (options !== undefined && options.calculateHeight !== undefined && options.calculateHeight ===
  3654. true) {
  3655. height = this._queryHeightFromGeo(resPoint[0], resPoint[1]);
  3656. }
  3657. /* 将移动后的点转换为世界坐标系坐标点 */
  3658. let cPosition = Cesium.Cartesian3.fromDegrees(resPoint[0], resPoint[1],
  3659. height);
  3660. /* 返回 */
  3661. return cPosition;
  3662. },
  3663. /**
  3664. * 取消实体编辑激活状态
  3665. * @ignore 生成方法时不对外公开
  3666. */
  3667. _unActivateEdit: function() {
  3668. this._clearEditPoint();
  3669. },
  3670. /**
  3671. * 激活编辑
  3672. * @ignore 生成方法时不对外公开
  3673. * @param {Cesium.Entity} editEntity 编辑实体
  3674. */
  3675. _activateEdit: function(editEntity) {
  3676. /* 获取编辑类型 */
  3677. let entityType = editEntity.getEntityType();
  3678. /* 获取实体是否可编辑 */
  3679. let entityIsEdit = editEntity.getIsEdit();
  3680. /* 不可编辑对象 直接退出 */
  3681. if (entityIsEdit === undefined || entityType === undefined || entityIsEdit === false) {
  3682. this._console('该实体不可编辑');
  3683. return;
  3684. };
  3685. if (entityType === DrawTools.DrawType.OdLine) {
  3686. this._activeteOdlineEdit(editEntity);
  3687. } else {
  3688. this._activeteNormalEdit(editEntity);
  3689. }
  3690. },
  3691. /**
  3692. * 激活编辑OD线实体
  3693. * @ignore 生成方法时不对外公开
  3694. * @param {Cesium.Entity} editEntity 编辑实体
  3695. */
  3696. _activeteOdlineEdit: function(editEntity) {
  3697. let _self = this;
  3698. let entityType = editEntity.getEntityType();
  3699. /* 不可编辑对象 直接退出 */
  3700. if (entityType === undefined || entityType !== DrawTools.DrawType.OdLine) {
  3701. this._console('该实体不可编辑或该实体不是OD线类型');
  3702. return;
  3703. };
  3704. /* 获取父实体Id */
  3705. let faterEntityId = editEntity.parent.id;
  3706. /* 当前编辑OD线集合 */
  3707. this._editOdlineEntities = [];
  3708. /* 循环集合寻找符合条件的实体 */
  3709. for (let entity of this._entities.values) {
  3710. if (entity.parent !== undefined && entity.parent.id === faterEntityId) {
  3711. this._editOdlineEntities.push(entity);
  3712. }
  3713. }
  3714. /* 不存在可编辑的OD线 */
  3715. if (this._editOdlineEntities.length === 0) return;
  3716. /* 赋值可编辑对象 */
  3717. this._editEntity = this._editOdlineEntities[0];
  3718. for (let i = 0; i < this._editOdlineEntities.length; i++) {
  3719. let entity = this._editOdlineEntities[i];
  3720. let positions = entity.polyline.positions._value;
  3721. if (i === 0) {
  3722. this._createEditOdlineStartPoint(positions.first(), entity);
  3723. this._createEditOdlineEndPoint(positions.last(), entity);
  3724. } else {
  3725. this._createEditOdlineEndPoint(positions.last(), entity);
  3726. }
  3727. }
  3728. /* 创建事件句柄 */
  3729. if (this._sketchEditHandler === undefined) {
  3730. this._sketchEditHandler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
  3731. }
  3732. /* 注册鼠标左键按下事件 */
  3733. this._registerLeftDownEvent(this._sketchEditHandler, function(event) {
  3734. _self._eventEditMouseDown(event);
  3735. });
  3736. /* 注册鼠标左键移动事件 */
  3737. this._registerMouseMoveEvent(this._sketchEditHandler, function(event) {
  3738. _self._eventEditMouseMove(event);
  3739. });
  3740. /* 注册鼠标左键抬起事件 */
  3741. this._registerLeftUpEvent(this._sketchEditHandler, function(event) {
  3742. _self._eventEditMouseUp(event);
  3743. });
  3744. },
  3745. /**
  3746. * 激活编辑单实体
  3747. * @ignore 生成方法时不对外公开
  3748. * @param {Cesium.Entity} editEntity 编辑实体
  3749. */
  3750. _activeteNormalEdit: function(editEntity) {
  3751. let _self = this;
  3752. let positions = this._getEntityEditData(editEntity);
  3753. /* 删除所有临时绘制的点 */
  3754. this._removePointEntitys();
  3755. /* 获取编辑类型 */
  3756. let entityType = editEntity.getEntityType();
  3757. /* 赋值可编辑对象 */
  3758. this._editEntity = editEntity;
  3759. /* 创建节点和中心点 */
  3760. if (entityType === DrawTools.DrawType.Circle || entityType === DrawTools
  3761. .DrawType.DynamicCircle) {
  3762. this._createEditCenterPoint(positions[0]);
  3763. this._createEditNodePoint(positions, 1);
  3764. } else if (entityType === DrawTools.DrawType.VideoWall) {
  3765. let position = positions[0];
  3766. this._removeCoorinateAxis();
  3767. this._createCoordinateAxis(position);
  3768. } else {
  3769. this._createEditNodePoint(positions);
  3770. let centerPosition = this._calculateCenterPosition(positions);
  3771. if (centerPosition !== undefined) {
  3772. this._createEditCenterPoint(centerPosition);
  3773. }
  3774. }
  3775. /* 创建中点 */
  3776. if (entityType !== DrawTools.DrawType.Rectangle && entityType !== DrawTools
  3777. .DrawType.Circle && entityType !== DrawTools.DrawType.DynamicCircle && entityType !== DrawTools
  3778. .DrawType.VideoWall) {
  3779. if (entityType === DrawTools.DrawType.SpatialLine) {
  3780. this._createEditMiddlePoint(positions, true);
  3781. } else {
  3782. this._createEditMiddlePoint(positions);
  3783. }
  3784. }
  3785. /* 创建事件句柄 */
  3786. if (this._sketchEditHandler === undefined) {
  3787. this._sketchEditHandler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
  3788. }
  3789. /* 注册鼠标左键按下事件 */
  3790. this._registerLeftDownEvent(this._sketchEditHandler, function(event) {
  3791. _self._eventEditMouseDown(event);
  3792. })
  3793. /* 注册鼠标移动事件 */
  3794. this._registerMouseMoveEvent(this._sketchEditHandler, function(event) {
  3795. _self._eventEditMouseMove(event);
  3796. });
  3797. /* 注册鼠标抬起事件 */
  3798. this._registerLeftUpEvent(this._sketchEditHandler, function(event) {
  3799. _self._eventEditMouseUp(event);
  3800. })
  3801. },
  3802. /**
  3803. * 编辑点鼠标抬起事件
  3804. * @ignore 生成方法时不对外公开
  3805. * @param {Object} event 事件
  3806. */
  3807. _eventEditMouseDown: function(event) {
  3808. let _self = this;
  3809. /* 拾取实体 */
  3810. let feature = _self._viewer.scene.pick(event.position);
  3811. /* 分类处理 */
  3812. if (feature != undefined && feature.id instanceof Cesium.Entity) {
  3813. /* 获取选择实体的样式 */
  3814. let featureType = feature.id.getEditType();
  3815. /* 说明当前选中的实体 不是编辑点 */
  3816. if (featureType === undefined) return;
  3817. /* 禁用场景的旋转移动功能 保留缩放功能 */
  3818. _self._viewer.scene.screenSpaceCameraController.enableRotate = false;
  3819. /* 位置信息 */
  3820. let entityPosition = feature.id.position._value;
  3821. /* 保存当前可编辑的实体 */
  3822. _self._editPointEntity = feature.id;
  3823. /* 设置鼠标样式为十字 */
  3824. _self._setMousePointerStyle();
  3825. /* 判断类型 是节点或中点 进行不同的操作 */
  3826. if (featureType.type === DrawTools.EditPointType.Node || featureType.type ===
  3827. DrawTools.EditPointType.Middle) {
  3828. /* 处理鼠标按下实体的属性变更回调 */
  3829. _self._entityCallbackPropertyByMouseDown();
  3830. /* 移除当前移动的点 */
  3831. _self._removeEntityByObject(_self._editPointEntity);
  3832. /* 删除高空点 */
  3833. if (_self._sketchEditEntitySpatialName != undefined) {
  3834. _self._removeEntityByName(_self._sketchEditEntitySpatialName);
  3835. }
  3836. } else if (featureType.type === DrawTools.EditPointType.Center) {
  3837. _self._entityCenterMouseDownEvent();
  3838. } else if (featureType.type === DrawTools.EditPointType.OdlineEndNode) {
  3839. /* 删除当前移动点 */
  3840. _self._removeEntityByObject(_self._editPointEntity);
  3841. /* 设置当前编辑的实体 */
  3842. _self._editEntity = featureType.joinEntity;
  3843. /* 获取OD线的必要参数 */
  3844. let params = _self._editEntity.parent.getParams();
  3845. _self._sketchEditPoints = [];
  3846. let joinEntityPositions = _self._editEntity.polyline.positions._value;
  3847. _self._sketchEditPoints.push(joinEntityPositions.first());
  3848. _self._sketchEditPoints.push(joinEntityPositions.last());
  3849. _self._editEntity.polyline.positions = new Cesium.CallbackProperty(function() {
  3850. let positions = _self._calculateOdlinePositios(_self._sketchEditPoints[0], _self
  3851. ._sketchEditPoints[1], parseInt(params.odlineHeight), parseInt(params
  3852. .odlineCount));
  3853. return positions;
  3854. }, false)
  3855. } else if (featureType.type === DrawTools.EditPointType.OdlineStrartNode) {
  3856. /* 删除当前移动点 */
  3857. _self._removeEntityByObject(_self._editPointEntity);
  3858. /* 设置当前编辑的实体 */
  3859. _self._editEntity = featureType.joinEntity;
  3860. /* 获取OD线的必要参数 */
  3861. let params = _self._editEntity.parent.getParams();
  3862. _self._sketchEditPoints = [];
  3863. let joinEntityPositions = _self._editEntity.polyline.positions._value;
  3864. _self._sketchEditPoints.push(joinEntityPositions.first());
  3865. for (let odEntity of _self._editOdlineEntities) {
  3866. let odEntityPositions = odEntity.polyline.positions._value;
  3867. let lastPosition = odEntityPositions.last();
  3868. _self._sketchEditPoints.push(lastPosition.clone());
  3869. odEntity.polyline.positions = new Cesium.CallbackProperty(function() {
  3870. let positions = _self._calculateOdlinePositios(_self._sketchEditPoints[0],
  3871. lastPosition, parseInt(params.odlineHeight), parseInt(params
  3872. .odlineCount));
  3873. return positions;
  3874. }, false);
  3875. }
  3876. }
  3877. /* 根据节点类型不同进行特殊的处理 */
  3878. if (featureType.type === DrawTools.EditPointType.Middle) {
  3879. /* 如果选择的是中点 则插入节点 并记录当前的索引 */
  3880. let index = featureType.index;
  3881. _self._sketchEditPoints.splice(index, 0, entityPosition);
  3882. _self._sketchEditIndex = index;
  3883. /* 如果当前移动的中点为墙的中点,则需要进行特殊处理一下,主要为了修正高度 */
  3884. if (_self._sketchWallHeights != undefined && _self._sketchWallHeights.length >
  3885. 0) {
  3886. /* 查询一下高度 */
  3887. let geoPoint = _self._cartesian3ToGeo(entityPosition);
  3888. let height = _self._queryHeightFromGeo(geoPoint.longitude, geoPoint
  3889. .latitude);
  3890. /* 墙的最小高度加入值 */
  3891. _self._sketchWallHeights.splice(index, 0, height);
  3892. /* 墙的最大高度需要加入值 */
  3893. let heightDifference = _self._sketchWallMaxHeights[0] - _self
  3894. ._sketchWallHeights[0];
  3895. _self._sketchWallMaxHeights.splice(index, 0, height + heightDifference);
  3896. }
  3897. /* 设置提示标签 */
  3898. _self._tooltipInit('拖动中点,改变形状', event.position);
  3899. } else if (featureType.type === DrawTools.EditPointType.Node) {
  3900. /* 如果是节点 则直接记录索引 */
  3901. _self._sketchEditIndex = featureType.index;
  3902. /* 设置提示标签 */
  3903. _self._tooltipInit('拖动节点,改变形状', event.position);
  3904. } else if (featureType.type === DrawTools.EditPointType.Spatial) {
  3905. /* 如果是节点 则直接记录索引 */
  3906. _self._sketchEditIndex = featureType.index;
  3907. /* 设置提示标签 */
  3908. _self._tooltipInit('拖动节点,改变高度', event.position);
  3909. } else if (featureType.type === DrawTools.EditPointType.CoordinateAxis) {
  3910. /* 设置提示标签 */
  3911. _self._tooltipInit('拖动坐标轴,改变位置', event.position);
  3912. } else if (featureType.type === DrawTools.EditPointType.OdlineEndNode || featureType.type ===
  3913. DrawTools.EditPointType.OdlineStrartNode) {
  3914. /* 设置提示标签 */
  3915. _self._tooltipInit('拖动节点,改变OD线位置', event.position);
  3916. }
  3917. }
  3918. },
  3919. /**
  3920. * 编辑点鼠标移动事件
  3921. * @ignore 生成方法时不对外公开
  3922. * @param {Object} event 事件
  3923. */
  3924. _eventEditMouseMove: function(event) {
  3925. let _self = this;
  3926. if (_self._editPointEntity != undefined) {
  3927. let loc = _self._transfromFromScreenPoint(event.endPosition);
  3928. if (!Cesium.defined(loc.sLocation)) return;
  3929. _self._editPosition = loc.sLocation;
  3930. /* 获取当前可编辑点的类型 */
  3931. let editEntityType = _self._editPointEntity.getEditType();
  3932. if (editEntityType.type === DrawTools.EditPointType.Node) {
  3933. _self._sketchEditPoints[_self._sketchEditIndex] = loc.sLocation;
  3934. /* 获取当前编辑的实体的类型 */
  3935. let editEntityType = _self._editEntity.getEntityType();
  3936. if (editEntityType != DrawTools.DrawType.Rectangle &&
  3937. editEntityType != DrawTools.DrawType.Circle && editEntityType != DrawTools
  3938. .DrawType.DynamicCircle) {
  3939. /* 这里对面对象需要进特殊处理 保证第0号点和最后一个点是一致的 */
  3940. if ((editEntityType === DrawTools.DrawType.Polygon || editEntityType ===
  3941. DrawTools.DrawType.House) && _self
  3942. ._sketchEditIndex === 0) {
  3943. _self._sketchEditPoints[_self._sketchEditPoints.length - 1] = loc
  3944. .sLocation;
  3945. } else if (editEntityType === DrawTools.DrawType.NormalWall ||
  3946. editEntityType === DrawTools.DrawType.DynamicWall || editEntityType ===
  3947. DrawTools.DrawType.TextWall) {
  3948. _self._sketchWallHeights[_self._sketchEditIndex] = loc.gLocation.height;
  3949. }
  3950. /* 移除所有中点 */
  3951. _self._removeEntityByName(_self._sketchEditEntityMiddleName);
  3952. /* 创建所有中点 */
  3953. if (editEntityType === DrawTools.DrawType.SpatialLine) {
  3954. _self._createEditMiddlePoint(_self._sketchEditPoints, true);
  3955. } else {
  3956. _self._createEditMiddlePoint(_self._sketchEditPoints);
  3957. }
  3958. }
  3959. } else if (editEntityType.type === DrawTools.EditPointType.Middle) {
  3960. _self._sketchEditPoints[_self._sketchEditIndex] = loc.sLocation;
  3961. } else if (editEntityType.type === DrawTools.EditPointType.Center) {
  3962. _self._entityCenterMouseMoveEvent(event);
  3963. } else if (editEntityType.type === DrawTools.EditPointType.Spatial) {
  3964. /* 当前移动的是空中点 */
  3965. let ellipsoid = _self._viewer.scene.globe.ellipsoid;
  3966. let cartesian = _self._viewer.camera.pickEllipsoid(event.endPosition,
  3967. ellipsoid);
  3968. let bottomPoint = _self._sketchEditPoints[_self._sketchEditIndex];
  3969. /* 计算高差 */
  3970. let heightDifference = cartesian.z - bottomPoint.z;
  3971. if (heightDifference > 0 && heightDifference < 500) {
  3972. for (let i = 0; i < _self._sketchWallHeights.length; i++) {
  3973. _self._sketchWallMaxHeights[i] = _self._sketchWallHeights[i] +
  3974. heightDifference;
  3975. }
  3976. }
  3977. } else if (editEntityType.type === DrawTools.EditPointType.OdlineEndNode) {
  3978. _self._sketchEditPoints[_self._sketchEditPoints.length - 1] = loc.sLocation;
  3979. } else if (editEntityType.type === DrawTools.EditPointType.OdlineStrartNode) {
  3980. _self._sketchEditPoints[0] = loc.sLocation;
  3981. }
  3982. /* 更改标签文字 */
  3983. _self._tooltipInit('抬起鼠标,完成更改', event.endPosition);
  3984. }
  3985. },
  3986. /**
  3987. * 编辑点鼠标抬起事件
  3988. * @ignore 生成方法时不对外公开
  3989. * @param {Object} event 事件
  3990. */
  3991. _eventEditMouseUp: function(event) {
  3992. let _self = this;
  3993. if (_self._editPointEntity != undefined) {
  3994. /* 恢复所有鼠标默认事件 */
  3995. _self._viewer.scene.screenSpaceCameraController.enableRotate = true;
  3996. /* 移除标签 */
  3997. _self._tooltipRemove();
  3998. /* 恢复鼠标默认样式 */
  3999. _self._setMouseDefaultStyle();
  4000. /* 获取当前编辑的点类型 */
  4001. let editEntityPointType = _self._editPointEntity.getEditType().type;
  4002. let entityType = _self._editEntity.getEntityType();
  4003. if (editEntityPointType === DrawTools.EditPointType.CoordinateAxis) {
  4004. } else if (editEntityPointType === DrawTools.EditPointType.OdlineEndNode) {
  4005. /* 获取OD线的必要参数 */
  4006. let params = _self._editEntity.parent.getParams();
  4007. /* 重置编辑实体的位置 */
  4008. let positions = _self._calculateOdlinePositios(_self._sketchEditPoints[0], _self
  4009. ._sketchEditPoints[1], parseInt(params.odlineHeight), parseInt(params.odlineCount));
  4010. _self._editEntity.polyline.positions = positions;
  4011. /* 创建OD线的终点 */
  4012. _self._createEditOdlineEndPoint(_self._sketchEditPoints[1], _self._editEntity);
  4013. } else if (editEntityPointType === DrawTools.EditPointType.OdlineStrartNode) {
  4014. /* 获取OD线的必要参数 */
  4015. let params = _self._editEntity.parent.getParams();
  4016. let index = 1;
  4017. for (let odEntity of _self._editOdlineEntities) {
  4018. let lastPosition = _self._sketchEditPoints[index++];
  4019. let positions = _self._calculateOdlinePositios(_self._sketchEditPoints[0],
  4020. lastPosition, parseInt(params.odlineHeight), parseInt(params.odlineCount));
  4021. odEntity.polyline.positions = positions;
  4022. }
  4023. _self._createEditOdlineStartPoint(_self._sketchEditPoints[0], _self._editOdlineEntities[0]);
  4024. } else {
  4025. if (editEntityPointType === DrawTools.EditPointType.Node ||
  4026. editEntityPointType === DrawTools.EditPointType.Middle) {
  4027. /* 处理鼠标抬起实体的属性变更回调 */
  4028. _self._entityCallbackPropertyByMouseUp();
  4029. } else if (editEntityPointType === DrawTools.EditPointType.Center) {
  4030. _self._entityCenterMouseUpEvent(event);
  4031. }
  4032. /* 删除节点、中点和中心点 */
  4033. _self._removeEntityByName(_self._sketchEditEntityNodeName);
  4034. _self._removeEntityByName(_self._sketchEditEntityMiddleName);
  4035. _self._removeEntityByName(_self._sketchEditEntityCenterName);
  4036. /* 创建节点、中点和中心点 */
  4037. if (entityType === DrawTools.DrawType.Circle || entityType === DrawTools
  4038. .DrawType
  4039. .DynamicCircle) {
  4040. /* 需要对点进行特殊处理 保证圆边界点始终在统一位置 */
  4041. let centerPosition = _self._editEntity.position._value;
  4042. let boundaryPosition = _self._calculateCircleBoundaryPoint(centerPosition,
  4043. _self
  4044. ._sketchEllipseRadius);
  4045. _self._sketchEditPoints[0] = centerPosition;
  4046. _self._sketchEditPoints[1] = boundaryPosition;
  4047. _self._createEditNodePoint(_self._sketchEditPoints, 1);
  4048. _self._createEditCenterPoint(centerPosition);
  4049. } else {
  4050. /* 创建节点 */
  4051. _self._createEditNodePoint(_self._sketchEditPoints);
  4052. /* 创建中心点 */
  4053. let centerPosition = _self._calculateCenterPosition(_self
  4054. ._sketchEditPoints);
  4055. _self._createEditCenterPoint(centerPosition);
  4056. }
  4057. /* 创建中点 */
  4058. if (entityType != DrawTools.DrawType.Rectangle &&
  4059. entityType != DrawTools.DrawType.Circle && entityType != DrawTools.DrawType
  4060. .DynamicCircle) {
  4061. if (entityType === DrawTools.DrawType.SpatialLine) {
  4062. _self._createEditMiddlePoint(_self._sketchEditPoints, true);
  4063. } else {
  4064. _self._createEditMiddlePoint(_self._sketchEditPoints);
  4065. }
  4066. }
  4067. }
  4068. /* 清除选择的实体 */
  4069. _self._editPointEntity = undefined;
  4070. }
  4071. },
  4072. /**
  4073. * 实体中心点鼠标按下(拖拽点按下)
  4074. * @ignore 生成方法时不对外公开
  4075. */
  4076. _entityCenterMouseDownEvent: function() {
  4077. let _self = this;
  4078. let entityPosition = this._editEntity.position._value;
  4079. /* 删除节点、中点和中心点 */
  4080. this._removeEntityByName(this._sketchEditEntityNodeName);
  4081. this._removeEntityByName(this._sketchEditEntityMiddleName);
  4082. this._removeEntityByName(this._sketchEditEntityCenterName);
  4083. /* 记录位置 包括起始点、移动起始点(主要是为了改变位置)、和需要移动计算的全部点 */
  4084. this._startPoint = entityPosition;
  4085. this._startMovePoints = [];
  4086. this._movePoint = entityPosition;
  4087. /* 获取编辑实体的类型 */
  4088. let editEntityType = this._editEntity.getEntityType();
  4089. /* 操作的如果是圆 */
  4090. if (editEntityType === DrawTools.DrawType.Circle || editEntityType === DrawTools
  4091. .DrawType.DynamicCircle) {
  4092. /* 记录移动点为所有的圆边界点 */
  4093. if (this._editEntity.polyline !== undefined) {
  4094. for (let i = 0; i < this._ellipseOutlineCoordinates.length; i++) {
  4095. this._startMovePoints.push(this._ellipseOutlineCoordinates[i]);
  4096. }
  4097. this._editEntity.polyline.positions = new Cesium.CallbackProperty(
  4098. function() {
  4099. return _self._ellipseOutlineCoordinates;
  4100. }, false);
  4101. }
  4102. this._editEntity.position = new Cesium.CallbackProperty(function() {
  4103. return _self._movePoint;
  4104. }, false);
  4105. } else if (editEntityType === DrawTools.DrawType.Polygon || editEntityType === DrawTools.DrawType
  4106. .House) {
  4107. /* 记录移动点为所有边界点 */
  4108. for (let i = 0; i < this._sketchEditPoints.length; i++) {
  4109. this._startMovePoints.push(this._sketchEditPoints[i]);
  4110. }
  4111. /* 设置位置属性更新方式 */
  4112. _self._editEntity.polygon.hierarchy = new Cesium.CallbackProperty(function() {
  4113. return {
  4114. positions: _self._sketchEditPoints,
  4115. };
  4116. }, false);
  4117. if (_self._editEntity.polyline != undefined) {
  4118. _self._editEntity.polyline.positions = new Cesium.CallbackProperty(function() {
  4119. return _self._sketchEditPoints;
  4120. }, false);
  4121. }
  4122. } else if (editEntityType === DrawTools.DrawType.Polyline || editEntityType === DrawTools.DrawType
  4123. .SpatialLine) {
  4124. /* 记录移动点为所有边界点 */
  4125. for (let i = 0; i < this._sketchEditPoints.length; i++) {
  4126. this._startMovePoints.push(this._sketchEditPoints[i]);
  4127. }
  4128. /* 设置属性更新方法回调 */
  4129. _self._editEntity.polyline.positions = new Cesium.CallbackProperty(function() {
  4130. return _self._sketchEditPoints;
  4131. }, false);
  4132. } else if (editEntityType === DrawTools.DrawType.Rectangle) {
  4133. /* 记录移动点为所有边界点 */
  4134. for (let i = 0; i < this._sketchEditPoints.length; i++) {
  4135. this._startMovePoints.push(this._sketchEditPoints[i]);
  4136. }
  4137. /* 设置属性变更回调 */
  4138. _self._editEntity.rectangle.coordinates = new Cesium.CallbackProperty(_self
  4139. ._callUpdateRectangleCoordinates(_self
  4140. ._sketchEditPoints), false);
  4141. /* 如果存在边界线 则特殊处理 */
  4142. if (_self._editEntity.polyline != undefined) {
  4143. _self._editEntity.polyline.positions = new Cesium.CallbackProperty(_self
  4144. ._callUpdateRectangleOutlineCoordinates(),
  4145. false);
  4146. }
  4147. }
  4148. },
  4149. /**
  4150. * 实体中心点鼠标移动
  4151. * @ignore 生成方法时不对外公开
  4152. * @param {Cesium.Event} event 事件
  4153. */
  4154. _entityCenterMouseMoveEvent: function(event) {
  4155. this._calculatePositionsByCenter(event.endPosition, false);
  4156. },
  4157. /* 换个思路试试 移动过程中不计算 待移动完成后计算 以便保证移动速度 要不实时计算高度 导致卡顿 */
  4158. /**
  4159. * 计算中心拖拽点移动后实体点随之移动后的位置数据
  4160. * @ignore 生成方法时不对外公开
  4161. * @param {JSON} screenPosition 移动后的屏幕点
  4162. * @param {Boolean} calculateHeight 是否计算移动点的高度
  4163. */
  4164. _calculatePositionsByCenter: function(screenPosition, calculateHeight) {
  4165. let _self = this;
  4166. /* 起点转换为经纬度 */
  4167. let strLoc = this._cartesian3ToGeo(this._startPoint);
  4168. /* 获取终止点 */
  4169. let endLoc = this._transfromFromScreenPoint(screenPosition);
  4170. /* 计算两点之间的角度 */
  4171. var point1 = turf.point([strLoc.longitude, strLoc.latitude]);
  4172. var point2 = turf.point([endLoc.gLocation.lng, endLoc.gLocation.lat]);
  4173. var bearing = turf.bearing(point1, point2);
  4174. /* 计算亮点之间的距离 距离单位和是否计算高度*/
  4175. var options = {
  4176. units: 'kilometers',
  4177. calculateHeight: calculateHeight
  4178. };
  4179. var distance = turf.distance(point1, point2, options);
  4180. /* 根据移动的不同类型实体进行不同的操作 */
  4181. let editEntityType = this._editEntity.getEntityType();
  4182. if (editEntityType === DrawTools.DrawType.Circle || editEntityType === DrawTools
  4183. .DrawType.DynamicCircle) {
  4184. /* 循环处理所有移动点 */
  4185. for (let i = 0; i < this._startMovePoints.length; i++) {
  4186. /* 计算转换后的位置 */
  4187. let position = this._calculateTransformPosition(this._startMovePoints[i], distance, bearing,
  4188. options);
  4189. /* 更新移动点数组 */
  4190. this._ellipseOutlineCoordinates[i] = position.clone();
  4191. }
  4192. /* 更新中心位置数组 */
  4193. this._movePoint = endLoc.sLocation;
  4194. } else {
  4195. /* 循环���理所有移动点 */
  4196. for (let i = 0; i < this._startMovePoints.length; i++) {
  4197. /* 计算转换后的位置 */
  4198. let position = this._calculateTransformPosition(this._startMovePoints[i], distance, bearing,
  4199. options);
  4200. /* 更新移动点数组 */
  4201. this._sketchEditPoints[i] = position.clone();
  4202. }
  4203. }
  4204. },
  4205. /**
  4206. * 实体中心点鼠标抬起(即拖拽点)
  4207. * @ignore 生成方法时不对外公开
  4208. * @param {Object} event 事件
  4209. */
  4210. _entityCenterMouseUpEvent: function(event) {
  4211. /* 计算最新位置点 */
  4212. this._calculatePositionsByCenter(event.position, true);
  4213. let _self = this;
  4214. /* 根据不同的实体进行不同的操作 */
  4215. let editEntityType = this._editEntity.getEntityType();
  4216. if (editEntityType === DrawTools.DrawType.Circle || editEntityType === DrawTools
  4217. .DrawType.DynamicCircle) {
  4218. this._editEntity.position = this._movePoint;
  4219. if (this._editEntity.polyline !== undefined) {
  4220. this._editEntity.polyline.positions = this._ellipseOutlineCoordinates;
  4221. }
  4222. } else if (editEntityType === DrawTools.DrawType.Polyline || editEntityType === DrawTools.DrawType
  4223. .SpatialLine) {
  4224. this._editEntity.polyline.positions = this._sketchEditPoints;
  4225. } else if (editEntityType === DrawTools.DrawType.Polygon || editEntityType === DrawTools.DrawType
  4226. .House) {
  4227. this._editEntity.polygon.hierarchy = {
  4228. positions: _self._sketchEditPoints,
  4229. };
  4230. if (this._editEntity.polyline != undefined) {
  4231. this._editEntity.polyline.positions = this._sketchEditPoints;
  4232. }
  4233. } else if (editEntityType === DrawTools.DrawType.Rectangle) {
  4234. this._editEntity.rectangle.coordinates = Cesium.Rectangle.fromDegrees(_self
  4235. ._rectangleCoordinates[
  4236. 0], _self
  4237. ._rectangleCoordinates[1], _self._rectangleCoordinates[2], _self
  4238. ._rectangleCoordinates[3]);
  4239. if (this._editEntity.polyline != undefined) {
  4240. this._editEntity.polyline.positions = _self._rectangleOutlineCoordinates;
  4241. }
  4242. }
  4243. },
  4244. /**
  4245. * 处理鼠标抬起实体的属性变更回调
  4246. * @ignore 生成方法时不对外公开
  4247. */
  4248. _entityCallbackPropertyByMouseUp: function() {
  4249. let _self = this;
  4250. let entityType = _self._editEntity.getEntityType();
  4251. if (entityType === DrawTools.DrawType.Polyline) {
  4252. _self._editEntity.polyline.positions = _self._sketchEditPoints;
  4253. } else if (entityType === DrawTools.DrawType.Polygon || entityType === DrawTools.DrawType.House) {
  4254. _self._editEntity.polygon.hierarchy = {
  4255. positions: _self._sketchEditPoints,
  4256. };
  4257. /* 此处���要特殊处理一下 */
  4258. if (_self._editEntity.polyline != undefined) {
  4259. /* 如果创建区域的同时 创建了边界线 则根据区域的边界创建线 */
  4260. let polygonPositions = _self._editEntity.polygon.hierarchy._value.positions;
  4261. let linePositions = [];
  4262. for (let i = 0; i < polygonPositions.length; i++) {
  4263. linePositions.push(polygonPositions[i].clone());
  4264. }
  4265. /* 判断是否需要加入0号点 */
  4266. if (linePositions[0].x !== linePositions[linePositions.length - 1].x) {
  4267. linePositions.push(linePositions[0].clone());
  4268. }
  4269. _self._editEntity.polyline.positions = linePositions;
  4270. }
  4271. } else if (entityType === DrawTools.DrawType.Rectangle) {
  4272. _self._editEntity.rectangle.coordinates = Cesium.Rectangle.fromDegrees(_self
  4273. ._rectangleCoordinates[0], _self
  4274. ._rectangleCoordinates[1], _self._rectangleCoordinates[2], _self
  4275. ._rectangleCoordinates[3]);
  4276. /* ��������������矩形有边界线 特殊处理 */
  4277. if (_self._editEntity.polyline != undefined) {
  4278. _self._editEntity.polyline.positions = _self._rectangleOutlineCoordinates;
  4279. }
  4280. } else if (entityType === DrawTools.DrawType.Circle || entityType === DrawTools.DrawType
  4281. .DynamicCircle) {
  4282. /* 移动的是圆的点 需要特殊处理 */
  4283. _self._editEntity.ellipse.semiMajorAxis = _self._sketchEllipseRadius;
  4284. _self._editEntity.ellipse.semiMinorAxis = _self._sketchEllipseRadius;
  4285. /* 如果圆有边界线 则进行特殊处理 */
  4286. if (_self._editEntity.polyline != undefined) {
  4287. _self._editEntity.polyline.positions = _self._ellipseOutlineCoordinates;
  4288. }
  4289. } else if (entityType === DrawTools.DrawType.NormalWall || entityType === DrawTools.DrawType
  4290. .DynamicWall || entityType === DrawTools.DrawType.TextWall) {
  4291. _self._editEntity.wall.positions = _self._sketchEditPoints;
  4292. _self._editEntity.wall.minimumHeights = _self._sketchWallHeights;
  4293. _self._editEntity.wall.maximumHeights = _self._sketchWallMaxHeights;
  4294. }
  4295. },
  4296. /**
  4297. * 处理鼠标按下实体的属性变更回调
  4298. * @ignore 生成方法时不对外公开
  4299. */
  4300. _entityCallbackPropertyByMouseDown: function() {
  4301. let _self = this;
  4302. /* 更改编辑实体的坐标数据获取方式 */
  4303. let entityType = _self._editEntity.getEntityType();
  4304. if (entityType === DrawTools.DrawType.Polyline || entityType === DrawTools.DrawType.SpatialLine) {
  4305. _self._editEntity.polyline.positions = new Cesium.CallbackProperty(
  4306. function() {
  4307. return _self._sketchEditPoints;
  4308. }, false);
  4309. } else if (entityType === DrawTools.DrawType.Polygon || entityType === DrawTools.DrawType.House) {
  4310. _self._editEntity.polygon.hierarchy = new Cesium.CallbackProperty(
  4311. function() {
  4312. return {
  4313. positions: _self._sketchEditPoints,
  4314. };
  4315. }, false);
  4316. /* 此处需要特殊处理 ���断���面实体是否挂接着线 */
  4317. if (_self._editEntity.polyline != undefined) {
  4318. _self._editEntity.polyline.positions = new Cesium.CallbackProperty(
  4319. function() {
  4320. /* 如果创建区域的同时 创建了边界线 则根据区域的边界创建线 */
  4321. let polygonPositions = _self._sketchEditPoints;
  4322. let linePositions = [];
  4323. for (let i = 0; i < polygonPositions.length; i++) {
  4324. linePositions.push(polygonPositions[i].clone());
  4325. }
  4326. /* 判断是否需要加入0号点 */
  4327. if (linePositions[0].x !== linePositions[linePositions.length - 1].x) {
  4328. linePositions.push(linePositions[0].clone());
  4329. }
  4330. return linePositions;
  4331. }, false);
  4332. }
  4333. } else if (entityType === DrawTools.DrawType.Rectangle) {
  4334. _self._editEntity.rectangle.coordinates = new Cesium.CallbackProperty(_self
  4335. ._callUpdateRectangleCoordinates(_self
  4336. ._sketchEditPoints),
  4337. false);
  4338. /* 如果存在边界线则特殊处理 */
  4339. if (_self._editEntity.polyline != undefined) {
  4340. _self._editEntity.polyline.positions = new Cesium.CallbackProperty(_self
  4341. ._callUpdateRectangleOutlineCoordinates(),
  4342. false);
  4343. }
  4344. } else if (entityType === DrawTools.DrawType.Circle || entityType === DrawTools.DrawType
  4345. .DynamicCircle) {
  4346. /* 移动的是圆的点 需要特殊处理 */
  4347. if (_self._editPointEntity.getEditType().index === 1) {
  4348. _self._editEntity.ellipse.semiMajorAxis = new Cesium.CallbackProperty(
  4349. _self
  4350. ._callUpdateEllipseMinorAxis(_self._sketchEditPoints), false);
  4351. _self._editEntity.ellipse.semiMinorAxis = new Cesium.CallbackProperty(
  4352. _self
  4353. ._callUpdateEllipseMinorAxis(_self._sketchEditPoints), false);
  4354. }
  4355. /* 如果圆有边界线 则进行特殊���理 */
  4356. if (_self._editEntity.polyline != undefined) {
  4357. _self._editEntity.polyline.positions = new Cesium.CallbackProperty(
  4358. _self._callEllipseOutlineCoordinate(_self
  4359. ._sketchEditPoints), false);
  4360. }
  4361. } else if (entityType === DrawTools.DrawType.NormalWall || entityType === DrawTools.DrawType
  4362. .DynamicWall || entityType === DrawTools.DrawType.TextWall) {
  4363. /* 位置属性变更 */
  4364. _self._editEntity.wall.positions = new Cesium.CallbackProperty(function() {
  4365. return _self._sketchEditPoints;
  4366. }, false);
  4367. /* 高度属性变更 */
  4368. _self._editEntity.wall.minimumHeights = new Cesium.CallbackProperty(function() {
  4369. return _self._sketchWallHeights;
  4370. }, false);
  4371. _self._editEntity.wall.maximumHeights = new Cesium.CallbackProperty(function() {
  4372. return _self._sketchWallMaxHeights;
  4373. }, false);
  4374. }
  4375. },
  4376. /**
  4377. * 创建编辑点
  4378. * @ignore 生成方法时不对外公开
  4379. * @param {JSON} options 配置项
  4380. * @param {Cesium.Cartesian3} options.position 位置<必须填写>
  4381. * @param {Array<Number>} options.color [颜色] 可选
  4382. * @param {Number} options.size [大小] 可选
  4383. * @param {Number} options.outlineWidth [边框大小] 可选
  4384. * @param {Array<Number>} options.outlineColor [边框颜色] 可选
  4385. * @param {DrawTools.EditPointType} options.editType 编辑点类型<必须填写>
  4386. * @param {String} options.name [实体的名称] 可选
  4387. */
  4388. _createEditPointEntity(options) {
  4389. let _self = this;
  4390. if (options === undefined || options.position === undefined) return;
  4391. if (options === undefined || options.editType === undefined) return;
  4392. /* 初始化参数 */
  4393. let color = options.color != undefined ? options.color : [255, 0, 0, 1.0];
  4394. let size = options.size != undefined && typeof options.size === 'number' ? options.size : 9;
  4395. let outlineWidth = options.outlineWidth != undefined && typeof options.outlineWidth === 'number' ?
  4396. options.outlineWidth : 1;
  4397. let outlineColor = options.outlineColor != undefined ? options.outlineColor : [255, 255, 255, 1.0];
  4398. /* 创建编辑点 */
  4399. let pointEntity = new Cesium.Entity({
  4400. name: options.name != undefined ? options.name : _self._sketchEntityName,
  4401. position: options.position,
  4402. point: {
  4403. show: true,
  4404. pixelSize: size,
  4405. heightReference: Cesium.HeightReference.NONE,
  4406. color: _self._toColorFromArray(color),
  4407. outlineWidth: outlineWidth,
  4408. outlineColor: _self._toColorFromArray(outlineColor),
  4409. disableDepthTestDistance: 1.5e12, //小于该数值后关闭深度检测默认为空
  4410. // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
  4411. },
  4412. })
  4413. /* 这是�����型 */
  4414. pointEntity.setEditType(options.editType);
  4415. /* 追加到集合中 */
  4416. _self._entities.add(pointEntity);
  4417. },
  4418. /**
  4419. * 创建可编辑�����节点
  4420. * @ignore 生成方法时不对外公开
  4421. * @param {Array<Cesium.Cartesian3>} positions 坐标集合
  4422. * @param {Number} startIndex [开始索引] 可选 默认为0
  4423. */
  4424. _createEditNodePoint(positions, startIndex) {
  4425. this._sketchEditEntityNodeName = "SketchEditEntityNode";
  4426. let _self = this;
  4427. /* 创建节点 */
  4428. this._sketchEditPoints = [];
  4429. /* 判断开始创建索引 */
  4430. let strIndex = startIndex === undefined ? 0 : startIndex;
  4431. for (let i = 0; i < positions.length; i++) {
  4432. /* 获取当前点 */
  4433. let position = positions[i];
  4434. /* 存储可编辑点 */
  4435. this._sketchEditPoints.push(position.clone());
  4436. /* 小于索引不会创建 */
  4437. if (i < strIndex) continue;
  4438. /* 为了保证不重复创建节点 需���进行特殊过滤处理 */
  4439. if (i !== 0 && position.x === positions[0].x && position.y === positions[0].y && position.z ===
  4440. positions[0]
  4441. .z) {
  4442. continue;
  4443. }
  4444. /* 创建节点前 特殊处理一下 以保证创建的节点 高度是正确的 */
  4445. let geoPoint = this._cartesian3ToGeo(position);
  4446. /* 查询高度 */
  4447. let height = this._queryHeightFromGeo(geoPoint.longitude, geoPoint.latitude);
  4448. /* 创建新位置 */
  4449. let newPosition = Cesium.Cartesian3.fromDegrees(geoPoint.longitude, geoPoint.latitude, height);
  4450. /* 创建实体 */
  4451. _self._createEditPointEntity({
  4452. name: _self._sketchEditEntityNodeName,
  4453. position: newPosition,
  4454. size: 12,
  4455. color: [0, 0, 255, 1.0],
  4456. editType: {
  4457. type: DrawTools.EditPointType.Node,
  4458. index: i,
  4459. },
  4460. });
  4461. }
  4462. },
  4463. /**
  4464. * 创建可编辑的空中点
  4465. * @ignore 生成方法时不对外公开
  4466. * @param {Array<Cesium.Cartesian3>} positions 底部坐标集合
  4467. * @param {Array<Number>} heights 高���集合
  4468. * @param {Number} startIndex [开始索引] 可选 默认为0
  4469. */
  4470. _createEditSpatialPoint(positions, heights, startIndex) {
  4471. /* 暂时不创建高空点 */
  4472. return;
  4473. if (positions === undefined || heights === undefined) return;
  4474. if (positions.length === undefined || heights.length === undefined) return;
  4475. if (heights.length < positions.length) return;
  4476. this._sketchEditEntitySpatialName = "SketchEditEntitySpatial";
  4477. let _self = this;
  4478. /* 判断开始创建索引 */
  4479. let strIndex = startIndex === undefined ? 0 : startIndex;
  4480. for (let i = 0; i < positions.length; i++) {
  4481. /* 获取当前点 */
  4482. let p = positions[i];
  4483. /* 当前点转换为经纬度 */
  4484. let geoPoint = this._cartesian3ToGeo(p);
  4485. /* 重新获取新的空间位置 */
  4486. let position = Cesium.Cartesian3.fromDegrees(geoPoint.longitude, geoPoint.latitude, heights[i]);
  4487. /* 小于索引不会创建 */
  4488. if (i < strIndex) continue;
  4489. /* 创建实体 */
  4490. this._createEditPointEntity({
  4491. name: _self._sketchEditEntitySpatialName,
  4492. position: position,
  4493. size: 12,
  4494. color: [255, 0, 0, 1.0],
  4495. editType: {
  4496. type: DrawTools.EditPointType.Spatial,
  4497. index: i,
  4498. },
  4499. });
  4500. }
  4501. },
  4502. /**
  4503. * 创建可编辑的中点
  4504. * @ignore 生成方法时不对外公开
  4505. * @param {Array<Cesium.Cartesian3>} positions 坐标集合
  4506. * @param {Boolean} isSpatial 是否是空中点
  4507. */
  4508. _createEditMiddlePoint(positions, isSpatial = false) {
  4509. this._sketchEditEntityMiddleName = "SketchEditEntityMiddle";
  4510. let _self = this;
  4511. if (!isSpatial) {
  4512. /* 创建中点 */
  4513. for (let i = 1; i < positions.length; i++) {
  4514. let p1 = positions[i - 1];
  4515. let p2 = positions[i];
  4516. /* 计算中点 */
  4517. let pCenter = this._calculateMiddlePoint(p1, p2);
  4518. /* 创建中点实体 */
  4519. this._createEditPointEntity({
  4520. name: _self._sketchEditEntityMiddleName,
  4521. position: pCenter,
  4522. size: 9,
  4523. color: [255, 255, 0, 1.0],
  4524. editType: {
  4525. type: DrawTools.EditPointType.Middle,
  4526. index: i
  4527. },
  4528. });
  4529. }
  4530. } else {
  4531. /* 创建中点 */
  4532. for (let i = 1; i < positions.length; i++) {
  4533. let p1 = positions[i - 1];
  4534. let p2 = positions[i];
  4535. /* 计算中点 */
  4536. let pCenter = {
  4537. x: (p1.x + p2.x) / 2,
  4538. y: (p1.y + p2.y) / 2,
  4539. z: (p1.z + p2.z) / 2,
  4540. };
  4541. /* 创建中点实体 */
  4542. this._createEditPointEntity({
  4543. name: _self._sketchEditEntityMiddleName,
  4544. position: pCenter,
  4545. size: 9,
  4546. color: [255, 255, 0, 1.0],
  4547. editType: {
  4548. type: DrawTools.EditPointType.Middle,
  4549. index: i
  4550. },
  4551. });
  4552. }
  4553. }
  4554. },
  4555. /**
  4556. * 创建可编辑的中心点
  4557. * @ignore 生成方法时不对外公开
  4558. * @param {Cesium.Cartesian3} position 坐标
  4559. */
  4560. _createEditCenterPoint(position) {
  4561. let _self = this;
  4562. this._sketchEditEntityCenterName = "SketchEditEntityCenter";
  4563. /* 创建实体 */
  4564. this._createEditPointEntity({
  4565. name: _self._sketchEditEntityCenterName,
  4566. position: position,
  4567. size: 12,
  4568. color: [0, 255, 0, 0.1],
  4569. outlineWidth: 2.0,
  4570. outlineColor: [255, 255, 255, 1.0],
  4571. editType: {
  4572. type: DrawTools.EditPointType.Center,
  4573. },
  4574. });
  4575. /* 创建中心点的同时将中心点付给当前的编辑实体 */
  4576. if (this._editEntity != undefined) {
  4577. this._editEntity.position = position.clone();
  4578. }
  4579. },
  4580. /**
  4581. * 创建可编辑的OD线编辑终点
  4582. * @ignore 生成方法时不对外公开
  4583. * @param {Cesium.Cartesian3} position 坐标
  4584. * @param {Cesium.Entity} joinEntity 关联的实体
  4585. */
  4586. _createEditOdlineEndPoint(position, joinEntity) {
  4587. this._sketchEditEntityNodeName = "SketchEditEntityNode";
  4588. let _self = this;
  4589. /* 创建节点前 特殊处理一下 以保证创建的节点 高度是正确的 */
  4590. let geoPoint = this._cartesian3ToGeo(position);
  4591. /* 查询高度 */
  4592. let height = this._queryHeightFromGeo(geoPoint.longitude, geoPoint.latitude);
  4593. /* 创建新位置 */
  4594. let newPosition = Cesium.Cartesian3.fromDegrees(geoPoint.longitude, geoPoint.latitude, height);
  4595. /* 创建实体 */
  4596. _self._createEditPointEntity({
  4597. name: _self._sketchEditEntityNodeName,
  4598. position: position,
  4599. size: 12,
  4600. color: [0, 0, 255, 1.0],
  4601. editType: {
  4602. type: DrawTools.EditPointType.OdlineEndNode,
  4603. joinEntity: joinEntity,
  4604. },
  4605. });
  4606. },
  4607. /**
  4608. * 创建可编辑的OD线编辑起点
  4609. * @ignore 生成方法时不对外公开
  4610. * @param {Cesium.Cartesian3} position 坐标
  4611. * @param {Cesium.Entity} joinEntity 关联的实体
  4612. */
  4613. _createEditOdlineStartPoint(position, joinEntity) {
  4614. this._sketchEditEntityNodeName = "SketchEditEntityNode";
  4615. let _self = this;
  4616. /* 创建节点前 特殊处理一下 以保证创建的节点 高度是正确的 */
  4617. let geoPoint = this._cartesian3ToGeo(position);
  4618. /* 查询高度 */
  4619. let height = this._queryHeightFromGeo(geoPoint.longitude, geoPoint.latitude);
  4620. /* 创建新位置 */
  4621. let newPosition = Cesium.Cartesian3.fromDegrees(geoPoint.longitude, geoPoint.latitude, height);
  4622. /* 创建实体 */
  4623. _self._createEditPointEntity({
  4624. name: _self._sketchEditEntityNodeName,
  4625. position: position,
  4626. size: 12,
  4627. color: [0, 255, 0, 0.6],
  4628. editType: {
  4629. type: DrawTools.EditPointType.OdlineStrartNode,
  4630. joinEntity: joinEntity,
  4631. },
  4632. });
  4633. },
  4634. /**
  4635. * 计算两个点的中点坐标
  4636. * @ignore 生成方法时不对外公开
  4637. * @param {Cesium.Cartesian3} position1 第一点
  4638. * @param {Cesium.Cartesian3} position2 第二点
  4639. */
  4640. _calculateMiddlePoint(position1, position2) {
  4641. /* 计算经纬度坐标 */
  4642. let g1 = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position1);
  4643. let g2 = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position2);
  4644. /* 转换为度格式 */
  4645. let pt1 = [Cesium.Math.toDegrees(g1.longitude), Cesium.Math.toDegrees(g1.latitude)];
  4646. let pt2 = [Cesium.Math.toDegrees(g2.longitude), Cesium.Math.toDegrees(g2.latitude)];
  4647. /* 计算中间点 */
  4648. let tpt1 = turf.point(pt1);
  4649. let tpt2 = turf.point(pt2);
  4650. let midpoint = turf.midpoint(tpt1, tpt2).geometry.coordinates;
  4651. /* 查询高度 */
  4652. let height = this._queryHeightFromGeo(midpoint[0], midpoint[1]);
  4653. /* 转换为世界坐标 */
  4654. let result = Cesium.Cartesian3.fromDegrees(midpoint[0], midpoint[1], height);
  4655. return result;
  4656. },
  4657. /**
  4658. * 世界坐标转换为经纬度坐标
  4659. * @ignore 生成方法时不对外公开
  4660. * @param {Cesium.Cartesian3} position 点
  4661. */
  4662. _cartesian3ToGeo: function(position) {
  4663. let g = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position);
  4664. return {
  4665. longitude: Cesium.Math.toDegrees(g.longitude),
  4666. latitude: Cesium.Math.toDegrees(g.latitude),
  4667. height: g.height,
  4668. }
  4669. },
  4670. /**
  4671. * 查询指定经纬度位置的高度 有地形则查地形 有模型则查模型 查询错误或未查询到,返回0
  4672. * @ignore 生成方法时不对外公开
  4673. * @param {Number} longitude 经度<度格式>
  4674. * @param {Number} latitude 纬度<度格式>
  4675. * @return {Number} 查询位置的高度值
  4676. */
  4677. _queryHeightFromGeo: function(longitude, latitude) {
  4678. if (longitude === undefined || latitude === undefined || typeof longitude != 'number' ||
  4679. typeof latitude != 'number') return 0;
  4680. let rLng = Cesium.Math.toRadians(longitude);
  4681. let rLat = Cesium.Math.toRadians(latitude);
  4682. let cartographic = new Cesium.Cartographic(rLng, rLat);
  4683. /* 获取不采样的实体数组 */
  4684. let noQueryEntities = [];
  4685. for (let i = 0; i < this._entities.values.length; i++) {
  4686. if (this._entities.values[i].name === this._sketchEntityName) {
  4687. noQueryEntities.push(this._entities.values[i]);
  4688. }
  4689. }
  4690. let height = this._viewer.scene.sampleHeight(cartographic, noQueryEntities);
  4691. if (height === undefined) return 0
  4692. else return height;
  4693. },
  4694. /**
  4695. * 查询指定经纬度位置的高度 有地形则查地形 有模型则查模型 查询错误或未查询到,返回0
  4696. * @ignore 生成方法时不对外公开
  4697. * @param {Number} longitude 经度<度格式>
  4698. * @param {Number} latitude 纬度<度格式>
  4699. * @param {Function} callComplete 查询回调函数callComplete(Number) 查询错误时为undefined
  4700. */
  4701. _queryHeightFromGeoAsync: function(longitude, latitude, callComplete) {
  4702. if (longitude === undefined || latitude === undefined || typeof longitude != 'number' ||
  4703. typeof latitude != 'number') return 0;
  4704. let rLng = Cesium.Math.toRadians(longitude);
  4705. let rLat = Cesium.Math.toRadians(latitude);
  4706. let cartographic = new Cesium.Cartographic(rLng, rLat);
  4707. let promise = this._viewer.scene.sampleHeightMostDetailed([cartographic]);
  4708. promise.then(function(updatedPositions) {
  4709. if (callComplete) callComplete(updatedPositions[0].height);
  4710. })
  4711. },
  4712. /**
  4713. * 清理编辑点
  4714. * @ignore 生成方法时不对外公开
  4715. */
  4716. _clearEditPoint: function() {
  4717. /* 清理事件句柄 */
  4718. if (this._sketchEditHandler != undefined) {
  4719. this._sketchEditHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN);
  4720. this._sketchEditHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP);
  4721. this._sketchEditHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  4722. }
  4723. /* 处理理编辑点数据 */
  4724. this._sketchEditPoints = [];
  4725. this._sketchEditIndex = undefined;
  4726. this._editEntity = undefined;
  4727. this._removeEntityByName(this._sketchEditEntityNodeName);
  4728. this._removeEntityByName(this._sketchEditEntityMiddleName);
  4729. this._removeEntityByName(this._sketchEditEntityCenterName);
  4730. this._removeEntityByName(this._sketchEditEntitySpatialName);
  4731. },
  4732. })
  4733. /* 编辑函数相关 */
  4734. Object.assign(DrawTools.prototype, {
  4735. /**
  4736. * 检查颜色值
  4737. * @ignore 生成方法时不对外公开
  4738. * @param {Number} color 颜色值[0~255]
  4739. * @return {Boolean} 是否满足颜色值要求
  4740. */
  4741. _checkColor: function(color) {
  4742. if (color === undefined || color === null) return false;
  4743. if (typeof color != 'number') return false;
  4744. let intColor = parseInt(color);
  4745. if (intColor < 0 || intColor > 255) return false;
  4746. return true;
  4747. },
  4748. /**
  4749. * 检查透明度是否符合要求
  4750. * @ignore 生成方法时不对外公开
  4751. * @param {Object} alpha 透明度[0~1]
  4752. */
  4753. _checkAlpha: function(alpha) {
  4754. if (alpha === undefined || alpha === null) return false;
  4755. if (typeof alpha != 'number') return false;
  4756. let floatAlpha = parseFloat(alpha);
  4757. if (floatAlpha < 0 || floatAlpha > 1) return false;
  4758. return true;
  4759. },
  4760. /**
  4761. * 颜色和透明度检测
  4762. * @ignore 生成方法时不对外公开
  4763. * @param {Array<Number>} colorAndAlpah 颜���和透明度
  4764. * @return {Array<Number>} [0~255,0~255,0~255,0~1] 如果异常 则�����回undefined
  4765. */
  4766. _checkColorAndAlpha: function(colorAndAlpah) {
  4767. let setColor = undefined;
  4768. if (!colorAndAlpah || colorAndAlpah.length === undefined || colorAndAlpah.length === 0)
  4769. return undefined;
  4770. if (colorAndAlpah.length === 1 && this._checkColor(colorAndAlpah[0])) {
  4771. setColor = [colorAndAlpah[0], 0, 0, 1.0];
  4772. } else if (colorAndAlpah.length === 2 && this._checkColor(colorAndAlpah[0]) && this._checkColor(
  4773. colorAndAlpah[1])) {
  4774. setColor = [colorAndAlpah[0], colorAndAlpah[1], 0, 1.0];
  4775. } else if (colorAndAlpah.length === 3 && this._checkColor(colorAndAlpah[0]) && this._checkColor(
  4776. colorAndAlpah[1]) && this._checkColor(colorAndAlpah[2])) {
  4777. setColor = [colorAndAlpah[0], colorAndAlpah[1], colorAndAlpah[2], 1.0];
  4778. } else if (colorAndAlpah.length === 4 && this._checkColor(colorAndAlpah[0]) && this._checkColor(
  4779. colorAndAlpah[1]) && this._checkColor(colorAndAlpah[2]) && this._checkAlpha(
  4780. colorAndAlpah[
  4781. 3])) {
  4782. setColor = [colorAndAlpah[0], colorAndAlpah[1], colorAndAlpah[2], colorAndAlpah[3]];
  4783. }
  4784. return setColor;
  4785. },
  4786. });
  4787. /**
  4788. * 绘制类型
  4789. */
  4790. DrawTools.DrawType = Object.freeze({
  4791. Point: 'point',
  4792. Polyline: 'polyline', //贴地线
  4793. ArrowPolyline: 'arrowPolyline', //箭头线
  4794. DynamicPolyline: 'dynamicPolyline', //流动线
  4795. GrowPolyline: '发光线',
  4796. OutlinePolyline: 'outlinePolyline', //描边线
  4797. OdLine: 'odLine', //OD线
  4798. Polygon: 'polygon', //贴地面
  4799. SpatialLine: 'spatialLine', //空间线
  4800. Circle: 'circle', //普通圆
  4801. DynamicCircle: 'dynamicCircle', //动态圆
  4802. Rectangle: 'rectangle', //矩形
  4803. NormalWall: 'normalWall', //普通墙
  4804. DynamicWall: 'dynamicWall', //动态墙
  4805. House: 'house', //房屋
  4806. TextWall: 'text', //文字
  4807. VideoWall: 'videoWall', //视频墙
  4808. })
  4809. /**
  4810. * 点图标类型
  4811. */
  4812. DrawTools.IconType = Object.freeze({
  4813. Normal: 'normal',
  4814. Blue: 'blue',
  4815. Green: 'green',
  4816. Violet: 'violter',
  4817. })
  4818. /**
  4819. * 编辑点类型
  4820. */
  4821. DrawTools.EditPointType = Object.freeze({
  4822. Node: 'node', //节点
  4823. Middle: 'middle', //中间点
  4824. Center: 'center', //中心点
  4825. CoordinateAxis: 'coordinateAxis', //坐标轴
  4826. OdlineStrartNode: 'odlineStartNode', //OD线起始点
  4827. OdlineEndNode: 'odlineEndNode', //OD线终点
  4828. })
  4829. /**
  4830. * 绘制墙的类型
  4831. */
  4832. DrawTools.WallType = Object.freeze({
  4833. ColorWall: 'colorWall', //颜色墙
  4834. DynamicWall: 'dynamicWall', //动态墙
  4835. TextWall: 'textWall', //文字墙
  4836. })
  4837. /**
  4838. * 绘制圆类型
  4839. */
  4840. DrawTools.CircleType = Object.freeze({
  4841. ColorCircle: 'colorCircle', //颜色圆
  4842. DynamicCircle: 'dynamicCircle', //动态圆
  4843. })
  4844. /**
  4845. * 绘制线类型
  4846. */
  4847. DrawTools.PolylineType = Object.freeze({
  4848. NormalPolyline: 'normalPolyline', //普通线
  4849. ArrowsPolyline: 'arrowsPolyline', //箭头线
  4850. DynamicPolyline: 'dynamicPolyline', //流动线
  4851. DottedPolyline: 'dottedPolyline', //虚线
  4852. GrowPolyline: 'growPolyline', //发光线
  4853. OutlinePolyline: 'outlinePolyline', //描边线
  4854. })
  4855. /**
  4856. * 绘制面类型
  4857. */
  4858. DrawTools.PolygonType = Object.freeze({
  4859. NormalPolygon: 'normalPolygon', //贴地面
  4860. HousePolygon: 'housePolygon', //拉伸贴地面
  4861. })
  4862. class WallMaterialProperty {
  4863. /**
  4864. * 构造方法
  4865. * @ignore 无需公开
  4866. * @param {JSON} options 配置项
  4867. * @param {Cesium.Viewer} options.viewer 着色器运行所需的视图
  4868. * @param {Cesium.Color} options.color [墙的颜色,默认蓝色] 可选
  4869. * @param {Number} options.duration [循环时间 默认1000] 可选
  4870. * @param {String} options.trailImage 墙的贴图
  4871. * @param {JSON} options.param 着色器参数
  4872. * @param {Number} options.param.count [数量 可选 默认为1]
  4873. * @param {String} options.param.direction [方向 可选 默认竖直 ] 取值vertical/horizontal
  4874. * @param {String} options.param.order [顺序 可选 上下/下上/顺时针/逆时针 与方向配合使用 ] 取值+/-
  4875. */
  4876. constructor(options) {
  4877. /* 着色器运行依赖的视图 */
  4878. this._viewer = options.viewer;
  4879. /* 变更事件 */
  4880. this._definitionChanged = new Cesium.Event();
  4881. this._color = undefined;
  4882. /* 墙的颜色 */
  4883. this.color = options.color || Cesium.Color.BLUE;
  4884. /* 动态循环周期 */
  4885. this.duration = options.duration || 1000;
  4886. /* 墙的贴图 */
  4887. this.trailImage = options.trailImage;
  4888. /* 默认时间 */
  4889. this._time = (new Date()).getTime();
  4890. /* 材质类型名称 */
  4891. this._materialTypeName = 'WallMaterial' + this._guid();
  4892. /* 存储相关参数的属性 以便后期进行追踪修改 */
  4893. this._param = {
  4894. color: this.color._value.toCssColorString(),
  4895. image: this.trailImage,
  4896. duration: this.duration,
  4897. count: 0,
  4898. direction: '',
  4899. order: '',
  4900. }
  4901. /* 将材质加入缓存 以便重复利用 */
  4902. Cesium.Material._materialCache.addMaterial(this._materialTypeName, {
  4903. fabric: {
  4904. type: this._materialTypeName,
  4905. uniforms: {
  4906. time: -20,
  4907. color: new Cesium.Color(1.0, 0.0, 0.0, 0.5),
  4908. image: options.trailImage,
  4909. },
  4910. source: this._getDirectionWallShader(options.param)
  4911. },
  4912. translucent: function(material) {
  4913. /* 材质是否半透明 */
  4914. return true;
  4915. }
  4916. });
  4917. }
  4918. /**
  4919. * 生成GUID随机数
  4920. * @ignore 无需公开
  4921. */
  4922. _guid() {
  4923. function S4() {
  4924. return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
  4925. }
  4926. return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
  4927. }
  4928. /**
  4929. * 重新获取类型方法
  4930. * @ignore 无需公开
  4931. * @param {Cesium.JulianDate} time 时间
  4932. */
  4933. getType(time) {
  4934. return this._materialTypeName;
  4935. }
  4936. /**
  4937. * 重写获取值方法
  4938. * @ignore 无需公开
  4939. * @param {Cesium.JulianDate} time
  4940. * @param {JSON} result
  4941. */
  4942. getValue(time, result) {
  4943. if (!Cesium.defined(result)) {
  4944. result = {};
  4945. }
  4946. result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.BLUE, result.color);
  4947. result.image = this.trailImage;
  4948. if (this.duration) {
  4949. result.time = (((new Date()).getTime() - this._time) % this.duration) / this.duration;
  4950. }
  4951. this._viewer.scene.requestRender();
  4952. return result;
  4953. }
  4954. /**
  4955. * 重写对比函数
  4956. * @ignore 无需公开
  4957. * @param {Object} other 传入对比对象
  4958. */
  4959. equals(other) {
  4960. return (this === other || (other instanceof WallMaterialProperty && Cesium.Property.equals(this
  4961. ._color, other._color) && other._param.order === this._param.order && other._param.count ===
  4962. this._param.count && other._param.direction === this._param.direction && other.duration === this
  4963. .duration));
  4964. }
  4965. /**
  4966. * 创建着色器资源
  4967. * @ignore 无需公开
  4968. * @param {JSON} options 配置项
  4969. * @param {Number} options.count [数量 可选 默认为1]
  4970. * @param {String} options.direction [方向 可选 默认竖直 ] 取值vertical/horizontal
  4971. * @param {String} options.order [顺序 可选 上下/下上/顺时针/逆时针 与方向配合使用 ] 取值+/-
  4972. */
  4973. _getDirectionWallShader(options) {
  4974. let op = Cesium.defaultValue(options, {});
  4975. // console.log('>>>op===', op);
  4976. let count = op.count !== undefined && typeof op.count === 'number' && op.count > 0 ? op
  4977. .count : 1;
  4978. let direction = op.direction === 'horizontal' ? 'horizontal' : 'vertical';
  4979. let order = op.order === '+' ? '+' : '-';
  4980. this._param.count = count;
  4981. this._param.direction = direction;
  4982. this._param.order = order;
  4983. let materail = '';
  4984. /* 补充参数 */
  4985. // console.log(this._param);
  4986. materail += 'czm_material czm_getMaterial(czm_materialInput materialInput){\n' +
  4987. ' czm_material material = czm_getDefaultMaterial(materialInput);\n' +
  4988. ' vec2 st = materialInput.st;\n';
  4989. if (direction === 'vertical') {
  4990. materail += ' vec4 colorImage = texture2D(image,vec2(st.s,fract(float(' + count + ')*st.t ' + order +
  4991. ' time)));\n';
  4992. } else if (direction === 'horizontal') {
  4993. materail += ' vec4 colorImage = texture2D(image, vec2(fract(float(' + count + ')*st.s ' + order +
  4994. ' time), st.t));\n'
  4995. }
  4996. materail += ' vec4 fragColor;\n' +
  4997. ' fragColor.rgb = color.rgb / 1.0;\n' +
  4998. ' fragColor = czm_gammaCorrect(fragColor);\n' +
  4999. ' material.alpha = colorImage.a * color.a;\n' +
  5000. ' material.diffuse = color.rgb;\n' +
  5001. ' material.emission = fragColor.rgb;\n' +
  5002. ' return material;\n' +
  5003. '}';
  5004. return materail;
  5005. }
  5006. }
  5007. /**
  5008. * 增加默认属性
  5009. */
  5010. Object.defineProperties(WallMaterialProperty.prototype, {
  5011. /**
  5012. * @ignore 无需公开
  5013. * 判断是否相等,返回false表示属性一直在变化中
  5014. */
  5015. isConstant: {
  5016. get: function() {
  5017. return false;
  5018. }
  5019. },
  5020. /**
  5021. * @ignore 无需公开
  5022. * 事件变更
  5023. */
  5024. definitionChanged: {
  5025. get: function() {
  5026. return this._definitionChanged;
  5027. }
  5028. },
  5029. /* 颜色属性 */
  5030. color: Cesium.createPropertyDescriptor('color')
  5031. })
  5032. /**
  5033. * 创建者:王成
  5034. * 操作系统:MAC
  5035. * 创建日期:2022年12月29日
  5036. * 描述:动态扩散圆材质
  5037. */
  5038. class CircleMaterialProperty {
  5039. /**
  5040. * 构造方法
  5041. * @ignore 无需公开
  5042. * @param {JSON} options 配置项
  5043. * @param {Cesium.Viewer} options.viewer 着色器运行所需的视图
  5044. * @param {Cesium.Color} options.color [圆环的颜色,默认蓝色] 可选
  5045. * @param {Number} options.duration [循环时间 默认1000] 可选
  5046. * @param {Number} options.count [圆环的数量 可选 默认为1]
  5047. */
  5048. constructor(options) {
  5049. /* 着色器运行依赖的视图 */
  5050. this._viewer = options.viewer;
  5051. /* 变更事件 */
  5052. this._definitionChanged = new Cesium.Event();
  5053. this._color = undefined;
  5054. /* 扩算圆环的颜色 */
  5055. this.color = options.color || Cesium.Color.BLUE;
  5056. /* 扩散圆环的数量 */
  5057. this.count = options.count || 1.0;
  5058. /* 动态循环周期 */
  5059. this.duration = options.duration || 1000;
  5060. /* 默认时间 */
  5061. this._time = (new Date()).getTime();
  5062. /* 材质类型名称 */
  5063. this._materialTypeName = 'jtCircleMaterial'
  5064. /* 存储相关参数的属性 以便后期进行追踪修改 */
  5065. this._param = {
  5066. color: this.color._value.toCssColorString(),
  5067. duration: this.duration,
  5068. count: this.count,
  5069. }
  5070. /* 将材质加入缓存 以便重复利用 */
  5071. Cesium.Material._materialCache.addMaterial(this._materialTypeName, {
  5072. fabric: {
  5073. type: this._materialTypeName,
  5074. uniforms: {
  5075. time: 0,
  5076. color: new Cesium.Color(1.0, 0.0, 0.0, 0.5),
  5077. count: 1.0,
  5078. },
  5079. source: this._getCircleMaterial(),
  5080. },
  5081. translucent: function(material) {
  5082. /* 材质是否半透明 */
  5083. return true;
  5084. }
  5085. });
  5086. }
  5087. /**
  5088. * @ignore 无需公开
  5089. * 获取材质着色器Shader
  5090. */
  5091. _getCircleMaterial() {
  5092. let circleMaterial = "czm_material czm_getMaterial(czm_materialInput materialInput)\n" +
  5093. "{\n" +
  5094. " czm_material material = czm_getDefaultMaterial(materialInput);\n" +
  5095. " material.diffuse = 1.5 * color.rgb;\n" +
  5096. " vec2 st = materialInput.st;\n" +
  5097. " vec3 str = materialInput.str;\n" +
  5098. " float dis = distance(st, vec2(0.5, 0.5));\n" +
  5099. " float per = fract(time);\n" +
  5100. " if (abs(str.z) > 0.001)\n" +
  5101. " {\n" +
  5102. " //着色器渲染停止,不在绘制内容 \n" +
  5103. " discard;\n" +
  5104. " }\n" +
  5105. " if (dis > 0.5)\n" +
  5106. " {\n" +
  5107. " //超出半径范围时,着色器渲染停止 \n" +
  5108. " discard;\n" +
  5109. " } else {\n" +
  5110. " //把半径分成count份,每两份之间的间隔距离 \n" +
  5111. " float perDis = 0.5 / count;\n" +
  5112. " float disNum;\n" +
  5113. " float bl = 0.0;\n" +
  5114. " //循环,最多999个环 \n" +
  5115. " for (int i = 0; i <= 999; i++)\n" +
  5116. " {\n" +
  5117. " //判断是否属于数量内的环 \n" +
  5118. " if (float(i) <= count)\n" +
  5119. " {\n" +
  5120. " disNum = perDis * float(i) - dis + per / count;\n" +
  5121. " if (disNum > 0.0)\n" +
  5122. " {\n" +
  5123. " if (disNum < perDis)\n" +
  5124. " {\n" +
  5125. " bl = 1.0 - disNum / perDis;\n" +
  5126. " } else if (disNum - perDis < perDis) {\n" +
  5127. " bl = 1.0 - abs(1.0 - disNum / perDis);\n" +
  5128. " }\n" +
  5129. " material.alpha = color.a * pow(bl, 3.0);\n" +
  5130. " }\n" +
  5131. " }\n" +
  5132. " }\n" +
  5133. " }\n" +
  5134. " return material;\n" +
  5135. "}\n";
  5136. return circleMaterial;
  5137. }
  5138. }
  5139. /**
  5140. * @ignore 无需公开
  5141. * 必须重写的方法
  5142. */
  5143. Object.assign(CircleMaterialProperty.prototype, {
  5144. /**
  5145. * 重新获取类型方法
  5146. * @ignore 无需公开
  5147. * @param {Cesium.JulianDate} time 时间
  5148. */
  5149. getType: function(time) {
  5150. return this._materialTypeName;
  5151. },
  5152. /**
  5153. * 重写获取值方法
  5154. * @ignore 无需公开
  5155. * @param {Cesium.JulianDate} time
  5156. * @param {JSON} result
  5157. */
  5158. getValue: function(time, result) {
  5159. if (!Cesium.defined(result)) {
  5160. result = {};
  5161. }
  5162. result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.BLUE, result
  5163. .color);
  5164. result.count = this.count;
  5165. if (this.duration) {
  5166. result.time = (((new Date()).getTime() - this._time) % this.duration) / this.duration;
  5167. }
  5168. this._viewer.scene.requestRender();
  5169. return result;
  5170. },
  5171. /**
  5172. * 重写对比函数
  5173. * @ignore 无需公开
  5174. * @param {Object} other 传入对比对象
  5175. */
  5176. equals: function(other) {
  5177. return (this === other || (other instanceof CircleMaterialProperty && Cesium.Property.equals(this
  5178. ._color, other._color)));
  5179. }
  5180. })
  5181. /**
  5182. * 默认属性
  5183. */
  5184. Object.defineProperties(CircleMaterialProperty.prototype, {
  5185. /**
  5186. * 判断是否相等,返回false表示属性一直在变化中
  5187. * @ignore 无需公开
  5188. */
  5189. isConstant: {
  5190. get: function() {
  5191. return false;
  5192. }
  5193. },
  5194. /**
  5195. * 事件变更
  5196. * @ignore 无需公开
  5197. */
  5198. definitionChanged: {
  5199. get: function() {
  5200. return this._definitionChanged;
  5201. }
  5202. },
  5203. /* 颜色属性 */
  5204. color: Cesium.createPropertyDescriptor('color')
  5205. })
  5206. /* 输出 */
  5207. export {
  5208. DrawTools
  5209. }