map23dlib-nolib.js 906 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758
  1. ;(function (window, document, undefined) {
  2. window.map23DVersion = '2.1.16'
  3. if (typeof module === 'object' && typeof module.exports === 'object') {
  4. module.exports = map23DVersion;
  5. } else if (typeof define === 'function' && define.amd) {
  6. define(map23DVersion);
  7. }
  8. }(window, document));
  9. /*
  10. Leaflet 1.0.2+4bbb16c, a JS library for interactive maps. http://leafletjs.com
  11. (c) 2010-2016 Vladimir Agafonkin, (c) 2010-2011 CloudMade
  12. */
  13. !function(t,e,i){function n(){var e=t.L;o.noConflict=function(){return t.L=e,this},t.L=o}var o={version:"1.0.2+4bbb16c"};"object"==typeof module&&"object"==typeof module.exports?module.exports=o:"function"==typeof define&&define.amd&&define(o),"undefined"!=typeof t&&n(),o.Util={extend:function(t){var e,i,n,o;for(i=1,n=arguments.length;i<n;i++){o=arguments[i];for(e in o)t[e]=o[e]}return t},create:Object.create||function(){function t(){}return function(e){return t.prototype=e,new t}}(),bind:function(t,e){var i=Array.prototype.slice;if(t.bind)return t.bind.apply(t,i.call(arguments,1));var n=i.call(arguments,2);return function(){return t.apply(e,n.length?n.concat(i.call(arguments)):arguments)}},stamp:function(t){return t._leaflet_id=t._leaflet_id||++o.Util.lastId,t._leaflet_id},lastId:0,throttle:function(t,e,i){var n,o,s,r;return r=function(){n=!1,o&&(s.apply(i,o),o=!1)},s=function(){n?o=arguments:(t.apply(i,arguments),setTimeout(r,e),n=!0)}},wrapNum:function(t,e,i){var n=e[1],o=e[0],s=n-o;return t===n&&i?t:((t-o)%s+s)%s+o},falseFn:function(){return!1},formatNum:function(t,e){var i=Math.pow(10,e||5);return Math.round(t*i)/i},trim:function(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")},splitWords:function(t){return o.Util.trim(t).split(/\s+/)},setOptions:function(t,e){t.hasOwnProperty("options")||(t.options=t.options?o.Util.create(t.options):{});for(var i in e)t.options[i]=e[i];return t.options},getParamString:function(t,e,i){var n=[];for(var o in t)n.push(encodeURIComponent(i?o.toUpperCase():o)+"="+encodeURIComponent(t[o]));return(e&&e.indexOf("?")!==-1?"&":"?")+n.join("&")},template:function(t,e){return t.replace(o.Util.templateRe,function(t,n){var o=e[n];if(o===i)throw new Error("No value provided for variable "+t);return"function"==typeof o&&(o=o(e)),o})},templateRe:/\{ *([\w_\-]+) *\}/g,isArray:Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)},indexOf:function(t,e){for(var i=0;i<t.length;i++)if(t[i]===e)return i;return-1},emptyImageUrl:"data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="},function(){function e(e){return t["webkit"+e]||t["moz"+e]||t["ms"+e]}function i(e){var i=+new Date,o=Math.max(0,16-(i-n));return n=i+o,t.setTimeout(e,o)}var n=0,s=t.requestAnimationFrame||e("RequestAnimationFrame")||i,r=t.cancelAnimationFrame||e("CancelAnimationFrame")||e("CancelRequestAnimationFrame")||function(e){t.clearTimeout(e)};o.Util.requestAnimFrame=function(e,n,r){return r&&s===i?void e.call(n):s.call(t,o.bind(e,n))},o.Util.cancelAnimFrame=function(e){e&&r.call(t,e)}}(),o.extend=o.Util.extend,o.bind=o.Util.bind,o.stamp=o.Util.stamp,o.setOptions=o.Util.setOptions,o.Class=function(){},o.Class.extend=function(t){var e=function(){this.initialize&&this.initialize.apply(this,arguments),this.callInitHooks()},i=e.__super__=this.prototype,n=o.Util.create(i);n.constructor=e,e.prototype=n;for(var s in this)this.hasOwnProperty(s)&&"prototype"!==s&&(e[s]=this[s]);return t.statics&&(o.extend(e,t.statics),delete t.statics),t.includes&&(o.Util.extend.apply(null,[n].concat(t.includes)),delete t.includes),n.options&&(t.options=o.Util.extend(o.Util.create(n.options),t.options)),o.extend(n,t),n._initHooks=[],n.callInitHooks=function(){if(!this._initHooksCalled){i.callInitHooks&&i.callInitHooks.call(this),this._initHooksCalled=!0;for(var t=0,e=n._initHooks.length;t<e;t++)n._initHooks[t].call(this)}},e},o.Class.include=function(t){return o.extend(this.prototype,t),this},o.Class.mergeOptions=function(t){return o.extend(this.prototype.options,t),this},o.Class.addInitHook=function(t){var e=Array.prototype.slice.call(arguments,1),i="function"==typeof t?t:function(){this[t].apply(this,e)};return this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(i),this},o.Evented=o.Class.extend({on:function(t,e,i){if("object"==typeof t)for(var n in t)this._on(n,t[n],e);else{t=o.Util.splitWords(t);for(var s=0,r=t.length;s<r;s++)this._on(t[s],e,i)}return this},off:function(t,e,i){if(t)if("object"==typeof t)for(var n in t)this._off(n,t[n],e);else{t=o.Util.splitWords(t);for(var s=0,r=t.length;s<r;s++)this._off(t[s],e,i)}else delete this._events;return this},_on:function(t,e,n){this._events=this._events||{};var o=this._events[t];o||(o=[],this._events[t]=o),n===this&&(n=i);for(var s={fn:e,ctx:n},r=o,a=0,h=r.length;a<h;a++)if(r[a].fn===e&&r[a].ctx===n)return;r.push(s),o.count++},_off:function(t,e,n){var s,r,a;if(this._events&&(s=this._events[t])){if(!e){for(r=0,a=s.length;r<a;r++)s[r].fn=o.Util.falseFn;return void delete this._events[t]}if(n===this&&(n=i),s)for(r=0,a=s.length;r<a;r++){var h=s[r];if(h.ctx===n&&h.fn===e)return h.fn=o.Util.falseFn,this._firingCount&&(this._events[t]=s=s.slice()),void s.splice(r,1)}}},fire:function(t,e,i){if(!this.listens(t,i))return this;var n=o.Util.extend({},e,{type:t,target:this});if(this._events){var s=this._events[t];if(s){this._firingCount=this._firingCount+1||1;for(var r=0,a=s.length;r<a;r++){var h=s[r];h.fn.call(h.ctx||this,n)}this._firingCount--}}return i&&this._propagateEvent(n),this},listens:function(t,e){var i=this._events&&this._events[t];if(i&&i.length)return!0;if(e)for(var n in this._eventParents)if(this._eventParents[n].listens(t,e))return!0;return!1},once:function(t,e,i){if("object"==typeof t){for(var n in t)this.once(n,t[n],e);return this}var s=o.bind(function(){this.off(t,e,i).off(t,s,i)},this);return this.on(t,e,i).on(t,s,i)},addEventParent:function(t){return this._eventParents=this._eventParents||{},this._eventParents[o.stamp(t)]=t,this},removeEventParent:function(t){return this._eventParents&&delete this._eventParents[o.stamp(t)],this},_propagateEvent:function(t){for(var e in this._eventParents)this._eventParents[e].fire(t.type,o.extend({layer:t.target},t),!0)}});var s=o.Evented.prototype;s.addEventListener=s.on,s.removeEventListener=s.clearAllEventListeners=s.off,s.addOneTimeEventListener=s.once,s.fireEvent=s.fire,s.hasEventListeners=s.listens,o.Mixin={Events:s},function(){var i=navigator.userAgent.toLowerCase(),n=e.documentElement,s="ActiveXObject"in t,r=i.indexOf("webkit")!==-1,a=i.indexOf("phantom")!==-1,h=i.search("android [23]")!==-1,l=i.indexOf("chrome")!==-1,u=i.indexOf("gecko")!==-1&&!r&&!t.opera&&!s,c=0===navigator.platform.indexOf("Win"),d="undefined"!=typeof orientation||i.indexOf("mobile")!==-1,_=!t.PointerEvent&&t.MSPointerEvent,m=t.PointerEvent||_,p=s&&"transition"in n.style,f="WebKitCSSMatrix"in t&&"m11"in new t.WebKitCSSMatrix&&!h,g="MozPerspective"in n.style,v="OTransition"in n.style,y=!t.L_NO_TOUCH&&(m||"ontouchstart"in t||t.DocumentTouch&&e instanceof t.DocumentTouch);o.Browser={ie:s,ielt9:s&&!e.addEventListener,edge:"msLaunchUri"in navigator&&!("documentMode"in e),webkit:r,gecko:u,android:i.indexOf("android")!==-1,android23:h,chrome:l,safari:!l&&i.indexOf("safari")!==-1,win:c,ie3d:p,webkit3d:f,gecko3d:g,opera12:v,any3d:!t.L_DISABLE_3D&&(p||f||g)&&!v&&!a,mobile:d,mobileWebkit:d&&r,mobileWebkit3d:d&&f,mobileOpera:d&&t.opera,mobileGecko:d&&u,touch:!!y,msPointer:!!_,pointer:!!m,retina:(t.devicePixelRatio||t.screen.deviceXDPI/t.screen.logicalXDPI)>1}}(),o.Point=function(t,e,i){this.x=i?Math.round(t):t,this.y=i?Math.round(e):e},o.Point.prototype={clone:function(){return new o.Point(this.x,this.y)},add:function(t){return this.clone()._add(o.point(t))},_add:function(t){return this.x+=t.x,this.y+=t.y,this},subtract:function(t){return this.clone()._subtract(o.point(t))},_subtract:function(t){return this.x-=t.x,this.y-=t.y,this},divideBy:function(t){return this.clone()._divideBy(t)},_divideBy:function(t){return this.x/=t,this.y/=t,this},multiplyBy:function(t){return this.clone()._multiplyBy(t)},_multiplyBy:function(t){return this.x*=t,this.y*=t,this},scaleBy:function(t){return new o.Point(this.x*t.x,this.y*t.y)},unscaleBy:function(t){return new o.Point(this.x/t.x,this.y/t.y)},round:function(){return this.clone()._round()},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this},floor:function(){return this.clone()._floor()},_floor:function(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this},ceil:function(){return this.clone()._ceil()},_ceil:function(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this},distanceTo:function(t){t=o.point(t);var e=t.x-this.x,i=t.y-this.y;return Math.sqrt(e*e+i*i)},equals:function(t){return t=o.point(t),t.x===this.x&&t.y===this.y},contains:function(t){return t=o.point(t),Math.abs(t.x)<=Math.abs(this.x)&&Math.abs(t.y)<=Math.abs(this.y)},toString:function(){return"Point("+o.Util.formatNum(this.x)+", "+o.Util.formatNum(this.y)+")"}},o.point=function(t,e,n){return t instanceof o.Point?t:o.Util.isArray(t)?new o.Point(t[0],t[1]):t===i||null===t?t:"object"==typeof t&&"x"in t&&"y"in t?new o.Point(t.x,t.y):new o.Point(t,e,n)},o.Bounds=function(t,e){if(t)for(var i=e?[t,e]:t,n=0,o=i.length;n<o;n++)this.extend(i[n])},o.Bounds.prototype={extend:function(t){return t=o.point(t),this.min||this.max?(this.min.x=Math.min(t.x,this.min.x),this.max.x=Math.max(t.x,this.max.x),this.min.y=Math.min(t.y,this.min.y),this.max.y=Math.max(t.y,this.max.y)):(this.min=t.clone(),this.max=t.clone()),this},getCenter:function(t){return new o.Point((this.min.x+this.max.x)/2,(this.min.y+this.max.y)/2,t)},getBottomLeft:function(){return new o.Point(this.min.x,this.max.y)},getTopRight:function(){return new o.Point(this.max.x,this.min.y)},getSize:function(){return this.max.subtract(this.min)},contains:function(t){var e,i;return t="number"==typeof t[0]||t instanceof o.Point?o.point(t):o.bounds(t),t instanceof o.Bounds?(e=t.min,i=t.max):e=i=t,e.x>=this.min.x&&i.x<=this.max.x&&e.y>=this.min.y&&i.y<=this.max.y},intersects:function(t){t=o.bounds(t);var e=this.min,i=this.max,n=t.min,s=t.max,r=s.x>=e.x&&n.x<=i.x,a=s.y>=e.y&&n.y<=i.y;return r&&a},overlaps:function(t){t=o.bounds(t);var e=this.min,i=this.max,n=t.min,s=t.max,r=s.x>e.x&&n.x<i.x,a=s.y>e.y&&n.y<i.y;return r&&a},isValid:function(){return!(!this.min||!this.max)}},o.bounds=function(t,e){return!t||t instanceof o.Bounds?t:new o.Bounds(t,e)},o.Transformation=function(t,e,i,n){this._a=t,this._b=e,this._c=i,this._d=n},o.Transformation.prototype={transform:function(t,e){return this._transform(t.clone(),e)},_transform:function(t,e){return e=e||1,t.x=e*(this._a*t.x+this._b),t.y=e*(this._c*t.y+this._d),t},untransform:function(t,e){return e=e||1,new o.Point((t.x/e-this._b)/this._a,(t.y/e-this._d)/this._c)}},o.DomUtil={get:function(t){return"string"==typeof t?e.getElementById(t):t},getStyle:function(t,i){var n=t.style[i]||t.currentStyle&&t.currentStyle[i];if((!n||"auto"===n)&&e.defaultView){var o=e.defaultView.getComputedStyle(t,null);n=o?o[i]:null}return"auto"===n?null:n},create:function(t,i,n){var o=e.createElement(t);return o.className=i||"",n&&n.appendChild(o),o},remove:function(t){var e=t.parentNode;e&&e.removeChild(t)},empty:function(t){for(;t.firstChild;)t.removeChild(t.firstChild)},toFront:function(t){t.parentNode.appendChild(t)},toBack:function(t){var e=t.parentNode;e.insertBefore(t,e.firstChild)},hasClass:function(t,e){if(t.classList!==i)return t.classList.contains(e);var n=o.DomUtil.getClass(t);return n.length>0&&new RegExp("(^|\\s)"+e+"(\\s|$)").test(n)},addClass:function(t,e){if(t.classList!==i)for(var n=o.Util.splitWords(e),s=0,r=n.length;s<r;s++)t.classList.add(n[s]);else if(!o.DomUtil.hasClass(t,e)){var a=o.DomUtil.getClass(t);o.DomUtil.setClass(t,(a?a+" ":"")+e)}},removeClass:function(t,e){t.classList!==i?t.classList.remove(e):o.DomUtil.setClass(t,o.Util.trim((" "+o.DomUtil.getClass(t)+" ").replace(" "+e+" "," ")))},setClass:function(t,e){t.className.baseVal===i?t.className=e:t.className.baseVal=e},getClass:function(t){return t.className.baseVal===i?t.className:t.className.baseVal},setOpacity:function(t,e){"opacity"in t.style?t.style.opacity=e:"filter"in t.style&&o.DomUtil._setOpacityIE(t,e)},_setOpacityIE:function(t,e){var i=!1,n="DXImageTransform.Microsoft.Alpha";try{i=t.filters.item(n)}catch(t){if(1===e)return}e=Math.round(100*e),i?(i.Enabled=100!==e,i.Opacity=e):t.style.filter+=" progid:"+n+"(opacity="+e+")"},testProp:function(t){for(var i=e.documentElement.style,n=0;n<t.length;n++)if(t[n]in i)return t[n];return!1},setTransform:function(t,e,i){var n=e||new o.Point(0,0);t.style[o.DomUtil.TRANSFORM]=(o.Browser.ie3d?"translate("+n.x+"px,"+n.y+"px)":"translate3d("+n.x+"px,"+n.y+"px,0)")+(i?" scale("+i+")":"")},setPosition:function(t,e){t._leaflet_pos=e,o.Browser.any3d?o.DomUtil.setTransform(t,e):(t.style.left=e.x+"px",t.style.top=e.y+"px")},getPosition:function(t){return t._leaflet_pos||new o.Point(0,0)}},function(){o.DomUtil.TRANSFORM=o.DomUtil.testProp(["transform","WebkitTransform","OTransform","MozTransform","msTransform"]);var i=o.DomUtil.TRANSITION=o.DomUtil.testProp(["webkitTransition","transition","OTransition","MozTransition","msTransition"]);if(o.DomUtil.TRANSITION_END="webkitTransition"===i||"OTransition"===i?i+"End":"transitionend","onselectstart"in e)o.DomUtil.disableTextSelection=function(){o.DomEvent.on(t,"selectstart",o.DomEvent.preventDefault)},o.DomUtil.enableTextSelection=function(){o.DomEvent.off(t,"selectstart",o.DomEvent.preventDefault)};else{var n=o.DomUtil.testProp(["userSelect","WebkitUserSelect","OUserSelect","MozUserSelect","msUserSelect"]);o.DomUtil.disableTextSelection=function(){if(n){var t=e.documentElement.style;this._userSelect=t[n],t[n]="none"}},o.DomUtil.enableTextSelection=function(){n&&(e.documentElement.style[n]=this._userSelect,delete this._userSelect)}}o.DomUtil.disableImageDrag=function(){o.DomEvent.on(t,"dragstart",o.DomEvent.preventDefault)},o.DomUtil.enableImageDrag=function(){o.DomEvent.off(t,"dragstart",o.DomEvent.preventDefault)},o.DomUtil.preventOutline=function(e){for(;e.tabIndex===-1;)e=e.parentNode;e&&e.style&&(o.DomUtil.restoreOutline(),this._outlineElement=e,this._outlineStyle=e.style.outline,e.style.outline="none",o.DomEvent.on(t,"keydown",o.DomUtil.restoreOutline,this))},o.DomUtil.restoreOutline=function(){this._outlineElement&&(this._outlineElement.style.outline=this._outlineStyle,delete this._outlineElement,delete this._outlineStyle,o.DomEvent.off(t,"keydown",o.DomUtil.restoreOutline,this))}}(),o.LatLng=function(t,e,n){if(isNaN(t)||isNaN(e))throw new Error("Invalid LatLng object: ("+t+", "+e+")");this.lat=+t,this.lng=+e,n!==i&&(this.alt=+n)},o.LatLng.prototype={equals:function(t,e){if(!t)return!1;t=o.latLng(t);var n=Math.max(Math.abs(this.lat-t.lat),Math.abs(this.lng-t.lng));return n<=(e===i?1e-9:e)},toString:function(t){return"LatLng("+o.Util.formatNum(this.lat,t)+", "+o.Util.formatNum(this.lng,t)+")"},distanceTo:function(t){return o.CRS.Earth.distance(this,o.latLng(t))},wrap:function(){return o.CRS.Earth.wrapLatLng(this)},toBounds:function(t){var e=180*t/40075017,i=e/Math.cos(Math.PI/180*this.lat);return o.latLngBounds([this.lat-e,this.lng-i],[this.lat+e,this.lng+i])},clone:function(){return new o.LatLng(this.lat,this.lng,this.alt)}},o.latLng=function(t,e,n){return t instanceof o.LatLng?t:o.Util.isArray(t)&&"object"!=typeof t[0]?3===t.length?new o.LatLng(t[0],t[1],t[2]):2===t.length?new o.LatLng(t[0],t[1]):null:t===i||null===t?t:"object"==typeof t&&"lat"in t?new o.LatLng(t.lat,"lng"in t?t.lng:t.lon,t.alt):e===i?null:new o.LatLng(t,e,n)},o.LatLngBounds=function(t,e){if(t)for(var i=e?[t,e]:t,n=0,o=i.length;n<o;n++)this.extend(i[n])},o.LatLngBounds.prototype={extend:function(t){var e,i,n=this._southWest,s=this._northEast;if(t instanceof o.LatLng)e=t,i=t;else{if(!(t instanceof o.LatLngBounds))return t?this.extend(o.latLng(t)||o.latLngBounds(t)):this;if(e=t._southWest,i=t._northEast,!e||!i)return this}return n||s?(n.lat=Math.min(e.lat,n.lat),n.lng=Math.min(e.lng,n.lng),s.lat=Math.max(i.lat,s.lat),s.lng=Math.max(i.lng,s.lng)):(this._southWest=new o.LatLng(e.lat,e.lng),this._northEast=new o.LatLng(i.lat,i.lng)),this},pad:function(t){var e=this._southWest,i=this._northEast,n=Math.abs(e.lat-i.lat)*t,s=Math.abs(e.lng-i.lng)*t;return new o.LatLngBounds(new o.LatLng(e.lat-n,e.lng-s),new o.LatLng(i.lat+n,i.lng+s))},getCenter:function(){return new o.LatLng((this._southWest.lat+this._northEast.lat)/2,(this._southWest.lng+this._northEast.lng)/2)},getSouthWest:function(){return this._southWest},getNorthEast:function(){return this._northEast},getNorthWest:function(){return new o.LatLng(this.getNorth(),this.getWest())},getSouthEast:function(){return new o.LatLng(this.getSouth(),this.getEast())},getWest:function(){return this._southWest.lng},getSouth:function(){return this._southWest.lat},getEast:function(){return this._northEast.lng},getNorth:function(){return this._northEast.lat},contains:function(t){t="number"==typeof t[0]||t instanceof o.LatLng?o.latLng(t):o.latLngBounds(t);var e,i,n=this._southWest,s=this._northEast;return t instanceof o.LatLngBounds?(e=t.getSouthWest(),i=t.getNorthEast()):e=i=t,e.lat>=n.lat&&i.lat<=s.lat&&e.lng>=n.lng&&i.lng<=s.lng},intersects:function(t){t=o.latLngBounds(t);var e=this._southWest,i=this._northEast,n=t.getSouthWest(),s=t.getNorthEast(),r=s.lat>=e.lat&&n.lat<=i.lat,a=s.lng>=e.lng&&n.lng<=i.lng;return r&&a},overlaps:function(t){t=o.latLngBounds(t);var e=this._southWest,i=this._northEast,n=t.getSouthWest(),s=t.getNorthEast(),r=s.lat>e.lat&&n.lat<i.lat,a=s.lng>e.lng&&n.lng<i.lng;return r&&a},toBBoxString:function(){return[this.getWest(),this.getSouth(),this.getEast(),this.getNorth()].join(",")},equals:function(t){return!!t&&(t=o.latLngBounds(t),this._southWest.equals(t.getSouthWest())&&this._northEast.equals(t.getNorthEast()))},isValid:function(){return!(!this._southWest||!this._northEast)}},o.latLngBounds=function(t,e){return t instanceof o.LatLngBounds?t:new o.LatLngBounds(t,e)},o.Projection={},o.Projection.LonLat={project:function(t){return new o.Point(t.lng,t.lat)},unproject:function(t){return new o.LatLng(t.y,t.x)},bounds:o.bounds([-180,-90],[180,90])},o.Projection.SphericalMercator={R:6378137,MAX_LATITUDE:85.0511287798,project:function(t){var e=Math.PI/180,i=this.MAX_LATITUDE,n=Math.max(Math.min(i,t.lat),-i),s=Math.sin(n*e);return new o.Point(this.R*t.lng*e,this.R*Math.log((1+s)/(1-s))/2)},unproject:function(t){var e=180/Math.PI;return new o.LatLng((2*Math.atan(Math.exp(t.y/this.R))-Math.PI/2)*e,t.x*e/this.R)},bounds:function(){var t=6378137*Math.PI;return o.bounds([-t,-t],[t,t])}()},o.CRS={latLngToPoint:function(t,e){var i=this.projection.project(t),n=this.scale(e);return this.transformation._transform(i,n)},pointToLatLng:function(t,e){var i=this.scale(e),n=this.transformation.untransform(t,i);return this.projection.unproject(n)},project:function(t){return this.projection.project(t)},unproject:function(t){return this.projection.unproject(t)},scale:function(t){return 256*Math.pow(2,t)},zoom:function(t){return Math.log(t/256)/Math.LN2},getProjectedBounds:function(t){if(this.infinite)return null;var e=this.projection.bounds,i=this.scale(t),n=this.transformation.transform(e.min,i),s=this.transformation.transform(e.max,i);return o.bounds(n,s)},infinite:!1,wrapLatLng:function(t){var e=this.wrapLng?o.Util.wrapNum(t.lng,this.wrapLng,!0):t.lng,i=this.wrapLat?o.Util.wrapNum(t.lat,this.wrapLat,!0):t.lat,n=t.alt;return o.latLng(i,e,n)}},o.CRS.Simple=o.extend({},o.CRS,{projection:o.Projection.LonLat,transformation:new o.Transformation(1,0,-1,0),scale:function(t){return Math.pow(2,t)},zoom:function(t){return Math.log(t)/Math.LN2},distance:function(t,e){var i=e.lng-t.lng,n=e.lat-t.lat;return Math.sqrt(i*i+n*n)},infinite:!0}),o.CRS.Earth=o.extend({},o.CRS,{wrapLng:[-180,180],R:6371e3,distance:function(t,e){var i=Math.PI/180,n=t.lat*i,o=e.lat*i,s=Math.sin(n)*Math.sin(o)+Math.cos(n)*Math.cos(o)*Math.cos((e.lng-t.lng)*i);return this.R*Math.acos(Math.min(s,1))}}),o.CRS.EPSG3857=o.extend({},o.CRS.Earth,{code:"EPSG:3857",projection:o.Projection.SphericalMercator,transformation:function(){var t=.5/(Math.PI*o.Projection.SphericalMercator.R);return new o.Transformation(t,.5,-t,.5)}()}),o.CRS.EPSG900913=o.extend({},o.CRS.EPSG3857,{code:"EPSG:900913"}),o.CRS.EPSG4326=o.extend({},o.CRS.Earth,{code:"EPSG:4326",projection:o.Projection.LonLat,transformation:new o.Transformation(1/180,1,-1/180,.5)}),o.Map=o.Evented.extend({options:{crs:o.CRS.EPSG3857,center:i,zoom:i,minZoom:i,maxZoom:i,layers:[],maxBounds:i,renderer:i,zoomAnimation:!0,zoomAnimationThreshold:4,fadeAnimation:!0,markerZoomAnimation:!0,transform3DLimit:8388608,zoomSnap:1,zoomDelta:1,trackResize:!0},initialize:function(t,e){e=o.setOptions(this,e),this._initContainer(t),this._initLayout(),this._onResize=o.bind(this._onResize,this),this._initEvents(),e.maxBounds&&this.setMaxBounds(e.maxBounds),e.zoom!==i&&(this._zoom=this._limitZoom(e.zoom)),e.center&&e.zoom!==i&&this.setView(o.latLng(e.center),e.zoom,{reset:!0}),this._handlers=[],this._layers={},this._zoomBoundLayers={},this._sizeChanged=!0,this.callInitHooks(),this._zoomAnimated=o.DomUtil.TRANSITION&&o.Browser.any3d&&!o.Browser.mobileOpera&&this.options.zoomAnimation,this._zoomAnimated&&(this._createAnimProxy(),o.DomEvent.on(this._proxy,o.DomUtil.TRANSITION_END,this._catchTransitionEnd,this)),this._addLayers(this.options.layers)},setView:function(t,e,n){if(e=e===i?this._zoom:this._limitZoom(e),t=this._limitCenter(o.latLng(t),e,this.options.maxBounds),n=n||{},this._stop(),this._loaded&&!n.reset&&n!==!0){n.animate!==i&&(n.zoom=o.extend({animate:n.animate},n.zoom),n.pan=o.extend({animate:n.animate,duration:n.duration},n.pan));var s=this._zoom!==e?this._tryAnimatedZoom&&this._tryAnimatedZoom(t,e,n.zoom):this._tryAnimatedPan(t,n.pan);if(s)return clearTimeout(this._sizeTimer),this}return this._resetView(t,e),this},setZoom:function(t,e){return this._loaded?this.setView(this.getCenter(),t,{zoom:e}):(this._zoom=t,this)},zoomIn:function(t,e){return t=t||(o.Browser.any3d?this.options.zoomDelta:1),this.setZoom(this._zoom+t,e)},zoomOut:function(t,e){return t=t||(o.Browser.any3d?this.options.zoomDelta:1),this.setZoom(this._zoom-t,e)},setZoomAround:function(t,e,i){var n=this.getZoomScale(e),s=this.getSize().divideBy(2),r=t instanceof o.Point?t:this.latLngToContainerPoint(t),a=r.subtract(s).multiplyBy(1-1/n),h=this.containerPointToLatLng(s.add(a));return this.setView(h,e,{zoom:i})},_getBoundsCenterZoom:function(t,e){e=e||{},t=t.getBounds?t.getBounds():o.latLngBounds(t);var i=o.point(e.paddingTopLeft||e.padding||[0,0]),n=o.point(e.paddingBottomRight||e.padding||[0,0]),s=this.getBoundsZoom(t,!1,i.add(n));s="number"==typeof e.maxZoom?Math.min(e.maxZoom,s):s;var r=n.subtract(i).divideBy(2),a=this.project(t.getSouthWest(),s),h=this.project(t.getNorthEast(),s),l=this.unproject(a.add(h).divideBy(2).add(r),s);return{center:l,zoom:s}},fitBounds:function(t,e){if(t=o.latLngBounds(t),!t.isValid())throw new Error("Bounds are not valid.");var i=this._getBoundsCenterZoom(t,e);return this.setView(i.center,i.zoom,e)},fitWorld:function(t){return this.fitBounds([[-90,-180],[90,180]],t)},panTo:function(t,e){return this.setView(t,this._zoom,{pan:e})},panBy:function(t,e){if(t=o.point(t).round(),e=e||{},!t.x&&!t.y)return this.fire("moveend");if(e.animate!==!0&&!this.getSize().contains(t))return this._resetView(this.unproject(this.project(this.getCenter()).add(t)),this.getZoom()),this;if(this._panAnim||(this._panAnim=new o.PosAnimation,this._panAnim.on({step:this._onPanTransitionStep,end:this._onPanTransitionEnd},this)),e.noMoveStart||this.fire("movestart"),e.animate!==!1){o.DomUtil.addClass(this._mapPane,"leaflet-pan-anim");var i=this._getMapPanePos().subtract(t).round();this._panAnim.run(this._mapPane,i,e.duration||.25,e.easeLinearity)}else this._rawPanBy(t),this.fire("move").fire("moveend");return this},flyTo:function(t,e,n){function s(t){var e=t?-1:1,i=t?v:g,n=v*v-g*g+e*L*L*y*y,o=2*i*L*y,s=n/o,r=Math.sqrt(s*s+1)-s,a=r<1e-9?-18:Math.log(r);return a}function r(t){return(Math.exp(t)-Math.exp(-t))/2}function a(t){return(Math.exp(t)+Math.exp(-t))/2}function h(t){return r(t)/a(t)}function l(t){return g*(a(x)/a(x+P*t))}function u(t){return g*(a(x)*h(x+P*t)-r(x))/L}function c(t){return 1-Math.pow(1-t,1.5)}function d(){var i=(Date.now()-b)/T,n=c(i)*w;i<=1?(this._flyToFrame=o.Util.requestAnimFrame(d,this),this._move(this.unproject(_.add(m.subtract(_).multiplyBy(u(n)/y)),f),this.getScaleZoom(g/l(n),f),{flyTo:!0})):this._move(t,e)._moveEnd(!0)}if(n=n||{},n.animate===!1||!o.Browser.any3d)return this.setView(t,e,n);this._stop();var _=this.project(this.getCenter()),m=this.project(t),p=this.getSize(),f=this._zoom;t=o.latLng(t),e=e===i?f:e;var g=Math.max(p.x,p.y),v=g*this.getZoomScale(f,e),y=m.distanceTo(_)||1,P=1.42,L=P*P,x=s(0),b=Date.now(),w=(s(1)-x)/P,T=n.duration?1e3*n.duration:1e3*w*.8;return this._moveStart(!0),d.call(this),this},flyToBounds:function(t,e){var i=this._getBoundsCenterZoom(t,e);return this.flyTo(i.center,i.zoom,e)},setMaxBounds:function(t){return t=o.latLngBounds(t),t.isValid()?(this.options.maxBounds&&this.off("moveend",this._panInsideMaxBounds),this.options.maxBounds=t,this._loaded&&this._panInsideMaxBounds(),this.on("moveend",this._panInsideMaxBounds)):(this.options.maxBounds=null,this.off("moveend",this._panInsideMaxBounds))},setMinZoom:function(t){return this.options.minZoom=t,this._loaded&&this.getZoom()<this.options.minZoom?this.setZoom(t):this},setMaxZoom:function(t){return this.options.maxZoom=t,this._loaded&&this.getZoom()>this.options.maxZoom?this.setZoom(t):this},panInsideBounds:function(t,e){this._enforcingBounds=!0;var i=this.getCenter(),n=this._limitCenter(i,this._zoom,o.latLngBounds(t));return i.equals(n)||this.panTo(n,e),this._enforcingBounds=!1,this},invalidateSize:function(t){if(!this._loaded)return this;t=o.extend({animate:!1,pan:!0},t===!0?{animate:!0}:t);var e=this.getSize();this._sizeChanged=!0,this._lastCenter=null;var i=this.getSize(),n=e.divideBy(2).round(),s=i.divideBy(2).round(),r=n.subtract(s);return r.x||r.y?(t.animate&&t.pan?this.panBy(r):(t.pan&&this._rawPanBy(r),this.fire("move"),t.debounceMoveend?(clearTimeout(this._sizeTimer),this._sizeTimer=setTimeout(o.bind(this.fire,this,"moveend"),200)):this.fire("moveend")),this.fire("resize",{oldSize:e,newSize:i})):this},stop:function(){return this.setZoom(this._limitZoom(this._zoom)),this.options.zoomSnap||this.fire("viewreset"),this._stop()},locate:function(t){if(t=this._locateOptions=o.extend({timeout:1e4,watch:!1},t),!("geolocation"in navigator))return this._handleGeolocationError({code:0,message:"Geolocation not supported."}),this;var e=o.bind(this._handleGeolocationResponse,this),i=o.bind(this._handleGeolocationError,this);return t.watch?this._locationWatchId=navigator.geolocation.watchPosition(e,i,t):navigator.geolocation.getCurrentPosition(e,i,t),this},stopLocate:function(){return navigator.geolocation&&navigator.geolocation.clearWatch&&navigator.geolocation.clearWatch(this._locationWatchId),this._locateOptions&&(this._locateOptions.setView=!1),this},_handleGeolocationError:function(t){var e=t.code,i=t.message||(1===e?"permission denied":2===e?"position unavailable":"timeout");this._locateOptions.setView&&!this._loaded&&this.fitWorld(),this.fire("locationerror",{code:e,message:"Geolocation error: "+i+"."})},_handleGeolocationResponse:function(t){var e=t.coords.latitude,i=t.coords.longitude,n=new o.LatLng(e,i),s=n.toBounds(t.coords.accuracy),r=this._locateOptions;if(r.setView){var a=this.getBoundsZoom(s);this.setView(n,r.maxZoom?Math.min(a,r.maxZoom):a)}var h={latlng:n,bounds:s,timestamp:t.timestamp};for(var l in t.coords)"number"==typeof t.coords[l]&&(h[l]=t.coords[l]);this.fire("locationfound",h)},addHandler:function(t,e){if(!e)return this;var i=this[t]=new e(this);return this._handlers.push(i),this.options[t]&&i.enable(),this},remove:function(){if(this._initEvents(!0),this._containerId!==this._container._leaflet_id)throw new Error("Map container is being reused by another instance");try{delete this._container._leaflet_id,delete this._containerId}catch(t){this._container._leaflet_id=i,this._containerId=i}o.DomUtil.remove(this._mapPane),this._clearControlPos&&this._clearControlPos(),this._clearHandlers(),this._loaded&&this.fire("unload");for(var t in this._layers)this._layers[t].remove();return this},createPane:function(t,e){var i="leaflet-pane"+(t?" leaflet-"+t.replace("Pane","")+"-pane":""),n=o.DomUtil.create("div",i,e||this._mapPane);return t&&(this._panes[t]=n),n},getCenter:function(){return this._checkIfLoaded(),this._lastCenter&&!this._moved()?this._lastCenter:this.layerPointToLatLng(this._getCenterLayerPoint())},getZoom:function(){return this._zoom},getBounds:function(){var t=this.getPixelBounds(),e=this.unproject(t.getBottomLeft()),i=this.unproject(t.getTopRight());return new o.LatLngBounds(e,i)},getMinZoom:function(){return this.options.minZoom===i?this._layersMinZoom||0:this.options.minZoom},getMaxZoom:function(){return this.options.maxZoom===i?this._layersMaxZoom===i?1/0:this._layersMaxZoom:this.options.maxZoom},getBoundsZoom:function(t,e,i){t=o.latLngBounds(t),i=o.point(i||[0,0]);var n=this.getZoom()||0,s=this.getMinZoom(),r=this.getMaxZoom(),a=t.getNorthWest(),h=t.getSouthEast(),l=this.getSize().subtract(i),u=this.project(h,n).subtract(this.project(a,n)),c=o.Browser.any3d?this.options.zoomSnap:1,d=Math.min(l.x/u.x,l.y/u.y);return n=this.getScaleZoom(d,n),c&&(n=Math.round(n/(c/100))*(c/100),n=e?Math.ceil(n/c)*c:Math.floor(n/c)*c),Math.max(s,Math.min(r,n))},getSize:function(){return this._size&&!this._sizeChanged||(this._size=new o.Point(this._container.clientWidth,this._container.clientHeight),this._sizeChanged=!1),this._size.clone()},getPixelBounds:function(t,e){var i=this._getTopLeftPoint(t,e);return new o.Bounds(i,i.add(this.getSize()))},getPixelOrigin:function(){return this._checkIfLoaded(),this._pixelOrigin},getPixelWorldBounds:function(t){return this.options.crs.getProjectedBounds(t===i?this.getZoom():t)},getPane:function(t){return"string"==typeof t?this._panes[t]:t},getPanes:function(){return this._panes},getContainer:function(){return this._container},getZoomScale:function(t,e){var n=this.options.crs;return e=e===i?this._zoom:e,n.scale(t)/n.scale(e)},getScaleZoom:function(t,e){var n=this.options.crs;e=e===i?this._zoom:e;var o=n.zoom(t*n.scale(e));return isNaN(o)?1/0:o},project:function(t,e){return e=e===i?this._zoom:e,this.options.crs.latLngToPoint(o.latLng(t),e)},unproject:function(t,e){return e=e===i?this._zoom:e,this.options.crs.pointToLatLng(o.point(t),e)},layerPointToLatLng:function(t){var e=o.point(t).add(this.getPixelOrigin());return this.unproject(e)},latLngToLayerPoint:function(t){var e=this.project(o.latLng(t))._round();return e._subtract(this.getPixelOrigin())},wrapLatLng:function(t){return this.options.crs.wrapLatLng(o.latLng(t))},distance:function(t,e){return this.options.crs.distance(o.latLng(t),o.latLng(e))},containerPointToLayerPoint:function(t){return o.point(t).subtract(this._getMapPanePos())},layerPointToContainerPoint:function(t){return o.point(t).add(this._getMapPanePos())},containerPointToLatLng:function(t){var e=this.containerPointToLayerPoint(o.point(t));return this.layerPointToLatLng(e)},latLngToContainerPoint:function(t){return this.layerPointToContainerPoint(this.latLngToLayerPoint(o.latLng(t)))},mouseEventToContainerPoint:function(t){return o.DomEvent.getMousePosition(t,this._container)},mouseEventToLayerPoint:function(t){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(t))},mouseEventToLatLng:function(t){return this.layerPointToLatLng(this.mouseEventToLayerPoint(t))},_initContainer:function(t){var e=this._container=o.DomUtil.get(t);if(!e)throw new Error("Map container not found.");if(e._leaflet_id)throw new Error("Map container is already initialized.");o.DomEvent.addListener(e,"scroll",this._onScroll,this),this._containerId=o.Util.stamp(e)},_initLayout:function(){var t=this._container;this._fadeAnimated=this.options.fadeAnimation&&o.Browser.any3d,o.DomUtil.addClass(t,"leaflet-container"+(o.Browser.touch?" leaflet-touch":"")+(o.Browser.retina?" leaflet-retina":"")+(o.Browser.ielt9?" leaflet-oldie":"")+(o.Browser.safari?" leaflet-safari":"")+(this._fadeAnimated?" leaflet-fade-anim":""));var e=o.DomUtil.getStyle(t,"position");"absolute"!==e&&"relative"!==e&&"fixed"!==e&&(t.style.position="relative"),this._initPanes(),
  14. this._initControlPos&&this._initControlPos()},_initPanes:function(){var t=this._panes={};this._paneRenderers={},this._mapPane=this.createPane("mapPane",this._container),o.DomUtil.setPosition(this._mapPane,new o.Point(0,0)),this.createPane("tilePane"),this.createPane("shadowPane"),this.createPane("overlayPane"),this.createPane("markerPane"),this.createPane("tooltipPane"),this.createPane("popupPane"),this.options.markerZoomAnimation||(o.DomUtil.addClass(t.markerPane,"leaflet-zoom-hide"),o.DomUtil.addClass(t.shadowPane,"leaflet-zoom-hide"))},_resetView:function(t,e){o.DomUtil.setPosition(this._mapPane,new o.Point(0,0));var i=!this._loaded;this._loaded=!0,e=this._limitZoom(e),this.fire("viewprereset");var n=this._zoom!==e;this._moveStart(n)._move(t,e)._moveEnd(n),this.fire("viewreset"),i&&this.fire("load")},_moveStart:function(t){return t&&this.fire("zoomstart"),this.fire("movestart")},_move:function(t,e,n){e===i&&(e=this._zoom);var o=this._zoom!==e;return this._zoom=e,this._lastCenter=t,this._pixelOrigin=this._getNewPixelOrigin(t),(o||n&&n.pinch)&&this.fire("zoom",n),this.fire("move",n)},_moveEnd:function(t){return t&&this.fire("zoomend"),this.fire("moveend")},_stop:function(){return o.Util.cancelAnimFrame(this._flyToFrame),this._panAnim&&this._panAnim.stop(),this},_rawPanBy:function(t){o.DomUtil.setPosition(this._mapPane,this._getMapPanePos().subtract(t))},_getZoomSpan:function(){return this.getMaxZoom()-this.getMinZoom()},_panInsideMaxBounds:function(){this._enforcingBounds||this.panInsideBounds(this.options.maxBounds)},_checkIfLoaded:function(){if(!this._loaded)throw new Error("Set map center and zoom first.")},_initEvents:function(e){if(o.DomEvent){this._targets={},this._targets[o.stamp(this._container)]=this;var i=e?"off":"on";o.DomEvent[i](this._container,"click dblclick mousedown mouseup mouseover mouseout mousemove contextmenu keypress",this._handleDOMEvent,this),this.options.trackResize&&o.DomEvent[i](t,"resize",this._onResize,this),o.Browser.any3d&&this.options.transform3DLimit&&this[i]("moveend",this._onMoveEnd)}},_onResize:function(){o.Util.cancelAnimFrame(this._resizeRequest),this._resizeRequest=o.Util.requestAnimFrame(function(){this.invalidateSize({debounceMoveend:!0})},this)},_onScroll:function(){this._container.scrollTop=0,this._container.scrollLeft=0},_onMoveEnd:function(){var t=this._getMapPanePos();Math.max(Math.abs(t.x),Math.abs(t.y))>=this.options.transform3DLimit&&this._resetView(this.getCenter(),this.getZoom())},_findEventTargets:function(t,e){for(var i,n=[],s="mouseout"===e||"mouseover"===e,r=t.target||t.srcElement,a=!1;r;){if(i=this._targets[o.stamp(r)],i&&("click"===e||"preclick"===e)&&!t._simulated&&this._draggableMoved(i)){a=!0;break}if(i&&i.listens(e,!0)){if(s&&!o.DomEvent._isExternalTarget(r,t))break;if(n.push(i),s)break}if(r===this._container)break;r=r.parentNode}return n.length||a||s||!o.DomEvent._isExternalTarget(r,t)||(n=[this]),n},_handleDOMEvent:function(t){if(this._loaded&&!o.DomEvent._skipped(t)){var e="keypress"===t.type&&13===t.keyCode?"click":t.type;"mousedown"===e&&o.DomUtil.preventOutline(t.target||t.srcElement),this._fireDOMEvent(t,e)}},_fireDOMEvent:function(t,e,i){if("click"===t.type){var n=o.Util.extend({},t);n.type="preclick",this._fireDOMEvent(n,n.type,i)}if(!t._stopped&&(i=(i||[]).concat(this._findEventTargets(t,e)),i.length)){var s=i[0];"contextmenu"===e&&s.listens(e,!0)&&o.DomEvent.preventDefault(t);var r={originalEvent:t};if("keypress"!==t.type){var a=s instanceof o.Marker;r.containerPoint=a?this.latLngToContainerPoint(s.getLatLng()):this.mouseEventToContainerPoint(t),r.layerPoint=this.containerPointToLayerPoint(r.containerPoint),r.latlng=a?s.getLatLng():this.layerPointToLatLng(r.layerPoint)}for(var h=0;h<i.length;h++)if(i[h].fire(e,r,!0),r.originalEvent._stopped||i[h].options.nonBubblingEvents&&o.Util.indexOf(i[h].options.nonBubblingEvents,e)!==-1)return}},_draggableMoved:function(t){return t=t.dragging&&t.dragging.enabled()?t:this,t.dragging&&t.dragging.moved()||this.boxZoom&&this.boxZoom.moved()},_clearHandlers:function(){for(var t=0,e=this._handlers.length;t<e;t++)this._handlers[t].disable()},whenReady:function(t,e){return this._loaded?t.call(e||this,{target:this}):this.on("load",t,e),this},_getMapPanePos:function(){return o.DomUtil.getPosition(this._mapPane)||new o.Point(0,0)},_moved:function(){var t=this._getMapPanePos();return t&&!t.equals([0,0])},_getTopLeftPoint:function(t,e){var n=t&&e!==i?this._getNewPixelOrigin(t,e):this.getPixelOrigin();return n.subtract(this._getMapPanePos())},_getNewPixelOrigin:function(t,e){var i=this.getSize()._divideBy(2);return this.project(t,e)._subtract(i)._add(this._getMapPanePos())._round()},_latLngToNewLayerPoint:function(t,e,i){var n=this._getNewPixelOrigin(i,e);return this.project(t,e)._subtract(n)},_latLngBoundsToNewLayerBounds:function(t,e,i){var n=this._getNewPixelOrigin(i,e);return o.bounds([this.project(t.getSouthWest(),e)._subtract(n),this.project(t.getNorthWest(),e)._subtract(n),this.project(t.getSouthEast(),e)._subtract(n),this.project(t.getNorthEast(),e)._subtract(n)])},_getCenterLayerPoint:function(){return this.containerPointToLayerPoint(this.getSize()._divideBy(2))},_getCenterOffset:function(t){return this.latLngToLayerPoint(t).subtract(this._getCenterLayerPoint())},_limitCenter:function(t,e,i){if(!i)return t;var n=this.project(t,e),s=this.getSize().divideBy(2),r=new o.Bounds(n.subtract(s),n.add(s)),a=this._getBoundsOffset(r,i,e);return a.round().equals([0,0])?t:this.unproject(n.add(a),e)},_limitOffset:function(t,e){if(!e)return t;var i=this.getPixelBounds(),n=new o.Bounds(i.min.add(t),i.max.add(t));return t.add(this._getBoundsOffset(n,e))},_getBoundsOffset:function(t,e,i){var n=o.bounds(this.project(e.getNorthEast(),i),this.project(e.getSouthWest(),i)),s=n.min.subtract(t.min),r=n.max.subtract(t.max),a=this._rebound(s.x,-r.x),h=this._rebound(s.y,-r.y);return new o.Point(a,h)},_rebound:function(t,e){return t+e>0?Math.round(t-e)/2:Math.max(0,Math.ceil(t))-Math.max(0,Math.floor(e))},_limitZoom:function(t){var e=this.getMinZoom(),i=this.getMaxZoom(),n=o.Browser.any3d?this.options.zoomSnap:1;return n&&(t=Math.round(t/n)*n),Math.max(e,Math.min(i,t))},_onPanTransitionStep:function(){this.fire("move")},_onPanTransitionEnd:function(){o.DomUtil.removeClass(this._mapPane,"leaflet-pan-anim"),this.fire("moveend")},_tryAnimatedPan:function(t,e){var i=this._getCenterOffset(t)._floor();return!((e&&e.animate)!==!0&&!this.getSize().contains(i))&&(this.panBy(i,e),!0)},_createAnimProxy:function(){var t=this._proxy=o.DomUtil.create("div","leaflet-proxy leaflet-zoom-animated");this._panes.mapPane.appendChild(t),this.on("zoomanim",function(e){var i=o.DomUtil.TRANSFORM,n=t.style[i];o.DomUtil.setTransform(t,this.project(e.center,e.zoom),this.getZoomScale(e.zoom,1)),n===t.style[i]&&this._animatingZoom&&this._onZoomTransitionEnd()},this),this.on("load moveend",function(){var e=this.getCenter(),i=this.getZoom();o.DomUtil.setTransform(t,this.project(e,i),this.getZoomScale(i,1))},this)},_catchTransitionEnd:function(t){this._animatingZoom&&t.propertyName.indexOf("transform")>=0&&this._onZoomTransitionEnd()},_nothingToAnimate:function(){return!this._container.getElementsByClassName("leaflet-zoom-animated").length},_tryAnimatedZoom:function(t,e,i){if(this._animatingZoom)return!0;if(i=i||{},!this._zoomAnimated||i.animate===!1||this._nothingToAnimate()||Math.abs(e-this._zoom)>this.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(e),s=this._getCenterOffset(t)._divideBy(1-1/n);return!(i.animate!==!0&&!this.getSize().contains(s))&&(o.Util.requestAnimFrame(function(){this._moveStart(!0)._animateZoom(t,e,!0)},this),!0)},_animateZoom:function(t,e,i,n){i&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=e,o.DomUtil.addClass(this._mapPane,"leaflet-zoom-anim")),this.fire("zoomanim",{center:t,zoom:e,noUpdate:n}),setTimeout(o.bind(this._onZoomTransitionEnd,this),250)},_onZoomTransitionEnd:function(){this._animatingZoom&&(o.DomUtil.removeClass(this._mapPane,"leaflet-zoom-anim"),this._animatingZoom=!1,this._move(this._animateToCenter,this._animateToZoom),o.Util.requestAnimFrame(function(){this._moveEnd(!0)},this))}}),o.map=function(t,e){return new o.Map(t,e)},o.Layer=o.Evented.extend({options:{pane:"overlayPane",nonBubblingEvents:[],attribution:null},addTo:function(t){return t.addLayer(this),this},remove:function(){return this.removeFrom(this._map||this._mapToAdd)},removeFrom:function(t){return t&&t.removeLayer(this),this},getPane:function(t){return this._map.getPane(t?this.options[t]||t:this.options.pane)},addInteractiveTarget:function(t){return this._map._targets[o.stamp(t)]=this,this},removeInteractiveTarget:function(t){return delete this._map._targets[o.stamp(t)],this},getAttribution:function(){return this.options.attribution},_layerAdd:function(t){var e=t.target;if(e.hasLayer(this)){if(this._map=e,this._zoomAnimated=e._zoomAnimated,this.getEvents){var i=this.getEvents();e.on(i,this),this.once("remove",function(){e.off(i,this)},this)}this.onAdd(e),this.getAttribution&&this._map.attributionControl&&this._map.attributionControl.addAttribution(this.getAttribution()),this.fire("add"),e.fire("layeradd",{layer:this})}}}),o.Map.include({addLayer:function(t){var e=o.stamp(t);return this._layers[e]?this:(this._layers[e]=t,t._mapToAdd=this,t.beforeAdd&&t.beforeAdd(this),this.whenReady(t._layerAdd,t),this)},removeLayer:function(t){var e=o.stamp(t);return this._layers[e]?(this._loaded&&t.onRemove(this),t.getAttribution&&this.attributionControl&&this.attributionControl.removeAttribution(t.getAttribution()),delete this._layers[e],this._loaded&&(this.fire("layerremove",{layer:t}),t.fire("remove")),t._map=t._mapToAdd=null,this):this},hasLayer:function(t){return!!t&&o.stamp(t)in this._layers},eachLayer:function(t,e){for(var i in this._layers)t.call(e,this._layers[i]);return this},_addLayers:function(t){t=t?o.Util.isArray(t)?t:[t]:[];for(var e=0,i=t.length;e<i;e++)this.addLayer(t[e])},_addZoomLimit:function(t){!isNaN(t.options.maxZoom)&&isNaN(t.options.minZoom)||(this._zoomBoundLayers[o.stamp(t)]=t,this._updateZoomLevels())},_removeZoomLimit:function(t){var e=o.stamp(t);this._zoomBoundLayers[e]&&(delete this._zoomBoundLayers[e],this._updateZoomLevels())},_updateZoomLevels:function(){var t=1/0,e=-(1/0),n=this._getZoomSpan();for(var o in this._zoomBoundLayers){var s=this._zoomBoundLayers[o].options;t=s.minZoom===i?t:Math.min(t,s.minZoom),e=s.maxZoom===i?e:Math.max(e,s.maxZoom)}this._layersMaxZoom=e===-(1/0)?i:e,this._layersMinZoom=t===1/0?i:t,n!==this._getZoomSpan()&&this.fire("zoomlevelschange"),this.options.maxZoom===i&&this._layersMaxZoom&&this.getZoom()>this._layersMaxZoom&&this.setZoom(this._layersMaxZoom),this.options.minZoom===i&&this._layersMinZoom&&this.getZoom()<this._layersMinZoom&&this.setZoom(this._layersMinZoom)}});var r="_leaflet_events";o.DomEvent={on:function(t,e,i,n){if("object"==typeof e)for(var s in e)this._on(t,s,e[s],i);else{e=o.Util.splitWords(e);for(var r=0,a=e.length;r<a;r++)this._on(t,e[r],i,n)}return this},off:function(t,e,i,n){if("object"==typeof e)for(var s in e)this._off(t,s,e[s],i);else{e=o.Util.splitWords(e);for(var r=0,a=e.length;r<a;r++)this._off(t,e[r],i,n)}return this},_on:function(e,i,n,s){var a=i+o.stamp(n)+(s?"_"+o.stamp(s):"");if(e[r]&&e[r][a])return this;var h=function(i){return n.call(s||e,i||t.event)},l=h;return o.Browser.pointer&&0===i.indexOf("touch")?this.addPointerListener(e,i,h,a):o.Browser.touch&&"dblclick"===i&&this.addDoubleTapListener?this.addDoubleTapListener(e,h,a):"addEventListener"in e?"mousewheel"===i?e.addEventListener("onwheel"in e?"wheel":"mousewheel",h,!1):"mouseenter"===i||"mouseleave"===i?(h=function(i){i=i||t.event,o.DomEvent._isExternalTarget(e,i)&&l(i)},e.addEventListener("mouseenter"===i?"mouseover":"mouseout",h,!1)):("click"===i&&o.Browser.android&&(h=function(t){return o.DomEvent._filterClick(t,l)}),e.addEventListener(i,h,!1)):"attachEvent"in e&&e.attachEvent("on"+i,h),e[r]=e[r]||{},e[r][a]=h,this},_off:function(t,e,i,n){var s=e+o.stamp(i)+(n?"_"+o.stamp(n):""),a=t[r]&&t[r][s];return a?(o.Browser.pointer&&0===e.indexOf("touch")?this.removePointerListener(t,e,s):o.Browser.touch&&"dblclick"===e&&this.removeDoubleTapListener?this.removeDoubleTapListener(t,s):"removeEventListener"in t?"mousewheel"===e?t.removeEventListener("onwheel"in t?"wheel":"mousewheel",a,!1):t.removeEventListener("mouseenter"===e?"mouseover":"mouseleave"===e?"mouseout":e,a,!1):"detachEvent"in t&&t.detachEvent("on"+e,a),t[r][s]=null,this):this},stopPropagation:function(t){return t.stopPropagation?t.stopPropagation():t.originalEvent?t.originalEvent._stopped=!0:t.cancelBubble=!0,o.DomEvent._skipped(t),this},disableScrollPropagation:function(t){return o.DomEvent.on(t,"mousewheel",o.DomEvent.stopPropagation)},disableClickPropagation:function(t){var e=o.DomEvent.stopPropagation;return o.DomEvent.on(t,o.Draggable.START.join(" "),e),o.DomEvent.on(t,{click:o.DomEvent._fakeStop,dblclick:e})},preventDefault:function(t){return t.preventDefault?t.preventDefault():t.returnValue=!1,this},stop:function(t){return o.DomEvent.preventDefault(t).stopPropagation(t)},getMousePosition:function(t,e){if(!e)return new o.Point(t.clientX,t.clientY);var i=e.getBoundingClientRect();return new o.Point(t.clientX-i.left-e.clientLeft,t.clientY-i.top-e.clientTop)},_wheelPxFactor:o.Browser.win&&o.Browser.chrome?2:o.Browser.gecko?t.devicePixelRatio:1,getWheelDelta:function(t){return o.Browser.edge?t.wheelDeltaY/2:t.deltaY&&0===t.deltaMode?-t.deltaY/o.DomEvent._wheelPxFactor:t.deltaY&&1===t.deltaMode?20*-t.deltaY:t.deltaY&&2===t.deltaMode?60*-t.deltaY:t.deltaX||t.deltaZ?0:t.wheelDelta?(t.wheelDeltaY||t.wheelDelta)/2:t.detail&&Math.abs(t.detail)<32765?20*-t.detail:t.detail?t.detail/-32765*60:0},_skipEvents:{},_fakeStop:function(t){o.DomEvent._skipEvents[t.type]=!0},_skipped:function(t){var e=this._skipEvents[t.type];return this._skipEvents[t.type]=!1,e},_isExternalTarget:function(t,e){var i=e.relatedTarget;if(!i)return!0;try{for(;i&&i!==t;)i=i.parentNode}catch(t){return!1}return i!==t},_filterClick:function(t,e){var i=t.timeStamp||t.originalEvent&&t.originalEvent.timeStamp,n=o.DomEvent._lastClick&&i-o.DomEvent._lastClick;return n&&n>100&&n<500||t.target._simulatedClick&&!t._simulated?void o.DomEvent.stop(t):(o.DomEvent._lastClick=i,void e(t))}},o.DomEvent.addListener=o.DomEvent.on,o.DomEvent.removeListener=o.DomEvent.off,o.PosAnimation=o.Evented.extend({run:function(t,e,i,n){this.stop(),this._el=t,this._inProgress=!0,this._duration=i||.25,this._easeOutPower=1/Math.max(n||.5,.2),this._startPos=o.DomUtil.getPosition(t),this._offset=e.subtract(this._startPos),this._startTime=+new Date,this.fire("start"),this._animate()},stop:function(){this._inProgress&&(this._step(!0),this._complete())},_animate:function(){this._animId=o.Util.requestAnimFrame(this._animate,this),this._step()},_step:function(t){var e=+new Date-this._startTime,i=1e3*this._duration;e<i?this._runFrame(this._easeOut(e/i),t):(this._runFrame(1),this._complete())},_runFrame:function(t,e){var i=this._startPos.add(this._offset.multiplyBy(t));e&&i._round(),o.DomUtil.setPosition(this._el,i),this.fire("step")},_complete:function(){o.Util.cancelAnimFrame(this._animId),this._inProgress=!1,this.fire("end")},_easeOut:function(t){return 1-Math.pow(1-t,this._easeOutPower)}}),o.Projection.Mercator={R:6378137,R_MINOR:6356752.314245179,bounds:o.bounds([-20037508.34279,-15496570.73972],[20037508.34279,18764656.23138]),project:function(t){var e=Math.PI/180,i=this.R,n=t.lat*e,s=this.R_MINOR/i,r=Math.sqrt(1-s*s),a=r*Math.sin(n),h=Math.tan(Math.PI/4-n/2)/Math.pow((1-a)/(1+a),r/2);return n=-i*Math.log(Math.max(h,1e-10)),new o.Point(t.lng*e*i,n)},unproject:function(t){for(var e,i=180/Math.PI,n=this.R,s=this.R_MINOR/n,r=Math.sqrt(1-s*s),a=Math.exp(-t.y/n),h=Math.PI/2-2*Math.atan(a),l=0,u=.1;l<15&&Math.abs(u)>1e-7;l++)e=r*Math.sin(h),e=Math.pow((1-e)/(1+e),r/2),u=Math.PI/2-2*Math.atan(a*e)-h,h+=u;return new o.LatLng(h*i,t.x*i/n)}},o.CRS.EPSG3395=o.extend({},o.CRS.Earth,{code:"EPSG:3395",projection:o.Projection.Mercator,transformation:function(){var t=.5/(Math.PI*o.Projection.Mercator.R);return new o.Transformation(t,.5,-t,.5)}()}),o.GridLayer=o.Layer.extend({options:{tileSize:256,opacity:1,updateWhenIdle:o.Browser.mobile,updateWhenZooming:!0,updateInterval:200,zIndex:1,bounds:null,minZoom:0,maxZoom:i,noWrap:!1,pane:"tilePane",className:"",keepBuffer:2},initialize:function(t){o.setOptions(this,t)},onAdd:function(){this._initContainer(),this._levels={},this._tiles={},this._resetView(),this._update()},beforeAdd:function(t){t._addZoomLimit(this)},onRemove:function(t){this._removeAllTiles(),o.DomUtil.remove(this._container),t._removeZoomLimit(this),this._container=null,this._tileZoom=null},bringToFront:function(){return this._map&&(o.DomUtil.toFront(this._container),this._setAutoZIndex(Math.max)),this},bringToBack:function(){return this._map&&(o.DomUtil.toBack(this._container),this._setAutoZIndex(Math.min)),this},getContainer:function(){return this._container},setOpacity:function(t){return this.options.opacity=t,this._updateOpacity(),this},setZIndex:function(t){return this.options.zIndex=t,this._updateZIndex(),this},isLoading:function(){return this._loading},redraw:function(){return this._map&&(this._removeAllTiles(),this._update()),this},getEvents:function(){var t={viewprereset:this._invalidateAll,viewreset:this._resetView,zoom:this._resetView,moveend:this._onMoveEnd};return this.options.updateWhenIdle||(this._onMove||(this._onMove=o.Util.throttle(this._onMoveEnd,this.options.updateInterval,this)),t.move=this._onMove),this._zoomAnimated&&(t.zoomanim=this._animateZoom),t},createTile:function(){return e.createElement("div")},getTileSize:function(){var t=this.options.tileSize;return t instanceof o.Point?t:new o.Point(t,t)},_updateZIndex:function(){this._container&&this.options.zIndex!==i&&null!==this.options.zIndex&&(this._container.style.zIndex=this.options.zIndex)},_setAutoZIndex:function(t){for(var e,i=this.getPane().children,n=-t(-(1/0),1/0),o=0,s=i.length;o<s;o++)e=i[o].style.zIndex,i[o]!==this._container&&e&&(n=t(n,+e));isFinite(n)&&(this.options.zIndex=n+t(-1,1),this._updateZIndex())},_updateOpacity:function(){if(this._map&&!o.Browser.ielt9){o.DomUtil.setOpacity(this._container,this.options.opacity);var t=+new Date,e=!1,i=!1;for(var n in this._tiles){var s=this._tiles[n];if(s.current&&s.loaded){var r=Math.min(1,(t-s.loaded)/200);o.DomUtil.setOpacity(s.el,r),r<1?e=!0:(s.active&&(i=!0),s.active=!0)}}i&&!this._noPrune&&this._pruneTiles(),e&&(o.Util.cancelAnimFrame(this._fadeFrame),this._fadeFrame=o.Util.requestAnimFrame(this._updateOpacity,this))}},_initContainer:function(){this._container||(this._container=o.DomUtil.create("div","leaflet-layer "+(this.options.className||"")),this._updateZIndex(),this.options.opacity<1&&this._updateOpacity(),this.getPane().appendChild(this._container))},_updateLevels:function(){var t=this._tileZoom,e=this.options.maxZoom;if(t===i)return i;for(var n in this._levels)this._levels[n].el.children.length||n===t?this._levels[n].el.style.zIndex=e-Math.abs(t-n):(o.DomUtil.remove(this._levels[n].el),this._removeTilesAtZoom(n),delete this._levels[n]);var s=this._levels[t],r=this._map;return s||(s=this._levels[t]={},s.el=o.DomUtil.create("div","leaflet-tile-container leaflet-zoom-animated",this._container),s.el.style.zIndex=e,s.origin=r.project(r.unproject(r.getPixelOrigin()),t).round(),s.zoom=t,this._setZoomTransform(s,r.getCenter(),r.getZoom()),o.Util.falseFn(s.el.offsetWidth)),this._level=s,s},_pruneTiles:function(){if(this._map){var t,e,i=this._map.getZoom();if(i>this.options.maxZoom||i<this.options.minZoom)return void this._removeAllTiles();for(t in this._tiles)e=this._tiles[t],e.retain=e.current;for(t in this._tiles)if(e=this._tiles[t],e.current&&!e.active){var n=e.coords;this._retainParent(n.x,n.y,n.z,n.z-5)||this._retainChildren(n.x,n.y,n.z,n.z+2)}for(t in this._tiles)this._tiles[t].retain||this._removeTile(t)}},_removeTilesAtZoom:function(t){for(var e in this._tiles)this._tiles[e].coords.z===t&&this._removeTile(e)},_removeAllTiles:function(){for(var t in this._tiles)this._removeTile(t)},_invalidateAll:function(){for(var t in this._levels)o.DomUtil.remove(this._levels[t].el),delete this._levels[t];this._removeAllTiles(),this._tileZoom=null},_retainParent:function(t,e,i,n){var s=Math.floor(t/2),r=Math.floor(e/2),a=i-1,h=new o.Point(+s,+r);h.z=+a;var l=this._tileCoordsToKey(h),u=this._tiles[l];return u&&u.active?(u.retain=!0,!0):(u&&u.loaded&&(u.retain=!0),a>n&&this._retainParent(s,r,a,n))},_retainChildren:function(t,e,i,n){for(var s=2*t;s<2*t+2;s++)for(var r=2*e;r<2*e+2;r++){var a=new o.Point(s,r);a.z=i+1;var h=this._tileCoordsToKey(a),l=this._tiles[h];l&&l.active?l.retain=!0:(l&&l.loaded&&(l.retain=!0),i+1<n&&this._retainChildren(s,r,i+1,n))}},_resetView:function(t){var e=t&&(t.pinch||t.flyTo);this._setView(this._map.getCenter(),this._map.getZoom(),e,e)},_animateZoom:function(t){this._setView(t.center,t.zoom,!0,t.noUpdate)},_setView:function(t,e,n,o){var s=Math.round(e);(this.options.maxZoom!==i&&s>this.options.maxZoom||this.options.minZoom!==i&&s<this.options.minZoom)&&(s=i);var r=this.options.updateWhenZooming&&s!==this._tileZoom;o&&!r||(this._tileZoom=s,this._abortLoading&&this._abortLoading(),this._updateLevels(),this._resetGrid(),s!==i&&this._update(t),n||this._pruneTiles(),this._noPrune=!!n),this._setZoomTransforms(t,e)},_setZoomTransforms:function(t,e){for(var i in this._levels)this._setZoomTransform(this._levels[i],t,e)},_setZoomTransform:function(t,e,i){var n=this._map.getZoomScale(i,t.zoom),s=t.origin.multiplyBy(n).subtract(this._map._getNewPixelOrigin(e,i)).round();o.Browser.any3d?o.DomUtil.setTransform(t.el,s,n):o.DomUtil.setPosition(t.el,s)},_resetGrid:function(){var t=this._map,e=t.options.crs,i=this._tileSize=this.getTileSize(),n=this._tileZoom,o=this._map.getPixelWorldBounds(this._tileZoom);o&&(this._globalTileRange=this._pxBoundsToTileRange(o)),this._wrapX=e.wrapLng&&!this.options.noWrap&&[Math.floor(t.project([0,e.wrapLng[0]],n).x/i.x),Math.ceil(t.project([0,e.wrapLng[1]],n).x/i.y)],this._wrapY=e.wrapLat&&!this.options.noWrap&&[Math.floor(t.project([e.wrapLat[0],0],n).y/i.x),Math.ceil(t.project([e.wrapLat[1],0],n).y/i.y)]},_onMoveEnd:function(){this._map&&!this._map._animatingZoom&&this._update()},_getTiledPixelBounds:function(t){var e=this._map,i=e._animatingZoom?Math.max(e._animateToZoom,e.getZoom()):e.getZoom(),n=e.getZoomScale(i,this._tileZoom),s=e.project(t,this._tileZoom).floor(),r=e.getSize().divideBy(2*n);return new o.Bounds(s.subtract(r),s.add(r))},_update:function(t){var n=this._map;if(n){var s=n.getZoom();if(t===i&&(t=n.getCenter()),this._tileZoom!==i){var r=this._getTiledPixelBounds(t),a=this._pxBoundsToTileRange(r),h=a.getCenter(),l=[],u=this.options.keepBuffer,c=new o.Bounds(a.getBottomLeft().subtract([u,-u]),a.getTopRight().add([u,-u]));for(var d in this._tiles){var _=this._tiles[d].coords;_.z===this._tileZoom&&c.contains(o.point(_.x,_.y))||(this._tiles[d].current=!1)}if(Math.abs(s-this._tileZoom)>1)return void this._setView(t,s);for(var m=a.min.y;m<=a.max.y;m++)for(var p=a.min.x;p<=a.max.x;p++){var f=new o.Point(p,m);if(f.z=this._tileZoom,this._isValidTile(f)){var g=this._tiles[this._tileCoordsToKey(f)];g?g.current=!0:l.push(f)}}if(l.sort(function(t,e){return t.distanceTo(h)-e.distanceTo(h)}),0!==l.length){this._loading||(this._loading=!0,this.fire("loading"));var v=e.createDocumentFragment();for(p=0;p<l.length;p++)this._addTile(l[p],v);this._level.el.appendChild(v)}}}},_isValidTile:function(t){var e=this._map.options.crs;if(!e.infinite){var i=this._globalTileRange;if(!e.wrapLng&&(t.x<i.min.x||t.x>i.max.x)||!e.wrapLat&&(t.y<i.min.y||t.y>i.max.y))return!1}if(!this.options.bounds)return!0;var n=this._tileCoordsToBounds(t);return o.latLngBounds(this.options.bounds).overlaps(n)},_keyToBounds:function(t){return this._tileCoordsToBounds(this._keyToTileCoords(t))},_tileCoordsToBounds:function(t){var e=this._map,i=this.getTileSize(),n=t.scaleBy(i),s=n.add(i),r=e.unproject(n,t.z),a=e.unproject(s,t.z);return this.options.noWrap||(r=e.wrapLatLng(r),a=e.wrapLatLng(a)),new o.LatLngBounds(r,a)},_tileCoordsToKey:function(t){return t.x+":"+t.y+":"+t.z},_keyToTileCoords:function(t){var e=t.split(":"),i=new o.Point(+e[0],+e[1]);return i.z=+e[2],i},_removeTile:function(t){var e=this._tiles[t];e&&(o.DomUtil.remove(e.el),delete this._tiles[t],this.fire("tileunload",{tile:e.el,coords:this._keyToTileCoords(t)}))},_initTile:function(t){o.DomUtil.addClass(t,"leaflet-tile");var e=this.getTileSize();t.style.width=e.x+"px",t.style.height=e.y+"px",t.onselectstart=o.Util.falseFn,t.onmousemove=o.Util.falseFn,o.Browser.ielt9&&this.options.opacity<1&&o.DomUtil.setOpacity(t,this.options.opacity),o.Browser.android&&!o.Browser.android23&&(t.style.WebkitBackfaceVisibility="hidden")},_addTile:function(t,e){var i=this._getTilePos(t),n=this._tileCoordsToKey(t),s=this.createTile(this._wrapCoords(t),o.bind(this._tileReady,this,t));this._initTile(s),this.createTile.length<2&&o.Util.requestAnimFrame(o.bind(this._tileReady,this,t,null,s)),o.DomUtil.setPosition(s,i),this._tiles[n]={el:s,coords:t,current:!0},e.appendChild(s),this.fire("tileloadstart",{tile:s,coords:t})},_tileReady:function(t,e,i){if(this._map){e&&this.fire("tileerror",{error:e,tile:i,coords:t});var n=this._tileCoordsToKey(t);i=this._tiles[n],i&&(i.loaded=+new Date,this._map._fadeAnimated?(o.DomUtil.setOpacity(i.el,0),o.Util.cancelAnimFrame(this._fadeFrame),this._fadeFrame=o.Util.requestAnimFrame(this._updateOpacity,this)):(i.active=!0,this._pruneTiles()),e||(o.DomUtil.addClass(i.el,"leaflet-tile-loaded"),this.fire("tileload",{tile:i.el,coords:t})),this._noTilesToLoad()&&(this._loading=!1,this.fire("load"),o.Browser.ielt9||!this._map._fadeAnimated?o.Util.requestAnimFrame(this._pruneTiles,this):setTimeout(o.bind(this._pruneTiles,this),250)))}},_getTilePos:function(t){return t.scaleBy(this.getTileSize()).subtract(this._level.origin)},_wrapCoords:function(t){var e=new o.Point(this._wrapX?o.Util.wrapNum(t.x,this._wrapX):t.x,this._wrapY?o.Util.wrapNum(t.y,this._wrapY):t.y);return e.z=t.z,e},_pxBoundsToTileRange:function(t){var e=this.getTileSize();return new o.Bounds(t.min.unscaleBy(e).floor(),t.max.unscaleBy(e).ceil().subtract([1,1]))},_noTilesToLoad:function(){for(var t in this._tiles)if(!this._tiles[t].loaded)return!1;return!0}}),o.gridLayer=function(t){return new o.GridLayer(t)},o.TileLayer=o.GridLayer.extend({options:{minZoom:0,maxZoom:18,maxNativeZoom:null,minNativeZoom:null,subdomains:"abc",errorTileUrl:"",zoomOffset:0,tms:!1,zoomReverse:!1,detectRetina:!1,crossOrigin:!1},initialize:function(t,e){this._url=t,e=o.setOptions(this,e),e.detectRetina&&o.Browser.retina&&e.maxZoom>0&&(e.tileSize=Math.floor(e.tileSize/2),e.zoomReverse?(e.zoomOffset--,e.minZoom++):(e.zoomOffset++,e.maxZoom--),e.minZoom=Math.max(0,e.minZoom)),"string"==typeof e.subdomains&&(e.subdomains=e.subdomains.split("")),o.Browser.android||this.on("tileunload",this._onTileRemove)},setUrl:function(t,e){return this._url=t,e||this.redraw(),this},createTile:function(t,i){var n=e.createElement("img");return o.DomEvent.on(n,"load",o.bind(this._tileOnLoad,this,i,n)),o.DomEvent.on(n,"error",o.bind(this._tileOnError,this,i,n)),this.options.crossOrigin&&(n.crossOrigin=""),n.alt="",n.setAttribute("role","presentation"),n.src=this.getTileUrl(t),n},getTileUrl:function(t){var e={r:o.Browser.retina?"@2x":"",s:this._getSubdomain(t),x:t.x,y:t.y,z:this._getZoomForUrl()};if(this._map&&!this._map.options.crs.infinite){var i=this._globalTileRange.max.y-t.y;this.options.tms&&(e.y=i),e["-y"]=i}return o.Util.template(this._url,o.extend(e,this.options))},_tileOnLoad:function(t,e){o.Browser.ielt9?setTimeout(o.bind(t,this,null,e),0):t(null,e)},_tileOnError:function(t,e,i){var n=this.options.errorTileUrl;n&&(e.src=n),t(i,e)},getTileSize:function(){var t=this._map,e=o.GridLayer.prototype.getTileSize.call(this),i=this._tileZoom+this.options.zoomOffset,n=this.options.minNativeZoom,s=this.options.maxNativeZoom;return null!==n&&i<n?e.divideBy(t.getZoomScale(n,i)).round():null!==s&&i>s?e.divideBy(t.getZoomScale(s,i)).round():e},_onTileRemove:function(t){t.tile.onload=null},_getZoomForUrl:function(){var t=this._tileZoom,e=this.options.maxZoom,i=this.options.zoomReverse,n=this.options.zoomOffset,o=this.options.minNativeZoom,s=this.options.maxNativeZoom;return i&&(t=e-t),t+=n,null!==o&&t<o?o:null!==s&&t>s?s:t},_getSubdomain:function(t){var e=Math.abs(t.x+t.y)%this.options.subdomains.length;return this.options.subdomains[e]},_abortLoading:function(){var t,e;for(t in this._tiles)this._tiles[t].coords.z!==this._tileZoom&&(e=this._tiles[t].el,e.onload=o.Util.falseFn,e.onerror=o.Util.falseFn,e.complete||(e.src=o.Util.emptyImageUrl,o.DomUtil.remove(e)))}}),o.tileLayer=function(t,e){return new o.TileLayer(t,e)},o.TileLayer.WMS=o.TileLayer.extend({defaultWmsParams:{service:"WMS",request:"GetMap",layers:"",styles:"",format:"image/jpeg",transparent:!1,version:"1.1.1"},options:{crs:null,uppercase:!1},initialize:function(t,e){this._url=t;var i=o.extend({},this.defaultWmsParams);for(var n in e)n in this.options||(i[n]=e[n]);e=o.setOptions(this,e),i.width=i.height=e.tileSize*(e.detectRetina&&o.Browser.retina?2:1),this.wmsParams=i},onAdd:function(t){this._crs=this.options.crs||t.options.crs,this._wmsVersion=parseFloat(this.wmsParams.version);var e=this._wmsVersion>=1.3?"crs":"srs";this.wmsParams[e]=this._crs.code,o.TileLayer.prototype.onAdd.call(this,t)},getTileUrl:function(t){var e=this._tileCoordsToBounds(t),i=this._crs.project(e.getNorthWest()),n=this._crs.project(e.getSouthEast()),s=(this._wmsVersion>=1.3&&this._crs===o.CRS.EPSG4326?[n.y,i.x,i.y,n.x]:[i.x,n.y,n.x,i.y]).join(","),r=o.TileLayer.prototype.getTileUrl.call(this,t);return r+o.Util.getParamString(this.wmsParams,r,this.options.uppercase)+(this.options.uppercase?"&BBOX=":"&bbox=")+s},setParams:function(t,e){return o.extend(this.wmsParams,t),e||this.redraw(),this}}),o.tileLayer.wms=function(t,e){return new o.TileLayer.WMS(t,e)},o.ImageOverlay=o.Layer.extend({options:{opacity:1,alt:"",interactive:!1,crossOrigin:!1},initialize:function(t,e,i){this._url=t,this._bounds=o.latLngBounds(e),o.setOptions(this,i)},onAdd:function(){this._image||(this._initImage(),this.options.opacity<1&&this._updateOpacity()),this.options.interactive&&(o.DomUtil.addClass(this._image,"leaflet-interactive"),this.addInteractiveTarget(this._image)),this.getPane().appendChild(this._image),this._reset()},onRemove:function(){o.DomUtil.remove(this._image),this.options.interactive&&this.removeInteractiveTarget(this._image)},setOpacity:function(t){return this.options.opacity=t,this._image&&this._updateOpacity(),this},setStyle:function(t){return t.opacity&&this.setOpacity(t.opacity),this},bringToFront:function(){return this._map&&o.DomUtil.toFront(this._image),this},bringToBack:function(){return this._map&&o.DomUtil.toBack(this._image),this},setUrl:function(t){return this._url=t,this._image&&(this._image.src=t),this},setBounds:function(t){return this._bounds=t,this._map&&this._reset(),this},getEvents:function(){var t={zoom:this._reset,viewreset:this._reset};return this._zoomAnimated&&(t.zoomanim=this._animateZoom),t},getBounds:function(){return this._bounds},getElement:function(){return this._image},_initImage:function(){var t=this._image=o.DomUtil.create("img","leaflet-image-layer "+(this._zoomAnimated?"leaflet-zoom-animated":""));t.onselectstart=o.Util.falseFn,t.onmousemove=o.Util.falseFn,t.onload=o.bind(this.fire,this,"load"),this.options.crossOrigin&&(t.crossOrigin=""),t.src=this._url,t.alt=this.options.alt},_animateZoom:function(t){var e=this._map.getZoomScale(t.zoom),i=this._map._latLngBoundsToNewLayerBounds(this._bounds,t.zoom,t.center).min;o.DomUtil.setTransform(this._image,i,e)},_reset:function(){var t=this._image,e=new o.Bounds(this._map.latLngToLayerPoint(this._bounds.getNorthWest()),this._map.latLngToLayerPoint(this._bounds.getSouthEast())),i=e.getSize();o.DomUtil.setPosition(t,e.min),t.style.width=i.x+"px",t.style.height=i.y+"px"},_updateOpacity:function(){
  15. o.DomUtil.setOpacity(this._image,this.options.opacity)}}),o.imageOverlay=function(t,e,i){return new o.ImageOverlay(t,e,i)},o.Icon=o.Class.extend({initialize:function(t){o.setOptions(this,t)},createIcon:function(t){return this._createIcon("icon",t)},createShadow:function(t){return this._createIcon("shadow",t)},_createIcon:function(t,e){var i=this._getIconUrl(t);if(!i){if("icon"===t)throw new Error("iconUrl not set in Icon options (see the docs).");return null}var n=this._createImg(i,e&&"IMG"===e.tagName?e:null);return this._setIconStyles(n,t),n},_setIconStyles:function(t,e){var i=this.options,n=i[e+"Size"];"number"==typeof n&&(n=[n,n]);var s=o.point(n),r=o.point("shadow"===e&&i.shadowAnchor||i.iconAnchor||s&&s.divideBy(2,!0));t.className="leaflet-marker-"+e+" "+(i.className||""),r&&(t.style.marginLeft=-r.x+"px",t.style.marginTop=-r.y+"px"),s&&(t.style.width=s.x+"px",t.style.height=s.y+"px")},_createImg:function(t,i){return i=i||e.createElement("img"),i.src=t,i},_getIconUrl:function(t){return o.Browser.retina&&this.options[t+"RetinaUrl"]||this.options[t+"Url"]}}),o.icon=function(t){return new o.Icon(t)},o.Icon.Default=o.Icon.extend({options:{iconUrl:"marker-icon.png",iconRetinaUrl:"marker-icon-2x.png",shadowUrl:"marker-shadow.png",iconSize:[25,41],iconAnchor:[12,41],popupAnchor:[1,-34],tooltipAnchor:[16,-28],shadowSize:[41,41]},_getIconUrl:function(t){return o.Icon.Default.imagePath||(o.Icon.Default.imagePath=this._detectIconPath()),(this.options.imagePath||o.Icon.Default.imagePath)+o.Icon.prototype._getIconUrl.call(this,t)},_detectIconPath:function(){var t=o.DomUtil.create("div","leaflet-default-icon-path",e.body),i=o.DomUtil.getStyle(t,"background-image")||o.DomUtil.getStyle(t,"backgroundImage");return e.body.removeChild(t),0===i.indexOf("url")?i.replace(/^url\([\"\']?/,"").replace(/marker-icon\.png[\"\']?\)$/,""):""}}),o.Marker=o.Layer.extend({options:{icon:new o.Icon.Default,interactive:!0,draggable:!1,keyboard:!0,title:"",alt:"",zIndexOffset:0,opacity:1,riseOnHover:!1,riseOffset:250,pane:"markerPane",nonBubblingEvents:["click","dblclick","mouseover","mouseout","contextmenu"]},initialize:function(t,e){o.setOptions(this,e),this._latlng=o.latLng(t)},onAdd:function(t){this._zoomAnimated=this._zoomAnimated&&t.options.markerZoomAnimation,this._zoomAnimated&&t.on("zoomanim",this._animateZoom,this),this._initIcon(),this.update()},onRemove:function(t){this.dragging&&this.dragging.enabled()&&(this.options.draggable=!0,this.dragging.removeHooks()),this._zoomAnimated&&t.off("zoomanim",this._animateZoom,this),this._removeIcon(),this._removeShadow()},getEvents:function(){return{zoom:this.update,viewreset:this.update}},getLatLng:function(){return this._latlng},setLatLng:function(t){var e=this._latlng;return this._latlng=o.latLng(t),this.update(),this.fire("move",{oldLatLng:e,latlng:this._latlng})},setZIndexOffset:function(t){return this.options.zIndexOffset=t,this.update()},setIcon:function(t){return this.options.icon=t,this._map&&(this._initIcon(),this.update()),this._popup&&this.bindPopup(this._popup,this._popup.options),this},getElement:function(){return this._icon},update:function(){if(this._icon){var t=this._map.latLngToLayerPoint(this._latlng).round();this._setPos(t)}return this},_initIcon:function(){var t=this.options,e="leaflet-zoom-"+(this._zoomAnimated?"animated":"hide"),i=t.icon.createIcon(this._icon),n=!1;i!==this._icon&&(this._icon&&this._removeIcon(),n=!0,t.title&&(i.title=t.title),t.alt&&(i.alt=t.alt)),o.DomUtil.addClass(i,e),t.keyboard&&(i.tabIndex="0"),this._icon=i,t.riseOnHover&&this.on({mouseover:this._bringToFront,mouseout:this._resetZIndex});var s=t.icon.createShadow(this._shadow),r=!1;s!==this._shadow&&(this._removeShadow(),r=!0),s&&o.DomUtil.addClass(s,e),this._shadow=s,t.opacity<1&&this._updateOpacity(),n&&this.getPane().appendChild(this._icon),this._initInteraction(),s&&r&&this.getPane("shadowPane").appendChild(this._shadow)},_removeIcon:function(){this.options.riseOnHover&&this.off({mouseover:this._bringToFront,mouseout:this._resetZIndex}),o.DomUtil.remove(this._icon),this.removeInteractiveTarget(this._icon),this._icon=null},_removeShadow:function(){this._shadow&&o.DomUtil.remove(this._shadow),this._shadow=null},_setPos:function(t){o.DomUtil.setPosition(this._icon,t),this._shadow&&o.DomUtil.setPosition(this._shadow,t),this._zIndex=t.y+this.options.zIndexOffset,this._resetZIndex()},_updateZIndex:function(t){this._icon.style.zIndex=this._zIndex+t},_animateZoom:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center).round();this._setPos(e)},_initInteraction:function(){if(this.options.interactive&&(o.DomUtil.addClass(this._icon,"leaflet-interactive"),this.addInteractiveTarget(this._icon),o.Handler.MarkerDrag)){var t=this.options.draggable;this.dragging&&(t=this.dragging.enabled(),this.dragging.disable()),this.dragging=new o.Handler.MarkerDrag(this),t&&this.dragging.enable()}},setOpacity:function(t){return this.options.opacity=t,this._map&&this._updateOpacity(),this},_updateOpacity:function(){var t=this.options.opacity;o.DomUtil.setOpacity(this._icon,t),this._shadow&&o.DomUtil.setOpacity(this._shadow,t)},_bringToFront:function(){this._updateZIndex(this.options.riseOffset)},_resetZIndex:function(){this._updateZIndex(0)},_getPopupAnchor:function(){return this.options.icon.options.popupAnchor||[0,0]},_getTooltipAnchor:function(){return this.options.icon.options.tooltipAnchor||[0,0]}}),o.marker=function(t,e){return new o.Marker(t,e)},o.DivIcon=o.Icon.extend({options:{iconSize:[12,12],html:!1,bgPos:null,className:"leaflet-div-icon"},createIcon:function(t){var i=t&&"DIV"===t.tagName?t:e.createElement("div"),n=this.options;if(i.innerHTML=n.html!==!1?n.html:"",n.bgPos){var s=o.point(n.bgPos);i.style.backgroundPosition=-s.x+"px "+-s.y+"px"}return this._setIconStyles(i,"icon"),i},createShadow:function(){return null}}),o.divIcon=function(t){return new o.DivIcon(t)},o.DivOverlay=o.Layer.extend({options:{offset:[0,7],className:"",pane:"popupPane"},initialize:function(t,e){o.setOptions(this,t),this._source=e},onAdd:function(t){this._zoomAnimated=t._zoomAnimated,this._container||this._initLayout(),t._fadeAnimated&&o.DomUtil.setOpacity(this._container,0),clearTimeout(this._removeTimeout),this.getPane().appendChild(this._container),this.update(),t._fadeAnimated&&o.DomUtil.setOpacity(this._container,1),this.bringToFront()},onRemove:function(t){t._fadeAnimated?(o.DomUtil.setOpacity(this._container,0),this._removeTimeout=setTimeout(o.bind(o.DomUtil.remove,o.DomUtil,this._container),200)):o.DomUtil.remove(this._container)},getLatLng:function(){return this._latlng},setLatLng:function(t){return this._latlng=o.latLng(t),this._map&&(this._updatePosition(),this._adjustPan()),this},getContent:function(){return this._content},setContent:function(t){return this._content=t,this.update(),this},getElement:function(){return this._container},update:function(){this._map&&(this._container.style.visibility="hidden",this._updateContent(),this._updateLayout(),this._updatePosition(),this._container.style.visibility="",this._adjustPan())},getEvents:function(){var t={zoom:this._updatePosition,viewreset:this._updatePosition};return this._zoomAnimated&&(t.zoomanim=this._animateZoom),t},isOpen:function(){return!!this._map&&this._map.hasLayer(this)},bringToFront:function(){return this._map&&o.DomUtil.toFront(this._container),this},bringToBack:function(){return this._map&&o.DomUtil.toBack(this._container),this},_updateContent:function(){if(this._content){var t=this._contentNode,e="function"==typeof this._content?this._content(this._source||this):this._content;if("string"==typeof e)t.innerHTML=e;else{for(;t.hasChildNodes();)t.removeChild(t.firstChild);t.appendChild(e)}this.fire("contentupdate")}},_updatePosition:function(){if(this._map){var t=this._map.latLngToLayerPoint(this._latlng),e=o.point(this.options.offset),i=this._getAnchor();this._zoomAnimated?o.DomUtil.setPosition(this._container,t.add(i)):e=e.add(t).add(i);var n=this._containerBottom=-e.y,s=this._containerLeft=-Math.round(this._containerWidth/2)+e.x;this._container.style.bottom=n+"px",this._container.style.left=s+"px"}},_getAnchor:function(){return[0,0]}}),o.Popup=o.DivOverlay.extend({options:{maxWidth:300,minWidth:50,maxHeight:null,autoPan:!0,autoPanPaddingTopLeft:null,autoPanPaddingBottomRight:null,autoPanPadding:[5,5],keepInView:!1,closeButton:!0,autoClose:!0,className:""},openOn:function(t){return t.openPopup(this),this},onAdd:function(t){o.DivOverlay.prototype.onAdd.call(this,t),t.fire("popupopen",{popup:this}),this._source&&(this._source.fire("popupopen",{popup:this},!0),this._source instanceof o.Path||this._source.on("preclick",o.DomEvent.stopPropagation))},onRemove:function(t){o.DivOverlay.prototype.onRemove.call(this,t),t.fire("popupclose",{popup:this}),this._source&&(this._source.fire("popupclose",{popup:this},!0),this._source instanceof o.Path||this._source.off("preclick",o.DomEvent.stopPropagation))},getEvents:function(){var t=o.DivOverlay.prototype.getEvents.call(this);return("closeOnClick"in this.options?this.options.closeOnClick:this._map.options.closePopupOnClick)&&(t.preclick=this._close),this.options.keepInView&&(t.moveend=this._adjustPan),t},_close:function(){this._map&&this._map.closePopup(this)},_initLayout:function(){var t="leaflet-popup",e=this._container=o.DomUtil.create("div",t+" "+(this.options.className||"")+" leaflet-zoom-animated");if(this.options.closeButton){var i=this._closeButton=o.DomUtil.create("a",t+"-close-button",e);i.href="#close",i.innerHTML="&#215;",o.DomEvent.on(i,"click",this._onCloseButtonClick,this)}var n=this._wrapper=o.DomUtil.create("div",t+"-content-wrapper",e);this._contentNode=o.DomUtil.create("div",t+"-content",n),o.DomEvent.disableClickPropagation(n).disableScrollPropagation(this._contentNode).on(n,"contextmenu",o.DomEvent.stopPropagation),this._tipContainer=o.DomUtil.create("div",t+"-tip-container",e),this._tip=o.DomUtil.create("div",t+"-tip",this._tipContainer)},_updateLayout:function(){var t=this._contentNode,e=t.style;e.width="",e.whiteSpace="nowrap";var i=t.offsetWidth;i=Math.min(i,this.options.maxWidth),i=Math.max(i,this.options.minWidth),e.width=i+1+"px",e.whiteSpace="",e.height="";var n=t.offsetHeight,s=this.options.maxHeight,r="leaflet-popup-scrolled";s&&n>s?(e.height=s+"px",o.DomUtil.addClass(t,r)):o.DomUtil.removeClass(t,r),this._containerWidth=this._container.offsetWidth},_animateZoom:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center),i=this._getAnchor();o.DomUtil.setPosition(this._container,e.add(i))},_adjustPan:function(){if(!(!this.options.autoPan||this._map._panAnim&&this._map._panAnim._inProgress)){var t=this._map,e=parseInt(o.DomUtil.getStyle(this._container,"marginBottom"),10)||0,i=this._container.offsetHeight+e,n=this._containerWidth,s=new o.Point(this._containerLeft,-i-this._containerBottom);s._add(o.DomUtil.getPosition(this._container));var r=t.layerPointToContainerPoint(s),a=o.point(this.options.autoPanPadding),h=o.point(this.options.autoPanPaddingTopLeft||a),l=o.point(this.options.autoPanPaddingBottomRight||a),u=t.getSize(),c=0,d=0;r.x+n+l.x>u.x&&(c=r.x+n-u.x+l.x),r.x-c-h.x<0&&(c=r.x-h.x),r.y+i+l.y>u.y&&(d=r.y+i-u.y+l.y),r.y-d-h.y<0&&(d=r.y-h.y),(c||d)&&t.fire("autopanstart").panBy([c,d])}},_onCloseButtonClick:function(t){this._close(),o.DomEvent.stop(t)},_getAnchor:function(){return o.point(this._source&&this._source._getPopupAnchor?this._source._getPopupAnchor():[0,0])}}),o.popup=function(t,e){return new o.Popup(t,e)},o.Map.mergeOptions({closePopupOnClick:!0}),o.Map.include({openPopup:function(t,e,i){return t instanceof o.Popup||(t=new o.Popup(i).setContent(t)),e&&t.setLatLng(e),this.hasLayer(t)?this:(this._popup&&this._popup.options.autoClose&&this.closePopup(),this._popup=t,this.addLayer(t))},closePopup:function(t){return t&&t!==this._popup||(t=this._popup,this._popup=null),t&&this.removeLayer(t),this}}),o.Layer.include({bindPopup:function(t,e){return t instanceof o.Popup?(o.setOptions(t,e),this._popup=t,t._source=this):(this._popup&&!e||(this._popup=new o.Popup(e,this)),this._popup.setContent(t)),this._popupHandlersAdded||(this.on({click:this._openPopup,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!0),this},unbindPopup:function(){return this._popup&&(this.off({click:this._openPopup,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!1,this._popup=null),this},openPopup:function(t,e){if(t instanceof o.Layer||(e=t,t=this),t instanceof o.FeatureGroup)for(var i in this._layers){t=this._layers[i];break}return e||(e=t.getCenter?t.getCenter():t.getLatLng()),this._popup&&this._map&&(this._popup._source=t,this._popup.update(),this._map.openPopup(this._popup,e)),this},closePopup:function(){return this._popup&&this._popup._close(),this},togglePopup:function(t){return this._popup&&(this._popup._map?this.closePopup():this.openPopup(t)),this},isPopupOpen:function(){return this._popup.isOpen()},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},getPopup:function(){return this._popup},_openPopup:function(t){var e=t.layer||t.target;if(this._popup&&this._map)return o.DomEvent.stop(t),e instanceof o.Path?void this.openPopup(t.layer||t.target,t.latlng):void(this._map.hasLayer(this._popup)&&this._popup._source===e?this.closePopup():this.openPopup(e,t.latlng))},_movePopup:function(t){this._popup.setLatLng(t.latlng)}}),o.Tooltip=o.DivOverlay.extend({options:{pane:"tooltipPane",offset:[0,0],direction:"auto",permanent:!1,sticky:!1,interactive:!1,opacity:.9},onAdd:function(t){o.DivOverlay.prototype.onAdd.call(this,t),this.setOpacity(this.options.opacity),t.fire("tooltipopen",{tooltip:this}),this._source&&this._source.fire("tooltipopen",{tooltip:this},!0)},onRemove:function(t){o.DivOverlay.prototype.onRemove.call(this,t),t.fire("tooltipclose",{tooltip:this}),this._source&&this._source.fire("tooltipclose",{tooltip:this},!0)},getEvents:function(){var t=o.DivOverlay.prototype.getEvents.call(this);return o.Browser.touch&&!this.options.permanent&&(t.preclick=this._close),t},_close:function(){this._map&&this._map.closeTooltip(this)},_initLayout:function(){var t="leaflet-tooltip",e=t+" "+(this.options.className||"")+" leaflet-zoom-"+(this._zoomAnimated?"animated":"hide");this._contentNode=this._container=o.DomUtil.create("div",e)},_updateLayout:function(){},_adjustPan:function(){},_setPosition:function(t){var e=this._map,i=this._container,n=e.latLngToContainerPoint(e.getCenter()),s=e.layerPointToContainerPoint(t),r=this.options.direction,a=i.offsetWidth,h=i.offsetHeight,l=o.point(this.options.offset),u=this._getAnchor();"top"===r?t=t.add(o.point(-a/2+l.x,-h+l.y+u.y,!0)):"bottom"===r?t=t.subtract(o.point(a/2-l.x,-l.y,!0)):"center"===r?t=t.subtract(o.point(a/2+l.x,h/2-u.y+l.y,!0)):"right"===r||"auto"===r&&s.x<n.x?(r="right",t=t.add(o.point(l.x+u.x,u.y-h/2+l.y,!0))):(r="left",t=t.subtract(o.point(a+u.x-l.x,h/2-u.y-l.y,!0))),o.DomUtil.removeClass(i,"leaflet-tooltip-right"),o.DomUtil.removeClass(i,"leaflet-tooltip-left"),o.DomUtil.removeClass(i,"leaflet-tooltip-top"),o.DomUtil.removeClass(i,"leaflet-tooltip-bottom"),o.DomUtil.addClass(i,"leaflet-tooltip-"+r),o.DomUtil.setPosition(i,t)},_updatePosition:function(){var t=this._map.latLngToLayerPoint(this._latlng);this._setPosition(t)},setOpacity:function(t){this.options.opacity=t,this._container&&o.DomUtil.setOpacity(this._container,t)},_animateZoom:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center);this._setPosition(e)},_getAnchor:function(){return o.point(this._source&&this._source._getTooltipAnchor&&!this.options.sticky?this._source._getTooltipAnchor():[0,0])}}),o.tooltip=function(t,e){return new o.Tooltip(t,e)},o.Map.include({openTooltip:function(t,e,i){return t instanceof o.Tooltip||(t=new o.Tooltip(i).setContent(t)),e&&t.setLatLng(e),this.hasLayer(t)?this:this.addLayer(t)},closeTooltip:function(t){return t&&this.removeLayer(t),this}}),o.Layer.include({bindTooltip:function(t,e){return t instanceof o.Tooltip?(o.setOptions(t,e),this._tooltip=t,t._source=this):(this._tooltip&&!e||(this._tooltip=o.tooltip(e,this)),this._tooltip.setContent(t)),this._initTooltipInteractions(),this._tooltip.options.permanent&&this._map&&this._map.hasLayer(this)&&this.openTooltip(),this},unbindTooltip:function(){return this._tooltip&&(this._initTooltipInteractions(!0),this.closeTooltip(),this._tooltip=null),this},_initTooltipInteractions:function(t){if(t||!this._tooltipHandlersAdded){var e=t?"off":"on",i={remove:this.closeTooltip,move:this._moveTooltip};this._tooltip.options.permanent?i.add=this._openTooltip:(i.mouseover=this._openTooltip,i.mouseout=this.closeTooltip,this._tooltip.options.sticky&&(i.mousemove=this._moveTooltip),o.Browser.touch&&(i.click=this._openTooltip)),this[e](i),this._tooltipHandlersAdded=!t}},openTooltip:function(t,e){if(t instanceof o.Layer||(e=t,t=this),t instanceof o.FeatureGroup)for(var i in this._layers){t=this._layers[i];break}return e||(e=t.getCenter?t.getCenter():t.getLatLng()),this._tooltip&&this._map&&(this._tooltip._source=t,this._tooltip.update(),this._map.openTooltip(this._tooltip,e),this._tooltip.options.interactive&&this._tooltip._container&&(o.DomUtil.addClass(this._tooltip._container,"leaflet-clickable"),this.addInteractiveTarget(this._tooltip._container))),this},closeTooltip:function(){return this._tooltip&&(this._tooltip._close(),this._tooltip.options.interactive&&this._tooltip._container&&(o.DomUtil.removeClass(this._tooltip._container,"leaflet-clickable"),this.removeInteractiveTarget(this._tooltip._container))),this},toggleTooltip:function(t){return this._tooltip&&(this._tooltip._map?this.closeTooltip():this.openTooltip(t)),this},isTooltipOpen:function(){return this._tooltip.isOpen()},setTooltipContent:function(t){return this._tooltip&&this._tooltip.setContent(t),this},getTooltip:function(){return this._tooltip},_openTooltip:function(t){var e=t.layer||t.target;this._tooltip&&this._map&&this.openTooltip(e,this._tooltip.options.sticky?t.latlng:i)},_moveTooltip:function(t){var e,i,n=t.latlng;this._tooltip.options.sticky&&t.originalEvent&&(e=this._map.mouseEventToContainerPoint(t.originalEvent),i=this._map.containerPointToLayerPoint(e),n=this._map.layerPointToLatLng(i)),this._tooltip.setLatLng(n)}}),o.LayerGroup=o.Layer.extend({initialize:function(t){this._layers={};var e,i;if(t)for(e=0,i=t.length;e<i;e++)this.addLayer(t[e])},addLayer:function(t){var e=this.getLayerId(t);return this._layers[e]=t,this._map&&this._map.addLayer(t),this},removeLayer:function(t){var e=t in this._layers?t:this.getLayerId(t);return this._map&&this._layers[e]&&this._map.removeLayer(this._layers[e]),delete this._layers[e],this},hasLayer:function(t){return!!t&&(t in this._layers||this.getLayerId(t)in this._layers)},clearLayers:function(){for(var t in this._layers)this.removeLayer(this._layers[t]);return this},invoke:function(t){var e,i,n=Array.prototype.slice.call(arguments,1);for(e in this._layers)i=this._layers[e],i[t]&&i[t].apply(i,n);return this},onAdd:function(t){for(var e in this._layers)t.addLayer(this._layers[e])},onRemove:function(t){for(var e in this._layers)t.removeLayer(this._layers[e])},eachLayer:function(t,e){for(var i in this._layers)t.call(e,this._layers[i]);return this},getLayer:function(t){return this._layers[t]},getLayers:function(){var t=[];for(var e in this._layers)t.push(this._layers[e]);return t},setZIndex:function(t){return this.invoke("setZIndex",t)},getLayerId:function(t){return o.stamp(t)}}),o.layerGroup=function(t){return new o.LayerGroup(t)},o.FeatureGroup=o.LayerGroup.extend({addLayer:function(t){return this.hasLayer(t)?this:(t.addEventParent(this),o.LayerGroup.prototype.addLayer.call(this,t),this.fire("layeradd",{layer:t}))},removeLayer:function(t){return this.hasLayer(t)?(t in this._layers&&(t=this._layers[t]),t.removeEventParent(this),o.LayerGroup.prototype.removeLayer.call(this,t),this.fire("layerremove",{layer:t})):this},setStyle:function(t){return this.invoke("setStyle",t)},bringToFront:function(){return this.invoke("bringToFront")},bringToBack:function(){return this.invoke("bringToBack")},getBounds:function(){var t=new o.LatLngBounds;for(var e in this._layers){var i=this._layers[e];t.extend(i.getBounds?i.getBounds():i.getLatLng())}return t}}),o.featureGroup=function(t){return new o.FeatureGroup(t)},o.Renderer=o.Layer.extend({options:{padding:.1},initialize:function(t){o.setOptions(this,t),o.stamp(this),this._layers=this._layers||{}},onAdd:function(){this._container||(this._initContainer(),this._zoomAnimated&&o.DomUtil.addClass(this._container,"leaflet-zoom-animated")),this.getPane().appendChild(this._container),this._update(),this.on("update",this._updatePaths,this)},onRemove:function(){o.DomUtil.remove(this._container),this.off("update",this._updatePaths,this)},getEvents:function(){var t={viewreset:this._reset,zoom:this._onZoom,moveend:this._update,zoomend:this._onZoomEnd};return this._zoomAnimated&&(t.zoomanim=this._onAnimZoom),t},_onAnimZoom:function(t){this._updateTransform(t.center,t.zoom)},_onZoom:function(){this._updateTransform(this._map.getCenter(),this._map.getZoom())},_updateTransform:function(t,e){var i=this._map.getZoomScale(e,this._zoom),n=o.DomUtil.getPosition(this._container),s=this._map.getSize().multiplyBy(.5+this.options.padding),r=this._map.project(this._center,e),a=this._map.project(t,e),h=a.subtract(r),l=s.multiplyBy(-i).add(n).add(s).subtract(h);o.Browser.any3d?o.DomUtil.setTransform(this._container,l,i):o.DomUtil.setPosition(this._container,l)},_reset:function(){this._update(),this._updateTransform(this._center,this._zoom);for(var t in this._layers)this._layers[t]._reset()},_onZoomEnd:function(){for(var t in this._layers)this._layers[t]._project()},_updatePaths:function(){for(var t in this._layers)this._layers[t]._update()},_update:function(){var t=this.options.padding,e=this._map.getSize(),i=this._map.containerPointToLayerPoint(e.multiplyBy(-t)).round();this._bounds=new o.Bounds(i,i.add(e.multiplyBy(1+2*t)).round()),this._center=this._map.getCenter(),this._zoom=this._map.getZoom()}}),o.Map.include({getRenderer:function(t){var e=t.options.renderer||this._getPaneRenderer(t.options.pane)||this.options.renderer||this._renderer;return e||(e=this._renderer=this.options.preferCanvas&&o.canvas()||o.svg()),this.hasLayer(e)||this.addLayer(e),e},_getPaneRenderer:function(t){if("overlayPane"===t||t===i)return!1;var e=this._paneRenderers[t];return e===i&&(e=o.SVG&&o.svg({pane:t})||o.Canvas&&o.canvas({pane:t}),this._paneRenderers[t]=e),e}}),o.Path=o.Layer.extend({options:{stroke:!0,color:"#3388ff",weight:3,opacity:1,lineCap:"round",lineJoin:"round",dashArray:null,dashOffset:null,fill:!1,fillColor:null,fillOpacity:.2,fillRule:"evenodd",interactive:!0},beforeAdd:function(t){this._renderer=t.getRenderer(this)},onAdd:function(){this._renderer._initPath(this),this._reset(),this._renderer._addPath(this)},onRemove:function(){this._renderer._removePath(this)},redraw:function(){return this._map&&this._renderer._updatePath(this),this},setStyle:function(t){return o.setOptions(this,t),this._renderer&&this._renderer._updateStyle(this),this},bringToFront:function(){return this._renderer&&this._renderer._bringToFront(this),this},bringToBack:function(){return this._renderer&&this._renderer._bringToBack(this),this},getElement:function(){return this._path},_reset:function(){this._project(),this._update()},_clickTolerance:function(){return(this.options.stroke?this.options.weight/2:0)+(o.Browser.touch?10:0)}}),o.LineUtil={simplify:function(t,e){if(!e||!t.length)return t.slice();var i=e*e;return t=this._reducePoints(t,i),t=this._simplifyDP(t,i)},pointToSegmentDistance:function(t,e,i){return Math.sqrt(this._sqClosestPointOnSegment(t,e,i,!0))},closestPointOnSegment:function(t,e,i){return this._sqClosestPointOnSegment(t,e,i)},_simplifyDP:function(t,e){var n=t.length,o=typeof Uint8Array!=i+""?Uint8Array:Array,s=new o(n);s[0]=s[n-1]=1,this._simplifyDPStep(t,s,e,0,n-1);var r,a=[];for(r=0;r<n;r++)s[r]&&a.push(t[r]);return a},_simplifyDPStep:function(t,e,i,n,o){var s,r,a,h=0;for(r=n+1;r<=o-1;r++)a=this._sqClosestPointOnSegment(t[r],t[n],t[o],!0),a>h&&(s=r,h=a);h>i&&(e[s]=1,this._simplifyDPStep(t,e,i,n,s),this._simplifyDPStep(t,e,i,s,o))},_reducePoints:function(t,e){for(var i=[t[0]],n=1,o=0,s=t.length;n<s;n++)this._sqDist(t[n],t[o])>e&&(i.push(t[n]),o=n);return o<s-1&&i.push(t[s-1]),i},clipSegment:function(t,e,i,n,o){var s,r,a,h=n?this._lastCode:this._getBitCode(t,i),l=this._getBitCode(e,i);for(this._lastCode=l;;){if(!(h|l))return[t,e];if(h&l)return!1;s=h||l,r=this._getEdgeIntersection(t,e,s,i,o),a=this._getBitCode(r,i),s===h?(t=r,h=a):(e=r,l=a)}},_getEdgeIntersection:function(t,e,i,n,s){var r,a,h=e.x-t.x,l=e.y-t.y,u=n.min,c=n.max;return 8&i?(r=t.x+h*(c.y-t.y)/l,a=c.y):4&i?(r=t.x+h*(u.y-t.y)/l,a=u.y):2&i?(r=c.x,a=t.y+l*(c.x-t.x)/h):1&i&&(r=u.x,a=t.y+l*(u.x-t.x)/h),new o.Point(r,a,s)},_getBitCode:function(t,e){var i=0;return t.x<e.min.x?i|=1:t.x>e.max.x&&(i|=2),t.y<e.min.y?i|=4:t.y>e.max.y&&(i|=8),i},_sqDist:function(t,e){var i=e.x-t.x,n=e.y-t.y;return i*i+n*n},_sqClosestPointOnSegment:function(t,e,i,n){var s,r=e.x,a=e.y,h=i.x-r,l=i.y-a,u=h*h+l*l;return u>0&&(s=((t.x-r)*h+(t.y-a)*l)/u,s>1?(r=i.x,a=i.y):s>0&&(r+=h*s,a+=l*s)),h=t.x-r,l=t.y-a,n?h*h+l*l:new o.Point(r,a)}},o.Polyline=o.Path.extend({options:{smoothFactor:1,noClip:!1},initialize:function(t,e){o.setOptions(this,e),this._setLatLngs(t)},getLatLngs:function(){return this._latlngs},setLatLngs:function(t){return this._setLatLngs(t),this.redraw()},isEmpty:function(){return!this._latlngs.length},closestLayerPoint:function(t){for(var e,i,n=1/0,s=null,r=o.LineUtil._sqClosestPointOnSegment,a=0,h=this._parts.length;a<h;a++)for(var l=this._parts[a],u=1,c=l.length;u<c;u++){e=l[u-1],i=l[u];var d=r(t,e,i,!0);d<n&&(n=d,s=r(t,e,i))}return s&&(s.distance=Math.sqrt(n)),s},getCenter:function(){if(!this._map)throw new Error("Must add layer to map before using getCenter()");var t,e,i,n,o,s,r,a=this._rings[0],h=a.length;if(!h)return null;for(t=0,e=0;t<h-1;t++)e+=a[t].distanceTo(a[t+1])/2;if(0===e)return this._map.layerPointToLatLng(a[0]);for(t=0,n=0;t<h-1;t++)if(o=a[t],s=a[t+1],i=o.distanceTo(s),n+=i,n>e)return r=(n-e)/i,this._map.layerPointToLatLng([s.x-r*(s.x-o.x),s.y-r*(s.y-o.y)])},getBounds:function(){return this._bounds},addLatLng:function(t,e){return e=e||this._defaultShape(),t=o.latLng(t),e.push(t),this._bounds.extend(t),this.redraw()},_setLatLngs:function(t){this._bounds=new o.LatLngBounds,this._latlngs=this._convertLatLngs(t)},_defaultShape:function(){return o.Polyline._flat(this._latlngs)?this._latlngs:this._latlngs[0]},_convertLatLngs:function(t){for(var e=[],i=o.Polyline._flat(t),n=0,s=t.length;n<s;n++)i?(e[n]=o.latLng(t[n]),this._bounds.extend(e[n])):e[n]=this._convertLatLngs(t[n]);return e},_project:function(){var t=new o.Bounds;this._rings=[],this._projectLatlngs(this._latlngs,this._rings,t);var e=this._clickTolerance(),i=new o.Point(e,e);this._bounds.isValid()&&t.isValid()&&(t.min._subtract(i),t.max._add(i),this._pxBounds=t)},_projectLatlngs:function(t,e,i){var n,s,r=t[0]instanceof o.LatLng,a=t.length;if(r){for(s=[],n=0;n<a;n++)s[n]=this._map.latLngToLayerPoint(t[n]),i.extend(s[n]);e.push(s)}else for(n=0;n<a;n++)this._projectLatlngs(t[n],e,i)},_clipPoints:function(){var t=this._renderer._bounds;if(this._parts=[],this._pxBounds&&this._pxBounds.intersects(t)){if(this.options.noClip)return void(this._parts=this._rings);var e,i,n,s,r,a,h,l=this._parts;for(e=0,n=0,s=this._rings.length;e<s;e++)for(h=this._rings[e],i=0,r=h.length;i<r-1;i++)a=o.LineUtil.clipSegment(h[i],h[i+1],t,i,!0),a&&(l[n]=l[n]||[],l[n].push(a[0]),a[1]===h[i+1]&&i!==r-2||(l[n].push(a[1]),n++))}},_simplifyPoints:function(){for(var t=this._parts,e=this.options.smoothFactor,i=0,n=t.length;i<n;i++)t[i]=o.LineUtil.simplify(t[i],e)},_update:function(){this._map&&(this._clipPoints(),this._simplifyPoints(),this._updatePath())},_updatePath:function(){this._renderer._updatePoly(this)}}),o.polyline=function(t,e){return new o.Polyline(t,e)},o.Polyline._flat=function(t){return!o.Util.isArray(t[0])||"object"!=typeof t[0][0]&&"undefined"!=typeof t[0][0]},o.PolyUtil={},o.PolyUtil.clipPolygon=function(t,e,i){var n,s,r,a,h,l,u,c,d,_=[1,4,2,8],m=o.LineUtil;for(s=0,u=t.length;s<u;s++)t[s]._code=m._getBitCode(t[s],e);for(a=0;a<4;a++){for(c=_[a],n=[],s=0,u=t.length,r=u-1;s<u;r=s++)h=t[s],l=t[r],h._code&c?l._code&c||(d=m._getEdgeIntersection(l,h,c,e,i),d._code=m._getBitCode(d,e),n.push(d)):(l._code&c&&(d=m._getEdgeIntersection(l,h,c,e,i),d._code=m._getBitCode(d,e),n.push(d)),n.push(h));t=n}return t},o.Polygon=o.Polyline.extend({options:{fill:!0},isEmpty:function(){return!this._latlngs.length||!this._latlngs[0].length},getCenter:function(){if(!this._map)throw new Error("Must add layer to map before using getCenter()");var t,e,i,n,o,s,r,a,h,l=this._rings[0],u=l.length;if(!u)return null;for(s=r=a=0,t=0,e=u-1;t<u;e=t++)i=l[t],n=l[e],o=i.y*n.x-n.y*i.x,r+=(i.x+n.x)*o,a+=(i.y+n.y)*o,s+=3*o;return h=0===s?l[0]:[r/s,a/s],this._map.layerPointToLatLng(h)},_convertLatLngs:function(t){var e=o.Polyline.prototype._convertLatLngs.call(this,t),i=e.length;return i>=2&&e[0]instanceof o.LatLng&&e[0].equals(e[i-1])&&e.pop(),e},_setLatLngs:function(t){o.Polyline.prototype._setLatLngs.call(this,t),o.Polyline._flat(this._latlngs)&&(this._latlngs=[this._latlngs])},_defaultShape:function(){return o.Polyline._flat(this._latlngs[0])?this._latlngs[0]:this._latlngs[0][0]},_clipPoints:function(){var t=this._renderer._bounds,e=this.options.weight,i=new o.Point(e,e);if(t=new o.Bounds(t.min.subtract(i),t.max.add(i)),this._parts=[],this._pxBounds&&this._pxBounds.intersects(t)){if(this.options.noClip)return void(this._parts=this._rings);for(var n,s=0,r=this._rings.length;s<r;s++)n=o.PolyUtil.clipPolygon(this._rings[s],t,!0),n.length&&this._parts.push(n)}},_updatePath:function(){this._renderer._updatePoly(this,!0)}}),o.polygon=function(t,e){return new o.Polygon(t,e)},o.Rectangle=o.Polygon.extend({initialize:function(t,e){o.Polygon.prototype.initialize.call(this,this._boundsToLatLngs(t),e)},setBounds:function(t){return this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return t=o.latLngBounds(t),[t.getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}}),o.rectangle=function(t,e){return new o.Rectangle(t,e)},o.CircleMarker=o.Path.extend({options:{fill:!0,radius:10},initialize:function(t,e){o.setOptions(this,e),this._latlng=o.latLng(t),this._radius=this.options.radius},setLatLng:function(t){return this._latlng=o.latLng(t),this.redraw(),this.fire("move",{latlng:this._latlng})},getLatLng:function(){return this._latlng},setRadius:function(t){return this.options.radius=this._radius=t,this.redraw()},getRadius:function(){return this._radius},setStyle:function(t){var e=t&&t.radius||this._radius;return o.Path.prototype.setStyle.call(this,t),this.setRadius(e),this},_project:function(){this._point=this._map.latLngToLayerPoint(this._latlng),this._updateBounds()},_updateBounds:function(){var t=this._radius,e=this._radiusY||t,i=this._clickTolerance(),n=[t+i,e+i];this._pxBounds=new o.Bounds(this._point.subtract(n),this._point.add(n))},_update:function(){this._map&&this._updatePath()},_updatePath:function(){this._renderer._updateCircle(this)},_empty:function(){return this._radius&&!this._renderer._bounds.intersects(this._pxBounds)}}),o.circleMarker=function(t,e){return new o.CircleMarker(t,e)},o.Circle=o.CircleMarker.extend({initialize:function(t,e,i){if("number"==typeof e&&(e=o.extend({},i,{radius:e})),o.setOptions(this,e),this._latlng=o.latLng(t),isNaN(this.options.radius))throw new Error("Circle radius cannot be NaN");this._mRadius=this.options.radius},setRadius:function(t){return this._mRadius=t,this.redraw()},getRadius:function(){return this._mRadius},getBounds:function(){var t=[this._radius,this._radiusY||this._radius];return new o.LatLngBounds(this._map.layerPointToLatLng(this._point.subtract(t)),this._map.layerPointToLatLng(this._point.add(t)))},setStyle:o.Path.prototype.setStyle,_project:function(){var t=this._latlng.lng,e=this._latlng.lat,i=this._map,n=i.options.crs;
  16. if(n.distance===o.CRS.Earth.distance){var s=Math.PI/180,r=this._mRadius/o.CRS.Earth.R/s,a=i.project([e+r,t]),h=i.project([e-r,t]),l=a.add(h).divideBy(2),u=i.unproject(l).lat,c=Math.acos((Math.cos(r*s)-Math.sin(e*s)*Math.sin(u*s))/(Math.cos(e*s)*Math.cos(u*s)))/s;(isNaN(c)||0===c)&&(c=r/Math.cos(Math.PI/180*e)),this._point=l.subtract(i.getPixelOrigin()),this._radius=isNaN(c)?0:Math.max(Math.round(l.x-i.project([u,t-c]).x),1),this._radiusY=Math.max(Math.round(l.y-a.y),1)}else{var d=n.unproject(n.project(this._latlng).subtract([this._mRadius,0]));this._point=i.latLngToLayerPoint(this._latlng),this._radius=this._point.x-i.latLngToLayerPoint(d).x}this._updateBounds()}}),o.circle=function(t,e,i){return new o.Circle(t,e,i)},o.SVG=o.Renderer.extend({getEvents:function(){var t=o.Renderer.prototype.getEvents.call(this);return t.zoomstart=this._onZoomStart,t},_initContainer:function(){this._container=o.SVG.create("svg"),this._container.setAttribute("pointer-events","none"),this._rootGroup=o.SVG.create("g"),this._container.appendChild(this._rootGroup)},_onZoomStart:function(){this._update()},_update:function(){if(!this._map._animatingZoom||!this._bounds){o.Renderer.prototype._update.call(this);var t=this._bounds,e=t.getSize(),i=this._container;this._svgSize&&this._svgSize.equals(e)||(this._svgSize=e,i.setAttribute("width",e.x),i.setAttribute("height",e.y)),o.DomUtil.setPosition(i,t.min),i.setAttribute("viewBox",[t.min.x,t.min.y,e.x,e.y].join(" ")),this.fire("update")}},_initPath:function(t){var e=t._path=o.SVG.create("path");t.options.className&&o.DomUtil.addClass(e,t.options.className),t.options.interactive&&o.DomUtil.addClass(e,"leaflet-interactive"),this._updateStyle(t),this._layers[o.stamp(t)]=t},_addPath:function(t){this._rootGroup.appendChild(t._path),t.addInteractiveTarget(t._path)},_removePath:function(t){o.DomUtil.remove(t._path),t.removeInteractiveTarget(t._path),delete this._layers[o.stamp(t)]},_updatePath:function(t){t._project(),t._update()},_updateStyle:function(t){var e=t._path,i=t.options;e&&(i.stroke?(e.setAttribute("stroke",i.color),e.setAttribute("stroke-opacity",i.opacity),e.setAttribute("stroke-width",i.weight),e.setAttribute("stroke-linecap",i.lineCap),e.setAttribute("stroke-linejoin",i.lineJoin),i.dashArray?e.setAttribute("stroke-dasharray",i.dashArray):e.removeAttribute("stroke-dasharray"),i.dashOffset?e.setAttribute("stroke-dashoffset",i.dashOffset):e.removeAttribute("stroke-dashoffset")):e.setAttribute("stroke","none"),i.fill?(e.setAttribute("fill",i.fillColor||i.color),e.setAttribute("fill-opacity",i.fillOpacity),e.setAttribute("fill-rule",i.fillRule||"evenodd")):e.setAttribute("fill","none"))},_updatePoly:function(t,e){this._setPath(t,o.SVG.pointsToPath(t._parts,e))},_updateCircle:function(t){var e=t._point,i=t._radius,n=t._radiusY||i,o="a"+i+","+n+" 0 1,0 ",s=t._empty()?"M0 0":"M"+(e.x-i)+","+e.y+o+2*i+",0 "+o+2*-i+",0 ";this._setPath(t,s)},_setPath:function(t,e){t._path.setAttribute("d",e)},_bringToFront:function(t){o.DomUtil.toFront(t._path)},_bringToBack:function(t){o.DomUtil.toBack(t._path)}}),o.extend(o.SVG,{create:function(t){return e.createElementNS("http://www.w3.org/2000/svg",t)},pointsToPath:function(t,e){var i,n,s,r,a,h,l="";for(i=0,s=t.length;i<s;i++){for(a=t[i],n=0,r=a.length;n<r;n++)h=a[n],l+=(n?"L":"M")+h.x+" "+h.y;l+=e?o.Browser.svg?"z":"x":""}return l||"M0 0"}}),o.Browser.svg=!(!e.createElementNS||!o.SVG.create("svg").createSVGRect),o.svg=function(t){return o.Browser.svg||o.Browser.vml?new o.SVG(t):null},o.Browser.vml=!o.Browser.svg&&function(){try{var t=e.createElement("div");t.innerHTML='<v:shape adj="1"/>';var i=t.firstChild;return i.style.behavior="url(#default#VML)",i&&"object"==typeof i.adj}catch(t){return!1}}(),o.SVG.include(o.Browser.vml?{_initContainer:function(){this._container=o.DomUtil.create("div","leaflet-vml-container")},_update:function(){this._map._animatingZoom||(o.Renderer.prototype._update.call(this),this.fire("update"))},_initPath:function(t){var e=t._container=o.SVG.create("shape");o.DomUtil.addClass(e,"leaflet-vml-shape "+(this.options.className||"")),e.coordsize="1 1",t._path=o.SVG.create("path"),e.appendChild(t._path),this._updateStyle(t)},_addPath:function(t){var e=t._container;this._container.appendChild(e),t.options.interactive&&t.addInteractiveTarget(e)},_removePath:function(t){var e=t._container;o.DomUtil.remove(e),t.removeInteractiveTarget(e)},_updateStyle:function(t){var e=t._stroke,i=t._fill,n=t.options,s=t._container;s.stroked=!!n.stroke,s.filled=!!n.fill,n.stroke?(e||(e=t._stroke=o.SVG.create("stroke")),s.appendChild(e),e.weight=n.weight+"px",e.color=n.color,e.opacity=n.opacity,n.dashArray?e.dashStyle=o.Util.isArray(n.dashArray)?n.dashArray.join(" "):n.dashArray.replace(/( *, *)/g," "):e.dashStyle="",e.endcap=n.lineCap.replace("butt","flat"),e.joinstyle=n.lineJoin):e&&(s.removeChild(e),t._stroke=null),n.fill?(i||(i=t._fill=o.SVG.create("fill")),s.appendChild(i),i.color=n.fillColor||n.color,i.opacity=n.fillOpacity):i&&(s.removeChild(i),t._fill=null)},_updateCircle:function(t){var e=t._point.round(),i=Math.round(t._radius),n=Math.round(t._radiusY||i);this._setPath(t,t._empty()?"M0 0":"AL "+e.x+","+e.y+" "+i+","+n+" 0,23592600")},_setPath:function(t,e){t._path.v=e},_bringToFront:function(t){o.DomUtil.toFront(t._container)},_bringToBack:function(t){o.DomUtil.toBack(t._container)}}:{}),o.Browser.vml&&(o.SVG.create=function(){try{return e.namespaces.add("lvml","urn:schemas-microsoft-com:vml"),function(t){return e.createElement("<lvml:"+t+' class="lvml">')}}catch(t){return function(t){return e.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}()),o.Canvas=o.Renderer.extend({onAdd:function(){o.Renderer.prototype.onAdd.call(this),this._draw()},_initContainer:function(){var t=this._container=e.createElement("canvas");o.DomEvent.on(t,"mousemove",o.Util.throttle(this._onMouseMove,32,this),this).on(t,"click dblclick mousedown mouseup contextmenu",this._onClick,this).on(t,"mouseout",this._handleMouseOut,this),this._ctx=t.getContext("2d")},_updatePaths:function(){var t;this._redrawBounds=null;for(var e in this._layers)t=this._layers[e],t._update();this._redraw()},_update:function(){if(!this._map._animatingZoom||!this._bounds){this._drawnLayers={},o.Renderer.prototype._update.call(this);var t=this._bounds,e=this._container,i=t.getSize(),n=o.Browser.retina?2:1;o.DomUtil.setPosition(e,t.min),e.width=n*i.x,e.height=n*i.y,e.style.width=i.x+"px",e.style.height=i.y+"px",o.Browser.retina&&this._ctx.scale(2,2),this._ctx.translate(-t.min.x,-t.min.y),this.fire("update")}},_initPath:function(t){this._updateDashArray(t),this._layers[o.stamp(t)]=t;var e=t._order={layer:t,prev:this._drawLast,next:null};this._drawLast&&(this._drawLast.next=e),this._drawLast=e,this._drawFirst=this._drawFirst||this._drawLast},_addPath:function(t){this._requestRedraw(t)},_removePath:function(t){var e=t._order,i=e.next,n=e.prev;i?i.prev=n:this._drawLast=n,n?n.next=i:this._drawFirst=i,delete t._order,delete this._layers[o.stamp(t)],this._requestRedraw(t)},_updatePath:function(t){this._extendRedrawBounds(t),t._project(),t._update(),this._requestRedraw(t)},_updateStyle:function(t){this._updateDashArray(t),this._requestRedraw(t)},_updateDashArray:function(t){if(t.options.dashArray){var e,i=t.options.dashArray.split(","),n=[];for(e=0;e<i.length;e++)n.push(Number(i[e]));t.options._dashArray=n}},_requestRedraw:function(t){this._map&&(this._extendRedrawBounds(t),this._redrawRequest=this._redrawRequest||o.Util.requestAnimFrame(this._redraw,this))},_extendRedrawBounds:function(t){var e=(t.options.weight||0)+1;this._redrawBounds=this._redrawBounds||new o.Bounds,this._redrawBounds.extend(t._pxBounds.min.subtract([e,e])),this._redrawBounds.extend(t._pxBounds.max.add([e,e]))},_redraw:function(){this._redrawRequest=null,this._clear(),this._draw(),this._redrawBounds=null},_clear:function(){var t=this._redrawBounds;if(t){var e=t.getSize();this._ctx.clearRect(t.min.x,t.min.y,e.x,e.y)}else this._ctx.clearRect(0,0,this._container.width,this._container.height)},_draw:function(){var t,e=this._redrawBounds;if(this._ctx.save(),e){var i=e.getSize();this._ctx.beginPath(),this._ctx.rect(e.min.x,e.min.y,i.x,i.y),this._ctx.clip()}this._drawing=!0;for(var n=this._drawFirst;n;n=n.next)t=n.layer,(!e||t._pxBounds&&t._pxBounds.intersects(e))&&t._updatePath();this._drawing=!1,this._ctx.restore()},_updatePoly:function(t,e){if(this._drawing){var i,n,o,s,r=t._parts,a=r.length,h=this._ctx;if(a){for(this._drawnLayers[t._leaflet_id]=t,h.beginPath(),h.setLineDash&&h.setLineDash(t.options&&t.options._dashArray||[]),i=0;i<a;i++){for(n=0,o=r[i].length;n<o;n++)s=r[i][n],h[n?"lineTo":"moveTo"](s.x,s.y);e&&h.closePath()}this._fillStroke(h,t)}}},_updateCircle:function(t){if(this._drawing&&!t._empty()){var e=t._point,i=this._ctx,n=t._radius,o=(t._radiusY||n)/n;this._drawnLayers[t._leaflet_id]=t,1!==o&&(i.save(),i.scale(1,o)),i.beginPath(),i.arc(e.x,e.y/o,n,0,2*Math.PI,!1),1!==o&&i.restore(),this._fillStroke(i,t)}},_fillStroke:function(t,e){var i=e.options;i.fill&&(t.globalAlpha=i.fillOpacity,t.fillStyle=i.fillColor||i.color,t.fill(i.fillRule||"evenodd")),i.stroke&&0!==i.weight&&(t.globalAlpha=i.opacity,t.lineWidth=i.weight,t.strokeStyle=i.color,t.lineCap=i.lineCap,t.lineJoin=i.lineJoin,t.stroke())},_onClick:function(t){for(var e,i,n=this._map.mouseEventToLayerPoint(t),s=this._drawFirst;s;s=s.next)e=s.layer,e.options.interactive&&e._containsPoint(n)&&!this._map._draggableMoved(e)&&(i=e);i&&(o.DomEvent._fakeStop(t),this._fireEvent([i],t))},_onMouseMove:function(t){if(this._map&&!this._map.dragging.moving()&&!this._map._animatingZoom){var e=this._map.mouseEventToLayerPoint(t);this._handleMouseHover(t,e)}},_handleMouseOut:function(t){var e=this._hoveredLayer;e&&(o.DomUtil.removeClass(this._container,"leaflet-interactive"),this._fireEvent([e],t,"mouseout"),this._hoveredLayer=null)},_handleMouseHover:function(t,e){for(var i,n,s=this._drawFirst;s;s=s.next)i=s.layer,i.options.interactive&&i._containsPoint(e)&&(n=i);n!==this._hoveredLayer&&(this._handleMouseOut(t),n&&(o.DomUtil.addClass(this._container,"leaflet-interactive"),this._fireEvent([n],t,"mouseover"),this._hoveredLayer=n)),this._hoveredLayer&&this._fireEvent([this._hoveredLayer],t)},_fireEvent:function(t,e,i){this._map._fireDOMEvent(e,i||e.type,t)},_bringToFront:function(t){var e=t._order,i=e.next,n=e.prev;i&&(i.prev=n,n?n.next=i:i&&(this._drawFirst=i),e.prev=this._drawLast,this._drawLast.next=e,e.next=null,this._drawLast=e,this._requestRedraw(t))},_bringToBack:function(t){var e=t._order,i=e.next,n=e.prev;n&&(n.next=i,i?i.prev=n:n&&(this._drawLast=n),e.prev=null,e.next=this._drawFirst,this._drawFirst.prev=e,this._drawFirst=e,this._requestRedraw(t))}}),o.Browser.canvas=function(){return!!e.createElement("canvas").getContext}(),o.canvas=function(t){return o.Browser.canvas?new o.Canvas(t):null},o.Polyline.prototype._containsPoint=function(t,e){var i,n,s,r,a,h,l=this._clickTolerance();if(!this._pxBounds.contains(t))return!1;for(i=0,r=this._parts.length;i<r;i++)for(h=this._parts[i],n=0,a=h.length,s=a-1;n<a;s=n++)if((e||0!==n)&&o.LineUtil.pointToSegmentDistance(t,h[s],h[n])<=l)return!0;return!1},o.Polygon.prototype._containsPoint=function(t){var e,i,n,s,r,a,h,l,u=!1;if(!this._pxBounds.contains(t))return!1;for(s=0,h=this._parts.length;s<h;s++)for(e=this._parts[s],r=0,l=e.length,a=l-1;r<l;a=r++)i=e[r],n=e[a],i.y>t.y!=n.y>t.y&&t.x<(n.x-i.x)*(t.y-i.y)/(n.y-i.y)+i.x&&(u=!u);return u||o.Polyline.prototype._containsPoint.call(this,t,!0)},o.CircleMarker.prototype._containsPoint=function(t){return t.distanceTo(this._point)<=this._radius+this._clickTolerance()},o.GeoJSON=o.FeatureGroup.extend({initialize:function(t,e){o.setOptions(this,e),this._layers={},t&&this.addData(t)},addData:function(t){var e,i,n,s=o.Util.isArray(t)?t:t.features;if(s){for(e=0,i=s.length;e<i;e++)n=s[e],(n.geometries||n.geometry||n.features||n.coordinates)&&this.addData(n);return this}var r=this.options;if(r.filter&&!r.filter(t))return this;var a=o.GeoJSON.geometryToLayer(t,r);return a?(a.feature=o.GeoJSON.asFeature(t),a.defaultOptions=a.options,this.resetStyle(a),r.onEachFeature&&r.onEachFeature(t,a),this.addLayer(a)):this},resetStyle:function(t){return t.options=o.Util.extend({},t.defaultOptions),this._setLayerStyle(t,this.options.style),this},setStyle:function(t){return this.eachLayer(function(e){this._setLayerStyle(e,t)},this)},_setLayerStyle:function(t,e){"function"==typeof e&&(e=e(t.feature)),t.setStyle&&t.setStyle(e)}}),o.extend(o.GeoJSON,{geometryToLayer:function(t,e){var i,n,s,r,a="Feature"===t.type?t.geometry:t,h=a?a.coordinates:null,l=[],u=e&&e.pointToLayer,c=e&&e.coordsToLatLng||this.coordsToLatLng;if(!h&&!a)return null;switch(a.type){case"Point":return i=c(h),u?u(t,i):new o.Marker(i);case"MultiPoint":for(s=0,r=h.length;s<r;s++)i=c(h[s]),l.push(u?u(t,i):new o.Marker(i));return new o.FeatureGroup(l);case"LineString":case"MultiLineString":return n=this.coordsToLatLngs(h,"LineString"===a.type?0:1,c),new o.Polyline(n,e);case"Polygon":case"MultiPolygon":return n=this.coordsToLatLngs(h,"Polygon"===a.type?1:2,c),new o.Polygon(n,e);case"GeometryCollection":for(s=0,r=a.geometries.length;s<r;s++){var d=this.geometryToLayer({geometry:a.geometries[s],type:"Feature",properties:t.properties},e);d&&l.push(d)}return new o.FeatureGroup(l);default:throw new Error("Invalid GeoJSON object.")}},coordsToLatLng:function(t){return new o.LatLng(t[1],t[0],t[2])},coordsToLatLngs:function(t,e,i){for(var n,o=[],s=0,r=t.length;s<r;s++)n=e?this.coordsToLatLngs(t[s],e-1,i):(i||this.coordsToLatLng)(t[s]),o.push(n);return o},latLngToCoords:function(t){return t.alt!==i?[t.lng,t.lat,t.alt]:[t.lng,t.lat]},latLngsToCoords:function(t,e,i){for(var n=[],s=0,r=t.length;s<r;s++)n.push(e?o.GeoJSON.latLngsToCoords(t[s],e-1,i):o.GeoJSON.latLngToCoords(t[s]));return!e&&i&&n.push(n[0]),n},getFeature:function(t,e){return t.feature?o.extend({},t.feature,{geometry:e}):o.GeoJSON.asFeature(e)},asFeature:function(t){return"Feature"===t.type||"FeatureCollection"===t.type?t:{type:"Feature",properties:{},geometry:t}}});var a={toGeoJSON:function(){return o.GeoJSON.getFeature(this,{type:"Point",coordinates:o.GeoJSON.latLngToCoords(this.getLatLng())})}};o.Marker.include(a),o.Circle.include(a),o.CircleMarker.include(a),o.Polyline.prototype.toGeoJSON=function(){var t=!o.Polyline._flat(this._latlngs),e=o.GeoJSON.latLngsToCoords(this._latlngs,t?1:0);return o.GeoJSON.getFeature(this,{type:(t?"Multi":"")+"LineString",coordinates:e})},o.Polygon.prototype.toGeoJSON=function(){var t=!o.Polyline._flat(this._latlngs),e=t&&!o.Polyline._flat(this._latlngs[0]),i=o.GeoJSON.latLngsToCoords(this._latlngs,e?2:t?1:0,!0);return t||(i=[i]),o.GeoJSON.getFeature(this,{type:(e?"Multi":"")+"Polygon",coordinates:i})},o.LayerGroup.include({toMultiPoint:function(){var t=[];return this.eachLayer(function(e){t.push(e.toGeoJSON().geometry.coordinates)}),o.GeoJSON.getFeature(this,{type:"MultiPoint",coordinates:t})},toGeoJSON:function(){var t=this.feature&&this.feature.geometry&&this.feature.geometry.type;if("MultiPoint"===t)return this.toMultiPoint();var e="GeometryCollection"===t,i=[];return this.eachLayer(function(t){if(t.toGeoJSON){var n=t.toGeoJSON();i.push(e?n.geometry:o.GeoJSON.asFeature(n))}}),e?o.GeoJSON.getFeature(this,{geometries:i,type:"GeometryCollection"}):{type:"FeatureCollection",features:i}}}),o.geoJSON=function(t,e){return new o.GeoJSON(t,e)},o.geoJson=o.geoJSON,o.Draggable=o.Evented.extend({options:{clickTolerance:3},statics:{START:o.Browser.touch?["touchstart","mousedown"]:["mousedown"],END:{mousedown:"mouseup",touchstart:"touchend",pointerdown:"touchend",MSPointerDown:"touchend"},MOVE:{mousedown:"mousemove",touchstart:"touchmove",pointerdown:"touchmove",MSPointerDown:"touchmove"}},initialize:function(t,e,i){this._element=t,this._dragStartTarget=e||t,this._preventOutline=i},enable:function(){this._enabled||(o.DomEvent.on(this._dragStartTarget,o.Draggable.START.join(" "),this._onDown,this),this._enabled=!0)},disable:function(){this._enabled&&(o.Draggable._dragging===this&&this.finishDrag(),o.DomEvent.off(this._dragStartTarget,o.Draggable.START.join(" "),this._onDown,this),this._enabled=!1,this._moved=!1)},_onDown:function(t){if(!t._simulated&&this._enabled&&(this._moved=!1,!o.DomUtil.hasClass(this._element,"leaflet-zoom-anim")&&!(o.Draggable._dragging||t.shiftKey||1!==t.which&&1!==t.button&&!t.touches||(o.Draggable._dragging=this,this._preventOutline&&o.DomUtil.preventOutline(this._element),o.DomUtil.disableImageDrag(),o.DomUtil.disableTextSelection(),this._moving)))){this.fire("down");var i=t.touches?t.touches[0]:t;this._startPoint=new o.Point(i.clientX,i.clientY),o.DomEvent.on(e,o.Draggable.MOVE[t.type],this._onMove,this).on(e,o.Draggable.END[t.type],this._onUp,this)}},_onMove:function(i){if(!i._simulated&&this._enabled){if(i.touches&&i.touches.length>1)return void(this._moved=!0);var n=i.touches&&1===i.touches.length?i.touches[0]:i,s=new o.Point(n.clientX,n.clientY),r=s.subtract(this._startPoint);(r.x||r.y)&&(Math.abs(r.x)+Math.abs(r.y)<this.options.clickTolerance||(o.DomEvent.preventDefault(i),this._moved||(this.fire("dragstart"),this._moved=!0,this._startPos=o.DomUtil.getPosition(this._element).subtract(r),o.DomUtil.addClass(e.body,"leaflet-dragging"),this._lastTarget=i.target||i.srcElement,t.SVGElementInstance&&this._lastTarget instanceof SVGElementInstance&&(this._lastTarget=this._lastTarget.correspondingUseElement),o.DomUtil.addClass(this._lastTarget,"leaflet-drag-target")),this._newPos=this._startPos.add(r),this._moving=!0,o.Util.cancelAnimFrame(this._animRequest),this._lastEvent=i,this._animRequest=o.Util.requestAnimFrame(this._updatePosition,this,!0)))}},_updatePosition:function(){var t={originalEvent:this._lastEvent};this.fire("predrag",t),o.DomUtil.setPosition(this._element,this._newPos),this.fire("drag",t)},_onUp:function(t){!t._simulated&&this._enabled&&this.finishDrag()},finishDrag:function(){o.DomUtil.removeClass(e.body,"leaflet-dragging"),this._lastTarget&&(o.DomUtil.removeClass(this._lastTarget,"leaflet-drag-target"),this._lastTarget=null);for(var t in o.Draggable.MOVE)o.DomEvent.off(e,o.Draggable.MOVE[t],this._onMove,this).off(e,o.Draggable.END[t],this._onUp,this);o.DomUtil.enableImageDrag(),o.DomUtil.enableTextSelection(),this._moved&&this._moving&&(o.Util.cancelAnimFrame(this._animRequest),this.fire("dragend",{distance:this._newPos.distanceTo(this._startPos)})),this._moving=!1,o.Draggable._dragging=!1}}),o.Handler=o.Class.extend({initialize:function(t){this._map=t},enable:function(){return this._enabled?this:(this._enabled=!0,this.addHooks(),this)},disable:function(){return this._enabled?(this._enabled=!1,this.removeHooks(),this):this},enabled:function(){return!!this._enabled}}),o.Map.mergeOptions({dragging:!0,inertia:!o.Browser.android23,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,easeLinearity:.2,worldCopyJump:!1,maxBoundsViscosity:0}),o.Map.Drag=o.Handler.extend({addHooks:function(){if(!this._draggable){var t=this._map;this._draggable=new o.Draggable(t._mapPane,t._container),this._draggable.on({down:this._onDown,dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this),this._draggable.on("predrag",this._onPreDragLimit,this),t.options.worldCopyJump&&(this._draggable.on("predrag",this._onPreDragWrap,this),t.on("zoomend",this._onZoomEnd,this),t.whenReady(this._onZoomEnd,this))}o.DomUtil.addClass(this._map._container,"leaflet-grab leaflet-touch-drag"),this._draggable.enable(),this._positions=[],this._times=[]},removeHooks:function(){o.DomUtil.removeClass(this._map._container,"leaflet-grab"),o.DomUtil.removeClass(this._map._container,"leaflet-touch-drag"),this._draggable.disable()},moved:function(){return this._draggable&&this._draggable._moved},moving:function(){return this._draggable&&this._draggable._moving},_onDown:function(){this._map._stop()},_onDragStart:function(){var t=this._map;if(this._map.options.maxBounds&&this._map.options.maxBoundsViscosity){var e=o.latLngBounds(this._map.options.maxBounds);this._offsetLimit=o.bounds(this._map.latLngToContainerPoint(e.getNorthWest()).multiplyBy(-1),this._map.latLngToContainerPoint(e.getSouthEast()).multiplyBy(-1).add(this._map.getSize())),this._viscosity=Math.min(1,Math.max(0,this._map.options.maxBoundsViscosity))}else this._offsetLimit=null;t.fire("movestart").fire("dragstart"),t.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(t){if(this._map.options.inertia){var e=this._lastTime=+new Date,i=this._lastPos=this._draggable._absPos||this._draggable._newPos;this._positions.push(i),this._times.push(e),e-this._times[0]>50&&(this._positions.shift(),this._times.shift())}this._map.fire("move",t).fire("drag",t)},_onZoomEnd:function(){var t=this._map.getSize().divideBy(2),e=this._map.latLngToLayerPoint([0,0]);this._initialWorldOffset=e.subtract(t).x,this._worldWidth=this._map.getPixelWorldBounds().getSize().x},_viscousLimit:function(t,e){return t-(t-e)*this._viscosity},_onPreDragLimit:function(){if(this._viscosity&&this._offsetLimit){var t=this._draggable._newPos.subtract(this._draggable._startPos),e=this._offsetLimit;t.x<e.min.x&&(t.x=this._viscousLimit(t.x,e.min.x)),t.y<e.min.y&&(t.y=this._viscousLimit(t.y,e.min.y)),t.x>e.max.x&&(t.x=this._viscousLimit(t.x,e.max.x)),t.y>e.max.y&&(t.y=this._viscousLimit(t.y,e.max.y)),this._draggable._newPos=this._draggable._startPos.add(t)}},_onPreDragWrap:function(){var t=this._worldWidth,e=Math.round(t/2),i=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-e+i)%t+e-i,s=(n+e+i)%t-e-i,r=Math.abs(o+i)<Math.abs(s+i)?o:s;this._draggable._absPos=this._draggable._newPos.clone(),this._draggable._newPos.x=r},_onDragEnd:function(t){var e=this._map,i=e.options,n=!i.inertia||this._times.length<2;if(e.fire("dragend",t),n)e.fire("moveend");else{var s=this._lastPos.subtract(this._positions[0]),r=(this._lastTime-this._times[0])/1e3,a=i.easeLinearity,h=s.multiplyBy(a/r),l=h.distanceTo([0,0]),u=Math.min(i.inertiaMaxSpeed,l),c=h.multiplyBy(u/l),d=u/(i.inertiaDeceleration*a),_=c.multiplyBy(-d/2).round();_.x||_.y?(_=e._limitOffset(_,e.options.maxBounds),o.Util.requestAnimFrame(function(){e.panBy(_,{duration:d,easeLinearity:a,noMoveStart:!0,animate:!0})})):e.fire("moveend")}}}),o.Map.addInitHook("addHandler","dragging",o.Map.Drag),o.Map.mergeOptions({doubleClickZoom:!0}),o.Map.DoubleClickZoom=o.Handler.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var e=this._map,i=e.getZoom(),n=e.options.zoomDelta,o=t.originalEvent.shiftKey?i-n:i+n;"center"===e.options.doubleClickZoom?e.setZoom(o):e.setZoomAround(t.containerPoint,o)}}),o.Map.addInitHook("addHandler","doubleClickZoom",o.Map.DoubleClickZoom),o.Map.mergeOptions({scrollWheelZoom:!0,wheelDebounceTime:40,wheelPxPerZoomLevel:60}),o.Map.ScrollWheelZoom=o.Handler.extend({addHooks:function(){o.DomEvent.on(this._map._container,"mousewheel",this._onWheelScroll,this),this._delta=0},removeHooks:function(){o.DomEvent.off(this._map._container,"mousewheel",this._onWheelScroll,this)},_onWheelScroll:function(t){var e=o.DomEvent.getWheelDelta(t),i=this._map.options.wheelDebounceTime;this._delta+=e,this._lastMousePos=this._map.mouseEventToContainerPoint(t),this._startTime||(this._startTime=+new Date);var n=Math.max(i-(+new Date-this._startTime),0);clearTimeout(this._timer),this._timer=setTimeout(o.bind(this._performZoom,this),n),o.DomEvent.stop(t)},_performZoom:function(){var t=this._map,e=t.getZoom(),i=this._map.options.zoomSnap||0;t._stop();var n=this._delta/(4*this._map.options.wheelPxPerZoomLevel),o=4*Math.log(2/(1+Math.exp(-Math.abs(n))))/Math.LN2,s=i?Math.ceil(o/i)*i:o,r=t._limitZoom(e+(this._delta>0?s:-s))-e;this._delta=0,this._startTime=null,r&&("center"===t.options.scrollWheelZoom?t.setZoom(e+r):t.setZoomAround(this._lastMousePos,e+r))}}),o.Map.addInitHook("addHandler","scrollWheelZoom",o.Map.ScrollWheelZoom),o.extend(o.DomEvent,{_touchstart:o.Browser.msPointer?"MSPointerDown":o.Browser.pointer?"pointerdown":"touchstart",_touchend:o.Browser.msPointer?"MSPointerUp":o.Browser.pointer?"pointerup":"touchend",addDoubleTapListener:function(t,e,i){function n(t){var e;if(e=o.Browser.pointer?o.DomEvent._pointersCount:t.touches.length,!(e>1)){var i=Date.now(),n=i-(r||i);a=t.touches?t.touches[0]:t,h=n>0&&n<=l,r=i}}function s(){if(h&&!a.cancelBubble){if(o.Browser.pointer){var t,i,n={};for(i in a)t=a[i],n[i]=t&&t.bind?t.bind(a):t;a=n}a.type="dblclick",e(a),r=null}}var r,a,h=!1,l=250,u="_leaflet_",c=this._touchstart,d=this._touchend;return t[u+c+i]=n,t[u+d+i]=s,t[u+"dblclick"+i]=e,t.addEventListener(c,n,!1),t.addEventListener(d,s,!1),o.Browser.edge||t.addEventListener("dblclick",e,!1),this},removeDoubleTapListener:function(t,e){var i="_leaflet_",n=t[i+this._touchstart+e],s=t[i+this._touchend+e],r=t[i+"dblclick"+e];return t.removeEventListener(this._touchstart,n,!1),t.removeEventListener(this._touchend,s,!1),o.Browser.edge||t.removeEventListener("dblclick",r,!1),this}}),o.extend(o.DomEvent,{POINTER_DOWN:o.Browser.msPointer?"MSPointerDown":"pointerdown",POINTER_MOVE:o.Browser.msPointer?"MSPointerMove":"pointermove",POINTER_UP:o.Browser.msPointer?"MSPointerUp":"pointerup",POINTER_CANCEL:o.Browser.msPointer?"MSPointerCancel":"pointercancel",TAG_WHITE_LIST:["INPUT","SELECT","OPTION"],_pointers:{},_pointersCount:0,addPointerListener:function(t,e,i,n){return"touchstart"===e?this._addPointerStart(t,i,n):"touchmove"===e?this._addPointerMove(t,i,n):"touchend"===e&&this._addPointerEnd(t,i,n),this},removePointerListener:function(t,e,i){var n=t["_leaflet_"+e+i];return"touchstart"===e?t.removeEventListener(this.POINTER_DOWN,n,!1):"touchmove"===e?t.removeEventListener(this.POINTER_MOVE,n,!1):"touchend"===e&&(t.removeEventListener(this.POINTER_UP,n,!1),t.removeEventListener(this.POINTER_CANCEL,n,!1)),this},_addPointerStart:function(t,i,n){var s=o.bind(function(t){if("mouse"!==t.pointerType&&t.pointerType!==t.MSPOINTER_TYPE_MOUSE){if(!(this.TAG_WHITE_LIST.indexOf(t.target.tagName)<0))return;o.DomEvent.preventDefault(t)}this._handlePointer(t,i)},this);if(t["_leaflet_touchstart"+n]=s,t.addEventListener(this.POINTER_DOWN,s,!1),!this._pointerDocListener){var r=o.bind(this._globalPointerUp,this);e.documentElement.addEventListener(this.POINTER_DOWN,o.bind(this._globalPointerDown,this),!0),e.documentElement.addEventListener(this.POINTER_MOVE,o.bind(this._globalPointerMove,this),!0),e.documentElement.addEventListener(this.POINTER_UP,r,!0),e.documentElement.addEventListener(this.POINTER_CANCEL,r,!0),this._pointerDocListener=!0}},_globalPointerDown:function(t){this._pointers[t.pointerId]=t,this._pointersCount++},_globalPointerMove:function(t){this._pointers[t.pointerId]&&(this._pointers[t.pointerId]=t)},_globalPointerUp:function(t){delete this._pointers[t.pointerId],this._pointersCount--},_handlePointer:function(t,e){t.touches=[];for(var i in this._pointers)t.touches.push(this._pointers[i]);t.changedTouches=[t],e(t)},_addPointerMove:function(t,e,i){var n=o.bind(function(t){(t.pointerType!==t.MSPOINTER_TYPE_MOUSE&&"mouse"!==t.pointerType||0!==t.buttons)&&this._handlePointer(t,e)},this);t["_leaflet_touchmove"+i]=n,t.addEventListener(this.POINTER_MOVE,n,!1)},_addPointerEnd:function(t,e,i){var n=o.bind(function(t){this._handlePointer(t,e)},this);t["_leaflet_touchend"+i]=n,t.addEventListener(this.POINTER_UP,n,!1),t.addEventListener(this.POINTER_CANCEL,n,!1)}}),o.Map.mergeOptions({touchZoom:o.Browser.touch&&!o.Browser.android23,bounceAtZoomLimits:!0}),o.Map.TouchZoom=o.Handler.extend({addHooks:function(){o.DomUtil.addClass(this._map._container,"leaflet-touch-zoom"),o.DomEvent.on(this._map._container,"touchstart",this._onTouchStart,this)},removeHooks:function(){o.DomUtil.removeClass(this._map._container,"leaflet-touch-zoom"),o.DomEvent.off(this._map._container,"touchstart",this._onTouchStart,this)},_onTouchStart:function(t){var i=this._map;if(t.touches&&2===t.touches.length&&!i._animatingZoom&&!this._zooming){var n=i.mouseEventToContainerPoint(t.touches[0]),s=i.mouseEventToContainerPoint(t.touches[1]);this._centerPoint=i.getSize()._divideBy(2),this._startLatLng=i.containerPointToLatLng(this._centerPoint),"center"!==i.options.touchZoom&&(this._pinchStartLatLng=i.containerPointToLatLng(n.add(s)._divideBy(2))),this._startDist=n.distanceTo(s),this._startZoom=i.getZoom(),this._moved=!1,this._zooming=!0,i._stop(),o.DomEvent.on(e,"touchmove",this._onTouchMove,this).on(e,"touchend",this._onTouchEnd,this),o.DomEvent.preventDefault(t)}},_onTouchMove:function(t){if(t.touches&&2===t.touches.length&&this._zooming){var e=this._map,i=e.mouseEventToContainerPoint(t.touches[0]),n=e.mouseEventToContainerPoint(t.touches[1]),s=i.distanceTo(n)/this._startDist;if(this._zoom=e.getScaleZoom(s,this._startZoom),!e.options.bounceAtZoomLimits&&(this._zoom<e.getMinZoom()&&s<1||this._zoom>e.getMaxZoom()&&s>1)&&(this._zoom=e._limitZoom(this._zoom)),"center"===e.options.touchZoom){if(this._center=this._startLatLng,1===s)return}else{var r=i._add(n)._divideBy(2)._subtract(this._centerPoint);if(1===s&&0===r.x&&0===r.y)return;this._center=e.unproject(e.project(this._pinchStartLatLng,this._zoom).subtract(r),this._zoom)}this._moved||(e._moveStart(!0),this._moved=!0),o.Util.cancelAnimFrame(this._animRequest);var a=o.bind(e._move,e,this._center,this._zoom,{pinch:!0,round:!1});this._animRequest=o.Util.requestAnimFrame(a,this,!0),o.DomEvent.preventDefault(t)}},_onTouchEnd:function(){return this._moved&&this._zooming?(this._zooming=!1,o.Util.cancelAnimFrame(this._animRequest),o.DomEvent.off(e,"touchmove",this._onTouchMove).off(e,"touchend",this._onTouchEnd),void(this._map.options.zoomAnimation?this._map._animateZoom(this._center,this._map._limitZoom(this._zoom),!0,this._map.options.zoomSnap):this._map._resetView(this._center,this._map._limitZoom(this._zoom)))):void(this._zooming=!1)}}),o.Map.addInitHook("addHandler","touchZoom",o.Map.TouchZoom),o.Map.mergeOptions({tap:!0,tapTolerance:15}),o.Map.Tap=o.Handler.extend({addHooks:function(){o.DomEvent.on(this._map._container,"touchstart",this._onDown,this)},removeHooks:function(){o.DomEvent.off(this._map._container,"touchstart",this._onDown,this)},_onDown:function(t){if(t.touches){if(o.DomEvent.preventDefault(t),this._fireClick=!0,t.touches.length>1)return this._fireClick=!1,void clearTimeout(this._holdTimeout);var i=t.touches[0],n=i.target;this._startPos=this._newPos=new o.Point(i.clientX,i.clientY),n.tagName&&"a"===n.tagName.toLowerCase()&&o.DomUtil.addClass(n,"leaflet-active"),this._holdTimeout=setTimeout(o.bind(function(){this._isTapValid()&&(this._fireClick=!1,this._onUp(),this._simulateEvent("contextmenu",i))},this),1e3),this._simulateEvent("mousedown",i),o.DomEvent.on(e,{touchmove:this._onMove,touchend:this._onUp},this)}},_onUp:function(t){if(clearTimeout(this._holdTimeout),o.DomEvent.off(e,{touchmove:this._onMove,touchend:this._onUp},this),this._fireClick&&t&&t.changedTouches){var i=t.changedTouches[0],n=i.target;n&&n.tagName&&"a"===n.tagName.toLowerCase()&&o.DomUtil.removeClass(n,"leaflet-active"),this._simulateEvent("mouseup",i),this._isTapValid()&&this._simulateEvent("click",i)}},_isTapValid:function(){return this._newPos.distanceTo(this._startPos)<=this._map.options.tapTolerance},_onMove:function(t){var e=t.touches[0];this._newPos=new o.Point(e.clientX,e.clientY),this._simulateEvent("mousemove",e)},_simulateEvent:function(i,n){var o=e.createEvent("MouseEvents");o._simulated=!0,n.target._simulatedClick=!0,o.initMouseEvent(i,!0,!0,t,1,n.screenX,n.screenY,n.clientX,n.clientY,!1,!1,!1,!1,0,null),n.target.dispatchEvent(o)}}),o.Browser.touch&&!o.Browser.pointer&&o.Map.addInitHook("addHandler","tap",o.Map.Tap),o.Map.mergeOptions({boxZoom:!0}),o.Map.BoxZoom=o.Handler.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane},addHooks:function(){o.DomEvent.on(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){o.DomEvent.off(this._container,"mousedown",this._onMouseDown,this)},moved:function(){return this._moved},_resetState:function(){
  17. this._moved=!1},_onMouseDown:function(t){return!(!t.shiftKey||1!==t.which&&1!==t.button)&&(this._resetState(),o.DomUtil.disableTextSelection(),o.DomUtil.disableImageDrag(),this._startPoint=this._map.mouseEventToContainerPoint(t),void o.DomEvent.on(e,{contextmenu:o.DomEvent.stop,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this))},_onMouseMove:function(t){this._moved||(this._moved=!0,this._box=o.DomUtil.create("div","leaflet-zoom-box",this._container),o.DomUtil.addClass(this._container,"leaflet-crosshair"),this._map.fire("boxzoomstart")),this._point=this._map.mouseEventToContainerPoint(t);var e=new o.Bounds(this._point,this._startPoint),i=e.getSize();o.DomUtil.setPosition(this._box,e.min),this._box.style.width=i.x+"px",this._box.style.height=i.y+"px"},_finish:function(){this._moved&&(o.DomUtil.remove(this._box),o.DomUtil.removeClass(this._container,"leaflet-crosshair")),o.DomUtil.enableTextSelection(),o.DomUtil.enableImageDrag(),o.DomEvent.off(e,{contextmenu:o.DomEvent.stop,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseUp:function(t){if((1===t.which||1===t.button)&&(this._finish(),this._moved)){setTimeout(o.bind(this._resetState,this),0);var e=new o.LatLngBounds(this._map.containerPointToLatLng(this._startPoint),this._map.containerPointToLatLng(this._point));this._map.fitBounds(e).fire("boxzoomend",{boxZoomBounds:e})}},_onKeyDown:function(t){27===t.keyCode&&this._finish()}}),o.Map.addInitHook("addHandler","boxZoom",o.Map.BoxZoom),o.Map.mergeOptions({keyboard:!0,keyboardPanDelta:80}),o.Map.Keyboard=o.Handler.extend({keyCodes:{left:[37],right:[39],down:[40],up:[38],zoomIn:[187,107,61,171],zoomOut:[189,109,54,173]},initialize:function(t){this._map=t,this._setPanDelta(t.options.keyboardPanDelta),this._setZoomDelta(t.options.zoomDelta)},addHooks:function(){var t=this._map._container;t.tabIndex<=0&&(t.tabIndex="0"),o.DomEvent.on(t,{focus:this._onFocus,blur:this._onBlur,mousedown:this._onMouseDown},this),this._map.on({focus:this._addHooks,blur:this._removeHooks},this)},removeHooks:function(){this._removeHooks(),o.DomEvent.off(this._map._container,{focus:this._onFocus,blur:this._onBlur,mousedown:this._onMouseDown},this),this._map.off({focus:this._addHooks,blur:this._removeHooks},this)},_onMouseDown:function(){if(!this._focused){var i=e.body,n=e.documentElement,o=i.scrollTop||n.scrollTop,s=i.scrollLeft||n.scrollLeft;this._map._container.focus(),t.scrollTo(s,o)}},_onFocus:function(){this._focused=!0,this._map.fire("focus")},_onBlur:function(){this._focused=!1,this._map.fire("blur")},_setPanDelta:function(t){var e,i,n=this._panKeys={},o=this.keyCodes;for(e=0,i=o.left.length;e<i;e++)n[o.left[e]]=[-1*t,0];for(e=0,i=o.right.length;e<i;e++)n[o.right[e]]=[t,0];for(e=0,i=o.down.length;e<i;e++)n[o.down[e]]=[0,t];for(e=0,i=o.up.length;e<i;e++)n[o.up[e]]=[0,-1*t]},_setZoomDelta:function(t){var e,i,n=this._zoomKeys={},o=this.keyCodes;for(e=0,i=o.zoomIn.length;e<i;e++)n[o.zoomIn[e]]=t;for(e=0,i=o.zoomOut.length;e<i;e++)n[o.zoomOut[e]]=-t},_addHooks:function(){o.DomEvent.on(e,"keydown",this._onKeyDown,this)},_removeHooks:function(){o.DomEvent.off(e,"keydown",this._onKeyDown,this)},_onKeyDown:function(t){if(!(t.altKey||t.ctrlKey||t.metaKey)){var e,i=t.keyCode,n=this._map;if(i in this._panKeys){if(n._panAnim&&n._panAnim._inProgress)return;e=this._panKeys[i],t.shiftKey&&(e=o.point(e).multiplyBy(3)),n.panBy(e),n.options.maxBounds&&n.panInsideBounds(n.options.maxBounds)}else if(i in this._zoomKeys)n.setZoom(n.getZoom()+(t.shiftKey?3:1)*this._zoomKeys[i]);else{if(27!==i)return;n.closePopup()}o.DomEvent.stop(t)}}}),o.Map.addInitHook("addHandler","keyboard",o.Map.Keyboard),o.Handler.MarkerDrag=o.Handler.extend({initialize:function(t){this._marker=t},addHooks:function(){var t=this._marker._icon;this._draggable||(this._draggable=new o.Draggable(t,t,!0)),this._draggable.on({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this).enable(),o.DomUtil.addClass(t,"leaflet-marker-draggable")},removeHooks:function(){this._draggable.off({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this).disable(),this._marker._icon&&o.DomUtil.removeClass(this._marker._icon,"leaflet-marker-draggable")},moved:function(){return this._draggable&&this._draggable._moved},_onDragStart:function(){this._oldLatLng=this._marker.getLatLng(),this._marker.closePopup().fire("movestart").fire("dragstart")},_onDrag:function(t){var e=this._marker,i=e._shadow,n=o.DomUtil.getPosition(e._icon),s=e._map.layerPointToLatLng(n);i&&o.DomUtil.setPosition(i,n),e._latlng=s,t.latlng=s,t.oldLatLng=this._oldLatLng,e.fire("move",t).fire("drag",t)},_onDragEnd:function(t){delete this._oldLatLng,this._marker.fire("moveend").fire("dragend",t)}}),o.Control=o.Class.extend({options:{position:"topright"},initialize:function(t){o.setOptions(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var e=this._map;return e&&e.removeControl(this),this.options.position=t,e&&e.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this.remove(),this._map=t;var e=this._container=this.onAdd(t),i=this.getPosition(),n=t._controlCorners[i];return o.DomUtil.addClass(e,"leaflet-control"),i.indexOf("bottom")!==-1?n.insertBefore(e,n.firstChild):n.appendChild(e),this},remove:function(){return this._map?(o.DomUtil.remove(this._container),this.onRemove&&this.onRemove(this._map),this._map=null,this):this},_refocusOnMap:function(t){this._map&&t&&t.screenX>0&&t.screenY>0&&this._map.getContainer().focus()}}),o.control=function(t){return new o.Control(t)},o.Map.include({addControl:function(t){return t.addTo(this),this},removeControl:function(t){return t.remove(),this},_initControlPos:function(){function t(t,s){var r=i+t+" "+i+s;e[t+s]=o.DomUtil.create("div",r,n)}var e=this._controlCorners={},i="leaflet-",n=this._controlContainer=o.DomUtil.create("div",i+"control-container",this._container);t("top","left"),t("top","right"),t("bottom","left"),t("bottom","right")},_clearControlPos:function(){o.DomUtil.remove(this._controlContainer)}}),o.Control.Zoom=o.Control.extend({options:{position:"topleft",zoomInText:"+",zoomInTitle:"Zoom in",zoomOutText:"-",zoomOutTitle:"Zoom out"},onAdd:function(t){var e="leaflet-control-zoom",i=o.DomUtil.create("div",e+" leaflet-bar"),n=this.options;return this._zoomInButton=this._createButton(n.zoomInText,n.zoomInTitle,e+"-in",i,this._zoomIn),this._zoomOutButton=this._createButton(n.zoomOutText,n.zoomOutTitle,e+"-out",i,this._zoomOut),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),i},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},disable:function(){return this._disabled=!0,this._updateDisabled(),this},enable:function(){return this._disabled=!1,this._updateDisabled(),this},_zoomIn:function(t){!this._disabled&&this._map._zoom<this._map.getMaxZoom()&&this._map.zoomIn(this._map.options.zoomDelta*(t.shiftKey?3:1))},_zoomOut:function(t){!this._disabled&&this._map._zoom>this._map.getMinZoom()&&this._map.zoomOut(this._map.options.zoomDelta*(t.shiftKey?3:1))},_createButton:function(t,e,i,n,s){var r=o.DomUtil.create("a",i,n);return r.innerHTML=t,r.href="#",r.title=e,r.setAttribute("role","button"),r.setAttribute("aria-label",e),o.DomEvent.on(r,"mousedown dblclick",o.DomEvent.stopPropagation).on(r,"click",o.DomEvent.stop).on(r,"click",s,this).on(r,"click",this._refocusOnMap,this),r},_updateDisabled:function(){var t=this._map,e="leaflet-disabled";o.DomUtil.removeClass(this._zoomInButton,e),o.DomUtil.removeClass(this._zoomOutButton,e),(this._disabled||t._zoom===t.getMinZoom())&&o.DomUtil.addClass(this._zoomOutButton,e),(this._disabled||t._zoom===t.getMaxZoom())&&o.DomUtil.addClass(this._zoomInButton,e)}}),o.Map.mergeOptions({zoomControl:!0}),o.Map.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new o.Control.Zoom,this.addControl(this.zoomControl))}),o.control.zoom=function(t){return new o.Control.Zoom(t)},o.Control.Attribution=o.Control.extend({options:{position:"bottomright",prefix:'<a href="http://leafletjs.com" title="A JS library for interactive maps">Leaflet</a>'},initialize:function(t){o.setOptions(this,t),this._attributions={}},onAdd:function(t){t.attributionControl=this,this._container=o.DomUtil.create("div","leaflet-control-attribution"),o.DomEvent&&o.DomEvent.disableClickPropagation(this._container);for(var e in t._layers)t._layers[e].getAttribution&&this.addAttribution(t._layers[e].getAttribution());return this._update(),this._container},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t?(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update(),this):this},removeAttribution:function(t){return t?(this._attributions[t]&&(this._attributions[t]--,this._update()),this):this},_update:function(){if(this._map){var t=[];for(var e in this._attributions)this._attributions[e]&&t.push(e);var i=[];this.options.prefix&&i.push(this.options.prefix),t.length&&i.push(t.join(", ")),this._container.innerHTML=i.join(" | ")}}}),o.Map.mergeOptions({attributionControl:!0}),o.Map.addInitHook(function(){this.options.attributionControl&&(new o.Control.Attribution).addTo(this)}),o.control.attribution=function(t){return new o.Control.Attribution(t)},o.Control.Scale=o.Control.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0},onAdd:function(t){var e="leaflet-control-scale",i=o.DomUtil.create("div",e),n=this.options;return this._addScales(n,e+"-line",i),t.on(n.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),i},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,e,i){t.metric&&(this._mScale=o.DomUtil.create("div",e,i)),t.imperial&&(this._iScale=o.DomUtil.create("div",e,i))},_update:function(){var t=this._map,e=t.getSize().y/2,i=t.distance(t.containerPointToLatLng([0,e]),t.containerPointToLatLng([this.options.maxWidth,e]));this._updateScales(i)},_updateScales:function(t){this.options.metric&&t&&this._updateMetric(t),this.options.imperial&&t&&this._updateImperial(t)},_updateMetric:function(t){var e=this._getRoundNum(t),i=e<1e3?e+" m":e/1e3+" km";this._updateScale(this._mScale,i,e/t)},_updateImperial:function(t){var e,i,n,o=3.2808399*t;o>5280?(e=o/5280,i=this._getRoundNum(e),this._updateScale(this._iScale,i+" mi",i/e)):(n=this._getRoundNum(o),this._updateScale(this._iScale,n+" ft",n/o))},_updateScale:function(t,e,i){t.style.width=Math.round(this.options.maxWidth*i)+"px",t.innerHTML=e},_getRoundNum:function(t){var e=Math.pow(10,(Math.floor(t)+"").length-1),i=t/e;return i=i>=10?10:i>=5?5:i>=3?3:i>=2?2:1,e*i}}),o.control.scale=function(t){return new o.Control.Scale(t)},o.Control.Layers=o.Control.extend({options:{collapsed:!0,position:"topright",autoZIndex:!0,hideSingleBase:!1,sortLayers:!1,sortFunction:function(t,e,i,n){return i<n?-1:n<i?1:0}},initialize:function(t,e,i){o.setOptions(this,i),this._layers=[],this._lastZIndex=0,this._handlingClick=!1;for(var n in t)this._addLayer(t[n],n);for(n in e)this._addLayer(e[n],n,!0)},onAdd:function(t){return this._initLayout(),this._update(),this._map=t,t.on("zoomend",this._checkDisabledLayers,this),this._container},onRemove:function(){this._map.off("zoomend",this._checkDisabledLayers,this);for(var t=0;t<this._layers.length;t++)this._layers[t].layer.off("add remove",this._onLayerChange,this)},addBaseLayer:function(t,e){return this._addLayer(t,e),this._map?this._update():this},addOverlay:function(t,e){return this._addLayer(t,e,!0),this._map?this._update():this},removeLayer:function(t){t.off("add remove",this._onLayerChange,this);var e=this._getLayer(o.stamp(t));return e&&this._layers.splice(this._layers.indexOf(e),1),this._map?this._update():this},expand:function(){o.DomUtil.addClass(this._container,"leaflet-control-layers-expanded"),this._form.style.height=null;var t=this._map.getSize().y-(this._container.offsetTop+50);return t<this._form.clientHeight?(o.DomUtil.addClass(this._form,"leaflet-control-layers-scrollbar"),this._form.style.height=t+"px"):o.DomUtil.removeClass(this._form,"leaflet-control-layers-scrollbar"),this._checkDisabledLayers(),this},collapse:function(){return o.DomUtil.removeClass(this._container,"leaflet-control-layers-expanded"),this},_initLayout:function(){var t="leaflet-control-layers",e=this._container=o.DomUtil.create("div",t);e.setAttribute("aria-haspopup",!0),o.DomEvent.disableClickPropagation(e),o.Browser.touch||o.DomEvent.disableScrollPropagation(e);var i=this._form=o.DomUtil.create("form",t+"-list");o.Browser.android||o.DomEvent.on(e,{mouseenter:this.expand,mouseleave:this.collapse},this);var n=this._layersLink=o.DomUtil.create("a",t+"-toggle",e);n.href="#",n.title="Layers",o.Browser.touch?o.DomEvent.on(n,"click",o.DomEvent.stop).on(n,"click",this.expand,this):o.DomEvent.on(n,"focus",this.expand,this),o.DomEvent.on(i,"click",function(){setTimeout(o.bind(this._onInputClick,this),0)},this),this._map.on("click",this.collapse,this),this.options.collapsed||this.expand(),this._baseLayersList=o.DomUtil.create("div",t+"-base",i),this._separator=o.DomUtil.create("div",t+"-separator",i),this._overlaysList=o.DomUtil.create("div",t+"-overlays",i),e.appendChild(i)},_getLayer:function(t){for(var e=0;e<this._layers.length;e++)if(this._layers[e]&&o.stamp(this._layers[e].layer)===t)return this._layers[e]},_addLayer:function(t,e,i){t.on("add remove",this._onLayerChange,this),this._layers.push({layer:t,name:e,overlay:i}),this.options.sortLayers&&this._layers.sort(o.bind(function(t,e){return this.options.sortFunction(t.layer,e.layer,t.name,e.name)},this)),this.options.autoZIndex&&t.setZIndex&&(this._lastZIndex++,t.setZIndex(this._lastZIndex))},_update:function(){if(!this._container)return this;o.DomUtil.empty(this._baseLayersList),o.DomUtil.empty(this._overlaysList);var t,e,i,n,s=0;for(i=0;i<this._layers.length;i++)n=this._layers[i],this._addItem(n),e=e||n.overlay,t=t||!n.overlay,s+=n.overlay?0:1;return this.options.hideSingleBase&&(t=t&&s>1,this._baseLayersList.style.display=t?"":"none"),this._separator.style.display=e&&t?"":"none",this},_onLayerChange:function(t){this._handlingClick||this._update();var e=this._getLayer(o.stamp(t.target)),i=e.overlay?"add"===t.type?"overlayadd":"overlayremove":"add"===t.type?"baselayerchange":null;i&&this._map.fire(i,e)},_createRadioElement:function(t,i){var n='<input type="radio" class="leaflet-control-layers-selector" name="'+t+'"'+(i?' checked="checked"':"")+"/>",o=e.createElement("div");return o.innerHTML=n,o.firstChild},_addItem:function(t){var i,n=e.createElement("label"),s=this._map.hasLayer(t.layer);t.overlay?(i=e.createElement("input"),i.type="checkbox",i.className="leaflet-control-layers-selector",i.defaultChecked=s):i=this._createRadioElement("leaflet-base-layers",s),i.layerId=o.stamp(t.layer),o.DomEvent.on(i,"click",this._onInputClick,this);var r=e.createElement("span");r.innerHTML=" "+t.name;var a=e.createElement("div");n.appendChild(a),a.appendChild(i),a.appendChild(r);var h=t.overlay?this._overlaysList:this._baseLayersList;return h.appendChild(n),this._checkDisabledLayers(),n},_onInputClick:function(){var t,e,i,n=this._form.getElementsByTagName("input"),o=[],s=[];this._handlingClick=!0;for(var r=n.length-1;r>=0;r--)t=n[r],e=this._getLayer(t.layerId).layer,i=this._map.hasLayer(e),t.checked&&!i?o.push(e):!t.checked&&i&&s.push(e);for(r=0;r<s.length;r++)this._map.removeLayer(s[r]);for(r=0;r<o.length;r++)this._map.addLayer(o[r]);this._handlingClick=!1,this._refocusOnMap()},_checkDisabledLayers:function(){for(var t,e,n=this._form.getElementsByTagName("input"),o=this._map.getZoom(),s=n.length-1;s>=0;s--)t=n[s],e=this._getLayer(t.layerId).layer,t.disabled=e.options.minZoom!==i&&o<e.options.minZoom||e.options.maxZoom!==i&&o>e.options.maxZoom},_expand:function(){return this.expand()},_collapse:function(){return this.collapse()}}),o.control.layers=function(t,e,i){return new o.Control.Layers(t,e,i)}}(window,document);
  18. /**
  19. * 经纬度转墨卡托
  20. */
  21. L.Util.transformMercator =function(lonLat){
  22. var mercator = {};
  23. var x = lonLat.x * 20037508.34 / 180;
  24. var y = Math.log(Math.tan((90 + lonLat.y) * Math.PI / 360)) / (Math.PI / 180);
  25. y = y * 20037508.34 / 180;
  26. mercator.x = x;
  27. mercator.y = y;
  28. return mercator;
  29. };
  30. /**
  31. * 墨卡托转经纬度
  32. */
  33. L.Util.transformMercator =function(lonLat){
  34. var mercator = {};
  35. var x = lonLat.x * 20037508.34 / 180;
  36. var y = Math.log(Math.tan((90 + lonLat.y) * Math.PI / 360)) / (Math.PI / 180);
  37. y = y * 20037508.34 / 180;
  38. mercator.x = x;
  39. mercator.y = y;
  40. return mercator;
  41. };
  42. /**
  43. * 航向量算
  44. */
  45. L.Util.getAngleByLatLng = function(startLong,startLat,endLong,endLat){
  46. startLong = parseFloat(startLong);
  47. startLat = parseFloat(startLat);
  48. endLong = parseFloat(endLong);
  49. endLat = parseFloat(endLat);
  50. var stsrtP = {
  51. x:startLong,
  52. y:startLat
  53. };
  54. var endP = {};
  55. endP.x=endLong;
  56. endP.y=endLat;
  57. var startPX_LatLongCoords = startLong;
  58. var startPY_LatLongCoords = startLat;
  59. var endPX_LatLongCoords = endLong;
  60. var endPY_LatLongCoords = endLat;
  61. var zhongjianX;
  62. var zhongjianY;
  63. zhongjianX = startPX_LatLongCoords > endPX_LatLongCoords ? startPX_LatLongCoords : endPX_LatLongCoords;
  64. zhongjianY = startPX_LatLongCoords > endPX_LatLongCoords ? startPY_LatLongCoords : endPY_LatLongCoords;
  65. var thirdX = zhongjianX;
  66. var thirdY = zhongjianY + 0.001;
  67. var prjParaPointC = {};
  68. prjParaPointC.x=thirdX;
  69. prjParaPointC.y=thirdY;
  70. stsrtP = L.Util.transformMercator(stsrtP);
  71. endP = L.Util.transformMercator(endP);
  72. var startPX = stsrtP.x;
  73. var startPY = stsrtP.y;
  74. var endPX = endP.x;
  75. var endPY = endP.y;
  76. prjParaPointC = L.Util.transformMercator(prjParaPointC);
  77. var objChangeCx = prjParaPointC.x;
  78. var objChangeCy = prjParaPointC.y;
  79. //有三点计算角度,使用向量方法
  80. var mx, my, ax, ay, bx, by, ma_x, ma_y, mb_x, mb_y;
  81. mx = startPX_LatLongCoords > endPX_LatLongCoords ? startPX : endPX;
  82. my = startPX_LatLongCoords > endPX_LatLongCoords ? startPY : endPY;
  83. if (mx == startPX && my == startPY) {
  84. ax = endPX;
  85. ay = endPY;
  86. } else {
  87. ax = startPX;
  88. ay = startPY;
  89. }
  90. bx = objChangeCx;
  91. by = objChangeCy;
  92. ma_x = ax - mx;
  93. ma_y = ay - my;
  94. mb_x = bx - mx;
  95. mb_y = by - my;
  96. var v1 = (ma_x * mb_x) + (ma_y * mb_y);
  97. var ma_val = Math.sqrt(ma_x * ma_x + ma_y * ma_y);
  98. var mb_val = Math.sqrt(mb_x * mb_x + mb_y * mb_y);
  99. var cosM = v1 / (ma_val * mb_val);
  100. var angleAMB = Math.acos(cosM) * 180 / Math.PI;
  101. var xiangxian = 0; // 定义象限变量
  102. var lastAngle = 0;
  103. if ((endPY_LatLongCoords - startPY_LatLongCoords) > 0 && (endPX_LatLongCoords - startPX_LatLongCoords) == 0) {
  104. lastAngle = 0;
  105. } else if ((endPY_LatLongCoords - startPY_LatLongCoords) == 0
  106. && (endPX_LatLongCoords - startPX_LatLongCoords) > 0) {
  107. lastAngle = 90;
  108. } else if ((endPY_LatLongCoords - startPY_LatLongCoords) < 0
  109. && (endPX_LatLongCoords - startPX_LatLongCoords) == 0) {
  110. lastAngle = 180;
  111. } else if ((endPY_LatLongCoords - startPY_LatLongCoords) == 0
  112. && (endPX_LatLongCoords - startPX_LatLongCoords) < 0) {
  113. lastAngle = 270;
  114. } else if ((endPY_LatLongCoords - startPY_LatLongCoords) > 0
  115. && (endPX_LatLongCoords - startPX_LatLongCoords) > 0) {
  116. xiangxian = 1;
  117. } else if ((endPY_LatLongCoords - startPY_LatLongCoords) > 0
  118. && (endPX_LatLongCoords - startPX_LatLongCoords) < 0) {
  119. xiangxian = 2;
  120. } else if ((endPY_LatLongCoords - startPY_LatLongCoords) < 0
  121. && (endPX_LatLongCoords - startPX_LatLongCoords) < 0) {
  122. xiangxian = 3;
  123. } else if ((endPY_LatLongCoords - startPY_LatLongCoords) < 0
  124. && (endPX_LatLongCoords - startPX_LatLongCoords) > 0) {
  125. xiangxian = 4;
  126. };
  127. switch (xiangxian) {
  128. case 1:
  129. lastAngle = 180 - angleAMB;
  130. break;
  131. case 2:
  132. lastAngle = 360 - angleAMB;
  133. break;
  134. case 3:
  135. lastAngle = 360 - angleAMB;
  136. break;
  137. case 4:
  138. lastAngle = 180 - angleAMB;
  139. break;
  140. default:
  141. //alert("none");
  142. }
  143. return parseInt(Math.round(lastAngle));
  144. }
  145. /**
  146. * 判断是否是合法的经纬度
  147. * @param {[type]} lat [纬度]
  148. * @param {[type]} lng [经度]
  149. * @return {[type]} [布尔值]
  150. */
  151. L.Util.verifyLatLng = function(lat, lng) {
  152. if (parseFloat(lat) >= -90 && parseFloat(lat) <= 90 && parseFloat(lng) >= -180 && parseFloat(lng) <= 180) {
  153. return true;
  154. } else {
  155. return false;
  156. }
  157. };
  158. /**
  159. * 地球坐标纠正
  160. * @param {[type]} latlng [description]
  161. * @return {[type]} [description]
  162. */
  163. L.Util.formatEarthLatLng = function(latlng){
  164. var lat = latlng.hasOwnProperty('lat') ? latlng.lat : latlng[0];
  165. var lng = latlng.hasOwnProperty('lng') ? latlng.lng : latlng[1];
  166. lng = lng%360;
  167. if(lng>180){
  168. lng = (lng%180)-180;
  169. }else if(lng<-180){
  170. lng = 180+(lng%180);
  171. }
  172. return new L.LatLng(lat,lng);
  173. };
  174. /**
  175. * 十进制经纬度转度分秒
  176. * @param {[type]} latlng [对象或数组]
  177. * @return {[type]} [度分秒]
  178. */
  179. L.Util.formatHMS = function(latlng) {
  180. var lat = latlng.hasOwnProperty('lat') ? latlng.lat : latlng[0];
  181. var lng = latlng.hasOwnProperty('lng') ? latlng.lng : latlng[1];
  182. lng = lng%360;
  183. if(lng>180){
  184. lng = (lng%180)-180;
  185. }else if(lng<-180){
  186. lng = 180+(lng%180);
  187. }
  188. function setHMS(f) {
  189. f = parseInt(f * 3600);
  190. var h = parseInt(f / 3600);
  191. var m = parseInt((f - h * 3600) / 60);
  192. var s = parseInt((f - h * 3600 - m * 60));
  193. if (m.toString().length == 1) {
  194. m = '0' + m.toString();
  195. }
  196. if (s.toString().length == 1) {
  197. s = '0' + s.toString();
  198. }
  199. return h + '\u00b0' + m + '\u2032' + s + '\u2033';
  200. }
  201. var nLat = '';
  202. var nLng = '';
  203. if (lat < 0) {
  204. nLat = setHMS(lat * -1)+'S';
  205. } else {
  206. nLat = setHMS(lat)+'N';
  207. }
  208. if (lng < 0) {
  209. nLng = setHMS(lng * -1)+'W';
  210. } else {
  211. nLng = setHMS(lng)+'E';
  212. }
  213. return {
  214. lat: nLat,
  215. lng: nLng
  216. };
  217. };
  218. /**
  219. * 度分秒转经纬度
  220. * @param {[type]} p [方位]
  221. * @param {[type]} d [度]
  222. * @param {[type]} f [分]
  223. * @param {[type]} m [秒]
  224. */
  225. L.Util.HMStoLatLng = function(p, d, f, m) {
  226. var dfm = parseFloat(d) + parseFloat(f) / 60 + parseFloat(m) / 3600;
  227. if (p.toLowerCase() === 'w' || p.toLowerCase() === 's') {
  228. dfm = -1 * dfm;
  229. }
  230. return dfm;
  231. };
  232. /**
  233. * 获取弧线的节点坐标数组
  234. * @type {Function}
  235. * @param points
  236. * @returns {Array}
  237. * @private
  238. */
  239. L.Util.getCurvePoints = function(points){
  240. var getCurve = function(start,finish,segments){
  241. var startlat = start.lat;
  242. var startlon = start.lng;
  243. var finishlat = finish.lat;
  244. var finishlon = finish.lng;
  245. var segments = segments;
  246. var curveAry = [];
  247. var lat1 = startlat * (Math.PI / 180);
  248. var lon1 = startlon * (Math.PI / 180);
  249. var lat2 = finishlat * (Math.PI / 180);
  250. var lon2 = finishlon * (Math.PI / 180);
  251. var d = 2 * Math.asin(Math.sqrt(Math.pow((Math.sin((lat1-lat2)/2)),2)+Math.cos(lat1)*Math.cos(lat2)*Math.pow((Math.sin((lon1-lon2)/2)),2)));
  252. for(var n= 0; n<segments+1;n++){
  253. var f = (1/segments)*n;
  254. var A = Math.sin((1-f)*d)/Math.sin(d);
  255. var B = Math.sin(f*d)/Math.sin(d);
  256. var x = A * Math.cos(lat1)*Math.cos(lon1) + B*Math.cos(lat2)*Math.cos(lon2);
  257. var y = A * Math.cos(lat1)*Math.sin(lon1) + B*Math.cos(lat2)*Math.sin(lon2);
  258. var z = A * Math.sin(lat1) + B * Math.sin(lat2);
  259. var lat = Math.atan2(z,Math.sqrt(Math.pow(x,2)+Math.pow(y,2)));
  260. var lon = Math.atan2(y,x);
  261. try{
  262. var temp = L.latLng(lat/(Math.PI/180),lon/(Math.PI/180));
  263. curveAry.push(temp);
  264. }catch (e){
  265. }
  266. }
  267. return curveAry;
  268. };
  269. var curvePoints = [];
  270. for(var i = 0; i < points.length-1;i++){
  271. if(points[i]['lat'] == points[i+1]['lat'] && points[i]['lng'] == points[i+1]['lng']){
  272. curvePoints = curvePoints.concat(points[i]);
  273. }else {
  274. var p = getCurve(points[i],points[i+1],20);
  275. if(p && p.length > 0){
  276. curvePoints = curvePoints.concat(p);
  277. }
  278. }
  279. }
  280. return curvePoints;
  281. },
  282. /**
  283. * 画大圆标绘坐标转换
  284. */
  285. L.Util.circleDrawLatlng = function(poly){
  286. var distance = [];
  287. var lineDistance;
  288. if(poly._latlngs.length ===1){
  289. poly._latlngs = poly._latlngs[0];
  290. for(i=0,l=poly._latlngs.length;i<l;i++){
  291. if(i<poly._latlngs.length-1){
  292. lineDistance = poly._latlngs[i].distanceTo(poly._latlngs[i+1]);
  293. }
  294. else{
  295. lineDistance = poly._latlngs[i].distanceTo(poly._latlngs[0]);
  296. }
  297. distance.push(lineDistance);
  298. }
  299. }else{
  300. for(i=0,l=poly._latlngs.length;i<l;i++){
  301. if(i<poly._latlngs.length-1){
  302. lineDistance = poly._latlngs[i].distanceTo(poly._latlngs[i+1]);
  303. distance.push(lineDistance);
  304. }
  305. }
  306. }
  307. var segments;
  308. var bigcurveAry = [];
  309. for (i = 0, l = poly._latlngs.length; i < l ; i++) {
  310. var startlat = poly._latlngs[i].lat;
  311. var startlon = poly._latlngs[i].lng;
  312. if(i==poly._latlngs.length-1){
  313. var finishlat = poly._latlngs[0].lat;
  314. var finishlon = poly._latlngs[0].lng;
  315. }
  316. else{
  317. var finishlat = poly._latlngs[i + 1].lat;
  318. var finishlon = poly._latlngs[i + 1].lng;
  319. }
  320. var curveAry = [];
  321. var lat1 = startlat * (Math.PI / 180);
  322. var lon1 = startlon * (Math.PI / 180);
  323. var lat2 = finishlat * (Math.PI / 180);
  324. var lon2 = finishlon * (Math.PI / 180);
  325. var d = 2 * Math.asin(Math.sqrt(Math.pow((Math.sin((lat1 - lat2) / 2)), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow((Math.sin((lon1 - lon2) / 2)), 2)));
  326. segments = Math.ceil((distance[i] / 1000) / 100);
  327. for (var n = 0; n < segments + 1; n++) {
  328. var f = (1 / segments) * n;
  329. var A = Math.sin((1 - f) * d) / Math.sin(d);
  330. var B = Math.sin(f * d) / Math.sin(d);
  331. var x = A * Math.cos(lat1) * Math.cos(lon1) + B * Math.cos(lat2) * Math.cos(lon2);
  332. var y = A * Math.cos(lat1) * Math.sin(lon1) + B * Math.cos(lat2) * Math.sin(lon2);
  333. var z = A * Math.sin(lat1) + B * Math.sin(lat2);
  334. var lat = Math.atan2(z, Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));
  335. var lon = Math.atan2(y, x);
  336. try {
  337. var temp = L.latLng(lat / (Math.PI / 180), lon / (Math.PI / 180));
  338. curveAry.push(temp);
  339. bigcurveAry.push(temp);
  340. } catch (e) {
  341. }
  342. }
  343. }
  344. //return bigcurveAry;
  345. poly.setLatLngs(bigcurveAry);
  346. },
  347. /**
  348. * ajax 方法 支持jsonp
  349. * @param {[type]} url [提交url]
  350. * @param {[type]} options [参数]
  351. * @param {Function} cb [回调方法]
  352. * @return {[type]} [description]
  353. */
  354. L.Util.ajax = function (url,options, cb) {
  355. var cbName,ourl,cbSuffix,scriptNode, head, cbParam, XMHreq;
  356. try{
  357. if(typeof options === "function"){
  358. cb = options;
  359. options = {};
  360. }
  361. if(options.jsonp){
  362. head = document.getElementsByTagName('head')[0];
  363. cbParam = options.cbParam || "callback";
  364. if(options.callbackName){
  365. cbName= options.callbackName;
  366. }else{
  367. cbSuffix = "_" + ("" + Math.random()).slice(2);
  368. cbName = "L.Util.ajax.cb." + cbSuffix;
  369. }
  370. scriptNode = document.createElement('script');
  371. scriptNode.setAttribute('type','text/javascript');
  372. if (url.indexOf("?") === -1 ){
  373. ourl = url+"?"+cbParam+"="+cbName;
  374. }else{
  375. ourl = url+"&"+cbParam+"="+cbName;
  376. }
  377. scriptNode.setAttribute('src',ourl);
  378. head.appendChild(scriptNode);
  379. if(cbSuffix) {
  380. L.Util.ajax.cb[cbSuffix] = function(data){
  381. delete L.Util.ajax.cb[cbSuffix];
  382. cb(data);
  383. head.removeChild(scriptNode);
  384. };
  385. }
  386. return {abort:function(){return false;}};
  387. }else{
  388. // the following is from JavaScript: The Definitive Guide
  389. if (window.XMLHttpRequest === undefined) {
  390. XMHreq = function() {
  391. try {
  392. return new ActiveXObject("Microsoft.XMLHTTP");
  393. //return new ActiveXObject("Microsoft.XMLHTTP.6.0");
  394. }
  395. catch (e1) {
  396. try {
  397. return new ActiveXObject("Microsoft.XMLHTTP.3.0");
  398. }
  399. catch (e2) {
  400. throw new Error("XMLHttpRequest is not supported");
  401. }
  402. }
  403. };
  404. }else{
  405. XMHreq = window.XMLHttpRequest;
  406. }
  407. var response, request = new XMHreq();
  408. request.open("GET", url);
  409. request.onreadystatechange = function() {
  410. if (request.readyState === 4 && request.status === 200) {
  411. if(window.JSON) {
  412. response = JSON.parse(request.responseText);
  413. } else {
  414. response = eval("("+ request.responseText + ")");
  415. }
  416. cb(response);
  417. }
  418. };
  419. request.send();
  420. return request;
  421. }
  422. }catch (e){
  423. cb(e);
  424. }
  425. };
  426. L.Util.ajax.cb = {};
  427. L.DefaultImagePath = (function () {
  428. var scripts = document.getElementsByTagName('script'),
  429. leafletRe = /[\/^]map23dlib[\-\._]?([\w\-\._]*)\.js\??/;
  430. var i, len, src, path;
  431. for (i = 0, len = scripts.length; i < len; i++) {
  432. src = scripts[i].src || '';
  433. if (src.match(leafletRe)) {
  434. path = src.split(leafletRe)[0];
  435. return (path ? path + '/' : '') + 'images';
  436. }
  437. }
  438. }());
  439. if(!L.DefaultImagePath){
  440. L.DefaultImagePath = '/dist/images'
  441. }
  442. L.Map.include({
  443. setZoomScope:function(minZoom,maxZoom){
  444. if(maxZoom >= minZoom){
  445. this.options.minZoom = minZoom;
  446. this.options.maxZoom = maxZoom;
  447. this.fire('zoomlevelschange');
  448. }
  449. }
  450. });
  451. L.Control.include({
  452. addTo: function (map) {
  453. this.remove();
  454. this._map = map;
  455. var container = this._container = this.onAdd(map),
  456. pos = this.getPosition(),
  457. corner = map._controlCorners[pos];
  458. L.DomUtil.addClass(container, 'leaflet-control');
  459. if (pos.indexOf('bottom') !== -1) {
  460. corner.insertBefore(container, corner.firstChild);
  461. } else {
  462. corner.appendChild(container);
  463. }
  464. if(this._callBack){
  465. this._callBack();
  466. }
  467. return this;
  468. }
  469. });
  470. L.Map.include({
  471. _initControlPos: function () {
  472. var corners = this._controlCorners = {},
  473. l = 'leaflet-',
  474. container = this._controlContainer =
  475. L.DomUtil.create('div', l + 'control-container', this._container);
  476. function createCorner(vSide, hSide) {
  477. var className = l + vSide + ' ' + l + hSide;
  478. corners[vSide + hSide] = L.DomUtil.create('div', className, container);
  479. }
  480. createCorner('top', 'left');
  481. createCorner('top', 'center');
  482. createCorner('top', 'right');
  483. createCorner('bottom', 'left');
  484. createCorner('bottom', 'center');
  485. createCorner('bottom', 'right');
  486. }
  487. });
  488. /*!
  489. * Copyright (c) 2012, Smartrak, David Leaver
  490. * Leaflet.utfgrid is an open-source JavaScript library that provides utfgrid interaction on leaflet powered maps.
  491. * https://github.com/danzel/Leaflet.utfgrid
  492. *
  493. * @license MIT
  494. */
  495. (function (window, undefined) {
  496. L.Util.utfgridAjax = function (url, success, error) {
  497. // the following is from JavaScript: The Definitive Guide
  498. // and https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest_in_IE6
  499. if (window.XMLHttpRequest === undefined) {
  500. window.XMLHttpRequest = function () {
  501. /*global ActiveXObject:true */
  502. try {
  503. return new ActiveXObject("Microsoft.XMLHTTP");
  504. }
  505. catch (e) {
  506. throw new Error("XMLHttpRequest is not supported");
  507. }
  508. };
  509. }
  510. var response, request = new XMLHttpRequest();
  511. request.open("GET", url);
  512. request.onreadystatechange = function () {
  513. /*jshint evil: true */
  514. if (request.readyState === 4) {
  515. if (request.status === 200) {
  516. if (window.JSON) {
  517. response = JSON.parse(request.responseText);
  518. } else {
  519. response = eval("(" + request.responseText + ")");
  520. }
  521. success(response);
  522. } else if (request.status !== 0 && error !== undefined) {
  523. error(request.status);
  524. }
  525. }
  526. };
  527. request.ontimeout = function () { error('timeout'); };
  528. request.send();
  529. return request;
  530. };
  531. L.UtfGrid = (L.Layer || L.Class).extend({
  532. includes: L.Mixin.Events,
  533. options: {
  534. subdomains: map23DConfig.tileSubdomains||'',
  535. minZoom: 0,
  536. maxZoom: 18,
  537. tileSize: 256,
  538. resolution: 4,
  539. useJsonP: true,
  540. pointerCursor: true,
  541. maxRequests: 4,
  542. requestTimeout: 60000
  543. },
  544. //The thing the mouse is currently on
  545. _mouseOn: null,
  546. initialize: function (url, options) {
  547. L.Util.setOptions(this, options);
  548. // The requests
  549. this._requests = {};
  550. this._request_queue = [];
  551. this._requests_in_process = [];
  552. this._url = url;
  553. this._cache = {};
  554. //Find a unique id in window we can use for our callbacks
  555. //Required for jsonP
  556. var i = 0;
  557. while (window['lu' + i]) {
  558. i++;
  559. }
  560. this._windowKey = 'lu' + i;
  561. window[this._windowKey] = {};
  562. var subdomains = this.options.subdomains;
  563. if (typeof this.options.subdomains === 'string') {
  564. this.options.subdomains = subdomains.split('');
  565. }
  566. },
  567. onAdd: function (map) {
  568. this._map = map;
  569. this._container = this._map._container;
  570. this._update();
  571. var zoom = Math.round(this._map.getZoom());
  572. if (zoom > this.options.maxZoom || zoom < this.options.minZoom) {
  573. return;
  574. }
  575. map.on('click', this._click, this);
  576. map.on('mousemove', this._move, this);
  577. map.on('moveend', this._update, this);
  578. },
  579. onRemove: function () {
  580. var map = this._map;
  581. map.off('click', this._click, this);
  582. map.off('mousemove', this._move, this);
  583. map.off('moveend', this._update, this);
  584. if (this.options.pointerCursor) {
  585. this._container.style.cursor = '';
  586. }
  587. },
  588. setUrl: function (url, noRedraw) {
  589. this._url = url;
  590. if (!noRedraw) {
  591. this.redraw();
  592. }
  593. return this;
  594. },
  595. redraw: function () {
  596. // Clear cache to force all tiles to reload
  597. this._request_queue = [];
  598. for (var req_key in this._requests) {
  599. if (this._requests.hasOwnProperty(req_key)) {
  600. this._abort_request(req_key);
  601. }
  602. }
  603. this._cache = {};
  604. this._update();
  605. },
  606. _click: function (e) {
  607. this.fire('click', this._objectForEvent(e));
  608. },
  609. _move: function (e) {
  610. var on = this._objectForEvent(e);
  611. if (on.data !== this._mouseOn) {
  612. if (this._mouseOn) {
  613. this.fire('mouseout', { latlng: e.latlng, data: this._mouseOn });
  614. if (this.options.pointerCursor) {
  615. this._container.style.cursor = '';
  616. }
  617. }
  618. if (on.data) {
  619. this.fire('mouseover', on);
  620. if (this.options.pointerCursor) {
  621. this._container.style.cursor = 'pointer';
  622. }
  623. }
  624. this._mouseOn = on.data;
  625. } else if (on.data) {
  626. this.fire('mousemove', on);
  627. }
  628. },
  629. _objectForEvent: function (e) {
  630. var map = this._map,
  631. point = map.project(e.latlng),
  632. tileSize = this.options.tileSize,
  633. resolution = this.options.resolution,
  634. x = Math.floor(point.x / tileSize),
  635. y = Math.floor(point.y / tileSize),
  636. gridX = Math.floor((point.x - (x * tileSize)) / resolution),
  637. gridY = Math.floor((point.y - (y * tileSize)) / resolution),
  638. max = map.options.crs.scale(map.getZoom()) / tileSize;
  639. x = (x + max) % max;
  640. y = (y + max) % max;
  641. var data = this._cache[map.getZoom() + '_' + x + '_' + y];
  642. var result = null;
  643. if (data && data.grid) {
  644. var idx = this._utfDecode(data.grid[gridY].charCodeAt(gridX)),
  645. key = data.keys[idx];
  646. if (data.data.hasOwnProperty(key)) {
  647. result = data.data[key];
  648. }
  649. }
  650. return L.extend({ latlng: e.latlng, data: result }, e);
  651. },
  652. //Load up all required json grid files
  653. //TODO: Load from center etc
  654. _update: function () {
  655. var bounds = this._map.getPixelBounds(),
  656. zoom = Math.round(this._map.getZoom()),
  657. tileSize = this.options.tileSize;
  658. if (zoom > this.options.maxZoom || zoom < this.options.minZoom) {
  659. return;
  660. }
  661. var nwTilePoint = new L.Point(
  662. Math.floor(bounds.min.x / tileSize),
  663. Math.floor(bounds.min.y / tileSize)),
  664. seTilePoint = new L.Point(
  665. Math.floor(bounds.max.x / tileSize),
  666. Math.floor(bounds.max.y / tileSize)),
  667. max = this._map.options.crs.scale(zoom) / tileSize;
  668. //Load all required ones
  669. var visible_tiles = [];
  670. for (var x = nwTilePoint.x; x <= seTilePoint.x; x++) {
  671. for (var y = nwTilePoint.y; y <= seTilePoint.y; y++) {
  672. var xw = (x + max) % max, yw = (y + max) % max;
  673. var key = zoom + '_' + xw + '_' + yw;
  674. visible_tiles.push(key);
  675. if (!this._cache.hasOwnProperty(key)) {
  676. this._cache[key] = null;
  677. if (this.options.useJsonP) {
  678. this._loadTileP(zoom, xw, yw);
  679. } else {
  680. this._loadTile(zoom, xw, yw);
  681. }
  682. }
  683. }
  684. }
  685. // If we still have requests for tiles that have now gone out of sight, attempt to abort them.
  686. for (var req_key in this._requests) {
  687. if (visible_tiles.indexOf(req_key) < 0) {
  688. this._abort_request(req_key);
  689. }
  690. }
  691. },
  692. _loadTileP: function (zoom, x, y) {
  693. var head = document.getElementsByTagName('head')[0],
  694. key = zoom + '_' + x + '_' + y,
  695. functionName = 'lu_' + key,
  696. wk = this._windowKey,
  697. self = this;
  698. var url = L.Util.template(this._url, L.Util.extend({
  699. s: L.TileLayer.prototype._getSubdomain.call(this, { x: x, y: y }),
  700. z: zoom,
  701. x: x,
  702. y: y,
  703. cb: wk + '.' + functionName
  704. }, this.options));
  705. var script = document.createElement('script');
  706. script.setAttribute("type", "text/javascript");
  707. script.setAttribute("src", url);
  708. window[wk][functionName] = function (data) {
  709. try {
  710. self._cache[key] = data;
  711. delete window[wk][functionName];
  712. head.removeChild(script);
  713. self._finish_request(key);
  714. }
  715. catch (e) {
  716. }
  717. };
  718. this._queue_request(key, url, function () {
  719. head.appendChild(script);
  720. return {
  721. abort: function () {
  722. head.removeChild(script);
  723. }
  724. };
  725. });
  726. },
  727. _loadTile: function (zoom, x, y) {
  728. var url = L.Util.template(this._url, L.Util.extend({
  729. s: L.TileLayer.prototype._getSubdomain.call(this, { x: x, y: y }),
  730. z: zoom,
  731. x: x,
  732. y: y
  733. }, this.options));
  734. var key = zoom + '_' + x + '_' + y;
  735. this._queue_request(key, url, this._ajaxRequestFactory(key, url));
  736. },
  737. _ajaxRequestFactory: function (key, url) {
  738. var successCallback = this._successCallbackFactory(key);
  739. var errorCallback = this._errorCallbackFactory(url);
  740. return function () {
  741. var request = L.Util.utfgridAjax(url, successCallback, errorCallback);
  742. request.timeout = this.options.requestTimeout;
  743. return request;
  744. }.bind(this);
  745. },
  746. _successCallbackFactory: function (key) {
  747. return function (data) {
  748. this._cache[key] = data;
  749. this._finish_request(key);
  750. }.bind(this);
  751. },
  752. _errorCallbackFactory: function (tileurl) {
  753. return function (statuscode) {
  754. this.fire('tileerror', {
  755. url: tileurl,
  756. code: statuscode
  757. });
  758. }.bind(this);
  759. },
  760. _queue_request: function (key, url, callback) {
  761. this._requests[key] = {
  762. callback: callback,
  763. timeout: null,
  764. handler: null,
  765. url: url
  766. };
  767. this._request_queue.push(key);
  768. this._process_queued_requests();
  769. },
  770. _finish_request: function (key) {
  771. // Remove from requests in process
  772. var pos = this._requests_in_process.indexOf(key);
  773. if (pos >= 0) {
  774. this._requests_in_process.splice(pos, 1);
  775. }
  776. // Remove from request queue
  777. pos = this._request_queue.indexOf(key);
  778. if (pos >= 0) {
  779. this._request_queue.splice(pos, 1);
  780. }
  781. // Remove the request entry
  782. if (this._requests[key]) {
  783. if (this._requests[key].timeout) {
  784. window.clearTimeout(this._requests[key].timeout);
  785. }
  786. delete this._requests[key];
  787. }
  788. // Recurse
  789. this._process_queued_requests();
  790. // Fire 'load' event if all tiles have been loaded
  791. if (this._requests_in_process.length === 0) {
  792. this.fire('load');
  793. }
  794. },
  795. _abort_request: function (key) {
  796. // Abort the request if possible
  797. if (this._requests[key] && this._requests[key].handler) {
  798. if (typeof this._requests[key].handler.abort === 'function') {
  799. this._requests[key].handler.abort();
  800. }
  801. }
  802. // Ensure we don't keep a false copy of the data in the cache
  803. if (this._cache[key] === null) {
  804. delete this._cache[key];
  805. }
  806. // And remove the request
  807. this._finish_request(key);
  808. },
  809. _process_queued_requests: function () {
  810. while (this._request_queue.length > 0 && (this.options.maxRequests === 0 ||
  811. this._requests_in_process.length < this.options.maxRequests)) {
  812. this._process_request(this._request_queue.pop());
  813. }
  814. },
  815. _process_request: function (key) {
  816. this._requests_in_process.push(key);
  817. // The callback might call _finish_request, so don't assume _requests[key] still exists.
  818. var handler = this._requests[key].callback();
  819. if (this._requests[key]) {
  820. this._requests[key].handler = handler;
  821. if (handler.timeout === undefined) {
  822. var timeoutCallback = this._timeoutCallbackFactory(key);
  823. this._requests[key].timeout = window.setTimeout(timeoutCallback, this.options.requestTimeout);
  824. }
  825. }
  826. },
  827. _timeoutCallbackFactory: function (key) {
  828. var tileurl = this._requests[key].url;
  829. return function () {
  830. this.fire('tileerror', { url: tileurl, code: 'timeout' });
  831. this._abort_request(key);
  832. }.bind(this);
  833. },
  834. _utfDecode: function (c) {
  835. if (c >= 93) {
  836. c--;
  837. }
  838. if (c >= 35) {
  839. c--;
  840. }
  841. return c - 32;
  842. }
  843. });
  844. L.utfGrid = function (url, options) {
  845. return new L.UtfGrid(url, options);
  846. };
  847. }(window));
  848. /*
  849. Leaflet.label, a plugin that adds labels to markers and vectors for Leaflet powered maps.
  850. (c) 2012-2013, Jacob Toye, Smartrak
  851. https://github.com/Leaflet/Leaflet.label
  852. http://leafletjs.com
  853. https://github.com/jacobtoye
  854. */
  855. (function () {
  856. //var L = window.L;
  857. /*
  858. * Leaflet.label assumes that you have already included the Leaflet library.
  859. */
  860. //L.labelVersion = '0.2.2-dev';
  861. L.Label = (L.Layer ? L.Layer : L.Class).extend({
  862. includes: L.Mixin.Events,
  863. options: {
  864. className: '',
  865. clickable: false,
  866. direction: 'auto',
  867. noHide: false,
  868. offset: [13, -16], // 6 (width of the label triangle) + 6 (padding)
  869. opacity: 1,
  870. zoomAnimation: true
  871. },
  872. initialize: function (options, source) {
  873. L.setOptions(this, options);
  874. this._source = source;
  875. this._animated = L.Browser.any3d && this.options.zoomAnimation;
  876. this._isOpen = false;
  877. },
  878. onAdd: function (map) {
  879. this._map = map;
  880. this._pane = this.options.pane ? map._panes[this.options.pane] :
  881. this._source instanceof L.Marker ? map._panes.markerPane : map._panes.popupPane;
  882. if (!this._container) {
  883. this._initLayout();
  884. }
  885. this._pane.appendChild(this._container);
  886. this._initInteraction();
  887. this._update();
  888. this.setOpacity(this.options.opacity);
  889. map
  890. .on('moveend', this._onMoveEnd, this)
  891. .on('viewreset', this._onViewReset, this);
  892. if (this._animated) {
  893. map.on('zoomanim', this._zoomAnimation, this);
  894. }
  895. if (L.Browser.touch && !this.options.noHide) {
  896. L.DomEvent.on(this._container, 'click', this.close, this);
  897. map.on('click', this.close, this);
  898. }
  899. },
  900. onRemove: function (map) {
  901. this._pane.removeChild(this._container);
  902. map.off({
  903. zoomanim: this._zoomAnimation,
  904. moveend: this._onMoveEnd,
  905. viewreset: this._onViewReset
  906. }, this);
  907. this._removeInteraction();
  908. this._map = null;
  909. },
  910. setLatLng: function (latlng) {
  911. this._latlng = L.latLng(latlng);
  912. if (this._map) {
  913. this._updatePosition();
  914. }
  915. return this;
  916. },
  917. setContent: function (content) {
  918. // Backup previous content and store new content
  919. this._previousContent = this._content;
  920. this._content = content;
  921. this._updateContent();
  922. return this;
  923. },
  924. close: function () {
  925. var map = this._map;
  926. if (map) {
  927. if (L.Browser.touch && !this.options.noHide) {
  928. L.DomEvent.off(this._container, 'click', this.close);
  929. map.off('click', this.close, this);
  930. }
  931. map.removeLayer(this);
  932. }
  933. },
  934. updateZIndex: function (zIndex) {
  935. this._zIndex = zIndex;
  936. if (this._container && this._zIndex) {
  937. this._container.style.zIndex = zIndex;
  938. }
  939. },
  940. setOpacity: function (opacity) {
  941. this.options.opacity = opacity;
  942. if (this._container) {
  943. L.DomUtil.setOpacity(this._container, opacity);
  944. }
  945. },
  946. _initLayout: function () {
  947. this._container = L.DomUtil.create('div', 'leaflet-label ' + this.options.className + ' leaflet-zoom-animated');
  948. this.updateZIndex(this._zIndex);
  949. },
  950. _update: function () {
  951. if (!this._map) { return; }
  952. this._container.style.visibility = 'hidden';
  953. this._updateContent();
  954. this._updatePosition();
  955. this._container.style.visibility = '';
  956. },
  957. _updateContent: function () {
  958. if (!this._content || !this._map || this._prevContent === this._content) {
  959. return;
  960. }
  961. if (typeof this._content === 'string') {
  962. this._container.innerHTML = this._content;
  963. this._prevContent = this._content;
  964. this._labelWidth = this._container.offsetWidth;
  965. }else {
  966. this._container.appendChild(this._content);
  967. this._prevContent = this._content;
  968. this._labelWidth = this._container.offsetWidth;
  969. }
  970. //==S== 修改标记
  971. L.DomUtil.create('div','leaflet-label-tips',this._container);
  972. //==E== 修改标记
  973. },
  974. _updatePosition: function () {
  975. var pos = this._map.latLngToLayerPoint(this._latlng);
  976. this._setPosition(pos);
  977. },
  978. _setPosition: function (pos) {
  979. var map = this._map,
  980. container = this._container,
  981. centerPoint = map.latLngToContainerPoint(map.getCenter()),
  982. labelPoint = map.layerPointToContainerPoint(pos),
  983. direction = this.options.direction,
  984. labelWidth = this._labelWidth,
  985. offset = L.point(this.options.offset);
  986. // position to the right (right or auto & needs to)
  987. if (direction === 'right' || direction === 'auto' && labelPoint.x < centerPoint.x) {
  988. L.DomUtil.addClass(container, 'leaflet-label-right');
  989. L.DomUtil.removeClass(container, 'leaflet-label-left');
  990. pos = pos.add(offset);
  991. } else { // position to the left
  992. L.DomUtil.addClass(container, 'leaflet-label-left');
  993. L.DomUtil.removeClass(container, 'leaflet-label-right');
  994. pos = pos.add(L.point(-offset.x - labelWidth, offset.y));
  995. }
  996. L.DomUtil.setPosition(container, pos);
  997. },
  998. _zoomAnimation: function (opt) {
  999. var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round();
  1000. this._setPosition(pos);
  1001. },
  1002. _onMoveEnd: function () {
  1003. if (!this._animated || this.options.direction === 'auto') {
  1004. this._updatePosition();
  1005. }
  1006. },
  1007. _onViewReset: function (e) {
  1008. /* if map resets hard, we must update the label */
  1009. if (e && e.hard) {
  1010. this._update();
  1011. }
  1012. },
  1013. _initInteraction: function () {
  1014. if (!this.options.clickable) { return; }
  1015. var container = this._container,
  1016. events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu'];
  1017. L.DomUtil.addClass(container, 'leaflet-clickable');
  1018. L.DomEvent.on(container, 'click', this._onMouseClick, this);
  1019. for (var i = 0; i < events.length; i++) {
  1020. L.DomEvent.on(container, events[i], this._fireMouseEvent, this);
  1021. }
  1022. },
  1023. _removeInteraction: function () {
  1024. if (!this.options.clickable) { return; }
  1025. var container = this._container,
  1026. events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu'];
  1027. L.DomUtil.removeClass(container, 'leaflet-clickable');
  1028. L.DomEvent.off(container, 'click', this._onMouseClick, this);
  1029. for (var i = 0; i < events.length; i++) {
  1030. L.DomEvent.off(container, events[i], this._fireMouseEvent, this);
  1031. }
  1032. },
  1033. _onMouseClick: function (e) {
  1034. if (this.hasEventListeners(e.type)) {
  1035. L.DomEvent.stopPropagation(e);
  1036. }
  1037. this.fire(e.type, {
  1038. originalEvent: e
  1039. });
  1040. },
  1041. _fireMouseEvent: function (e) {
  1042. this.fire(e.type, {
  1043. originalEvent: e
  1044. });
  1045. // TODO proper custom event propagation
  1046. // this line will always be called if marker is in a FeatureGroup
  1047. if (e.type === 'contextmenu' && this.hasEventListeners(e.type)) {
  1048. L.DomEvent.preventDefault(e);
  1049. }
  1050. if (e.type !== 'mousedown') {
  1051. L.DomEvent.stopPropagation(e);
  1052. } else {
  1053. L.DomEvent.preventDefault(e);
  1054. }
  1055. }
  1056. });
  1057. // This object is a mixin for L.Marker and L.CircleMarker. We declare it here as both need to include the contents.
  1058. L.BaseMarkerMethods = {
  1059. showLabel: function () {
  1060. if (this.label && this._map) {
  1061. this.label.setLatLng(this._latlng);
  1062. this._map.showLabel(this.label);
  1063. }
  1064. return this;
  1065. },
  1066. hideLabel: function () {
  1067. if (this.label) {
  1068. this.label.close();
  1069. }
  1070. return this;
  1071. },
  1072. setLabelNoHide: function (noHide) {
  1073. if (this._labelNoHide === noHide) {
  1074. return;
  1075. }
  1076. this._labelNoHide = noHide;
  1077. if (noHide) {
  1078. this._removeLabelRevealHandlers();
  1079. this.showLabel();
  1080. } else {
  1081. this._addLabelRevealHandlers();
  1082. this.hideLabel();
  1083. }
  1084. },
  1085. bindLabel: function (content, options) {
  1086. if(this.label){
  1087. return false;
  1088. }
  1089. var labelAnchor = this.options.icon ? this.options.icon.options.labelAnchor : this.options.labelAnchor,
  1090. anchor = L.point(labelAnchor) || L.point(0, 0);
  1091. anchor = anchor.add(L.Label.prototype.options.offset);
  1092. if (options && options.offset) {
  1093. anchor = anchor.add(options.offset);
  1094. }
  1095. options = L.Util.extend({offset: anchor}, options);
  1096. this._labelNoHide = options.noHide;
  1097. if (!this.label) {
  1098. if (!this._labelNoHide) {
  1099. this._addLabelRevealHandlers();
  1100. }
  1101. this
  1102. .on('remove', this.hideLabel, this)
  1103. .on('move', this._moveLabel, this)
  1104. .on('add', this._onMarkerAdd, this);
  1105. this._hasLabelHandlers = true;
  1106. }
  1107. this.label = new L.Label(options, this)
  1108. .setContent(content);
  1109. return this;
  1110. },
  1111. unbindLabel: function () {
  1112. if (this.label) {
  1113. this.hideLabel();
  1114. this.label = null;
  1115. if (this._hasLabelHandlers) {
  1116. if (!this._labelNoHide) {
  1117. this._removeLabelRevealHandlers();
  1118. }
  1119. this
  1120. .off('remove', this.hideLabel, this)
  1121. .off('move', this._moveLabel, this)
  1122. .off('add', this._onMarkerAdd, this);
  1123. }
  1124. this._hasLabelHandlers = false;
  1125. }
  1126. return this;
  1127. },
  1128. updateLabelContent: function (content) {
  1129. if (this.label) {
  1130. this.label.setContent(content);
  1131. }
  1132. },
  1133. getLabel: function () {
  1134. return this.label;
  1135. },
  1136. _onMarkerAdd: function () {
  1137. if (this._labelNoHide) {
  1138. this.showLabel();
  1139. }
  1140. },
  1141. _addLabelRevealHandlers: function () {
  1142. this
  1143. .on('mouseover', this.showLabel, this)
  1144. .on('mouseout', this.hideLabel, this);
  1145. if (L.Browser.touch) {
  1146. this.on('click', this.showLabel, this);
  1147. }
  1148. },
  1149. _removeLabelRevealHandlers: function () {
  1150. this
  1151. .off('mouseover', this.showLabel, this)
  1152. .off('mouseout', this.hideLabel, this);
  1153. if (L.Browser.touch) {
  1154. this.off('click', this.showLabel, this);
  1155. }
  1156. },
  1157. _moveLabel: function (e) {
  1158. this.label.setLatLng(e.latlng);
  1159. }
  1160. };
  1161. // Add in an option to icon that is used to set where the label anchor is
  1162. L.Icon.Default.mergeOptions({
  1163. labelAnchor: new L.Point(4, -15)
  1164. });
  1165. // Have to do this since Leaflet is loaded before this plugin and initializes
  1166. // L.Marker.options.icon therefore missing our mixin above.
  1167. L.Marker.mergeOptions({
  1168. icon: new L.Icon.Default()
  1169. });
  1170. L.Marker.include(L.BaseMarkerMethods);
  1171. L.Marker.include({
  1172. _originalUpdateZIndex: L.Marker.prototype._updateZIndex,
  1173. _updateZIndex: function (offset) {
  1174. var zIndex = this._zIndex + offset;
  1175. this._originalUpdateZIndex(offset);
  1176. if (this.label) {
  1177. this.label.updateZIndex(zIndex);
  1178. }
  1179. },
  1180. _originalSetOpacity: L.Marker.prototype.setOpacity,
  1181. setOpacity: function (opacity, labelHasSemiTransparency) {
  1182. this.options.labelHasSemiTransparency = labelHasSemiTransparency;
  1183. this._originalSetOpacity(opacity);
  1184. },
  1185. _originalUpdateOpacity: L.Marker.prototype._updateOpacity,
  1186. _updateOpacity: function () {
  1187. var absoluteOpacity = this.options.opacity === 0 ? 0 : 1;
  1188. this._originalUpdateOpacity();
  1189. if (this.label) {
  1190. this.label.setOpacity(this.options.labelHasSemiTransparency ? this.options.opacity : absoluteOpacity);
  1191. }
  1192. },
  1193. _originalSetLatLng: L.Marker.prototype.setLatLng,
  1194. setLatLng: function (latlng) {
  1195. if (this.label && !this._labelNoHide) {
  1196. this.hideLabel();
  1197. }
  1198. return this._originalSetLatLng(latlng);
  1199. }
  1200. });
  1201. // Add in an option to icon that is used to set where the label anchor is
  1202. L.CircleMarker.mergeOptions({
  1203. labelAnchor: new L.Point(-5, 5)
  1204. });
  1205. L.CircleMarker.include(L.BaseMarkerMethods);
  1206. L.Path.include({
  1207. bindLabel: function (content, options) {
  1208. if (!this.label || this.label.options !== options) {
  1209. this.label = new L.Label(options, this);
  1210. }
  1211. this.label.setContent(content);
  1212. if (!this._showLabelAdded) {
  1213. this
  1214. .on('mouseover', this._showLabel, this)
  1215. .on('mousemove', this._moveLabel, this)
  1216. .on('mouseout remove', this._hideLabel, this);
  1217. if (L.Browser.touch) {
  1218. this.on('click', this._showLabel, this);
  1219. }
  1220. this._showLabelAdded = true;
  1221. }
  1222. return this;
  1223. },
  1224. unbindLabel: function () {
  1225. if (this.label) {
  1226. this._hideLabel();
  1227. this.label = null;
  1228. this._showLabelAdded = false;
  1229. this
  1230. .off('mouseover', this._showLabel, this)
  1231. .off('mousemove', this._moveLabel, this)
  1232. .off('mouseout remove', this._hideLabel, this);
  1233. }
  1234. return this;
  1235. },
  1236. updateLabelContent: function (content) {
  1237. if (this.label) {
  1238. this.label.setContent(content);
  1239. }
  1240. },
  1241. _showLabel: function (e) {
  1242. this.label.setLatLng(e.latlng);
  1243. this._map.showLabel(this.label);
  1244. },
  1245. _moveLabel: function (e) {
  1246. this.label.setLatLng(e.latlng);
  1247. },
  1248. _hideLabel: function () {
  1249. this.label.close();
  1250. }
  1251. });
  1252. L.Map.include({
  1253. showLabel: function (label) {
  1254. return this.addLayer(label);
  1255. }
  1256. });
  1257. L.FeatureGroup.include({
  1258. // TODO: remove this when AOP is supported in Leaflet, need this as we cannot put code in removeLayer()
  1259. clearLayers: function () {
  1260. this.unbindLabel();
  1261. this.eachLayer(this.removeLayer, this);
  1262. return this;
  1263. },
  1264. bindLabel: function (content, options) {
  1265. return this.invoke('bindLabel', content, options);
  1266. },
  1267. unbindLabel: function () {
  1268. return this.invoke('unbindLabel');
  1269. },
  1270. updateLabelContent: function (content) {
  1271. this.invoke('updateLabelContent', content);
  1272. }
  1273. });
  1274. }(window, document));
  1275. /*
  1276. Leaflet.plabel, a plugin that adds plabels to markers and vectors for Leaflet powered maps.
  1277. (c) 2012-2013, Jacob Toye, Smartrak
  1278. https://github.com/Leaflet/Leaflet.plabel
  1279. http://leafletjs.com
  1280. https://github.com/jacobtoye
  1281. */
  1282. (function () {
  1283. //var L = window.L;
  1284. /*
  1285. * Leaflet.plabel assumes that you have already included the Leaflet library.
  1286. */
  1287. //L.plabelVersion = '0.2.2-dev';
  1288. L.Plabel = (L.Layer ? L.Layer : L.Class).extend({
  1289. includes: L.Mixin.Events,
  1290. options: {
  1291. className: '',
  1292. clickable: true,
  1293. direction: 'right',
  1294. noHide: false,
  1295. offset: [0, 0], // 6 (width of the plabel triangle) + 6 (padding)
  1296. opacity: 1,
  1297. color:'#000000',
  1298. bold:false,
  1299. background:'',
  1300. zoomAnimation: true,
  1301. lineWidth:42.4,
  1302. },
  1303. initialize: function (options, source) {
  1304. L.setOptions(this, options);
  1305. this._source = source;
  1306. this._animated = L.Browser.any3d && this.options.zoomAnimation;
  1307. this._isOpen = false;
  1308. },
  1309. onAdd: function (map) {
  1310. this._map = map;
  1311. this._isOpen = true;
  1312. this._pane = this.options.pane ? map._panes[this.options.pane] :
  1313. this._source instanceof L.Marker ? map._panes.markerPane : map._panes.popupPane;
  1314. if (!this._container) {
  1315. this._initLayout();
  1316. }
  1317. this._pane.appendChild(this._container);
  1318. this._initInteraction();
  1319. this._update();
  1320. this.setOpacity(this.options.opacity);
  1321. map
  1322. .on('moveend', this._onMoveEnd, this)
  1323. .on('move',this._onMoveEnd,this)
  1324. .on('viewreset', this._onViewReset, this);
  1325. if (this._animated) {
  1326. map.on('zoomanim', this._zoomAnimation, this);
  1327. }
  1328. // if (L.Browser.touch && !this.options.noHide) {
  1329. // L.DomEvent.on(this._container, 'click', this.close, this);
  1330. // map.on('click', this.close, this);
  1331. // }
  1332. },
  1333. onRemove: function (map) {
  1334. this._pane.removeChild(this._container);
  1335. this._isOpen = false;
  1336. map.off({
  1337. zoomanim: this._zoomAnimation,
  1338. move:this._onMoveEnd,
  1339. moveend: this._onMoveEnd,
  1340. viewreset: this._onViewReset
  1341. }, this);
  1342. this._removeInteraction();
  1343. this._map = null;
  1344. },
  1345. setLatLng: function (latlng) {
  1346. this._latlng = L.latLng(latlng);
  1347. if (this._map) {
  1348. this._updatePosition();
  1349. }
  1350. return this;
  1351. },
  1352. setContent: function (content) {
  1353. // Backup previous content and store new content
  1354. this._previousContent = this._content;
  1355. this._content = content;
  1356. this._updateContent();
  1357. return this;
  1358. },
  1359. setColor:function(color){
  1360. this.options.color = color;
  1361. if (this._container) {
  1362. this._containerLine.style.borderBottomColor = color;
  1363. this._containerText.style.color = color;
  1364. }
  1365. return this;
  1366. },
  1367. setBold:function(flag){
  1368. this.options.bold = flag;
  1369. if (this._container) {
  1370. if(flag){
  1371. this._containerLine.style.borderBottomWidth = '2px';
  1372. this._containerText.style.fontWeight = 800;
  1373. }else{
  1374. this._containerLine.style.borderBottomWidth = '1px';
  1375. this._containerText.style.fontWeight = 400;
  1376. }
  1377. }
  1378. return this;
  1379. },
  1380. setBackground:function(color){
  1381. this.options.background = color;
  1382. if (this._container) {
  1383. if(color){
  1384. this._containerText.style.backgroundColor = color;
  1385. }else{
  1386. this._containerText.style.backgroundColor = '';
  1387. }
  1388. }
  1389. return this;
  1390. },
  1391. close: function () {
  1392. var map = this._map;
  1393. this._isOpen = false;
  1394. if (map) {
  1395. // if (L.Browser.touch && !this.options.noHide) {
  1396. // L.DomEvent.off(this._container, 'click', this.close);
  1397. // map.off('click', this.close, this);
  1398. // }
  1399. map.removeLayer(this);
  1400. }
  1401. },
  1402. updateZIndex: function (zIndex) {
  1403. this._zIndex = zIndex;
  1404. if (this._container && this._zIndex) {
  1405. this._container.style.zIndex = zIndex;
  1406. }
  1407. },
  1408. setOpacity: function (opacity) {
  1409. this.options.opacity = opacity;
  1410. if (this._container) {
  1411. L.DomUtil.setOpacity(this._container, opacity);
  1412. }
  1413. },
  1414. _initLayout: function () {
  1415. this._container = L.DomUtil.create('div', 'leaflet-plabel ' + this.options.className + ' leaflet-zoom-animated');
  1416. this._containerLine = L.DomUtil.create('div','leaflet-plabel-line',this._container);
  1417. this._containerText = L.DomUtil.create('div','leaflet-plabel-text',this._container);
  1418. $(this._containerText).dragmove();
  1419. var lleft = Math.pow(Math.pow(this.options.lineWidth,2)/2,0.5)+'px';
  1420. var ltop = -Math.pow(Math.pow(this.options.lineWidth,2)/2,0.5)+'px';
  1421. this._containerText.style.left = lleft;
  1422. this._containerText.style.top = ltop;
  1423. this._containerLine.style.width = this.options.lineWidth+'px';
  1424. this._containerText.style.backgroundColor = this.options.background;
  1425. L.DomEvent.on(this._containerText,'mousedown',function(e){
  1426. this._map.dragging.disable();
  1427. },this)
  1428. L.DomEvent.on(this._containerText,'mousemove',function(e){
  1429. var left = parseInt(this._containerText.style.left||30);
  1430. var top = parseInt(this._containerText.style.top||-30);
  1431. var angle = this._angle({x:0,y:0},{x:left,y:top})
  1432. this._containerLine.style.transform = 'rotate('+angle+'deg)';
  1433. this._containerLine.style.msTransform = 'rotate('+angle+'deg)';
  1434. var lineWidth = Math.pow((Math.abs(left) * Math.abs(left) + Math.abs(top) * Math.abs(top)), 0.5)
  1435. this._containerLine.style.width = lineWidth+'px';
  1436. },this)
  1437. L.DomEvent.on(this._containerText,'mouseup',function(e){
  1438. this._map.dragging.enable();
  1439. },this)
  1440. this.updateZIndex(this._zIndex);
  1441. },
  1442. _angle:function(start,end){
  1443. var diff_x = end.x - start.x,
  1444. diff_y = end.y - start.y;
  1445. //返回角度,不是弧度
  1446. var angle = 360*Math.atan(diff_y/diff_x)/(2*Math.PI);
  1447. if(end.x<start.x){
  1448. angle += 180
  1449. }
  1450. return angle;
  1451. },
  1452. _update: function () {
  1453. if (!this._map) { return; }
  1454. this._container.style.visibility = 'hidden';
  1455. this._updateContent();
  1456. this._updatePosition();
  1457. this._container.style.visibility = '';
  1458. this._containerText.style.backgroundColor = this.options.background;
  1459. if(this.options.bold){
  1460. this._containerLine.style.borderBottomWidth = '2px';
  1461. this._containerText.style.fontWeight = 800;
  1462. }else{
  1463. this._containerLine.style.borderBottomWidth = '1px';
  1464. this._containerText.style.fontWeight = 400;
  1465. }
  1466. this._containerLine.style.borderBottomColor = this.options.color;
  1467. this._containerText.style.color = this.options.color;
  1468. },
  1469. _updateContent: function () {
  1470. if (!this._content || !this._map || this._prevContent === this._content) {
  1471. return;
  1472. }
  1473. if (typeof this._content === 'string') {
  1474. this._containerText.innerHTML = this._content;
  1475. this._prevContent = this._content;
  1476. this._plabelWidth = this._containerText.offsetWidth;
  1477. }else {
  1478. this._containerText.appendChild(this._content);
  1479. this._prevContent = this._content;
  1480. this._plabelWidth = this._containerText.offsetWidth;
  1481. }
  1482. },
  1483. _updatePosition: function () {
  1484. var pos = this._map.latLngToLayerPoint(this._latlng);
  1485. this._setPosition(pos);
  1486. },
  1487. _setPosition: function (pos) {
  1488. var map = this._map,
  1489. container = this._container,
  1490. centerPoint = map.latLngToContainerPoint(map.getCenter()),
  1491. plabelPoint = map.layerPointToContainerPoint(pos),
  1492. direction = this.options.direction,
  1493. plabelWidth = this._plabelWidth,
  1494. offset = L.point(this.options.offset);
  1495. // position to the right (right or auto & needs to)
  1496. if (direction === 'right' || direction === 'auto' && plabelPoint.x < centerPoint.x) {
  1497. L.DomUtil.addClass(container, 'leaflet-plabel-right');
  1498. L.DomUtil.removeClass(container, 'leaflet-plabel-left');
  1499. pos = pos.add(offset);
  1500. } else { // position to the left
  1501. L.DomUtil.addClass(container, 'leaflet-plabel-left');
  1502. L.DomUtil.removeClass(container, 'leaflet-plabel-right');
  1503. pos = pos.add(L.point(-offset.x - plabelWidth, offset.y));
  1504. }
  1505. L.DomUtil.setPosition(container, pos);
  1506. },
  1507. _zoomAnimation: function (opt) {
  1508. var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round();
  1509. this._setPosition(pos);
  1510. },
  1511. _onMoveEnd: function () {
  1512. //if (!this._animated || this.options.direction === 'auto') {
  1513. this._updatePosition();
  1514. //}
  1515. },
  1516. _onViewReset: function (e) {
  1517. /* if map resets hard, we must update the plabel */
  1518. if (e && e.hard) {
  1519. this._update();
  1520. }
  1521. },
  1522. _initInteraction: function () {
  1523. if (!this.options.clickable) { return; }
  1524. var container = this._container,
  1525. events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu'];
  1526. L.DomUtil.addClass(container, 'leaflet-clickable');
  1527. L.DomEvent.on(container, 'click', this._onMouseClick, this);
  1528. for (var i = 0; i < events.length; i++) {
  1529. L.DomEvent.on(container, events[i], this._fireMouseEvent, this);
  1530. }
  1531. },
  1532. _removeInteraction: function () {
  1533. if (!this.options.clickable) { return; }
  1534. var container = this._container,
  1535. events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu'];
  1536. L.DomUtil.removeClass(container, 'leaflet-clickable');
  1537. L.DomEvent.off(container, 'click', this._onMouseClick, this);
  1538. for (var i = 0; i < events.length; i++) {
  1539. L.DomEvent.off(container, events[i], this._fireMouseEvent, this);
  1540. }
  1541. },
  1542. _onMouseClick: function (e) {
  1543. if (this.hasEventListeners(e.type)) {
  1544. L.DomEvent.stopPropagation(e);
  1545. }
  1546. this.fire(e.type, {
  1547. originalEvent: e
  1548. });
  1549. },
  1550. _fireMouseEvent: function (e) {
  1551. this.fire(e.type, {
  1552. originalEvent: e
  1553. });
  1554. // TODO proper custom event propagation
  1555. // this line will always be called if marker is in a FeatureGroup
  1556. if (e.type === 'contextmenu' && this.hasEventListeners(e.type)) {
  1557. L.DomEvent.preventDefault(e);
  1558. }
  1559. if (e.type !== 'mousedown') {
  1560. L.DomEvent.stopPropagation(e);
  1561. } else {
  1562. L.DomEvent.preventDefault(e);
  1563. }
  1564. }
  1565. });
  1566. // This object is a mixin for L.Marker and L.CircleMarker. We declare it here as both need to include the contents.
  1567. L.BasePMarkerMethods = {
  1568. showPlabel: function () {
  1569. if (this.plabel && this._map) {
  1570. this.plabel.setLatLng(this._latlng);
  1571. if(!this.plabel._isOpen){
  1572. this._map.showPlabel(this.plabel);
  1573. }
  1574. }
  1575. return this;
  1576. },
  1577. hidePlabel: function () {
  1578. if (this.plabel) {
  1579. this.plabel.close();
  1580. }
  1581. return this;
  1582. },
  1583. setPlabelNoHide: function (noHide) {
  1584. if (this._plabelNoHide === noHide) {
  1585. return;
  1586. }
  1587. this._plabelNoHide = noHide;
  1588. this.options.noHide = noHide;
  1589. if (noHide) {
  1590. this._removePlabelRevealHandlers();
  1591. this.showPlabel();
  1592. } else {
  1593. this._addPlabelRevealHandlers();
  1594. this.hidePlabel();
  1595. }
  1596. },
  1597. bindPlabel: function (content, options) {
  1598. if(this.plabel){
  1599. return false;
  1600. }
  1601. var plabelAnchor = this.options.icon ? this.options.icon.options.plabelAnchor : this.options.plabelAnchor,
  1602. anchor = L.point(plabelAnchor) || L.point(0, 0);
  1603. anchor = anchor.add(L.Plabel.prototype.options.offset);
  1604. if (options && options.offset) {
  1605. anchor = anchor.add(options.offset);
  1606. }
  1607. options = L.Util.extend({offset: anchor}, options);
  1608. this._plabelNoHide = options.noHide;
  1609. if (!this.plabel) {
  1610. if (!this._plabelNoHide) {
  1611. this._addPlabelRevealHandlers();
  1612. }
  1613. this
  1614. .on('remove', this.hidePlabel, this)
  1615. .on('move', this._movePlabel, this)
  1616. .on('add', this._onPMarkerAdd, this);
  1617. this._hasPlabelHandlers = true;
  1618. }
  1619. this.plabel = new L.Plabel(options, this)
  1620. .setContent(content);
  1621. return this;
  1622. },
  1623. unbindPlabel: function () {
  1624. if (this.plabel) {
  1625. this.hidePlabel();
  1626. this.plabel = null;
  1627. if (this._hasPlabelHandlers) {
  1628. if (!this._plabelNoHide) {
  1629. this._removePlabelRevealHandlers();
  1630. }
  1631. this
  1632. .off('remove', this.hidePlabel, this)
  1633. .off('move', this._movePlabel, this)
  1634. .off('add', this._onPMarkerAdd, this);
  1635. }
  1636. this._hasPlabelHandlers = false;
  1637. }
  1638. return this;
  1639. },
  1640. updatePlabelContent: function (content) {
  1641. if (this.plabel) {
  1642. this.plabel.setContent(content);
  1643. }
  1644. },
  1645. getPlabel: function () {
  1646. return this.plabel;
  1647. },
  1648. _onPMarkerAdd: function () {
  1649. if (this._plabelNoHide) {
  1650. this.showPlabel();
  1651. }
  1652. },
  1653. _addPlabelRevealHandlers: function () {
  1654. this
  1655. .on('mouseover', this.showPlabel, this)
  1656. .on('mouseout', this.hidePlabel, this);
  1657. if (L.Browser.touch) {
  1658. this.on('click', this.showPlabel, this);
  1659. }
  1660. },
  1661. _removePlabelRevealHandlers: function () {
  1662. this
  1663. .off('mouseover', this.showPlabel, this)
  1664. .off('mouseout', this.hidePlabel, this);
  1665. if (L.Browser.touch) {
  1666. this.off('click', this.showPlabel, this);
  1667. }
  1668. },
  1669. _movePlabel: function (e) {
  1670. this.plabel.setLatLng(e.latlng);
  1671. }
  1672. };
  1673. // Add in an option to icon that is used to set where the plabel anchor is
  1674. L.Icon.Default.mergeOptions({
  1675. plabelAnchor: new L.Point(4, -15)
  1676. });
  1677. // Have to do this since Leaflet is loaded before this plugin and initializes
  1678. // L.Marker.options.icon therefore missing our mixin above.
  1679. // L.Marker.mergeOptions({
  1680. // icon: new L.Icon.Default()
  1681. // });
  1682. L.Marker.include(L.BasePMarkerMethods);
  1683. L.Marker.include({
  1684. _originalUpdatePZIndex: L.Marker.prototype._updateZIndex,
  1685. _updateZIndex: function (offset) {
  1686. var zIndex = this._zIndex + offset;
  1687. this._originalUpdatePZIndex(offset);
  1688. if (this.plabel) {
  1689. this.plabel.updateZIndex(zIndex);
  1690. }
  1691. },
  1692. _originalSetPOpacity: L.Marker.prototype.setOpacity,
  1693. setOpacity: function (opacity, plabelHasSemiTransparency) {
  1694. this.options.plabelHasSemiTransparency = plabelHasSemiTransparency;
  1695. this._originalSetPOpacity(opacity);
  1696. },
  1697. _originalUpdatePOpacity: L.Marker.prototype._updateOpacity,
  1698. _updateOpacity: function () {
  1699. var absoluteOpacity = this.options.opacity === 0 ? 0 : 1;
  1700. this._originalUpdatePOpacity();
  1701. if (this.plabel) {
  1702. this.plabel.setOpacity(this.options.plabelHasSemiTransparency ? this.options.opacity : absoluteOpacity);
  1703. }
  1704. },
  1705. _originalPSetLatLng: L.Marker.prototype.setLatLng,
  1706. setLatLng: function (latlng) {
  1707. if (this.plabel) {
  1708. this.plabel.setLatLng(latlng)
  1709. }
  1710. return this._originalPSetLatLng(latlng);
  1711. }
  1712. });
  1713. // Add in an option to icon that is used to set where the plabel anchor is
  1714. L.CircleMarker.mergeOptions({
  1715. plabelAnchor: new L.Point(1, 1)
  1716. });
  1717. L.CircleMarker.include(L.BasePMarkerMethods);
  1718. L.Path.include({
  1719. showPlabel: function () {
  1720. if (this.plabel && this._map) {
  1721. this.plabel.setLatLng(this._latlngs[0]);
  1722. this._map.showPlabel(this.plabel);
  1723. }
  1724. return this;
  1725. },
  1726. hidePlabel: function () {
  1727. if (this.plabel) {
  1728. this.plabel.close();
  1729. }
  1730. return this;
  1731. },
  1732. bindPlabel: function (content, options) {
  1733. if (!this.plabel || this.plabel.options !== options) {
  1734. this.plabel = new L.Plabel(options, this);
  1735. }
  1736. this.plabel.setContent(content);
  1737. //if (!this._showPlabelAdded) {
  1738. // this
  1739. // .on('mouseover', this._showPlabel, this)
  1740. // .on('mousemove', this._movePlabel, this)
  1741. // .on('mouseout remove', this._hidePlabel, this);
  1742. this.on('remove', this._hidePlabel, this);
  1743. if (L.Browser.touch) {
  1744. this.on('click', this._showPlabel, this);
  1745. }
  1746. this._showPlabelAdded = true;
  1747. //}
  1748. return this;
  1749. },
  1750. unbindPlabel: function () {
  1751. if (this.plabel) {
  1752. this._hidePlabel();
  1753. this.plabel = null;
  1754. //this._showPlabelAdded = false;
  1755. // this
  1756. // .off('mouseover', this._showPlabel, this)
  1757. // .off('mousemove', this._movePlabel, this)
  1758. // .off('mouseout remove', this._hidePlabel, this);
  1759. this.off('remove', this._hidePlabel, this);
  1760. }
  1761. return this;
  1762. },
  1763. updatePlabelContent: function (content) {
  1764. if (this.plabel) {
  1765. this.plabel.setContent(content);
  1766. }
  1767. },
  1768. _showPlabel: function (e) {
  1769. this.plabel.setLatLng(e.latlng);
  1770. //this.plabel.setLatLng(this.latlngs[0])
  1771. this._map.showPlabel(this.plabel);
  1772. },
  1773. _movePlabel: function (e) {
  1774. this.plabel.setLatLng(e.latlng);
  1775. },
  1776. _hidePlabel: function () {
  1777. this.plabel.close();
  1778. }
  1779. });
  1780. L.Polyline.include({
  1781. showPlabel: function () {
  1782. if (this.plabel && this._map) {
  1783. var pCenter = this._latlngs[parseInt(this._latlngs.length/2)];
  1784. if(this._latlngs.length == 2){
  1785. pCenter = [(this._latlngs[0].lat+this._latlngs[1].lat)/2,(this._latlngs[0].lng+this._latlngs[1].lng)/2]
  1786. }
  1787. this.plabel.setLatLng(pCenter);
  1788. this._map.showPlabel(this.plabel);
  1789. }
  1790. return this;
  1791. }
  1792. });
  1793. L.Polygon.include({
  1794. showPlabel: function () {
  1795. if (this.plabel && this._map) {
  1796. this.plabel.setLatLng(this.getBounds().getCenter());
  1797. this._map.showPlabel(this.plabel);
  1798. }
  1799. return this;
  1800. }
  1801. });
  1802. L.Circle.include({
  1803. showPlabel: function () {
  1804. if (this.plabel && this._map) {
  1805. this.plabel.setLatLng(this._latlng);
  1806. this._map.showPlabel(this.plabel);
  1807. }
  1808. return this;
  1809. }
  1810. });
  1811. L.Map.include({
  1812. showPlabel: function (plabel) {
  1813. return this.addLayer(plabel);
  1814. }
  1815. });
  1816. L.FeatureGroup.include({
  1817. // TODO: remove this when AOP is supported in Leaflet, need this as we cannot put code in removeLayer()
  1818. clearLayers: function () {
  1819. this.unbindPlabel();
  1820. this.eachLayer(this.removeLayer, this);
  1821. return this;
  1822. },
  1823. bindPlabel: function (content, options) {
  1824. return this.invoke('bindPlabel', content, options);
  1825. },
  1826. unbindPlabel: function () {
  1827. return this.invoke('unbindPlabel');
  1828. },
  1829. updatePlabelContent: function (content) {
  1830. this.invoke('updatePlabelContent', content);
  1831. }
  1832. });
  1833. }(window, document));
  1834. L.AnimatedMarker = L.Marker.extend({
  1835. options: {
  1836. // meters
  1837. distance: 200,
  1838. // ms
  1839. interval: 800,
  1840. //速度倍数
  1841. speedMultiple:0.001,
  1842. // animate on add?
  1843. autoStart: true,
  1844. // callback onend
  1845. onEnd: function(){},
  1846. clickable: false
  1847. },
  1848. initialize: function (latlngs, options) {
  1849. this.setLine(latlngs);
  1850. L.Marker.prototype.initialize.call(this, latlngs[0], options);
  1851. },
  1852. // Breaks the line up into tiny chunks (see options) ONLY if CSS3 animations
  1853. // are not supported.
  1854. _chunk: function(latlngs) {
  1855. var i,
  1856. len = latlngs.length,
  1857. chunkedLatLngs = [];
  1858. for (i=1;i<len;i++) {
  1859. var cur = latlngs[i-1],
  1860. next = latlngs[i],
  1861. dist = cur.distanceTo(next),
  1862. factor = this.options.distance / dist,
  1863. dLat = factor * (next.lat - cur.lat),
  1864. dLng = factor * (next.lng - cur.lng);
  1865. if (dist > this.options.distance) {
  1866. while (dist > this.options.distance) {
  1867. cur = new L.LatLng(cur.lat + dLat, cur.lng + dLng);
  1868. dist = cur.distanceTo(next);
  1869. chunkedLatLngs.push(cur);
  1870. }
  1871. } else {
  1872. chunkedLatLngs.push(cur);
  1873. }
  1874. }
  1875. chunkedLatLngs.push(latlngs[len-1]);
  1876. return chunkedLatLngs;
  1877. },
  1878. onAdd: function (map) {
  1879. L.Marker.prototype.onAdd.call(this, map);
  1880. // Start animating when added to the map
  1881. if (this.options.autoStart) {
  1882. this.start();
  1883. }
  1884. },
  1885. animate: function() {
  1886. map23DControl.anMarkerGon = true;
  1887. var self = this,
  1888. len = this._latlngs.length,
  1889. speed = this.options.speedMultiple;
  1890. var guid = this.guid;
  1891. $.each(map23DData.timeLineData,function(i,t){
  1892. if((guid === i) && (t._i > 0)){
  1893. self._i = t._i;
  1894. t._i = -11;
  1895. }
  1896. });
  1897. // Normalize the transition speed from vertex to vertex
  1898. if (this._i < len && this._i > 0) {
  1899. var maxlength = $("#"+guid+" .Main").width();
  1900. var curlength = Math.round((self._i/(len-1))*maxlength);
  1901. $("#"+guid+" .scroll_Thumb").css("left", curlength -32+ "px");
  1902. $("#"+guid+" .scroll_Track").css("width", curlength + "px");
  1903. $("#"+guid+" .scrollBarTxt").html(self._i + "/" + len);
  1904. var turnrorate = L.Util.getAngleByLatLng(this._latlngs[this._i-1].lng,this._latlngs[this._i-1].lat,this._latlngs[this._i].lng,this._latlngs[this._i].lat);
  1905. turnrorate = turnrorate;
  1906. var markerData = map23DData.markers[guid];
  1907. var marker = map2DViewer.markers[guid];
  1908. if(!!markerData){
  1909. var icon_html='<img width="'+markerData.geojson.properties.iconSize[0]+'" height="'+markerData.geojson.properties.iconSize[1]+'" src="'+markerData.geojson.properties.iconUrl+'" style=" -webkit-transform: rotate('+turnrorate+'deg); -moz-transform:rotate('+turnrorate+'deg);-ms-transform:rotate('+turnrorate+'deg);" />';
  1910. var setDivIcon = L.divIcon({
  1911. className:'rorate_div',
  1912. html:icon_html,
  1913. iconAnchor:markerData.geojson.properties.iconAnchor,
  1914. iconSize:markerData.geojson.properties.iconSize,
  1915. popupAnchor:markerData.geojson.properties.popupAnchor});
  1916. marker.setIcon(setDivIcon);
  1917. //var curTime = Date.parse(map23DData.markers[guid].geojson.properties.markerTime[this._i-1]);
  1918. //var curPreTime = Date.parse(map23DData.markers[guid].geojson.properties.markerTime[this._i]);
  1919. var curTime = map23DData.markers[guid].geojson.properties.markerTime[this._i-1];
  1920. var curPreTime = map23DData.markers[guid].geojson.properties.markerTime[this._i];
  1921. //marker实时更新信息
  1922. var curTSpeed = new L.LatLng(this._latlngs[this._i -1].lng,this._latlngs[this._i -1].lat).distanceTo(new L.LatLng(this._latlngs[this._i].lng,this._latlngs[this._i].lat));
  1923. this.curOptions = {
  1924. "curTime":curTime,
  1925. "curPreTime":curPreTime,
  1926. "curLatlng":this._latlngs[this._i],
  1927. "curPreLatlng":this._latlngs[this._i -1],
  1928. "curDiatance":curTSpeed
  1929. };
  1930. PubSub.publishSync('curMarkerOptions',guid);
  1931. if(this._i === 1){
  1932. speed = 1;
  1933. }else{
  1934. speed = (curPreTime - curTime)/this.options.speedMultiple;
  1935. }
  1936. }
  1937. }else if(this._i == len){
  1938. }
  1939. map2DViewer.map.on('zoomend',function(){
  1940. /*if (L.DomUtil.TRANSITION) {
  1941. if (this._icon) { this._icon.style[L.DomUtil.TRANSITION] = ('all ' + 1 + 'ms linear'); }
  1942. if (this._shadow) { this._shadow.style[L.DomUtil.TRANSITION] = 'all ' + 1 + 'ms linear'; }
  1943. }
  1944. this.setLatLng(this._latlngs[this._i]);*/
  1945. map23DControl.Speed = true;
  1946. if(!map23DControl.anMarkerGon){
  1947. $.each(map2DViewer.routeBackGroup,function(i,t){
  1948. var animate_data = map2DViewer.routeBackGroup[i].marker;
  1949. if(map23DData.markers[animate_data].visible2D){
  1950. var _this = map2DViewer.markers[animate_data];
  1951. if (L.DomUtil.TRANSITION) {
  1952. if (_this._icon) { _this._icon.style[L.DomUtil.TRANSITION] = ('all ' + 0 + 'ms linear'); }
  1953. if (_this._shadow) { _this._shadow.style[L.DomUtil.TRANSITION] = 'all ' + 0 + 'ms linear'; }
  1954. }
  1955. if(_this._i < _this._latlngs.length){
  1956. _this.setLatLng(_this._latlngs[_this._i]);
  1957. _this['_i'] = _this._i;
  1958. }
  1959. }
  1960. })
  1961. }
  1962. })
  1963. // Only if CSS3 transitions are supported
  1964. if (L.DomUtil.TRANSITION) {
  1965. if(map23DControl.Speed){
  1966. if (this._icon) { this._icon.style[L.DomUtil.TRANSITION] = ('all ' + 0 + 'ms linear'); }
  1967. if (this._shadow) { this._shadow.style[L.DomUtil.TRANSITION] = 'all ' + 0 + 'ms linear'; }
  1968. map23DControl.Speed = false;
  1969. }else{
  1970. if (this._icon) { this._icon.style[L.DomUtil.TRANSITION] = ('all ' + speed + 'ms linear'); }
  1971. if (this._shadow) { this._shadow.style[L.DomUtil.TRANSITION] = 'all ' + speed + 'ms linear'; }
  1972. }
  1973. }
  1974. // Move to the next vertex
  1975. this.setLatLng(this._latlngs[this._i]);
  1976. this._i++;
  1977. map23DControl.anMarkerGon = false;
  1978. // Queue up the animation to the next next vertex
  1979. this._tid = setTimeout(function(){
  1980. if (self._i === len) {
  1981. $.each(map2DViewer.routeBackGroup,function(i,t){
  1982. if(map2DViewer.routeBackGroup[i].marker === guid){
  1983. map2DViewer.routeBackGroup[i].isEnd = true;
  1984. PubSub.publishSync('payBackEnd',i);
  1985. };
  1986. })
  1987. self.options.onEnd.apply(self, Array.prototype.slice.call(arguments));
  1988. } else {
  1989. self.animate();
  1990. }
  1991. }, speed);
  1992. },
  1993. // Start the animation
  1994. start: function() {
  1995. this.animate();
  1996. window.marker_Animate = true;
  1997. $.each(map2DViewer.routeBackGroup,function(i,t){
  1998. map2DViewer.routeBackGroup[i].marker === this.guid;
  1999. map2DViewer.routeBackGroup[i].isEnd = false;
  2000. })
  2001. },
  2002. restart:function(){
  2003. this.stop();
  2004. this['_i'] = 0;
  2005. this.start();
  2006. },
  2007. // Stop the animation in place
  2008. stop: function() {
  2009. if (this._tid) {
  2010. clearTimeout(this._tid);
  2011. window.marker_Animate = false;
  2012. //this.animate();
  2013. }
  2014. },
  2015. setLine: function(latlngs){
  2016. if (L.DomUtil.TRANSITION) {
  2017. // No need to to check up the line if we can animate using CSS3
  2018. this._latlngs = latlngs;
  2019. } else {
  2020. // Chunk up the lines into options.distance bits
  2021. this._latlngs = this._chunk(latlngs);
  2022. this.options.distance = 10;
  2023. this.options.interval = 3;
  2024. }
  2025. this._i = 0;
  2026. }
  2027. });
  2028. L.animatedMarker = function (latlngs, options) {
  2029. return new L.AnimatedMarker(latlngs, options);
  2030. };
  2031. /*
  2032. Leaflet.markercluster, Provides Beautiful Animated Marker Clustering functionality for Leaflet, a JS library for interactive maps.
  2033. https://github.com/Leaflet/Leaflet.markercluster
  2034. (c) 2012-2013, Dave Leaver, smartrak
  2035. */
  2036. (function (window, document, undefined) {/*
  2037. * L.MarkerClusterGroup extends L.FeatureGroup by clustering the markers contained within
  2038. */
  2039. L.MarkerClusterGroup = L.FeatureGroup.extend({
  2040. options: {
  2041. maxClusterRadius: 120, //A cluster will cover at most this many pixels from its center
  2042. iconCreateFunction: null,
  2043. spiderfyOnMaxZoom: false,
  2044. showCoverageOnHover: false,
  2045. zoomToBoundsOnClick: true,
  2046. singleMarkerMode: false,
  2047. disableClusteringAtZoom: null,
  2048. // Setting this to false prevents the removal of any clusters outside of the viewpoint, which
  2049. // is the default behaviour for performance reasons.
  2050. removeOutsideVisibleBounds: true,
  2051. // Set to false to disable all animations (zoom and spiderfy).
  2052. // If false, option animateAddingMarkers below has no effect.
  2053. // If L.DomUtil.TRANSITION is falsy, this option has no effect.
  2054. animate: true,
  2055. //Whether to animate adding markers after adding the MarkerClusterGroup to the map
  2056. // If you are adding individual markers set to true, if adding bulk markers leave false for massive performance gains.
  2057. animateAddingMarkers: false,
  2058. //Increase to increase the distance away that spiderfied markers appear from the center
  2059. spiderfyDistanceMultiplier: 1,
  2060. // Make it possible to specify a polyline options on a spider leg
  2061. spiderLegPolylineOptions: { weight: 1, color: '#222', opacity: 0.5 },
  2062. // When bulk adding layers, adds markers in chunks. Means addLayers may not add all the layers in the call, others will be loaded during setTimeouts
  2063. chunkedLoading: false,
  2064. chunkInterval: 200, // process markers for a maximum of ~ n milliseconds (then trigger the chunkProgress callback)
  2065. chunkDelay: 50, // at the end of each interval, give n milliseconds back to system/browser
  2066. chunkProgress: null, // progress callback: function(processed, total, elapsed) (e.g. for a progress indicator)
  2067. //Options to pass to the L.Polygon constructor
  2068. polygonOptions: {weight: 1, opacity: 0.5}
  2069. },
  2070. initialize: function (options) {
  2071. L.Util.setOptions(this, options);
  2072. if (!this.options.iconCreateFunction) {
  2073. this.options.iconCreateFunction = this._defaultIconCreateFunction;
  2074. }
  2075. this._featureGroup = L.featureGroup();
  2076. this._featureGroup.addEventParent(this);
  2077. this._nonPointGroup = L.featureGroup();
  2078. this._nonPointGroup.addEventParent(this);
  2079. this._inZoomAnimation = 0;
  2080. this._needsClustering = [];
  2081. this._needsRemoving = []; //Markers removed while we aren't on the map need to be kept track of
  2082. //The bounds of the currently shown area (from _getExpandedVisibleBounds) Updated on zoom/move
  2083. this._currentShownBounds = null;
  2084. this._queue = [];
  2085. // Hook the appropriate animation methods.
  2086. var animate = L.DomUtil.TRANSITION && this.options.animate;
  2087. L.extend(this, animate ? this._withAnimation : this._noAnimation);
  2088. // Remember which MarkerCluster class to instantiate (animated or not).
  2089. this._markerCluster = animate ? L.MarkerCluster : L.MarkerClusterNonAnimated;
  2090. },
  2091. addLayer: function (layer) {
  2092. if (layer instanceof L.LayerGroup) {
  2093. return this.addLayers([layer]);
  2094. }
  2095. //Don't cluster non point data
  2096. if (!layer.getLatLng) {
  2097. this._nonPointGroup.addLayer(layer);
  2098. return this;
  2099. }
  2100. if (!this._map) {
  2101. this._needsClustering.push(layer);
  2102. return this;
  2103. }
  2104. if (this.hasLayer(layer)) {
  2105. return this;
  2106. }
  2107. //If we have already clustered we'll need to add this one to a cluster
  2108. if (this._unspiderfy) {
  2109. this._unspiderfy();
  2110. }
  2111. this._addLayer(layer, this._maxZoom);
  2112. // Refresh bounds and weighted positions.
  2113. this._topClusterLevel._recalculateBounds();
  2114. this._refreshClustersIcons();
  2115. //Work out what is visible
  2116. var visibleLayer = layer,
  2117. currentZoom = this._zoom;
  2118. if (layer.__parent) {
  2119. while (visibleLayer.__parent._zoom >= currentZoom) {
  2120. visibleLayer = visibleLayer.__parent;
  2121. }
  2122. }
  2123. if (this._currentShownBounds.contains(visibleLayer.getLatLng())) {
  2124. if (this.options.animateAddingMarkers) {
  2125. this._animationAddLayer(layer, visibleLayer);
  2126. } else {
  2127. this._animationAddLayerNonAnimated(layer, visibleLayer);
  2128. }
  2129. }
  2130. return this;
  2131. },
  2132. removeLayer: function (layer) {
  2133. if (layer instanceof L.LayerGroup) {
  2134. return this.removeLayers([layer]);
  2135. }
  2136. //Non point layers
  2137. if (!layer.getLatLng) {
  2138. this._nonPointGroup.removeLayer(layer);
  2139. return this;
  2140. }
  2141. if (!this._map) {
  2142. if (!this._arraySplice(this._needsClustering, layer) && this.hasLayer(layer)) {
  2143. this._needsRemoving.push(layer);
  2144. }
  2145. return this;
  2146. }
  2147. if (!layer.__parent) {
  2148. return this;
  2149. }
  2150. if (this._unspiderfy) {
  2151. this._unspiderfy();
  2152. this._unspiderfyLayer(layer);
  2153. }
  2154. //Remove the marker from clusters
  2155. this._removeLayer(layer, true);
  2156. // Refresh bounds and weighted positions.
  2157. this._topClusterLevel._recalculateBounds();
  2158. this._refreshClustersIcons();
  2159. layer.off('move', this._childMarkerMoved, this);
  2160. if (this._featureGroup.hasLayer(layer)) {
  2161. this._featureGroup.removeLayer(layer);
  2162. if (layer.clusterShow) {
  2163. layer.clusterShow();
  2164. }
  2165. }
  2166. return this;
  2167. },
  2168. //Takes an array of markers and adds them in bulk
  2169. addLayers: function (layersArray) {
  2170. if (!L.Util.isArray(layersArray)) {
  2171. return this.addLayer(layersArray);
  2172. }
  2173. var fg = this._featureGroup,
  2174. npg = this._nonPointGroup,
  2175. chunked = this.options.chunkedLoading,
  2176. chunkInterval = this.options.chunkInterval,
  2177. chunkProgress = this.options.chunkProgress,
  2178. l = layersArray.length,
  2179. offset = 0,
  2180. originalArray = true,
  2181. m;
  2182. if (this._map) {
  2183. var started = (new Date()).getTime();
  2184. var process = L.bind(function () {
  2185. var start = (new Date()).getTime();
  2186. for (; offset < l; offset++) {
  2187. if (chunked && offset % 200 === 0) {
  2188. // every couple hundred markers, instrument the time elapsed since processing started:
  2189. var elapsed = (new Date()).getTime() - start;
  2190. if (elapsed > chunkInterval) {
  2191. break; // been working too hard, time to take a break :-)
  2192. }
  2193. }
  2194. m = layersArray[offset];
  2195. // Group of layers, append children to layersArray and skip.
  2196. // Side effects:
  2197. // - Total increases, so chunkProgress ratio jumps backward.
  2198. // - Groups are not included in this group, only their non-group child layers (hasLayer).
  2199. // Changing array length while looping does not affect performance in current browsers:
  2200. // http://jsperf.com/for-loop-changing-length/6
  2201. if (m instanceof L.LayerGroup) {
  2202. if (originalArray) {
  2203. layersArray = layersArray.slice();
  2204. originalArray = false;
  2205. }
  2206. this._extractNonGroupLayers(m, layersArray);
  2207. l = layersArray.length;
  2208. continue;
  2209. }
  2210. //Not point data, can't be clustered
  2211. if (!m.getLatLng) {
  2212. npg.addLayer(m);
  2213. continue;
  2214. }
  2215. if (this.hasLayer(m)) {
  2216. continue;
  2217. }
  2218. this._addLayer(m, this._maxZoom);
  2219. //If we just made a cluster of size 2 then we need to remove the other marker from the map (if it is) or we never will
  2220. if (m.__parent) {
  2221. if (m.__parent.getChildCount() === 2) {
  2222. var markers = m.__parent.getAllChildMarkers(),
  2223. otherMarker = markers[0] === m ? markers[1] : markers[0];
  2224. fg.removeLayer(otherMarker);
  2225. }
  2226. }
  2227. }
  2228. if (chunkProgress) {
  2229. // report progress and time elapsed:
  2230. chunkProgress(offset, l, (new Date()).getTime() - started);
  2231. }
  2232. // Completed processing all markers.
  2233. if (offset === l) {
  2234. // Refresh bounds and weighted positions.
  2235. this._topClusterLevel._recalculateBounds();
  2236. this._refreshClustersIcons();
  2237. this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds);
  2238. } else {
  2239. setTimeout(process, this.options.chunkDelay);
  2240. }
  2241. }, this);
  2242. process();
  2243. } else {
  2244. var needsClustering = this._needsClustering;
  2245. for (; offset < l; offset++) {
  2246. m = layersArray[offset];
  2247. // Group of layers, append children to layersArray and skip.
  2248. if (m instanceof L.LayerGroup) {
  2249. if (originalArray) {
  2250. layersArray = layersArray.slice();
  2251. originalArray = false;
  2252. }
  2253. this._extractNonGroupLayers(m, layersArray);
  2254. l = layersArray.length;
  2255. continue;
  2256. }
  2257. //Not point data, can't be clustered
  2258. if (!m.getLatLng) {
  2259. npg.addLayer(m);
  2260. continue;
  2261. }
  2262. if (this.hasLayer(m)) {
  2263. continue;
  2264. }
  2265. needsClustering.push(m);
  2266. }
  2267. }
  2268. return this;
  2269. },
  2270. //Takes an array of markers and removes them in bulk
  2271. removeLayers: function (layersArray) {
  2272. var i, m,
  2273. l = layersArray.length,
  2274. fg = this._featureGroup,
  2275. npg = this._nonPointGroup,
  2276. originalArray = true;
  2277. if (!this._map) {
  2278. for (i = 0; i < l; i++) {
  2279. m = layersArray[i];
  2280. // Group of layers, append children to layersArray and skip.
  2281. if (m instanceof L.LayerGroup) {
  2282. if (originalArray) {
  2283. layersArray = layersArray.slice();
  2284. originalArray = false;
  2285. }
  2286. this._extractNonGroupLayers(m, layersArray);
  2287. l = layersArray.length;
  2288. continue;
  2289. }
  2290. this._arraySplice(this._needsClustering, m);
  2291. npg.removeLayer(m);
  2292. if (this.hasLayer(m)) {
  2293. this._needsRemoving.push(m);
  2294. }
  2295. }
  2296. return this;
  2297. }
  2298. if (this._unspiderfy) {
  2299. this._unspiderfy();
  2300. // Work on a copy of the array, so that next loop is not affected.
  2301. var layersArray2 = layersArray.slice(),
  2302. l2 = l;
  2303. for (i = 0; i < l2; i++) {
  2304. m = layersArray2[i];
  2305. // Group of layers, append children to layersArray and skip.
  2306. if (m instanceof L.LayerGroup) {
  2307. this._extractNonGroupLayers(m, layersArray2);
  2308. l2 = layersArray2.length;
  2309. continue;
  2310. }
  2311. this._unspiderfyLayer(m);
  2312. }
  2313. }
  2314. for (i = 0; i < l; i++) {
  2315. m = layersArray[i];
  2316. // Group of layers, append children to layersArray and skip.
  2317. if (m instanceof L.LayerGroup) {
  2318. if (originalArray) {
  2319. layersArray = layersArray.slice();
  2320. originalArray = false;
  2321. }
  2322. this._extractNonGroupLayers(m, layersArray);
  2323. l = layersArray.length;
  2324. continue;
  2325. }
  2326. if (!m.__parent) {
  2327. npg.removeLayer(m);
  2328. continue;
  2329. }
  2330. this._removeLayer(m, true, true);
  2331. if (fg.hasLayer(m)) {
  2332. fg.removeLayer(m);
  2333. if (m.clusterShow) {
  2334. m.clusterShow();
  2335. }
  2336. }
  2337. }
  2338. // Refresh bounds and weighted positions.
  2339. this._topClusterLevel._recalculateBounds();
  2340. this._refreshClustersIcons();
  2341. //Fix up the clusters and markers on the map
  2342. this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds);
  2343. return this;
  2344. },
  2345. //Removes all layers from the MarkerClusterGroup
  2346. clearLayers: function () {
  2347. //Need our own special implementation as the LayerGroup one doesn't work for us
  2348. //If we aren't on the map (yet), blow away the markers we know of
  2349. if (!this._map) {
  2350. this._needsClustering = [];
  2351. delete this._gridClusters;
  2352. delete this._gridUnclustered;
  2353. }
  2354. if (this._noanimationUnspiderfy) {
  2355. this._noanimationUnspiderfy();
  2356. }
  2357. //Remove all the visible layers
  2358. this._featureGroup.clearLayers();
  2359. this._nonPointGroup.clearLayers();
  2360. this.eachLayer(function (marker) {
  2361. marker.off('move', this._childMarkerMoved, this);
  2362. delete marker.__parent;
  2363. });
  2364. if (this._map) {
  2365. //Reset _topClusterLevel and the DistanceGrids
  2366. this._generateInitialClusters();
  2367. }
  2368. return this;
  2369. },
  2370. //Override FeatureGroup.getBounds as it doesn't work
  2371. getBounds: function () {
  2372. var bounds = new L.LatLngBounds();
  2373. if (this._topClusterLevel) {
  2374. bounds.extend(this._topClusterLevel._bounds);
  2375. }
  2376. for (var i = this._needsClustering.length - 1; i >= 0; i--) {
  2377. bounds.extend(this._needsClustering[i].getLatLng());
  2378. }
  2379. bounds.extend(this._nonPointGroup.getBounds());
  2380. return bounds;
  2381. },
  2382. //Overrides LayerGroup.eachLayer
  2383. eachLayer: function (method, context) {
  2384. var markers = this._needsClustering.slice(),
  2385. needsRemoving = this._needsRemoving,
  2386. i;
  2387. if (this._topClusterLevel) {
  2388. this._topClusterLevel.getAllChildMarkers(markers);
  2389. }
  2390. for (i = markers.length - 1; i >= 0; i--) {
  2391. if (needsRemoving.indexOf(markers[i]) === -1) {
  2392. method.call(context, markers[i]);
  2393. }
  2394. }
  2395. this._nonPointGroup.eachLayer(method, context);
  2396. },
  2397. //Overrides LayerGroup.getLayers
  2398. getLayers: function () {
  2399. var layers = [];
  2400. this.eachLayer(function (l) {
  2401. layers.push(l);
  2402. });
  2403. return layers;
  2404. },
  2405. //Overrides LayerGroup.getLayer, WARNING: Really bad performance
  2406. getLayer: function (id) {
  2407. var result = null;
  2408. id = parseInt(id, 10);
  2409. this.eachLayer(function (l) {
  2410. if (L.stamp(l) === id) {
  2411. result = l;
  2412. }
  2413. });
  2414. return result;
  2415. },
  2416. //Returns true if the given layer is in this MarkerClusterGroup
  2417. hasLayer: function (layer) {
  2418. if (!layer) {
  2419. return false;
  2420. }
  2421. var i, anArray = this._needsClustering;
  2422. for (i = anArray.length - 1; i >= 0; i--) {
  2423. if (anArray[i] === layer) {
  2424. return true;
  2425. }
  2426. }
  2427. anArray = this._needsRemoving;
  2428. for (i = anArray.length - 1; i >= 0; i--) {
  2429. if (anArray[i] === layer) {
  2430. return false;
  2431. }
  2432. }
  2433. return !!(layer.__parent && layer.__parent._group === this) || this._nonPointGroup.hasLayer(layer);
  2434. },
  2435. //Zoom down to show the given layer (spiderfying if necessary) then calls the callback
  2436. zoomToShowLayer: function (layer, callback) {
  2437. if (typeof callback !== 'function') {
  2438. callback = function () {};
  2439. }
  2440. var showMarker = function () {
  2441. if ((layer._icon || layer.__parent._icon) && !this._inZoomAnimation) {
  2442. this._map.off('moveend', showMarker, this);
  2443. this.off('animationend', showMarker, this);
  2444. if (layer._icon) {
  2445. callback();
  2446. } else if (layer.__parent._icon) {
  2447. this.once('spiderfied', callback, this);
  2448. layer.__parent.spiderfy();
  2449. }
  2450. }
  2451. };
  2452. if (layer._icon && this._map.getBounds().contains(layer.getLatLng())) {
  2453. //Layer is visible ond on screen, immediate return
  2454. callback();
  2455. } else if (layer.__parent._zoom < Math.round(this._map._zoom)) {
  2456. //Layer should be visible at this zoom level. It must not be on screen so just pan over to it
  2457. this._map.on('moveend', showMarker, this);
  2458. this._map.panTo(layer.getLatLng());
  2459. } else {
  2460. var moveStart = function () {
  2461. this._map.off('movestart', moveStart, this);
  2462. moveStart = null;
  2463. };
  2464. this._map.on('movestart', moveStart, this);
  2465. this._map.on('moveend', showMarker, this);
  2466. this.on('animationend', showMarker, this);
  2467. layer.__parent.zoomToBounds();
  2468. if (moveStart) {
  2469. //Never started moving, must already be there, probably need clustering however
  2470. showMarker.call(this);
  2471. }
  2472. }
  2473. },
  2474. //Overrides FeatureGroup.onAdd
  2475. onAdd: function (map) {
  2476. this._map = map;
  2477. var i, l, layer;
  2478. if (!isFinite(this._map.getMaxZoom())) {
  2479. throw "Map has no maxZoom specified";
  2480. }
  2481. this._featureGroup.addTo(map);
  2482. this._nonPointGroup.addTo(map);
  2483. if (!this._gridClusters) {
  2484. this._generateInitialClusters();
  2485. }
  2486. this._maxLat = map.options.crs.projection.MAX_LATITUDE;
  2487. for (i = 0, l = this._needsRemoving.length; i < l; i++) {
  2488. layer = this._needsRemoving[i];
  2489. this._removeLayer(layer, true);
  2490. }
  2491. this._needsRemoving = [];
  2492. //Remember the current zoom level and bounds
  2493. this._zoom = Math.round(this._map._zoom);
  2494. this._currentShownBounds = this._getExpandedVisibleBounds();
  2495. this._map.on('zoomend', this._zoomEnd, this);
  2496. this._map.on('moveend', this._moveEnd, this);
  2497. if (this._spiderfierOnAdd) { //TODO FIXME: Not sure how to have spiderfier add something on here nicely
  2498. this._spiderfierOnAdd();
  2499. }
  2500. this._bindEvents();
  2501. //Actually add our markers to the map:
  2502. l = this._needsClustering;
  2503. this._needsClustering = [];
  2504. this.addLayers(l);
  2505. },
  2506. //Overrides FeatureGroup.onRemove
  2507. onRemove: function (map) {
  2508. map.off('zoomend', this._zoomEnd, this);
  2509. map.off('moveend', this._moveEnd, this);
  2510. this._unbindEvents();
  2511. //In case we are in a cluster animation
  2512. this._map._mapPane.className = this._map._mapPane.className.replace(' leaflet-cluster-anim', '');
  2513. if (this._spiderfierOnRemove) { //TODO FIXME: Not sure how to have spiderfier add something on here nicely
  2514. this._spiderfierOnRemove();
  2515. }
  2516. delete this._maxLat;
  2517. //Clean up all the layers we added to the map
  2518. this._hideCoverage();
  2519. this._featureGroup.remove();
  2520. this._nonPointGroup.remove();
  2521. this._featureGroup.clearLayers();
  2522. this._map = null;
  2523. },
  2524. getVisibleParent: function (marker) {
  2525. var vMarker = marker;
  2526. while (vMarker && !vMarker._icon) {
  2527. vMarker = vMarker.__parent;
  2528. }
  2529. return vMarker || null;
  2530. },
  2531. //Remove the given object from the given array
  2532. _arraySplice: function (anArray, obj) {
  2533. for (var i = anArray.length - 1; i >= 0; i--) {
  2534. if (anArray[i] === obj) {
  2535. anArray.splice(i, 1);
  2536. return true;
  2537. }
  2538. }
  2539. },
  2540. /**
  2541. * Removes a marker from all _gridUnclustered zoom levels, starting at the supplied zoom.
  2542. * @param marker to be removed from _gridUnclustered.
  2543. * @param z integer bottom start zoom level (included)
  2544. * @private
  2545. */
  2546. _removeFromGridUnclustered: function (marker, z) {
  2547. var map = this._map,
  2548. gridUnclustered = this._gridUnclustered;
  2549. for (; z >= 0; z--) {
  2550. if (!gridUnclustered[z].removeObject(marker, map.project(marker.getLatLng(), z))) {
  2551. break;
  2552. }
  2553. }
  2554. },
  2555. _childMarkerMoved: function (e) {
  2556. if (!this._ignoreMove) {
  2557. e.target._latlng = e.oldLatLng;
  2558. this.removeLayer(e.target);
  2559. e.target._latlng = e.latlng;
  2560. this.addLayer(e.target);
  2561. }
  2562. },
  2563. //Internal function for removing a marker from everything.
  2564. //dontUpdateMap: set to true if you will handle updating the map manually (for bulk functions)
  2565. _removeLayer: function (marker, removeFromDistanceGrid, dontUpdateMap) {
  2566. var gridClusters = this._gridClusters,
  2567. gridUnclustered = this._gridUnclustered,
  2568. fg = this._featureGroup,
  2569. map = this._map;
  2570. //Remove the marker from distance clusters it might be in
  2571. if (removeFromDistanceGrid) {
  2572. this._removeFromGridUnclustered(marker, this._maxZoom);
  2573. }
  2574. //Work our way up the clusters removing them as we go if required
  2575. var cluster = marker.__parent,
  2576. markers = cluster._markers,
  2577. otherMarker;
  2578. //Remove the marker from the immediate parents marker list
  2579. this._arraySplice(markers, marker);
  2580. while (cluster) {
  2581. cluster._childCount--;
  2582. cluster._boundsNeedUpdate = true;
  2583. if (cluster._zoom < 0) {
  2584. //Top level, do nothing
  2585. break;
  2586. } else if (removeFromDistanceGrid && cluster._childCount <= 1) { //Cluster no longer required
  2587. //We need to push the other marker up to the parent
  2588. otherMarker = cluster._markers[0] === marker ? cluster._markers[1] : cluster._markers[0];
  2589. //Update distance grid
  2590. gridClusters[cluster._zoom].removeObject(cluster, map.project(cluster._cLatLng, cluster._zoom));
  2591. gridUnclustered[cluster._zoom].addObject(otherMarker, map.project(otherMarker.getLatLng(), cluster._zoom));
  2592. //Move otherMarker up to parent
  2593. this._arraySplice(cluster.__parent._childClusters, cluster);
  2594. cluster.__parent._markers.push(otherMarker);
  2595. otherMarker.__parent = cluster.__parent;
  2596. if (cluster._icon) {
  2597. //Cluster is currently on the map, need to put the marker on the map instead
  2598. fg.removeLayer(cluster);
  2599. if (!dontUpdateMap) {
  2600. fg.addLayer(otherMarker);
  2601. }
  2602. }
  2603. } else {
  2604. cluster._iconNeedsUpdate = true;
  2605. }
  2606. cluster = cluster.__parent;
  2607. }
  2608. delete marker.__parent;
  2609. },
  2610. _isOrIsParent: function (el, oel) {
  2611. while (oel) {
  2612. if (el === oel) {
  2613. return true;
  2614. }
  2615. oel = oel.parentNode;
  2616. }
  2617. return false;
  2618. },
  2619. //Override L.Evented.fire
  2620. fire: function (type, data, propagate) {
  2621. if (data && data.layer instanceof L.MarkerCluster) {
  2622. //Prevent multiple clustermouseover/off events if the icon is made up of stacked divs (Doesn't work in ie <= 8, no relatedTarget)
  2623. if (data.originalEvent && this._isOrIsParent(data.layer._icon, data.originalEvent.relatedTarget)) {
  2624. return;
  2625. }
  2626. type = 'cluster' + type;
  2627. }
  2628. L.FeatureGroup.prototype.fire.call(this, type, data, propagate);
  2629. },
  2630. //Override L.Evented.listens
  2631. listens: function (type, propagate) {
  2632. return L.FeatureGroup.prototype.listens.call(this, type, propagate) || L.FeatureGroup.prototype.listens.call(this, 'cluster' + type, propagate);
  2633. },
  2634. //Default functionality
  2635. _defaultIconCreateFunction: function (cluster) {
  2636. var childCount = cluster.getChildCount();
  2637. var c = ' marker-cluster-';
  2638. if (childCount < 10) {
  2639. c += 'small';
  2640. } else if (childCount < 100) {
  2641. c += 'medium';
  2642. } else {
  2643. c += 'large';
  2644. }
  2645. return new L.DivIcon({ html: '<div><span>' + childCount + '</span></div>', className: 'marker-cluster' + c, iconSize: new L.Point(40, 40) });
  2646. },
  2647. _bindEvents: function () {
  2648. var map = this._map,
  2649. spiderfyOnMaxZoom = this.options.spiderfyOnMaxZoom,
  2650. showCoverageOnHover = this.options.showCoverageOnHover,
  2651. zoomToBoundsOnClick = this.options.zoomToBoundsOnClick;
  2652. //Zoom on cluster click or spiderfy if we are at the lowest level
  2653. if (spiderfyOnMaxZoom || zoomToBoundsOnClick) {
  2654. this.on('clusterclick', this._zoomOrSpiderfy, this);
  2655. }
  2656. //Show convex hull (boundary) polygon on mouse over
  2657. if (showCoverageOnHover) {
  2658. this.on('clustermouseover', this._showCoverage, this);
  2659. this.on('clustermouseout', this._hideCoverage, this);
  2660. map.on('zoomend', this._hideCoverage, this);
  2661. }
  2662. },
  2663. _zoomOrSpiderfy: function (e) {
  2664. var cluster = e.layer,
  2665. bottomCluster = cluster;
  2666. while (bottomCluster._childClusters.length === 1) {
  2667. bottomCluster = bottomCluster._childClusters[0];
  2668. }
  2669. if (bottomCluster._zoom === this._maxZoom &&
  2670. bottomCluster._childCount === cluster._childCount &&
  2671. this.options.spiderfyOnMaxZoom) {
  2672. // All child markers are contained in a single cluster from this._maxZoom to this cluster.
  2673. cluster.spiderfy();
  2674. } else if (this.options.zoomToBoundsOnClick) {
  2675. cluster.zoomToBounds();
  2676. }
  2677. // Focus the map again for keyboard users.
  2678. if (e.originalEvent && e.originalEvent.keyCode === 13) {
  2679. this._map._container.focus();
  2680. }
  2681. },
  2682. _showCoverage: function (e) {
  2683. var map = this._map;
  2684. if (this._inZoomAnimation) {
  2685. return;
  2686. }
  2687. if (this._shownPolygon) {
  2688. map.removeLayer(this._shownPolygon);
  2689. }
  2690. if (e.layer.getChildCount() > 2 && e.layer !== this._spiderfied) {
  2691. this._shownPolygon = new L.Polygon(e.layer.getConvexHull(), this.options.polygonOptions);
  2692. map.addLayer(this._shownPolygon);
  2693. }
  2694. },
  2695. _hideCoverage: function () {
  2696. if (this._shownPolygon) {
  2697. this._map.removeLayer(this._shownPolygon);
  2698. this._shownPolygon = null;
  2699. }
  2700. },
  2701. _unbindEvents: function () {
  2702. var spiderfyOnMaxZoom = this.options.spiderfyOnMaxZoom,
  2703. showCoverageOnHover = this.options.showCoverageOnHover,
  2704. zoomToBoundsOnClick = this.options.zoomToBoundsOnClick,
  2705. map = this._map;
  2706. if (spiderfyOnMaxZoom || zoomToBoundsOnClick) {
  2707. this.off('clusterclick', this._zoomOrSpiderfy, this);
  2708. }
  2709. if (showCoverageOnHover) {
  2710. this.off('clustermouseover', this._showCoverage, this);
  2711. this.off('clustermouseout', this._hideCoverage, this);
  2712. map.off('zoomend', this._hideCoverage, this);
  2713. }
  2714. },
  2715. _zoomEnd: function () {
  2716. if (!this._map) { //May have been removed from the map by a zoomEnd handler
  2717. return;
  2718. }
  2719. this._mergeSplitClusters();
  2720. this._zoom = Math.round(this._map._zoom);
  2721. this._currentShownBounds = this._getExpandedVisibleBounds();
  2722. },
  2723. _moveEnd: function () {
  2724. if (this._inZoomAnimation) {
  2725. return;
  2726. }
  2727. var newBounds = this._getExpandedVisibleBounds();
  2728. this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, this._zoom, newBounds);
  2729. this._topClusterLevel._recursivelyAddChildrenToMap(null, Math.round(this._map._zoom), newBounds);
  2730. this._currentShownBounds = newBounds;
  2731. return;
  2732. },
  2733. _generateInitialClusters: function () {
  2734. var maxZoom = this._map.getMaxZoom(),
  2735. radius = this.options.maxClusterRadius,
  2736. radiusFn = radius;
  2737. //If we just set maxClusterRadius to a single number, we need to create
  2738. //a simple function to return that number. Otherwise, we just have to
  2739. //use the function we've passed in.
  2740. if (typeof radius !== "function") {
  2741. radiusFn = function () { return radius; };
  2742. }
  2743. if (this.options.disableClusteringAtZoom) {
  2744. maxZoom = this.options.disableClusteringAtZoom - 1;
  2745. }
  2746. this._maxZoom = maxZoom;
  2747. this._gridClusters = {};
  2748. this._gridUnclustered = {};
  2749. //Set up DistanceGrids for each zoom
  2750. for (var zoom = maxZoom; zoom >= 0; zoom--) {
  2751. this._gridClusters[zoom] = new L.DistanceGrid(radiusFn(zoom));
  2752. this._gridUnclustered[zoom] = new L.DistanceGrid(radiusFn(zoom));
  2753. }
  2754. // Instantiate the appropriate L.MarkerCluster class (animated or not).
  2755. this._topClusterLevel = new this._markerCluster(this, -1);
  2756. },
  2757. //Zoom: Zoom to start adding at (Pass this._maxZoom to start at the bottom)
  2758. _addLayer: function (layer, zoom) {
  2759. var gridClusters = this._gridClusters,
  2760. gridUnclustered = this._gridUnclustered,
  2761. markerPoint, z;
  2762. if (this.options.singleMarkerMode) {
  2763. this._overrideMarkerIcon(layer);
  2764. }
  2765. layer.on('move', this._childMarkerMoved, this);
  2766. //Find the lowest zoom level to slot this one in
  2767. for (; zoom >= 0; zoom--) {
  2768. markerPoint = this._map.project(layer.getLatLng(), zoom); // calculate pixel position
  2769. //Try find a cluster close by
  2770. var closest = gridClusters[zoom].getNearObject(markerPoint);
  2771. if (closest) {
  2772. closest._addChild(layer);
  2773. layer.__parent = closest;
  2774. return;
  2775. }
  2776. //Try find a marker close by to form a new cluster with
  2777. closest = gridUnclustered[zoom].getNearObject(markerPoint);
  2778. if (closest) {
  2779. var parent = closest.__parent;
  2780. if (parent) {
  2781. this._removeLayer(closest, false);
  2782. }
  2783. //Create new cluster with these 2 in it
  2784. var newCluster = new this._markerCluster(this, zoom, closest, layer);
  2785. gridClusters[zoom].addObject(newCluster, this._map.project(newCluster._cLatLng, zoom));
  2786. closest.__parent = newCluster;
  2787. layer.__parent = newCluster;
  2788. //First create any new intermediate parent clusters that don't exist
  2789. var lastParent = newCluster;
  2790. for (z = zoom - 1; z > parent._zoom; z--) {
  2791. lastParent = new this._markerCluster(this, z, lastParent);
  2792. gridClusters[z].addObject(lastParent, this._map.project(closest.getLatLng(), z));
  2793. }
  2794. parent._addChild(lastParent);
  2795. //Remove closest from this zoom level and any above that it is in, replace with newCluster
  2796. this._removeFromGridUnclustered(closest, zoom);
  2797. return;
  2798. }
  2799. //Didn't manage to cluster in at this zoom, record us as a marker here and continue upwards
  2800. gridUnclustered[zoom].addObject(layer, markerPoint);
  2801. }
  2802. //Didn't get in anything, add us to the top
  2803. this._topClusterLevel._addChild(layer);
  2804. layer.__parent = this._topClusterLevel;
  2805. return;
  2806. },
  2807. /**
  2808. * Refreshes the icon of all "dirty" visible clusters.
  2809. * Non-visible "dirty" clusters will be updated when they are added to the map.
  2810. * @private
  2811. */
  2812. _refreshClustersIcons: function () {
  2813. this._featureGroup.eachLayer(function (c) {
  2814. if (c instanceof L.MarkerCluster && c._iconNeedsUpdate) {
  2815. c._updateIcon();
  2816. }
  2817. });
  2818. },
  2819. //Enqueue code to fire after the marker expand/contract has happened
  2820. _enqueue: function (fn) {
  2821. this._queue.push(fn);
  2822. if (!this._queueTimeout) {
  2823. this._queueTimeout = setTimeout(L.bind(this._processQueue, this), 300);
  2824. }
  2825. },
  2826. _processQueue: function () {
  2827. for (var i = 0; i < this._queue.length; i++) {
  2828. this._queue[i].call(this);
  2829. }
  2830. this._queue.length = 0;
  2831. clearTimeout(this._queueTimeout);
  2832. this._queueTimeout = null;
  2833. },
  2834. //Merge and split any existing clusters that are too big or small
  2835. _mergeSplitClusters: function () {
  2836. var mapZoom = Math.round(this._map._zoom);
  2837. //In case we are starting to split before the animation finished
  2838. this._processQueue();
  2839. if (this._zoom < mapZoom && this._currentShownBounds.intersects(this._getExpandedVisibleBounds())) { //Zoom in, split
  2840. this._animationStart();
  2841. //Remove clusters now off screen
  2842. this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, this._zoom, this._getExpandedVisibleBounds());
  2843. this._animationZoomIn(this._zoom, mapZoom);
  2844. } else if (this._zoom > mapZoom) { //Zoom out, merge
  2845. this._animationStart();
  2846. this._animationZoomOut(this._zoom, mapZoom);
  2847. } else {
  2848. this._moveEnd();
  2849. }
  2850. },
  2851. //Gets the maps visible bounds expanded in each direction by the size of the screen (so the user cannot see an area we do not cover in one pan)
  2852. _getExpandedVisibleBounds: function () {
  2853. if (!this.options.removeOutsideVisibleBounds) {
  2854. return this._mapBoundsInfinite;
  2855. } else if (L.Browser.mobile) {
  2856. return this._checkBoundsMaxLat(this._map.getBounds());
  2857. }
  2858. return this._checkBoundsMaxLat(this._map.getBounds().pad(1)); // Padding expands the bounds by its own dimensions but scaled with the given factor.
  2859. },
  2860. /**
  2861. * Expands the latitude to Infinity (or -Infinity) if the input bounds reach the map projection maximum defined latitude
  2862. * (in the case of Web/Spherical Mercator, it is 85.0511287798 / see https://en.wikipedia.org/wiki/Web_Mercator#Formulas).
  2863. * Otherwise, the removeOutsideVisibleBounds option will remove markers beyond that limit, whereas the same markers without
  2864. * this option (or outside MCG) will have their position floored (ceiled) by the projection and rendered at that limit,
  2865. * making the user think that MCG "eats" them and never displays them again.
  2866. * @param bounds L.LatLngBounds
  2867. * @returns {L.LatLngBounds}
  2868. * @private
  2869. */
  2870. _checkBoundsMaxLat: function (bounds) {
  2871. var maxLat = this._maxLat;
  2872. if (maxLat !== undefined) {
  2873. if (bounds.getNorth() >= maxLat) {
  2874. bounds._northEast.lat = Infinity;
  2875. }
  2876. if (bounds.getSouth() <= -maxLat) {
  2877. bounds._southWest.lat = -Infinity;
  2878. }
  2879. }
  2880. return bounds;
  2881. },
  2882. //Shared animation code
  2883. _animationAddLayerNonAnimated: function (layer, newCluster) {
  2884. if (newCluster === layer) {
  2885. this._featureGroup.addLayer(layer);
  2886. } else if (newCluster._childCount === 2) {
  2887. newCluster._addToMap();
  2888. var markers = newCluster.getAllChildMarkers();
  2889. this._featureGroup.removeLayer(markers[0]);
  2890. this._featureGroup.removeLayer(markers[1]);
  2891. } else {
  2892. newCluster._updateIcon();
  2893. }
  2894. },
  2895. /**
  2896. * Extracts individual (i.e. non-group) layers from a Layer Group.
  2897. * @param group to extract layers from.
  2898. * @param output {Array} in which to store the extracted layers.
  2899. * @returns {*|Array}
  2900. * @private
  2901. */
  2902. _extractNonGroupLayers: function (group, output) {
  2903. var layers = group.getLayers(),
  2904. i = 0,
  2905. layer;
  2906. output = output || [];
  2907. for (; i < layers.length; i++) {
  2908. layer = layers[i];
  2909. if (layer instanceof L.LayerGroup) {
  2910. this._extractNonGroupLayers(layer, output);
  2911. continue;
  2912. }
  2913. output.push(layer);
  2914. }
  2915. return output;
  2916. },
  2917. /**
  2918. * Implements the singleMarkerMode option.
  2919. * @param layer Marker to re-style using the Clusters iconCreateFunction.
  2920. * @returns {L.Icon} The newly created icon.
  2921. * @private
  2922. */
  2923. _overrideMarkerIcon: function (layer) {
  2924. var icon = layer.options.icon = this.options.iconCreateFunction({
  2925. getChildCount: function () {
  2926. return 1;
  2927. },
  2928. getAllChildMarkers: function () {
  2929. return [layer];
  2930. }
  2931. });
  2932. return icon;
  2933. }
  2934. });
  2935. // Constant bounds used in case option "removeOutsideVisibleBounds" is set to false.
  2936. L.MarkerClusterGroup.include({
  2937. _mapBoundsInfinite: new L.LatLngBounds(new L.LatLng(-Infinity, -Infinity), new L.LatLng(Infinity, Infinity))
  2938. });
  2939. L.MarkerClusterGroup.include({
  2940. _noAnimation: {
  2941. //Non Animated versions of everything
  2942. _animationStart: function () {
  2943. //Do nothing...
  2944. },
  2945. _animationZoomIn: function (previousZoomLevel, newZoomLevel) {
  2946. this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, previousZoomLevel);
  2947. this._topClusterLevel._recursivelyAddChildrenToMap(null, newZoomLevel, this._getExpandedVisibleBounds());
  2948. //We didn't actually animate, but we use this event to mean "clustering animations have finished"
  2949. this.fire('animationend');
  2950. },
  2951. _animationZoomOut: function (previousZoomLevel, newZoomLevel) {
  2952. this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, previousZoomLevel);
  2953. this._topClusterLevel._recursivelyAddChildrenToMap(null, newZoomLevel, this._getExpandedVisibleBounds());
  2954. //We didn't actually animate, but we use this event to mean "clustering animations have finished"
  2955. this.fire('animationend');
  2956. },
  2957. _animationAddLayer: function (layer, newCluster) {
  2958. this._animationAddLayerNonAnimated(layer, newCluster);
  2959. }
  2960. },
  2961. _withAnimation: {
  2962. //Animated versions here
  2963. _animationStart: function () {
  2964. this._map._mapPane.className += ' leaflet-cluster-anim';
  2965. this._inZoomAnimation++;
  2966. },
  2967. _animationZoomIn: function (previousZoomLevel, newZoomLevel) {
  2968. var bounds = this._getExpandedVisibleBounds(),
  2969. fg = this._featureGroup,
  2970. i;
  2971. this._ignoreMove = true;
  2972. //Add all children of current clusters to map and remove those clusters from map
  2973. this._topClusterLevel._recursively(bounds, previousZoomLevel, 0, function (c) {
  2974. var startPos = c._latlng,
  2975. markers = c._markers,
  2976. m;
  2977. if (!bounds.contains(startPos)) {
  2978. startPos = null;
  2979. }
  2980. if (c._isSingleParent() && previousZoomLevel + 1 === newZoomLevel) { //Immediately add the new child and remove us
  2981. fg.removeLayer(c);
  2982. c._recursivelyAddChildrenToMap(null, newZoomLevel, bounds);
  2983. } else {
  2984. //Fade out old cluster
  2985. c.clusterHide();
  2986. c._recursivelyAddChildrenToMap(startPos, newZoomLevel, bounds);
  2987. }
  2988. //Remove all markers that aren't visible any more
  2989. //TODO: Do we actually need to do this on the higher levels too?
  2990. for (i = markers.length - 1; i >= 0; i--) {
  2991. m = markers[i];
  2992. if (!bounds.contains(m._latlng)) {
  2993. fg.removeLayer(m);
  2994. }
  2995. }
  2996. });
  2997. this._forceLayout();
  2998. //Update opacities
  2999. this._topClusterLevel._recursivelyBecomeVisible(bounds, newZoomLevel);
  3000. //TODO Maybe? Update markers in _recursivelyBecomeVisible
  3001. fg.eachLayer(function (n) {
  3002. if (!(n instanceof L.MarkerCluster) && n._icon) {
  3003. n.clusterShow();
  3004. }
  3005. });
  3006. //update the positions of the just added clusters/markers
  3007. this._topClusterLevel._recursively(bounds, previousZoomLevel, newZoomLevel, function (c) {
  3008. c._recursivelyRestoreChildPositions(newZoomLevel);
  3009. });
  3010. this._ignoreMove = false;
  3011. //Remove the old clusters and close the zoom animation
  3012. this._enqueue(function () {
  3013. //update the positions of the just added clusters/markers
  3014. this._topClusterLevel._recursively(bounds, previousZoomLevel, 0, function (c) {
  3015. fg.removeLayer(c);
  3016. c.clusterShow();
  3017. });
  3018. this._animationEnd();
  3019. });
  3020. },
  3021. _animationZoomOut: function (previousZoomLevel, newZoomLevel) {
  3022. this._animationZoomOutSingle(this._topClusterLevel, previousZoomLevel - 1, newZoomLevel);
  3023. //Need to add markers for those that weren't on the map before but are now
  3024. this._topClusterLevel._recursivelyAddChildrenToMap(null, newZoomLevel, this._getExpandedVisibleBounds());
  3025. //Remove markers that were on the map before but won't be now
  3026. this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, previousZoomLevel, this._getExpandedVisibleBounds());
  3027. },
  3028. _animationAddLayer: function (layer, newCluster) {
  3029. var me = this,
  3030. fg = this._featureGroup;
  3031. fg.addLayer(layer);
  3032. if (newCluster !== layer) {
  3033. if (newCluster._childCount > 2) { //Was already a cluster
  3034. newCluster._updateIcon();
  3035. this._forceLayout();
  3036. this._animationStart();
  3037. layer._setPos(this._map.latLngToLayerPoint(newCluster.getLatLng()));
  3038. layer.clusterHide();
  3039. this._enqueue(function () {
  3040. fg.removeLayer(layer);
  3041. layer.clusterShow();
  3042. me._animationEnd();
  3043. });
  3044. } else { //Just became a cluster
  3045. this._forceLayout();
  3046. me._animationStart();
  3047. me._animationZoomOutSingle(newCluster, this._map.getMaxZoom(), this._zoom);
  3048. }
  3049. }
  3050. }
  3051. },
  3052. // Private methods for animated versions.
  3053. _animationZoomOutSingle: function (cluster, previousZoomLevel, newZoomLevel) {
  3054. var bounds = this._getExpandedVisibleBounds();
  3055. //Animate all of the markers in the clusters to move to their cluster center point
  3056. cluster._recursivelyAnimateChildrenInAndAddSelfToMap(bounds, previousZoomLevel + 1, newZoomLevel);
  3057. var me = this;
  3058. //Update the opacity (If we immediately set it they won't animate)
  3059. this._forceLayout();
  3060. cluster._recursivelyBecomeVisible(bounds, newZoomLevel);
  3061. //TODO: Maybe use the transition timing stuff to make this more reliable
  3062. //When the animations are done, tidy up
  3063. this._enqueue(function () {
  3064. //This cluster stopped being a cluster before the timeout fired
  3065. if (cluster._childCount === 1) {
  3066. var m = cluster._markers[0];
  3067. //If we were in a cluster animation at the time then the opacity and position of our child could be wrong now, so fix it
  3068. this._ignoreMove = true;
  3069. m.setLatLng(m.getLatLng());
  3070. this._ignoreMove = false;
  3071. if (m.clusterShow) {
  3072. m.clusterShow();
  3073. }
  3074. } else {
  3075. cluster._recursively(bounds, newZoomLevel, 0, function (c) {
  3076. c._recursivelyRemoveChildrenFromMap(bounds, previousZoomLevel + 1);
  3077. });
  3078. }
  3079. me._animationEnd();
  3080. });
  3081. },
  3082. _animationEnd: function () {
  3083. if (this._map) {
  3084. this._map._mapPane.className = this._map._mapPane.className.replace(' leaflet-cluster-anim', '');
  3085. }
  3086. this._inZoomAnimation--;
  3087. this.fire('animationend');
  3088. },
  3089. //Force a browser layout of stuff in the map
  3090. // Should apply the current opacity and location to all elements so we can update them again for an animation
  3091. _forceLayout: function () {
  3092. //In my testing this works, infact offsetWidth of any element seems to work.
  3093. //Could loop all this._layers and do this for each _icon if it stops working
  3094. L.Util.falseFn(document.body.offsetWidth);
  3095. }
  3096. });
  3097. L.markerClusterGroup = function (options) {
  3098. return new L.MarkerClusterGroup(options);
  3099. };
  3100. L.MarkerCluster = L.Marker.extend({
  3101. initialize: function (group, zoom, a, b) {
  3102. L.Marker.prototype.initialize.call(this, a ? (a._cLatLng || a.getLatLng()) : new L.LatLng(0, 0), { icon: this });
  3103. this._group = group;
  3104. this._zoom = zoom;
  3105. this._markers = [];
  3106. this._childClusters = [];
  3107. this._childCount = 0;
  3108. this._iconNeedsUpdate = true;
  3109. this._boundsNeedUpdate = true;
  3110. this._bounds = new L.LatLngBounds();
  3111. if (a) {
  3112. this._addChild(a);
  3113. }
  3114. if (b) {
  3115. this._addChild(b);
  3116. }
  3117. },
  3118. //Recursively retrieve all child markers of this cluster
  3119. getAllChildMarkers: function (storageArray) {
  3120. storageArray = storageArray || [];
  3121. for (var i = this._childClusters.length - 1; i >= 0; i--) {
  3122. this._childClusters[i].getAllChildMarkers(storageArray);
  3123. }
  3124. for (var j = this._markers.length - 1; j >= 0; j--) {
  3125. storageArray.push(this._markers[j]);
  3126. }
  3127. return storageArray;
  3128. },
  3129. //Returns the count of how many child markers we have
  3130. getChildCount: function () {
  3131. return this._childCount;
  3132. },
  3133. //Zoom to the minimum of showing all of the child markers, or the extents of this cluster
  3134. zoomToBounds: function () {
  3135. var childClusters = this._childClusters.slice(),
  3136. map = this._group._map,
  3137. boundsZoom = map.getBoundsZoom(this._bounds),
  3138. zoom = this._zoom + 1,
  3139. mapZoom = map.getZoom(),
  3140. i;
  3141. //calculate how far we need to zoom down to see all of the markers
  3142. while (childClusters.length > 0 && boundsZoom > zoom) {
  3143. zoom++;
  3144. var newClusters = [];
  3145. for (i = 0; i < childClusters.length; i++) {
  3146. newClusters = newClusters.concat(childClusters[i]._childClusters);
  3147. }
  3148. childClusters = newClusters;
  3149. }
  3150. if (boundsZoom > zoom) {
  3151. this._group._map.setView(this._latlng, zoom);
  3152. } else if (boundsZoom <= mapZoom) { //If fitBounds wouldn't zoom us down, zoom us down instead
  3153. this._group._map.setView(this._latlng, mapZoom + 1);
  3154. } else {
  3155. this._group._map.fitBounds(this._bounds);
  3156. }
  3157. },
  3158. getBounds: function () {
  3159. var bounds = new L.LatLngBounds();
  3160. bounds.extend(this._bounds);
  3161. return bounds;
  3162. },
  3163. _updateIcon: function () {
  3164. this._iconNeedsUpdate = true;
  3165. if (this._icon) {
  3166. this.setIcon(this);
  3167. }
  3168. },
  3169. //Cludge for Icon, we pretend to be an icon for performance
  3170. createIcon: function () {
  3171. if (this._iconNeedsUpdate) {
  3172. this._iconObj = this._group.options.iconCreateFunction(this);
  3173. this._iconNeedsUpdate = false;
  3174. }
  3175. return this._iconObj.createIcon();
  3176. },
  3177. createShadow: function () {
  3178. return this._iconObj.createShadow();
  3179. },
  3180. _addChild: function (new1, isNotificationFromChild) {
  3181. this._iconNeedsUpdate = true;
  3182. this._boundsNeedUpdate = true;
  3183. this._setClusterCenter(new1);
  3184. if (new1 instanceof L.MarkerCluster) {
  3185. if (!isNotificationFromChild) {
  3186. this._childClusters.push(new1);
  3187. new1.__parent = this;
  3188. }
  3189. this._childCount += new1._childCount;
  3190. } else {
  3191. if (!isNotificationFromChild) {
  3192. this._markers.push(new1);
  3193. }
  3194. this._childCount++;
  3195. }
  3196. if (this.__parent) {
  3197. this.__parent._addChild(new1, true);
  3198. }
  3199. },
  3200. /**
  3201. * Makes sure the cluster center is set. If not, uses the child center if it is a cluster, or the marker position.
  3202. * @param child L.MarkerCluster|L.Marker that will be used as cluster center if not defined yet.
  3203. * @private
  3204. */
  3205. _setClusterCenter: function (child) {
  3206. if (!this._cLatLng) {
  3207. // when clustering, take position of the first point as the cluster center
  3208. this._cLatLng = child._cLatLng || child._latlng;
  3209. }
  3210. },
  3211. /**
  3212. * Assigns impossible bounding values so that the next extend entirely determines the new bounds.
  3213. * This method avoids having to trash the previous L.LatLngBounds object and to create a new one, which is much slower for this class.
  3214. * As long as the bounds are not extended, most other methods would probably fail, as they would with bounds initialized but not extended.
  3215. * @private
  3216. */
  3217. _resetBounds: function () {
  3218. var bounds = this._bounds;
  3219. if (bounds._southWest) {
  3220. bounds._southWest.lat = Infinity;
  3221. bounds._southWest.lng = Infinity;
  3222. }
  3223. if (bounds._northEast) {
  3224. bounds._northEast.lat = -Infinity;
  3225. bounds._northEast.lng = -Infinity;
  3226. }
  3227. },
  3228. _recalculateBounds: function () {
  3229. var markers = this._markers,
  3230. childClusters = this._childClusters,
  3231. latSum = 0,
  3232. lngSum = 0,
  3233. totalCount = this._childCount,
  3234. i, child, childLatLng, childCount;
  3235. // Case where all markers are removed from the map and we are left with just an empty _topClusterLevel.
  3236. if (totalCount === 0) {
  3237. return;
  3238. }
  3239. // Reset rather than creating a new object, for performance.
  3240. this._resetBounds();
  3241. // Child markers.
  3242. for (i = 0; i < markers.length; i++) {
  3243. childLatLng = markers[i]._latlng;
  3244. this._bounds.extend(childLatLng);
  3245. latSum += childLatLng.lat;
  3246. lngSum += childLatLng.lng;
  3247. }
  3248. // Child clusters.
  3249. for (i = 0; i < childClusters.length; i++) {
  3250. child = childClusters[i];
  3251. // Re-compute child bounds and weighted position first if necessary.
  3252. if (child._boundsNeedUpdate) {
  3253. child._recalculateBounds();
  3254. }
  3255. this._bounds.extend(child._bounds);
  3256. childLatLng = child._wLatLng;
  3257. childCount = child._childCount;
  3258. latSum += childLatLng.lat * childCount;
  3259. lngSum += childLatLng.lng * childCount;
  3260. }
  3261. this._latlng = this._wLatLng = new L.LatLng(latSum / totalCount, lngSum / totalCount);
  3262. // Reset dirty flag.
  3263. this._boundsNeedUpdate = false;
  3264. },
  3265. //Set our markers position as given and add it to the map
  3266. _addToMap: function (startPos) {
  3267. if (startPos) {
  3268. this._backupLatlng = this._latlng;
  3269. this.setLatLng(startPos);
  3270. }
  3271. this._group._featureGroup.addLayer(this);
  3272. if(this.plabel){
  3273. if(this.plabel._isOpen){
  3274. this.showPlabel();
  3275. }
  3276. }
  3277. },
  3278. _recursivelyAnimateChildrenIn: function (bounds, center, maxZoom) {
  3279. this._recursively(bounds, 0, maxZoom - 1,
  3280. function (c) {
  3281. var markers = c._markers,
  3282. i, m;
  3283. for (i = markers.length - 1; i >= 0; i--) {
  3284. m = markers[i];
  3285. //Only do it if the icon is still on the map
  3286. if (m._icon) {
  3287. m._setPos(center);
  3288. m.clusterHide();
  3289. }
  3290. }
  3291. },
  3292. function (c) {
  3293. var childClusters = c._childClusters,
  3294. j, cm;
  3295. for (j = childClusters.length - 1; j >= 0; j--) {
  3296. cm = childClusters[j];
  3297. if (cm._icon) {
  3298. cm._setPos(center);
  3299. cm.clusterHide();
  3300. }
  3301. }
  3302. }
  3303. );
  3304. },
  3305. _recursivelyAnimateChildrenInAndAddSelfToMap: function (bounds, previousZoomLevel, newZoomLevel) {
  3306. this._recursively(bounds, newZoomLevel, 0,
  3307. function (c) {
  3308. c._recursivelyAnimateChildrenIn(bounds, c._group._map.latLngToLayerPoint(c.getLatLng()).round(), previousZoomLevel);
  3309. //TODO: depthToAnimateIn affects _isSingleParent, if there is a multizoom we may/may not be.
  3310. //As a hack we only do a animation free zoom on a single level zoom, if someone does multiple levels then we always animate
  3311. if (c._isSingleParent() && previousZoomLevel - 1 === newZoomLevel) {
  3312. c.clusterShow();
  3313. c._recursivelyRemoveChildrenFromMap(bounds, previousZoomLevel); //Immediately remove our children as we are replacing them. TODO previousBounds not bounds
  3314. } else {
  3315. c.clusterHide();
  3316. }
  3317. c._addToMap();
  3318. }
  3319. );
  3320. },
  3321. _recursivelyBecomeVisible: function (bounds, zoomLevel) {
  3322. this._recursively(bounds, 0, zoomLevel, null, function (c) {
  3323. c.clusterShow();
  3324. });
  3325. },
  3326. _recursivelyAddChildrenToMap: function (startPos, zoomLevel, bounds) {
  3327. this._recursively(bounds, -1, zoomLevel,
  3328. function (c) {
  3329. if (zoomLevel === c._zoom) {
  3330. return;
  3331. }
  3332. //Add our child markers at startPos (so they can be animated out)
  3333. for (var i = c._markers.length - 1; i >= 0; i--) {
  3334. var nm = c._markers[i];
  3335. if (!bounds.contains(nm._latlng)) {
  3336. continue;
  3337. }
  3338. if (startPos) {
  3339. nm._backupLatlng = nm.getLatLng();
  3340. nm.setLatLng(startPos);
  3341. if (nm.clusterHide) {
  3342. nm.clusterHide();
  3343. }
  3344. }
  3345. c._group._featureGroup.addLayer(nm);
  3346. }
  3347. },
  3348. function (c) {
  3349. c._addToMap(startPos);
  3350. }
  3351. );
  3352. },
  3353. _recursivelyRestoreChildPositions: function (zoomLevel) {
  3354. //Fix positions of child markers
  3355. for (var i = this._markers.length - 1; i >= 0; i--) {
  3356. var nm = this._markers[i];
  3357. if (nm._backupLatlng) {
  3358. nm.setLatLng(nm._backupLatlng);
  3359. delete nm._backupLatlng;
  3360. }
  3361. }
  3362. if (zoomLevel - 1 === this._zoom) {
  3363. //Reposition child clusters
  3364. for (var j = this._childClusters.length - 1; j >= 0; j--) {
  3365. this._childClusters[j]._restorePosition();
  3366. }
  3367. } else {
  3368. for (var k = this._childClusters.length - 1; k >= 0; k--) {
  3369. this._childClusters[k]._recursivelyRestoreChildPositions(zoomLevel);
  3370. }
  3371. }
  3372. },
  3373. _restorePosition: function () {
  3374. if (this._backupLatlng) {
  3375. this.setLatLng(this._backupLatlng);
  3376. delete this._backupLatlng;
  3377. }
  3378. },
  3379. //exceptBounds: If set, don't remove any markers/clusters in it
  3380. _recursivelyRemoveChildrenFromMap: function (previousBounds, zoomLevel, exceptBounds) {
  3381. var m, i;
  3382. this._recursively(previousBounds, -1, zoomLevel - 1,
  3383. function (c) {
  3384. //Remove markers at every level
  3385. for (i = c._markers.length - 1; i >= 0; i--) {
  3386. m = c._markers[i];
  3387. if (!exceptBounds || !exceptBounds.contains(m._latlng)) {
  3388. c._group._featureGroup.removeLayer(m);
  3389. if (m.clusterShow) {
  3390. m.clusterShow();
  3391. }
  3392. }
  3393. }
  3394. },
  3395. function (c) {
  3396. //Remove child clusters at just the bottom level
  3397. for (i = c._childClusters.length - 1; i >= 0; i--) {
  3398. m = c._childClusters[i];
  3399. if (!exceptBounds || !exceptBounds.contains(m._latlng)) {
  3400. c._group._featureGroup.removeLayer(m);
  3401. if (m.clusterShow) {
  3402. m.clusterShow();
  3403. }
  3404. }
  3405. }
  3406. }
  3407. );
  3408. },
  3409. //Run the given functions recursively to this and child clusters
  3410. // boundsToApplyTo: a L.LatLngBounds representing the bounds of what clusters to recurse in to
  3411. // zoomLevelToStart: zoom level to start running functions (inclusive)
  3412. // zoomLevelToStop: zoom level to stop running functions (inclusive)
  3413. // runAtEveryLevel: function that takes an L.MarkerCluster as an argument that should be applied on every level
  3414. // runAtBottomLevel: function that takes an L.MarkerCluster as an argument that should be applied at only the bottom level
  3415. _recursively: function (boundsToApplyTo, zoomLevelToStart, zoomLevelToStop, runAtEveryLevel, runAtBottomLevel) {
  3416. var childClusters = this._childClusters,
  3417. zoom = this._zoom,
  3418. i, c;
  3419. if (zoomLevelToStart <= zoom) {
  3420. if (runAtEveryLevel) {
  3421. runAtEveryLevel(this);
  3422. }
  3423. if (runAtBottomLevel && zoom === zoomLevelToStop) {
  3424. runAtBottomLevel(this);
  3425. }
  3426. }
  3427. if (zoom < zoomLevelToStart || zoom < zoomLevelToStop) {
  3428. for (i = childClusters.length - 1; i >= 0; i--) {
  3429. c = childClusters[i];
  3430. if (boundsToApplyTo.intersects(c._bounds)) {
  3431. c._recursively(boundsToApplyTo, zoomLevelToStart, zoomLevelToStop, runAtEveryLevel, runAtBottomLevel);
  3432. }
  3433. }
  3434. }
  3435. },
  3436. //Returns true if we are the parent of only one cluster and that cluster is the same as us
  3437. _isSingleParent: function () {
  3438. //Don't need to check this._markers as the rest won't work if there are any
  3439. return this._childClusters.length > 0 && this._childClusters[0]._childCount === this._childCount;
  3440. }
  3441. });
  3442. /*
  3443. * Extends L.Marker to include two extra methods: clusterHide and clusterShow.
  3444. *
  3445. * They work as setOpacity(0) and setOpacity(1) respectively, but
  3446. * they will remember the marker's opacity when hiding and showing it again.
  3447. *
  3448. */
  3449. L.Marker.include({
  3450. clusterHide: function () {
  3451. this.options.opacityWhenUnclustered = this.options.opacity || 1;
  3452. return this.setOpacity(0);
  3453. },
  3454. clusterShow: function () {
  3455. var ret = this.setOpacity(this.options.opacity || this.options.opacityWhenUnclustered);
  3456. delete this.options.opacityWhenUnclustered;
  3457. return ret;
  3458. }
  3459. });
  3460. L.DistanceGrid = function (cellSize) {
  3461. this._cellSize = cellSize;
  3462. this._sqCellSize = cellSize * cellSize;
  3463. this._grid = {};
  3464. this._objectPoint = { };
  3465. };
  3466. L.DistanceGrid.prototype = {
  3467. addObject: function (obj, point) {
  3468. var x = this._getCoord(point.x),
  3469. y = this._getCoord(point.y),
  3470. grid = this._grid,
  3471. row = grid[y] = grid[y] || {},
  3472. cell = row[x] = row[x] || [],
  3473. stamp = L.Util.stamp(obj);
  3474. this._objectPoint[stamp] = point;
  3475. cell.push(obj);
  3476. },
  3477. updateObject: function (obj, point) {
  3478. this.removeObject(obj);
  3479. this.addObject(obj, point);
  3480. },
  3481. //Returns true if the object was found
  3482. removeObject: function (obj, point) {
  3483. var x = this._getCoord(point.x),
  3484. y = this._getCoord(point.y),
  3485. grid = this._grid,
  3486. row = grid[y] = grid[y] || {},
  3487. cell = row[x] = row[x] || [],
  3488. i, len;
  3489. delete this._objectPoint[L.Util.stamp(obj)];
  3490. for (i = 0, len = cell.length; i < len; i++) {
  3491. if (cell[i] === obj) {
  3492. cell.splice(i, 1);
  3493. if (len === 1) {
  3494. delete row[x];
  3495. }
  3496. return true;
  3497. }
  3498. }
  3499. },
  3500. eachObject: function (fn, context) {
  3501. var i, j, k, len, row, cell, removed,
  3502. grid = this._grid;
  3503. for (i in grid) {
  3504. row = grid[i];
  3505. for (j in row) {
  3506. cell = row[j];
  3507. for (k = 0, len = cell.length; k < len; k++) {
  3508. removed = fn.call(context, cell[k]);
  3509. if (removed) {
  3510. k--;
  3511. len--;
  3512. }
  3513. }
  3514. }
  3515. }
  3516. },
  3517. getNearObject: function (point) {
  3518. var x = this._getCoord(point.x),
  3519. y = this._getCoord(point.y),
  3520. i, j, k, row, cell, len, obj, dist,
  3521. objectPoint = this._objectPoint,
  3522. closestDistSq = this._sqCellSize,
  3523. closest = null;
  3524. for (i = y - 1; i <= y + 1; i++) {
  3525. row = this._grid[i];
  3526. if (row) {
  3527. for (j = x - 1; j <= x + 1; j++) {
  3528. cell = row[j];
  3529. if (cell) {
  3530. for (k = 0, len = cell.length; k < len; k++) {
  3531. obj = cell[k];
  3532. dist = this._sqDist(objectPoint[L.Util.stamp(obj)], point);
  3533. if (dist < closestDistSq) {
  3534. closestDistSq = dist;
  3535. closest = obj;
  3536. }
  3537. }
  3538. }
  3539. }
  3540. }
  3541. }
  3542. return closest;
  3543. },
  3544. _getCoord: function (x) {
  3545. return Math.floor(x / this._cellSize);
  3546. },
  3547. _sqDist: function (p, p2) {
  3548. var dx = p2.x - p.x,
  3549. dy = p2.y - p.y;
  3550. return dx * dx + dy * dy;
  3551. }
  3552. };
  3553. /* Copyright (c) 2012 the authors listed at the following URL, and/or
  3554. the authors of referenced articles or incorporated external code:
  3555. http://en.literateprograms.org/Quickhull_(Javascript)?action=history&offset=20120410175256
  3556. Permission is hereby granted, free of charge, to any person obtaining
  3557. a copy of this software and associated documentation files (the
  3558. "Software"), to deal in the Software without restriction, including
  3559. without limitation the rights to use, copy, modify, merge, publish,
  3560. distribute, sublicense, and/or sell copies of the Software, and to
  3561. permit persons to whom the Software is furnished to do so, subject to
  3562. the following conditions:
  3563. The above copyright notice and this permission notice shall be
  3564. included in all copies or substantial portions of the Software.
  3565. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  3566. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  3567. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  3568. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  3569. CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  3570. TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  3571. SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  3572. Retrieved from: http://en.literateprograms.org/Quickhull_(Javascript)?oldid=18434
  3573. */
  3574. (function () {
  3575. L.QuickHull = {
  3576. /*
  3577. * @param {Object} cpt a point to be measured from the baseline
  3578. * @param {Array} bl the baseline, as represented by a two-element
  3579. * array of latlng objects.
  3580. * @returns {Number} an approximate distance measure
  3581. */
  3582. getDistant: function (cpt, bl) {
  3583. var vY = bl[1].lat - bl[0].lat,
  3584. vX = bl[0].lng - bl[1].lng;
  3585. return (vX * (cpt.lat - bl[0].lat) + vY * (cpt.lng - bl[0].lng));
  3586. },
  3587. /*
  3588. * @param {Array} baseLine a two-element array of latlng objects
  3589. * representing the baseline to project from
  3590. * @param {Array} latLngs an array of latlng objects
  3591. * @returns {Object} the maximum point and all new points to stay
  3592. * in consideration for the hull.
  3593. */
  3594. findMostDistantPointFromBaseLine: function (baseLine, latLngs) {
  3595. var maxD = 0,
  3596. maxPt = null,
  3597. newPoints = [],
  3598. i, pt, d;
  3599. for (i = latLngs.length - 1; i >= 0; i--) {
  3600. pt = latLngs[i];
  3601. d = this.getDistant(pt, baseLine);
  3602. if (d > 0) {
  3603. newPoints.push(pt);
  3604. } else {
  3605. continue;
  3606. }
  3607. if (d > maxD) {
  3608. maxD = d;
  3609. maxPt = pt;
  3610. }
  3611. }
  3612. return { maxPoint: maxPt, newPoints: newPoints };
  3613. },
  3614. /*
  3615. * Given a baseline, compute the convex hull of latLngs as an array
  3616. * of latLngs.
  3617. *
  3618. * @param {Array} latLngs
  3619. * @returns {Array}
  3620. */
  3621. buildConvexHull: function (baseLine, latLngs) {
  3622. var convexHullBaseLines = [],
  3623. t = this.findMostDistantPointFromBaseLine(baseLine, latLngs);
  3624. if (t.maxPoint) { // if there is still a point "outside" the base line
  3625. convexHullBaseLines =
  3626. convexHullBaseLines.concat(
  3627. this.buildConvexHull([baseLine[0], t.maxPoint], t.newPoints)
  3628. );
  3629. convexHullBaseLines =
  3630. convexHullBaseLines.concat(
  3631. this.buildConvexHull([t.maxPoint, baseLine[1]], t.newPoints)
  3632. );
  3633. return convexHullBaseLines;
  3634. } else { // if there is no more point "outside" the base line, the current base line is part of the convex hull
  3635. return [baseLine[0]];
  3636. }
  3637. },
  3638. /*
  3639. * Given an array of latlngs, compute a convex hull as an array
  3640. * of latlngs
  3641. *
  3642. * @param {Array} latLngs
  3643. * @returns {Array}
  3644. */
  3645. getConvexHull: function (latLngs) {
  3646. // find first baseline
  3647. var maxLat = false, minLat = false,
  3648. maxLng = false, minLng = false,
  3649. maxLatPt = null, minLatPt = null,
  3650. maxLngPt = null, minLngPt = null,
  3651. maxPt = null, minPt = null,
  3652. i;
  3653. for (i = latLngs.length - 1; i >= 0; i--) {
  3654. var pt = latLngs[i];
  3655. if (maxLat === false || pt.lat > maxLat) {
  3656. maxLatPt = pt;
  3657. maxLat = pt.lat;
  3658. }
  3659. if (minLat === false || pt.lat < minLat) {
  3660. minLatPt = pt;
  3661. minLat = pt.lat;
  3662. }
  3663. if (maxLng === false || pt.lng > maxLng) {
  3664. maxLngPt = pt;
  3665. maxLng = pt.lng;
  3666. }
  3667. if (minLng === false || pt.lng < minLng) {
  3668. minLngPt = pt;
  3669. minLng = pt.lng;
  3670. }
  3671. }
  3672. if (minLat !== maxLat) {
  3673. minPt = minLatPt;
  3674. maxPt = maxLatPt;
  3675. } else {
  3676. minPt = minLngPt;
  3677. maxPt = maxLngPt;
  3678. }
  3679. var ch = [].concat(this.buildConvexHull([minPt, maxPt], latLngs),
  3680. this.buildConvexHull([maxPt, minPt], latLngs));
  3681. return ch;
  3682. }
  3683. };
  3684. }());
  3685. L.MarkerCluster.include({
  3686. getConvexHull: function () {
  3687. var childMarkers = this.getAllChildMarkers(),
  3688. points = [],
  3689. p, i;
  3690. for (i = childMarkers.length - 1; i >= 0; i--) {
  3691. p = childMarkers[i].getLatLng();
  3692. points.push(p);
  3693. }
  3694. return L.QuickHull.getConvexHull(points);
  3695. }
  3696. });
  3697. //This code is 100% based on https://github.com/jawj/OverlappingMarkerSpiderfier-Leaflet
  3698. //Huge thanks to jawj for implementing it first to make my job easy :-)
  3699. L.MarkerCluster.include({
  3700. _2PI: Math.PI * 2,
  3701. _circleFootSeparation: 25, //related to circumference of circle
  3702. _circleStartAngle: Math.PI / 6,
  3703. _spiralFootSeparation: 28, //related to size of spiral (experiment!)
  3704. _spiralLengthStart: 11,
  3705. _spiralLengthFactor: 5,
  3706. _circleSpiralSwitchover: 9, //show spiral instead of circle from this marker count upwards.
  3707. // 0 -> always spiral; Infinity -> always circle
  3708. spiderfy: function () {
  3709. if (this._group._spiderfied === this || this._group._inZoomAnimation) {
  3710. return;
  3711. }
  3712. var childMarkers = this.getAllChildMarkers(),
  3713. group = this._group,
  3714. map = group._map,
  3715. center = map.latLngToLayerPoint(this._latlng),
  3716. positions;
  3717. this._group._unspiderfy();
  3718. this._group._spiderfied = this;
  3719. //TODO Maybe: childMarkers order by distance to center
  3720. if (childMarkers.length >= this._circleSpiralSwitchover) {
  3721. positions = this._generatePointsSpiral(childMarkers.length, center);
  3722. } else {
  3723. center.y += 10; // Otherwise circles look wrong => hack for standard blue icon, renders differently for other icons.
  3724. positions = this._generatePointsCircle(childMarkers.length, center);
  3725. }
  3726. this._animationSpiderfy(childMarkers, positions);
  3727. },
  3728. unspiderfy: function (zoomDetails) {
  3729. /// <param Name="zoomDetails">Argument from zoomanim if being called in a zoom animation or null otherwise</param>
  3730. if (this._group._inZoomAnimation) {
  3731. return;
  3732. }
  3733. this._animationUnspiderfy(zoomDetails);
  3734. this._group._spiderfied = null;
  3735. },
  3736. _generatePointsCircle: function (count, centerPt) {
  3737. var circumference = this._group.options.spiderfyDistanceMultiplier * this._circleFootSeparation * (2 + count),
  3738. legLength = circumference / this._2PI, //radius from circumference
  3739. angleStep = this._2PI / count,
  3740. res = [],
  3741. i, angle;
  3742. res.length = count;
  3743. for (i = count - 1; i >= 0; i--) {
  3744. angle = this._circleStartAngle + i * angleStep;
  3745. res[i] = new L.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle))._round();
  3746. }
  3747. return res;
  3748. },
  3749. _generatePointsSpiral: function (count, centerPt) {
  3750. var spiderfyDistanceMultiplier = this._group.options.spiderfyDistanceMultiplier,
  3751. legLength = spiderfyDistanceMultiplier * this._spiralLengthStart,
  3752. separation = spiderfyDistanceMultiplier * this._spiralFootSeparation,
  3753. lengthFactor = spiderfyDistanceMultiplier * this._spiralLengthFactor * this._2PI,
  3754. angle = 0,
  3755. res = [],
  3756. i;
  3757. res.length = count;
  3758. // Higher index, closer position to cluster center.
  3759. for (i = count - 1; i >= 0; i--) {
  3760. angle += separation / legLength + i * 0.0005;
  3761. res[i] = new L.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle))._round();
  3762. legLength += lengthFactor / angle;
  3763. }
  3764. return res;
  3765. },
  3766. _noanimationUnspiderfy: function () {
  3767. var group = this._group,
  3768. map = group._map,
  3769. fg = group._featureGroup,
  3770. childMarkers = this.getAllChildMarkers(),
  3771. m, i;
  3772. group._ignoreMove = true;
  3773. this.setOpacity(1);
  3774. for (i = childMarkers.length - 1; i >= 0; i--) {
  3775. m = childMarkers[i];
  3776. fg.removeLayer(m);
  3777. if (m._preSpiderfyLatlng) {
  3778. m.setLatLng(m._preSpiderfyLatlng);
  3779. delete m._preSpiderfyLatlng;
  3780. }
  3781. if (m.setZIndexOffset) {
  3782. m.setZIndexOffset(0);
  3783. }
  3784. if (m._spiderLeg) {
  3785. map.removeLayer(m._spiderLeg);
  3786. delete m._spiderLeg;
  3787. }
  3788. }
  3789. group.fire('unspiderfied', {
  3790. cluster: this,
  3791. markers: childMarkers
  3792. });
  3793. group._ignoreMove = false;
  3794. group._spiderfied = null;
  3795. }
  3796. });
  3797. //Non Animated versions of everything
  3798. L.MarkerClusterNonAnimated = L.MarkerCluster.extend({
  3799. _animationSpiderfy: function (childMarkers, positions) {
  3800. var group = this._group,
  3801. map = group._map,
  3802. fg = group._featureGroup,
  3803. legOptions = this._group.options.spiderLegPolylineOptions,
  3804. i, m, leg, newPos;
  3805. group._ignoreMove = true;
  3806. // Traverse in ascending order to make sure that inner circleMarkers are on top of further legs. Normal markers are re-ordered by newPosition.
  3807. // The reverse order trick no longer improves performance on modern browsers.
  3808. for (i = 0; i < childMarkers.length; i++) {
  3809. newPos = map.layerPointToLatLng(positions[i]);
  3810. m = childMarkers[i];
  3811. // Add the leg before the marker, so that in case the latter is a circleMarker, the leg is behind it.
  3812. leg = new L.Polyline([this._latlng, newPos], legOptions);
  3813. map.addLayer(leg);
  3814. m._spiderLeg = leg;
  3815. // Now add the marker.
  3816. m._preSpiderfyLatlng = m._latlng;
  3817. m.setLatLng(newPos);
  3818. if (m.setZIndexOffset) {
  3819. m.setZIndexOffset(1000000); //Make these appear on top of EVERYTHING
  3820. }
  3821. fg.addLayer(m);
  3822. }
  3823. this.setOpacity(0.3);
  3824. group._ignoreMove = false;
  3825. group.fire('spiderfied', {
  3826. cluster: this,
  3827. markers: childMarkers
  3828. });
  3829. },
  3830. _animationUnspiderfy: function () {
  3831. this._noanimationUnspiderfy();
  3832. }
  3833. });
  3834. //Animated versions here
  3835. L.MarkerCluster.include({
  3836. _animationSpiderfy: function (childMarkers, positions) {
  3837. var me = this,
  3838. group = this._group,
  3839. map = group._map,
  3840. fg = group._featureGroup,
  3841. thisLayerLatLng = this._latlng,
  3842. thisLayerPos = map.latLngToLayerPoint(thisLayerLatLng),
  3843. svg = L.Path.SVG,
  3844. legOptions = L.extend({}, this._group.options.spiderLegPolylineOptions), // Copy the options so that we can modify them for animation.
  3845. finalLegOpacity = legOptions.opacity,
  3846. i, m, leg, legPath, legLength, newPos;
  3847. if (finalLegOpacity === undefined) {
  3848. finalLegOpacity = L.MarkerClusterGroup.prototype.options.spiderLegPolylineOptions.opacity;
  3849. }
  3850. if (svg) {
  3851. // If the initial opacity of the spider leg is not 0 then it appears before the animation starts.
  3852. legOptions.opacity = 0;
  3853. // Add the class for CSS transitions.
  3854. legOptions.className = (legOptions.className || '') + ' leaflet-cluster-spider-leg';
  3855. } else {
  3856. // Make sure we have a defined opacity.
  3857. legOptions.opacity = finalLegOpacity;
  3858. }
  3859. group._ignoreMove = true;
  3860. // Add markers and spider legs to map, hidden at our center point.
  3861. // Traverse in ascending order to make sure that inner circleMarkers are on top of further legs. Normal markers are re-ordered by newPosition.
  3862. // The reverse order trick no longer improves performance on modern browsers.
  3863. for (i = 0; i < childMarkers.length; i++) {
  3864. m = childMarkers[i];
  3865. newPos = map.layerPointToLatLng(positions[i]);
  3866. // Add the leg before the marker, so that in case the latter is a circleMarker, the leg is behind it.
  3867. leg = new L.Polyline([thisLayerLatLng, newPos], legOptions);
  3868. map.addLayer(leg);
  3869. m._spiderLeg = leg;
  3870. // Explanations: https://jakearchibald.com/2013/animated-line-drawing-svg/
  3871. // In our case the transition property is declared in the CSS file.
  3872. if (svg) {
  3873. legPath = leg._path;
  3874. legLength = legPath.getTotalLength() + 0.1; // Need a small extra length to avoid remaining dot in Firefox.
  3875. legPath.style.strokeDasharray = legLength; // Just 1 length is enough, it will be duplicated.
  3876. legPath.style.strokeDashoffset = legLength;
  3877. }
  3878. // If it is a marker, add it now and we'll animate it out
  3879. if (m.setZIndexOffset) {
  3880. m.setZIndexOffset(1000000); // Make normal markers appear on top of EVERYTHING
  3881. }
  3882. if (m.clusterHide) {
  3883. m.clusterHide();
  3884. }
  3885. // Vectors just get immediately added
  3886. fg.addLayer(m);
  3887. if (m._setPos) {
  3888. m._setPos(thisLayerPos);
  3889. }
  3890. }
  3891. group._forceLayout();
  3892. group._animationStart();
  3893. // Reveal markers and spider legs.
  3894. for (i = childMarkers.length - 1; i >= 0; i--) {
  3895. newPos = map.layerPointToLatLng(positions[i]);
  3896. m = childMarkers[i];
  3897. //Move marker to new position
  3898. m._preSpiderfyLatlng = m._latlng;
  3899. m.setLatLng(newPos);
  3900. if (m.clusterShow) {
  3901. m.clusterShow();
  3902. }
  3903. // Animate leg (animation is actually delegated to CSS transition).
  3904. if (svg) {
  3905. leg = m._spiderLeg;
  3906. legPath = leg._path;
  3907. legPath.style.strokeDashoffset = 0;
  3908. //legPath.style.strokeOpacity = finalLegOpacity;
  3909. leg.setStyle({opacity: finalLegOpacity});
  3910. }
  3911. }
  3912. this.setOpacity(0.3);
  3913. group._ignoreMove = false;
  3914. setTimeout(function () {
  3915. group._animationEnd();
  3916. group.fire('spiderfied', {
  3917. cluster: me,
  3918. markers: childMarkers
  3919. });
  3920. }, 200);
  3921. },
  3922. _animationUnspiderfy: function (zoomDetails) {
  3923. var me = this,
  3924. group = this._group,
  3925. map = group._map,
  3926. fg = group._featureGroup,
  3927. thisLayerPos = zoomDetails ? map._latLngToNewLayerPoint(this._latlng, zoomDetails.zoom, zoomDetails.center) : map.latLngToLayerPoint(this._latlng),
  3928. childMarkers = this.getAllChildMarkers(),
  3929. svg = L.Path.SVG,
  3930. m, i, leg, legPath, legLength, nonAnimatable;
  3931. group._ignoreMove = true;
  3932. group._animationStart();
  3933. //Make us visible and bring the child markers back in
  3934. this.setOpacity(1);
  3935. for (i = childMarkers.length - 1; i >= 0; i--) {
  3936. m = childMarkers[i];
  3937. //Marker was added to us after we were spiderfied
  3938. if (!m._preSpiderfyLatlng) {
  3939. continue;
  3940. }
  3941. //Fix up the location to the real one
  3942. m.setLatLng(m._preSpiderfyLatlng);
  3943. delete m._preSpiderfyLatlng;
  3944. //Hack override the location to be our center
  3945. nonAnimatable = true;
  3946. if (m._setPos) {
  3947. m._setPos(thisLayerPos);
  3948. nonAnimatable = false;
  3949. }
  3950. if (m.clusterHide) {
  3951. m.clusterHide();
  3952. nonAnimatable = false;
  3953. }
  3954. if (nonAnimatable) {
  3955. fg.removeLayer(m);
  3956. }
  3957. // Animate the spider leg back in (animation is actually delegated to CSS transition).
  3958. if (svg) {
  3959. leg = m._spiderLeg;
  3960. legPath = leg._path;
  3961. legLength = legPath.getTotalLength() + 0.1;
  3962. legPath.style.strokeDashoffset = legLength;
  3963. leg.setStyle({opacity: 0});
  3964. }
  3965. }
  3966. group._ignoreMove = false;
  3967. setTimeout(function () {
  3968. //If we have only <= one child left then that marker will be shown on the map so don't remove it!
  3969. var stillThereChildCount = 0;
  3970. for (i = childMarkers.length - 1; i >= 0; i--) {
  3971. m = childMarkers[i];
  3972. if (m._spiderLeg) {
  3973. stillThereChildCount++;
  3974. }
  3975. }
  3976. for (i = childMarkers.length - 1; i >= 0; i--) {
  3977. m = childMarkers[i];
  3978. if (!m._spiderLeg) { //Has already been unspiderfied
  3979. continue;
  3980. }
  3981. if (m.clusterShow) {
  3982. m.clusterShow();
  3983. }
  3984. if (m.setZIndexOffset) {
  3985. m.setZIndexOffset(0);
  3986. }
  3987. if (stillThereChildCount > 1) {
  3988. fg.removeLayer(m);
  3989. }
  3990. map.removeLayer(m._spiderLeg);
  3991. delete m._spiderLeg;
  3992. }
  3993. group._animationEnd();
  3994. group.fire('unspiderfied', {
  3995. cluster: me,
  3996. markers: childMarkers
  3997. });
  3998. }, 200);
  3999. }
  4000. });
  4001. L.MarkerClusterGroup.include({
  4002. //The MarkerCluster currently spiderfied (if any)
  4003. _spiderfied: null,
  4004. unspiderfy: function () {
  4005. this._unspiderfy.apply(this, arguments);
  4006. },
  4007. _spiderfierOnAdd: function () {
  4008. this._map.on('click', this._unspiderfyWrapper, this);
  4009. if (this._map.options.zoomAnimation) {
  4010. this._map.on('zoomstart', this._unspiderfyZoomStart, this);
  4011. }
  4012. //Browsers without zoomAnimation or a big zoom don't fire zoomstart
  4013. this._map.on('zoomend', this._noanimationUnspiderfy, this);
  4014. if (!L.Browser.touch) {
  4015. this._map.getRenderer(this);
  4016. //Needs to happen in the pageload, not after, or animations don't work in webkit
  4017. // http://stackoverflow.com/questions/8455200/svg-animate-with-dynamically-added-elements
  4018. //Disable on touch browsers as the animation messes up on a touch zoom and isn't very noticable
  4019. }
  4020. },
  4021. _spiderfierOnRemove: function () {
  4022. this._map.off('click', this._unspiderfyWrapper, this);
  4023. this._map.off('zoomstart', this._unspiderfyZoomStart, this);
  4024. this._map.off('zoomanim', this._unspiderfyZoomAnim, this);
  4025. this._map.off('zoomend', this._noanimationUnspiderfy, this);
  4026. //Ensure that markers are back where they should be
  4027. // Use no animation to avoid a sticky leaflet-cluster-anim class on mapPane
  4028. this._noanimationUnspiderfy();
  4029. },
  4030. //On zoom start we add a zoomanim handler so that we are guaranteed to be last (after markers are animated)
  4031. //This means we can define the animation they do rather than Markers doing an animation to their actual location
  4032. _unspiderfyZoomStart: function () {
  4033. if (!this._map) { //May have been removed from the map by a zoomEnd handler
  4034. return;
  4035. }
  4036. this._map.on('zoomanim', this._unspiderfyZoomAnim, this);
  4037. },
  4038. _unspiderfyZoomAnim: function (zoomDetails) {
  4039. //Wait until the first zoomanim after the user has finished touch-zooming before running the animation
  4040. if (L.DomUtil.hasClass(this._map._mapPane, 'leaflet-touching')) {
  4041. return;
  4042. }
  4043. this._map.off('zoomanim', this._unspiderfyZoomAnim, this);
  4044. this._unspiderfy(zoomDetails);
  4045. },
  4046. _unspiderfyWrapper: function () {
  4047. /// <summary>_unspiderfy but passes no arguments</summary>
  4048. this._unspiderfy();
  4049. },
  4050. _unspiderfy: function (zoomDetails) {
  4051. if (this._spiderfied) {
  4052. this._spiderfied.unspiderfy(zoomDetails);
  4053. }
  4054. },
  4055. _noanimationUnspiderfy: function () {
  4056. if (this._spiderfied) {
  4057. this._spiderfied._noanimationUnspiderfy();
  4058. }
  4059. },
  4060. //If the given layer is currently being spiderfied then we unspiderfy it so it isn't on the map anymore etc
  4061. _unspiderfyLayer: function (layer) {
  4062. if (layer._spiderLeg) {
  4063. this._featureGroup.removeLayer(layer);
  4064. if (layer.clusterShow) {
  4065. layer.clusterShow();
  4066. }
  4067. //Position will be fixed up immediately in _animationUnspiderfy
  4068. if (layer.setZIndexOffset) {
  4069. layer.setZIndexOffset(0);
  4070. }
  4071. this._map.removeLayer(layer._spiderLeg);
  4072. delete layer._spiderLeg;
  4073. }
  4074. }
  4075. });
  4076. /**
  4077. * Adds 1 public method to MCG and 1 to L.Marker to facilitate changing
  4078. * markers' icon options and refreshing their icon and their parent clusters
  4079. * accordingly (case where their iconCreateFunction uses data of childMarkers
  4080. * to make up the cluster icon).
  4081. */
  4082. L.MarkerClusterGroup.include({
  4083. /**
  4084. * Updates the icon of all clusters which are parents of the given marker(s).
  4085. * In singleMarkerMode, also updates the given marker(s) icon.
  4086. * @param layers L.MarkerClusterGroup|L.LayerGroup|Array(L.Marker)|Map(L.Marker)|
  4087. * L.MarkerCluster|L.Marker (optional) list of markers (or single marker) whose parent
  4088. * clusters need to be updated. If not provided, retrieves all child markers of this.
  4089. * @returns {L.MarkerClusterGroup}
  4090. */
  4091. refreshClusters: function (layers) {
  4092. if (!layers) {
  4093. layers = this._topClusterLevel.getAllChildMarkers();
  4094. } else if (layers instanceof L.MarkerClusterGroup) {
  4095. layers = layers._topClusterLevel.getAllChildMarkers();
  4096. } else if (layers instanceof L.LayerGroup) {
  4097. layers = layers._layers;
  4098. } else if (layers instanceof L.MarkerCluster) {
  4099. layers = layers.getAllChildMarkers();
  4100. } else if (layers instanceof L.Marker) {
  4101. layers = [layers];
  4102. } // else: must be an Array(L.Marker)|Map(L.Marker)
  4103. this._flagParentsIconsNeedUpdate(layers);
  4104. this._refreshClustersIcons();
  4105. // In case of singleMarkerMode, also re-draw the markers.
  4106. if (this.options.singleMarkerMode) {
  4107. this._refreshSingleMarkerModeMarkers(layers);
  4108. }
  4109. return this;
  4110. },
  4111. /**
  4112. * Simply flags all parent clusters of the given markers as having a "dirty" icon.
  4113. * @param layers Array(L.Marker)|Map(L.Marker) list of markers.
  4114. * @private
  4115. */
  4116. _flagParentsIconsNeedUpdate: function (layers) {
  4117. var id, parent;
  4118. // Assumes layers is an Array or an Object whose prototype is non-enumerable.
  4119. for (id in layers) {
  4120. // Flag parent clusters' icon as "dirty", all the way up.
  4121. // Dumb process that flags multiple times upper parents, but still
  4122. // much more efficient than trying to be smart and make short lists,
  4123. // at least in the case of a hierarchy following a power law:
  4124. // http://jsperf.com/flag-nodes-in-power-hierarchy/2
  4125. parent = layers[id].__parent;
  4126. while (parent) {
  4127. parent._iconNeedsUpdate = true;
  4128. parent = parent.__parent;
  4129. }
  4130. }
  4131. },
  4132. /**
  4133. * Re-draws the icon of the supplied markers.
  4134. * To be used in singleMarkerMode only.
  4135. * @param layers Array(L.Marker)|Map(L.Marker) list of markers.
  4136. * @private
  4137. */
  4138. _refreshSingleMarkerModeMarkers: function (layers) {
  4139. var id, layer;
  4140. for (id in layers) {
  4141. layer = layers[id];
  4142. // Make sure we do not override markers that do not belong to THIS group.
  4143. if (this.hasLayer(layer)) {
  4144. // Need to re-create the icon first, then re-draw the marker.
  4145. layer.setIcon(this._overrideMarkerIcon(layer));
  4146. }
  4147. }
  4148. }
  4149. });
  4150. L.Marker.include({
  4151. /**
  4152. * Updates the given options in the marker's icon and refreshes the marker.
  4153. * @param options map object of icon options.
  4154. * @param directlyRefreshClusters boolean (optional) true to trigger
  4155. * MCG.refreshClustersOf() right away with this single marker.
  4156. * @returns {L.Marker}
  4157. */
  4158. refreshIconOptions: function (options, directlyRefreshClusters) {
  4159. var icon = this.options.icon;
  4160. L.setOptions(icon, options);
  4161. this.setIcon(icon);
  4162. // Shortcut to refresh the associated MCG clusters right away.
  4163. // To be used when refreshing a single marker.
  4164. // Otherwise, better use MCG.refreshClusters() once at the end with
  4165. // the list of modified markers.
  4166. if (directlyRefreshClusters && this.__parent) {
  4167. this.__parent._group.refreshClusters(this);
  4168. }
  4169. return this;
  4170. }
  4171. });
  4172. }(window, document));
  4173. 'use strict';
  4174. (function (factory, window) {
  4175. /*globals define, module, require*/
  4176. // define an AMD module that relies on 'leaflet'
  4177. if (typeof define === 'function' && define.amd) {
  4178. define(['leaflet'], factory);
  4179. // define a Common JS module that relies on 'leaflet'
  4180. } else if (typeof exports === 'object') {
  4181. module.exports = factory(require('leaflet'));
  4182. }
  4183. // attach your plugin to the global 'L' variable
  4184. if(typeof window !== 'undefined' && window.L){
  4185. factory(window.L);
  4186. }
  4187. }(function (L) {
  4188. // 🍂miniclass CancelableEvent (Event objects)
  4189. // 🍂method cancel()
  4190. // Cancel any subsequent action.
  4191. // 🍂miniclass VertexEvent (Event objects)
  4192. // 🍂property vertex: VertexMarker
  4193. // The vertex that fires the event.
  4194. // 🍂miniclass ShapeEvent (Event objects)
  4195. // 🍂property shape: Array
  4196. // The shape (LatLngs array) subject of the action.
  4197. // 🍂miniclass CancelableVertexEvent (Event objects)
  4198. // 🍂inherits VertexEvent
  4199. // 🍂inherits CancelableEvent
  4200. // 🍂miniclass CancelableShapeEvent (Event objects)
  4201. // 🍂inherits ShapeEvent
  4202. // 🍂inherits CancelableEvent
  4203. // 🍂miniclass LayerEvent (Event objects)
  4204. // 🍂property layer: object
  4205. // The Layer (Marker, Polyline…) subject of the action.
  4206. // 🍂namespace Editable; 🍂class Editable; 🍂aka L.Editable
  4207. // Main edition handler. By default, it is attached to the map
  4208. // as `map.editTools` property.
  4209. // Leaflet.Editable is made to be fully extendable. You have three ways to customize
  4210. // the behaviour: using options, listening to events, or extending.
  4211. L.Editable = L.Evented.extend({
  4212. statics: {
  4213. FORWARD: 1,
  4214. BACKWARD: -1
  4215. },
  4216. options: {
  4217. // You can pass them when creating a map using the `editOptions` key.
  4218. // 🍂option zIndex: int = 1000
  4219. // The default zIndex of the editing tools.
  4220. zIndex: 1000,
  4221. // 🍂option polygonClass: class = L.Polygon
  4222. // Class to be used when creating a new Polygon.
  4223. polygonClass: L.Polygon,
  4224. // 🍂option polylineClass: class = L.Polyline
  4225. // Class to be used when creating a new Polyline.
  4226. polylineClass: L.Polyline,
  4227. // 🍂option markerClass: class = L.Marker
  4228. // Class to be used when creating a new Marker.
  4229. markerClass: L.Marker,
  4230. // 🍂option rectangleClass: class = L.Rectangle
  4231. // Class to be used when creating a new Rectangle.
  4232. rectangleClass: L.Rectangle,
  4233. // 🍂option circleClass: class = L.Circle
  4234. // Class to be used when creating a new Circle.
  4235. circleClass: L.Circle,
  4236. // 🍂option drawingCSSClass: string = 'leaflet-editable-drawing'
  4237. // CSS class to be added to the map container while drawing.
  4238. drawingCSSClass: 'leaflet-editable-drawing',
  4239. // 🍂option drawingCursor: const = 'crosshair'
  4240. // Cursor mode set to the map while drawing.
  4241. drawingCursor: 'crosshair',
  4242. // 🍂option editLayer: Layer = new L.LayerGroup()
  4243. // Layer used to store edit tools (vertex, line guide…).
  4244. editLayer: undefined,
  4245. // 🍂option featuresLayer: Layer = new L.LayerGroup()
  4246. // Default layer used to store drawn features (Marker, Polyline…).
  4247. featuresLayer: undefined,
  4248. // 🍂option polylineEditorClass: class = PolylineEditor
  4249. // Class to be used as Polyline editor.
  4250. polylineEditorClass: undefined,
  4251. // 🍂option polygonEditorClass: class = PolygonEditor
  4252. // Class to be used as Polygon editor.
  4253. polygonEditorClass: undefined,
  4254. // 🍂option markerEditorClass: class = MarkerEditor
  4255. // Class to be used as Marker editor.
  4256. markerEditorClass: undefined,
  4257. // 🍂option rectangleEditorClass: class = RectangleEditor
  4258. // Class to be used as Rectangle editor.
  4259. rectangleEditorClass: undefined,
  4260. // 🍂option circleEditorClass: class = CircleEditor
  4261. // Class to be used as Circle editor.
  4262. circleEditorClass: undefined,
  4263. // 🍂option lineGuideOptions: hash = {}
  4264. // Options to be passed to the line guides.
  4265. lineGuideOptions: {},
  4266. // 🍂option skipMiddleMarkers: boolean = false
  4267. // Set this to true if you don't want middle markers.
  4268. skipMiddleMarkers: false
  4269. },
  4270. initialize: function (map, options) {
  4271. L.setOptions(this, options);
  4272. this._lastZIndex = this.options.zIndex;
  4273. this.map = map;
  4274. this.editLayer = this.createEditLayer();
  4275. this.featuresLayer = this.createFeaturesLayer();
  4276. this.forwardLineGuide = this.createLineGuide();
  4277. this.backwardLineGuide = this.createLineGuide();
  4278. },
  4279. fireAndForward: function (type, e) {
  4280. e = e || {};
  4281. e.editTools = this;
  4282. this.fire(type, e);
  4283. this.map.fire(type, e);
  4284. },
  4285. createLineGuide: function () {
  4286. var options = L.extend({dashArray: '5,10', weight: 1, interactive: false}, this.options.lineGuideOptions);
  4287. return L.polyline([], options);
  4288. },
  4289. createVertexIcon: function (options) {
  4290. return L.Browser.touch ? new L.Editable.TouchVertexIcon(options) : new L.Editable.VertexIcon(options);
  4291. },
  4292. createEditLayer: function () {
  4293. return this.options.editLayer || new L.LayerGroup().addTo(this.map);
  4294. },
  4295. createFeaturesLayer: function () {
  4296. return this.options.featuresLayer || new L.LayerGroup().addTo(this.map);
  4297. },
  4298. moveForwardLineGuide: function (latlng) {
  4299. if (this.forwardLineGuide._latlngs.length) {
  4300. this.forwardLineGuide._latlngs[1] = latlng;
  4301. this.forwardLineGuide._bounds.extend(latlng);
  4302. this.forwardLineGuide.redraw();
  4303. }
  4304. },
  4305. moveBackwardLineGuide: function (latlng) {
  4306. if (this.backwardLineGuide._latlngs.length) {
  4307. this.backwardLineGuide._latlngs[1] = latlng;
  4308. this.backwardLineGuide._bounds.extend(latlng);
  4309. this.backwardLineGuide.redraw();
  4310. }
  4311. },
  4312. anchorForwardLineGuide: function (latlng) {
  4313. this.forwardLineGuide._latlngs[0] = latlng;
  4314. this.forwardLineGuide._bounds.extend(latlng);
  4315. this.forwardLineGuide.redraw();
  4316. },
  4317. anchorBackwardLineGuide: function (latlng) {
  4318. this.backwardLineGuide._latlngs[0] = latlng;
  4319. this.backwardLineGuide._bounds.extend(latlng);
  4320. this.backwardLineGuide.redraw();
  4321. },
  4322. attachForwardLineGuide: function () {
  4323. this.editLayer.addLayer(this.forwardLineGuide);
  4324. },
  4325. attachBackwardLineGuide: function () {
  4326. this.editLayer.addLayer(this.backwardLineGuide);
  4327. },
  4328. detachForwardLineGuide: function () {
  4329. this.forwardLineGuide.setLatLngs([]);
  4330. this.editLayer.removeLayer(this.forwardLineGuide);
  4331. },
  4332. detachBackwardLineGuide: function () {
  4333. this.backwardLineGuide.setLatLngs([]);
  4334. this.editLayer.removeLayer(this.backwardLineGuide);
  4335. },
  4336. blockEvents: function () {
  4337. // Hack: force map not to listen to other layers events while drawing.
  4338. if (!this._oldTargets) {
  4339. this._oldTargets = this.map._targets;
  4340. this.map._targets = {};
  4341. }
  4342. },
  4343. unblockEvents: function () {
  4344. if (this._oldTargets) {
  4345. // Reset, but keep targets created while drawing.
  4346. this.map._targets = L.extend(this.map._targets, this._oldTargets);
  4347. delete this._oldTargets;
  4348. }
  4349. },
  4350. registerForDrawing: function (editor) {
  4351. if (this._drawingEditor) this.unregisterForDrawing(this._drawingEditor);
  4352. this.blockEvents();
  4353. editor.reset(); // Make sure editor tools still receive events.
  4354. this._drawingEditor = editor;
  4355. this.map.on('mousemove touchmove', editor.onDrawingMouseMove, editor);
  4356. this.map.on('mousedown', this.onMousedown, this);
  4357. this.map.on('mouseup', this.onMouseup, this);
  4358. L.DomUtil.addClass(this.map._container, this.options.drawingCSSClass);
  4359. this.defaultMapCursor = this.map._container.style.cursor;
  4360. this.map._container.style.cursor = this.options.drawingCursor;
  4361. },
  4362. unregisterForDrawing: function (editor) {
  4363. this.unblockEvents();
  4364. L.DomUtil.removeClass(this.map._container, this.options.drawingCSSClass);
  4365. this.map._container.style.cursor = this.defaultMapCursor;
  4366. editor = editor || this._drawingEditor;
  4367. if (!editor) return;
  4368. this.map.off('mousemove touchmove', editor.onDrawingMouseMove, editor);
  4369. this.map.off('mousedown', this.onMousedown, this);
  4370. this.map.off('mouseup', this.onMouseup, this);
  4371. if (editor !== this._drawingEditor) return;
  4372. delete this._drawingEditor;
  4373. if (editor._drawing) editor.cancelDrawing();
  4374. },
  4375. onMousedown: function (e) {
  4376. this._mouseDown = e;
  4377. this._drawingEditor.onDrawingMouseDown(e);
  4378. },
  4379. onMouseup: function (e) {
  4380. if (this._mouseDown) {
  4381. var editor = this._drawingEditor,
  4382. mouseDown = this._mouseDown;
  4383. this._mouseDown = null;
  4384. editor.onDrawingMouseUp(e);
  4385. if (this._drawingEditor !== editor) return; // onDrawingMouseUp may call unregisterFromDrawing.
  4386. var origin = L.point(mouseDown.originalEvent.clientX, mouseDown.originalEvent.clientY);
  4387. var distance = L.point(e.originalEvent.clientX, e.originalEvent.clientY).distanceTo(origin);
  4388. if (Math.abs(distance) < 9 * (window.devicePixelRatio || 1)) this._drawingEditor.onDrawingClick(e);
  4389. }
  4390. },
  4391. // 🍂section Public methods
  4392. // You will generally access them by the `map.editTools`
  4393. // instance:
  4394. //
  4395. // `map.editTools.startPolyline();`
  4396. // 🍂method drawing(): boolean
  4397. // Return true if any drawing action is ongoing.
  4398. drawing: function () {
  4399. return this._drawingEditor && this._drawingEditor.drawing();
  4400. },
  4401. // 🍂method stopDrawing()
  4402. // When you need to stop any ongoing drawing, without needing to know which editor is active.
  4403. stopDrawing: function () {
  4404. this.unregisterForDrawing();
  4405. },
  4406. // 🍂method commitDrawing()
  4407. // When you need to commit any ongoing drawing, without needing to know which editor is active.
  4408. commitDrawing: function (e) {
  4409. if (!this._drawingEditor) return;
  4410. this._drawingEditor.commitDrawing(e);
  4411. },
  4412. connectCreatedToMap: function (layer) {
  4413. return this.featuresLayer.addLayer(layer);
  4414. },
  4415. // 🍂method startPolyline(latlng: L.LatLng, options: hash): L.Polyline
  4416. // Start drawing a Polyline. If `latlng` is given, a first point will be added. In any case, continuing on user click.
  4417. // If `options` is given, it will be passed to the Polyline class constructor.
  4418. startPolyline: function (latlng, options) {
  4419. var line = this.createPolyline([], options);
  4420. line.enableEdit(this.map).newShape(latlng);
  4421. return line;
  4422. },
  4423. // 🍂method startPolygon(latlng: L.LatLng, options: hash): L.Polygon
  4424. // Start drawing a Polygon. If `latlng` is given, a first point will be added. In any case, continuing on user click.
  4425. // If `options` is given, it will be passed to the Polygon class constructor.
  4426. startPolygon: function (latlng, options) {
  4427. var polygon = this.createPolygon([], options);
  4428. polygon.enableEdit(this.map).newShape(latlng);
  4429. return polygon;
  4430. },
  4431. // 🍂method startMarker(latlng: L.LatLng, options: hash): L.Marker
  4432. // Start adding a Marker. If `latlng` is given, the Marker will be shown first at this point.
  4433. // In any case, it will follow the user mouse, and will have a final `latlng` on next click (or touch).
  4434. // If `options` is given, it will be passed to the Marker class constructor.
  4435. startMarker: function (latlng, options) {
  4436. latlng = latlng || this.map.getCenter().clone();
  4437. var marker = this.createMarker(latlng, options);
  4438. marker.enableEdit(this.map).startDrawing();
  4439. return marker;
  4440. },
  4441. // 🍂method startRectangle(latlng: L.LatLng, options: hash): L.Rectangle
  4442. // Start drawing a Rectangle. If `latlng` is given, the Rectangle anchor will be added. In any case, continuing on user drag.
  4443. // If `options` is given, it will be passed to the Rectangle class constructor.
  4444. startRectangle: function(latlng, options) {
  4445. var corner = latlng || L.latLng([0, 0]);
  4446. var bounds = new L.LatLngBounds(corner, corner);
  4447. var rectangle = this.createRectangle(bounds, options);
  4448. rectangle.enableEdit(this.map).startDrawing();
  4449. return rectangle;
  4450. },
  4451. // 🍂method startCircle(latlng: L.LatLng, options: hash): L.Circle
  4452. // Start drawing a Circle. If `latlng` is given, the Circle anchor will be added. In any case, continuing on user drag.
  4453. // If `options` is given, it will be passed to the Circle class constructor.
  4454. startCircle: function (latlng, options) {
  4455. latlng = latlng || this.map.getCenter().clone();
  4456. var circle = this.createCircle(latlng, options);
  4457. circle.enableEdit(this.map).startDrawing();
  4458. return circle;
  4459. },
  4460. startHole: function (editor, latlng) {
  4461. editor.newHole(latlng);
  4462. },
  4463. createLayer: function (klass, latlngs, options) {
  4464. options = L.Util.extend({editOptions: {editTools: this}}, options);
  4465. var layer = new klass(latlngs, options);
  4466. // 🍂namespace Editable
  4467. // 🍂event editable:created: LayerEvent
  4468. // Fired when a new feature (Marker, Polyline…) is created.
  4469. this.fireAndForward('editable:created', {layer: layer});
  4470. return layer;
  4471. },
  4472. createPolyline: function (latlngs, options) {
  4473. return this.createLayer(options && options.polylineClass || this.options.polylineClass, latlngs, options);
  4474. },
  4475. createPolygon: function (latlngs, options) {
  4476. return this.createLayer(options && options.polygonClass || this.options.polygonClass, latlngs, options);
  4477. },
  4478. createMarker: function (latlng, options) {
  4479. return this.createLayer(options && options.markerClass || this.options.markerClass, latlng, options);
  4480. },
  4481. createRectangle: function (bounds, options) {
  4482. return this.createLayer(options && options.rectangleClass || this.options.rectangleClass, bounds, options);
  4483. },
  4484. createCircle: function (latlng, options) {
  4485. return this.createLayer(options && options.circleClass || this.options.circleClass, latlng, options);
  4486. }
  4487. });
  4488. L.extend(L.Editable, {
  4489. makeCancellable: function (e) {
  4490. e.cancel = function () {
  4491. e._cancelled = true;
  4492. };
  4493. }
  4494. });
  4495. // 🍂namespace Map; 🍂class Map
  4496. // Leaflet.Editable add options and events to the `L.Map` object.
  4497. // See `Editable` events for the list of events fired on the Map.
  4498. // 🍂example
  4499. //
  4500. // ```js
  4501. // var map = L.map('map', {
  4502. // editable: true,
  4503. // editOptions: {
  4504. // …
  4505. // }
  4506. // });
  4507. // ```
  4508. // 🍂section Editable Map Options
  4509. L.Map.mergeOptions({
  4510. // 🍂namespace Map
  4511. // 🍂section Map Options
  4512. // 🍂option editToolsClass: class = L.Editable
  4513. // Class to be used as vertex, for path editing.
  4514. editToolsClass: L.Editable,
  4515. // 🍂option editable: boolean = false
  4516. // Whether to create a L.Editable instance at map init.
  4517. editable: false,
  4518. // 🍂option editOptions: hash = {}
  4519. // Options to pass to L.Editable when instanciating.
  4520. editOptions: {}
  4521. });
  4522. L.Map.addInitHook(function () {
  4523. this.whenReady(function () {
  4524. if (this.options.editable) {
  4525. this.editTools = new this.options.editToolsClass(this, this.options.editOptions);
  4526. }
  4527. });
  4528. });
  4529. L.Editable.VertexIcon = L.DivIcon.extend({
  4530. options: {
  4531. iconSize: new L.Point(8, 8)
  4532. }
  4533. });
  4534. L.Editable.TouchVertexIcon = L.Editable.VertexIcon.extend({
  4535. options: {
  4536. iconSize: new L.Point(20, 20)
  4537. }
  4538. });
  4539. // 🍂namespace Editable; 🍂class VertexMarker; Handler for dragging path vertices.
  4540. L.Editable.VertexMarker = L.Marker.extend({
  4541. options: {
  4542. draggable: true,
  4543. className: 'leaflet-div-icon leaflet-vertex-icon'
  4544. },
  4545. // 🍂section Public methods
  4546. // The marker used to handle path vertex. You will usually interact with a `VertexMarker`
  4547. // instance when listening for events like `editable:vertex:ctrlclick`.
  4548. initialize: function (latlng, latlngs, editor, options) {
  4549. // We don't use this._latlng, because on drag Leaflet replace it while
  4550. // we want to keep reference.
  4551. this.latlng = latlng;
  4552. this.latlngs = latlngs;
  4553. this.editor = editor;
  4554. L.Marker.prototype.initialize.call(this, latlng, options);
  4555. this.options.icon = this.editor.tools.createVertexIcon({className: this.options.className});
  4556. this.latlng.__vertex = this;
  4557. this.editor.editLayer.addLayer(this);
  4558. this.setZIndexOffset(editor.tools._lastZIndex + 1);
  4559. },
  4560. onAdd: function (map) {
  4561. L.Marker.prototype.onAdd.call(this, map);
  4562. this.on('drag', this.onDrag);
  4563. this.on('dragstart', this.onDragStart);
  4564. this.on('dragend', this.onDragEnd);
  4565. this.on('mouseup', this.onMouseup);
  4566. this.on('click', this.onClick);
  4567. this.on('contextmenu', this.onContextMenu);
  4568. this.on('mousedown touchstart', this.onMouseDown);
  4569. this.addMiddleMarkers();
  4570. },
  4571. onRemove: function (map) {
  4572. if (this.middleMarker) this.middleMarker.delete();
  4573. delete this.latlng.__vertex;
  4574. this.off('drag', this.onDrag);
  4575. this.off('dragstart', this.onDragStart);
  4576. this.off('dragend', this.onDragEnd);
  4577. this.off('mouseup', this.onMouseup);
  4578. this.off('click', this.onClick);
  4579. this.off('contextmenu', this.onContextMenu);
  4580. this.off('mousedown touchstart', this.onMouseDown);
  4581. L.Marker.prototype.onRemove.call(this, map);
  4582. },
  4583. onDrag: function (e) {
  4584. e.vertex = this;
  4585. this.editor.onVertexMarkerDrag(e);
  4586. var iconPos = L.DomUtil.getPosition(this._icon),
  4587. latlng = this._map.layerPointToLatLng(iconPos);
  4588. this.latlng.update(latlng);
  4589. this._latlng = this.latlng; // Push back to Leaflet our reference.
  4590. this.editor.refresh();
  4591. if (this.middleMarker) this.middleMarker.updateLatLng();
  4592. var next = this.getNext();
  4593. if (next && next.middleMarker) next.middleMarker.updateLatLng();
  4594. },
  4595. onDragStart: function (e) {
  4596. e.vertex = this;
  4597. this.editor.onVertexMarkerDragStart(e);
  4598. },
  4599. onDragEnd: function (e) {
  4600. e.vertex = this;
  4601. this.editor.onVertexMarkerDragEnd(e);
  4602. },
  4603. onClick: function (e) {
  4604. e.vertex = this;
  4605. this.editor.onVertexMarkerClick(e);
  4606. },
  4607. onMouseup: function (e) {
  4608. L.DomEvent.stop(e);
  4609. e.vertex = this;
  4610. this.editor.map.fire('mouseup', e);
  4611. },
  4612. onContextMenu: function (e) {
  4613. e.vertex = this;
  4614. this.editor.onVertexMarkerContextMenu(e);
  4615. },
  4616. onMouseDown: function (e) {
  4617. e.vertex = this;
  4618. this.editor.onVertexMarkerMouseDown(e);
  4619. },
  4620. // 🍂method delete()
  4621. // Delete a vertex and the related LatLng.
  4622. delete: function () {
  4623. var next = this.getNext(); // Compute before changing latlng
  4624. this.latlngs.splice(this.getIndex(), 1);
  4625. this.editor.editLayer.removeLayer(this);
  4626. this.editor.onVertexDeleted({latlng: this.latlng, vertex: this});
  4627. if (!this.latlngs.length) this.editor.deleteShape(this.latlngs);
  4628. if (next) next.resetMiddleMarker();
  4629. this.editor.refresh();
  4630. },
  4631. // 🍂method getIndex(): int
  4632. // Get the index of the current vertex among others of the same LatLngs group.
  4633. getIndex: function () {
  4634. return this.latlngs.indexOf(this.latlng);
  4635. },
  4636. // 🍂method getLastIndex(): int
  4637. // Get last vertex index of the LatLngs group of the current vertex.
  4638. getLastIndex: function () {
  4639. return this.latlngs.length - 1;
  4640. },
  4641. // 🍂method getPrevious(): VertexMarker
  4642. // Get the previous VertexMarker in the same LatLngs group.
  4643. getPrevious: function () {
  4644. if (this.latlngs.length < 2) return;
  4645. var index = this.getIndex(),
  4646. previousIndex = index - 1;
  4647. if (index === 0 && this.editor.CLOSED) previousIndex = this.getLastIndex();
  4648. var previous = this.latlngs[previousIndex];
  4649. if (previous) return previous.__vertex;
  4650. },
  4651. // 🍂method getNext(): VertexMarker
  4652. // Get the next VertexMarker in the same LatLngs group.
  4653. getNext: function () {
  4654. if (this.latlngs.length < 2) return;
  4655. var index = this.getIndex(),
  4656. nextIndex = index + 1;
  4657. if (index === this.getLastIndex() && this.editor.CLOSED) nextIndex = 0;
  4658. var next = this.latlngs[nextIndex];
  4659. if (next) return next.__vertex;
  4660. },
  4661. addMiddleMarker: function (previous) {
  4662. if (!this.editor.hasMiddleMarkers()) return;
  4663. previous = previous || this.getPrevious();
  4664. if (previous && !this.middleMarker) this.middleMarker = this.editor.addMiddleMarker(previous, this, this.latlngs, this.editor);
  4665. },
  4666. addMiddleMarkers: function () {
  4667. if (!this.editor.hasMiddleMarkers()) return;
  4668. var previous = this.getPrevious();
  4669. if (previous) this.addMiddleMarker(previous);
  4670. var next = this.getNext();
  4671. if (next) next.resetMiddleMarker();
  4672. },
  4673. resetMiddleMarker: function () {
  4674. if (this.middleMarker) this.middleMarker.delete();
  4675. this.addMiddleMarker();
  4676. },
  4677. // 🍂method split()
  4678. // Split the vertex LatLngs group at its index, if possible.
  4679. split: function () {
  4680. if (!this.editor.splitShape) return; // Only for PolylineEditor
  4681. this.editor.splitShape(this.latlngs, this.getIndex());
  4682. },
  4683. // 🍂method continue()
  4684. // Continue the vertex LatLngs from this vertex. Only active for first and last vertices of a Polyline.
  4685. continue: function () {
  4686. if (!this.editor.continueBackward) return; // Only for PolylineEditor
  4687. var index = this.getIndex();
  4688. if (index === 0) this.editor.continueBackward(this.latlngs);
  4689. else if (index === this.getLastIndex()) this.editor.continueForward(this.latlngs);
  4690. }
  4691. });
  4692. L.Editable.mergeOptions({
  4693. // 🍂namespace Editable
  4694. // 🍂option vertexMarkerClass: class = VertexMarker
  4695. // Class to be used as vertex, for path editing.
  4696. vertexMarkerClass: L.Editable.VertexMarker
  4697. });
  4698. L.Editable.MiddleMarker = L.Marker.extend({
  4699. options: {
  4700. opacity: 0.5,
  4701. className: 'leaflet-div-icon leaflet-middle-icon',
  4702. draggable: true
  4703. },
  4704. initialize: function (left, right, latlngs, editor, options) {
  4705. this.left = left;
  4706. this.right = right;
  4707. this.editor = editor;
  4708. this.latlngs = latlngs;
  4709. L.Marker.prototype.initialize.call(this, this.computeLatLng(), options);
  4710. this._opacity = this.options.opacity;
  4711. this.options.icon = this.editor.tools.createVertexIcon({className: this.options.className});
  4712. this.editor.editLayer.addLayer(this);
  4713. this.setVisibility();
  4714. },
  4715. setVisibility: function () {
  4716. var leftPoint = this._map.latLngToContainerPoint(this.left.latlng),
  4717. rightPoint = this._map.latLngToContainerPoint(this.right.latlng),
  4718. size = L.point(this.options.icon.options.iconSize);
  4719. if (leftPoint.distanceTo(rightPoint) < size.x * 3) this.hide();
  4720. else this.show();
  4721. },
  4722. show: function () {
  4723. this.setOpacity(this._opacity);
  4724. },
  4725. hide: function () {
  4726. this.setOpacity(0);
  4727. },
  4728. updateLatLng: function () {
  4729. this.setLatLng(this.computeLatLng());
  4730. this.setVisibility();
  4731. },
  4732. computeLatLng: function () {
  4733. var leftPoint = this.editor.map.latLngToContainerPoint(this.left.latlng),
  4734. rightPoint = this.editor.map.latLngToContainerPoint(this.right.latlng),
  4735. y = (leftPoint.y + rightPoint.y) / 2,
  4736. x = (leftPoint.x + rightPoint.x) / 2;
  4737. return this.editor.map.containerPointToLatLng([x, y]);
  4738. },
  4739. onAdd: function (map) {
  4740. L.Marker.prototype.onAdd.call(this, map);
  4741. L.DomEvent.on(this._icon, 'mousedown touchstart', this.onMouseDown, this);
  4742. map.on('zoomend', this.setVisibility, this);
  4743. },
  4744. onRemove: function (map) {
  4745. delete this.right.middleMarker;
  4746. L.DomEvent.off(this._icon, 'mousedown touchstart', this.onMouseDown, this);
  4747. map.off('zoomend', this.setVisibility, this);
  4748. L.Marker.prototype.onRemove.call(this, map);
  4749. },
  4750. onMouseDown: function (e) {
  4751. var iconPos = L.DomUtil.getPosition(this._icon),
  4752. latlng = this.editor.map.layerPointToLatLng(iconPos);
  4753. e = {
  4754. originalEvent: e,
  4755. latlng: latlng
  4756. };
  4757. if (this.options.opacity === 0) return;
  4758. L.Editable.makeCancellable(e);
  4759. this.editor.onMiddleMarkerMouseDown(e);
  4760. if (e._cancelled) return;
  4761. this.latlngs.splice(this.index(), 0, e.latlng);
  4762. this.editor.refresh();
  4763. var icon = this._icon;
  4764. var marker = this.editor.addVertexMarker(e.latlng, this.latlngs);
  4765. /* Hack to workaround browser not firing touchend when element is no more on DOM */
  4766. var parent = marker._icon.parentNode;
  4767. parent.removeChild(marker._icon);
  4768. marker._icon = icon;
  4769. parent.appendChild(marker._icon);
  4770. marker._initIcon();
  4771. marker._initInteraction();
  4772. marker.setOpacity(1);
  4773. /* End hack */
  4774. // Transfer ongoing dragging to real marker
  4775. L.Draggable._dragging = false;
  4776. marker.dragging._draggable._onDown(e.originalEvent);
  4777. this.delete();
  4778. },
  4779. delete: function () {
  4780. this.editor.editLayer.removeLayer(this);
  4781. },
  4782. index: function () {
  4783. return this.latlngs.indexOf(this.right.latlng);
  4784. }
  4785. });
  4786. L.Editable.mergeOptions({
  4787. // 🍂namespace Editable
  4788. // 🍂option middleMarkerClass: class = VertexMarker
  4789. // Class to be used as middle vertex, pulled by the user to create a new point in the middle of a path.
  4790. middleMarkerClass: L.Editable.MiddleMarker
  4791. });
  4792. // 🍂namespace Editable; 🍂class BaseEditor; 🍂aka L.Editable.BaseEditor
  4793. // When editing a feature (Marker, Polyline…), an editor is attached to it. This
  4794. // editor basically knows how to handle the edition.
  4795. L.Editable.BaseEditor = L.Handler.extend({
  4796. initialize: function (map, feature, options) {
  4797. L.setOptions(this, options);
  4798. this.map = map;
  4799. this.feature = feature;
  4800. this.feature.editor = this;
  4801. this.editLayer = new L.LayerGroup();
  4802. this.tools = this.options.editTools || map.editTools;
  4803. },
  4804. // 🍂method enable(): this
  4805. // Set up the drawing tools for the feature to be editable.
  4806. addHooks: function () {
  4807. if (this.isConnected()) this.onFeatureAdd();
  4808. else this.feature.once('add', this.onFeatureAdd, this);
  4809. this.onEnable();
  4810. this.feature.on(this._getEvents(), this);
  4811. return;
  4812. },
  4813. // 🍂method disable(): this
  4814. // Remove the drawing tools for the feature.
  4815. removeHooks: function () {
  4816. this.feature.off(this._getEvents(), this);
  4817. if (this.feature.dragging) this.feature.dragging.disable();
  4818. this.editLayer.clearLayers();
  4819. this.tools.editLayer.removeLayer(this.editLayer);
  4820. this.onDisable();
  4821. if (this._drawing) this.cancelDrawing();
  4822. return;
  4823. },
  4824. // 🍂method drawing(): boolean
  4825. // Return true if any drawing action is ongoing with this editor.
  4826. drawing: function () {
  4827. return !!this._drawing;
  4828. },
  4829. reset: function () {},
  4830. onFeatureAdd: function () {
  4831. this.tools.editLayer.addLayer(this.editLayer);
  4832. if (this.feature.dragging) this.feature.dragging.enable();
  4833. },
  4834. hasMiddleMarkers: function () {
  4835. return !this.options.skipMiddleMarkers && !this.tools.options.skipMiddleMarkers;
  4836. },
  4837. fireAndForward: function (type, e) {
  4838. if(this.feature.linetype === "circleline" || this.feature.linetype === "circlepolygon"){
  4839. }else{
  4840. e = e || {};
  4841. e.layer = this.feature;
  4842. this.feature.fire(type, e);
  4843. this.tools.fireAndForward(type, e);
  4844. }
  4845. },
  4846. onEnable: function () {
  4847. // 🍂namespace Editable
  4848. // 🍂event editable:enable: Event
  4849. // Fired when an existing feature is ready to be edited.
  4850. this.fireAndForward('editable:enable');
  4851. },
  4852. onDisable: function () {
  4853. // 🍂namespace Editable
  4854. // 🍂event editable:disable: Event
  4855. // Fired when an existing feature is not ready anymore to be edited.
  4856. this.fireAndForward('editable:disable');
  4857. },
  4858. onEditing: function () {
  4859. // 🍂namespace Editable
  4860. // 🍂event editable:editing: Event
  4861. // Fired as soon as any change is made to the feature geometry.
  4862. this.fireAndForward('editable:editing');
  4863. },
  4864. onStartDrawing: function () {
  4865. // 🍂namespace Editable
  4866. // 🍂section Drawing events
  4867. // 🍂event editable:drawing:start: Event
  4868. // Fired when a feature is to be drawn.
  4869. this.fireAndForward('editable:drawing:start');
  4870. },
  4871. onEndDrawing: function () {
  4872. // 🍂namespace Editable
  4873. // 🍂section Drawing events
  4874. // 🍂event editable:drawing:end: Event
  4875. // Fired when a feature is not drawn anymore.
  4876. this.fireAndForward('editable:drawing:end');
  4877. },
  4878. onCancelDrawing: function () {
  4879. // 🍂namespace Editable
  4880. // 🍂section Drawing events
  4881. // 🍂event editable:drawing:cancel: Event
  4882. // Fired when user cancel drawing while a feature is being drawn.
  4883. this.fireAndForward('editable:drawing:cancel');
  4884. },
  4885. onCommitDrawing: function (e) {
  4886. // 🍂namespace Editable
  4887. // 🍂section Drawing events
  4888. // 🍂event editable:drawing:commit: Event
  4889. // Fired when user finish drawing a feature.
  4890. this.fireAndForward('editable:drawing:commit', e);
  4891. },
  4892. onDrawingMouseDown: function (e) {
  4893. // 🍂namespace Editable
  4894. // 🍂section Drawing events
  4895. // 🍂event editable:drawing:mousedown: Event
  4896. // Fired when user `mousedown` while drawing.
  4897. this.fireAndForward('editable:drawing:mousedown', e);
  4898. },
  4899. onDrawingMouseUp: function (e) {
  4900. // 🍂namespace Editable
  4901. // 🍂section Drawing events
  4902. // 🍂event editable:drawing:mouseup: Event
  4903. // Fired when user `mouseup` while drawing.
  4904. this.fireAndForward('editable:drawing:mouseup', e);
  4905. },
  4906. startDrawing: function () {
  4907. if (!this._drawing) this._drawing = L.Editable.FORWARD;
  4908. this.tools.registerForDrawing(this);
  4909. this.onStartDrawing();
  4910. },
  4911. commitDrawing: function (e) {
  4912. this.onCommitDrawing(e);
  4913. this.endDrawing();
  4914. },
  4915. cancelDrawing: function () {
  4916. // If called during a vertex drag, the vertex will be removed before
  4917. // the mouseup fires on it. This is a workaround. Maybe better fix is
  4918. // To have L.Draggable reset it's status on disable (Leaflet side).
  4919. L.Draggable._dragging = false;
  4920. this.onCancelDrawing();
  4921. this.endDrawing();
  4922. },
  4923. endDrawing: function () {
  4924. this._drawing = false;
  4925. this.tools.unregisterForDrawing(this);
  4926. this.onEndDrawing();
  4927. },
  4928. onDrawingClick: function (e) {
  4929. if (!this.drawing()) return;
  4930. L.Editable.makeCancellable(e);
  4931. // 🍂namespace Editable
  4932. // 🍂section Drawing events
  4933. // 🍂event editable:drawing:click: CancelableEvent
  4934. // Fired when user `click` while drawing, before any internal action is being processed.
  4935. this.fireAndForward('editable:drawing:click', e);
  4936. if (e._cancelled) return;
  4937. if (!this.isConnected()) this.connect(e);
  4938. this.processDrawingClick(e);
  4939. },
  4940. isConnected: function () {
  4941. return this.map.hasLayer(this.feature);
  4942. },
  4943. connect: function (e) {
  4944. this.tools.connectCreatedToMap(this.feature);
  4945. this.tools.editLayer.addLayer(this.editLayer);
  4946. },
  4947. onMove: function (e) {
  4948. // 🍂namespace Editable
  4949. // 🍂section Drawing events
  4950. // 🍂event editable:drawing:move: Event
  4951. // Fired when `move` mouse while drawing, while dragging a marker, and while dragging a vertex.
  4952. this.fireAndForward('editable:drawing:move', e);
  4953. },
  4954. onDrawingMouseMove: function (e) {
  4955. this.onMove(e);
  4956. },
  4957. _getEvents: function () {
  4958. return {
  4959. dragstart: this.onDragStart,
  4960. drag: this.onDrag,
  4961. dragend: this.onDragEnd,
  4962. remove: this.disable
  4963. };
  4964. },
  4965. onDragStart: function (e) {
  4966. this.onEditing();
  4967. // 🍂namespace Editable
  4968. // 🍂event editable:dragstart: Event
  4969. // Fired before a path feature is dragged.
  4970. this.fireAndForward('editable:dragstart', e);
  4971. },
  4972. onDrag: function (e) {
  4973. this.onMove(e);
  4974. // 🍂namespace Editable
  4975. // 🍂event editable:drag: Event
  4976. // Fired when a path feature is being dragged.
  4977. this.fireAndForward('editable:drag', e);
  4978. },
  4979. onDragEnd: function (e) {
  4980. // 🍂namespace Editable
  4981. // 🍂event editable:dragend: Event
  4982. // Fired after a path feature has been dragged.
  4983. this.fireAndForward('editable:dragend', e);
  4984. }
  4985. });
  4986. // 🍂namespace Editable; 🍂class MarkerEditor; 🍂aka L.Editable.MarkerEditor
  4987. // 🍂inherits BaseEditor
  4988. // Editor for Marker.
  4989. L.Editable.MarkerEditor = L.Editable.BaseEditor.extend({
  4990. onDrawingMouseMove: function (e) {
  4991. L.Editable.BaseEditor.prototype.onDrawingMouseMove.call(this, e);
  4992. if (this._drawing) this.feature.setLatLng(e.latlng);
  4993. },
  4994. processDrawingClick: function (e) {
  4995. // 🍂namespace Editable
  4996. // 🍂section Drawing events
  4997. // 🍂event editable:drawing:clicked: Event
  4998. // Fired when user `click` while drawing, after all internal actions.
  4999. this.fireAndForward('editable:drawing:clicked', e);
  5000. this.commitDrawing(e);
  5001. },
  5002. connect: function (e) {
  5003. // On touch, the latlng has not been updated because there is
  5004. // no mousemove.
  5005. if (e) this.feature._latlng = e.latlng;
  5006. L.Editable.BaseEditor.prototype.connect.call(this, e);
  5007. }
  5008. });
  5009. // 🍂namespace Editable; 🍂class PathEditor; 🍂aka L.Editable.PathEditor
  5010. // 🍂inherits BaseEditor
  5011. // Base class for all path editors.
  5012. L.Editable.PathEditor = L.Editable.BaseEditor.extend({
  5013. CLOSED: false,
  5014. MIN_VERTEX: 2,
  5015. addHooks: function () {
  5016. L.Editable.BaseEditor.prototype.addHooks.call(this);
  5017. if (this.feature) this.initVertexMarkers();
  5018. return this;
  5019. },
  5020. initVertexMarkers: function (latlngs) {
  5021. if (!this.enabled()) return;
  5022. latlngs = latlngs || this.getLatLngs();
  5023. if (L.Polyline._flat(latlngs)) this.addVertexMarkers(latlngs);
  5024. else for (var i = 0; i < latlngs.length; i++) this.initVertexMarkers(latlngs[i]);
  5025. },
  5026. getLatLngs: function () {
  5027. return this.feature.getLatLngs();
  5028. },
  5029. // 🍂method reset()
  5030. // Rebuild edit elements (Vertex, MiddleMarker, etc.).
  5031. reset: function () {
  5032. this.editLayer.clearLayers();
  5033. this.initVertexMarkers();
  5034. },
  5035. addVertexMarker: function (latlng, latlngs) {
  5036. return new this.tools.options.vertexMarkerClass(latlng, latlngs, this);
  5037. },
  5038. addVertexMarkers: function (latlngs) {
  5039. for (var i = 0; i < latlngs.length; i++) {
  5040. this.addVertexMarker(latlngs[i], latlngs);
  5041. }
  5042. },
  5043. refreshVertexMarkers: function (latlngs) {
  5044. latlngs = latlngs || this.getDefaultLatLngs();
  5045. for (var i = 0; i < latlngs.length; i++) {
  5046. latlngs[i].__vertex.update();
  5047. }
  5048. },
  5049. addMiddleMarker: function (left, right, latlngs) {
  5050. return new this.tools.options.middleMarkerClass(left, right, latlngs, this);
  5051. },
  5052. onVertexMarkerClick: function (e) {
  5053. L.Editable.makeCancellable(e);
  5054. // 🍂namespace Editable
  5055. // 🍂section Vertex events
  5056. // 🍂event editable:vertex:click: CancelableVertexEvent
  5057. // Fired when a `click` is issued on a vertex, before any internal action is being processed.
  5058. this.fireAndForward('editable:vertex:click', e);
  5059. if (e._cancelled) return;
  5060. if (this.tools.drawing() && this.tools._drawingEditor !== this) return;
  5061. var index = e.vertex.getIndex(), commit;
  5062. if (e.originalEvent.ctrlKey) {
  5063. this.onVertexMarkerCtrlClick(e);
  5064. } else if (e.originalEvent.altKey) {
  5065. this.onVertexMarkerAltClick(e);
  5066. } else if (e.originalEvent.shiftKey) {
  5067. this.onVertexMarkerShiftClick(e);
  5068. } else if (e.originalEvent.metaKey) {
  5069. this.onVertexMarkerMetaKeyClick(e);
  5070. } else if (index === e.vertex.getLastIndex() && this._drawing === L.Editable.FORWARD) {
  5071. if (index >= this.MIN_VERTEX - 1) commit = true;
  5072. } else if (index === 0 && this._drawing === L.Editable.BACKWARD && this._drawnLatLngs.length >= this.MIN_VERTEX) {
  5073. commit = true;
  5074. } else if (index === 0 && this._drawing === L.Editable.FORWARD && this._drawnLatLngs.length >= this.MIN_VERTEX && this.CLOSED) {
  5075. commit = true; // Allow to close on first point also for polygons
  5076. } else {
  5077. this.onVertexRawMarkerClick(e);
  5078. }
  5079. // 🍂namespace Editable
  5080. // 🍂section Vertex events
  5081. // 🍂event editable:vertex:clicked: VertexEvent
  5082. // Fired when a `click` is issued on a vertex, after all internal actions.
  5083. this.fireAndForward('editable:vertex:clicked', e);
  5084. if (commit) this.commitDrawing(e);
  5085. },
  5086. onVertexRawMarkerClick: function (e) {
  5087. // 🍂namespace Editable
  5088. // 🍂section Vertex events
  5089. // 🍂event editable:vertex:rawclick: CancelableVertexEvent
  5090. // Fired when a `click` is issued on a vertex without any special key and without being in drawing mode.
  5091. this.fireAndForward('editable:vertex:rawclick', e);
  5092. if (e._cancelled) return;
  5093. if (!this.vertexCanBeDeleted(e.vertex)) return;
  5094. e.vertex.delete();
  5095. },
  5096. vertexCanBeDeleted: function (vertex) {
  5097. return vertex.latlngs.length > this.MIN_VERTEX;
  5098. },
  5099. onVertexDeleted: function (e) {
  5100. // 🍂namespace Editable
  5101. // 🍂section Vertex events
  5102. // 🍂event editable:vertex:deleted: VertexEvent
  5103. // Fired after a vertex has been deleted by user.
  5104. this.fireAndForward('editable:vertex:deleted', e);
  5105. },
  5106. onVertexMarkerCtrlClick: function (e) {
  5107. // 🍂namespace Editable
  5108. // 🍂section Vertex events
  5109. // 🍂event editable:vertex:ctrlclick: VertexEvent
  5110. // Fired when a `click` with `ctrlKey` is issued on a vertex.
  5111. this.fireAndForward('editable:vertex:ctrlclick', e);
  5112. },
  5113. onVertexMarkerShiftClick: function (e) {
  5114. // 🍂namespace Editable
  5115. // 🍂section Vertex events
  5116. // 🍂event editable:vertex:shiftclick: VertexEvent
  5117. // Fired when a `click` with `shiftKey` is issued on a vertex.
  5118. this.fireAndForward('editable:vertex:shiftclick', e);
  5119. },
  5120. onVertexMarkerMetaKeyClick: function (e) {
  5121. // 🍂namespace Editable
  5122. // 🍂section Vertex events
  5123. // 🍂event editable:vertex:metakeyclick: VertexEvent
  5124. // Fired when a `click` with `metaKey` is issued on a vertex.
  5125. this.fireAndForward('editable:vertex:metakeyclick', e);
  5126. },
  5127. onVertexMarkerAltClick: function (e) {
  5128. // 🍂namespace Editable
  5129. // 🍂section Vertex events
  5130. // 🍂event editable:vertex:altclick: VertexEvent
  5131. // Fired when a `click` with `altKey` is issued on a vertex.
  5132. this.fireAndForward('editable:vertex:altclick', e);
  5133. },
  5134. onVertexMarkerContextMenu: function (e) {
  5135. // 🍂namespace Editable
  5136. // 🍂section Vertex events
  5137. // 🍂event editable:vertex:contextmenu: VertexEvent
  5138. // Fired when a `contextmenu` is issued on a vertex.
  5139. this.fireAndForward('editable:vertex:contextmenu', e);
  5140. },
  5141. onVertexMarkerMouseDown: function (e) {
  5142. // 🍂namespace Editable
  5143. // 🍂section Vertex events
  5144. // 🍂event editable:vertex:mousedown: VertexEvent
  5145. // Fired when user `mousedown` a vertex.
  5146. this.fireAndForward('editable:vertex:mousedown', e);
  5147. },
  5148. onMiddleMarkerMouseDown: function (e) {
  5149. // 🍂namespace Editable
  5150. // 🍂section MiddleMarker events
  5151. // 🍂event editable:middlemarker:mousedown: VertexEvent
  5152. // Fired when user `mousedown` a middle marker.
  5153. this.fireAndForward('editable:middlemarker:mousedown', e);
  5154. },
  5155. onVertexMarkerDrag: function (e) {
  5156. this.onMove(e);
  5157. if (this.feature._bounds) this.extendBounds(e);
  5158. // 🍂namespace Editable
  5159. // 🍂section Vertex events
  5160. // 🍂event editable:vertex:drag: VertexEvent
  5161. // Fired when a vertex is dragged by user.
  5162. this.fireAndForward('editable:vertex:drag', e);
  5163. },
  5164. onVertexMarkerDragStart: function (e) {
  5165. // 🍂namespace Editable
  5166. // 🍂section Vertex events
  5167. // 🍂event editable:vertex:dragstart: VertexEvent
  5168. // Fired before a vertex is dragged by user.
  5169. this.fireAndForward('editable:vertex:dragstart', e);
  5170. },
  5171. onVertexMarkerDragEnd: function (e) {
  5172. // 🍂namespace Editable
  5173. // 🍂section Vertex events
  5174. // 🍂event editable:vertex:dragend: VertexEvent
  5175. // Fired after a vertex is dragged by user.
  5176. this.fireAndForward('editable:vertex:dragend', e);
  5177. },
  5178. setDrawnLatLngs: function (latlngs) {
  5179. this._drawnLatLngs = latlngs || this.getDefaultLatLngs();
  5180. },
  5181. startDrawing: function () {
  5182. if (!this._drawnLatLngs) this.setDrawnLatLngs();
  5183. L.Editable.BaseEditor.prototype.startDrawing.call(this);
  5184. },
  5185. startDrawingForward: function () {
  5186. this.startDrawing();
  5187. },
  5188. endDrawing: function () {
  5189. this.tools.detachForwardLineGuide();
  5190. this.tools.detachBackwardLineGuide();
  5191. if (this._drawnLatLngs && this._drawnLatLngs.length < this.MIN_VERTEX) this.deleteShape(this._drawnLatLngs);
  5192. L.Editable.BaseEditor.prototype.endDrawing.call(this);
  5193. delete this._drawnLatLngs;
  5194. },
  5195. addLatLng: function (latlng) {
  5196. if (this._drawing === L.Editable.FORWARD) this._drawnLatLngs.push(latlng);
  5197. else this._drawnLatLngs.unshift(latlng);
  5198. this.feature._bounds.extend(latlng);
  5199. this.addVertexMarker(latlng, this._drawnLatLngs);
  5200. this.refresh();
  5201. },
  5202. newPointForward: function (latlng) {
  5203. this.addLatLng(latlng);
  5204. this.tools.attachForwardLineGuide();
  5205. this.tools.anchorForwardLineGuide(latlng);
  5206. },
  5207. newPointBackward: function (latlng) {
  5208. this.addLatLng(latlng);
  5209. this.tools.anchorBackwardLineGuide(latlng);
  5210. },
  5211. // 🍂namespace PathEditor
  5212. // 🍂method push()
  5213. // Programmatically add a point while drawing.
  5214. push: function (latlng) {
  5215. if (!latlng) return console.error('L.Editable.PathEditor.push expect a vaild latlng as parameter');
  5216. if (this._drawing === L.Editable.FORWARD) this.newPointForward(latlng);
  5217. else this.newPointBackward(latlng);
  5218. },
  5219. removeLatLng: function (latlng) {
  5220. latlng.__vertex.delete();
  5221. this.refresh();
  5222. },
  5223. // 🍂method pop(): L.LatLng or null
  5224. // Programmatically remove last point (if any) while drawing.
  5225. pop: function () {
  5226. if (this._drawnLatLngs.length <= 1) return;
  5227. var latlng;
  5228. if (this._drawing === L.Editable.FORWARD) latlng = this._drawnLatLngs[this._drawnLatLngs.length - 1];
  5229. else latlng = this._drawnLatLngs[0];
  5230. this.removeLatLng(latlng);
  5231. if (this._drawing === L.Editable.FORWARD) this.tools.anchorForwardLineGuide(this._drawnLatLngs[this._drawnLatLngs.length - 1]);
  5232. else this.tools.anchorForwardLineGuide(this._drawnLatLngs[0]);
  5233. return latlng;
  5234. },
  5235. processDrawingClick: function (e) {
  5236. if (e.vertex && e.vertex.editor === this) return;
  5237. if (this._drawing === L.Editable.FORWARD) this.newPointForward(e.latlng);
  5238. else this.newPointBackward(e.latlng);
  5239. this.fireAndForward('editable:drawing:clicked', e);
  5240. },
  5241. onDrawingMouseMove: function (e) {
  5242. L.Editable.BaseEditor.prototype.onDrawingMouseMove.call(this, e);
  5243. if (this._drawing) {
  5244. this.tools.moveForwardLineGuide(e.latlng);
  5245. this.tools.moveBackwardLineGuide(e.latlng);
  5246. }
  5247. },
  5248. refresh: function () {
  5249. this.feature.redraw();
  5250. this.callback(this.feature)
  5251. this.onEditing();
  5252. },
  5253. // 🍂namespace PathEditor
  5254. // 🍂method newShape(latlng?: L.LatLng)
  5255. // Add a new shape (Polyline, Polygon) in a multi, and setup up drawing tools to draw it;
  5256. // if optional `latlng` is given, start a path at this point.
  5257. newShape: function (latlng) {
  5258. var shape = this.addNewEmptyShape();
  5259. if (!shape) return;
  5260. this.setDrawnLatLngs(shape[0] || shape); // Polygon or polyline
  5261. this.startDrawingForward();
  5262. // 🍂namespace Editable
  5263. // 🍂section Shape events
  5264. // 🍂event editable:shape:new: ShapeEvent
  5265. // Fired when a new shape is created in a multi (Polygon or Polyline).
  5266. this.fireAndForward('editable:shape:new', {shape: shape});
  5267. if (latlng) this.newPointForward(latlng);
  5268. },
  5269. deleteShape: function (shape, latlngs) {
  5270. var e = {shape: shape};
  5271. L.Editable.makeCancellable(e);
  5272. // 🍂namespace Editable
  5273. // 🍂section Shape events
  5274. // 🍂event editable:shape:delete: CancelableShapeEvent
  5275. // Fired before a new shape is deleted in a multi (Polygon or Polyline).
  5276. this.fireAndForward('editable:shape:delete', e);
  5277. if (e._cancelled) return;
  5278. shape = this._deleteShape(shape, latlngs);
  5279. if (this.ensureNotFlat) this.ensureNotFlat(); // Polygon.
  5280. this.feature.setLatLngs(this.getLatLngs()); // Force bounds reset.
  5281. this.refresh();
  5282. this.reset();
  5283. // 🍂namespace Editable
  5284. // 🍂section Shape events
  5285. // 🍂event editable:shape:deleted: ShapeEvent
  5286. // Fired after a new shape is deleted in a multi (Polygon or Polyline).
  5287. this.fireAndForward('editable:shape:deleted', {shape: shape});
  5288. return shape;
  5289. },
  5290. _deleteShape: function (shape, latlngs) {
  5291. latlngs = latlngs || this.getLatLngs();
  5292. if (!latlngs.length) return;
  5293. var self = this,
  5294. inplaceDelete = function (latlngs, shape) {
  5295. // Called when deleting a flat latlngs
  5296. shape = latlngs.splice(0, Number.MAX_VALUE);
  5297. return shape;
  5298. },
  5299. spliceDelete = function (latlngs, shape) {
  5300. // Called when removing a latlngs inside an array
  5301. latlngs.splice(latlngs.indexOf(shape), 1);
  5302. if (!latlngs.length) self._deleteShape(latlngs);
  5303. return shape;
  5304. };
  5305. if (latlngs === shape) return inplaceDelete(latlngs, shape);
  5306. for (var i = 0; i < latlngs.length; i++) {
  5307. if (latlngs[i] === shape) return spliceDelete(latlngs, shape);
  5308. else if (latlngs[i].indexOf(shape) !== -1) return spliceDelete(latlngs[i], shape);
  5309. }
  5310. },
  5311. // 🍂namespace PathEditor
  5312. // 🍂method deleteShapeAt(latlng: L.LatLng): Array
  5313. // Remove a path shape at the given `latlng`.
  5314. deleteShapeAt: function (latlng) {
  5315. var shape = this.feature.shapeAt(latlng);
  5316. if (shape) return this.deleteShape(shape);
  5317. },
  5318. // 🍂method appendShape(shape: Array)
  5319. // Append a new shape to the Polygon or Polyline.
  5320. appendShape: function (shape) {
  5321. this.insertShape(shape);
  5322. },
  5323. // 🍂method prependShape(shape: Array)
  5324. // Prepend a new shape to the Polygon or Polyline.
  5325. prependShape: function (shape) {
  5326. this.insertShape(shape, 0);
  5327. },
  5328. // 🍂method insertShape(shape: Array, index: int)
  5329. // Insert a new shape to the Polygon or Polyline at given index (default is to append).
  5330. insertShape: function (shape, index) {
  5331. this.ensureMulti();
  5332. shape = this.formatShape(shape);
  5333. if (typeof index === 'undefined') index = this.feature._latlngs.length;
  5334. this.feature._latlngs.splice(index, 0, shape);
  5335. this.feature.redraw();
  5336. if (this._enabled) this.reset();
  5337. },
  5338. extendBounds: function (e) {
  5339. this.feature._bounds.extend(e.vertex.latlng);
  5340. },
  5341. onDragStart: function (e) {
  5342. this.editLayer.clearLayers();
  5343. L.Editable.BaseEditor.prototype.onDragStart.call(this, e);
  5344. },
  5345. onDragEnd: function (e) {
  5346. this.initVertexMarkers();
  5347. L.Editable.BaseEditor.prototype.onDragEnd.call(this, e);
  5348. }
  5349. });
  5350. // 🍂namespace Editable; 🍂class PolylineEditor; 🍂aka L.Editable.PolylineEditor
  5351. // 🍂inherits PathEditor
  5352. L.Editable.PolylineEditor = L.Editable.PathEditor.extend({
  5353. startDrawingBackward: function () {
  5354. this._drawing = L.Editable.BACKWARD;
  5355. this.startDrawing();
  5356. },
  5357. // 🍂method continueBackward(latlngs?: Array)
  5358. // Set up drawing tools to continue the line backward.
  5359. continueBackward: function (latlngs) {
  5360. if (this.drawing()) return;
  5361. latlngs = latlngs || this.getDefaultLatLngs();
  5362. this.setDrawnLatLngs(latlngs);
  5363. if (latlngs.length > 0) {
  5364. this.tools.attachBackwardLineGuide();
  5365. this.tools.anchorBackwardLineGuide(latlngs[0]);
  5366. }
  5367. this.startDrawingBackward();
  5368. },
  5369. // 🍂method continueForward(latlngs?: Array)
  5370. // Set up drawing tools to continue the line forward.
  5371. continueForward: function (latlngs) {
  5372. if (this.drawing()) return;
  5373. latlngs = latlngs || this.getDefaultLatLngs();
  5374. this.setDrawnLatLngs(latlngs);
  5375. if (latlngs.length > 0) {
  5376. this.tools.attachForwardLineGuide();
  5377. this.tools.anchorForwardLineGuide(latlngs[latlngs.length - 1]);
  5378. }
  5379. this.startDrawingForward();
  5380. },
  5381. getDefaultLatLngs: function (latlngs) {
  5382. latlngs = latlngs || this.feature._latlngs;
  5383. if (!latlngs.length || latlngs[0] instanceof L.LatLng) return latlngs;
  5384. else return this.getDefaultLatLngs(latlngs[0]);
  5385. },
  5386. ensureMulti: function () {
  5387. if (this.feature._latlngs.length && L.Polyline._flat(this.feature._latlngs)) {
  5388. this.feature._latlngs = [this.feature._latlngs];
  5389. }
  5390. },
  5391. addNewEmptyShape: function () {
  5392. if (this.feature._latlngs.length) {
  5393. var shape = [];
  5394. this.appendShape(shape);
  5395. return shape;
  5396. } else {
  5397. return this.feature._latlngs;
  5398. }
  5399. },
  5400. formatShape: function (shape) {
  5401. if (L.Polyline._flat(shape)) return shape;
  5402. else if (shape[0]) return this.formatShape(shape[0]);
  5403. },
  5404. // 🍂method splitShape(latlngs?: Array, index: int)
  5405. // Split the given `latlngs` shape at index `index` and integrate new shape in instance `latlngs`.
  5406. splitShape: function (shape, index) {
  5407. if (!index || index >= shape.length - 1) return;
  5408. this.ensureMulti();
  5409. var shapeIndex = this.feature._latlngs.indexOf(shape);
  5410. if (shapeIndex === -1) return;
  5411. var first = shape.slice(0, index + 1),
  5412. second = shape.slice(index);
  5413. // We deal with reference, we don't want twice the same latlng around.
  5414. second[0] = L.latLng(second[0].lat, second[0].lng, second[0].alt);
  5415. this.feature._latlngs.splice(shapeIndex, 1, first, second);
  5416. this.refresh();
  5417. this.reset();
  5418. }
  5419. });
  5420. // 🍂namespace Editable; 🍂class PolygonEditor; 🍂aka L.Editable.PolygonEditor
  5421. // 🍂inherits PathEditor
  5422. L.Editable.PolygonEditor = L.Editable.PathEditor.extend({
  5423. CLOSED: true,
  5424. MIN_VERTEX: 3,
  5425. newPointForward: function (latlng) {
  5426. L.Editable.PathEditor.prototype.newPointForward.call(this, latlng);
  5427. if (!this.tools.backwardLineGuide._latlngs.length) this.tools.anchorBackwardLineGuide(latlng);
  5428. if (this._drawnLatLngs.length === 2) this.tools.attachBackwardLineGuide();
  5429. },
  5430. addNewEmptyHole: function (latlng) {
  5431. this.ensureNotFlat();
  5432. var latlngs = this.feature.shapeAt(latlng);
  5433. if (!latlngs) return;
  5434. var holes = [];
  5435. latlngs.push(holes);
  5436. return holes;
  5437. },
  5438. // 🍂method newHole(latlng?: L.LatLng, index: int)
  5439. // Set up drawing tools for creating a new hole on the Polygon. If the `latlng` param is given, a first point is created.
  5440. newHole: function (latlng) {
  5441. var holes = this.addNewEmptyHole(latlng);
  5442. if (!holes) return;
  5443. this.setDrawnLatLngs(holes);
  5444. this.startDrawingForward();
  5445. if (latlng) this.newPointForward(latlng);
  5446. },
  5447. addNewEmptyShape: function () {
  5448. if (this.feature._latlngs.length && this.feature._latlngs[0].length) {
  5449. var shape = [];
  5450. this.appendShape(shape);
  5451. return shape;
  5452. } else {
  5453. return this.feature._latlngs;
  5454. }
  5455. },
  5456. ensureMulti: function () {
  5457. if (this.feature._latlngs.length && L.Polyline._flat(this.feature._latlngs[0])) {
  5458. this.feature._latlngs = [this.feature._latlngs];
  5459. }
  5460. },
  5461. ensureNotFlat: function () {
  5462. if (!this.feature._latlngs.length || L.Polyline._flat(this.feature._latlngs)) this.feature._latlngs = [this.feature._latlngs];
  5463. },
  5464. vertexCanBeDeleted: function (vertex) {
  5465. var parent = this.feature.parentShape(vertex.latlngs),
  5466. idx = L.Util.indexOf(parent, vertex.latlngs);
  5467. if (idx > 0) return true; // Holes can be totally deleted without removing the layer itself.
  5468. return L.Editable.PathEditor.prototype.vertexCanBeDeleted.call(this, vertex);
  5469. },
  5470. getDefaultLatLngs: function () {
  5471. if (!this.feature._latlngs.length) this.feature._latlngs.push([]);
  5472. return this.feature._latlngs[0];
  5473. },
  5474. formatShape: function (shape) {
  5475. // [[1, 2], [3, 4]] => must be nested
  5476. // [] => must be nested
  5477. // [[]] => is already nested
  5478. if (L.Polyline._flat(shape) && (!shape[0] || shape[0].length !== 0)) return [shape];
  5479. else return shape;
  5480. }
  5481. });
  5482. // 🍂namespace Editable; 🍂class RectangleEditor; 🍂aka L.Editable.RectangleEditor
  5483. // 🍂inherits PathEditor
  5484. L.Editable.RectangleEditor = L.Editable.PathEditor.extend({
  5485. CLOSED: true,
  5486. MIN_VERTEX: 4,
  5487. options: {
  5488. skipMiddleMarkers: true
  5489. },
  5490. extendBounds: function (e) {
  5491. var index = e.vertex.getIndex(),
  5492. next = e.vertex.getNext(),
  5493. previous = e.vertex.getPrevious(),
  5494. oppositeIndex = (index + 2) % 4,
  5495. opposite = e.vertex.latlngs[oppositeIndex],
  5496. bounds = new L.LatLngBounds(e.latlng, opposite);
  5497. // Update latlngs by hand to preserve order.
  5498. previous.latlng.update([e.latlng.lat, opposite.lng]);
  5499. next.latlng.update([opposite.lat, e.latlng.lng]);
  5500. this.updateBounds(bounds);
  5501. this.refreshVertexMarkers();
  5502. },
  5503. onDrawingMouseDown: function (e) {
  5504. L.Editable.PathEditor.prototype.onDrawingMouseDown.call(this, e);
  5505. this.connect();
  5506. var latlngs = this.getDefaultLatLngs();
  5507. // L.Polygon._convertLatLngs removes last latlng if it equals first point,
  5508. // which is the case here as all latlngs are [0, 0]
  5509. if (latlngs.length === 3) latlngs.push(e.latlng);
  5510. var bounds = new L.LatLngBounds(e.latlng, e.latlng);
  5511. this.updateBounds(bounds);
  5512. this.updateLatLngs(bounds);
  5513. this.refresh();
  5514. this.reset();
  5515. // Stop dragging map.
  5516. // L.Draggable has two workflows:
  5517. // - mousedown => mousemove => mouseup
  5518. // - touchstart => touchmove => touchend
  5519. // Problem: L.Map.Tap does not allow us to listen to touchstart, so we only
  5520. // can deal with mousedown, but then when in a touch device, we are dealing with
  5521. // simulated events (actually simulated by L.Map.Tap), which are no more taken
  5522. // into account by L.Draggable.
  5523. // Ref.: https://github.com/Leaflet/Leaflet.Editable/issues/103
  5524. e.originalEvent._simulated = false;
  5525. this.map.dragging._draggable._onUp(e.originalEvent);
  5526. // Now transfer ongoing drag action to the bottom right corner.
  5527. // Should we refine which corne will handle the drag according to
  5528. // drag direction?
  5529. latlngs[3].__vertex.dragging._draggable._onDown(e.originalEvent);
  5530. },
  5531. onDrawingMouseUp: function (e) {
  5532. this.commitDrawing(e);
  5533. e.originalEvent._simulated = false;
  5534. L.Editable.PathEditor.prototype.onDrawingMouseUp.call(this, e);
  5535. },
  5536. onDrawingMouseMove: function (e) {
  5537. e.originalEvent._simulated = false;
  5538. L.Editable.PathEditor.prototype.onDrawingMouseMove.call(this, e);
  5539. },
  5540. getDefaultLatLngs: function (latlngs) {
  5541. return latlngs || this.feature._latlngs[0];
  5542. },
  5543. updateBounds: function (bounds) {
  5544. this.feature._bounds = bounds;
  5545. },
  5546. updateLatLngs: function (bounds) {
  5547. var latlngs = this.getDefaultLatLngs(),
  5548. newLatlngs = this.feature._boundsToLatLngs(bounds);
  5549. // Keep references.
  5550. for (var i = 0; i < latlngs.length; i++) {
  5551. latlngs[i].update(newLatlngs[i]);
  5552. };
  5553. }
  5554. });
  5555. // 🍂namespace Editable; 🍂class CircleEditor; 🍂aka L.Editable.CircleEditor
  5556. // 🍂inherits PathEditor
  5557. L.Editable.CircleEditor = L.Editable.PathEditor.extend({
  5558. MIN_VERTEX: 2,
  5559. options: {
  5560. skipMiddleMarkers: true
  5561. },
  5562. initialize: function (map, feature, options) {
  5563. L.Editable.PathEditor.prototype.initialize.call(this, map, feature, options);
  5564. this._resizeLatLng = this.computeResizeLatLng();
  5565. },
  5566. computeResizeLatLng: function () {
  5567. // While circle is not added to the map, _radius is not set.
  5568. var delta = (this.feature._radius || this.feature._mRadius) * Math.cos(Math.PI / 4),
  5569. point = this.map.project(this.feature._latlng);
  5570. return this.map.unproject([point.x + delta, point.y - delta]);
  5571. },
  5572. updateResizeLatLng: function () {
  5573. this._resizeLatLng.update(this.computeResizeLatLng());
  5574. this._resizeLatLng.__vertex.update();
  5575. },
  5576. getLatLngs: function () {
  5577. return [this.feature._latlng, this._resizeLatLng];
  5578. },
  5579. getDefaultLatLngs: function () {
  5580. return this.getLatLngs();
  5581. },
  5582. onVertexMarkerDrag: function (e) {
  5583. if (e.vertex.getIndex() === 1) this.resize(e);
  5584. else this.updateResizeLatLng(e);
  5585. L.Editable.PathEditor.prototype.onVertexMarkerDrag.call(this, e);
  5586. },
  5587. resize: function (e) {
  5588. var radius = this.feature._latlng.distanceTo(e.latlng)
  5589. this.feature.setRadius(radius);
  5590. },
  5591. onDrawingMouseDown: function (e) {
  5592. L.Editable.PathEditor.prototype.onDrawingMouseDown.call(this, e);
  5593. this._resizeLatLng.update(e.latlng);
  5594. this.feature._latlng.update(e.latlng);
  5595. this.connect();
  5596. // Stop dragging map.
  5597. e.originalEvent._simulated = false;
  5598. this.map.dragging._draggable._onUp(e.originalEvent);
  5599. // Now transfer ongoing drag action to the radius handler.
  5600. this._resizeLatLng.__vertex.dragging._draggable._onDown(e.originalEvent);
  5601. },
  5602. onDrawingMouseUp: function (e) {
  5603. this.commitDrawing(e);
  5604. e.originalEvent._simulated = false;
  5605. L.Editable.PathEditor.prototype.onDrawingMouseUp.call(this, e);
  5606. },
  5607. onDrawingMouseMove: function (e) {
  5608. e.originalEvent._simulated = false;
  5609. L.Editable.PathEditor.prototype.onDrawingMouseMove.call(this, e);
  5610. },
  5611. onDrag: function (e) {
  5612. L.Editable.PathEditor.prototype.onDrag.call(this, e);
  5613. this.feature.dragging.updateLatLng(this._resizeLatLng);
  5614. }
  5615. });
  5616. // 🍂namespace Editable; 🍂class EditableMixin
  5617. // `EditableMixin` is included to `L.Polyline`, `L.Polygon`, `L.Rectangle`, `L.Circle`
  5618. // and `L.Marker`. It adds some methods to them.
  5619. // *When editing is enabled, the editor is accessible on the instance with the
  5620. // `editor` property.*
  5621. var EditableMixin = {
  5622. createEditor: function (map) {
  5623. map = map || this._map;
  5624. var tools = (this.options.editOptions || {}).editTools || map.editTools;
  5625. if (!tools) throw Error('Unable to detect Editable instance.')
  5626. var Klass = this.options.editorClass || this.getEditorClass(tools);
  5627. return new Klass(map, this, this.options.editOptions);
  5628. },
  5629. // 🍂method enableEdit(map?: L.Map): this.editor
  5630. // Enable editing, by creating an editor if not existing, and then calling `enable` on it.
  5631. enableEdit: function (callback,map) {
  5632. if (!this.editor) this.createEditor(map);
  5633. this.editor.enable();
  5634. this.editor.callback = callback;
  5635. return this.editor;
  5636. },
  5637. // 🍂method editEnabled(): boolean
  5638. // Return true if current instance has an editor attached, and this editor is enabled.
  5639. editEnabled: function () {
  5640. return this.editor && this.editor.enabled();
  5641. },
  5642. // 🍂method disableEdit()
  5643. // Disable editing, also remove the editor property reference.
  5644. disableEdit: function () {
  5645. if (this.editor) {
  5646. this.editor.disable();
  5647. delete this.editor;
  5648. }
  5649. },
  5650. // 🍂method toggleEdit()
  5651. // Enable or disable editing, according to current status.
  5652. toggleEdit: function () {
  5653. if (this.editEnabled()) this.disableEdit();
  5654. else this.enableEdit();
  5655. },
  5656. _onEditableAdd: function () {
  5657. if (this.editor) this.enableEdit();
  5658. }
  5659. };
  5660. var PolylineMixin = {
  5661. getEditorClass: function (tools) {
  5662. return (tools && tools.options.polylineEditorClass) ? tools.options.polylineEditorClass : L.Editable.PolylineEditor;
  5663. },
  5664. shapeAt: function (latlng, latlngs) {
  5665. // We can have those cases:
  5666. // - latlngs are just a flat array of latlngs, use this
  5667. // - latlngs is an array of arrays of latlngs, loop over
  5668. var shape = null;
  5669. latlngs = latlngs || this._latlngs;
  5670. if (!latlngs.length) return shape;
  5671. else if (L.Polyline._flat(latlngs) && this.isInLatLngs(latlng, latlngs)) shape = latlngs;
  5672. else for (var i = 0; i < latlngs.length; i++) if (this.isInLatLngs(latlng, latlngs[i])) return latlngs[i];
  5673. return shape;
  5674. },
  5675. isInLatLngs: function (l, latlngs) {
  5676. if (!latlngs) return false;
  5677. var i, k, len, part = [], p,
  5678. w = this._clickTolerance();
  5679. this._projectLatlngs(latlngs, part, this._pxBounds);
  5680. part = part[0];
  5681. p = this._map.latLngToLayerPoint(l);
  5682. if (!this._pxBounds.contains(p)) { return false; }
  5683. for (i = 1, len = part.length, k = 0; i < len; k = i++) {
  5684. if (L.LineUtil.pointToSegmentDistance(p, part[k], part[i]) <= w) {
  5685. return true;
  5686. }
  5687. }
  5688. return false;
  5689. }
  5690. };
  5691. var PolygonMixin = {
  5692. getEditorClass: function (tools) {
  5693. return (tools && tools.options.polygonEditorClass) ? tools.options.polygonEditorClass : L.Editable.PolygonEditor;
  5694. },
  5695. shapeAt: function (latlng, latlngs) {
  5696. // We can have those cases:
  5697. // - latlngs are just a flat array of latlngs, use this
  5698. // - latlngs is an array of arrays of latlngs, this is a simple polygon (maybe with holes), use the first
  5699. // - latlngs is an array of arrays of arrays, this is a multi, loop over
  5700. var shape = null;
  5701. latlngs = latlngs || this._latlngs;
  5702. if (!latlngs.length) return shape;
  5703. else if (L.Polyline._flat(latlngs) && this.isInLatLngs(latlng, latlngs)) shape = latlngs;
  5704. else if (L.Polyline._flat(latlngs[0]) && this.isInLatLngs(latlng, latlngs[0])) shape = latlngs;
  5705. else for (var i = 0; i < latlngs.length; i++) if (this.isInLatLngs(latlng, latlngs[i][0])) return latlngs[i];
  5706. return shape;
  5707. },
  5708. isInLatLngs: function (l, latlngs) {
  5709. var inside = false, l1, l2, j, k, len2;
  5710. for (j = 0, len2 = latlngs.length, k = len2 - 1; j < len2; k = j++) {
  5711. l1 = latlngs[j];
  5712. l2 = latlngs[k];
  5713. if (((l1.lat > l.lat) !== (l2.lat > l.lat)) &&
  5714. (l.lng < (l2.lng - l1.lng) * (l.lat - l1.lat) / (l2.lat - l1.lat) + l1.lng)) {
  5715. inside = !inside;
  5716. }
  5717. }
  5718. return inside;
  5719. },
  5720. parentShape: function (shape, latlngs) {
  5721. latlngs = latlngs || this._latlngs;
  5722. if (!latlngs) return;
  5723. var idx = L.Util.indexOf(latlngs, shape);
  5724. if (idx !== -1) return latlngs;
  5725. for (var i = 0; i < latlngs.length; i++) {
  5726. idx = L.Util.indexOf(latlngs[i], shape);
  5727. if (idx !== -1) return latlngs[i];
  5728. }
  5729. }
  5730. };
  5731. var MarkerMixin = {
  5732. getEditorClass: function (tools) {
  5733. return (tools && tools.options.markerEditorClass) ? tools.options.markerEditorClass : L.Editable.MarkerEditor;
  5734. }
  5735. };
  5736. var RectangleMixin = {
  5737. getEditorClass: function (tools) {
  5738. return (tools && tools.options.rectangleEditorClass) ? tools.options.rectangleEditorClass : L.Editable.RectangleEditor;
  5739. }
  5740. };
  5741. var CircleMixin = {
  5742. getEditorClass: function (tools) {
  5743. return (tools && tools.options.circleEditorClass) ? tools.options.circleEditorClass : L.Editable.CircleEditor;
  5744. }
  5745. };
  5746. var keepEditable = function () {
  5747. // Make sure you can remove/readd an editable layer.
  5748. this.on('add', this._onEditableAdd);
  5749. };
  5750. if (L.Polyline) {
  5751. L.Polyline.include(EditableMixin);
  5752. L.Polyline.include(PolylineMixin);
  5753. L.Polyline.addInitHook(keepEditable);
  5754. }
  5755. if (L.Polygon) {
  5756. L.Polygon.include(EditableMixin);
  5757. L.Polygon.include(PolygonMixin);
  5758. }
  5759. if (L.Marker) {
  5760. L.Marker.include(EditableMixin);
  5761. L.Marker.include(MarkerMixin);
  5762. L.Marker.addInitHook(keepEditable);
  5763. }
  5764. if (L.Rectangle) {
  5765. L.Rectangle.include(EditableMixin);
  5766. L.Rectangle.include(RectangleMixin);
  5767. }
  5768. if (L.Circle) {
  5769. L.Circle.include(EditableMixin);
  5770. L.Circle.include(CircleMixin);
  5771. }
  5772. L.LatLng.prototype.update = function (latlng) {
  5773. latlng = L.latLng(latlng);
  5774. this.lat = latlng.lat;
  5775. this.lng = latlng.lng;
  5776. }
  5777. }, window));
  5778. /*
  5779. Leaflet.contextmenu, a context menu for Leaflet.
  5780. (c) 2015, Adam Ratcliffe, GeoSmart Maps Limited
  5781. @preserve
  5782. */
  5783. (function(factory) {
  5784. // Packaging/modules magic dance
  5785. var L;
  5786. if (typeof define === 'function' && define.amd) {
  5787. // AMD
  5788. define(['leaflet'], factory);
  5789. } else if (typeof module !== 'undefined') {
  5790. // Node/CommonJS
  5791. L = require('leaflet');
  5792. module.exports = factory(L);
  5793. } else {
  5794. // Browser globals
  5795. if (typeof window.L === 'undefined') {
  5796. throw new Error('Leaflet must be loaded first');
  5797. }
  5798. factory(window.L);
  5799. }
  5800. })(function(L) {
  5801. L.Map.mergeOptions({
  5802. contextmenuItems: []
  5803. });
  5804. L.Map.ContextMenu = L.Handler.extend({
  5805. _touchstart: L.Browser.msPointer ? 'MSPointerDown' : L.Browser.pointer ? 'pointerdown' : 'touchstart',
  5806. statics: {
  5807. BASE_CLS: 'leaflet-contextmenu'
  5808. },
  5809. runCallFunc:[],
  5810. initialize: function (map) {
  5811. L.Handler.prototype.initialize.call(this, map);
  5812. this._items = [];
  5813. this._visible = false;
  5814. var container = this._container = L.DomUtil.create('div', L.Map.ContextMenu.BASE_CLS, map._container);
  5815. container.style.zIndex = 10000;
  5816. container.style.position = 'absolute';
  5817. if (map.options.contextmenuWidth) {
  5818. container.style.width = map.options.contextmenuWidth + 'px';
  5819. }
  5820. this._createItems();
  5821. L.DomEvent
  5822. .on(container, 'click', L.DomEvent.stop)
  5823. .on(container, 'mousedown', L.DomEvent.stop)
  5824. .on(container, 'dblclick', L.DomEvent.stop)
  5825. .on(container, 'contextmenu', L.DomEvent.stop);
  5826. },
  5827. addHooks: function () {
  5828. var container = this._map.getContainer();
  5829. L.DomEvent
  5830. .on(container, 'mouseleave', this._hide, this)
  5831. .on(document, 'keydown', this._onKeyDown, this);
  5832. if (L.Browser.touch) {
  5833. L.DomEvent.on(document, this._touchstart, this._hide, this);
  5834. }
  5835. this._map.on({
  5836. contextmenu: this._show,
  5837. mousedown: this._hide,
  5838. movestart: this._hide,
  5839. zoomstart: this._hide
  5840. }, this);
  5841. },
  5842. removeHooks: function () {
  5843. var container = this._map.getContainer();
  5844. L.DomEvent
  5845. .off(container, 'mouseleave', this._hide, this)
  5846. .off(document, 'keydown', this._onKeyDown, this);
  5847. if (L.Browser.touch) {
  5848. L.DomEvent.off(document, this._touchstart, this._hide, this);
  5849. }
  5850. this._map.off({
  5851. contextmenu: this._show,
  5852. mousedown: this._hide,
  5853. movestart: this._hide,
  5854. zoomstart: this._hide
  5855. }, this);
  5856. },
  5857. showAt: function (point, data) {
  5858. if (point instanceof L.LatLng) {
  5859. point = this._map.latLngToContainerPoint(point);
  5860. }
  5861. this._showAtPoint(point, data);
  5862. },
  5863. hide: function () {
  5864. this._hide();
  5865. },
  5866. addItem: function (options) {
  5867. return this.insertItem(options);
  5868. },
  5869. insertItem: function (options, index) {
  5870. index = index !== undefined ? index: this._items.length;
  5871. var item = this._createItem(this._container, options, index);
  5872. this._items.push(item);
  5873. this._sizeChanged = true;
  5874. this._map.fire('contextmenu.additem', {
  5875. contextmenu: this,
  5876. el: item.el,
  5877. index: index
  5878. });
  5879. return item.el;
  5880. },
  5881. removeItem: function (item) {
  5882. var container = this._container;
  5883. if (!isNaN(item)) {
  5884. item = container.children[item];
  5885. }
  5886. if (item) {
  5887. this._removeItem(L.Util.stamp(item));
  5888. this._sizeChanged = true;
  5889. this._map.fire('contextmenu.removeitem', {
  5890. contextmenu: this,
  5891. el: item
  5892. });
  5893. }
  5894. },
  5895. removeAllItems: function () {
  5896. var item;
  5897. while (this._container.children.length) {
  5898. item = this._container.children[0];
  5899. this._removeItem(L.Util.stamp(item));
  5900. }
  5901. },
  5902. hideAllItems: function () {
  5903. var item, i, l;
  5904. for (i = 0, l = this._items.length; i < l; i++) {
  5905. item = this._items[i];
  5906. item.el.style.display = 'none';
  5907. }
  5908. },
  5909. showAllItems: function () {
  5910. var item, i, l;
  5911. for (i = 0, l = this._items.length; i < l; i++) {
  5912. item = this._items[i];
  5913. item.el.style.display = '';
  5914. }
  5915. },
  5916. setDisabled: function (item, disabled) {
  5917. var container = this._container,
  5918. itemCls = L.Map.ContextMenu.BASE_CLS + '-item';
  5919. if (!isNaN(item)) {
  5920. item = container.children[item];
  5921. }
  5922. if (item && L.DomUtil.hasClass(item, itemCls)) {
  5923. if (disabled) {
  5924. L.DomUtil.addClass(item, itemCls + '-disabled');
  5925. this._map.fire('contextmenu.disableitem', {
  5926. contextmenu: this,
  5927. el: item
  5928. });
  5929. } else {
  5930. L.DomUtil.removeClass(item, itemCls + '-disabled');
  5931. this._map.fire('contextmenu.enableitem', {
  5932. contextmenu: this,
  5933. el: item
  5934. });
  5935. }
  5936. }
  5937. },
  5938. isVisible: function () {
  5939. return this._visible;
  5940. },
  5941. _createItems: function () {
  5942. var itemOptions = this._map.options.contextmenuItems,
  5943. item,
  5944. i, l;
  5945. for (i = 0, l = itemOptions.length; i < l; i++) {
  5946. this._items.push(this._createItem(this._container, itemOptions[i]));
  5947. }
  5948. },
  5949. _createItem: function (container, options, index) {
  5950. if (options.separator || options === '-') {
  5951. return this._createSeparator(container, index);
  5952. }
  5953. var itemCls = L.Map.ContextMenu.BASE_CLS + '-item',
  5954. cls = options.disabled ? (itemCls + ' ' + itemCls + '-disabled') : itemCls;
  5955. if(options.hasOwnProperty('className')){
  5956. cls = cls + ' ' + options.className;
  5957. }
  5958. var el = this._insertElementAt('a', cls, container, index),
  5959. callback = this._createEventHandler(el, options.callback, options.context, options.hideOnSelect),
  5960. html = '';
  5961. if(options.hasOwnProperty('runCall')){
  5962. this.runCallFunc.push(options.runCall);
  5963. }
  5964. if (options.icon) {
  5965. html = '<img class="' + L.Map.ContextMenu.BASE_CLS + '-icon" src="' + options.icon + '"/>';
  5966. } else if (options.iconCls) {
  5967. html = '<span class="' + L.Map.ContextMenu.BASE_CLS + '-icon ' + options.iconCls + '"></span>';
  5968. }
  5969. if(typeof options.text === 'object'){
  5970. el.innerHTML = html;
  5971. el.appendChild(options.text);
  5972. }else {
  5973. el.innerHTML = html + options.text;
  5974. }
  5975. el.href = '#';
  5976. L.DomEvent
  5977. .on(el, 'mouseover', this._onItemMouseOver, this)
  5978. .on(el, 'mouseout', this._onItemMouseOut, this)
  5979. .on(el, 'mousedown', L.DomEvent.stopPropagation)
  5980. .on(el, 'click', callback);
  5981. if (L.Browser.touch) {
  5982. L.DomEvent.on(el, this._touchstart, L.DomEvent.stopPropagation);
  5983. }
  5984. return {
  5985. id: L.Util.stamp(el),
  5986. el: el,
  5987. callback: callback
  5988. };
  5989. },
  5990. _removeItem: function (id) {
  5991. var item,
  5992. el,
  5993. i, l, callback;
  5994. for (i = 0, l = this._items.length; i < l; i++) {
  5995. item = this._items[i];
  5996. if (item.id === id) {
  5997. el = item.el;
  5998. callback = item.callback;
  5999. if (callback) {
  6000. L.DomEvent
  6001. .off(el, 'mouseover', this._onItemMouseOver, this)
  6002. .off(el, 'mouseover', this._onItemMouseOut, this)
  6003. .off(el, 'mousedown', L.DomEvent.stopPropagation)
  6004. .off(el, 'click', callback);
  6005. if (L.Browser.touch) {
  6006. L.DomEvent.off(el, this._touchstart, L.DomEvent.stopPropagation);
  6007. }
  6008. }
  6009. this._container.removeChild(el);
  6010. this._items.splice(i, 1);
  6011. return item;
  6012. }
  6013. }
  6014. return null;
  6015. },
  6016. _createSeparator: function (container, index) {
  6017. var el = this._insertElementAt('div', L.Map.ContextMenu.BASE_CLS + '-separator', container, index);
  6018. return {
  6019. id: L.Util.stamp(el),
  6020. el: el
  6021. };
  6022. },
  6023. _createEventHandler: function (el, func, context, hideOnSelect) {
  6024. var me = this,
  6025. map = this._map,
  6026. disabledCls = L.Map.ContextMenu.BASE_CLS + '-item-disabled',
  6027. hideOnSelect = (hideOnSelect !== undefined) ? hideOnSelect : true;
  6028. return function (e) {
  6029. if (L.DomUtil.hasClass(el, disabledCls)) {
  6030. return;
  6031. }
  6032. if (hideOnSelect) {
  6033. me._hide();
  6034. }
  6035. if (func) {
  6036. func.call(context || map, me._showLocation);
  6037. }
  6038. me._map.fire('contextmenu:select', {
  6039. contextmenu: me,
  6040. el: el
  6041. });
  6042. };
  6043. },
  6044. _insertElementAt: function (tagName, className, container, index) {
  6045. var refEl,
  6046. el = document.createElement(tagName);
  6047. el.className = className;
  6048. if (index !== undefined) {
  6049. refEl = container.children[index];
  6050. }
  6051. if (refEl) {
  6052. container.insertBefore(el, refEl);
  6053. } else {
  6054. container.appendChild(el);
  6055. }
  6056. return el;
  6057. },
  6058. _show: function (e) {
  6059. var _this = this;
  6060. //this._showAtPoint(e.containerPoint, e);
  6061. for(var i = 0, l=this.runCallFunc.length; i<l; i++){
  6062. this.runCallFunc[i](e);
  6063. }
  6064. _this.tempE = e;
  6065. setTimeout(function(){
  6066. _this._showAtPoint(_this.tempE.containerPoint);
  6067. },100);
  6068. if(_this.circleMarker){
  6069. _this._map.removeLayer(_this.circleMarker);
  6070. }
  6071. _this.circleMarker = L.circleMarker(e.latlng, { fillColor: "#cb0000",fillOpacity:1,weight:1, color:"#fff", radius: 3, opacity:1 }).addTo(this._map);
  6072. },
  6073. _showAtPoint: function (pt, data) {
  6074. if (this._items.length) {
  6075. var map = this._map,
  6076. layerPoint = map.containerPointToLayerPoint(pt),
  6077. latlng = map.layerPointToLatLng(layerPoint),
  6078. event = L.extend(data || {}, {contextmenu: this});
  6079. this._showLocation = {
  6080. latlng: latlng,
  6081. layerPoint: layerPoint,
  6082. containerPoint: pt
  6083. };
  6084. if(data && data.relatedTarget){
  6085. this._showLocation.relatedTarget = data.relatedTarget;
  6086. }
  6087. this._setPosition(pt);
  6088. if (!this._visible) {
  6089. this._container.style.display = 'block';
  6090. this._visible = true;
  6091. } else {
  6092. this._setPosition(pt);
  6093. }
  6094. this._map.fire('contextmenu.show', event);
  6095. }
  6096. },
  6097. _hide: function () {
  6098. if (this._visible) {
  6099. this._visible = false;
  6100. this._container.style.display = 'none';
  6101. this._map.fire('contextmenu.hide', {contextmenu: this});
  6102. this._map.removeLayer(this.circleMarker);
  6103. }
  6104. },
  6105. _setPosition: function (pt) {
  6106. var mapSize = this._map.getSize(),
  6107. container = this._container,
  6108. containerSize = this._getElementSize(container),
  6109. anchor;
  6110. if (this._map.options.contextmenuAnchor) {
  6111. anchor = L.point(this._map.options.contextmenuAnchor);
  6112. pt = pt.add(anchor);
  6113. }
  6114. container._leaflet_pos = pt;
  6115. if (pt.x + containerSize.x > mapSize.x) {
  6116. container.style.left = 'auto';
  6117. container.style.right = Math.max(mapSize.x - pt.x, 0) + 'px';
  6118. } else {
  6119. container.style.left = Math.max(pt.x, 0) + 'px';
  6120. container.style.right = 'auto';
  6121. }
  6122. if (pt.y + containerSize.y > mapSize.y) {
  6123. container.style.top = 'auto';
  6124. container.style.bottom = Math.max(mapSize.y - pt.y, 0) + 'px';
  6125. } else {
  6126. container.style.top = Math.max(pt.y, 0) + 'px';
  6127. container.style.bottom = 'auto';
  6128. }
  6129. },
  6130. _getElementSize: function (el) {
  6131. var size = this._size,
  6132. initialDisplay = el.style.display;
  6133. if (!size || this._sizeChanged) {
  6134. size = {};
  6135. el.style.left = '-999999px';
  6136. el.style.right = 'auto';
  6137. el.style.display = 'block';
  6138. size.x = el.offsetWidth;
  6139. size.y = el.offsetHeight;
  6140. el.style.left = 'auto';
  6141. el.style.display = initialDisplay;
  6142. this._sizeChanged = false;
  6143. }
  6144. return size;
  6145. },
  6146. _onKeyDown: function (e) {
  6147. var key = e.keyCode;
  6148. // If ESC pressed and context menu is visible hide it
  6149. if (key === 27) {
  6150. this._hide();
  6151. }
  6152. },
  6153. _onItemMouseOver: function (e) {
  6154. L.DomUtil.addClass(e.target || e.srcElement, 'over');
  6155. },
  6156. _onItemMouseOut: function (e) {
  6157. L.DomUtil.removeClass(e.target || e.srcElement, 'over');
  6158. }
  6159. });
  6160. L.Map.addInitHook('addHandler', 'contextmenu', L.Map.ContextMenu);
  6161. L.Mixin.ContextMenu = {
  6162. bindContextMenu: function (options) {
  6163. L.setOptions(this, options);
  6164. this._initContextMenu();
  6165. return this;
  6166. },
  6167. unbindContextMenu: function (){
  6168. this.off('contextmenu', this._showContextMenu, this);
  6169. return this;
  6170. },
  6171. addContextMenuItem: function (item) {
  6172. this.options.contextmenuItems.push(item);
  6173. },
  6174. removeContextMenuItemWithIndex: function (index) {
  6175. var items = [];
  6176. for (var i = 0; i < this.options.contextmenuItems.length; i++) {
  6177. if(this.options.contextmenuItems[i].index == index){
  6178. items.push(i);
  6179. }
  6180. }
  6181. var elem = items.pop();
  6182. while (elem !== undefined) {
  6183. this.options.contextmenuItems.splice(elem,1);
  6184. elem = items.pop();
  6185. }
  6186. },
  6187. replaceConextMenuItem: function (item) {
  6188. this.removeContextMenuItemWithIndex(item.index);
  6189. this.addContextMenuItem(item);
  6190. },
  6191. _initContextMenu: function () {
  6192. this._items = [];
  6193. this.on('contextmenu', this._showContextMenu, this);
  6194. },
  6195. _showContextMenu: function (e) {
  6196. var itemOptions,
  6197. data, pt, i, l;
  6198. if (this._map.contextmenu) {
  6199. data = L.extend({relatedTarget: this}, e)
  6200. pt = this._map.mouseEventToContainerPoint(e.originalEvent);
  6201. if (!this.options.contextmenuInheritItems) {
  6202. this._map.contextmenu.hideAllItems();
  6203. }
  6204. for (i = 0, l = this.options.contextmenuItems.length; i < l; i++) {
  6205. itemOptions = this.options.contextmenuItems[i];
  6206. this._items.push(this._map.contextmenu.insertItem(itemOptions, itemOptions.index));
  6207. }
  6208. this._map.once('contextmenu.hide', this._hideContextMenu, this);
  6209. this._map.contextmenu.showAt(pt, data);
  6210. }
  6211. },
  6212. _hideContextMenu: function () {
  6213. var i, l;
  6214. for (i = 0, l = this._items.length; i < l; i++) {
  6215. this._map.contextmenu.removeItem(this._items[i]);
  6216. }
  6217. this._items.length = 0;
  6218. if (!this.options.contextmenuInheritItems) {
  6219. this._map.contextmenu.showAllItems();
  6220. }
  6221. }
  6222. };
  6223. var classes = [L.Marker, L.Path],
  6224. defaultOptions = {
  6225. contextmenu: false,
  6226. contextmenuItems: [],
  6227. contextmenuInheritItems: true
  6228. },
  6229. cls, i, l;
  6230. for (i = 0, l = classes.length; i < l; i++) {
  6231. cls = classes[i];
  6232. // L.Class should probably provide an empty options hash, as it does not test
  6233. // for it here and add if needed
  6234. if (!cls.prototype.options) {
  6235. cls.prototype.options = defaultOptions;
  6236. } else {
  6237. cls.mergeOptions(defaultOptions);
  6238. }
  6239. cls.addInitHook(function () {
  6240. if (this.options.contextmenu) {
  6241. this._initContextMenu();
  6242. }
  6243. });
  6244. cls.include(L.Mixin.ContextMenu);
  6245. }
  6246. return L.Map.ContextMenu;
  6247. });
  6248. /**
  6249. * Semicircle extension for L.Circle.
  6250. * Jan Pieter Waagmeester <jieter@jieter.nl>
  6251. *
  6252. * This version is tested with leaflet 1.0.2
  6253. */
  6254. (function (factory) {
  6255. if (typeof define === 'function' && define.amd) {
  6256. // AMD
  6257. define(['leaflet'], factory);
  6258. } else if (typeof module !== 'undefined') {
  6259. // Node/CommonJS
  6260. module.exports = factory(require('leaflet'));
  6261. } else {
  6262. // Browser globals
  6263. if (typeof window.L === 'undefined') {
  6264. throw 'Leaflet must be loaded first';
  6265. }
  6266. factory(window.L);
  6267. }
  6268. })(function (L) {
  6269. var DEG_TO_RAD = Math.PI / 180;
  6270. // make sure 0 degrees is up (North) and convert to radians.
  6271. function fixAngle (angle) {
  6272. return (angle - 90) * DEG_TO_RAD;
  6273. }
  6274. // rotate point [x + r, y+r] around [x, y] by `angle` radians.
  6275. function rotated (p, angle, r) {
  6276. return p.add(
  6277. L.point(Math.cos(angle), Math.sin(angle)).multiplyBy(r)
  6278. );
  6279. }
  6280. L.Point.prototype.rotated = function (angle, r) {
  6281. return rotated(this, angle, r);
  6282. };
  6283. L.Circle = L.Circle.extend({
  6284. options: {
  6285. startAngle: 0,
  6286. stopAngle: 359.9999999999999999999999
  6287. },
  6288. startAngle: function () {
  6289. if (this.options.startAngle < this.options.stopAngle) {
  6290. return fixAngle(this.options.startAngle);
  6291. } else {
  6292. return fixAngle(this.options.stopAngle);
  6293. }
  6294. },
  6295. stopAngle: function () {
  6296. if (this.options.startAngle < this.options.stopAngle) {
  6297. return fixAngle(this.options.stopAngle);
  6298. } else {
  6299. return fixAngle(this.options.startAngle);
  6300. }
  6301. },
  6302. setStartAngle: function (angle) {
  6303. this.options.startAngle = angle;
  6304. return this.redraw();
  6305. },
  6306. setStopAngle: function (angle) {
  6307. this.options.stopAngle = angle;
  6308. return this.redraw();
  6309. },
  6310. setDirection: function (direction, degrees) {
  6311. if (degrees === undefined) {
  6312. degrees = 10;
  6313. }
  6314. this.options.startAngle = direction - (degrees / 2);
  6315. this.options.stopAngle = direction + (degrees / 2);
  6316. return this.redraw();
  6317. },
  6318. getDirection: function () {
  6319. return this.stopAngle() - (this.stopAngle() - this.startAngle()) / 2;
  6320. },
  6321. isSemicircle: function () {
  6322. var startAngle = this.options.startAngle,
  6323. stopAngle = this.options.stopAngle;
  6324. return (
  6325. !(startAngle === 0 && stopAngle > 359) &&
  6326. !(startAngle == stopAngle)
  6327. );
  6328. },
  6329. _containsPoint: function (p) {
  6330. function normalize (angle) {
  6331. while (angle <= -Math.PI) {
  6332. angle += 2.0 * Math.PI;
  6333. }
  6334. while (angle > Math.PI) {
  6335. angle -= 2.0 * Math.PI;
  6336. }
  6337. return angle;
  6338. }
  6339. var angle = Math.atan2(p.y - this._point.y, p.x - this._point.x);
  6340. var nStart = normalize(this.startAngle());
  6341. var nStop = normalize(this.stopAngle());
  6342. if (nStop <= nStart) {
  6343. nStop += 2.0 * Math.PI;
  6344. }
  6345. if (angle <= nStart) {
  6346. angle += 2.0 * Math.PI;
  6347. }
  6348. return (
  6349. nStart < angle && angle <= nStop &&
  6350. p.distanceTo(this._point) <= this._radius + this._clickTolerance()
  6351. );
  6352. }
  6353. });
  6354. var _updateCircleSVG = L.SVG.prototype._updateCircle;
  6355. var _updateCircleCanvas = L.Canvas.prototype._updateCircle;
  6356. L.SVG.include({
  6357. _updateCircle: function (layer) {
  6358. // If we want a circle, we use the original function
  6359. if (!layer.isSemicircle()) {
  6360. return _updateCircleSVG.call(this, layer);
  6361. }
  6362. if (layer._empty()) {
  6363. return this._setPath(layer, 'M0 0');
  6364. }
  6365. var p = layer._point,
  6366. r = layer._radius,
  6367. r2 = Math.round(layer._radiusY || r),
  6368. start = p.rotated(layer.startAngle(), r),
  6369. end = p.rotated(layer.stopAngle(), r);
  6370. var largeArc = (layer.options.stopAngle - layer.options.startAngle >= 180) ? '1' : '0';
  6371. var d = 'M' + p.x + ',' + p.y +
  6372. // line to first start point
  6373. 'L' + start.x + ',' + start.y +
  6374. 'A ' + r + ',' + r2 + ',0,' + largeArc + ',1,' + end.x + ',' + end.y +
  6375. ' z';
  6376. this._setPath(layer, d);
  6377. }
  6378. });
  6379. L.Canvas.include({
  6380. _updateCircle: function (layer) {
  6381. // If we want a circle, we use the original function
  6382. if (!layer.isSemicircle()) {
  6383. return _updateCircleCanvas.call(this, layer);
  6384. }
  6385. var p = layer._point,
  6386. ctx = this._ctx,
  6387. r = layer._radius,
  6388. s = (layer._radiusY || r) / r,
  6389. start = p.rotated(layer.startAngle(), r);
  6390. this._drawnLayers[layer._leaflet_id] = layer;
  6391. if (s !== 1) {
  6392. ctx.save();
  6393. ctx.scale(1, s);
  6394. }
  6395. ctx.beginPath();
  6396. ctx.moveTo(p.x, p.y);
  6397. ctx.lineTo(start.x, start.y);
  6398. ctx.arc(p.x, p.y, r, layer.startAngle(), layer.stopAngle());
  6399. ctx.lineTo(p.x, p.y);
  6400. if (s !== 1) {
  6401. ctx.restore();
  6402. }
  6403. this._fillStroke(ctx, layer);
  6404. }
  6405. });
  6406. // L.CircleMarker inherits from L.Circle before the Semicircle stuff is
  6407. // added. The renderers test if the layer is a semicircle with a function
  6408. // isSemicircle, so add that to L.CircleMarker to make sure we can still
  6409. // make L.CircleMarkers.
  6410. L.CircleMarker = L.CircleMarker.extend({
  6411. isSemicircle: function () { return false; }
  6412. });
  6413. });
  6414. ;
  6415. (function(window, document, undefined) {
  6416. //获取三维视图任一点象素位置的经纬度坐标
  6417. function get3DPixToLnglat(option) {
  6418. var point = locaSpaceMap.CreatePoint2D();
  6419. if (option == 'topleft') {
  6420. var S2dx = 0; //3D视图容器宽度的二分之一
  6421. var S2dy = 0; //3D视图容器高度的二分之一
  6422. } else if (option == 'bottomright') {
  6423. var S2dx = $('#map3DWrap').width(); //3D视图容器宽度的二分之一
  6424. var S2dy = $('#map3DWrap').height(); //3D视图容器高度的二分之一
  6425. } else if (option == 'center') {
  6426. var S2dx = $('#map3DWrap').width() / 2; //3D视图容器宽度的二分之一
  6427. var S2dy = $('#map3DWrap').height() / 2; //3D视图容器高度的二分之一
  6428. }
  6429. point.x = parseInt(S2dx);
  6430. point.y = parseInt(S2dy);
  6431. var result = locaSpaceMap.Globe.ScreenToScene(point);
  6432. return {
  6433. lng: result.x,
  6434. lat: result.y
  6435. };
  6436. }
  6437. /**
  6438. * 聚集区显示
  6439. * 根据两个点或三个点计算出聚集区坐标
  6440. */
  6441. function getGeoGatheringPlace(start, middle, stop) {
  6442. var originP = new SuperMap.Geometry.Point(start[0], start[1]);
  6443. var lastP = new SuperMap.Geometry.Point(stop[0], stop[1]);
  6444. var gather = new SuperMap.Geometry.GeoGatheringPlace;
  6445. var points = [];
  6446. // 向量originP_lastP
  6447. var vectorOL = new SuperMap.Geometry.Point(lastP.x - originP.x, lastP.y - originP.y);
  6448. // 向量originP_lastP的模
  6449. var dOL = Math.sqrt(vectorOL.x * vectorOL.x + vectorOL.y * vectorOL.y);
  6450. //计算第一个插值控制点
  6451. //向量originP_P1以originP为起点,与向量originP_lastP的夹角设为30,模为√3/12*dOL,
  6452. var v_O_P1_lr = gather.calculateVector(vectorOL, Math.PI / 3, Math.sqrt(3) / 12 * dOL);
  6453. //取左边的向量作为向量originP_P1
  6454. var originP_P1 = v_O_P1_lr[0];
  6455. var p1 = new SuperMap.Geometry.Point(originP_P1.x + originP.x, originP_P1.y + originP.y);
  6456. //计算第二个插值控制点,取第一控制点和第二控制点的中点为第二个插值控制点
  6457. var p2 = new SuperMap.Geometry.Point((originP.x + lastP.x) / 2, (originP.y + lastP.y) / 2);
  6458. //计算第三个插值控制点
  6459. //向量originP_P3以lastP为起点,与向量originP_lastP的夹角设为150°,模为√3/12*dOL,
  6460. var v_L_P3_lr = gather.calculateVector(vectorOL, Math.PI * 2 / 3, Math.sqrt(3) / 12 * dOL);
  6461. //取左边的向量作为向量originP_P1
  6462. var lastP_P3 = v_L_P3_lr[0];
  6463. var p3 = new SuperMap.Geometry.Point(lastP_P3.x + lastP.x, lastP_P3.y + lastP.y);
  6464. //计算第四个插值控制点
  6465. if (middle) {
  6466. var p5 = new SuperMap.Geometry.Point(middle[0], middle[1]);
  6467. } else {
  6468. //向量originP_P4以向量originP_lastP中点为起点,与向量originP_lastP的夹角设为90°,模为1/2*dOL,
  6469. var v_O_P5_lr = gather.calculateVector(vectorOL, Math.PI / 2, 1 / 2 * dOL);
  6470. //取左边的向量作为向量originP_P1
  6471. var v_O_P5 = v_O_P5_lr[1];
  6472. var p5 = new SuperMap.Geometry.Point(v_O_P5.x + p2.x, v_O_P5.y + p2.y);
  6473. }
  6474. var P0 = originP.clone();
  6475. var P4 = lastP.clone();
  6476. points.push(P0, p1, p2, p3, P4, p5);
  6477. var cardinalPoints = SuperMap.Geometry.LineString.createCloseCardinal(points);
  6478. var gatherGeo = SuperMap.Geometry.LineString.createBezier3(cardinalPoints, 100);
  6479. gatherGeo = gatherGeo.components;
  6480. var newGatherGeo = [];
  6481. for (var i = 0; i < gatherGeo.length; i++) {
  6482. newGatherGeo.push([gatherGeo[i].x, gatherGeo[i].y])
  6483. }
  6484. return newGatherGeo;
  6485. }
  6486. /**
  6487. * 转换3世界坐标 用于在leaflet中实现跨逆子午线,线走最近距离 坐标不能超过一圈
  6488. * 遍历坐标数组,取经度,
  6489. * 如果(N+1).lng-N.lng 绝对值超过180表示需要进行换算,取最近路线:负数为逆时针,正数为顺时针
  6490. *
  6491. * @param {[type]} lnglats [description]
  6492. * @return {[type]} [description]
  6493. */
  6494. function lnglatsToDateLineLnglats(lnglats, circleLng) {
  6495. for (var i = 1; i < lnglats.length; i++) {
  6496. var dY = lnglats[i][0] - lnglats[i - 1][0];
  6497. if (dY > 180) {
  6498. if (dY > 540) {
  6499. lnglats[i][0] -= 720;
  6500. } else {
  6501. lnglats[i][0] -= 360;
  6502. }
  6503. }
  6504. if (dY < -180) {
  6505. if (dY < -540) {
  6506. lnglats[i][0] += 720;
  6507. } else {
  6508. lnglats[i][0] += 360;
  6509. }
  6510. }
  6511. }
  6512. //如果第一个点和圆心的差值小于-180 则圆平移360度
  6513. if (circleLng) {
  6514. if ((lnglats[0][0] - circleLng) < -180) {
  6515. for (var i = 0; i < lnglats.length; i++) {
  6516. lnglats[i][0] += 360
  6517. }
  6518. }
  6519. }
  6520. return lnglats;
  6521. }
  6522. /**
  6523. * 3世界坐标 转换 -180 180 纬度坐标
  6524. * @param {[type]} lnglats [description]
  6525. * @return {[type]} [description]
  6526. */
  6527. function dateLineLnglatsToLnglats(lnglats) {
  6528. for (var i = 1; i < lnglats.length; i++) {
  6529. var dY = lnglats[i][0] + lnglats[i - 1][0];
  6530. if (dY > 180) {
  6531. lnglats[i][0] -= 360;
  6532. }
  6533. if (dY < -180) {
  6534. lnglats[i][0] += 360;
  6535. }
  6536. }
  6537. return lnglats;
  6538. }
  6539. /**
  6540. *
  6541. * 2D坐标转3D视角中心点
  6542. */
  6543. function latlngsTo3DViewCenter(mapState) {
  6544. var RoraTilt = map23DData.view.pitch;
  6545. var gausscenter = coordn_to_gauss([mapState.center.lng, mapState.center.lat], mapState.zoom);
  6546. var h = map23DData.view.distance;
  6547. var heading3D = -map23DData.view.heading;
  6548. if (heading3D > 180) {
  6549. heading3D = heading3D % 180 - 180;
  6550. } else if (heading3D < -180) {
  6551. heading3D = 180 + heading3D % 180;
  6552. }
  6553. if (-90 < heading3D && heading3D <= 0) {
  6554. var RoraHead = Math.abs(map23DData.view.heading / 180 * Math.PI);
  6555. gausscenter[1] = gausscenter[1] - h * Math.sin(RoraTilt) * Math.cos(RoraHead);
  6556. gausscenter[0] = gausscenter[0] + h * Math.sin(RoraTilt) * Math.sin(RoraHead);
  6557. var mapsetlatlng = gaussToGeo(gausscenter[0], gausscenter[1], mapState.center.lng, mapState.zoom);
  6558. } else if (-180 <= heading3D && heading3D <= -90) {
  6559. var RoraHead = Math.abs((map23DData.view.heading + 180) / 180 * Math.PI);
  6560. gausscenter[1] = gausscenter[1] + h * Math.sin(RoraTilt) * Math.cos(RoraHead);
  6561. gausscenter[0] = gausscenter[0] - h * Math.sin(RoraTilt) * Math.sin(RoraHead);
  6562. var mapsetlatlng = gaussToGeo(gausscenter[0], gausscenter[1], mapState.center.lng, mapState.zoom);
  6563. } else if (0 < heading3D && heading3D <= 90) {
  6564. var RoraHead = Math.abs(map23DData.view.heading / 180 * Math.PI);
  6565. gausscenter[1] = gausscenter[1] - h * Math.sin(RoraTilt) * Math.cos(RoraHead);
  6566. gausscenter[0] = gausscenter[0] - h * Math.sin(RoraTilt) * Math.sin(RoraHead);
  6567. var mapsetlatlng = gaussToGeo(gausscenter[0], gausscenter[1], mapState.center.lng, mapState.zoom);
  6568. } else if (90 < heading3D && heading3D <= 180) {
  6569. var RoraHead = Math.abs((180 - map23DData.view.heading) / 180 * Math.PI);
  6570. gausscenter[1] = gausscenter[1] + h * Math.sin(RoraTilt) * Math.cos(RoraHead);
  6571. gausscenter[0] = gausscenter[0] + h * Math.sin(RoraTilt) * Math.sin(RoraHead);
  6572. var mapsetlatlng = gaussToGeo(gausscenter[0], gausscenter[1], mapState.center.lng, mapState.zoom);
  6573. }
  6574. return {
  6575. View3Dlat: mapsetlatlng.latitude,
  6576. View3Dlng: mapsetlatlng.longitude
  6577. }
  6578. }
  6579. /**
  6580. * 北半球高纬度雷达转换
  6581. */
  6582. function northHeightLatLD(coordinates) {
  6583. var positive;
  6584. var isPositive = false;
  6585. for (var i = 0; i < coordinates.length - 2; i++) {
  6586. if (coordinates[i][0] - coordinates[i + 1][0] > 0) {
  6587. if (!isPositive) {
  6588. positive = i;
  6589. isPositive = true;
  6590. }
  6591. coordinates[i + 1][0] = coordinates[positive][0] * 2 - coordinates[i + 1][0];
  6592. }
  6593. }
  6594. return coordinates;
  6595. }
  6596. /**
  6597. * 南半球高纬度雷达经纬度转换
  6598. */
  6599. function southHeightLatLD(coordinates) {
  6600. var negative;
  6601. var isNegative = false;
  6602. for (var i = 0; i < coordinates.length - 2; i++) {
  6603. if (coordinates[i][0] - coordinates[i + 1][0] < 0) {
  6604. if (!isNegative) {
  6605. negative = i;
  6606. isNegative = true;
  6607. }
  6608. coordinates[i + 1][0] = coordinates[negative][0] * 2 - coordinates[i + 1][0];
  6609. }
  6610. }
  6611. return coordinates;
  6612. }
  6613. /**
  6614. * 计算雷达半球最低拉伸高度
  6615. */
  6616. function getLDCircleExtrude(radius) {
  6617. var earthRadius = 6371000; //地球半径
  6618. var tangle = (360 * radius) / (4 * Math.PI * earthRadius);
  6619. tangle = tangle * Math.PI / 180;
  6620. var minExtrude = 2 * earthRadius * Math.sin(tangle) * Math.sin(tangle);
  6621. return minExtrude;
  6622. };
  6623. /**
  6624. * 经纬度转高斯坐标
  6625. */
  6626. function coordn_to_gauss(mapCenter_data, zoom) {
  6627. var mapxy = mapCenter_data;
  6628. var longitude = mapCenter_data[0];
  6629. var latitude = mapCenter_data[1];
  6630. var f = 1.0 / 298.257222101;
  6631. var a = 6378137;
  6632. var ipi = Math.PI / 180;
  6633. var X0 = 500000;
  6634. var Y0 = 0;
  6635. longitude = parseFloat(longitude);
  6636. latitude = parseFloat(latitude);
  6637. if (zoom >= 16) {
  6638. ProjNo = parseInt((longitude) / 3);
  6639. longitude0 = ProjNo * 3;
  6640. } else {
  6641. ProjNo = parseInt((longitude) / 6);
  6642. longitude0 = ProjNo * 6 + 3;
  6643. }
  6644. longitude0 = longitude0 * ipi;
  6645. latitude0 = 0;
  6646. longitude1 = longitude * ipi;
  6647. latitude1 = latitude * ipi;
  6648. e2 = 2 * f - f * f;
  6649. ee = e2 * (1.0 - e2);
  6650. NN = a / Math.sqrt(1.0 - e2 * Math.sin(latitude1) * Math.sin(latitude1));
  6651. T = Math.tan(latitude1) * Math.tan(latitude1);
  6652. C = ee * Math.cos(latitude1) * Math.cos(latitude1);
  6653. A = (longitude1 - longitude0) * Math.cos(latitude1);
  6654. M = a * ((1 - e2 / 4 - 3 * e2 * e2 / 64 - 5 * e2 * e2 * e2 / 256) * latitude1 -
  6655. (3 * e2 / 8 + 3 * e2 * e2 / 32 + 45 * e2 * e2 * e2 / 1024) * Math.sin(2 * latitude1) +
  6656. (15 * e2 * e2 / 256 + 45 * e2 * e2 * e2 / 1024) * Math.sin(4 * latitude1) -
  6657. (35 * e2 * e2 * e2 / 3072) * Math.sin(6 * latitude1));
  6658. xval = NN * (A + (1 - T + C) * A * A * A / 6 + (5 - 18 * T + T * T + 72 * C - 58 * ee) * A * A * A * A * A / 120);
  6659. yval = M + NN * Math.tan(latitude1) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24 +
  6660. (61 - 58 * T + T * T + 600 * C - 330 * ee) * A * A * A * A * A * A / 720);
  6661. xval = xval + X0;
  6662. yval = yval + Y0;
  6663. X = xval;
  6664. X = parseInt((X - 500000) * 0.9996 + 500000);
  6665. Y = yval;
  6666. Y = parseInt(Y * 0.9996);
  6667. return [X, Y];
  6668. }
  6669. /**
  6670. * 高斯坐标转经纬度
  6671. */
  6672. function gaussToGeo(X, Y, lng, zoom) {
  6673. var f = 1.0 / 298.257222101;
  6674. var X0 = 500000;
  6675. var Y0 = 0;
  6676. var iPI = Math.PI / 180;
  6677. var a = 6378137;
  6678. if (zoom >= 16) {
  6679. var ZoneWide = 3;
  6680. var ProjNo = parseInt((lng) / ZoneWide);
  6681. var longitude0 = ProjNo * ZoneWide;
  6682. } else {
  6683. var ZoneWide = 6;
  6684. var ProjNo = parseInt((lng) / ZoneWide);
  6685. var longitude0 = ProjNo * ZoneWide + ZoneWide / 2
  6686. }
  6687. longitude0 = longitude0 * iPI
  6688. X = (X - 500000) / 0.9996 + 500000;
  6689. Y = Y / 0.9996;
  6690. var xval = X - X0;
  6691. var yval = Y - Y0;
  6692. var e2 = 2 * f - f * f;
  6693. var e1 = (1.0 - Math.sqrt(1 - e2)) / (1.0 + Math.sqrt(1 - e2));
  6694. var ee = e2 / (1 - e2);
  6695. var M = yval;
  6696. var u = M / (a * (1 - e2 / 4 - 3 * e2 * e2 / 64 - 5 * e2 * e2 * e2 / 256));
  6697. var fai = u + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.sin(2 * u) +
  6698. (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) * Math.sin(4 * u) +
  6699. (151 * e1 * e1 * e1 / 96) * Math.sin(6 * u) + (1097 * e1 * e1 * e1 * e1 / 512) *
  6700. Math.sin(8 * u);
  6701. var C = ee * Math.cos(fai) * Math.cos(fai);
  6702. var T = Math.tan(fai) * Math.tan(fai);
  6703. var NN = a / Math.sqrt(1.0 - e2 * Math.sin(fai) * Math.sin(fai));
  6704. var R = a * (1 - e2) / Math.sqrt((1 - e2 * Math.sin(fai) * Math.sin(fai)) *
  6705. (1 - e2 * Math.sin(fai) * Math.sin(fai)) *
  6706. (1 - e2 * Math.sin(fai) * Math.sin(fai)));
  6707. var D = xval / NN;
  6708. longitude1 = longitude0 + (D - (1 + 2 * T + C) * D * D * D / 6 +
  6709. (5 - 2 * C + 28 * T - 3 * C * C + 8 * ee + 24 * T * T) * D * D * D * D * D / 120) / Math.cos(fai);
  6710. latitude1 = fai - (NN * Math.tan(fai) / R) * (D * D / 2 -
  6711. (5 + 3 * T + 10 * C - 4 * C * C - 9 * ee) * D * D * D * D / 24 +
  6712. (61 + 90 * T + 298 * C + 45 * T * T - 256 * ee - 3 * C * C) * D * D * D * D * D * D / 720);
  6713. longitude = longitude1 / iPI;
  6714. latitude = latitude1 / iPI;
  6715. return {
  6716. longitude: longitude,
  6717. latitude: latitude
  6718. }
  6719. }
  6720. /**
  6721. * 坐标反转
  6722. * @param {[type]} latlngsAry [description]
  6723. * @return {[type]} [description]
  6724. */
  6725. function latLngsToReverse(latlngsAry) {
  6726. var tempLatlngsAry = JSON.parse(JSON.stringify(latlngsAry));
  6727. if (!_.isArray(tempLatlngsAry[0])) {
  6728. return tempLatlngsAry.reverse();
  6729. } else {
  6730. for (var i = 0, l = tempLatlngsAry.length; i < l; i++) {
  6731. tempLatlngsAry[i] = latLngsToReverse(tempLatlngsAry[i]);
  6732. }
  6733. }
  6734. return tempLatlngsAry;
  6735. }
  6736. function getCentroid(arr) {
  6737. var twoTimesSignedArea = 0;
  6738. var cxTimes6SignedArea = 0;
  6739. var cyTimes6SignedArea = 0;
  6740. var length = arr.length;
  6741. var x = function(i) {
  6742. return arr[i % length][0]
  6743. };
  6744. var y = function(i) {
  6745. return arr[i % length][1]
  6746. };
  6747. for (var i = 0; i < arr.length; i++) {
  6748. var twoSA = x(i) * y(i + 1) - x(i + 1) * y(i);
  6749. twoTimesSignedArea += twoSA;
  6750. cxTimes6SignedArea += (x(i) + x(i + 1)) * twoSA;
  6751. cyTimes6SignedArea += (y(i) + y(i + 1)) * twoSA;
  6752. }
  6753. var sixSignedArea = 3 * twoTimesSignedArea;
  6754. return [cxTimes6SignedArea / sixSignedArea, cyTimes6SignedArea / sixSignedArea];
  6755. }
  6756. window.map23DUtil = {
  6757. latLngsToReverse: latLngsToReverse,
  6758. getCentroid: getCentroid,
  6759. latlngsTo3DViewCenter: latlngsTo3DViewCenter,
  6760. gaussToGeo: gaussToGeo,
  6761. coordn_to_gauss: coordn_to_gauss,
  6762. getLDCircleExtrude: getLDCircleExtrude,
  6763. dateLineLnglatsToLnglats: dateLineLnglatsToLnglats,
  6764. lnglatsToDateLineLnglats: lnglatsToDateLineLnglats,
  6765. northHeightLatLD: northHeightLatLD,
  6766. southHeightLatLD: southHeightLatLD,
  6767. getGeoGatheringPlace: getGeoGatheringPlace,
  6768. get3DPixToLnglat: get3DPixToLnglat
  6769. };
  6770. if (typeof module === 'object' && typeof module.exports === 'object') {
  6771. module.exports = map23DUtil;
  6772. } else if (typeof define === 'function' && define.amd) {
  6773. define(map23DUtil);
  6774. }
  6775. }(window, document));
  6776. ;
  6777. (function (window, document, undefined) {
  6778. window.map23DDefaultData = {
  6779. imageOverlay: {
  6780. from: '23D',
  6781. type: 'imageOverlay',
  6782. guid: null, //图层ID tileLayer23D/tileLayer2D/tileLayer3D
  6783. add2D: false, //2D是否已添加
  6784. add3D: false, //3D是否已添加
  6785. visible2D: false,
  6786. visible3D: false,
  6787. layers: {
  6788. opacity: 1, //2D透明度
  6789. layerBounds: [
  6790. [80, -180],
  6791. [-80, 180]
  6792. ], //左上角 右下角
  6793. imageUrl2D: null, //2D图片地址
  6794. imageUrl3D: null //3D图片服务地址
  6795. }
  6796. },
  6797. layer: {
  6798. from: '23D',
  6799. type: 'tileLayer',
  6800. guid: null, //图层ID tileLayer23D/tileLayer2D/tileLayer3D
  6801. add2D: false, //2D是否已添加
  6802. add3D: false, //3D是否已添加
  6803. visible2D: false,
  6804. visible3D: false,
  6805. layer: {
  6806. url2D: null, //2D瓦片服务地址
  6807. url3D: null, //3D瓦片服务地址
  6808. minZoom: map23DConfig.map23DMinZoom || 1, //23D最大缩放等级
  6809. maxZoom: map23DConfig.map23DMaxZoom || 21, //23D最小缩放等级
  6810. maxNativeZoom: map23DConfig.map2DMaxZoom || 21, //2D最大渲染等级
  6811. tileSubdomains: '0123456789',
  6812. attribution: null, //瓦片附属信息
  6813. opacity: 1, //瓦片透明度
  6814. layerBounds: [
  6815. [90, -180],
  6816. [-90, 180]
  6817. ], //左上角 右下角
  6818. imageType: 'png' //3D瓦片图片类型
  6819. }
  6820. },
  6821. DEMLayer: {
  6822. from: '23D',
  6823. type: 'tileLayer',
  6824. guid: null, //图层ID tileLayer23D/tileLayer2D/tileLayer3D
  6825. add2D: false, //2D是否已添加
  6826. add3D: false, //3D是否已添加
  6827. visible2D: false,
  6828. visible3D: false,
  6829. layer: {
  6830. url2D: null, // 2D瓦片服务地址
  6831. url3D: null, // 3D瓦片服务地址
  6832. DEMFormat: "bil", // bil terrain
  6833. DEMMaxZoom: 9 // DEM最大
  6834. }
  6835. },
  6836. group: {
  6837. from: '23D',
  6838. type: 'group',
  6839. guid: null, //图层组ID group23D/group2D/group3D
  6840. add2D: false, //2D是否已添加
  6841. add3D: false, //3D是否已添加
  6842. visible2D: false,
  6843. visible3D: false,
  6844. clustering: false, //2D是否聚合
  6845. clusterOptions: {
  6846. maxClusterRadius: 120, //多少像素距离的点会聚合 默认小于120像素内的点会聚合
  6847. polygonOptions: {
  6848. weight: 1,
  6849. opacity: 0.5
  6850. }, //聚合范围面样式
  6851. showCoverageOnHover: true, //是否显示聚合范围
  6852. disableClusteringAtZoom: null, //设置到达指定缩放等级后禁用聚合
  6853. } //2D聚合参数
  6854. },
  6855. marker: {
  6856. from: '23D',
  6857. type: 'marker',
  6858. guid: null, //标记ID marker23D/marker2D/marker3D
  6859. add2D: false,
  6860. add3D: false,
  6861. visible2D: false,
  6862. visible3D: false,
  6863. groupId: null,
  6864. animate: false,
  6865. vectorMarker: false,
  6866. geojson: {
  6867. "type": "Feature",
  6868. "properties": {
  6869. title: null,
  6870. titleColor: '#FFFFFF',
  6871. titleFontSize: 12,
  6872. baseSize: null, //矢量图片基础大小 控制地图缩放时显示
  6873. baseZoom: null, //矢量图片基础缩放级别
  6874. iconUrl: null,
  6875. icon3DUrl: null,
  6876. iconSize: [25, 41],
  6877. iconAnchor: [12, 41],
  6878. popupAnchor: [1, -34],
  6879. popupContent: null,
  6880. altitude: 0,
  6881. altitudeMode: 0,
  6882. iconRorate: 0,
  6883. iconScale: 10,
  6884. fontIcon: null,
  6885. fontSize: null,
  6886. fontColor: null,
  6887. fontWeight: null,
  6888. distanceDisplayCondition: [0, 100000000]
  6889. },
  6890. "geometry": {
  6891. "type": "Point",
  6892. "coordinates": [0, 0]
  6893. }
  6894. }
  6895. },
  6896. polyline: {
  6897. from: '23D',
  6898. type: 'polyline',
  6899. guid: null,
  6900. add2D: false,
  6901. add3D: false,
  6902. visible2D: false,
  6903. visible3D: false,
  6904. groupId: null,
  6905. linetype: 'line',
  6906. geojson: {
  6907. "type": "Feature",
  6908. "properties": {
  6909. title: null,
  6910. color: '#0033ff',
  6911. weight: 1,
  6912. opacity: 1,
  6913. popupContent: null,
  6914. dashArray: null,
  6915. lineType: 0, //3D用 Solid:0/Dash:1/Dot:2/DashDot:3/DashDotDot:4
  6916. extrude: 0, //拉伸高度
  6917. altitude: 0, //海拔高度
  6918. altitudeMode: 1
  6919. },
  6920. "geometry": {
  6921. "type": "LineString",
  6922. "coordinates": [
  6923. [0, 0]
  6924. ]
  6925. }
  6926. }
  6927. },
  6928. polygon: {
  6929. from: '23D',
  6930. type: 'polygon',
  6931. guid: null,
  6932. add2D: false,
  6933. add3D: false,
  6934. visible2D: false,
  6935. visible3D: false,
  6936. groupId: null,
  6937. polygontype: 'polygon',
  6938. geojson: {
  6939. "type": "Feature",
  6940. "properties": {
  6941. title: null,
  6942. color: '#ff0000',
  6943. weight: 1, //cesium部分外边框宽度固定为1
  6944. fillColor: '#ff6600',
  6945. opacity: 1,
  6946. fillOpacity: 1,
  6947. popupContent: null,
  6948. extrude: 0,
  6949. altitude: 0,
  6950. altitudeMode: 1,
  6951. extrudedHeight: 0
  6952. },
  6953. "geometry": {
  6954. "type": "Polygon",
  6955. "coordinates": [
  6956. [0, 0]
  6957. ]
  6958. }
  6959. }
  6960. },
  6961. circle: {
  6962. from: '23D',
  6963. type: 'circle',
  6964. guid: null,
  6965. add2D: false,
  6966. add3D: false,
  6967. visible2D: false,
  6968. visible3D: false,
  6969. groupId: null,
  6970. geojson: {
  6971. "type": "Feature",
  6972. "properties": {
  6973. title: null,
  6974. radius: 0, //半径 米
  6975. color: '#ff0000',
  6976. weight: 1, //cesium部分外边框宽度固定为1
  6977. opacity: 1,
  6978. fillColor: '#ff6600',
  6979. fillOpacity: 1,
  6980. popupContent: null,
  6981. extrude: 0,
  6982. altitude: 0,
  6983. altitudeMode: 1
  6984. },
  6985. "geometry": {
  6986. "type": "Circle",
  6987. "coordinates": [0, 0]
  6988. }
  6989. }
  6990. },
  6991. circleMarker: {
  6992. from: '23D',
  6993. type: 'circleMarker',
  6994. guid: null,
  6995. add2D: false,
  6996. add3D: false,
  6997. visible2D: false,
  6998. visible3D: false,
  6999. groupId: null,
  7000. geojson: {
  7001. "type": "Feature",
  7002. "properties": {
  7003. title: null,
  7004. radius: 0, //半径 米
  7005. color: '#ff0000',
  7006. weight: 1,
  7007. fillColor: '#ff6600',
  7008. opacity: 1,
  7009. fillOpacity: 1,
  7010. popupContent: null,
  7011. stroke: false,
  7012. extrude: 0,
  7013. altitude: 0,
  7014. altitudeMode: 1
  7015. },
  7016. "geometry": {
  7017. "type": "CircleMarker",
  7018. "coordinates": [0, 0]
  7019. }
  7020. }
  7021. },
  7022. model: {
  7023. from: '23D',
  7024. type: 'model',
  7025. guid: null,
  7026. groupId: null,
  7027. add2D: false,
  7028. add3D: false,
  7029. visible2D: false,
  7030. visible3D: false,
  7031. geojson: {
  7032. "type": "Feature",
  7033. "properties": {
  7034. title: null,
  7035. popupContent: null,
  7036. url: null,
  7037. timeLine: [0],
  7038. anination: false,
  7039. altitudeMode: 1, //高度模式 0否1是
  7040. altitude: [0], //高度
  7041. scale: 1,
  7042. path: true,
  7043. pathColor: '#ffffff',
  7044. pathWidth: 10,
  7045. },
  7046. "geometry": {
  7047. "type": "Model",
  7048. "coordinates": [
  7049. [0, 0] ////经度,纬度(时间戳为秒级, 仅在anination为true时与时间戳)
  7050. ],
  7051. }
  7052. },
  7053. },
  7054. radar: {
  7055. from: '23D',
  7056. type: 'radar',
  7057. center: {
  7058. lat: 39,
  7059. lng: 116
  7060. },
  7061. radius: 10000, //雷达半径
  7062. circleTangle: 10, //雷达高度密度1,5,10·····90
  7063. circlePointDensity: 5, //雷达圆周密度1,5,10·····90
  7064. // height: 1000, //中心点高度
  7065. properties: {
  7066. color: '#00ff00',
  7067. weight: 1,
  7068. opacity: 1,
  7069. },
  7070. display: {
  7071. show2D: true,
  7072. show3D: true
  7073. }
  7074. }
  7075. }
  7076. window.map23DData = {
  7077. mouseIn: '2D', //2D or 3D
  7078. display: {
  7079. map2D: false,
  7080. map3D: false
  7081. },
  7082. synch: false, //二三维是否同步 同步则同时加载,不同步则只加载一部分
  7083. view: {
  7084. center: {
  7085. lat: 39,
  7086. lng: 116
  7087. },
  7088. zoom: 12,
  7089. heading: 0, //摄像机平面角度 正北为0
  7090. pitch: 90, //摄像机倾斜角
  7091. distance: 0 //摄像机距地面高度
  7092. },
  7093. layers: {},
  7094. DEMLayers: {},
  7095. imageOverlays: {},
  7096. groups: {},
  7097. markers: {},
  7098. polylines: {},
  7099. circles: {},
  7100. circleMarkers: {},
  7101. polygons: {},
  7102. models: {},
  7103. timeLineData: {},
  7104. radar: {}
  7105. };
  7106. if (typeof module === 'object' && typeof module.exports === 'object') {
  7107. module.exports = map23DData;
  7108. } else if (typeof define === 'function' && define.amd) {
  7109. define(map23DData);
  7110. }
  7111. }(window, document));
  7112. ;
  7113. (function (window, document, undefined) {
  7114. window.map23DControl = {};
  7115. if (typeof module === 'object' && typeof module.exports === 'object') {
  7116. module.exports = map23DControl;
  7117. } else if (typeof define === 'function' && define.amd) {
  7118. define(map23DControl);
  7119. }
  7120. map23DControl.init = function (options) {
  7121. var _this = this;
  7122. _.merge(map23DData, options);
  7123. this.mapWrap = document.getElementById(map23DData.mapWrapId);
  7124. this.map2DWrap = document.createElement('div');
  7125. this.map2DWrap.id = 'map2DWrap';
  7126. this.mapWrap.appendChild(this.map2DWrap);
  7127. this.map3DWrap = document.createElement('div');
  7128. this.map3DWrap.id = 'map3DWrap';
  7129. this.mapWrap.appendChild(this.map3DWrap);
  7130. if (map23DData.synch) {
  7131. map2DViewer.init();
  7132. map3DViewer.init();
  7133. if (map23DData.display.map2D == true && map23DData.display.map3D == false) {
  7134. this.mapWrap.className = 'show2DOnly';
  7135. } else if (map23DData.display.map3D == true && map23DData.display.map2D == false) {
  7136. this.mapWrap.className = 'show3DOnly';
  7137. }
  7138. } else {
  7139. if (map23DData.display.map2D == true && map23DData.display.map3D == false) {
  7140. this.mapWrap.className = 'show2DOnly';
  7141. map2DViewer.init();
  7142. } else if (map23DData.display.map3D == true && map23DData.display.map2D == false) {
  7143. this.mapWrap.className = 'show3DOnly';
  7144. map3DViewer.init();
  7145. } else if (map23DData.display.map2D == false && map23DData.display.map3D == false) {
  7146. } else {
  7147. map2DViewer.init();
  7148. map3DViewer.init();
  7149. }
  7150. }
  7151. _this.map2DWrap.onmouseover = function (e) {
  7152. map23DData.mouseIn = '2D';
  7153. _this.map2DWrap.focus();
  7154. }
  7155. _this.map3DWrap.onmouseover = function (e) {
  7156. map23DData.mouseIn = '3D';
  7157. if (map3DViewer.inited) {
  7158. _this.map3DWrap.focus();
  7159. }
  7160. }
  7161. }
  7162. map23DControl.show2D = function () {
  7163. this.mapWrap = document.getElementById(map23DData.mapWrapId);
  7164. this.mapWrap.className = 'show2DOnly';
  7165. _.merge(map23DData, {
  7166. display: {
  7167. map2D: true,
  7168. map3D: false
  7169. }
  7170. });
  7171. PubSub.publish('map23D.show2D', {
  7172. from: '23D'
  7173. });
  7174. }
  7175. map23DControl.show3D = function () {
  7176. this.mapWrap = document.getElementById(map23DData.mapWrapId);
  7177. this.mapWrap.className = 'show3DOnly';
  7178. _.merge(map23DData, {
  7179. display: {
  7180. map2D: false,
  7181. map3D: true
  7182. }
  7183. });
  7184. PubSub.publish('map23D.show3D', {
  7185. from: '23D'
  7186. });
  7187. }
  7188. map23DControl.show23D = function () {
  7189. this.mapWrap = document.getElementById(map23DData.mapWrapId);
  7190. this.mapWrap.className = '';
  7191. _.merge(map23DData, {
  7192. display: {
  7193. map2D: true,
  7194. map3D: true
  7195. }
  7196. });
  7197. PubSub.publish('map23D.show23D', {
  7198. from: '23D'
  7199. })
  7200. }
  7201. /**
  7202. * 生成随机GUID
  7203. * @param {[type]} options [description]
  7204. * @return {[type]} [description]
  7205. */
  7206. map23DControl.buildGuid = function (options) {
  7207. var text = "";
  7208. var mar = options || 'default';
  7209. var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  7210. for (var i = 0; i < 18; i++) text += possible.charAt(Math.floor(Math.random() * possible.length));
  7211. return mar + '_' + (new Date()).getTime().toString() + text;
  7212. }
  7213. map23DControl.setView = function (options) {
  7214. _.merge(map23DData.view, options);
  7215. PubSub.publish('map23D.setView', {
  7216. from: '23D'
  7217. })
  7218. }
  7219. map23DControl.flyTo = function (options, callback) {
  7220. _.merge(map23DData.view, options);
  7221. PubSub.publish('map23D.flyTo', {
  7222. from: '23D',
  7223. callback: null,
  7224. })
  7225. }
  7226. //高斯转经纬度
  7227. map23DControl.coordn_to_gauss = function (mapCenter_data, zoom, curZoingNum) {
  7228. var mapxy = mapCenter_data;
  7229. var longitude = mapCenter_data[0];
  7230. var latitude = mapCenter_data[1];
  7231. var f = 1.0 / 298.257222101;
  7232. var a = 6378137;
  7233. var ipi = Math.PI / 180;
  7234. var X0 = 500000;
  7235. var Y0 = 0;
  7236. longitude = parseFloat(longitude);
  7237. latitude = parseFloat(latitude);
  7238. if (curZoingNum == 6) {
  7239. ProjNo = parseInt((longitude) / 6);
  7240. longitude0 = ProjNo * 6 + 3;
  7241. } else if (curZoingNum == 3) {
  7242. ProjNo = parseInt((longitude) / 3);
  7243. longitude0 = ProjNo * 3;
  7244. } else {
  7245. if (zoom >= 16) {
  7246. ProjNo = parseInt((longitude) / 3);
  7247. longitude0 = ProjNo * 3;
  7248. } else {
  7249. ProjNo = parseInt((longitude) / 6);
  7250. longitude0 = ProjNo * 6 + 3;
  7251. }
  7252. }
  7253. longitude0 = longitude0 * ipi;
  7254. latitude0 = 0;
  7255. longitude1 = longitude * ipi;
  7256. latitude1 = latitude * ipi;
  7257. e2 = 2 * f - f * f;
  7258. ee = e2 * (1.0 - e2);
  7259. NN = a / Math.sqrt(1.0 - e2 * Math.sin(latitude1) * Math.sin(latitude1));
  7260. T = Math.tan(latitude1) * Math.tan(latitude1);
  7261. C = ee * Math.cos(latitude1) * Math.cos(latitude1);
  7262. A = (longitude1 - longitude0) * Math.cos(latitude1);
  7263. M = a * ((1 - e2 / 4 - 3 * e2 * e2 / 64 - 5 * e2 * e2 * e2 / 256) * latitude1 -
  7264. (3 * e2 / 8 + 3 * e2 * e2 / 32 + 45 * e2 * e2 * e2 / 1024) * Math.sin(2 * latitude1) +
  7265. (15 * e2 * e2 / 256 + 45 * e2 * e2 * e2 / 1024) * Math.sin(4 * latitude1) -
  7266. (35 * e2 * e2 * e2 / 3072) * Math.sin(6 * latitude1));
  7267. xval = NN * (A + (1 - T + C) * A * A * A / 6 + (5 - 18 * T + T * T + 72 * C - 58 * ee) * A * A * A * A * A / 120);
  7268. yval = M + NN * Math.tan(latitude1) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24 +
  7269. (61 - 58 * T + T * T + 600 * C - 330 * ee) * A * A * A * A * A * A / 720);
  7270. xval = xval + X0;
  7271. yval = yval + Y0;
  7272. X = xval;
  7273. X = parseInt((X - 500000) * 0.9996 + 500000);
  7274. Y = yval;
  7275. Y = parseInt(Y * 0.9996);
  7276. return [X, Y];
  7277. }
  7278. //经纬度转高斯
  7279. map23DControl.gaussToGeo = function (X, Y, lng, zoom) {
  7280. var f = 1.0 / 298.257222101;
  7281. var X0 = 500000;
  7282. var Y0 = 0;
  7283. var iPI = Math.PI / 180;
  7284. var a = 6378137;
  7285. if (zoom >= 16) {
  7286. var ZoneWide = 3;
  7287. var ProjNo = parseInt((lng) / ZoneWide);
  7288. var longitude0 = ProjNo * ZoneWide;
  7289. } else {
  7290. var ZoneWide = 6;
  7291. var ProjNo = parseInt((lng) / ZoneWide);
  7292. var longitude0 = ProjNo * ZoneWide + ZoneWide / 2
  7293. }
  7294. longitude0 = longitude0 * iPI
  7295. X = (X - 500000) / 0.9996 + 500000;
  7296. Y = Y / 0.9996;
  7297. var xval = X - X0;
  7298. var yval = Y - Y0;
  7299. var e2 = 2 * f - f * f;
  7300. var e1 = (1.0 - Math.sqrt(1 - e2)) / (1.0 + Math.sqrt(1 - e2));
  7301. var ee = e2 / (1 - e2);
  7302. var M = yval;
  7303. var u = M / (a * (1 - e2 / 4 - 3 * e2 * e2 / 64 - 5 * e2 * e2 * e2 / 256));
  7304. var fai = u + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.sin(2 * u) +
  7305. (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) * Math.sin(4 * u) +
  7306. (151 * e1 * e1 * e1 / 96) * Math.sin(6 * u) + (1097 * e1 * e1 * e1 * e1 / 512) *
  7307. Math.sin(8 * u);
  7308. var C = ee * Math.cos(fai) * Math.cos(fai);
  7309. var T = Math.tan(fai) * Math.tan(fai);
  7310. var NN = a / Math.sqrt(1.0 - e2 * Math.sin(fai) * Math.sin(fai));
  7311. var R = a * (1 - e2) / Math.sqrt((1 - e2 * Math.sin(fai) * Math.sin(fai)) *
  7312. (1 - e2 * Math.sin(fai) * Math.sin(fai)) *
  7313. (1 - e2 * Math.sin(fai) * Math.sin(fai)));
  7314. var D = xval / NN;
  7315. longitude1 = longitude0 + (D - (1 + 2 * T + C) * D * D * D / 6 +
  7316. (5 - 2 * C + 28 * T - 3 * C * C + 8 * ee + 24 * T * T) * D * D * D * D * D / 120) / Math.cos(fai);
  7317. latitude1 = fai - (NN * Math.tan(fai) / R) * (D * D / 2 -
  7318. (5 + 3 * T + 10 * C - 4 * C * C - 9 * ee) * D * D * D * D / 24 +
  7319. (61 + 90 * T + 298 * C + 45 * T * T - 256 * ee - 3 * C * C) * D * D * D * D * D * D / 720);
  7320. longitude = longitude1 / iPI;
  7321. latitude = latitude1 / iPI;
  7322. return {
  7323. longitude: longitude,
  7324. latitude: latitude
  7325. }
  7326. }
  7327. //墨卡托转经纬度
  7328. map23DControl.mercatorToLatlng = function (mercator) {
  7329. var lonLat = {};
  7330. var x = mercator.X / 20037508.34 * 180;
  7331. var y = mercator.Y / 20037508.34 * 180;
  7332. y = 180 / Math.PI * (2 * Math.atan(Math.exp(y * Math.PI / 180)) - Math.PI / 2);
  7333. lonLat.lng = x;
  7334. lonLat.lat = y;
  7335. return lonLat;
  7336. }
  7337. /**
  7338. * 经纬度转墨卡托
  7339. */
  7340. map23DControl.transformMercator = function (lonLat) {
  7341. var mercator = {};
  7342. var x = lonLat.x * 20037508.34 / 180;
  7343. var y = Math.log(Math.tan((90 + lonLat.y) * Math.PI / 360)) / (Math.PI / 180);
  7344. y = y * 20037508.34 / 180;
  7345. mercator.x = x;
  7346. mercator.y = y;
  7347. return mercator;
  7348. };
  7349. //经纬度十进制转六进制
  7350. map23DControl.formatDegree = function (value) {
  7351. value = Math.abs(value);
  7352. var v1 = Math.floor(value); //度
  7353. var v2 = Math.floor((value - v1) * 60); //分
  7354. var v3 = Math.round((value - v1) * 3600 % 60); //秒
  7355. return v1 + '°' + v2 + '\'' + v3 + '"';
  7356. }
  7357. //经纬度六进制转十进制
  7358. map23DControl.DegreeConvertBack = function (value) {
  7359. var du = value.split("°")[0];
  7360. var fen = value.split("°")[1].split("'")[0];
  7361. var miao = value.split("°")[1].split("'")[1].split('"')[0];
  7362. return Math.abs(du) + (Math.abs(fen) / 60 + Math.abs(miao) / 3600);
  7363. }
  7364. //颜色16进制转10进制
  7365. map23DControl.SLTransToS = function (color) {
  7366. color = color.split("#");
  7367. colorS = color[1].slice(0, 2);
  7368. colorS = parseInt("0x" + colorS);
  7369. colorF = color[1].slice(2, 4);
  7370. colorF = parseInt("0x" + colorF);
  7371. colorT = color[1].slice(4);
  7372. colorT = parseInt("0x" + colorT);
  7373. return [colorS, colorF, colorT, 255]
  7374. }
  7375. //卫星增删改
  7376. map23DControl.satelliteModel = function (options) {
  7377. switch (options.action) {
  7378. case 'add':
  7379. return addSatelliteModel(options.satellite);
  7380. break;
  7381. case 'update':
  7382. return updateSatelliteModel(options);
  7383. break;
  7384. case 'remove':
  7385. return removeSatelliteModel(options);
  7386. break;
  7387. }
  7388. }
  7389. /**
  7390. * 添加卫星单元
  7391. * 经纬度、高度、角度
  7392. */
  7393. addSatelliteModel = function (options, atelliteTraData) {
  7394. var satelliteId = {
  7395. polygonId: null,
  7396. modelId: null,
  7397. polylineId: [],
  7398. GDId: null,
  7399. markerId: null
  7400. };
  7401. var cahlatlng = options.breadth / 111000 / 2;
  7402. var lng = options.lng;
  7403. var lat = options.lat;
  7404. var altitule = options.altitude;
  7405. var angle = options.angle - 90;
  7406. var weixingC = [lng, lat];
  7407. //添加卫星2D点
  7408. var markerId = map2DViewer.marker({
  7409. action: 'add',
  7410. geojson: {
  7411. "properties": {
  7412. title: options.properties.WXtitle,
  7413. iconUrl: options.model2DUrl, //当有fontIcon的时候 iconUrl无效
  7414. iconSize: options.properties.iconSize,
  7415. iconAnchor: options.properties.iconAnchor,
  7416. popupAnchor: options.properties.popupAnchor,
  7417. popupContent: options.properties.popupContent,
  7418. iconRorate: angle + 180,
  7419. },
  7420. "geometry": {
  7421. "coordinates": weixingC
  7422. }
  7423. }
  7424. })
  7425. satelliteId.markerId = markerId;
  7426. //添加卫星轨道
  7427. //添加23D线
  7428. var GDguid = map23DControl.polyline({
  7429. action: 'add',
  7430. geojson: {
  7431. "properties": {
  7432. title: options.properties.GDtitle,
  7433. color: options.properties.GDColor,
  7434. weight: options.properties.GDWeight,
  7435. opacity: options.properties.GDopacity,
  7436. extrude: 0, //拉伸高度
  7437. altitude: options.satelliteTraData.height, //点海拔高度
  7438. altitudeMode: 1 //海拔模式
  7439. },
  7440. "geometry": {
  7441. "coordinates": map23DUtil.lnglatsToDateLineLnglats(options.satelliteTraData.coordinates)
  7442. }
  7443. }
  7444. })
  7445. satelliteId.GDId = GDguid;
  7446. var model = map3DViewer.model({
  7447. action: 'add',
  7448. geojson: {
  7449. "properties": {
  7450. title: options.properties.WXtitle,
  7451. url: options.modelUrl,
  7452. altitude: altitule, //高度
  7453. altitudeMode: 1, //高度模式
  7454. scale: options.properties.scale, //放大倍数
  7455. rotate: [0, 0, angle], //前倾角度,左右摆角,平面转角
  7456. visible: true
  7457. },
  7458. "geometry": {
  7459. "coordinates": weixingC //纬度,经度
  7460. }
  7461. }
  7462. })
  7463. satelliteId.modelId = model;
  7464. //画面
  7465. var polygonCoors = map2DViewer.PointToPolygon([lng + cahlatlng, lat + cahlatlng], [lng - cahlatlng, lat - cahlatlng]);
  7466. var modelpolygonguid = map23DControl.polygon({
  7467. action: 'add',
  7468. geojson: {
  7469. "properties": {
  7470. title: options.properties.breadthPloygonTitle,
  7471. color: options.properties.breadthColor,
  7472. weight: options.properties.breadthWeight,
  7473. fillColor: options.properties.breadthFillColor,
  7474. opacity: options.properties.breadthOpacity,
  7475. fillOpacity: options.properties.breadthFillOpacity,
  7476. extrude: 0, //拉伸高度
  7477. altitude: [16000, 11000, 8000, 4000, 5000, 9000, 16000], //点海拔高度
  7478. altitudeMode: 0 //海拔模式
  7479. },
  7480. "geometry": {
  7481. "type": "Polygon",
  7482. "coordinates": [
  7483. polygonCoors.coordinates
  7484. ]
  7485. }
  7486. }
  7487. })
  7488. satelliteId.polygonId = modelpolygonguid;
  7489. for (var i = 0; i < polygonCoors.coordinates.length; i++) {
  7490. var guid = map23DControl.polyline({
  7491. action: 'add',
  7492. geojson: {
  7493. "properties": {
  7494. title: options.properties.lineTitle,
  7495. color: options.properties.lineColor,
  7496. weight: options.properties.lineWeigth,
  7497. opacity: options.properties.lineOpacity,
  7498. altitude: [altitule, 0], //点海拔高度
  7499. altitudeMode: 1 //海拔模式
  7500. },
  7501. "geometry": {
  7502. "coordinates": [
  7503. weixingC,
  7504. polygonCoors.coordinates[i]
  7505. ]
  7506. }
  7507. }
  7508. })
  7509. satelliteId.polylineId.push(guid);
  7510. }
  7511. return satelliteId;
  7512. }
  7513. /**
  7514. * 删除卫星单元
  7515. * 卫星单元GUID
  7516. */
  7517. removeSatelliteModel = function (options) {
  7518. //删除卫星轨道
  7519. map23DControl.polyline({
  7520. action: 'remove',
  7521. guid: options.satelliteId.GDId
  7522. })
  7523. //删除卫星模型
  7524. map3DViewer.model({
  7525. action: 'remove',
  7526. guid: options.satelliteId.modelId
  7527. })
  7528. //删除卫星扫描面
  7529. map23DControl.polygon({
  7530. action: 'remove',
  7531. guid: options.satelliteId.polygonId
  7532. })
  7533. //删除2D卫星点
  7534. map2DViewer.marker({
  7535. action: 'remove',
  7536. guid: options.satelliteId.markerId
  7537. })
  7538. //删除卫星扫描四根线
  7539. for (var i = 0; i < options.satelliteId.polylineId.length; i++) {
  7540. map23DControl.polyline({
  7541. action: 'remove',
  7542. guid: options.satelliteId.polylineId[i]
  7543. })
  7544. }
  7545. }
  7546. /**
  7547. * 更新卫星单元
  7548. */
  7549. updateSatelliteModel = function (options) {
  7550. var cahlatlng = options.satellite.breadth / 111000 / 2;
  7551. var lng = options.satellite.lng;
  7552. var lat = options.satellite.lat;
  7553. var altitule = options.satellite.altitude;
  7554. var angle = options.satellite.angle - 90;
  7555. var weixingC = [lng, lat];
  7556. //更新2D卫星点
  7557. var oldmarkerData = map23DData.markers[options.satelliteId.markerId];
  7558. var judgewx = weixingC[0] - oldmarkerData.geojson.geometry.coordinates[0];
  7559. if (judgewx < 0) {
  7560. var curweixingC = [weixingC[0] + 360, weixingC[1]];
  7561. } else {
  7562. var curweixingC = weixingC;
  7563. }
  7564. map2DViewer.marker({
  7565. action: 'update',
  7566. guid: options.satelliteId.markerId,
  7567. geojson: {
  7568. "properties": {
  7569. title: options.satellite.properties.WXtitle,
  7570. iconUrl: options.satellite.model2DUrl, //当有fontIcon的时候 iconUrl无效
  7571. iconSize: options.satellite.properties.iconSize,
  7572. iconAnchor: options.satellite.properties.iconAnchor,
  7573. popupAnchor: options.satellite.properties.popupAnchor,
  7574. popupContent: options.satellite.properties.popupContent,
  7575. iconRorate: angle + 180,
  7576. },
  7577. "geometry": {
  7578. "coordinates": curweixingC
  7579. }
  7580. }
  7581. })
  7582. //更新卫星轨道
  7583. if (options.satellite.updata2DOrbit) {
  7584. map23DControl.polyline({
  7585. action: 'update',
  7586. guid: options.satelliteId.GDId,
  7587. geojson: {
  7588. "properties": {
  7589. title: options.satellite.properties.GDtitle,
  7590. color: options.satellite.properties.GDColor,
  7591. weight: options.satellite.properties.GDWeight,
  7592. opacity: options.satellite.properties.GDopacity,
  7593. extrude: 0, //拉伸高度
  7594. altitude: options.satellite.satelliteTraData.height, //点海拔高度
  7595. altitudeMode: 1 //海拔模式
  7596. },
  7597. "geometry": {
  7598. "coordinates": map23DUtil.lnglatsToDateLineLnglats(options.satellite.satelliteTraData.coordinates)
  7599. }
  7600. }
  7601. })
  7602. } else {
  7603. map3DViewer.polyline({
  7604. action: 'update',
  7605. guid: options.satelliteId.GDId,
  7606. geojson: {
  7607. "properties": {
  7608. title: options.satellite.properties.GDtitle,
  7609. color: options.satellite.properties.GDColor,
  7610. weight: options.satellite.properties.GDWeight,
  7611. opacity: options.satellite.properties.GDopacity,
  7612. extrude: 0, //拉伸高度
  7613. altitude: options.satellite.satelliteTraData.height, //点海拔高度
  7614. altitudeMode: 1 //海拔模式
  7615. },
  7616. "geometry": {
  7617. "coordinates": map23DUtil.lnglatsToDateLineLnglats(options.satellite.satelliteTraData.coordinates)
  7618. }
  7619. }
  7620. })
  7621. }
  7622. //更新卫星模型
  7623. map3DViewer.model({
  7624. action: 'update',
  7625. guid: options.satelliteId.modelId,
  7626. geojson: {
  7627. "properties": {
  7628. title: options.satellite.properties.WXtitle,
  7629. url: options.satellite.modelUrl,
  7630. altitude: altitule, //高度
  7631. altitudeMode: 1, //高度模式
  7632. scale: options.satellite.properties.scale, //放大倍数
  7633. rotate: [0, 0, angle], //前倾角度,左右摆角,平面转角
  7634. visible: true
  7635. },
  7636. "geometry": {
  7637. "coordinates": weixingC //纬度,经度
  7638. }
  7639. }
  7640. })
  7641. //更新卫星扫描面
  7642. var polygonCoors = map2DViewer.PointToPolygon([lng + cahlatlng, lat + cahlatlng], [lng - cahlatlng, lat - cahlatlng]);
  7643. var curcoordinates = [];
  7644. if (judgewx < 0) {
  7645. for (var i = 0; i < polygonCoors.coordinates.length; i++) {
  7646. curcoordinates.push([polygonCoors.coordinates[i][0] + 360, polygonCoors.coordinates[i][1]]);
  7647. }
  7648. } else {
  7649. curcoordinates = polygonCoors.coordinates;
  7650. }
  7651. if (map23DData.display.map2D) {
  7652. map2DViewer.polygon({
  7653. action: 'update',
  7654. guid: options.satelliteId.polygonId,
  7655. geojson: {
  7656. "properties": {
  7657. title: options.satellite.properties.breadthPloygonTitle,
  7658. color: options.satellite.properties.breadthColor,
  7659. weight: options.satellite.properties.breadthWeight,
  7660. fillColor: options.satellite.properties.breadthFillColor,
  7661. opacity: options.satellite.properties.breadthOpacity,
  7662. fillOpacity: options.satellite.properties.breadthFillOpacity,
  7663. extrude: 0, //拉伸高度
  7664. altitude: [16000, 11000, 8000, 4000, 5000, 9000, 16000], //点海拔高度
  7665. altitudeMode: 0 //海拔模式
  7666. },
  7667. "geometry": {
  7668. "type": "Polygon",
  7669. "coordinates": [
  7670. curcoordinates
  7671. ]
  7672. }
  7673. }
  7674. })
  7675. } else if (map23DData.display.map3D) {
  7676. map3DViewer.polygon({
  7677. action: 'update',
  7678. guid: options.satelliteId.polygonId,
  7679. geojson: {
  7680. "properties": {
  7681. title: options.satellite.properties.breadthPloygonTitle,
  7682. color: options.satellite.properties.breadthColor,
  7683. weight: options.satellite.properties.breadthWeight,
  7684. fillColor: options.satellite.properties.breadthFillColor,
  7685. opacity: options.satellite.properties.breadthOpacity,
  7686. fillOpacity: options.satellite.properties.breadthFillOpacity,
  7687. extrude: 0, //拉伸高度
  7688. altitude: [16000, 11000, 8000, 4000, 5000, 9000, 16000], //点海拔高度
  7689. altitudeMode: 0 //海拔模式
  7690. },
  7691. "geometry": {
  7692. "type": "Polygon",
  7693. "coordinates": [
  7694. polygonCoors.coordinates
  7695. ]
  7696. }
  7697. }
  7698. })
  7699. }
  7700. //更新卫星扫描四根线
  7701. for (var i = 0; i < polygonCoors.coordinates.length; i++) {
  7702. if (map23DData.display.map2D) {
  7703. map2DViewer.polyline({
  7704. action: 'update',
  7705. guid: options.satelliteId.polylineId[i],
  7706. geojson: {
  7707. "properties": {
  7708. title: options.satellite.properties.lineTitle,
  7709. color: options.satellite.properties.lineColor,
  7710. weight: options.satellite.properties.lineWeigth,
  7711. opacity: options.satellite.properties.lineOpacity,
  7712. altitude: [altitule, 0], //点海拔高度
  7713. altitudeMode: 1 //海拔模式
  7714. },
  7715. "geometry": {
  7716. "coordinates": [
  7717. curweixingC,
  7718. curcoordinates[i]
  7719. ]
  7720. }
  7721. }
  7722. })
  7723. } else if (map23DData.display.map3D) {
  7724. map3DViewer.polyline({
  7725. action: 'update',
  7726. guid: options.satelliteId.polylineId[i],
  7727. geojson: {
  7728. "properties": {
  7729. title: options.satellite.properties.lineTitle,
  7730. color: options.satellite.properties.lineColor,
  7731. weight: options.satellite.properties.lineWeigth,
  7732. opacity: options.satellite.properties.lineOpacity,
  7733. altitude: [altitule, 0], //点海拔高度
  7734. altitudeMode: 1 //海拔模式
  7735. },
  7736. "geometry": {
  7737. "coordinates": [
  7738. curweixingC,
  7739. polygonCoors.coordinates[i]
  7740. ]
  7741. }
  7742. }
  7743. })
  7744. }
  7745. }
  7746. }
  7747. }(window, document));
  7748. ;
  7749. (function (window, document, undefined) {
  7750. window.map2DViewer = {
  7751. inited: false,
  7752. markers: {},
  7753. layers: {},
  7754. polylines: {},
  7755. polygons: {},
  7756. circles: {},
  7757. circleMarkers: {},
  7758. models: {},
  7759. groups: {},
  7760. hide2D: false,
  7761. syncTimeer: null,
  7762. imageOverlays: {}
  7763. };
  7764. if (typeof module === 'object' && typeof module.exports === 'object') {
  7765. module.exports = map2DViewer;
  7766. } else if (typeof define === 'function' && define.amd) {
  7767. define(map2DViewer);
  7768. }
  7769. PubSub.subscribe('map23D.show23D', function (msg, options) {
  7770. if (options.from == '23D' && map23DData.display.map2D) {
  7771. if (map2DViewer.inited) {
  7772. map2DViewer.map.invalidateSize();
  7773. } else {
  7774. map2DViewer.init();
  7775. }
  7776. map2DViewer.hide2D = false;
  7777. }
  7778. });
  7779. PubSub.subscribe('map23D.show2D', function (msg, options) {
  7780. if (options.from == '23D' && map23DData.display.map2D) {
  7781. if (map2DViewer.inited) {
  7782. map2DViewer.map.invalidateSize();
  7783. map2DViewer.map.setView([map23DData.view.center.lat, map23DData.view.center.lng], map23DData.view.zoom);
  7784. } else {
  7785. map2DViewer.init();
  7786. //如果从隐藏到显示,添加所有因show3D隐藏的地图元素,添加同步
  7787. }
  7788. map2DViewer.hide2D = false;
  7789. }
  7790. });
  7791. PubSub.subscribe('map23D.show3D', function (msg, options) {
  7792. if (options.from == '23D') {
  7793. if (map2DViewer.inited) {
  7794. //移除所有显示的地图元素,并断开同步
  7795. map2DViewer.hide2D = true;
  7796. }
  7797. }
  7798. });
  7799. //飞行定位
  7800. PubSub.subscribe('map23D.flyTo', function (msg, options) {
  7801. //_.merge(map23DData.view, options);
  7802. map2DViewer.map.flyTo(
  7803. [map23DData.view.center.lat, map23DData.view.center.lng],
  7804. map23DData.view.zoom
  7805. );
  7806. map23DData.mouseIn = '2D';
  7807. // PubSub.publish('map2D.setView', {
  7808. // from: '2D'
  7809. // })
  7810. });
  7811. map2DViewer.init = function (options) {
  7812. var _this = map2DViewer;
  7813. if (this.inited) {
  7814. return;
  7815. } else {
  7816. this.inited = true;
  7817. }
  7818. var map2DDiv = document.createElement("div");
  7819. map2DDiv.id = "map2DDiv"
  7820. document.getElementById("map2DWrap").appendChild(map2DDiv);
  7821. this.map = L.map('map2DDiv', {
  7822. editable: true,
  7823. attributionControl: false,
  7824. inertia: false,
  7825. // fadeAnimation: false,
  7826. // zoomAnimation: true,
  7827. contextmenu: true,
  7828. minZoom: map23DConfig.map2DMinZoom || 1,
  7829. maxZoom: map23DConfig.map2DMaxZoom || 21,
  7830. preferCanvas: false
  7831. }).setView([map23DData.view.center.lat, map23DData.view.center.lng], map23DData.view.zoom);
  7832. this.polygonCanvasRenderer = L.canvas();
  7833. this.polylineCanvasRenderer = L.canvas();
  7834. this.rectangleCanvasRenderer = L.canvas();
  7835. this.circleleCanvasRenderer = L.canvas();
  7836. this.circleMarkerCanvasRenderer = L.canvas();
  7837. this.map.on('zoomend', function () {
  7838. PubSub.publish('map2DViewerZoomend', {
  7839. from: '2D'
  7840. })
  7841. })
  7842. this.map.on('zoomend move', function (e) {
  7843. if (map23DData.mouseIn != '2D') {
  7844. return;
  7845. }
  7846. if (map2DViewer.syncTimeer) {
  7847. return false;
  7848. }
  7849. map2DViewer.syncTimeer = setTimeout(function () {
  7850. var mapState = {
  7851. view: {
  7852. center: {
  7853. lat: e.target.getCenter().lat,
  7854. lng: e.target.getCenter().lng
  7855. },
  7856. zoom: _this.map.getZoom()
  7857. }
  7858. }
  7859. _.merge(map23DData, mapState);
  7860. PubSub.publish('map2D.setView', {
  7861. from: '2D'
  7862. })
  7863. clearTimeout(map2DViewer.syncTimeer);
  7864. map2DViewer.syncTimeer = null;
  7865. }, 300)
  7866. });
  7867. PubSub.subscribe('map3D.setView', function (msg, options) {
  7868. if (options.from == '3D' && map23DData.mouseIn == '3D' && !map2DViewer.hide2D) {
  7869. _this.map.setView(
  7870. [map23DData.view.center.lat, map23DData.view.center.lng],
  7871. map23DData.view.zoom
  7872. );
  7873. }
  7874. });
  7875. PubSub.subscribe('map3D.flyTo', function (msg, options) {
  7876. if (options.from == '3D' && map23DData.mouseIn == '3D' && !map2DViewer.hide2D) {
  7877. map2DViewer.map.flyTo(
  7878. [map23DData.view.center.lat, map23DData.view.center.lng],
  7879. map23DData.view.zoom
  7880. );
  7881. }
  7882. });
  7883. PubSub.subscribe('map23D.setView', function (msg, options) {
  7884. if (options.from == '23D' && !map2DViewer.hide2D) {
  7885. _this.map.setView(
  7886. [map23DData.view.center.lat, map23DData.view.center.lng],
  7887. map23DData.view.zoom
  7888. );
  7889. }
  7890. });
  7891. }
  7892. /**
  7893. * 根据两点坐标返回矩形坐标
  7894. * IN 进入坐标[lng,lat]
  7895. * OUT 离开坐标[lng,lat]
  7896. * 扫描宽度在1200KM内效果较好
  7897. */
  7898. map2DViewer.PointToPolygon = function (IN, OUT, inverse) {
  7899. var polygonCoors = [];
  7900. var zoom = map23DData.view.zoom;
  7901. //两点之间距离
  7902. //var distanceIO = new L.LatLng(IN[0],IN[1]).distanceTo(new L.LatLng(OUT[0],OUT[1]));
  7903. var distanceIO = Math.sqrt(Math.pow((IN[0] - OUT[0]), 2) + Math.pow((IN[1] - OUT[1]), 2))
  7904. //经纬度转换成高斯坐标
  7905. //var goosIN = window.map23DUtil.coordn_to_gauss(IN,zoom);
  7906. //var goosOUT = window.map23DUtil.coordn_to_gauss(OUT,zoom);
  7907. var goosIN = IN;
  7908. var goosOUT = OUT;
  7909. //中心点坐标
  7910. var centerLngLatGoos = [(goosIN[0] + goosOUT[0]) / 2, (goosIN[1] + goosOUT[1]) / 2];
  7911. var centerLngLat = [(IN[0] + OUT[0]) / 2, (IN[1] + OUT[1]) / 2];
  7912. if (goosIN[1] >= centerLngLatGoos[1]) {
  7913. if (goosIN[0] > centerLngLatGoos[0]) {
  7914. var tangle = L.Util.getAngleByLatLng(centerLngLat[0], centerLngLat[1], IN[0], IN[1]);
  7915. } else {
  7916. var tangle = 360 - L.Util.getAngleByLatLng(centerLngLat[0], centerLngLat[1], IN[0], IN[1]);
  7917. }
  7918. } else {
  7919. if (goosIN[0] > centerLngLatGoos[0]) {
  7920. var tangle = 360 - L.Util.getAngleByLatLng(IN[0], IN[1], centerLngLat[0], centerLngLat[1]);
  7921. } else {
  7922. var tangle = L.Util.getAngleByLatLng(IN[0], IN[1], centerLngLat[0], centerLngLat[1]);
  7923. }
  7924. }
  7925. var curTangle = tangle;
  7926. tangle = tangle / 180 * Math.PI;
  7927. if (curTangle === 0) {
  7928. var chaX = distanceIO / 2;
  7929. var chaY = distanceIO / 2;
  7930. var inverseGoos1 = [centerLngLatGoos[0] - chaX, centerLngLatGoos[1] + chaY];
  7931. var inverseGoos2 = [centerLngLatGoos[0] - chaX, centerLngLatGoos[1] - chaY];
  7932. var inverseGoos3 = [centerLngLatGoos[0] + chaX, centerLngLatGoos[1] - chaY];
  7933. var inverseGoos4 = [centerLngLatGoos[0] + chaX, centerLngLatGoos[1] + chaY];
  7934. } else if (curTangle === 90) {
  7935. var chaX = distanceIO / 2;
  7936. var chaY = distanceIO / 2;
  7937. var inverseGoos1 = [centerLngLatGoos[0] - chaX, centerLngLatGoos[1] + chaY];
  7938. var inverseGoos2 = [centerLngLatGoos[0] - chaX, centerLngLatGoos[1] - chaY];
  7939. var inverseGoos3 = [centerLngLatGoos[0] + chaX, centerLngLatGoos[1] - chaY];
  7940. var inverseGoos4 = [centerLngLatGoos[0] + chaX, centerLngLatGoos[1] + chaY];
  7941. } else {
  7942. var chaX = distanceIO * Math.cos(tangle);
  7943. var chaY = distanceIO * Math.sin(tangle);
  7944. if (!inverse) {
  7945. chaY = chaY;
  7946. chaX = chaX;
  7947. } else {
  7948. chaY = -chaY;
  7949. chaX = -chaX;
  7950. }
  7951. var inverseGoos1 = goosIN;
  7952. var inverseGoos2 = [goosIN[0] + chaX, goosIN[1] - chaY];
  7953. var inverseGoos3 = [goosOUT[0] + chaX, goosOUT[1] - chaY];
  7954. var inverseGoos4 = goosOUT;
  7955. }
  7956. var inverse1 = window.map23DUtil.gaussToGeo(inverseGoos1[0], inverseGoos1[1], IN[0], zoom);
  7957. var inverse2 = window.map23DUtil.gaussToGeo(inverseGoos2[0], inverseGoos2[1], centerLngLat[0], zoom);
  7958. var inverse3 = window.map23DUtil.gaussToGeo(inverseGoos3[0], inverseGoos3[1], centerLngLat[0], zoom);
  7959. var inverse4 = window.map23DUtil.gaussToGeo(inverseGoos4[0], inverseGoos4[1], OUT[0], zoom);
  7960. //polygonCoors.push([inverse1.longitude,inverse1.latitude]);
  7961. //polygonCoors.push([inverse2.longitude,inverse2.latitude]);
  7962. //polygonCoors.push([inverse3.longitude,inverse3.latitude]);
  7963. //polygonCoors.push([inverse4.longitude,inverse4.latitude]);
  7964. polygonCoors.push(inverseGoos1);
  7965. polygonCoors.push(inverseGoos2);
  7966. polygonCoors.push(inverseGoos3);
  7967. polygonCoors.push(inverseGoos4);
  7968. return ({
  7969. "coordinates": polygonCoors
  7970. })
  7971. };
  7972. map2DViewer.setView = function (options) {
  7973. _.merge(map23DData.view, options);
  7974. map2DViewer.map.setView(
  7975. [map23DData.view.center.lat, map23DData.view.center.lng],
  7976. map23DData.view.zoom
  7977. );
  7978. map23DData.mouseIn = '2D';
  7979. PubSub.publish('map2D.setView', {
  7980. from: '2D'
  7981. })
  7982. }
  7983. map2DViewer.flyTo = function (options) {
  7984. _.merge(map23DData.view, options);
  7985. map2DViewer.map.flyTo(
  7986. [map23DData.view.center.lat, map23DData.view.center.lng],
  7987. map23DData.view.zoom
  7988. );
  7989. map23DData.mouseIn = '2D';
  7990. PubSub.publish('map2D.setView', {
  7991. from: '2D'
  7992. })
  7993. }
  7994. //2D图层组
  7995. map2DViewer.group = function (options) {
  7996. switch (options.action) {
  7997. case 'add':
  7998. return addGroup2D(options);
  7999. break;
  8000. case 'show':
  8001. return showGroup2D(options);
  8002. break;
  8003. case 'hide':
  8004. return hideGroup2D(options);
  8005. break;
  8006. case 'remove':
  8007. return removeGroup2D(options);
  8008. break;
  8009. case 'cleanAll':
  8010. return operationGroup2D(options, 'remove');
  8011. break;
  8012. }
  8013. }
  8014. function addGroup2D(options) {
  8015. var guid = options.guid || map23DControl.buildGuid('group2D');
  8016. var defaultData = _.cloneDeep(map23DDefaultData.group)
  8017. defaultData.guid = guid;
  8018. defaultData.from = '2D';
  8019. _.merge(defaultData, options);
  8020. map23DData.groups[guid] = defaultData;
  8021. PubSub.publishSync('map2D.group.add', guid);
  8022. return guid;
  8023. }
  8024. function removeGroup2D(options) {
  8025. if (map23DData.groups[options.guid]) {
  8026. operationGroup2D(options, "remove");
  8027. PubSub.publishSync('map2D.group.remove', options.guid);
  8028. if (map23DData.groups[options.guid].add3D == false) {
  8029. delete map23DData.groups[options.guid];
  8030. }
  8031. return options.guid;
  8032. } else {
  8033. return false;
  8034. }
  8035. }
  8036. function showGroup2D(options) {
  8037. if (map2DViewer.groups[options.guid]) {
  8038. operationGroup2D(options, "show");
  8039. PubSub.publishSync('map2D.group.show', options.guid);
  8040. return options.guid;
  8041. } else {
  8042. return false;
  8043. }
  8044. }
  8045. function hideGroup2D(options) {
  8046. if (map2DViewer.groups[options.guid]) {
  8047. operationGroup2D(options, "hide");
  8048. PubSub.publishSync('map2D.group.hide', options.guid);
  8049. return options.guid;
  8050. } else {
  8051. return false;
  8052. }
  8053. }
  8054. function operationGroup2D(options, action) {
  8055. if (map23DData.groups[options.guid]) {
  8056. //移除点
  8057. _(map23DData.markers).forEach(function (item, key) {
  8058. if (item.groupId == options.guid) {
  8059. map2DViewer.marker({
  8060. action: action,
  8061. guid: key
  8062. })
  8063. }
  8064. });
  8065. //移除线
  8066. _(map23DData.polylines).forEach(function (item, key) {
  8067. if (item.groupId == options.guid) {
  8068. map2DViewer.polyline({
  8069. action: action,
  8070. guid: key
  8071. })
  8072. }
  8073. });
  8074. //移除面
  8075. _(map23DData.polygons).forEach(function (item, key) {
  8076. if (item.groupId == options.guid) {
  8077. map2DViewer.polygon({
  8078. action: action,
  8079. guid: key
  8080. })
  8081. }
  8082. });
  8083. //移除圆
  8084. _(map23DData.circles).forEach(function (item, key) {
  8085. if (item.groupId == options.guid) {
  8086. map2DViewer.circle({
  8087. action: action,
  8088. guid: key
  8089. })
  8090. }
  8091. });
  8092. //移除圆标记
  8093. _(map23DData.circleMarkers).forEach(function (item, key) {
  8094. if (item.groupId == options.guid) {
  8095. map2DViewer.circleMarker({
  8096. action: action,
  8097. guid: key
  8098. })
  8099. }
  8100. });
  8101. return options.guid;
  8102. } else {
  8103. return false
  8104. }
  8105. }
  8106. //2D 点
  8107. map2DViewer.marker = function (options) {
  8108. switch (options.action) {
  8109. case 'add':
  8110. return addMarker2D(options);
  8111. break;
  8112. case 'remove':
  8113. return removeMarker2D(options);
  8114. break;
  8115. case 'update':
  8116. return updateMarker2D(options);
  8117. break;
  8118. case 'hide':
  8119. return hideMarker2D(options);
  8120. break;
  8121. case 'show':
  8122. return showMarker2D(options);
  8123. break;
  8124. }
  8125. }
  8126. function addMarker2D(options) {
  8127. var guid = options.guid || map23DControl.buildGuid('marker2D');
  8128. if (!options.RBkey) {
  8129. var markerTime = null;
  8130. } else {
  8131. var markerTime = map23DData.polylines[map2DViewer.routeBackGroup[options.RBkey].polyline].geojson.properties.times;
  8132. }
  8133. if (options.vectorMarker) {
  8134. var dataSize = options.geojson.properties.baseSize;
  8135. var curZoom = map23DData.view.zoom;
  8136. if (curZoom >= options.geojson.properties.baseZoom) {
  8137. var scaleX = dataSize[0] + dataSize[0] * (curZoom - options.geojson.properties.baseZoom);
  8138. var scaleY = dataSize[1] + dataSize[1] * (curZoom - options.geojson.properties.baseZoom);
  8139. } else {
  8140. var scaleX = dataSize[0] * Math.pow(options.geojson.properties.baseZoom - curZoom + 1, -1);
  8141. var scaleY = dataSize[1] * Math.pow(options.geojson.properties.baseZoom - curZoom + 1, -1);
  8142. }
  8143. options.geojson.properties.iconSize = [scaleX, scaleY];
  8144. options.geojson.properties.iconAnchor = [scaleX / 2, scaleY / 2];
  8145. options.geojson.properties.popupAnchor = [0, -scaleY];
  8146. }
  8147. var defaultData = _.cloneDeep(map23DDefaultData.marker)
  8148. defaultData.guid = guid;
  8149. defaultData.from = '2D';
  8150. defaultData.geojson.geometry.markerTime = markerTime;
  8151. _.merge(defaultData, options);
  8152. map23DData.markers[guid] = defaultData;
  8153. PubSub.publishSync('map2D.marker.add', guid);
  8154. return guid;
  8155. }
  8156. function showMarker2D(options) {
  8157. if (map2DViewer.markers[options.guid]) {
  8158. PubSub.publishSync('map2D.marker.show', options.guid);
  8159. return options.guid;
  8160. } else {
  8161. return false;
  8162. }
  8163. }
  8164. function hideMarker2D(options) {
  8165. if (map2DViewer.markers[options.guid]) {
  8166. PubSub.publishSync('map2D.marker.hide', options.guid);
  8167. return options.guid;
  8168. } else {
  8169. return false;
  8170. }
  8171. }
  8172. function removeMarker2D(options) {
  8173. if (map23DData.markers[options.guid]) {
  8174. PubSub.publishSync('map2D.marker.remove', options.guid);
  8175. if (map23DData.markers[options.guid].add3D == false) {
  8176. delete map23DData.markers[options.guid];
  8177. }
  8178. return options.guid;
  8179. } else {
  8180. return false;
  8181. }
  8182. }
  8183. function updateMarker2D(options) {
  8184. if (map23DData.markers[options.guid]) {
  8185. _.merge(map23DData.markers[options.guid], options);
  8186. if (options.geojson.geometry) {
  8187. if (options.geojson.geometry.coordinates)
  8188. map23DData.markers[options.guid].geojson.geometry.coordinates = options.geojson.geometry.coordinates
  8189. }
  8190. PubSub.publishSync('map2D.marker.update', options.guid);
  8191. return options.guid;
  8192. } else {
  8193. return false;
  8194. }
  8195. }
  8196. //2D 线
  8197. map2DViewer.polyline = function (options) {
  8198. switch (options.action) {
  8199. case 'add':
  8200. return addPolyline2D(options);
  8201. break;
  8202. case 'show':
  8203. return showPolyline2D(options);
  8204. break;
  8205. case 'hide':
  8206. return hidePolyline2D(options);
  8207. break;
  8208. case 'remove':
  8209. return removePolyline2D(options);
  8210. break;
  8211. case 'update':
  8212. return updatePolyline2D(options);
  8213. break;
  8214. }
  8215. }
  8216. function addPolyline2D(options) {
  8217. var guid = options.guid || map23DControl.buildGuid('polyline2D');
  8218. var defaultData = _.cloneDeep(map23DDefaultData.polyline)
  8219. defaultData.guid = guid;
  8220. defaultData.from = '2D';
  8221. _.merge(defaultData, options);
  8222. map23DData.polylines[guid] = defaultData;
  8223. PubSub.publishSync('map2D.polyline.add', guid);
  8224. return guid;
  8225. }
  8226. function showPolyline2D(options) {
  8227. if (map2DViewer.polylines[options.guid]) {
  8228. PubSub.publishSync('map2D.polyline.show', options.guid);
  8229. return options.guid;
  8230. } else {
  8231. return false;
  8232. }
  8233. }
  8234. function hidePolyline2D(options) {
  8235. if (map2DViewer.polylines[options.guid]) {
  8236. PubSub.publishSync('map2D.polyline.hide', options.guid);
  8237. return options.guid;
  8238. } else {
  8239. return false;
  8240. }
  8241. }
  8242. function removePolyline2D(options) {
  8243. if (map23DData.polylines[options.guid]) {
  8244. PubSub.publishSync('map2D.polyline.remove', options.guid);
  8245. if (map23DData.polylines[options.guid].add3D == false) {
  8246. delete map23DData.polylines[options.guid];
  8247. }
  8248. return options.guid;
  8249. } else {
  8250. return false;
  8251. }
  8252. }
  8253. function updatePolyline2D(options) {
  8254. if (map23DData.polylines[options.guid]) {
  8255. _.merge(map23DData.polylines[options.guid], options);
  8256. if (options.geojson.geometry) {
  8257. if (options.geojson.geometry.coordinates)
  8258. map23DData.polylines[options.guid].geojson.geometry.coordinates = options.geojson.geometry.coordinates
  8259. }
  8260. PubSub.publishSync('map2D.polyline.update', options.guid);
  8261. return options.guid;
  8262. } else {
  8263. return false;
  8264. }
  8265. }
  8266. //2D 面
  8267. map2DViewer.polygon = function (options) {
  8268. switch (options.action) {
  8269. case 'add':
  8270. return addPolygon2D(options);
  8271. break;
  8272. case 'show':
  8273. return showPolygon2D(options);
  8274. break;
  8275. case 'hide':
  8276. return hidePolygon2D(options);
  8277. break;
  8278. case 'remove':
  8279. return removePolygon2D(options);
  8280. break;
  8281. case 'update':
  8282. return updatePolygon2D(options);
  8283. break;
  8284. }
  8285. }
  8286. function addPolygon2D(options) {
  8287. var guid = options.guid || map23DControl.buildGuid('polygon2D');
  8288. var defaultData = _.cloneDeep(map23DDefaultData.polyline)
  8289. defaultData.guid = guid;
  8290. defaultData.from = '2D';
  8291. _.merge(defaultData, options);
  8292. map23DData.polygons[guid] = defaultData;
  8293. PubSub.publishSync('map2D.polygon.add', guid);
  8294. return guid;
  8295. }
  8296. function showPolygon2D(options) {
  8297. if (map2DViewer.polygons[options.guid]) {
  8298. PubSub.publishSync('map2D.polygon.show', options.guid);
  8299. return options.guid;
  8300. } else {
  8301. return false;
  8302. }
  8303. }
  8304. function hidePolygon2D(options) {
  8305. if (map2DViewer.polygons[options.guid]) {
  8306. PubSub.publishSync('map2D.polygon.hide', options.guid);
  8307. return options.guid;
  8308. } else {
  8309. return false;
  8310. }
  8311. }
  8312. function removePolygon2D(options) {
  8313. if (map23DData.polygons[options.guid]) {
  8314. PubSub.publishSync('map2D.polygon.remove', options.guid);
  8315. if (map23DData.polygons[options.guid].add3D == false) {
  8316. delete map23DData.polygons[options.guid];
  8317. }
  8318. return options.guid;
  8319. } else {
  8320. return false;
  8321. }
  8322. }
  8323. function updatePolygon2D(options) {
  8324. if (map23DData.polygons[options.guid]) {
  8325. _.merge(map23DData.polygons[options.guid], options);
  8326. if (options.geojson.geometry) {
  8327. if (options.geojson.geometry.coordinates)
  8328. map23DData.polygons[options.guid].geojson.geometry.coordinates = options.geojson.geometry.coordinates
  8329. }
  8330. PubSub.publishSync('map2D.polygon.update', options.guid);
  8331. return options.guid;
  8332. } else {
  8333. return false;
  8334. }
  8335. }
  8336. //2D 圆
  8337. map2DViewer.circle = function (options) {
  8338. switch (options.action) {
  8339. case 'add':
  8340. return addCircle2D(options);
  8341. break;
  8342. case 'show':
  8343. return showCircle2D(options);
  8344. break;
  8345. case 'hide':
  8346. return hideCircle2D(options);
  8347. break;
  8348. case 'remove':
  8349. return removeCircle2D(options);
  8350. break;
  8351. case 'update':
  8352. return updateCircle2D(options);
  8353. break;
  8354. }
  8355. }
  8356. function addCircle2D(options) {
  8357. var guid = options.guid || map23DControl.buildGuid('circle2D');
  8358. var defaultData = _.cloneDeep(map23DDefaultData.circle)
  8359. defaultData.guid = guid;
  8360. defaultData.from = '2D';
  8361. _.merge(defaultData, options);
  8362. map23DData.circles[guid] = defaultData;
  8363. PubSub.publishSync('map2D.circle.add', guid);
  8364. return guid;
  8365. }
  8366. function showCircle2D(options) {
  8367. if (map2DViewer.circles[options.guid]) {
  8368. PubSub.publishSync('map2D.circle.show', options.guid);
  8369. return options.guid;
  8370. } else {
  8371. return false;
  8372. }
  8373. }
  8374. function hideCircle2D(options) {
  8375. if (map2DViewer.circles[options.guid]) {
  8376. PubSub.publishSync('map2D.circle.hide', options.guid);
  8377. return options.guid;
  8378. } else {
  8379. return false;
  8380. }
  8381. }
  8382. function removeCircle2D(options) {
  8383. if (map23DData.circles[options.guid]) {
  8384. PubSub.publishSync('map2D.circle.remove', options.guid);
  8385. if (map23DData.circles[options.guid].add3D == false) {
  8386. delete map23DData.circles[options.guid];
  8387. }
  8388. return options.guid;
  8389. } else {
  8390. return false;
  8391. }
  8392. }
  8393. function updateCircle2D(options) {
  8394. if (map23DData.circles[options.guid]) {
  8395. _.merge(map23DData.circles[options.guid], options);
  8396. if (options.geojson.geometry) {
  8397. if (options.geojson.geometry.coordinates)
  8398. map23DData.circles[options.guid].geojson.geometry.coordinates = options.geojson.geometry.coordinates
  8399. }
  8400. PubSub.publishSync('map2D.circle.update', options.guid);
  8401. return options.guid;
  8402. } else {
  8403. return false;
  8404. }
  8405. }
  8406. //2D 圆标记
  8407. map2DViewer.circleMarker = function (options) {
  8408. switch (options.action) {
  8409. case 'add':
  8410. return addCircleMarker2D(options);
  8411. break;
  8412. case 'show':
  8413. return showCircleMarker2D(options);
  8414. break;
  8415. case 'hide':
  8416. return hideCircleMarker2D(options);
  8417. break;
  8418. case 'remove':
  8419. return removeCircleMarker2D(options);
  8420. break;
  8421. case 'update':
  8422. return updateCircleMarker2D(options);
  8423. break;
  8424. }
  8425. }
  8426. function addCircleMarker2D(options) {
  8427. var guid = options.guid || map23DControl.buildGuid('circleMarker2D');
  8428. var defaultData = _.cloneDeep(map23DDefaultData.circleMarker)
  8429. defaultData.guid = guid;
  8430. defaultData.from = '2D';
  8431. _.merge(defaultData, options);
  8432. map23DData.circleMarkers[guid] = defaultData;
  8433. PubSub.publishSync('map2D.circleMarker.add', guid);
  8434. return guid;
  8435. }
  8436. function showCircleMarker2D(options) {
  8437. if (map2DViewer.circleMarkers[options.guid]) {
  8438. PubSub.publishSync('map2D.circleMarker.show', options.guid);
  8439. return options.guid;
  8440. } else {
  8441. return false;
  8442. }
  8443. }
  8444. function hideCircleMarker2D(options) {
  8445. if (map2DViewer.circleMarkers[options.guid]) {
  8446. PubSub.publishSync('map2D.circleMarker.hide', options.guid);
  8447. return options.guid;
  8448. } else {
  8449. return false;
  8450. }
  8451. }
  8452. function removeCircleMarker2D(options) {
  8453. if (map23DData.circleMarkers[options.guid]) {
  8454. PubSub.publishSync('map2D.circleMarker.remove', options.guid);
  8455. if (map23DData.circleMarkers[options.guid].add3D == false) {
  8456. delete map23DData.circleMarkers[options.guid];
  8457. }
  8458. return options.guid;
  8459. } else {
  8460. return false;
  8461. }
  8462. }
  8463. function updateCircleMarker2D(options) {
  8464. if (map23DData.circleMarkers[options.guid]) {
  8465. _.merge(map23DData.circleMarkers[options.guid], options);
  8466. if (options.geojson.geometry) {
  8467. if (options.geojson.geometry.coordinates)
  8468. map23DData.circles[options.guid].geojson.geometry.coordinates = options.geojson.geometry.coordinates
  8469. }
  8470. PubSub.publishSync('map2D.circleMarker.update', options.guid);
  8471. return options.guid;
  8472. } else {
  8473. return false;
  8474. }
  8475. }
  8476. map2DViewer.imageOverlay = function (options) {
  8477. switch (options.action) {
  8478. case 'add':
  8479. return addImageOverlay2D(options);
  8480. break;
  8481. case 'remove':
  8482. return removeImageOverlay2D(options);
  8483. break;
  8484. case 'update':
  8485. return updateImageOverlay2D(options);
  8486. break;
  8487. case 'hide':
  8488. return hideImageOverlay2D(options);
  8489. break;
  8490. case 'show':
  8491. return showImageOverlay2D(options);
  8492. break;
  8493. }
  8494. }
  8495. function addImageOverlay2D(options) {
  8496. var guid = options.guid || map23DControl.buildGuid('imageOverlay23D');
  8497. var defaultData = _.cloneDeep(map23DDefaultData.imageOverlay)
  8498. defaultData.guid = guid;
  8499. _.merge(defaultData, options);
  8500. map23DData.imageOverlays[guid] = defaultData;
  8501. PubSub.publishSync('map2D.imageOverlay.add', guid);
  8502. return guid;
  8503. }
  8504. /**
  8505. * 移除图层组,移除前先清除图层组中的元素
  8506. * @param {[type]} options [description]
  8507. * @return {[type]} [description]
  8508. */
  8509. function removeImageOverlay2D(options) {
  8510. if (map23DData.imageOverlays[options.guid]) {
  8511. PubSub.publishSync('map2D.imageOverlay.remove', options.guid);
  8512. delete map23DData.imageOverlays[options.guid];
  8513. return options.guid;
  8514. } else {
  8515. return false;
  8516. }
  8517. }
  8518. function updateImageOverlay2D(options) {
  8519. if (map23DData.imageOverlays[options.guid]) {
  8520. _.merge(map23DData.imageOverlays[options.guid], options);
  8521. PubSub.publishSync('map2D.imageOverlay.update', options.guid);
  8522. return options.guid;
  8523. } else {
  8524. return false;
  8525. }
  8526. }
  8527. function showImageOverlay2D(options) {
  8528. if (map23DData.imageOverlays[options.guid]) {
  8529. _.merge(map23DData.imageOverlays[options.guid], options);
  8530. PubSub.publishSync('map2D.imageOverlay.show', options.guid);
  8531. return options.guid;
  8532. } else {
  8533. return false;
  8534. }
  8535. }
  8536. function hideImageOverlay2D(options) {
  8537. if (map23DData.imageOverlays[options.guid]) {
  8538. _.merge(map23DData.imageOverlays[options.guid], options);
  8539. PubSub.publishSync('map2D.imageOverlay.hide', options.guid);
  8540. return options.guid;
  8541. } else {
  8542. return false;
  8543. }
  8544. }
  8545. /**
  8546. * 设置系统自带图层
  8547. * @param {[type]} options [description]
  8548. */
  8549. map2DViewer.setDefaultTileLayer = function (options) {
  8550. PubSub.publish('map2D.defaultTileLayer.change', {
  8551. mapName: options
  8552. })
  8553. }
  8554. /**
  8555. * 2D图层控制
  8556. */
  8557. map2DViewer.tileLayer = function (options) {
  8558. switch (options.action) {
  8559. case 'add':
  8560. return addTileLayer2D(options);
  8561. break;
  8562. case 'remove':
  8563. return removeTileLayer2D(options);
  8564. break;
  8565. case 'update':
  8566. return updateTileLayer2D(options);
  8567. break;
  8568. case 'show':
  8569. return showTileLayer2D(options);
  8570. break;
  8571. case 'hide':
  8572. return hideTileLayer2D(options);
  8573. break;
  8574. }
  8575. }
  8576. function addTileLayer2D(options) {
  8577. var guid = options.guid || map23DControl.buildGuid('tileLayer2D');
  8578. var defaultData = _.cloneDeep(map23DDefaultData.layer)
  8579. defaultData.guid = guid;
  8580. defaultData.from = '2D';
  8581. _.merge(defaultData, options);
  8582. map23DData.layers[guid] = defaultData;
  8583. PubSub.publishSync('map2D.tileLayer.add', guid);
  8584. return guid;
  8585. }
  8586. function showTileLayer2D(options) {
  8587. if (map2DViewer.layers[options.guid]) {
  8588. PubSub.publishSync('map2D.tileLayer.show', options.guid);
  8589. return options.guid;
  8590. } else {
  8591. return false;
  8592. }
  8593. }
  8594. function hideTileLayer2D(options) {
  8595. if (map2DViewer.layers[options.guid]) {
  8596. PubSub.publishSync('map2D.tileLayer.hide', options.guid);
  8597. return options.guid;
  8598. } else {
  8599. return false;
  8600. }
  8601. }
  8602. function updateTileLayer2D(options) {
  8603. if (map23DData.layers[options.guid]) {
  8604. _.merge(map23DData.layers[options.guid], options);
  8605. PubSub.publishSync('map2D.tileLayer.update', options.guid);
  8606. return options.guid;
  8607. } else {
  8608. return false;
  8609. }
  8610. }
  8611. function removeTileLayer2D(options) {
  8612. if (map23DData.layers[options.guid]) {
  8613. PubSub.publishSync('map2D.tileLayer.remove', options.guid);
  8614. if (map23DData.layers[options.guid].add3D == false) {
  8615. delete map23DData.layers[options.guid];
  8616. }
  8617. return options.guid;
  8618. } else {
  8619. return false;
  8620. }
  8621. }
  8622. /**
  8623. * 2DCartodb控制
  8624. */
  8625. map2DViewer.cartodbLayer = function (options) {
  8626. switch (options.action) {
  8627. case 'add':
  8628. return addCartodbLayer2D(options);
  8629. break;
  8630. case 'remove':
  8631. return removeCartodbLayer2D(options);
  8632. break;
  8633. }
  8634. }
  8635. function addCartodbLayer2D(options) {
  8636. var guid = options.guid || map23DControl.buildGuid('cartodbLayer2D');
  8637. var defaultData = _.cloneDeep(map23DDefaultData.layer)
  8638. defaultData.guid = guid;
  8639. defaultData.from = '2D';
  8640. _.merge(defaultData, options);
  8641. map23DData.layers[guid] = defaultData;
  8642. PubSub.publishSync('map2D.cartodbLayer.add', guid);
  8643. return guid;
  8644. }
  8645. function removeCartodbLayer2D(options) {
  8646. if (map23DData.layers[options.guid]) {
  8647. PubSub.publishSync('map2D.cartodbLayer.remove', options.guid);
  8648. delete map23DData.layers[options.guid];
  8649. return options.guid;
  8650. } else {
  8651. return false;
  8652. }
  8653. }
  8654. }(window, document));
  8655. ;
  8656. (function (window, document, undefined) {
  8657. window.map3DViewer = {
  8658. inited: false,
  8659. markers: {},
  8660. DEMLayers: {},
  8661. layers: {},
  8662. polylines: {},
  8663. polygons: {},
  8664. circles: {},
  8665. groups: {},
  8666. models: {},
  8667. hide3D: false,
  8668. zoomAry: [90000, 50123, 31000, 16180, 8970, 5036, 2395, 1092, 580, 287, 146, 62.3, 33, 17.9, 9, 3.9, 2.1, 1.2, 0.53, 0.27, 0.01],
  8669. syncTimeer: null,
  8670. imageOverlays: {},
  8671. modelControlObj: {}
  8672. };
  8673. if (typeof module === 'object' && typeof module.exports === 'object') {
  8674. module.exports = map3DViewer;
  8675. } else if (typeof define === 'function' && define.amd) {
  8676. define(map3DViewer);
  8677. }
  8678. PubSub.subscribe('map23D.show23D', function (msg, options) {
  8679. if (options.from == '23D' && map23DData.display.map3D) {
  8680. if (map3DViewer.inited) {} else {
  8681. map3DViewer.init();
  8682. }
  8683. map3DViewer.hide3D = false;
  8684. }
  8685. });
  8686. PubSub.subscribe('map23D.show3D', function (msg, options) {
  8687. if (options.from == '23D' && map23DData.display.map3D) {
  8688. if (map3DViewer.inited) {
  8689. var newlatlng = map23DData.view.center;
  8690. var map3DHeading = map3DViewer.getHeadingForPi(map23DData.view.heading);
  8691. map3DViewer.map.camera.setView({
  8692. destination: Cesium.Cartesian3.fromDegrees(newlatlng.lng, newlatlng.lat, map3DViewer.getZoomFrom2DZoom(map23DData.view.zoom)), // 设置位置
  8693. orientation: {
  8694. heading: map3DHeading, // 方向
  8695. pitch: map3DViewer.getPitchForPi(map23DData.view.pitch), // 倾斜角度
  8696. roll: 0
  8697. }
  8698. })
  8699. map23DData.mouseIn = '3D';
  8700. } else {
  8701. map3DViewer.init();
  8702. //如果从隐藏到显示,添加所有因show2D隐藏的地图元素,添加同步
  8703. }
  8704. map3DViewer.hide3D = false;
  8705. }
  8706. });
  8707. PubSub.subscribe('map23D.show2D', function (msg, options) {
  8708. if (options.from == '23D') {
  8709. if (map3DViewer.inited) {
  8710. //移除所有显示的地图元素,并断开同步
  8711. map3DViewer.hide3D = true;
  8712. }
  8713. }
  8714. });
  8715. PubSub.subscribe('map23D.flyTo', function (msg, options) {
  8716. //_.merge(map23DData.view, options);
  8717. var newlatlng = map23DData.view.center;
  8718. var map3DHeading = map3DViewer.getHeadingForPi(map23DData.view.heading);
  8719. //longitude, latitude, altitude, dHeading, dTilt, dDistance, altMode
  8720. map3DViewer.map.camera.flyTo({
  8721. destination: Cesium.Cartesian3.fromDegrees(newlatlng.lng, newlatlng.lat, map3DViewer.getZoomFrom2DZoom(map23DData.view.zoom)), // 设置位置
  8722. orientation: {
  8723. heading: map3DHeading, // 方向
  8724. pitch: map3DViewer.getPitchForPi(map23DData.view.pitch), // 倾斜角度
  8725. roll: 0
  8726. },
  8727. duration: 5,
  8728. complete: function () {
  8729. if (options.callback) {
  8730. options.callback();
  8731. }
  8732. },
  8733. pitchAdjustHeight: -90, // 如果摄像机飞越高于该值,则调整俯仰俯仰的俯仰角度,并将地球保持在视口中。
  8734. maximumHeight: 150000, // 相机最大飞行高度
  8735. //flyOverLongitude: 100, // 如果到达目的地有2种方式,设置具体值后会强制选择方向飞过这个经度
  8736. })
  8737. map23DData.mouseIn = '3D';
  8738. // PubSub.publish('map3D.flyTo', {
  8739. // from: '3D'
  8740. // })
  8741. });
  8742. map3DViewer.init = function () {
  8743. var _this = this;
  8744. if (this.inited) {
  8745. return;
  8746. } else {
  8747. this.inited = true;
  8748. }
  8749. this.map = new Cesium.Viewer('map3DWrap', {
  8750. animation: false, //是否创建动画小器件,左下角仪表
  8751. baseLayerPicker: false, //是否显示图层选择器
  8752. imageryProvider: new Cesium.WebMapServiceImageryProvider({
  8753. url: map23DConfig.tileServerUrl + '/gr?l={z}&x={x}&y={y}',
  8754. format: "png"
  8755. }),
  8756. fullscreenButton: false, //是否显示全屏按钮
  8757. geocoder: false, //是否显示geocoder小器件,右上角查询按钮
  8758. homeButton: false, //是否显示Home按钮
  8759. infoBox: false, //是否显示信息框
  8760. sceneModePicker: false, //是否显示3D/2D选择器
  8761. selectionIndicator: false, //是否显示选取指示器组件
  8762. timeline: false, //是否显示时间轴
  8763. navigationHelpButton: false, //是否显示右上角的帮助按钮
  8764. navigationInstructionsInitiallyVisible: false,
  8765. scene3DOnly: true, //如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
  8766. mapProjection: new Cesium.WebMercatorProjection(),
  8767. infoBox: false, //是否显示点击要素之后显示的信息
  8768. shouldAnimate: true, //是否自动播放
  8769. });
  8770. this.map.scene.globe.baseColor = new Cesium.Color(0, 0, 0, 0);
  8771. this.map.scene.imageryLayers.removeAll();
  8772. this.map._cesiumWidget._creditContainer.style.display = "none";
  8773. //初始位置
  8774. var map3DHeading = map3DViewer.getHeadingForPi(map23DData.view.heading);
  8775. this.map.camera.setView({
  8776. destination: Cesium.Cartesian3.fromDegrees(map23DData.view.center.lng, map23DData.view.center.lat, map3DViewer.getZoomFrom2DZoom(map23DData.view.zoom)), // 设置位置
  8777. orientation: {
  8778. heading: map3DHeading, // 方向
  8779. pitch: map3DViewer.getPitchForPi(map23DData.view.pitch), // 倾斜角度
  8780. roll: 0
  8781. }
  8782. })
  8783. //监听事件
  8784. var handler = new Cesium.ScreenSpaceEventHandler(this.map.scene.canvas);
  8785. this.map.scene.camera.moveEnd.addEventListener(function () {
  8786. var center = map3DViewer.getCurCameraInfos();
  8787. if (map23DData.mouseIn != '3D') {
  8788. return;
  8789. }
  8790. if (map3DViewer.syncTimeer) {
  8791. return;
  8792. }
  8793. map3DViewer.syncTimeer = setTimeout(function () {
  8794. var map23DDataHeading = map3DViewer.getHeadingForTangle(map3DViewer.map.camera.heading);
  8795. var map23DDataPitch = map3DViewer.getPitchForTangle(map3DViewer.map.camera.pitch);
  8796. var mapState = {
  8797. view: {
  8798. center: {
  8799. lat: center.lat,
  8800. lng: center.lng
  8801. },
  8802. zoom: map3DViewer.getZoomFrom3DZoom(center.alt),
  8803. heading: map23DDataHeading,
  8804. pitch: map23DDataPitch,
  8805. distance: center.alt
  8806. }
  8807. }
  8808. //console.log(cameraState.Tilt);
  8809. _.merge(map23DData, mapState);
  8810. PubSub.publish('map3D.setView', {
  8811. from: '3D'
  8812. })
  8813. //locaSpaceMap.Refresh();
  8814. clearTimeout(map3DViewer.syncTimeer);
  8815. map3DViewer.syncTimeer = null;
  8816. }, 30)
  8817. })
  8818. handler.setInputAction(function (e) {
  8819. var feature = map3DViewer.map.scene.pick(e.position);
  8820. PubSub.publish('map3D.featureClick', {
  8821. from: '3D',
  8822. evt: e,
  8823. feature: feature
  8824. })
  8825. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  8826. //鼠标滑过元素
  8827. handler.setInputAction(function (e) {
  8828. var feature = map3DViewer.map.scene.pick(e.position);
  8829. PubSub.publish('map3D.featureMouseHover', {
  8830. from: '3D',
  8831. evt: e,
  8832. feature: feature
  8833. })
  8834. }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  8835. //鼠标移动
  8836. handler.setInputAction(function (e) {
  8837. PubSub.publish('map3D.mouseMove', {
  8838. from: '3D',
  8839. x: e.endPosition.x,
  8840. y: e.endPosition.y
  8841. })
  8842. }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  8843. //鼠标左键
  8844. handler.setInputAction(function (e) {
  8845. PubSub.publish('map3D.marker.showPopup', {
  8846. type: 'LEFT_CLICK',
  8847. infos: e,
  8848. })
  8849. PubSub.publish('map3D.click', {
  8850. from: '3D',
  8851. x: e.position.x,
  8852. y: e.position.y
  8853. })
  8854. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  8855. //鼠标右键
  8856. handler.setInputAction(function (e) {
  8857. PubSub.publish('map3D.right_click', {
  8858. from: '3D',
  8859. x: e.position.x,
  8860. y: e.position.y
  8861. })
  8862. }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  8863. //鼠标双击
  8864. handler.setInputAction(function (e) {
  8865. PubSub.publish('map3D.dblClick', {
  8866. from: '3D',
  8867. x: e.position.x,
  8868. y: e.position.y
  8869. })
  8870. }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
  8871. PubSub.subscribe('map2D.setView', function (msg, options) {
  8872. var newlatlng = map23DData.view.center;
  8873. var map3DHeading = map3DViewer.getHeadingForPi(map23DData.view.heading);
  8874. if (map23DData.view.zoom < 6) {
  8875. map23DData.view.pitch = 90;
  8876. }
  8877. map3DViewer.map.camera.setView({
  8878. destination: Cesium.Cartesian3.fromDegrees(newlatlng.lng, newlatlng.lat, map3DViewer.getZoomFrom2DZoom(map23DData.view.zoom)), // 设置位置
  8879. orientation: {
  8880. heading: map3DHeading, // 方向
  8881. pitch: map3DViewer.getPitchForPi(map23DData.view.pitch), // 倾斜角度
  8882. roll: 0
  8883. }
  8884. })
  8885. var center = map3DViewer.get3DViewCenter();
  8886. map23DData.view.distance = center.alt;
  8887. });
  8888. PubSub.subscribe('map2D.flyTo', function (msg, options) {
  8889. if (options.from == '2D' && map23DData.mouseIn == '2D' && !map2DViewer.hide3D) {
  8890. //_.merge(map23DData.view, options);
  8891. var newlatlng = map23DData.view.center;
  8892. var map3DHeading = map3DViewer.getHeadingForPi(map23DData.view.heading);
  8893. //longitude, latitude, altitude, dHeading, dTilt, dDistance, altMode
  8894. map3DViewer.map.camera.flyTo({
  8895. destination: Cesium.Cartesian3.fromDegrees(newlatlng.lng, newlatlng.lat, map3DViewer.getZoomFrom2DZoom(map23DData.view.zoom)), // 设置位置
  8896. orientation: {
  8897. heading: map3DHeading, // 方向
  8898. pitch: map3DViewer.getPitchForPi(map23DData.view.pitch), // 倾斜角度
  8899. roll: 0
  8900. },
  8901. duration: 5,
  8902. complete: function () {
  8903. if (options.callback) {
  8904. options.callback();
  8905. }
  8906. },
  8907. pitchAdjustHeight: -90, // 如果摄像机飞越高于该值,则调整俯仰俯仰的俯仰角度,并将地球保持在视口中。
  8908. maximumHeight: 150000, // 相机最大飞行高度
  8909. //flyOverLongitude: 100, // 如果到达目的地有2种方式,设置具体值后会强制选择方向飞过这个经度
  8910. })
  8911. }
  8912. // PubSub.publish('map3D.flyTo', {
  8913. // from: '3D'
  8914. // })
  8915. });
  8916. PubSub.subscribe('map23D.setView', function (msg, options) {
  8917. if (options.from == '23D' && !map3DViewer.hide3D) {
  8918. var newlatlng = map23DData.view.center;
  8919. var map3DHeading = map3DViewer.getHeadingForPi(map23DData.view.heading);
  8920. if (map23DData.view.zoom < 6) {
  8921. map23DData.view.pitch = 90;
  8922. }
  8923. map3DViewer.map.camera.setView({
  8924. destination: Cesium.Cartesian3.fromDegrees(newlatlng.lng, newlatlng.lat, map3DViewer.getZoomFrom2DZoom(map23DData.view.zoom)), // 设置位置
  8925. orientation: {
  8926. heading: map3DHeading, // 方向
  8927. pitch: map3DViewer.getPitchForPi(map23DData.view.pitch), // 倾斜角度
  8928. roll: 0
  8929. }
  8930. })
  8931. }
  8932. });
  8933. }
  8934. //显示支持文本的冒泡窗
  8935. map3DViewer.showTextTips = function (options) {
  8936. }
  8937. //显示支持html的冒泡窗
  8938. map3DViewer.showPopup = function (options) {
  8939. }
  8940. //跳转到指定位置
  8941. map3DViewer.setView = function (options) {
  8942. _.merge(map23DData.view, options);
  8943. var newlatlng = map23DData.view.center;
  8944. var map3DHeading = map3DViewer.getHeadingForPi(map23DData.view.heading);
  8945. if (map23DData.view.zoom < 6) {
  8946. map23DData.view.pitch = 90;
  8947. }
  8948. map3DViewer.map.camera.setView({
  8949. destination: Cesium.Cartesian3.fromDegrees(newlatlng.lng, newlatlng.lat, map3DViewer.getZoomFrom2DZoom(map23DData.view.zoom)), // 设置位置
  8950. orientation: {
  8951. heading: map3DHeading, // 方向
  8952. pitch: map3DViewer.getPitchForPi(map23DData.view.pitch), // 倾斜角度
  8953. roll: 0
  8954. }
  8955. })
  8956. map23DData.mouseIn = '3D';
  8957. PubSub.publish('map3D.setView', {
  8958. from: '3D'
  8959. })
  8960. }
  8961. //飞行到指定位置
  8962. map3DViewer.flyTo = function (options, callback) {
  8963. _.merge(map23DData.view, options);
  8964. var newlatlng = map23DData.view.center;
  8965. var map3DHeading = map3DViewer.getHeadingForPi(map23DData.view.heading);
  8966. //longitude, latitude, altitude, dHeading, dTilt, dDistance, altMode
  8967. map3DViewer.map.camera.flyTo({
  8968. destination: Cesium.Cartesian3.fromDegrees(newlatlng.lng, newlatlng.lat, map3DViewer.getZoomFrom2DZoom(map23DData.view.zoom)), // 设置位置
  8969. orientation: {
  8970. heading: map3DHeading, // 方向
  8971. pitch: map3DViewer.getPitchForPi(map23DData.view.pitch), // 倾斜角度
  8972. roll: 0
  8973. },
  8974. duration: 5,
  8975. complete: function () {
  8976. if (callback) {
  8977. callback();
  8978. }
  8979. },
  8980. pitchAdjustHeight: -90, // 如果摄像机飞越高于该值,则调整俯仰俯仰的俯仰角度,并将地球保持在视口中。
  8981. maximumHeight: 150000, // 相机最大飞行高度
  8982. //flyOverLongitude: 100, // 如果到达目的地有2种方式,设置具体值后会强制选择方向飞过这个经度
  8983. })
  8984. map23DData.mouseIn = '3D';
  8985. PubSub.publish('map3D.setView', {
  8986. from: '3D'
  8987. })
  8988. }
  8989. map3DViewer.getHeadingForPi = function (num) {
  8990. num = 360 - Math.abs(num);
  8991. num = num / 180 * Math.PI;
  8992. return num;
  8993. }
  8994. map3DViewer.getHeadingForTangle = function (num) {
  8995. num = parseInt(num * 180 / Math.PI);
  8996. return num;
  8997. }
  8998. map3DViewer.getPitchForPi = function (num) {
  8999. num = 0 - Math.abs(num);
  9000. num = num / 180 * Math.PI;
  9001. return num;
  9002. }
  9003. map3DViewer.getPitchForTangle = function (num) {
  9004. num = num * 180 / Math.PI;
  9005. return num;
  9006. }
  9007. map3DViewer.getZoomFrom2DZoom = function (zoom) {
  9008. var RoraTilt = map23DData.view.pitch;
  9009. return Math.abs(this.zoomAry[map23DData.view.zoom] * 1000 * Math.sin(RoraTilt));
  9010. }
  9011. map3DViewer.getZoomFrom3DZoom = function (distance) {
  9012. distance = distance / 1000;
  9013. for (var i = 0, len = this.zoomAry.length; i < len; i++) {
  9014. var max = (this.zoomAry[i] + this.zoomAry[i - 1]) / 2;
  9015. var min = (this.zoomAry[i] + this.zoomAry[i + 1]) / 2;
  9016. if (distance < max && distance > min) {
  9017. return i;
  9018. }
  9019. }
  9020. }
  9021. /**
  9022. * 获取3D视角中心点
  9023. */
  9024. map3DViewer.get3DViewCenter = function () {
  9025. var S2dx = $('#map3DWrap').width() / 2; //3D视图容器宽度的二分之一
  9026. var S2dy = $('#map3DWrap').height() / 2; //3D视图容器高度的二分之一
  9027. var x = parseInt(S2dx);
  9028. var y = parseInt(S2dy);
  9029. var curPosition = map3DViewer.screenToLatLng(x, y);
  9030. var camera = map3DViewer.map.camera.position;
  9031. var height = map3DViewer.Cartesian3ToLatLng(camera.x, camera.y, camera.z);
  9032. height = height.alt
  9033. if (curPosition) {
  9034. return {
  9035. lng: curPosition.lng,
  9036. lat: curPosition.lat,
  9037. alt: height
  9038. };
  9039. } else {
  9040. return false;
  9041. }
  9042. }
  9043. map3DViewer.screenToLatLng = function (x, y) {
  9044. var pick1 = new Cesium.Cartesian2(x, y);
  9045. var cartesian = map3DViewer.map.scene.globe.pick(map3DViewer.map.camera.getPickRay(pick1), map3DViewer.map.scene);
  9046. if (cartesian) {
  9047. var cartographic = map3DViewer.map.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
  9048. var lat = Cesium.Math.toDegrees(cartographic.latitude);
  9049. var lng = Cesium.Math.toDegrees(cartographic.longitude);
  9050. var alt = cartographic.height;
  9051. var position = {
  9052. lat: lat,
  9053. lng: lng,
  9054. alt: alt
  9055. }
  9056. } else {
  9057. var position = false
  9058. }
  9059. return position;
  9060. }
  9061. //世界坐标转经纬度坐标
  9062. map3DViewer.Cartesian3ToLatLng = function (x, y, z) {
  9063. var ellipsoid = map3DViewer.map.scene.globe.ellipsoid;
  9064. var Cartesian3 = new Cesium.Cartesian3(x, y, z);
  9065. var cartographic = ellipsoid.cartesianToCartographic(Cartesian3);
  9066. var lat = Cesium.Math.toDegrees(cartographic.latitude);
  9067. var lng = Cesium.Math.toDegrees(cartographic.longitude);
  9068. var alt = cartographic.height;
  9069. var position = {
  9070. lat: lat,
  9071. lng: lng,
  9072. alt: alt
  9073. }
  9074. return position;
  9075. }
  9076. //获取视角高度及经纬度
  9077. map3DViewer.getCurCameraInfos = function () {
  9078. var curPosition = map3DViewer.map.camera.position;
  9079. curPosition = map3DViewer.Cartesian3ToLatLng(curPosition.x, curPosition.y, curPosition.z);
  9080. return curPosition;
  9081. };
  9082. map3DViewer.Cartesian3ToScreen = function (cartesian) {
  9083. var pick = Cesium.SceneTransforms.wgs84ToWindowCoordinates(map3DViewer.map.scene, cartesian);
  9084. return pick;
  9085. }
  9086. //设置当前时区
  9087. map3DViewer.setClock = function (viewer) {
  9088. var d = new Date();
  9089. var hour = 0 - d.getTimezoneOffset();
  9090. viewer.animation.viewModel.timeFormatter = function (date, viewModel) {
  9091. var dateZone8 = Cesium.JulianDate.addMinutes(date, hour, new Cesium.JulianDate());
  9092. var gregorianDate = Cesium.JulianDate.toGregorianDate(dateZone8);
  9093. if (Math.abs(viewModel._clockViewModel.multiplier) < 1) {
  9094. return Cesium.sprintf("%02d:%02d:%02d.%03d;", gregorianDate.hour, gregorianDate.minute, gregorianDate.second);
  9095. }
  9096. return Cesium.sprintf("%02d:%02d:%02d GMT+8", gregorianDate.hour, gregorianDate.minute, gregorianDate.second);
  9097. };
  9098. }
  9099. // //3D绑定Label
  9100. // map3DViewer.label = function (options) {
  9101. // switch (options.action) {
  9102. // case 'add':
  9103. // return PubSub.publishSync('map3D.label.add', options);
  9104. // break;
  9105. // case 'remove':
  9106. // return PubSub.publishSync('map3D.label.remove', options);
  9107. // break;
  9108. // case 'update':
  9109. // return PubSub.publishSync('map3D.label.update', options);
  9110. // break;
  9111. // }
  9112. // }
  9113. //3D 组
  9114. map3DViewer.group = function (options) {
  9115. switch (options.action) {
  9116. case 'add':
  9117. return addGroup3D(options);
  9118. break;
  9119. case 'remove':
  9120. return removeGroup3D(options);
  9121. break;
  9122. case 'hide':
  9123. return hideGroup3D(options);
  9124. break;
  9125. case 'show':
  9126. return showGroup3D(options);
  9127. break;
  9128. case 'cleanAll':
  9129. return operationGroup3D(options, 'remove');
  9130. break;
  9131. }
  9132. }
  9133. function addGroup3D(options) {
  9134. var guid = options.guid || map23DControl.buildGuid('group3D');
  9135. var defaultData = _.cloneDeep(map23DDefaultData.group)
  9136. defaultData.guid = guid;
  9137. defaultData.from = '3D';
  9138. _.merge(defaultData, options);
  9139. map23DData.groups[guid] = defaultData;
  9140. PubSub.publishSync('map3D.group.add', guid);
  9141. return guid;
  9142. }
  9143. function removeGroup3D(options) {
  9144. if (map23DData.groups[options.guid]) {
  9145. operationGroup3D(options, "remove");
  9146. PubSub.publishSync('map3D.group.remove', options.guid);
  9147. if (map23DData.groups[options.guid].add2D == false) {
  9148. delete map23DData.groups[options.guid];
  9149. }
  9150. return options.guid;
  9151. } else {
  9152. return false;
  9153. }
  9154. }
  9155. function showGroup3D(options) {
  9156. if (map23DData.groups[options.guid]) {
  9157. operationGroup3D(options, "show");
  9158. PubSub.publishSync('map3D.group.show', options.guid);
  9159. return options.guid;
  9160. } else {
  9161. return false;
  9162. }
  9163. }
  9164. function hideGroup3D(options) {
  9165. if (map23DData.groups[options.guid]) {
  9166. operationGroup3D(options, "hide");
  9167. PubSub.publishSync('map3D.group.hide', options.guid);
  9168. return options.guid;
  9169. } else {
  9170. return false;
  9171. }
  9172. }
  9173. function operationGroup3D(options, action) {
  9174. if (map23DData.groups[options.guid]) {
  9175. //点
  9176. _(map23DData.markers).forEach(function (item, key) {
  9177. if (item.groupId == options.guid) {
  9178. map3DViewer.marker({
  9179. action: action,
  9180. guid: key
  9181. })
  9182. }
  9183. });
  9184. //线
  9185. _(map23DData.polylines).forEach(function (item, key) {
  9186. if (item.groupId == options.guid) {
  9187. map3DViewer.polyline({
  9188. action: action,
  9189. guid: key
  9190. })
  9191. }
  9192. });
  9193. //移除面
  9194. _(map23DData.polygons).forEach(function (item, key) {
  9195. if (item.groupId == options.guid) {
  9196. map3DViewer.polygon({
  9197. action: action,
  9198. guid: key
  9199. })
  9200. }
  9201. });
  9202. //圆
  9203. _(map23DData.circles).forEach(function (item, key) {
  9204. if (item.groupId == options.guid) {
  9205. map3DViewer.circle({
  9206. action: action,
  9207. guid: key
  9208. })
  9209. }
  9210. });
  9211. //模型
  9212. _(map23DData.models).forEach(function (item, key) {
  9213. if (item.groupId == options.guid) {
  9214. map3DViewer.model({
  9215. action: action,
  9216. guid: key
  9217. })
  9218. }
  9219. });
  9220. return options.guid;
  9221. } else {
  9222. return false
  9223. }
  9224. }
  9225. //3D 点
  9226. map3DViewer.marker = function (options) {
  9227. switch (options.action) {
  9228. case 'add':
  9229. return addMarker3D(options);
  9230. break;
  9231. case 'remove':
  9232. return removeMarker3D(options);
  9233. break;
  9234. case 'update':
  9235. return updateMarker3D(options);
  9236. break;
  9237. case 'show':
  9238. return showMarker3D(options);
  9239. break;
  9240. case 'hide':
  9241. return hideMarker3D(options);
  9242. break;
  9243. }
  9244. }
  9245. function addMarker3D(options) {
  9246. var guid = options.guid || map23DControl.buildGuid('marker3D');
  9247. var defaultData = _.cloneDeep(map23DDefaultData.marker)
  9248. defaultData.guid = guid;
  9249. defaultData.from = '3D';
  9250. _.merge(defaultData, options);
  9251. map23DData.markers[guid] = defaultData;
  9252. PubSub.publishSync('map3D.marker.add', guid);
  9253. return guid;
  9254. }
  9255. function removeMarker3D(options) {
  9256. if (map23DData.markers[options.guid]) {
  9257. PubSub.publishSync('map3D.marker.remove', options.guid);
  9258. if (map23DData.markers[options.guid].add2D == false) {
  9259. delete map23DData.markers[options.guid];
  9260. }
  9261. return options.guid;
  9262. } else {
  9263. return false;
  9264. }
  9265. }
  9266. function updateMarker3D(options) {
  9267. if (map23DData.markers[options.guid]) {
  9268. _.merge(map23DData.markers[options.guid], options);
  9269. if (options.geojson.geometry) {
  9270. if (options.geojson.geometry.coordinates)
  9271. map23DData.markers[options.guid].geojson.geometry.coordinates = options.geojson.geometry.coordinates
  9272. }
  9273. PubSub.publishSync('map3D.marker.update', options.guid);
  9274. return options.guid;
  9275. } else {
  9276. return false;
  9277. }
  9278. }
  9279. function showMarker3D(options) {
  9280. if (map23DData.markers[options.guid]) {
  9281. PubSub.publishSync('map3D.marker.show', options.guid);
  9282. return options.guid;
  9283. } else {
  9284. return false;
  9285. }
  9286. }
  9287. function hideMarker3D(options) {
  9288. if (map23DData.markers[options.guid]) {
  9289. PubSub.publishSync('map3D.marker.hide', options.guid);
  9290. return options.guid;
  9291. } else {
  9292. return false;
  9293. }
  9294. }
  9295. //3D 线
  9296. map3DViewer.polyline = function (options) {
  9297. switch (options.action) {
  9298. case 'add':
  9299. return addPolyline3D(options);
  9300. break;
  9301. case 'remove':
  9302. return removePolyline3D(options);
  9303. break;
  9304. case 'update':
  9305. return updatePolyline3D(options);
  9306. break;
  9307. case 'show':
  9308. return showPolyline3D(options);
  9309. break;
  9310. case 'hide':
  9311. return hidePolyline3D(options);
  9312. break;
  9313. }
  9314. }
  9315. function addPolyline3D(options) {
  9316. var guid = options.guid || map23DControl.buildGuid('polyline3D');
  9317. var defaultData = _.cloneDeep(map23DDefaultData.polyline)
  9318. defaultData.guid = guid;
  9319. defaultData.from = '3D';
  9320. _.merge(defaultData, options);
  9321. map23DData.polylines[guid] = defaultData;
  9322. PubSub.publishSync('map3D.polyline.add', guid);
  9323. return guid;
  9324. }
  9325. function removePolyline3D(options) {
  9326. if (map23DData.polylines[options.guid]) {
  9327. PubSub.publishSync('map3D.polyline.remove', options.guid);
  9328. if (map23DData.polylines[options.guid].add2D == false) {
  9329. delete map23DData.polylines[options.guid];
  9330. }
  9331. return options.guid;
  9332. } else {
  9333. return false;
  9334. }
  9335. }
  9336. function updatePolyline3D(options) {
  9337. if (map23DData.polylines[options.guid]) {
  9338. _.merge(map23DData.polylines[options.guid], options);
  9339. if (options.geojson.geometry) {
  9340. if (options.geojson.geometry.coordinates)
  9341. map23DData.polylines[options.guid].geojson.geometry.coordinates = options.geojson.geometry.coordinates
  9342. }
  9343. PubSub.publishSync('map3D.polyline.update', options.guid);
  9344. return options.guid;
  9345. } else {
  9346. return false;
  9347. }
  9348. }
  9349. function showPolyline3D(options) {
  9350. if (map23DData.polylines[options.guid]) {
  9351. PubSub.publishSync('map3D.polyline.show', options.guid);
  9352. return options.guid;
  9353. } else {
  9354. return false;
  9355. }
  9356. }
  9357. function hidePolyline3D(options) {
  9358. if (map23DData.polylines[options.guid]) {
  9359. PubSub.publishSync('map3D.polyline.hide', options.guid);
  9360. return options.guid;
  9361. } else {
  9362. return false;
  9363. }
  9364. }
  9365. //3D 面
  9366. map3DViewer.polygon = function (options) {
  9367. switch (options.action) {
  9368. case 'add':
  9369. return addPolygon3D(options);
  9370. break;
  9371. case 'remove':
  9372. return removePolygon3D(options);
  9373. break;
  9374. case 'update':
  9375. return updatePolygon3D(options);
  9376. break;
  9377. case 'show':
  9378. return showPolygon3D(options);
  9379. break;
  9380. case 'hide':
  9381. return hidePolygon3D(options);
  9382. break;
  9383. }
  9384. }
  9385. function addPolygon3D(options) {
  9386. var guid = options.guid || map23DControl.buildGuid('polygon3D');
  9387. var defaultData = _.cloneDeep(map23DDefaultData.polyline)
  9388. defaultData.guid = guid;
  9389. defaultData.from = '3D';
  9390. _.merge(defaultData, options);
  9391. map23DData.polygons[guid] = defaultData;
  9392. PubSub.publishSync('map3D.polygon.add', guid);
  9393. return guid;
  9394. }
  9395. function removePolygon3D(options) {
  9396. if (map23DData.polygons[options.guid]) {
  9397. PubSub.publishSync('map3D.polygon.remove', options.guid);
  9398. if (map23DData.polygons[options.guid].add2D == false) {
  9399. delete map23DData.polygons[options.guid];
  9400. }
  9401. return options.guid;
  9402. } else {
  9403. return false;
  9404. }
  9405. }
  9406. function updatePolygon3D(options) {
  9407. if (map23DData.polygons[options.guid]) {
  9408. _.merge(map23DData.polygons[options.guid], options);
  9409. if (options.geojson.geometry) {
  9410. if (options.geojson.geometry.coordinates)
  9411. map23DData.polygons[options.guid].geojson.geometry.coordinates = options.geojson.geometry.coordinates
  9412. }
  9413. PubSub.publishSync('map3D.polygon.update', options.guid);
  9414. return options.guid;
  9415. } else {
  9416. return false;
  9417. }
  9418. }
  9419. function showPolygon3D(options) {
  9420. if (map23DData.polygons[options.guid]) {
  9421. PubSub.publishSync('map3D.polygon.show', options.guid);
  9422. return options.guid;
  9423. } else {
  9424. return false;
  9425. }
  9426. }
  9427. function hidePolygon3D(options) {
  9428. if (map23DData.polygons[options.guid]) {
  9429. PubSub.publishSync('map3D.polygon.hide', options.guid);
  9430. return options.guid;
  9431. } else {
  9432. return false;
  9433. }
  9434. }
  9435. //3D 圆
  9436. map3DViewer.circle = function (options) {
  9437. switch (options.action) {
  9438. case 'add':
  9439. return addCircle3D(options);
  9440. break;
  9441. case 'remove':
  9442. return removeCircle3D(options);
  9443. break;
  9444. case 'update':
  9445. return updateCircle3D(options);
  9446. break;
  9447. case 'show':
  9448. return showCircle3D(options);
  9449. break;
  9450. case 'hide':
  9451. return hideCircle3D(options);
  9452. break;
  9453. }
  9454. }
  9455. function addCircle3D(options) {
  9456. var guid = options.guid || map23DControl.buildGuid('circle3D');
  9457. var defaultData = _.cloneDeep(map23DDefaultData.circle)
  9458. defaultData.guid = guid;
  9459. defaultData.from = '3D';
  9460. _.merge(defaultData, options);
  9461. map23DData.circles[guid] = defaultData;
  9462. PubSub.publishSync('map3D.circle.add', guid);
  9463. return guid;
  9464. }
  9465. function removeCircle3D(options) {
  9466. if (map23DData.circles[options.guid]) {
  9467. PubSub.publishSync('map3D.circle.remove', options.guid);
  9468. if (map23DData.circles[options.guid].add2D == false) {
  9469. delete map23DData.circles[options.guid];
  9470. }
  9471. return options.guid;
  9472. } else {
  9473. return false;
  9474. }
  9475. }
  9476. function updateCircle3D(options) {
  9477. if (map23DData.circles[options.guid]) {
  9478. _.merge(map23DData.circles[options.guid], options);
  9479. if (options.geojson.geometry) {
  9480. if (options.geojson.geometry.coordinates)
  9481. map23DData.circles[options.guid].geojson.geometry.coordinates = options.geojson.geometry.coordinates
  9482. }
  9483. PubSub.publishSync('map3D.circle.update', options.guid);
  9484. return options.guid;
  9485. } else {
  9486. return false;
  9487. }
  9488. }
  9489. function showCircle3D(options) {
  9490. if (map23DData.circles[options.guid]) {
  9491. PubSub.publishSync('map3D.circle.show', options.guid);
  9492. return options.guid;
  9493. } else {
  9494. return false;
  9495. }
  9496. }
  9497. function hideCircle3D(options) {
  9498. if (map23DData.circles[options.guid]) {
  9499. PubSub.publishSync('map3D.circle.hide', options.guid);
  9500. return options.guid;
  9501. } else {
  9502. return false;
  9503. }
  9504. }
  9505. //三维模型
  9506. map3DViewer.model = function (options) {
  9507. switch (options.action) {
  9508. case 'add':
  9509. return addModel3D(options);
  9510. break;
  9511. case 'update':
  9512. return updateModel3D(options);
  9513. break;
  9514. case 'remove':
  9515. return removeModel3D(options);
  9516. break;
  9517. case 'show':
  9518. return showModel3D(options);
  9519. break;
  9520. case 'hide':
  9521. return hideModel3D(options);
  9522. break;
  9523. }
  9524. }
  9525. function addModel3D(options) {
  9526. var guid = options.guid || map23DControl.buildGuid('model3D');
  9527. var defaultData = _.cloneDeep(map23DDefaultData.model)
  9528. defaultData.guid = guid;
  9529. defaultData.from = '3D';
  9530. _.merge(defaultData, options);
  9531. map23DData.models[guid] = defaultData;
  9532. PubSub.publishSync('map3D.model.add', guid);
  9533. return guid;
  9534. }
  9535. function removeModel3D(options) {
  9536. if (map23DData.models[options.guid]) {
  9537. _.merge(map23DData.models[options.guid], options);
  9538. PubSub.publish('map3D.model.remove', options.guid);
  9539. return options.guid;
  9540. } else {
  9541. return false;
  9542. }
  9543. }
  9544. function updateModel3D(options) {
  9545. if (map23DData.models[options.guid]) {
  9546. _.merge(map23DData.models[options.guid], options);
  9547. if (options.geojson.geometry) {
  9548. if (options.geojson.geometry.coordinates)
  9549. map23DData.models[options.guid].geojson.geometry.coordinates = options.geojson.geometry.coordinates
  9550. }
  9551. if (options.geojson.properties) {
  9552. if (options.geojson.properties.timeLine)
  9553. map23DData.models[options.guid].geojson.properties.timeLine = options.geojson.properties.timeLine
  9554. if (options.geojson.properties.altitude)
  9555. map23DData.models[options.guid].geojson.properties.altitude = options.geojson.properties.altitude
  9556. }
  9557. PubSub.publishSync('map3D.model.update', options.guid);
  9558. return options.guid;
  9559. } else {
  9560. return false;
  9561. }
  9562. }
  9563. function showModel3D(options) {
  9564. if (map23DData.models[options.guid]) {
  9565. PubSub.publishSync('map3D.model.show', options.guid);
  9566. return options.guid;
  9567. } else {
  9568. return false;
  9569. }
  9570. }
  9571. function hideModel3D(options) {
  9572. if (map23DData.models[options.guid]) {
  9573. PubSub.publishSync('map3D.model.hide', options.guid);
  9574. return options.guid;
  9575. } else {
  9576. return false;
  9577. }
  9578. }
  9579. //图片
  9580. map3DViewer.imageOverlay = function (options) {
  9581. switch (options.action) {
  9582. case 'add':
  9583. return addImageOverlay3D(options);
  9584. break;
  9585. case 'remove':
  9586. return removeImageOverlay3D(options);
  9587. break;
  9588. case 'update':
  9589. return updateImageOverlay3D(options);
  9590. break;
  9591. case 'hide':
  9592. return hideImageOverlay3D(options);
  9593. break;
  9594. case 'show':
  9595. return showImageOverlay3D(options);
  9596. break;
  9597. }
  9598. }
  9599. function addImageOverlay3D(options) {
  9600. var guid = options.guid || map23DControl.buildGuid('imageOverlay23D');
  9601. var defaultData = _.cloneDeep(map23DDefaultData.imageOverlay)
  9602. defaultData.guid = guid;
  9603. _.merge(defaultData, options);
  9604. map23DData.imageOverlays[guid] = defaultData;
  9605. PubSub.publishSync('map3D.imageOverlay.add', guid);
  9606. return guid;
  9607. }
  9608. /**
  9609. * 移除图层组,移除前先清除图层组中的元素
  9610. * @param {[type]} options [description]
  9611. * @return {[type]} [description]
  9612. */
  9613. function removeImageOverlay3D(options) {
  9614. if (map23DData.imageOverlays[options.guid]) {
  9615. PubSub.publishSync('map3D.imageOverlay.remove', options.guid);
  9616. delete map23DData.imageOverlays[options.guid];
  9617. return options.guid;
  9618. } else {
  9619. return false;
  9620. }
  9621. }
  9622. function updateImageOverlay3D(options) {
  9623. if (map23DData.imageOverlays[options.guid]) {
  9624. _.merge(map23DData.imageOverlays[options.guid], options);
  9625. PubSub.publishSync('map3D.imageOverlay.update', options.guid);
  9626. return options.guid;
  9627. } else {
  9628. return false;
  9629. }
  9630. }
  9631. function showImageOverlay3D(options) {
  9632. if (map23DData.imageOverlays[options.guid]) {
  9633. _.merge(map23DData.imageOverlays[options.guid], options);
  9634. PubSub.publishSync('map3D.imageOverlay.show', options.guid);
  9635. return options.guid;
  9636. } else {
  9637. return false;
  9638. }
  9639. }
  9640. function hideImageOverlay3D(options) {
  9641. if (map23DData.imageOverlays[options.guid]) {
  9642. _.merge(map23DData.imageOverlays[options.guid], options);
  9643. PubSub.publishSync('map3D.imageOverlay.hide', options.guid);
  9644. return options.guid;
  9645. } else {
  9646. return false;
  9647. }
  9648. }
  9649. /**
  9650. * 设置系统自带图层
  9651. * @param {[type]} options [description]
  9652. */
  9653. map3DViewer.setDefaultTileLayer = function (options) {
  9654. PubSub.publish('map3D.defaultTileLayer.change', {
  9655. mapName: options
  9656. })
  9657. }
  9658. //3D瓦片图层
  9659. map3DViewer.tileLayer = function (options) {
  9660. switch (options.action) {
  9661. case 'add':
  9662. return addTileLayer3D(options);
  9663. break;
  9664. case 'remove':
  9665. return removeTileLayer3D(options);
  9666. break;
  9667. case 'update':
  9668. return updateTileLayer3D(options);
  9669. break;
  9670. case 'hide':
  9671. return hideTileLayer3D(options);
  9672. break;
  9673. case 'show':
  9674. return showTileLayer3D(options);
  9675. break;
  9676. }
  9677. }
  9678. function addTileLayer3D(options) {
  9679. var guid = options.guid || map23DControl.buildGuid('tileLayer3D');
  9680. var defaultData = _.cloneDeep(map23DDefaultData.layer)
  9681. defaultData.guid = guid;
  9682. defaultData.from = '3D';
  9683. _.merge(defaultData, options);
  9684. map23DData.layers[guid] = defaultData;
  9685. PubSub.publishSync('map3D.tileLayer.add', guid);
  9686. return guid;
  9687. }
  9688. function removeTileLayer3D(options) {
  9689. if (map23DData.layers[options.guid]) {
  9690. PubSub.publishSync('map3D.tileLayer.remove', options.guid);
  9691. if (map23DData.layers[options.guid].add2D == false) {
  9692. delete map23DData.layers[options.guid];
  9693. }
  9694. return options.guid;
  9695. } else {
  9696. return false;
  9697. }
  9698. }
  9699. function updateTileLayer3D(options) {
  9700. if (map23DData.layers[options.guid]) {
  9701. _.merge(map23DData.layers[options.guid], options);
  9702. PubSub.publishSync('map3D.tileLayer.update', options.guid);
  9703. return options.guid;
  9704. } else {
  9705. return false;
  9706. }
  9707. }
  9708. function showTileLayer3D(options) {
  9709. if (map3DViewer.layers[options.guid]) {
  9710. PubSub.publishSync('map3D.tileLayer.show', options.guid);
  9711. return options.guid;
  9712. } else {
  9713. return false;
  9714. }
  9715. }
  9716. function hideTileLayer3D(options) {
  9717. if (map3DViewer.layers[options.guid]) {
  9718. PubSub.publishSync('map3D.tileLayer.hide', options.guid);
  9719. return options.guid;
  9720. } else {
  9721. return false;
  9722. }
  9723. }
  9724. //3D DEM
  9725. map3DViewer.DEMTileLayer = function (options) {
  9726. switch (options.action) {
  9727. case 'add':
  9728. return addDEMTileLayer3D(options);
  9729. break;
  9730. case 'remove':
  9731. return removeDEMTileLayer3D(options);
  9732. break;
  9733. }
  9734. }
  9735. function addDEMTileLayer3D(options) {
  9736. var guid = options.guid || map23DControl.buildGuid('DEMTileLayer3D');
  9737. var defaultData = _.cloneDeep(map23DDefaultData.DEMLayer)
  9738. defaultData.guid = guid;
  9739. defaultData.from = '3D';
  9740. _.merge(defaultData, options);
  9741. map23DData.DEMLayers[guid] = defaultData;
  9742. PubSub.publishSync('map3D.DEMTileLayer.add', guid);
  9743. return guid;
  9744. }
  9745. function removeDEMTileLayer3D(options) {
  9746. if (map23DData.DEMLayers[options.guid]) {
  9747. PubSub.publishSync('map3D.DEMTileLayer.remove', options.guid);
  9748. if (map23DData.DEMLayers[options.guid].add2D == false) {
  9749. delete map23DData.DEMLayers[options.guid];
  9750. }
  9751. return options.guid;
  9752. } else {
  9753. return false;
  9754. }
  9755. }
  9756. //3D 测距
  9757. //callback 完成绘制后是否继续保持激活该工具 默认保持
  9758. map3DViewer.measureDistance = function (options) {
  9759. switch (options.action) {
  9760. case 'add':
  9761. return addMeasureDistance3D(options);
  9762. break;
  9763. case 'remove':
  9764. return removeMeasureDistance3D(options);
  9765. break;
  9766. case 'clear':
  9767. return clearMeasureDistance3D(options);
  9768. break;
  9769. }
  9770. }
  9771. function addMeasureDistance3D(options) {
  9772. PubSub.publishSync('map3D.measureDistance.add', {
  9773. action: options.action,
  9774. viewer: map3DViewer.map
  9775. });
  9776. }
  9777. function removeMeasureDistance3D(options) {
  9778. PubSub.publishSync('map3D.measureDistance.remove', false);
  9779. }
  9780. function clearMeasureDistance3D(options) {
  9781. PubSub.publishSync('map3D.measureDistance.clear');
  9782. }
  9783. //3D 测面
  9784. map3DViewer.measureArea = function (options) {
  9785. switch (options.action) {
  9786. case 'add':
  9787. return addMeasureArea3D(options);
  9788. break;
  9789. case 'remove':
  9790. return removeMeasureArea3D(options);
  9791. break;
  9792. case 'clear':
  9793. return clearMeasureArea3D(options);
  9794. break;
  9795. }
  9796. }
  9797. function addMeasureArea3D(options) {
  9798. PubSub.publishSync('map3D.measureArea.add', {
  9799. action: options.action,
  9800. viewer: map3DViewer.map
  9801. });
  9802. }
  9803. function removeMeasureArea3D(options) {
  9804. PubSub.publishSync('map3D.measureArea.remove', false);
  9805. }
  9806. function clearMeasureArea3D(options) {
  9807. PubSub.publishSync('map3D.measureArea.clear');
  9808. }
  9809. // //3D 测高
  9810. // map3DViewer.measureHeight = function (options) {
  9811. // switch (options.action) {
  9812. // case 'add':
  9813. // return addMeasureHeight3D(options);
  9814. // break;
  9815. // case 'remove':
  9816. // return removeMeasureHeight3D(options);
  9817. // break;
  9818. // case 'clear':
  9819. // return clearMeasureHeight3D(options);
  9820. // break;
  9821. // }
  9822. // }
  9823. function addMeasureHeight3D(options) {
  9824. PubSub.publishSync('map3D.measureHeight.add', {
  9825. action: options.action,
  9826. viewer: map3DViewer.map
  9827. });
  9828. }
  9829. function removeMeasureHeight3D(options) {
  9830. PubSub.publishSync('map3D.measureHeight.remove', false);
  9831. }
  9832. function clearMeasureHeight3D(options) {
  9833. PubSub.publishSync('map3D.measureHeight.clear');
  9834. }
  9835. // 3D 通视分析
  9836. map3DViewer.visualAnalysis = function (options) {
  9837. switch (options.action) {
  9838. case 'add':
  9839. return addVisualAnalysis3D(options);
  9840. break;
  9841. case 'start':
  9842. return startVisualAnalysis3D(options);
  9843. break;
  9844. case 'stop':
  9845. return stopVisualAnalysis3D(options);
  9846. break;
  9847. case 'remove':
  9848. return removeVisualAnalysis3D(options);
  9849. break;
  9850. case 'clear':
  9851. return clearVisualAnalysis3D(options);
  9852. break;
  9853. }
  9854. }
  9855. function addVisualAnalysis3D(options) {
  9856. PubSub.publishSync('map3D.visualAnalysis.add', {
  9857. viewer: map3DViewer.map,
  9858. callback: options.callback
  9859. });
  9860. }
  9861. function startVisualAnalysis3D(options) {
  9862. PubSub.publishSync('map3D.visualAnalysis.start', {
  9863. viewHeight: options.viewHeight
  9864. });
  9865. }
  9866. function stopVisualAnalysis3D(options) {
  9867. PubSub.publishSync('map3D.visualAnalysis.stop', {});
  9868. }
  9869. function removeVisualAnalysis3D(options) {
  9870. PubSub.publishSync('map3D.visualAnalysis.remove', {});
  9871. }
  9872. function clearVisualAnalysis3D(options) {
  9873. PubSub.publishSync('map3D.visualAnalysis.clear', {});
  9874. }
  9875. // 3D 环视分析
  9876. map3DViewer.lookAroundAnalysis = function (options) {
  9877. switch (options.action) {
  9878. case 'add':
  9879. return addLookAroundAnalysis3D(options);
  9880. break;
  9881. case 'draw':
  9882. return drawLookAroundAnalysis3D(options);
  9883. break;
  9884. case 'start':
  9885. return startLookAroundAnalysis3D(options);
  9886. break;
  9887. case 'stop':
  9888. return stopLookAroundAnalysis3D(options);
  9889. break;
  9890. case 'remove':
  9891. return removeLookAroundAnalysis3D(options);
  9892. break;
  9893. case 'clear':
  9894. return clearLookAroundAnalysis3D(options);
  9895. break;
  9896. }
  9897. }
  9898. function addLookAroundAnalysis3D(options) {
  9899. PubSub.publishSync('map3D.lookAroundAnalysis.add', {
  9900. viewer: map3DViewer.map,
  9901. callback: options.callback
  9902. });
  9903. }
  9904. function drawLookAroundAnalysis3D(options) {
  9905. PubSub.publishSync('map3D.lookAroundAnalysis.draw', {
  9906. lng: options.lng,
  9907. lat: options.lat,
  9908. distance: options.distance,
  9909. viewHeight: options.viewHeight,
  9910. angleInterval: options.angleInterval
  9911. });
  9912. }
  9913. function startLookAroundAnalysis3D(options) {
  9914. PubSub.publishSync('map3D.lookAroundAnalysis.start', {
  9915. viewHeight: options.viewHeight,
  9916. angleInterval: options.angleInterval
  9917. });
  9918. }
  9919. function stopLookAroundAnalysis3D(options) {
  9920. PubSub.publishSync('map3D.lookAroundAnalysis.stop', {});
  9921. }
  9922. function removeLookAroundAnalysis3D(options) {
  9923. PubSub.publishSync('map3D.lookAroundAnalysis.remove', {});
  9924. }
  9925. function clearLookAroundAnalysis3D(options) {
  9926. PubSub.publishSync('map3D.lookAroundAnalysis.clear', {});
  9927. }
  9928. // 模拟飞行
  9929. map3DViewer.flightSimulation = function (options) {
  9930. switch (options.action) {
  9931. case 'add':
  9932. return addFlightSimulation3D(options);
  9933. break;
  9934. case 'changeView':
  9935. return changeViewFlightSimulation3D(options);
  9936. break;
  9937. }
  9938. }
  9939. function addFlightSimulation3D(options) {
  9940. delete options.action
  9941. var obj = Object.assign({}, {
  9942. viewer: map3DViewer.map
  9943. }, options);
  9944. PubSub.publishSync('map3D.flightSimulation.add', obj);
  9945. }
  9946. function changeViewFlightSimulation3D(options) {
  9947. delete options.action
  9948. PubSub.publishSync('map3D.flightSimulation.changeView', options);
  9949. }
  9950. // 3D 环视分析
  9951. map3DViewer.measureElevation = function (options) {
  9952. switch (options.action) {
  9953. case 'add':
  9954. return addMeasureElevation3D(options);
  9955. break;
  9956. case 'remove':
  9957. return removeMeasureElevation3D(options);
  9958. break;
  9959. case 'clear':
  9960. return clearMeasureElevation3D(options);
  9961. break;
  9962. }
  9963. }
  9964. function addMeasureElevation3D(options) {
  9965. var obj = Object.assign({}, {
  9966. viewer: map3DViewer.map
  9967. }, options);
  9968. PubSub.publishSync('map3D.measureElevation.add', obj);
  9969. }
  9970. function removeMeasureElevation3D(options) {
  9971. PubSub.publishSync('map3D.measureElevation.remove', {});
  9972. }
  9973. function clearMeasureElevation3D(options) {
  9974. PubSub.publishSync('map3D.measureElevation.clear', {});
  9975. }
  9976. }(window, document));
  9977. ;
  9978. (function (window, document, undefined) {
  9979. var group = map23DControl.group;
  9980. if (typeof module === 'object' && typeof module.exports === 'object') {
  9981. module.exports = group;
  9982. } else if (typeof define === 'function' && define.amd) {
  9983. define(group);
  9984. }
  9985. map23DControl.group = function (options) {
  9986. switch (options.action) {
  9987. case 'add':
  9988. return addgroup(options);
  9989. break;
  9990. case 'hide':
  9991. return hidegroup(options);
  9992. break;
  9993. case 'show':
  9994. return showgroup(options);
  9995. break;
  9996. case 'remove':
  9997. return removegroup(options);
  9998. break;
  9999. case 'cleanAll':
  10000. return operationGroup(options, 'remove');
  10001. break;
  10002. }
  10003. }
  10004. function addgroup(options) {
  10005. var guid = options.guid || map23DControl.buildGuid('group23D');
  10006. var defaultData = _.cloneDeep(map23DDefaultData.group)
  10007. defaultData.guid = guid;
  10008. defaultData.from = '23D';
  10009. _.merge(defaultData, options);
  10010. map23DData.groups[guid] = defaultData;
  10011. PubSub.publishSync('map23D.group.add', guid);
  10012. return guid;
  10013. }
  10014. /**
  10015. * 移除图层组,移除前先清除图层组中的元素
  10016. * @param {[type]} options [description]
  10017. * @return {[type]} [description]
  10018. */
  10019. function removegroup(options) {
  10020. if (map23DData.groups[options.guid]) {
  10021. operationGroup(options, "remove");
  10022. PubSub.publishSync('map23D.group.remove', options.guid);
  10023. delete map23DData.groups[options.guid];
  10024. return options.guid;
  10025. } else {
  10026. return false;
  10027. }
  10028. }
  10029. function showgroup(options) {
  10030. if (map23DData.groups[options.guid]) {
  10031. operationGroup(options, "show");
  10032. PubSub.publishSync('map23D.group.show', options.guid);
  10033. return options.guid;
  10034. } else {
  10035. return false;
  10036. }
  10037. }
  10038. function hidegroup(options) {
  10039. if (map23DData.groups[options.guid]) {
  10040. operationGroup(options, "hide");
  10041. PubSub.publishSync('map23D.group.hide', options.guid);
  10042. return options.guid;
  10043. } else {
  10044. return false;
  10045. }
  10046. }
  10047. /**
  10048. * 清除图层组元素
  10049. * @param {[type]} options [description]
  10050. * @return {[type]} [description]
  10051. */
  10052. function operationGroup(options, action) {
  10053. if (map23DData.groups[options.guid]) {
  10054. //移除点
  10055. _(map23DData.markers).forEach(function (item, key) {
  10056. if (item.groupId == options.guid) {
  10057. map23DControl.marker({
  10058. action: action,
  10059. guid: key
  10060. })
  10061. }
  10062. });
  10063. //移除线
  10064. _(map23DData.polylines).forEach(function (item, key) {
  10065. if (item.groupId == options.guid) {
  10066. map23DControl.polyline({
  10067. action: action,
  10068. guid: key
  10069. })
  10070. }
  10071. });
  10072. //移除面
  10073. _(map23DData.polygons).forEach(function (item, key) {
  10074. if (item.groupId == options.guid) {
  10075. map23DControl.polygon({
  10076. action: action,
  10077. guid: key
  10078. })
  10079. }
  10080. });
  10081. //移除圆
  10082. _(map23DData.circles).forEach(function (item, key) {
  10083. if (item.groupId == options.guid) {
  10084. map23DControl.circle({
  10085. action: action,
  10086. guid: key
  10087. })
  10088. }
  10089. });
  10090. return options.guid;
  10091. } else {
  10092. return false
  10093. }
  10094. }
  10095. }(window, document));
  10096. ;
  10097. (function (window, document, undefined) {
  10098. var imageOverlay = map23DControl.imageOverlay;
  10099. if (typeof module === 'object' && typeof module.exports === 'object') {
  10100. module.exports = imageOverlay;
  10101. } else if (typeof define === 'function' && define.amd) {
  10102. define(imageOverlay);
  10103. }
  10104. map23DControl.imageOverlay = function (options) {
  10105. switch (options.action) {
  10106. case 'add':
  10107. return addImageOverlay(options);
  10108. break;
  10109. case 'remove':
  10110. return removeImageOverlay(options);
  10111. break;
  10112. case 'update':
  10113. return updateImageOverlay(options);
  10114. break;
  10115. case 'hide':
  10116. return hideImageOverlay(options);
  10117. break;
  10118. case 'show':
  10119. return showImageOverlay(options);
  10120. break;
  10121. }
  10122. }
  10123. function addImageOverlay(options) {
  10124. var guid = options.guid || map23DControl.buildGuid('imageOverlay23D');
  10125. var defaultData = _.cloneDeep(map23DDefaultData.imageOverlay)
  10126. defaultData.guid = guid;
  10127. _.merge(defaultData, options);
  10128. map23DData.imageOverlays[guid] = defaultData;
  10129. PubSub.publishSync('map23D.imageOverlay.add', guid);
  10130. return guid;
  10131. }
  10132. /**
  10133. * 移除图层组,移除前先清除图层组中的元素
  10134. * @param {[type]} options [description]
  10135. * @return {[type]} [description]
  10136. */
  10137. function removeImageOverlay(options) {
  10138. if (map23DData.imageOverlays[options.guid]) {
  10139. PubSub.publishSync('map23D.imageOverlay.remove', options.guid);
  10140. delete map23DData.imageOverlays[options.guid];
  10141. return options.guid;
  10142. } else {
  10143. return false;
  10144. }
  10145. }
  10146. function updateImageOverlay(options) {
  10147. if (map23DData.imageOverlays[options.guid]) {
  10148. _.merge(map23DData.imageOverlays[options.guid], options);
  10149. PubSub.publishSync('map23D.imageOverlay.update', options.guid);
  10150. return options.guid;
  10151. } else {
  10152. return false;
  10153. }
  10154. }
  10155. function showImageOverlay(options) {
  10156. if (map23DData.imageOverlays[options.guid]) {
  10157. _.merge(map23DData.imageOverlays[options.guid], options);
  10158. PubSub.publishSync('map23D.imageOverlay.show', options.guid);
  10159. return options.guid;
  10160. } else {
  10161. return false;
  10162. }
  10163. }
  10164. function hideImageOverlay(options) {
  10165. if (map23DData.imageOverlays[options.guid]) {
  10166. _.merge(map23DData.imageOverlays[options.guid], options);
  10167. PubSub.publishSync('map23D.imageOverlay.hide', options.guid);
  10168. return options.guid;
  10169. } else {
  10170. return false;
  10171. }
  10172. }
  10173. }(window, document));
  10174. ;
  10175. (function (window, document, undefined) {
  10176. PubSub.subscribe('map23D.imageOverlay.add', add2DimageOverlay);
  10177. PubSub.subscribe('map23D.imageOverlay.remove', remove2DimageOverlay);
  10178. PubSub.subscribe('map23D.imageOverlay.update', update2DimageOverlay);
  10179. PubSub.subscribe('map23D.imageOverlay.show', show2DimageOverlay);
  10180. PubSub.subscribe('map23D.imageOverlay.hide', hide2DimageOverlay);
  10181. PubSub.subscribe('map2D.imageOverlay.add', add2DimageOverlay);
  10182. PubSub.subscribe('map2D.imageOverlay.remove', remove2DimageOverlay);
  10183. PubSub.subscribe('map2D.imageOverlay.update', update2DimageOverlay);
  10184. PubSub.subscribe('map2D.imageOverlay.show', show2DimageOverlay);
  10185. PubSub.subscribe('map2D.imageOverlay.hide', hide2DimageOverlay);
  10186. /**
  10187. * 根据GUID添加图层
  10188. * @param {[type]} msg [description]
  10189. * @param {[type]} guid [description]
  10190. */
  10191. function add2DimageOverlay(msg, guid) {
  10192. if (!map2DViewer.inited) {
  10193. return false;
  10194. }
  10195. var imageOverlayData = map23DData.imageOverlays[guid];
  10196. if (imageOverlayData.from === '3D') {
  10197. return false;
  10198. }
  10199. var corner1 = L.latLng(imageOverlayData.layers.layerBounds[0][1], imageOverlayData.layers.layerBounds[0][0]);
  10200. var corner2 = L.latLng(imageOverlayData.layers.layerBounds[1][1], imageOverlayData.layers.layerBounds[1][0]);
  10201. layerBounds = L.latLngBounds(corner1, corner2);
  10202. var imageOverlay = L.imageOverlay(imageOverlayData.layers.imageUrl2D, layerBounds, {
  10203. opacity: imageOverlayData.layers.opacity
  10204. });
  10205. imageOverlay.guid = guid;
  10206. imageOverlay.addTo(map2DViewer.map);
  10207. map2DViewer.imageOverlays[guid] = imageOverlay;
  10208. imageOverlayData.add2D = true;
  10209. imageOverlayData.visible2D = true;
  10210. }
  10211. /**
  10212. * 移除指定GUID的图层
  10213. * @param {[type]} msg [description]
  10214. * @param {[type]} guid [description]
  10215. * @return {[type]} [description]
  10216. */
  10217. function remove2DimageOverlay(msg, guid) {
  10218. if (!map2DViewer.inited) {
  10219. return false;
  10220. }
  10221. var imageOverlayData = map23DData.imageOverlays[guid];
  10222. if (imageOverlayData.from === '3D') {
  10223. return false;
  10224. }
  10225. map2DViewer.map.removeLayer(map2DViewer.imageOverlays[guid]);
  10226. delete map2DViewer.imageOverlays[guid];
  10227. imageOverlayData.add2D = false;
  10228. }
  10229. /**
  10230. * 更新指定GUID的图层
  10231. * @param {[type]} msg [description]
  10232. * @param {[type]} guid [description]
  10233. * @return {[type]} [description]
  10234. */
  10235. function update2DimageOverlay(msg, guid) {
  10236. if (!map2DViewer.inited) {
  10237. return false;
  10238. }
  10239. var imageOverlayData = map23DData.imageOverlays[guid];
  10240. if (imageOverlayData.from === '3D') {
  10241. return false;
  10242. }
  10243. var imageOverlay = map2DViewer.imageOverlays[guid];
  10244. if (imageOverlay.options.opacity != imageOverlayData.layers.opacity) {
  10245. imageOverlay.setOpacity(imageOverlayData.layers.opacity);
  10246. }
  10247. //if (imageOverlay.options._bounds != imageOverlayData.layers.layerBounds) {
  10248. var corner1 = L.latLng(imageOverlayData.layers.layerBounds[0][1], imageOverlayData.layers.layerBounds[0][0]);
  10249. var corner2 = L.latLng(imageOverlayData.layers.layerBounds[1][1], imageOverlayData.layers.layerBounds[1][0]);
  10250. layerBounds = L.latLngBounds(corner1, corner2);
  10251. imageOverlay.setBounds(layerBounds);
  10252. //}
  10253. if (imageOverlay._url != imageOverlayData.layers.imageUrl2D) {
  10254. imageOverlay.setUrl(imageOverlayData.layers.imageUrl2D);
  10255. }
  10256. }
  10257. function show2DimageOverlay(msg, guid) {
  10258. if (!map2DViewer.inited) {
  10259. return false;
  10260. }
  10261. var imageOverlayData = map23DData.imageOverlays[guid];
  10262. if (imageOverlayData.from === '3D') {
  10263. return false;
  10264. }
  10265. if (imageOverlayData.visible2D) {
  10266. return false;
  10267. }
  10268. map2DViewer.imageOverlays[guid].addTo(map2DViewer.map);
  10269. imageOverlayData.visible2D = true;
  10270. }
  10271. function hide2DimageOverlay(msg, guid) {
  10272. if (!map2DViewer.inited) {
  10273. return false;
  10274. }
  10275. var imageOverlayData = map23DData.imageOverlays[guid];
  10276. if (imageOverlayData.from === '3D') {
  10277. return false;
  10278. }
  10279. if (!imageOverlayData.visible2D) {
  10280. return false;
  10281. }
  10282. map2DViewer.map.removeLayer(map2DViewer.imageOverlays[guid]);
  10283. imageOverlayData.visible2D = false;
  10284. }
  10285. }(window, document));
  10286. ;
  10287. (function (window, document, undefined) {
  10288. PubSub.subscribe('map23D.imageOverlay.add', add3DimageOverlay);
  10289. PubSub.subscribe('map23D.imageOverlay.remove', remove3DimageOverlay);
  10290. PubSub.subscribe('map23D.imageOverlay.hide', hide3DimageOverlay);
  10291. PubSub.subscribe('map23D.imageOverlay.show', show3DimageOverlay);
  10292. PubSub.subscribe('map23D.imageOverlay.update', update3DimageOverlay);
  10293. PubSub.subscribe('map3D.imageOverlay.add', add3DimageOverlay);
  10294. PubSub.subscribe('map3D.imageOverlay.remove', remove3DimageOverlay);
  10295. PubSub.subscribe('map3D.imageOverlay.hide', hide3DimageOverlay);
  10296. PubSub.subscribe('map3D.imageOverlay.show', show3DimageOverlay);
  10297. PubSub.subscribe('map3D.imageOverlay.update', update3DimageOverlay);
  10298. function add3DimageOverlay(msg, guid) {
  10299. if (!map3DViewer.inited) {
  10300. return false;
  10301. }
  10302. var imageOverlayData = map23DData.imageOverlays[guid];
  10303. if (imageOverlayData.from === '2D') {
  10304. return false;
  10305. }
  10306. var imageLayer = map3DViewer.map.imageryLayers.addImageryProvider(new Cesium.SingleTileImageryProvider({
  10307. url: imageOverlayData.layers.imageUrl3D,
  10308. rectangle: Cesium.Rectangle.fromDegrees(imageOverlayData.layers.layerBounds[0][0], imageOverlayData.layers.layerBounds[1][1], imageOverlayData.layers.layerBounds[1][0], imageOverlayData.layers.layerBounds[0][1])
  10309. }))
  10310. imageLayer.alpha = imageOverlayData.layers.opacity;
  10311. delete imageOverlayData.action;
  10312. map3DViewer.imageOverlays[guid] = imageLayer;
  10313. imageOverlayData.add3D = true;
  10314. imageOverlayData.visible3D = true;
  10315. };
  10316. function remove3DimageOverlay(msg, guid) {
  10317. if (!map3DViewer.inited) {
  10318. return false;
  10319. }
  10320. var imageOverlayData = map23DData.imageOverlays[guid];
  10321. if (imageOverlayData.from === '2D') {
  10322. return false;
  10323. }
  10324. if (!map3DViewer.imageOverlays[guid]) {
  10325. return false;
  10326. }
  10327. var imageLayer = map3DViewer.imageOverlays[guid];
  10328. map3DViewer.map.imageryLayers.remove(imageLayer);
  10329. delete map3DViewer.imageOverlays[guid];
  10330. imageOverlayData.add3D = false;
  10331. };
  10332. function update3DimageOverlay(msg, guid) {
  10333. if (!map3DViewer.inited) {
  10334. return false;
  10335. }
  10336. var imageOverlayData = map23DData.imageOverlays[guid];
  10337. if (imageOverlayData.from === '2D') {
  10338. return false;
  10339. }
  10340. if (!map3DViewer.imageOverlays[guid]) {
  10341. return false;
  10342. }
  10343. var imageLayer = map3DViewer.imageOverlays[guid];
  10344. if (map3DViewer.map.scene.imageryLayers.contains(imageLayer))
  10345. map3DViewer.map.scene.imageryLayers.remove(imageLayer, true) // (要移除的图层,是否摧毁图层)
  10346. var imageLayer = map3DViewer.map.scene.imageryLayers.addImageryProvider(new Cesium.SingleTileImageryProvider({
  10347. url: imageOverlayData.layers.imageUrl3D,
  10348. rectangle: Cesium.Rectangle.fromDegrees(imageOverlayData.layers.layerBounds[0][0], imageOverlayData.layers.layerBounds[1][1], imageOverlayData.layers.layerBounds[1][0], imageOverlayData.layers.layerBounds[0][1])
  10349. }))
  10350. imageLayer.alpha = imageOverlayData.layers.opacity;
  10351. map3DViewer.imageOverlays[guid] = imageLayer;
  10352. delete map23DData.imageOverlays[guid].action;
  10353. };
  10354. function show3DimageOverlay(msg, guid) {
  10355. if (!map3DViewer.inited) {
  10356. return false;
  10357. }
  10358. var imageOverlayData = map23DData.imageOverlays[guid];
  10359. if (imageOverlayData.from === '2D') {
  10360. return false;
  10361. }
  10362. if (!map3DViewer.imageOverlays[guid]) {
  10363. return false;
  10364. }
  10365. var imageLayer = map3DViewer.imageOverlays[guid];
  10366. imageLayer.show = true;
  10367. imageOverlayData.visible3D = true;
  10368. }
  10369. function hide3DimageOverlay(msg, guid) {
  10370. if (!map3DViewer.inited) {
  10371. return false;
  10372. }
  10373. var imageOverlayData = map23DData.imageOverlays[guid];
  10374. if (imageOverlayData.from === '2D') {
  10375. return false;
  10376. }
  10377. if (!map3DViewer.imageOverlays[guid]) {
  10378. return false;
  10379. }
  10380. var imageLayer = map3DViewer.imageOverlays[guid];
  10381. imageLayer.show = false;
  10382. imageOverlayData.visible3D = false;
  10383. }
  10384. }(window, document));
  10385. ;
  10386. (function (window, document, undefined) {
  10387. var circle = map23DControl.circle;
  10388. if (typeof module === 'object' && typeof module.exports === 'object') {
  10389. module.exports = circle;
  10390. } else if (typeof define === 'function' && define.amd) {
  10391. define(circle);
  10392. }
  10393. map23DControl.circle = function (options) {
  10394. switch (options.action) {
  10395. case 'add':
  10396. return addCircle(options);
  10397. break;
  10398. case 'remove':
  10399. return removeCircle(options);
  10400. break;
  10401. case 'update':
  10402. return updateCircle(options);
  10403. break;
  10404. case 'show':
  10405. return showCircle(options);
  10406. break;
  10407. case 'hide':
  10408. return hideCircle(options);
  10409. break;
  10410. }
  10411. }
  10412. function addCircle(options) {
  10413. var guid = options.guid || map23DControl.buildGuid('circle23D');
  10414. var defaultData = _.cloneDeep(map23DDefaultData.circle)
  10415. defaultData.guid = guid;
  10416. _.merge(defaultData, options);
  10417. map23DData.circles[guid] = defaultData;
  10418. PubSub.publishSync('map23D.circle.add', guid);
  10419. return guid;
  10420. }
  10421. function removeCircle(options) {
  10422. if (map23DData.circles[options.guid]) {
  10423. PubSub.publishSync('map23D.circle.remove', options.guid);
  10424. delete map23DData.circles[options.guid];
  10425. return options.guid;
  10426. } else {
  10427. return false;
  10428. }
  10429. }
  10430. function updateCircle(options) {
  10431. if (map23DData.circles[options.guid]) {
  10432. _.merge(map23DData.circles[options.guid], options);
  10433. PubSub.publishSync('map23D.circle.update', options.guid);
  10434. return options.guid;
  10435. } else {
  10436. return false
  10437. }
  10438. }
  10439. function showCircle(options) {
  10440. if (map23DData.circles[options.guid]) {
  10441. _.merge(map23DData.circles[options.guid], options);
  10442. PubSub.publishSync('map23D.circle.show', options.guid);
  10443. return options.guid;
  10444. } else {
  10445. return false
  10446. }
  10447. }
  10448. function hideCircle(options) {
  10449. if (map23DData.circles[options.guid]) {
  10450. _.merge(map23DData.circles[options.guid], options);
  10451. PubSub.publishSync('map23D.circle.hide', options.guid);
  10452. return options.guid;
  10453. } else {
  10454. return false
  10455. }
  10456. }
  10457. }(window, document));
  10458. ;
  10459. (function (window, document, undefined) {
  10460. var marker = map23DControl.marker;
  10461. if (typeof module === 'object' && typeof module.exports === 'object') {
  10462. module.exports = marker;
  10463. } else if (typeof define === 'function' && define.amd) {
  10464. define(marker);
  10465. }
  10466. map23DControl.marker = function (options) {
  10467. switch (options.action) {
  10468. case 'add':
  10469. return addMarker(options);
  10470. break;
  10471. case 'remove':
  10472. return removeMarker(options);
  10473. break;
  10474. case 'update':
  10475. return updateMarker(options);
  10476. break;
  10477. case 'show':
  10478. return showMarker(options);
  10479. break;
  10480. case 'hide':
  10481. return hideMarker(options);
  10482. break;
  10483. }
  10484. }
  10485. function addMarker(options) {
  10486. var guid = options.guid || map23DControl.buildGuid('marker23D');
  10487. if (!options.RBkey) {
  10488. var markerTime = null;
  10489. } else {
  10490. var markerTime = map23DData.polylines[map2DViewer.routeBackGroup[options.RBkey].polyline].geojson.properties.times;
  10491. }
  10492. if (options.vectorMarker) {
  10493. var dataSize = options.geojson.properties.baseSize;
  10494. var curZoom = map23DData.view.zoom;
  10495. var scale = Math.pow(2, curZoom - options.geojson.properties.baseZoom);
  10496. options.geojson.properties.iconSize = [dataSize[0] * scale, dataSize[1] * scale];
  10497. options.geojson.properties.iconAnchor = [dataSize[0] * scale / 2, dataSize[1] * scale / 2];
  10498. options.geojson.properties.popupAnchor = [0, -dataSize[1] * scale];
  10499. }
  10500. var defaultData = _.cloneDeep(map23DDefaultData.marker)
  10501. defaultData.guid = guid;
  10502. defaultData.geojson.properties.markerTime = markerTime;
  10503. _.merge(defaultData, options);
  10504. map23DData.markers[guid] = defaultData;
  10505. PubSub.publishSync('map23D.marker.add', guid);
  10506. return guid;
  10507. }
  10508. function removeMarker(options) {
  10509. if (map23DData.markers[options.guid]) {
  10510. PubSub.publishSync('map23D.marker.remove', options.guid);
  10511. delete map23DData.markers[options.guid];
  10512. return options.guid;
  10513. } else {
  10514. return false;
  10515. }
  10516. }
  10517. function updateMarker(options) {
  10518. if (map23DData.markers[options.guid]) {
  10519. _.merge(map23DData.markers[options.guid], options);
  10520. if (options.geojson.geometry) {
  10521. if (options.geojson.geometry.coordinates)
  10522. map23DData.markers[options.guid].geojson.geometry.coordinates = options.geojson.geometry.coordinates
  10523. }
  10524. PubSub.publishSync('map23D.marker.update', options.guid);
  10525. return options.guid;
  10526. } else {
  10527. return false
  10528. }
  10529. }
  10530. function showMarker(options) {
  10531. var guid = options.guid;
  10532. PubSub.publishSync('map23D.marker.show', guid);
  10533. };
  10534. function hideMarker(options) {
  10535. var guid = options.guid;
  10536. PubSub.publishSync('map23D.marker.hide', guid);
  10537. };
  10538. }(window, document));
  10539. ;
  10540. (function (window, document, undefined) {
  10541. var polyline = map23DControl.polyline;
  10542. if (typeof module === 'object' && typeof module.exports === 'object') {
  10543. module.exports = polyline;
  10544. } else if (typeof define === 'function' && define.amd) {
  10545. define(polyline);
  10546. }
  10547. map23DControl.polyline = function (options) {
  10548. switch (options.action) {
  10549. case 'add':
  10550. return addPolyline(options);
  10551. break;
  10552. case 'remove':
  10553. return removePolyline(options);
  10554. break;
  10555. case 'update':
  10556. return updatePolyline(options);
  10557. break;
  10558. case 'show':
  10559. return showPolyline(options);
  10560. break;
  10561. case 'hide':
  10562. return hidePolyline(options);
  10563. break;
  10564. }
  10565. }
  10566. function addPolyline(options) {
  10567. var guid = options.guid || map23DControl.buildGuid('polyline23D');
  10568. var defaultData = _.cloneDeep(map23DDefaultData.polyline)
  10569. defaultData.guid = guid;
  10570. _.merge(defaultData, options);
  10571. map23DData.polylines[guid] = defaultData;
  10572. PubSub.publishSync('map23D.polyline.add', guid);
  10573. return guid;
  10574. }
  10575. function removePolyline(options) {
  10576. if (map23DData.polylines[options.guid]) {
  10577. PubSub.publishSync('map23D.polyline.remove', options.guid);
  10578. delete map23DData.polylines[options.guid];
  10579. return options.guid;
  10580. } else {
  10581. return false;
  10582. }
  10583. }
  10584. function updatePolyline(options) {
  10585. if (map23DData.polylines[options.guid]) {
  10586. _.merge(map23DData.polylines[options.guid], options);
  10587. if (options.geojson.geometry) {
  10588. if (options.geojson.geometry.coordinates)
  10589. map23DData.polylines[options.guid].geojson.geometry.coordinates = options.geojson.geometry.coordinates
  10590. }
  10591. PubSub.publishSync('map23D.polyline.update', options.guid);
  10592. return options.guid;
  10593. } else {
  10594. return false
  10595. }
  10596. }
  10597. function showPolyline(options) {
  10598. if (map23DData.polylines[options.guid]) {
  10599. _.merge(map23DData.polylines[options.guid], options);
  10600. PubSub.publishSync('map23D.polyline.show', options.guid);
  10601. return options.guid;
  10602. } else {
  10603. return false
  10604. }
  10605. }
  10606. function hidePolyline(options) {
  10607. if (map23DData.polylines[options.guid]) {
  10608. _.merge(map23DData.polylines[options.guid], options);
  10609. PubSub.publishSync('map23D.polyline.hide', options.guid);
  10610. return options.guid;
  10611. } else {
  10612. return false
  10613. }
  10614. }
  10615. }(window, document));
  10616. ;
  10617. (function (window, document, undefined) {
  10618. var polygon = map23DControl.polygon;
  10619. if (typeof module === 'object' && typeof module.exports === 'object') {
  10620. module.exports = polygon;
  10621. } else if (typeof define === 'function' && define.amd) {
  10622. define(polygon);
  10623. }
  10624. map23DControl.polygon = function (options) {
  10625. switch (options.action) {
  10626. case 'add':
  10627. return addPolygon(options);
  10628. break;
  10629. case 'remove':
  10630. return removePolygon(options);
  10631. break;
  10632. case 'update':
  10633. return updatePolygon(options);
  10634. break;
  10635. case 'hide':
  10636. return hidePolygon(options);
  10637. break;
  10638. case 'show':
  10639. return showPolygon(options);
  10640. break;
  10641. }
  10642. }
  10643. function addPolygon(options) {
  10644. var guid = options.guid || map23DControl.buildGuid('polygon23D');
  10645. var defaultData = _.cloneDeep(map23DDefaultData.polygon)
  10646. defaultData.guid = guid;
  10647. _.merge(defaultData, options);
  10648. map23DData.polygons[guid] = defaultData;
  10649. PubSub.publishSync('map23D.polygon.add', guid);
  10650. delete map23DData.polygons[guid].action
  10651. return guid;
  10652. }
  10653. function removePolygon(options) {
  10654. if (map23DData.polygons[options.guid]) {
  10655. PubSub.publishSync('map23D.polygon.remove', options.guid);
  10656. delete map23DData.polygons[options.guid];
  10657. return options.guid;
  10658. } else {
  10659. return false;
  10660. }
  10661. }
  10662. function updatePolygon(options) {
  10663. if (map23DData.polygons[options.guid]) {
  10664. _.merge(map23DData.polygons[options.guid], options);
  10665. if (options.geojson.geometry) {
  10666. if (options.geojson.geometry.coordinates)
  10667. map23DData.polygons[options.guid].geojson.geometry.coordinates = options.geojson.geometry.coordinates
  10668. }
  10669. PubSub.publishSync('map23D.polygon.update', options.guid);
  10670. return options.guid;
  10671. } else {
  10672. return false
  10673. }
  10674. }
  10675. function hidePolygon(options) {
  10676. if (map23DData.polygons[options.guid]) {
  10677. PubSub.publishSync('map23D.polygon.hide', options.guid);
  10678. return options.guid;
  10679. } else {
  10680. return false;
  10681. }
  10682. }
  10683. function showPolygon(options) {
  10684. if (map23DData.polygons[options.guid]) {
  10685. PubSub.publishSync('map23D.polygon.show', options.guid);
  10686. return options.guid;
  10687. } else {
  10688. return false;
  10689. }
  10690. }
  10691. }(window, document));
  10692. ;
  10693. (function (window, document, undefined) {
  10694. var modValue = {}
  10695. map3DViewer.radar = function (options) {
  10696. switch (options.action) {
  10697. case 'add':
  10698. return init(options);
  10699. break;
  10700. case 'draw':
  10701. return draw(options);
  10702. break;
  10703. case 'start':
  10704. return start(options);
  10705. break;
  10706. case 'stop':
  10707. return stop(options);
  10708. break;
  10709. case 'remove':
  10710. return remove(options);
  10711. break;
  10712. case 'clear':
  10713. return clear(options);
  10714. break;
  10715. }
  10716. }
  10717. function init(options) {
  10718. clear();
  10719. modValue.callback = options.callback;
  10720. modValue.handler = null;
  10721. modValue.tempEntities = {}
  10722. }
  10723. function start(options) {
  10724. modValue.center = [];
  10725. modValue.guid = options.guid || map23DControl.buildGuid('radar23D');
  10726. modValue.tempEntities[modValue.guid] = [];
  10727. modValue.radius = options.radius
  10728. modValue.circleTangle = options.circleTangle || 5;
  10729. if (!modValue.handler) {
  10730. modValue.handler = new Cesium.ScreenSpaceEventHandler(map3DViewer.map.scene.canvas);
  10731. modValue.handler.setInputAction(function (evt) {
  10732. var pick = new Cesium.Cartesian2(evt.position.x, evt.position.y);
  10733. var cartesian = map3DViewer.map.scene.globe.pick(map3DViewer.map.camera.getPickRay(pick), map3DViewer.map.scene);
  10734. if (cartesian) {
  10735. var obj = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian)
  10736. var center_lon = Cesium.Math.toDegrees(obj.longitude)
  10737. var center_lat = Cesium.Math.toDegrees(obj.latitude)
  10738. modValue.center = [
  10739. center_lon,
  10740. center_lat,
  10741. modValue.radius
  10742. ]
  10743. draw();
  10744. }
  10745. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  10746. }
  10747. }
  10748. function draw() {
  10749. //圆心
  10750. var allCirclePoint = [];
  10751. var extrudes = [];
  10752. //半径
  10753. var radius = modValue.radius; //米
  10754. var circleTangle = modValue.circleTangle
  10755. // //计算圆心到极点的距离
  10756. // if (center_lat < 0) {
  10757. // var centerToPole = turf.distance(turf.point([center_lon, center_lat]), turf.point([center_lon, -90])) // new L.LatLng(center_lat, center_lon).distanceTo(new L.LatLng(-90, center_lon));
  10758. // } else {
  10759. // var centerToPole = turf.distance(turf.point([center_lon, center_lat]), turf.point([center_lon, 90]))
  10760. // }
  10761. var minExtrudes = getLDCircleExtrude(radius);
  10762. for (var i = 0; i <= 90; i += circleTangle) {
  10763. if (i == 90) {
  10764. var curHeight = radius;
  10765. } else {
  10766. var ral = (i * Math.PI) / 180;
  10767. var curHeight = radius * Math.sin(ral);
  10768. }
  10769. if (i != 0) {
  10770. if (curHeight < minExtrudes) {
  10771. curHeight = minExtrudes;
  10772. }
  10773. }
  10774. var curBRedius = Math.sqrt(Math.pow(radius, 2) - Math.pow(curHeight, 2));
  10775. var center = turf.point([modValue.center[0], modValue.center[1]]);
  10776. if (i == 90) {
  10777. curBRedius = 0.1;
  10778. }
  10779. var circle = turf.circle(center, curBRedius, {
  10780. steps: 360 / 5,
  10781. units: 'meters',
  10782. });
  10783. var circlePoints = circle.geometry.coordinates[0];
  10784. extrudes.push(curHeight);
  10785. allCirclePoint.push(circlePoints)
  10786. if (i == 90) {
  10787. addCircleToPolygon(allCirclePoint, extrudes);
  10788. }
  10789. }
  10790. }
  10791. function stop() {
  10792. detach();
  10793. }
  10794. function remove() {
  10795. detach();
  10796. clear();
  10797. }
  10798. function detach() {
  10799. if (modValue.handler) {
  10800. modValue.handler.destroy();
  10801. modValue.handler = null
  10802. }
  10803. }
  10804. function clear(guid) {
  10805. if (guid) {
  10806. if (modValue.tempEntities) {
  10807. if (modValue.tempEntities.hasOwnProperty(guid)) {
  10808. var arr = modValue.tempEntities[guid];
  10809. for (var i = 0; i < arr.length; i++) {
  10810. map3DViewer.map.entities.removeById(arr[i]._id)
  10811. }
  10812. delete modValue.tempEntities[guid]
  10813. }
  10814. }
  10815. } else {
  10816. if (modValue.tempEntities)
  10817. for (var key in modValue.tempEntities) {
  10818. if (modValue.tempEntities.hasOwnProperty(key)) {
  10819. var arr = modValue.tempEntities[key];
  10820. for (var i = 0; i < arr.length; i++) {
  10821. map3DViewer.map.entities.removeById(arr[i]._id)
  10822. }
  10823. }
  10824. }
  10825. modValue.tempEntities = {};
  10826. }
  10827. modValue.center = [];
  10828. }
  10829. /**
  10830. * 计算雷达半球最低拉伸高度
  10831. */
  10832. function getLDCircleExtrude(radius) {
  10833. var earthRadius = 6371000; //地球半径
  10834. var tangle = (360 * radius) / (4 * Math.PI * earthRadius);
  10835. tangle = tangle * Math.PI / 180;
  10836. var minExtrude = 2 * earthRadius * Math.sin(tangle) * Math.sin(tangle);
  10837. return minExtrude;
  10838. }
  10839. function addCircleToPolygon(allCirclePoint, extrudes) {
  10840. var pos = {};
  10841. for (var n = 0; n < allCirclePoint.length; n++) {
  10842. var curExtrude = extrudes[n];
  10843. var positions = [];
  10844. for (var i = 0; i < allCirclePoint[n].length; i++) {
  10845. positions.push(allCirclePoint[n][i][0], allCirclePoint[n][i][1], curExtrude);
  10846. if (i < (allCirclePoint[n].length - 1) / 2) {
  10847. if (!pos[i]) {
  10848. pos[i] = {
  10849. push_item: [],
  10850. unshift_item: [],
  10851. all: [],
  10852. }
  10853. }
  10854. pos[i].push_item.push(allCirclePoint[n][i][0], allCirclePoint[n][i][1], curExtrude);
  10855. pos[i].unshift_item.unshift(allCirclePoint[n][(allCirclePoint[n].length - 1) / 2 + i][0], allCirclePoint[n][(allCirclePoint[n].length - 1) / 2 + i][1], curExtrude);
  10856. if (n == allCirclePoint.length - 1) {
  10857. pos[i].all = pos[i].all.concat(pos[i].push_item, modValue.center[0], modValue.center[1], modValue.center[2], pos[i].unshift_item)
  10858. var entity = map3DViewer.map.entities.add({
  10859. polyline: {
  10860. positions: Cesium.Cartesian3.fromDegreesArrayHeights(pos[i].all),
  10861. arcType: Cesium.ArcType.NONE,
  10862. width: 2,
  10863. material: Cesium.Color.GREEN,
  10864. // depthFailMaterial: Cesium.Color.RED
  10865. }
  10866. })
  10867. modValue.tempEntities[modValue.guid] = modValue.tempEntities[modValue.guid].concat([entity])
  10868. }
  10869. }
  10870. }
  10871. position = Cesium.Cartesian3.fromDegreesArrayHeights(positions);
  10872. var entity = map3DViewer.map.entities.add({
  10873. polyline: {
  10874. positions: position,
  10875. arcType: Cesium.ArcType.NONE,
  10876. width: 2,
  10877. material: Cesium.Color.GREEN,
  10878. // depthFailMaterial: Cesium.Color.RED
  10879. }
  10880. })
  10881. modValue.tempEntities[modValue.guid] = modValue.tempEntities[modValue.guid].concat([entity])
  10882. }
  10883. if (modValue.callback) modValue.callback();
  10884. }
  10885. }(window, document));
  10886. ;
  10887. (function (window, document, undefined) {
  10888. var tileLayer = map23DControl.tileLayer;
  10889. if (typeof module === 'object' && typeof module.exports === 'object') {
  10890. module.exports = tileLayer;
  10891. } else if (typeof define === 'function' && define.amd) {
  10892. define(tileLayer);
  10893. }
  10894. /**
  10895. * 设置系统自带图层
  10896. * @param {[type]} options [description]
  10897. */
  10898. map23DControl.setDefaultTileLayer = function (options) {
  10899. PubSub.publish('map23D.defaultTileLayer.change', {
  10900. mapName: options
  10901. })
  10902. }
  10903. map23DControl.tileLayer = function (options) {
  10904. switch (options.action) {
  10905. case 'add':
  10906. return addTileLayer(options);
  10907. break;
  10908. case 'remove':
  10909. return removeTileLayer(options);
  10910. break;
  10911. case 'update':
  10912. return updateTileLayer(options);
  10913. break;
  10914. case 'hide':
  10915. return hideTileLayer(options);
  10916. break;
  10917. case 'show':
  10918. return showTileLayer(options);
  10919. break;
  10920. }
  10921. }
  10922. function addTileLayer(options) {
  10923. var guid = options.guid || map23DControl.buildGuid('tileLayer23D');
  10924. var defaultData = _.cloneDeep(map23DDefaultData.layer)
  10925. defaultData.guid = guid;
  10926. _.merge(defaultData, options);
  10927. map23DData.layers[guid] = defaultData;
  10928. PubSub.publishSync('map23D.tileLayer.add', guid);
  10929. return guid;
  10930. }
  10931. /**
  10932. * 移除图层组,移除前先清除图层组中的元素
  10933. * @param {[type]} options [description]
  10934. * @return {[type]} [description]
  10935. */
  10936. function removeTileLayer(options) {
  10937. if (map23DData.layers[options.guid]) {
  10938. PubSub.publishSync('map23D.tileLayer.remove', options.guid);
  10939. delete map23DData.layers[options.guid];
  10940. return options.guid;
  10941. } else {
  10942. return false;
  10943. }
  10944. }
  10945. function updateTileLayer(options) {
  10946. if (map23DData.layers[options.guid]) {
  10947. _.merge(map23DData.layers[options.guid], options);
  10948. PubSub.publishSync('map23D.tileLayer.update', options.guid);
  10949. return options.guid;
  10950. } else {
  10951. return false;
  10952. }
  10953. }
  10954. function showTileLayer(options) {
  10955. if (map23DData.layers[options.guid]) {
  10956. _.merge(map23DData.layers[options.guid], options);
  10957. PubSub.publishSync('map23D.tileLayer.show', options.guid);
  10958. return options.guid;
  10959. } else {
  10960. return false;
  10961. }
  10962. }
  10963. function hideTileLayer(options) {
  10964. if (map23DData.layers[options.guid]) {
  10965. _.merge(map23DData.layers[options.guid], options);
  10966. PubSub.publishSync('map23D.tileLayer.hide', options.guid);
  10967. return options.guid;
  10968. } else {
  10969. return false;
  10970. }
  10971. }
  10972. }(window, document));
  10973. ;
  10974. (function (window, document, undefined) {
  10975. PubSub.subscribe('map23D.group.add', add2Dgroup);
  10976. PubSub.subscribe('map23D.group.remove', remove2Dgroup);
  10977. PubSub.subscribe('map23D.group.show', show2Dgroup);
  10978. PubSub.subscribe('map23D.group.hide', hide2Dgroup);
  10979. PubSub.subscribe('map2D.group.add', add2Dgroup);
  10980. PubSub.subscribe('map2D.group.remove', remove2Dgroup);
  10981. PubSub.subscribe('map2D.group.show', show2Dgroup);
  10982. PubSub.subscribe('map2D.group.hide', hide2Dgroup);
  10983. function add2Dgroup(msg, guid) {
  10984. if (!map2DViewer.inited) {
  10985. return false;
  10986. }
  10987. var groupData = map23DData.groups[guid];
  10988. if (groupData.from === '3D') {
  10989. return false;
  10990. }
  10991. var group = L.featureGroup();
  10992. if (groupData.clustering)
  10993. group = L.markerClusterGroup(groupData.clusterOptions);
  10994. group.guid = guid;
  10995. group.addTo(map2DViewer.map);
  10996. map2DViewer.groups[guid] = group;
  10997. groupData.add2D = true;
  10998. groupData.visible2D = true;
  10999. }
  11000. function remove2Dgroup(msg, guid) {
  11001. if (!map2DViewer.inited) {
  11002. return false;
  11003. }
  11004. var groupData = map23DData.groups[guid];
  11005. if (groupData.from === '3D') {
  11006. return false;
  11007. }
  11008. map2DViewer.map.removeLayer(map2DViewer.groups[guid]);
  11009. delete map2DViewer.groups[guid];
  11010. groupData.add2D = false;
  11011. }
  11012. function show2Dgroup(msg, guid) {
  11013. if (!map2DViewer.inited) {
  11014. return false;
  11015. }
  11016. var groupData = map23DData.groups[guid];
  11017. if (groupData.from === '3D') {
  11018. return false;
  11019. }
  11020. if (groupData.visible2D) {
  11021. return false;
  11022. }
  11023. map2DViewer.groups[guid].addTo(map2DViewer.map);
  11024. groupData.visible2D = true;
  11025. }
  11026. function hide2Dgroup(msg, guid) {
  11027. if (!map2DViewer.inited) {
  11028. return false;
  11029. }
  11030. var groupData = map23DData.groups[guid];
  11031. if (groupData.from === '3D') {
  11032. return false;
  11033. }
  11034. if (!groupData.visible2D) {
  11035. return false;
  11036. }
  11037. map2DViewer.map.removeLayer(map2DViewer.groups[guid]);
  11038. groupData.visible2D = false;
  11039. }
  11040. }(window, document));
  11041. ;
  11042. (function (window, document, undefined) {
  11043. PubSub.subscribe('map23D.group.add', add3Dgroup);
  11044. PubSub.subscribe('map23D.group.remove', remove3Dgroup);
  11045. PubSub.subscribe('map23D.group.show', show3Dgroup);
  11046. PubSub.subscribe('map23D.group.hide', hide3Dgroup);
  11047. PubSub.subscribe('map3D.group.add', add3Dgroup);
  11048. PubSub.subscribe('map3D.group.remove', remove3Dgroup);
  11049. PubSub.subscribe('map3D.group.show', show3Dgroup);
  11050. PubSub.subscribe('map3D.group.hide', hide3Dgroup);
  11051. function add3Dgroup(msg, guid) {
  11052. if (!map3DViewer.inited) {
  11053. return false;
  11054. }
  11055. var groupData = map23DData.groups[guid];
  11056. if (groupData.from === '2D') {
  11057. return false;
  11058. }
  11059. var group = new Cesium.EntityCollection({
  11060. id: guid,
  11061. show: true
  11062. })
  11063. map3DViewer.groups[guid] = group;
  11064. groupData.add3D = true;
  11065. };
  11066. function remove3Dgroup(msg, guid) {
  11067. if (!map3DViewer.inited) {
  11068. return false;
  11069. }
  11070. var groupData = map23DData.groups[guid];
  11071. if (groupData.from === '2D') {
  11072. return false;
  11073. }
  11074. if (!map3DViewer.groups[guid]) {
  11075. return false
  11076. }
  11077. // 三维图层组未添加到viewer中
  11078. // map3DViewer.groups[guid].removeAll();
  11079. delete map3DViewer.groups[guid];
  11080. groupData.add3D = false;
  11081. };
  11082. function hide3Dgroup(msg, guid) {
  11083. if (!map3DViewer.inited) {
  11084. return false;
  11085. }
  11086. var groupData = map23DData.groups[guid];
  11087. if (groupData.from === '2D') {
  11088. return false;
  11089. }
  11090. };
  11091. function show3Dgroup(msg, guid) {
  11092. if (!map3DViewer.inited) {
  11093. return false;
  11094. }
  11095. var groupData = map23DData.groups[guid];
  11096. if (groupData.from === '2D') {
  11097. return false;
  11098. }
  11099. };
  11100. }(window, document));
  11101. ;
  11102. (function (window, document, undefined) {
  11103. PubSub.subscribe('map23D.marker.add', add2Dmarker);
  11104. PubSub.subscribe('map23D.marker.show', show2Dmarker);
  11105. PubSub.subscribe('map23D.marker.hide', hide2Dmarker);
  11106. PubSub.subscribe('map23D.marker.remove', remove2Dmarker);
  11107. PubSub.subscribe('map23D.marker.update', update2Dmarker);
  11108. PubSub.subscribe('map2D.marker.add', add2Dmarker);
  11109. PubSub.subscribe('map2D.marker.show', show2Dmarker);
  11110. PubSub.subscribe('map2D.marker.hide', hide2Dmarker);
  11111. PubSub.subscribe('map2D.marker.remove', remove2Dmarker);
  11112. PubSub.subscribe('map2D.marker.update', update2Dmarker);
  11113. function creatPopup(options) {
  11114. var popupHtml = '<div class="popup_html">' +
  11115. ' <div class="popup-lt"></div>' +
  11116. ' <div class="popup-rt"></div>' +
  11117. ' <div class="popup-lb"></div>' +
  11118. ' <div class="popup-rb"></div>' +
  11119. ' <div class="popup-ct">' + options.title + '</div>' +
  11120. ' <div class="popup-cb">' + options.popupContent + '</div>' +
  11121. '</div>'
  11122. return popupHtml;
  11123. }
  11124. function marker_icon(markerData) {
  11125. if (markerData.geojson.properties.fontIcon) {
  11126. var icon_html = '<div width="' + markerData.geojson.properties.iconSize[0] + '" \
  11127. height="' + markerData.geojson.properties.iconSize[1] + '" \
  11128. style="color:' + markerData.geojson.properties.fontColor + ';\
  11129. line-height:1;\
  11130. font-weight:' + markerData.geojson.properties.fontWeight + '; \
  11131. font-size:' + markerData.geojson.properties.fontSize + 'px; \
  11132. -webkit-transform: rotate(' + markerData.geojson.properties.iconRorate + 'deg); \
  11133. transform-origin:' + markerData.geojson.properties.iconAnchor[0] + 'px ' + markerData.geojson.properties.iconAnchor[1] + 'px;\
  11134. -ms-transform-origin:' + markerData.geojson.properties.iconAnchor[0] + 'px ' + markerData.geojson.properties.iconAnchor[1] + 'px;\
  11135. -moz-transform:rotate(' + markerData.geojson.properties.iconRorate + 'deg);\
  11136. -ms-transform:rotate(' + markerData.geojson.properties.iconRorate + 'deg);">' + markerData.geojson.properties.fontIcon +
  11137. '</div>';
  11138. } else {
  11139. var icon_html = '<img width="' + markerData.geojson.properties.iconSize[0] + '" \
  11140. height="' + markerData.geojson.properties.iconSize[1] + '" \
  11141. src="' + markerData.geojson.properties.iconUrl + '" \
  11142. style=" -webkit-transform: rotate(' + markerData.geojson.properties.iconRorate + 'deg); \
  11143. transform-origin:' + markerData.geojson.properties.iconAnchor[0] + 'px ' + markerData.geojson.properties.iconAnchor[1] + 'px;\
  11144. -ms-transform-origin:' + markerData.geojson.properties.iconAnchor[0] + 'px ' + markerData.geojson.properties.iconAnchor[1] + 'px;\
  11145. -moz-transform:rotate(' + markerData.geojson.properties.iconRorate + 'deg);\
  11146. -ms-transform:rotate(' + markerData.geojson.properties.iconRorate + 'deg);" />';
  11147. }
  11148. return icon_html;
  11149. }
  11150. function add2Dmarker(msg, guid) {
  11151. if (!map2DViewer.inited) {
  11152. return false;
  11153. }
  11154. var markerData = map23DData.markers[guid];
  11155. if (markerData.from === '3D') {
  11156. return false;
  11157. }
  11158. if (markerData['animate']) {
  11159. var icon_html = marker_icon(markerData);
  11160. var setDivIcon = L.divIcon({
  11161. className: 'rorate_div',
  11162. html: icon_html,
  11163. iconAnchor: markerData.geojson.properties.iconAnchor,
  11164. iconSize: markerData.geojson.properties.iconSize,
  11165. popupAnchor: markerData.geojson.properties.popupAnchor
  11166. });
  11167. var marker = L.animatedMarker(map2DViewer.polylines[map2DViewer.routeBackGroup[markerData.RBkey].polyline].getLatLngs(), {
  11168. icon: setDivIcon,
  11169. autoStart: markerData.geojson.properties.autoStart,
  11170. interval: markerData.geojson.properties.interval,
  11171. distance: markerData.geojson.properties.distance,
  11172. onEnd: function () {
  11173. marker.stop();
  11174. }
  11175. });
  11176. } else {
  11177. var icon_html = marker_icon(markerData);
  11178. var setDivIcon = L.divIcon({
  11179. className: 'rorate_div',
  11180. html: icon_html,
  11181. iconAnchor: markerData.geojson.properties.iconAnchor,
  11182. iconSize: markerData.geojson.properties.iconSize,
  11183. popupAnchor: markerData.geojson.properties.popupAnchor
  11184. });
  11185. var marker = L.marker(
  11186. map23DUtil.latLngsToReverse(markerData.geojson.geometry.coordinates), {
  11187. icon: setDivIcon,
  11188. title: markerData.geojson.properties.title
  11189. }
  11190. )
  11191. PubSub.subscribe('map2DViewerZoomend', function () {
  11192. if (markerData.vectorMarker) {
  11193. setTimeout(function () {
  11194. var dataSize = markerData.geojson.properties.baseSize;
  11195. var curZoom = map2DViewer.map.getZoom();
  11196. if (curZoom >= markerData.geojson.properties.baseZoom) {
  11197. var scaleX = dataSize[0] + dataSize[0] * (curZoom - markerData.geojson.properties.baseZoom);
  11198. var scaleY = dataSize[1] + dataSize[1] * (curZoom - markerData.geojson.properties.baseZoom);
  11199. } else {
  11200. var scaleX = dataSize[0] * Math.pow(markerData.geojson.properties.baseZoom - curZoom + 1, -1);
  11201. var scaleY = dataSize[1] * Math.pow(markerData.geojson.properties.baseZoom - curZoom + 1, -1);
  11202. }
  11203. markerData.geojson.properties.iconSize = [scaleX, scaleY];
  11204. markerData.geojson.properties.iconAnchor = [scaleX / 2, scaleY / 2];
  11205. markerData.geojson.properties.popupAnchor = [0, -scaleY];
  11206. var icon_html = marker_icon(markerData);
  11207. var setDivIcon = L.divIcon({
  11208. className: 'rorate_div',
  11209. html: icon_html,
  11210. iconAnchor: markerData.geojson.properties.iconAnchor,
  11211. iconSize: markerData.geojson.properties.iconSize,
  11212. popupAnchor: markerData.geojson.properties.popupAnchor
  11213. });
  11214. marker.setIcon(setDivIcon);
  11215. }, 3)
  11216. }
  11217. })
  11218. }
  11219. marker.guid = guid;
  11220. //markerData.geojson.properties.title
  11221. //markerData.geojson.properties.popupContent
  11222. //creatPopup(markerData.geojson.properties)
  11223. if (markerData.geojson.properties.popupContent) {
  11224. marker.bindPopup(markerData.geojson.properties.popupContent, {
  11225. closeButton: false,
  11226. autoPan: false,
  11227. })
  11228. }
  11229. if (markerData.groupId) {
  11230. marker.addTo(map2DViewer.groups[markerData.groupId]);
  11231. } else {
  11232. marker.addTo(map2DViewer.map);
  11233. }
  11234. map2DViewer.markers[guid] = marker;
  11235. markerData.add2D = true;
  11236. markerData.visible2D = true;
  11237. };
  11238. function remove2Dmarker(msg, guid) {
  11239. if (!map2DViewer.inited) {
  11240. return false;
  11241. }
  11242. var markerData = map23DData.markers[guid];
  11243. if (markerData.from === '3D') {
  11244. return false;
  11245. }
  11246. if (markerData.groupId) {
  11247. map2DViewer.groups[markerData.groupId].removeLayer(map2DViewer.markers[guid]);
  11248. } else {
  11249. map2DViewer.map.removeLayer(map2DViewer.markers[guid]);
  11250. }
  11251. delete map2DViewer.markers[guid];
  11252. markerData.add2D = false;
  11253. };
  11254. function update2Dmarker(msg, guid) {
  11255. if (!map2DViewer.inited) {
  11256. return false;
  11257. }
  11258. if (map23DData.markers[guid]) {
  11259. var markerData = map23DData.markers[guid];
  11260. if (markerData.from === '3D') {
  11261. return false;
  11262. }
  11263. var marker = map2DViewer.markers[guid];
  11264. marker.setLatLng(map23DUtil.latLngsToReverse(markerData.geojson.geometry.coordinates));
  11265. var icon_html = marker_icon(markerData);
  11266. var setDivIcon = L.divIcon({
  11267. className: 'rorate_div',
  11268. html: icon_html,
  11269. iconAnchor: markerData.geojson.properties.iconAnchor,
  11270. iconSize: markerData.geojson.properties.iconSize,
  11271. popupAnchor: markerData.geojson.properties.popupAnchor
  11272. });
  11273. marker.setIcon(setDivIcon);
  11274. if (markerData.geojson.properties.popupContent) {
  11275. marker.bindPopup(markerData.geojson.properties.popupContent, {
  11276. closeButton: false,
  11277. autoPan: false,
  11278. })
  11279. }
  11280. delete markerData.action;
  11281. }
  11282. };
  11283. function show2Dmarker(msg, guid) {
  11284. if (!map2DViewer.inited) {
  11285. return false;
  11286. }
  11287. var markerData = map23DData.markers[guid];
  11288. if (markerData.from === '3D') {
  11289. return false;
  11290. }
  11291. if (markerData.visible2D) {
  11292. return false;
  11293. }
  11294. if (markerData.groupId) {
  11295. map2DViewer.markers[guid].addTo(map2DViewer.groups[markerData.groupId]);
  11296. } else {
  11297. map2DViewer.markers[guid].addTo(map2DViewer.map);
  11298. }
  11299. markerData.visible2D = true;
  11300. }
  11301. function hide2Dmarker(msg, guid) {
  11302. if (!map2DViewer.inited) {
  11303. return false;
  11304. }
  11305. var markerData = map23DData.markers[guid];
  11306. if (markerData.from === '3D') {
  11307. return false;
  11308. }
  11309. if (!markerData.visible2D) {
  11310. return false;
  11311. }
  11312. if (markerData.groupId) {
  11313. map2DViewer.groups[markerData.groupId].removeLayer(map2DViewer.markers[guid]);
  11314. } else {
  11315. map2DViewer.map.removeLayer(map2DViewer.markers[guid]);
  11316. }
  11317. markerData.visible2D = false;
  11318. }
  11319. }(window, document));
  11320. ;
  11321. (function (window, document, undefined) {
  11322. PubSub.subscribe('map3D.marker.showPopup', showMarkerPopup);
  11323. PubSub.subscribe('map23D.marker.add', add3Dmarker);
  11324. PubSub.subscribe('map23D.marker.remove', remove3Dmarker);
  11325. PubSub.subscribe('map23D.marker.update', update3Dmarker);
  11326. PubSub.subscribe('map23D.marker.hide', hide3Dmarker);
  11327. PubSub.subscribe('map23D.marker.show', show3Dmarker);
  11328. PubSub.subscribe('map3D.marker.add', add3Dmarker);
  11329. PubSub.subscribe('map3D.marker.remove', remove3Dmarker);
  11330. PubSub.subscribe('map3D.marker.update', update3Dmarker);
  11331. PubSub.subscribe('map3D.marker.hide', hide3Dmarker);
  11332. PubSub.subscribe('map3D.marker.show', show3Dmarker);
  11333. function add3Dmarker(msg, guid) {
  11334. if (!map3DViewer.inited) {
  11335. return false;
  11336. }
  11337. var markerData = map23DData.markers[guid];
  11338. if (markerData.from === '2D') {
  11339. return false;
  11340. }
  11341. if (markerData.geojson.properties.altitudeMode == 0) {
  11342. var position = Cesium.Cartesian3.fromDegrees(markerData.geojson.geometry.coordinates[0], markerData.geojson.geometry.coordinates[1]);
  11343. } else {
  11344. var position = Cesium.Cartesian3.fromDegrees(markerData.geojson.geometry.coordinates[0], markerData.geojson.geometry.coordinates[1], markerData.geojson.properties.altitude);
  11345. }
  11346. var markerDataObj = {
  11347. id: guid,
  11348. name: markerData.geojson.properties.title,
  11349. position: position,
  11350. billboard: { //
  11351. image: markerData.geojson.properties.iconUrl,
  11352. width: markerData.geojson.properties.iconSize[0],
  11353. height: markerData.geojson.properties.iconSize[1],
  11354. verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
  11355. rotation: markerData.geojson.properties.iconRorate,
  11356. heightReference: 1,
  11357. pixelOffset: new Cesium.Cartesian2(0, 0),
  11358. distanceDisplayCondition: new Cesium.DistanceDisplayCondition(markerData.geojson.properties.distanceDisplayCondition[0], markerData.geojson.properties.distanceDisplayCondition[1]),
  11359. },
  11360. label: {
  11361. text: name,
  11362. font: markerData.geojson.properties.titleFontSize + 'px Microsoft YaHei',
  11363. verticalOrigin: Cesium.VerticalOrigin.BOTTOM, //
  11364. pixelOffset: new Cesium.Cartesian2(0, -markerData.geojson.properties.iconSize[1] - 2),
  11365. heightReference: 1,
  11366. fillColor: Cesium.Color.fromCssColorString(markerData.geojson.properties.titleColor),
  11367. distanceDisplayCondition: new Cesium.DistanceDisplayCondition(markerData.geojson.properties.distanceDisplayCondition[0], markerData.geojson.properties.distanceDisplayCondition[1]),
  11368. }
  11369. }
  11370. var marker = map3DViewer.map.entities.add(markerDataObj);
  11371. delete markerData.action;
  11372. map3DViewer.markers[guid] = marker;
  11373. if (markerData.groupId) {
  11374. map3DViewer.groups[markerData.groupId].add(marker);
  11375. }
  11376. markerData.add3D = true;
  11377. markerData.visible3D = true;
  11378. };
  11379. function remove3Dmarker(msg, guid) {
  11380. if (!map3DViewer.inited) {
  11381. return false;
  11382. }
  11383. var markerData = map23DData.markers[guid];
  11384. if (!markerData.from === '2D') {
  11385. return false;
  11386. }
  11387. if (!map3DViewer.markers[guid]) {
  11388. return false;
  11389. }
  11390. var marker = map3DViewer.markers[guid];
  11391. map3DViewer.map.entities.remove(marker);
  11392. if (markerData.groupId) {
  11393. map3DViewer.groups[markerData.groupId].remove(marker)
  11394. }
  11395. delete map3DViewer.markers[guid];
  11396. markerData.add3D = false;
  11397. };
  11398. function update3Dmarker(msg, guid) {
  11399. if (!map3DViewer.inited) {
  11400. return false;
  11401. }
  11402. if (map23DData.markers[guid]) {
  11403. var markerData = map23DData.markers[guid];
  11404. if (markerData.from === '2D') {
  11405. return false;
  11406. }
  11407. if (!map3DViewer.markers[guid]) {
  11408. return false;
  11409. }
  11410. var marker = map3DViewer.markers[guid];
  11411. var properties = markerData.geojson.properties;
  11412. var geometry = markerData.geojson.geometry;
  11413. if (geometry) {
  11414. var altitude = properties.altitude || markerData.geojson.properties.altitude;
  11415. if (properties.altitudeMode == 0) {
  11416. var position = Cesium.Cartesian3.fromDegrees(geometry.coordinates[0], geometry.coordinates[1]);
  11417. } else {
  11418. var position = Cesium.Cartesian3.fromDegrees(geometry.coordinates[0], geometry.coordinates[1], properties.altitude);
  11419. }
  11420. marker.position = position;
  11421. }
  11422. if (properties.iconUrl) {
  11423. marker.billboard.image = properties.iconUrl;
  11424. }
  11425. if (properties.iconSize) {
  11426. marker.billboard.width = properties.iconSize[0];
  11427. marker.billboard.height = properties.iconSize[1];
  11428. }
  11429. if (properties.iconAnchor) {
  11430. marker.label.pixelOffset = new Cesium.Cartesian2(0, -properties.iconSize[1] - 2);
  11431. // var x = markerData.geojson.properties.iconAnchor[0] - markerData.geojson.properties.iconSize[0]
  11432. // var y = markerData.geojson.properties.iconAnchor[1] - markerData.geojson.properties.iconSize[1]
  11433. marker.billboard.pixelOffset = new Cesium.Cartesian2(0, 0);
  11434. }
  11435. if (properties.titleFontSize) {
  11436. marker.label.font = properties.titleFontSize + 'pt monospace';
  11437. }
  11438. marker.label.text = properties.title || '';
  11439. if (properties.titleColor) {
  11440. marker.label.fillColor = Cesium.Color.fromCssColorString(properties.titleColor);
  11441. }
  11442. if (markerData.groupId) {
  11443. //已更新,无需下步
  11444. //map3DViewer.groups[markerData.groupId].getById(guid) = marker;
  11445. }
  11446. delete markerData.action;
  11447. }
  11448. };
  11449. function show3Dmarker(msg, guid) {
  11450. if (!map3DViewer.inited) {
  11451. return false;
  11452. }
  11453. var markerData = map23DData.markers[guid];
  11454. if (markerData.from === '2D') {
  11455. return false;
  11456. }
  11457. if (markerData.visible3D) {
  11458. return false;
  11459. }
  11460. if (!map3DViewer.markers[guid]) {
  11461. return false;
  11462. }
  11463. var marker = map3DViewer.markers[guid];
  11464. marker.show = true;
  11465. if (markerData.groupId) {
  11466. map3DViewer.groups[markerData.groupId].getById(guid).show = true
  11467. }
  11468. markerData.visible3D = true;
  11469. }
  11470. function hide3Dmarker(msg, guid) {
  11471. if (!map3DViewer.inited) {
  11472. return false;
  11473. }
  11474. var markerData = map23DData.markers[guid];
  11475. if (markerData.from === '2D') {
  11476. return false;
  11477. }
  11478. if (!markerData.visible3D) {
  11479. return false;
  11480. }
  11481. if (!map3DViewer.markers[guid]) {
  11482. return false;
  11483. }
  11484. var marker = map3DViewer.markers[guid];
  11485. marker.show = false;
  11486. if (markerData.groupId) {
  11487. map3DViewer.groups[markerData.groupId].getById(guid).show = false
  11488. }
  11489. markerData.visible3D = false;
  11490. }
  11491. var marker3DInterVal = null;
  11492. function creatPopup(options) {
  11493. var popupHtml = '<div class="popup_html">' +
  11494. ' <div class="popup-lt"></div>' +
  11495. ' <div class="popup-rt"></div>' +
  11496. ' <div class="popup-lb"></div>' +
  11497. ' <div class="popup-rb"></div>' +
  11498. ' <div class="popup-ct">' + options.title + '</div>' +
  11499. ' <div class="popup-cb">' + options.popupContent + '</div>' +
  11500. '</div>'
  11501. return popupHtml;
  11502. }
  11503. function showMarkerPopup(msg, options) {
  11504. if (options.type == "LEFT_CLICK") {
  11505. if ($("#markerPopup")) {
  11506. $("#markerPopup").remove();
  11507. }
  11508. clearInterval(marker3DInterVal);
  11509. var evt = options.infos;
  11510. var pickedObject = map3DViewer.map.scene.pick(evt.position);
  11511. if (pickedObject && pickedObject.id) {
  11512. var clickMarkerId = pickedObject.id._id;
  11513. if (map23DData.markers[clickMarkerId]) {
  11514. var data = map23DData.markers[clickMarkerId];
  11515. data.geojson.properties.popupContent = data.geojson.properties.popupContent || '';
  11516. data.geojson.properties.title = data.geojson.properties.title || '';
  11517. var popupAnchor = data.geojson.properties.popupAnchor;
  11518. var cartesian = map3DViewer.markers[clickMarkerId].position.getValue();
  11519. var pick = map3DViewer.Cartesian3ToScreen(cartesian);
  11520. if (data.geojson.properties.popupContent.length > 0) {
  11521. //var popupItem = '<div id="markerPopup">' + creatPopup(data.geojson.properties) + '</div>';
  11522. var popupItem = '<div id="markerPopup">' + data.geojson.properties.popupContent + '</div>';
  11523. $(popupItem).appendTo($("#map3DWrap"));
  11524. var width = $("#markerPopup").width();
  11525. var height = $("#markerPopup").height();
  11526. $("#markerPopup").css({
  11527. 'left': pick.x - width / 2 - popupAnchor[0],
  11528. 'top': pick.y - height - popupAnchor[1]
  11529. })
  11530. marker3DInterVal = setInterval(function () {
  11531. if (Object.getOwnPropertyNames(map3DViewer.markers).length <= 0) {
  11532. clearInterval(marker3DInterVal);
  11533. return;
  11534. }
  11535. var cartesian = map3DViewer.markers[clickMarkerId].position.getValue();
  11536. var pick = map3DViewer.Cartesian3ToScreen(cartesian);
  11537. $("#markerPopup").css({
  11538. 'left': pick.x - width / 2 - popupAnchor[0],
  11539. 'top': pick.y - height - popupAnchor[1]
  11540. })
  11541. }, 10)
  11542. }
  11543. }
  11544. } else {
  11545. return false;
  11546. }
  11547. }
  11548. }
  11549. }(window, document));
  11550. ;
  11551. (function (window, document, undefined) {
  11552. PubSub.subscribe('map23D.polyline.add', add2Dpolyline);
  11553. PubSub.subscribe('map23D.polyline.remove', remove2Dplyline);
  11554. PubSub.subscribe('map23D.polyline.update', update2Dpolyline);
  11555. PubSub.subscribe('map23D.polyline.show', show2Dpolyline);
  11556. PubSub.subscribe('map23D.polyline.hide', hide2Dpolyline);
  11557. PubSub.subscribe('map2D.polyline.add', add2Dpolyline);
  11558. PubSub.subscribe('map2D.polyline.remove', remove2Dplyline);
  11559. PubSub.subscribe('map2D.polyline.update', update2Dpolyline);
  11560. PubSub.subscribe('map2D.polyline.show', show2Dpolyline);
  11561. PubSub.subscribe('map2D.polyline.hide', hide2Dpolyline);
  11562. function add2Dpolyline(msg, guid) {
  11563. if (!map2DViewer.inited) {
  11564. return false;
  11565. }
  11566. var polylineData = map23DData.polylines[guid];
  11567. if (polylineData.from === '3D') {
  11568. return false;
  11569. }
  11570. /*for(var i=0;i<polylineData.geojson.geometry.coordinates.length;i++){
  11571. if(polylineData.geojson.geometry.coordinates[i][0]<=0){
  11572. polylineData.geojson.geometry.coordinates[i][0] = 360+polylineData.geojson.geometry.coordinates[i][0];
  11573. }
  11574. }*/
  11575. var polyline = L.polyline(
  11576. map23DUtil.latLngsToReverse(polylineData.geojson.geometry.coordinates), {
  11577. color: polylineData.geojson.properties.color,
  11578. weight: polylineData.geojson.properties.weight,
  11579. opacity: polylineData.geojson.properties.opacity,
  11580. title: polylineData.geojson.properties.title,
  11581. dashArray: polylineData.geojson.properties.dashArray,
  11582. lineJoin: polylineData.geojson.properties.lineJoin,
  11583. lineCap: polylineData.geojson.properties.lineCap
  11584. }
  11585. )
  11586. if (polylineData.linetype === "circleline") {
  11587. L.Util.circleDrawLatlng(polyline);
  11588. }
  11589. polyline.guid = guid;
  11590. polyline.linetype = polylineData.linetype;
  11591. if (polylineData.geojson.properties.popupContent) {
  11592. polyline.bindPopup(polylineData.geojson.properties.popupContent)
  11593. }
  11594. if (polylineData.groupId) {
  11595. polyline.addTo(map2DViewer.groups[polylineData.groupId]);
  11596. } else {
  11597. polyline.addTo(map2DViewer.map);
  11598. }
  11599. map2DViewer.polylines[guid] = polyline;
  11600. polylineData.add2D = true;
  11601. polylineData.visible2D = true;
  11602. };
  11603. function remove2Dplyline(msg, guid) {
  11604. if (!map2DViewer.inited) {
  11605. return false;
  11606. }
  11607. var polylineData = map23DData.polylines[guid];
  11608. if (polylineData.from === '3D') {
  11609. return false;
  11610. }
  11611. if (polylineData.groupId) {
  11612. map2DViewer.groups[polylineData.groupId].removeLayer(map2DViewer.polylines[guid]);
  11613. } else {
  11614. map2DViewer.map.removeLayer(map2DViewer.polylines[guid]);
  11615. }
  11616. delete map2DViewer.polylines[guid];
  11617. polylineData.add2D = false;
  11618. };
  11619. function update2Dpolyline(msg, guid) {
  11620. if (!map2DViewer.inited) {
  11621. return false;
  11622. }
  11623. var polylineData = map23DData.polylines[guid];
  11624. if (polylineData.from === '3D') {
  11625. return false;
  11626. }
  11627. map2DViewer.polylines[guid].setStyle(
  11628. polylineData.geojson.properties
  11629. );
  11630. if (polylineData.geojson.hasOwnProperty('geometry')) {
  11631. if (polylineData.geojson.geometry.coordinates.length > 1) {
  11632. map2DViewer.polylines[guid].setLatLngs(map23DUtil.latLngsToReverse(polylineData.geojson.geometry.coordinates));
  11633. }
  11634. }
  11635. if (polylineData.geojson.properties.popupContent) {
  11636. polyline.bindPopup(polylineData.geojson.properties.popupContent)
  11637. }
  11638. };
  11639. function show2Dpolyline(msg, guid) {
  11640. if (!map2DViewer.inited) {
  11641. return false;
  11642. }
  11643. var polylineData = map23DData.polylines[guid];
  11644. if (polylineData.from === '3D') {
  11645. return false;
  11646. }
  11647. if (polylineData.visible2D) {
  11648. return false;
  11649. }
  11650. if (polylineData.groupId) {
  11651. map2DViewer.polylines[guid].addTo(map2DViewer.groups[polylineData.groupId]);
  11652. } else {
  11653. map2DViewer.polylines[guid].addTo(map2DViewer.map);
  11654. }
  11655. polylineData.visible2D = true;
  11656. }
  11657. function hide2Dpolyline(msg, guid) {
  11658. if (!map2DViewer.inited) {
  11659. return false;
  11660. }
  11661. var polylineData = map23DData.polylines[guid];
  11662. if (polylineData.from === '3D') {
  11663. return false;
  11664. }
  11665. if (!polylineData.visible2D) {
  11666. return false;
  11667. }
  11668. if (polylineData.groupId) {
  11669. map2DViewer.groups[polylineData.groupId].removeLayer(map2DViewer.polylines[guid]);
  11670. } else {
  11671. map2DViewer.map.removeLayer(map2DViewer.polylines[guid]);
  11672. }
  11673. polylineData.visible2D = false;
  11674. }
  11675. }(window, document));
  11676. ;
  11677. (function (window, document, undefined) {
  11678. PubSub.subscribe('map23D.polyline.add', add3Dpolyline);
  11679. PubSub.subscribe('map23D.polyline.remove', remove3Dpolyline);
  11680. PubSub.subscribe('map23D.polyline.update', update3Dpolyline);
  11681. PubSub.subscribe('map23D.polyline.show', show3Dpolyline);
  11682. PubSub.subscribe('map23D.polyline.hide', hide3Dpolyline);
  11683. PubSub.subscribe('map3D.polyline.add', add3Dpolyline);
  11684. PubSub.subscribe('map3D.polyline.remove', remove3Dpolyline);
  11685. PubSub.subscribe('map3D.polyline.update', update3Dpolyline);
  11686. PubSub.subscribe('map3D.polyline.show', show3Dpolyline);
  11687. PubSub.subscribe('map3D.polyline.hide', hide3Dpolyline);
  11688. function add3Dpolyline(msg, guid) {
  11689. if (!map3DViewer.inited) {
  11690. return false;
  11691. }
  11692. var polylineData = map23DData.polylines[guid];
  11693. if (polylineData.from === '2D') {
  11694. return false;
  11695. }
  11696. var properties = polylineData.geojson.properties;
  11697. var geometry = polylineData.geojson.geometry;
  11698. var position = [];
  11699. var clampToGround = true;
  11700. if (properties.altitudeMode == 0) {
  11701. for (var i = 0; i < geometry.coordinates.length; i++) {
  11702. position.push(geometry.coordinates[i][0], geometry.coordinates[i][1]);
  11703. }
  11704. clampToGround = true
  11705. position = Cesium.Cartesian3.fromDegreesArray(position);
  11706. } else {
  11707. clampToGround = false
  11708. for (var i = 0; i < geometry.coordinates.length; i++) {
  11709. position.push(geometry.coordinates[i][0], geometry.coordinates[i][1], properties.altitude[i]);
  11710. }
  11711. position = Cesium.Cartesian3.fromDegreesArrayHeights(position);
  11712. }
  11713. var materialObj = {
  11714. color: Cesium.Color.fromCssColorString(properties.color),
  11715. outlineWidth: 0,
  11716. outlineColor: Cesium.Color.fromCssColorString('#FFFFFF')
  11717. }
  11718. materialObj.color.alpha = properties.opacity;
  11719. if (properties.lineType == 0) {
  11720. var material = new Cesium.PolylineOutlineMaterialProperty(materialObj)
  11721. } else {
  11722. var material = new Cesium.PolylineDashMaterialProperty(materialObj)
  11723. }
  11724. var name = properties.title || ''
  11725. var polyline = map3DViewer.map.entities.add({
  11726. id: guid,
  11727. name: name,
  11728. polyline: {
  11729. clampToGround: clampToGround,
  11730. positions: position,
  11731. width: properties.weight,
  11732. material: material,
  11733. }
  11734. });
  11735. delete polylineData.action;
  11736. map3DViewer.polylines[guid] = polyline;
  11737. if (polylineData.groupId) {
  11738. map3DViewer.groups[polylineData.groupId].add(polyline);
  11739. }
  11740. polylineData.add3D = true;
  11741. polylineData.visible3D = true;
  11742. };
  11743. function remove3Dpolyline(msg, guid) {
  11744. if (!map3DViewer.inited) {
  11745. return false;
  11746. }
  11747. var polylineData = map23DData.polylines[guid];
  11748. if (polylineData.from === '2D') {
  11749. return false;
  11750. }
  11751. if (!map3DViewer.polylines[guid]) {
  11752. return false;
  11753. }
  11754. var polyline = map3DViewer.polylines[guid];
  11755. map3DViewer.map.entities.remove(polyline);
  11756. if (polylineData.groupId) {
  11757. map3DViewer.groups[polylineData.groupId].remove(polyline)
  11758. }
  11759. delete map3DViewer.polylines[guid];
  11760. polylineData.add3D = false;
  11761. };
  11762. function update3Dpolyline(msg, guid) {
  11763. if (!map3DViewer.inited) {
  11764. return false;
  11765. }
  11766. var polylineData = map23DData.polylines[guid];
  11767. if (polylineData.from === '2D') {
  11768. return false;
  11769. }
  11770. if (!map3DViewer.polylines[guid]) {
  11771. return false;
  11772. }
  11773. var properties = polylineData.geojson.properties;
  11774. var geometry = polylineData.geojson.geometry;
  11775. var position = [];
  11776. if (properties.altitudeMode == 0) {
  11777. for (var i = 0; i < geometry.coordinates.length; i++) {
  11778. position.push(geometry.coordinates[i][0], geometry.coordinates[i][1]);
  11779. }
  11780. position = Cesium.Cartesian3.fromDegreesArray(position);
  11781. } else {
  11782. for (var i = 0; i < geometry.coordinates.length; i++) {
  11783. position.push(geometry.coordinates[i][0], geometry.coordinates[i][1], properties.altitude[i]);
  11784. }
  11785. position = Cesium.Cartesian3.fromDegreesArrayHeights(position);
  11786. }
  11787. var materialObj = {
  11788. color: Cesium.Color.fromCssColorString(properties.color),
  11789. outlineWidth: 0,
  11790. outlineColor: Cesium.Color.fromCssColorString("#ffffff")
  11791. }
  11792. materialObj.color.alpha = properties.opacity;
  11793. if (properties.lineType == 0) {
  11794. var material = new Cesium.PolylineOutlineMaterialProperty(materialObj)
  11795. } else {
  11796. var material = new Cesium.PolylineDashMaterialProperty(materialObj)
  11797. }
  11798. var polyline = map3DViewer.polylines[guid].polyline;
  11799. polyline.positions.setValue(position);
  11800. polyline.material = material;
  11801. polyline.width = properties.weight;
  11802. if (polylineData.groupId) {
  11803. //已更新,无需下步
  11804. //map3DViewer.groups[polygonData.groupId].getById(guid) = polygons;
  11805. }
  11806. delete polylineData.action;
  11807. };
  11808. function show3Dpolyline(msg, guid) {
  11809. if (!map3DViewer.inited) {
  11810. return false;
  11811. }
  11812. var polylineData = map23DData.polylines[guid];
  11813. if (polylineData.from === '2D') {
  11814. return false;
  11815. }
  11816. if (polylineData.visible3D) {
  11817. return false;
  11818. }
  11819. if (!map3DViewer.polylines[guid]) {
  11820. return false;
  11821. }
  11822. var polyline = map3DViewer.polylines[guid];
  11823. polyline.show = true;
  11824. if (polylineData.groupId) {
  11825. map3DViewer.groups[polylineData.groupId].getById(guid).show = true
  11826. }
  11827. polylineData.visible3D = true;
  11828. }
  11829. function hide3Dpolyline(msg, guid) {
  11830. if (!map3DViewer.inited) {
  11831. return false;
  11832. }
  11833. var polylineData = map23DData.polylines[guid];
  11834. if (polylineData.from === '2D') {
  11835. return false;
  11836. }
  11837. if (!polylineData.visible3D) {
  11838. return false;
  11839. }
  11840. if (!map3DViewer.polylines[guid]) {
  11841. return false;
  11842. }
  11843. var polyline = map3DViewer.polylines[guid];
  11844. polyline.show = false;
  11845. if (polylineData.groupId) {
  11846. map3DViewer.groups[polylineData.groupId].getById(guid).show = false
  11847. }
  11848. polylineData.visible3D = false;
  11849. }
  11850. }(window, document));
  11851. ;
  11852. (function (window, document, undefined) {
  11853. PubSub.subscribe('map23D.polygon.add', add2Dpolygon);
  11854. PubSub.subscribe('map23D.polygon.remove', remove2Dpolygon);
  11855. PubSub.subscribe('map23D.polygon.update', update2Dpolygon);
  11856. PubSub.subscribe('map23D.polygon.hide', hide2Dpolygon);
  11857. PubSub.subscribe('map23D.polygon.show', show2Dpolygon);
  11858. PubSub.subscribe('map2D.polygon.add', add2Dpolygon);
  11859. PubSub.subscribe('map2D.polygon.remove', remove2Dpolygon);
  11860. PubSub.subscribe('map2D.polygon.update', update2Dpolygon);
  11861. PubSub.subscribe('map2D.polygon.show', show2Dpolygon);
  11862. PubSub.subscribe('map2D.polygon.hide', hide2Dpolygon);
  11863. function add2Dpolygon(msg, guid) {
  11864. if (!map2DViewer.inited) {
  11865. return false;
  11866. }
  11867. var polygonData = map23DData.polygons[guid];
  11868. if (polygonData.from === '3D') {
  11869. return false;
  11870. }
  11871. var polygon = L.polygon(
  11872. map23DUtil.latLngsToReverse(polygonData.geojson.geometry.coordinates[0]), {
  11873. color: polygonData.geojson.properties.color, //边框颜色
  11874. weight: polygonData.geojson.properties.weight, //边框宽度
  11875. fillColor: polygonData.geojson.properties.fillColor, //填充色
  11876. opacity: polygonData.geojson.properties.opacity, //线的透明度
  11877. fillOpacity: polygonData.geojson.properties.fillOpacity, //填充透明度
  11878. title: polygonData.geojson.properties.title
  11879. }
  11880. )
  11881. if (polygonData.polygontype === "circlepolygon") {
  11882. L.Util.circleDrawLatlng(polygon);
  11883. }
  11884. polygon.guid = guid;
  11885. polygon.polygontype = polygonData.polygontype;
  11886. if (polygonData.geojson.properties.popupContent) {
  11887. polygon.bindPopup(polygonData.geojson.properties.popupContent)
  11888. }
  11889. if (polygonData.groupId) {
  11890. polygon.addTo(map2DViewer.groups[polygonData.groupId]);
  11891. } else {
  11892. polygon.addTo(map2DViewer.map);
  11893. }
  11894. map2DViewer.polygons[guid] = polygon;
  11895. polygonData.add2D = true;
  11896. polygonData.visible2D = true;
  11897. };
  11898. function remove2Dpolygon(msg, guid) {
  11899. if (!map2DViewer.inited) {
  11900. return false;
  11901. }
  11902. var polygonData = map23DData.polygons[guid];
  11903. if (polygonData.from === '3D') {
  11904. return false;
  11905. }
  11906. if (polygonData.groupId) {
  11907. map2DViewer.groups[polygonData.groupId].removeLayer(map2DViewer.polygons[guid]);
  11908. } else {
  11909. map2DViewer.map.removeLayer(map2DViewer.polygons[guid]);
  11910. }
  11911. delete map2DViewer.polygons[guid];
  11912. polygonData.add2D = false;
  11913. };
  11914. function update2Dpolygon(msg, guid) {
  11915. if (!map2DViewer.inited) {
  11916. return false;
  11917. }
  11918. var polygonData = map23DData.polygons[guid];
  11919. if (polygonData.from === '3D') {
  11920. return false;
  11921. }
  11922. map2DViewer.polygons[guid].setStyle(
  11923. polygonData.geojson.properties
  11924. );
  11925. if (polygonData.geojson.hasOwnProperty('geometry')) {
  11926. if (polygonData.geojson.geometry.coordinates[0].length > 1) {
  11927. map2DViewer.polygons[guid].setLatLngs(map23DUtil.latLngsToReverse(polygonData.geojson.geometry.coordinates[0]));
  11928. }
  11929. }
  11930. if (polygonData.geojson.properties.popupContent) {
  11931. polygon.bindPopup(polygonData.geojson.properties.popupContent)
  11932. }
  11933. delete polygonData.action;
  11934. };
  11935. function show2Dpolygon(msg, guid) {
  11936. if (!map2DViewer.inited) {
  11937. return false;
  11938. }
  11939. var polygonData = map23DData.polygons[guid];
  11940. if (polygonData.from === '3D') {
  11941. return false;
  11942. }
  11943. if (polygonData.visible2D) {
  11944. return false;
  11945. }
  11946. if (polygonData.groupId) {
  11947. map2DViewer.polygons[guid].addTo(map2DViewer.groups[polygonData.groupId]);
  11948. } else {
  11949. map2DViewer.polygons[guid].addTo(map2DViewer.map);
  11950. }
  11951. polygonData.visible2D = true;
  11952. }
  11953. function hide2Dpolygon(msg, guid) {
  11954. if (!map2DViewer.inited) {
  11955. return false;
  11956. }
  11957. var polygonData = map23DData.polygons[guid];
  11958. if (polygonData.from === '3D') {
  11959. return false;
  11960. }
  11961. if (!polygonData.visible2D) {
  11962. return false;
  11963. }
  11964. if (polygonData.groupId) {
  11965. map2DViewer.groups[polygonData.groupId].removeLayer(map2DViewer.polygons[guid]);
  11966. } else {
  11967. map2DViewer.map.removeLayer(map2DViewer.polygons[guid]);
  11968. }
  11969. polygonData.visible2D = false;
  11970. }
  11971. }(window, document));
  11972. ;
  11973. (function (window, document, undefined) {
  11974. PubSub.subscribe('map23D.polygon.add', add3Dpolygon);
  11975. PubSub.subscribe('map23D.polygon.remove', remove3Dpolygon);
  11976. PubSub.subscribe('map23D.polygon.update', update3Dpolygon);
  11977. PubSub.subscribe('map23D.polygon.hide', hide3Dpolygon);
  11978. PubSub.subscribe('map23D.polygon.show', show3Dpolygon);
  11979. PubSub.subscribe('map3D.polygon.add', add3Dpolygon);
  11980. PubSub.subscribe('map3D.polygon.remove', remove3Dpolygon);
  11981. PubSub.subscribe('map3D.polygon.update', update3Dpolygon);
  11982. PubSub.subscribe('map3D.polygon.hide', hide3Dpolygon);
  11983. PubSub.subscribe('map3D.polygon.show', show3Dpolygon);
  11984. function add3Dpolygon(msg, guid) {
  11985. if (!map3DViewer.inited) {
  11986. return false;
  11987. }
  11988. var polygonData = map23DData.polygons[guid];
  11989. if (polygonData.from === '2D') {
  11990. return false;
  11991. }
  11992. var properties = polygonData.geojson.properties;
  11993. var geometry = polygonData.geojson.geometry;
  11994. var position = [];
  11995. if (properties.video) {
  11996. var material = document.getElementById(properties.videoContent)
  11997. } else {
  11998. var material = Cesium.Color.fromCssColorString(properties.fillColor);
  11999. }
  12000. if (properties.weight > 0 || !properties.weight.toString()) {
  12001. var outlineJudge = true;
  12002. } else {
  12003. var outlineJudge = false;
  12004. }
  12005. var polygonObj = {
  12006. outline: outlineJudge,
  12007. extrudedHeight: properties.extrudedHeight || 0,
  12008. material: material,
  12009. outlineWidth: properties.weight,
  12010. outlineColor: Cesium.Color.fromCssColorString(properties.color)
  12011. };
  12012. polygonObj.material.alpha = properties.fillOpacity;
  12013. polygonObj.outlineColor.alpha = properties.opacity;
  12014. polygonObj.height = 0
  12015. if (properties.altitudeMode == 0 || !properties.altitudeMode) {
  12016. for (var i = 0; i < geometry.coordinates[0].length; i++) {
  12017. position.push(geometry.coordinates[0][i][0], geometry.coordinates[0][i][1]);
  12018. }
  12019. position = Cesium.Cartesian3.fromDegreesArray(position);
  12020. } else {
  12021. polygonObj.perPositionHeight = true;
  12022. for (var i = 0; i < geometry.coordinates[0].length; i++) {
  12023. position.push(geometry.coordinates[0][i][0], geometry.coordinates[0][i][1], properties.altitude[i]);
  12024. }
  12025. position = Cesium.Cartesian3.fromDegreesArrayHeights(position);
  12026. }
  12027. polygonObj.hierarchy = position;
  12028. var name = properties.title || ''
  12029. var polygon = map3DViewer.map.entities.add({
  12030. id: guid,
  12031. name: name,
  12032. polygon: polygonObj
  12033. });
  12034. delete polygonData.action;
  12035. map3DViewer.polygons[guid] = polygon;
  12036. if (polygonData.groupId) {
  12037. map3DViewer.groups[polygonData.groupId].add(polygon);
  12038. }
  12039. polygonData.add3D = true;
  12040. polygonData.visible3D = true;
  12041. };
  12042. function remove3Dpolygon(msg, guid) {
  12043. if (!map3DViewer.inited) {
  12044. return false;
  12045. }
  12046. var polygonData = map23DData.polygons[guid];
  12047. if (polygonData.from === '2D') {
  12048. return false;
  12049. }
  12050. if (!map3DViewer.polygons[guid]) {
  12051. return false;
  12052. }
  12053. var polygon = map3DViewer.polygons[guid];
  12054. map3DViewer.map.entities.remove(polygon);
  12055. if (polygonData.groupId) {
  12056. map3DViewer.groups[polygonData.groupId].remove(polygon)
  12057. }
  12058. delete map3DViewer.polygons[guid];
  12059. polygonData.add3D = false;
  12060. };
  12061. function update3Dpolygon(msg, guid) {
  12062. if (!map3DViewer.inited) {
  12063. return false;
  12064. }
  12065. var polygonData = map23DData.polygons[guid];
  12066. if (polygonData.from === '2D') {
  12067. return false;
  12068. }
  12069. if (!map3DViewer.polygons[guid]) {
  12070. return false;
  12071. }
  12072. var properties = polygonData.geojson.properties;
  12073. var geometry = polygonData.geojson.geometry;
  12074. var position = [];
  12075. var fillColor = Cesium.Color.fromCssColorString(properties.fillColor)
  12076. fillColor.alpha = properties.fillOpacity;
  12077. var outlineColor = Cesium.Color.fromCssColorString(properties.color);
  12078. outlineColor.alpha = properties.opacity;
  12079. if (properties.altitudeMode == 0 || !properties.altitudeMode) {
  12080. for (var i = 0; i < geometry.coordinates[0].length; i++) {
  12081. position.push(geometry.coordinates[0][i][0], geometry.coordinates[0][i][1]);
  12082. }
  12083. position = Cesium.Cartesian3.fromDegreesArray(position);
  12084. } else {
  12085. for (var i = 0; i < geometry.coordinates[0].length; i++) {
  12086. position.push(geometry.coordinates[0][i][0], geometry.coordinates[0][i][1], properties.altitude[i]);
  12087. }
  12088. position = Cesium.Cartesian3.fromDegreesArrayHeights(position);
  12089. }
  12090. var name = properties.title || '';
  12091. if (properties.weight > 0 || !properties.weight.toString()) {
  12092. var outlineJudge = true;
  12093. } else {
  12094. var outlineJudge = false;
  12095. }
  12096. var polygon = map3DViewer.polygons[guid].polygon
  12097. polygon.outline = outlineJudge;
  12098. polygon.hierarchy = position;
  12099. polygon.material.color = fillColor;
  12100. polygon.outlineColor = outlineColor;
  12101. polygon.outlineWidth.setValue(properties.weight)
  12102. polygon.extrudedHeight = properties.extrudedHeight;
  12103. if (polygonData.groupId) {
  12104. //已更新,无需下步
  12105. //map3DViewer.groups[polygonData.groupId].getById(guid) = polygons;
  12106. }
  12107. delete polygonData.action;
  12108. };
  12109. function show3Dpolygon(msg, guid) {
  12110. if (!map3DViewer.inited) {
  12111. return false;
  12112. }
  12113. var polygonData = map23DData.polygons[guid];
  12114. if (polygonData.from === '2D') {
  12115. return false;
  12116. }
  12117. if (polygonData.visible3D) {
  12118. return false;
  12119. }
  12120. if (!map3DViewer.polygons[guid]) {
  12121. return false;
  12122. }
  12123. var polygon = map3DViewer.polygons[guid];
  12124. polygon.show = true;
  12125. if (polygonData.groupId) {
  12126. map3DViewer.groups[polygonData.groupId].getById(guid).show = true
  12127. }
  12128. polygonData.visible3D = true;
  12129. };
  12130. function hide3Dpolygon(msg, guid) {
  12131. if (!map3DViewer.inited) {
  12132. return false;
  12133. }
  12134. var polygonData = map23DData.polygons[guid];
  12135. if (polygonData.from === '2D') {
  12136. return false;
  12137. }
  12138. if (!polygonData.visible3D) {
  12139. return false;
  12140. }
  12141. if (!map3DViewer.polygons[guid]) {
  12142. return false;
  12143. }
  12144. var polygon = map3DViewer.polygons[guid];
  12145. polygon.show = false;
  12146. if (polygonData.groupId) {
  12147. map3DViewer.groups[polygonData.groupId].getById(guid).show = false
  12148. }
  12149. polygonData.visible3D = false;
  12150. };
  12151. }(window, document));
  12152. ;
  12153. (function (window, document, undefined) {
  12154. PubSub.subscribe('map23D.tileLayer.add', add2Dlayer);
  12155. PubSub.subscribe('map23D.tileLayer.remove', remove2Dlayer);
  12156. PubSub.subscribe('map23D.tileLayer.update', update2Dlayer);
  12157. PubSub.subscribe('map23D.tileLayer.show', show2Dlayer);
  12158. PubSub.subscribe('map23D.tileLayer.hide', hide2Dlayer);
  12159. PubSub.subscribe('map23D.defaultTileLayer.change', default2DtileLayer);
  12160. PubSub.subscribe('map2D.tileLayer.add', add2Dlayer);
  12161. PubSub.subscribe('map2D.tileLayer.remove', remove2Dlayer);
  12162. PubSub.subscribe('map2D.tileLayer.update', update2Dlayer);
  12163. PubSub.subscribe('map2D.tileLayer.show', show2Dlayer);
  12164. PubSub.subscribe('map2D.tileLayer.hide', hide2Dlayer);
  12165. PubSub.subscribe('map2D.defaultTileLayer.change', default2DtileLayer);
  12166. function default2DtileLayer(msg, options) {
  12167. return;
  12168. var guid = 'tileLayer2DDefault';
  12169. if (options.mapName.length == 0) {
  12170. if (map2DViewer.layers[guid]) {
  12171. map2DViewer.map.removeLayer(map2DViewer.layers[guid]);
  12172. delete map23DData.layers[guid];
  12173. }
  12174. return guid;
  12175. }
  12176. if (map2DViewer.layers[guid]) {
  12177. map2DViewer.map.removeLayer(map2DViewer.layers[guid]);
  12178. }
  12179. var tileLayerData = {
  12180. from: '2D',
  12181. type: 'tileLayer',
  12182. guid: guid,
  12183. layer: {
  12184. url2D: map23DConfig.tileServerUrl + '/' + options.mapName + '?l={z}&x={x}&y={y}',
  12185. minZoom: map23DConfig.map2DMinZoom || 1,
  12186. maxZoom: map23DConfig.map2DMaxZoom || 21,
  12187. maxNativeZoom: map23DConfig.map2DMaxZoom || 21,
  12188. attribution: '',
  12189. opacity: 1
  12190. }
  12191. }
  12192. map23DData.layers[guid] = tileLayerData;
  12193. var tileLayer = L.tileLayer(tileLayerData.layer.url2D, {
  12194. minZoom: tileLayerData.layer.minZoom,
  12195. maxZoom: tileLayerData.layer.maxZoom,
  12196. opacity: tileLayerData.layer.opacity,
  12197. maxNativeZoom: tileLayerData.layer.maxNativeZoom,
  12198. attribution: tileLayerData.layer.attribution,
  12199. subdomains: map23DConfig.tileSubdomains || '',
  12200. noWrap: false
  12201. });
  12202. tileLayer.guid = guid;
  12203. tileLayer.addTo(map2DViewer.map);
  12204. tileLayer.bringToBack();
  12205. map2DViewer.layers[guid] = tileLayer;
  12206. return guid;
  12207. }
  12208. /**
  12209. * 根据GUID添加图层
  12210. * @param {[type]} msg [description]
  12211. * @param {[type]} guid [description]
  12212. */
  12213. function add2Dlayer(msg, guid) {
  12214. if (!map2DViewer.inited) {
  12215. return false;
  12216. }
  12217. var tileLayerData = map23DData.layers[guid];
  12218. if (tileLayerData.from === '3D') {
  12219. return false;
  12220. }
  12221. var tileLayer = L.tileLayer(tileLayerData.layer.url2D, {
  12222. minZoom: tileLayerData.layer.minZoom,
  12223. maxZoom: tileLayerData.layer.maxZoom,
  12224. opacity: tileLayerData.layer.opacity,
  12225. attribution: tileLayerData.layer.attribution,
  12226. subdomains: map23DConfig.tileSubdomains || '',
  12227. noWrap: false
  12228. });
  12229. var startTime, stopTime;
  12230. tileLayer.on('tileloadstart', function () {
  12231. startTime = new Date();
  12232. })
  12233. tileLayer.on('load', function () {
  12234. stop = new Date();
  12235. console.log(stop - startTime)
  12236. })
  12237. tileLayer.guid = guid;
  12238. tileLayer.addTo(map2DViewer.map);
  12239. map2DViewer.layers[guid] = tileLayer;
  12240. tileLayerData.add2D = true;
  12241. tileLayerData.visible2D = true;
  12242. }
  12243. /**
  12244. * 移除指定GUID的图层
  12245. * @param {[type]} msg [description]
  12246. * @param {[type]} guid [description]
  12247. * @return {[type]} [description]
  12248. */
  12249. function remove2Dlayer(msg, guid) {
  12250. if (!map2DViewer.inited) {
  12251. return false;
  12252. }
  12253. var tileLayerData = map23DData.layers[guid];
  12254. if (tileLayerData.from === '3D') {
  12255. return false;
  12256. }
  12257. map2DViewer.map.removeLayer(map2DViewer.layers[guid]);
  12258. delete map2DViewer.layers[guid];
  12259. tileLayerData.add2D = false;
  12260. }
  12261. /**
  12262. * 更新指定GUID的图层
  12263. * @param {[type]} msg [description]
  12264. * @param {[type]} guid [description]
  12265. * @return {[type]} [description]
  12266. */
  12267. function update2Dlayer(msg, guid) {
  12268. if (!map2DViewer.inited) {
  12269. return false;
  12270. }
  12271. var tileLayerData = map23DData.layers[guid];
  12272. if (tileLayerData.from === '3D') {
  12273. return false;
  12274. }
  12275. var tileLayer = map2DViewer.layers[guid];
  12276. if (tileLayer.options.opacity != tileLayerData.layer.opacity) {
  12277. tileLayer.setOpacity(tileLayerData.layer.opacity);
  12278. }
  12279. if (tileLayer._url != tileLayerData.layer.url2D) {
  12280. tileLayer.setUrl(tileLayerData.layer.url2D);
  12281. }
  12282. }
  12283. function show2Dlayer(msg, guid) {
  12284. if (!map2DViewer.inited) {
  12285. return false;
  12286. }
  12287. var tileLayerData = map23DData.layers[guid];
  12288. if (tileLayerData.from === '3D') {
  12289. return false;
  12290. }
  12291. if (tileLayerData.visible2D) {
  12292. return false;
  12293. }
  12294. map2DViewer.layers[guid].addTo(map2DViewer.map);
  12295. tileLayerData.visible2D = true;
  12296. }
  12297. function hide2Dlayer(msg, guid) {
  12298. if (!map2DViewer.inited) {
  12299. return false;
  12300. }
  12301. var tileLayerData = map23DData.layers[guid];
  12302. if (tileLayerData.from === '3D') {
  12303. return false;
  12304. }
  12305. if (!tileLayerData.visible2D) {
  12306. return false;
  12307. }
  12308. map2DViewer.map.removeLayer(map2DViewer.layers[guid]);
  12309. tileLayerData.visible2D = false;
  12310. }
  12311. }(window, document));
  12312. ;
  12313. (function (window, document, undefined) {
  12314. PubSub.subscribe('map23D.tileLayer.add', add3DtileLayer);
  12315. PubSub.subscribe('map23D.tileLayer.remove', remove3DtileLayer);
  12316. PubSub.subscribe('map23D.tileLayer.update', update3DtileLayer);
  12317. PubSub.subscribe('map23D.tileLayer.hide', hide3DtileLayer);
  12318. PubSub.subscribe('map23D.tileLayer.show', show3DtileLayer);
  12319. PubSub.subscribe('map23D.defaultTileLayer.change', default3DtileLayer);
  12320. PubSub.subscribe('map3D.tileLayer.add', add3DtileLayer);
  12321. PubSub.subscribe('map3D.tileLayer.remove', remove3DtileLayer);
  12322. PubSub.subscribe('map3D.tileLayer.update', update3DtileLayer);
  12323. PubSub.subscribe('map3D.tileLayer.hide', hide3DtileLayer);
  12324. PubSub.subscribe('map3D.tileLayer.show', show3DtileLayer);
  12325. PubSub.subscribe('map3D.defaultTileLayer.change', default3DtileLayer);
  12326. function default3DtileLayer(msg, options) {
  12327. var guid = 'tileLayer3DDefault';
  12328. if (options.mapName.length == 0) {
  12329. if (map3DViewer.layers[guid]) {
  12330. map3DViewer.map.scene.imageryLayers.remove(map3DViewer.layers[guid]);
  12331. delete map23DData.layers[guid];
  12332. }
  12333. return guid;
  12334. }
  12335. if (map3DViewer.layers[guid]) {
  12336. map3DViewer.map.scene.imageryLayers.remove(map3DViewer.layers[guid]);
  12337. }
  12338. if(options.mapName == "gr"){
  12339. // var url3D = "http://121.43.55.7:10011/proxy?servertype=World_Imagery&token=622067E9-93E5-D8EC-E677-85B58A63C0C7"
  12340. var url3D = onemapUrlConfig.customizeLayer.gr
  12341. }else if(options.mapName == "gt"){
  12342. // var url3D = "http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer"
  12343. var url3D = onemapUrlConfig.customizeLayer.gt
  12344. }else if(options.mapName == "gm"){
  12345. // var url3D = "http://121.43.55.7:10011/proxy?servertype=World_Street_Map&token=622067E9-93E5-D8EC-E677-85B58A63C0C7"
  12346. var url3D = onemapUrlConfig.customizeLayer.gm
  12347. }
  12348. var tileLayerData = {
  12349. from: '3D',
  12350. type: 'tileLayer',
  12351. guid: guid,
  12352. layer: {
  12353. url3D: url3D,
  12354. minZoom: map23DConfig.map23DMinZoom || 1,
  12355. maxZoom: map23DConfig.map23DMaxZoom || 21,
  12356. imageType: map23DConfig.imageType, //3D瓦片图片类型
  12357. layerBounds: map23DConfig.layerBounds,
  12358. subdomains: map23DConfig.tileSubdomains || '0123456789',
  12359. opacity: 1
  12360. }
  12361. }
  12362. map23DData.layers[guid] = tileLayerData;
  12363. // var tileLayer = map3DViewer.map.scene.imageryLayers.addImageryProvider(new Cesium.ArcGisMapServerImageryProvider({ //默认加载影像图
  12364. // url: tileLayerData.layer.url3D,
  12365. // minimumLevel: tileLayerData.layer.minZoom,
  12366. // maximumLevel: tileLayerData.layer.maxZoom,
  12367. // format: tileLayerData.layer.imageType || "png",
  12368. // subdomains: tileLayerData.layer.subdomains,
  12369. // rectangle: Cesium.Rectangle.fromDegrees(tileLayerData.layer.layerBounds[0][1], tileLayerData.layer.layerBounds[1][0], tileLayerData.layer.layerBounds[1][1], tileLayerData.layer.layerBounds[0][0])
  12370. // }))
  12371. var tileLayer = map3DViewer.map.imageryLayers.addImageryProvider(new Cesium.CGCS2000ArcGisMapServerImageryProvider({ //默认加载影像图
  12372. url: tileLayerData.layer.url3D,
  12373. // minimumLevel: tileLayerData.layer.minZoom,
  12374. // maximumLevel: tileLayerData.layer.maxZoom,
  12375. // format: tileLayerData.layer.imageType || "png",
  12376. // subdomains: tileLayerData.layer.subdomains,
  12377. // rectangle: Cesium.Rectangle.fromDegrees(tileLayerData.layer.layerBounds[0][1], tileLayerData.layer.layerBounds[1][0], tileLayerData.layer.layerBounds[1][1], tileLayerData.layer.layerBounds[0][0])
  12378. }))
  12379. tileLayer.alpha = tileLayerData.layer.opacity;
  12380. map3DViewer.layers[guid] = tileLayer;
  12381. tileLayerData.add3D = true;
  12382. tileLayerData.visible3D = true;
  12383. }
  12384. function add3DtileLayer(msg, guid) {
  12385. if (!map3DViewer.inited) {
  12386. return false;
  12387. }
  12388. var tileLayerData = map23DData.layers[guid];
  12389. if (tileLayerData.from === '2D') {
  12390. return false;
  12391. }
  12392. var tileLayer = map3DViewer.map.scene.imageryLayers.addImageryProvider(new Cesium.UrlTemplateImageryProvider({ //默认加载影像图
  12393. url: tileLayerData.layer.url3D,
  12394. minimumLevel: tileLayerData.layer.minZoom,
  12395. maximumLevel: tileLayerData.layer.maxZoom,
  12396. format: tileLayerData.layer.imageType,
  12397. subdomains: tileLayerData.layer.tileSubdomains || '0123456789',
  12398. rectangle: Cesium.Rectangle.fromDegrees(tileLayerData.layer.layerBounds[0][1], tileLayerData.layer.layerBounds[1][0], tileLayerData.layer.layerBounds[1][1], tileLayerData.layer.layerBounds[0][0])
  12399. }))
  12400. tileLayer.alpha = tileLayerData.layer.opacity;
  12401. map3DViewer.layers[guid] = tileLayer;
  12402. tileLayerData.add3D = true;
  12403. tileLayerData.visible3D = true;
  12404. };
  12405. function remove3DtileLayer(msg, guid) {
  12406. if (!map3DViewer.inited) {
  12407. return false;
  12408. }
  12409. var tileLayerData = map23DData.layers[guid];
  12410. if (tileLayerData.from === '2D') {
  12411. return false;
  12412. }
  12413. if (!map3DViewer.layers[guid]) {
  12414. return false;
  12415. }
  12416. if (map3DViewer.layers[guid] != null) {
  12417. map3DViewer.map.scene.imageryLayers.remove(map3DViewer.layers[guid]);
  12418. }
  12419. delete map3DViewer.layers[guid];
  12420. tileLayerData.add3D = false;
  12421. };
  12422. function update3DtileLayer(msg, guid) {
  12423. if (!map3DViewer.inited) {
  12424. return false;
  12425. }
  12426. var tileLayerData = map23DData.layers[guid];
  12427. if (tileLayerData.from === '2D') {
  12428. return false;
  12429. }
  12430. if (!map3DViewer.layers[guid]) {
  12431. return false;
  12432. }
  12433. var layer = map3DViewer.layers[guid]
  12434. if (map3DViewer.map.scene.imageryLayers.contains(layer))
  12435. map3DViewer.map.scene.imageryLayers.remove(layer, true) // (要移除的图层,是否摧毁图层)
  12436. var tileLayer = map3DViewer.map.scene.imageryLayers.addImageryProvider(new Cesium.UrlTemplateImageryProvider({ //默认加载影像图
  12437. url: tileLayerData.layer.url3D,
  12438. minimumLevel: tileLayerData.layer.minZoom,
  12439. maximumLevel: tileLayerData.layer.maxZoom,
  12440. format: tileLayerData.layer.imageType,
  12441. subdomains: tileLayerData.layer.tileSubdomains || '0123456789',
  12442. rectangle: Cesium.Rectangle.fromDegrees(tileLayerData.layer.layerBounds[0][1], tileLayerData.layer.layerBounds[1][0], tileLayerData.layer.layerBounds[1][1], tileLayerData.layer.layerBounds[0][0])
  12443. }))
  12444. tileLayer.alpha = tileLayerData.layer.opacity;
  12445. map3DViewer.layers[guid] = tileLayer;
  12446. }
  12447. function show3DtileLayer(msg, guid) {
  12448. if (!map3DViewer.inited) {
  12449. return false;
  12450. }
  12451. var tileLayerData = map23DData.layers[guid];
  12452. if (tileLayerData.from === '2D') {
  12453. return false;
  12454. }
  12455. if (tileLayerData.visible3D) {
  12456. return false;
  12457. }
  12458. if (!map3DViewer.layers[guid]) {
  12459. return false;
  12460. }
  12461. map3DViewer.layers[guid].show = true;
  12462. tileLayerData.visible3D = true;
  12463. }
  12464. function hide3DtileLayer(msg, guid) {
  12465. if (!map3DViewer.inited) {
  12466. return false;
  12467. }
  12468. var tileLayerData = map23DData.layers[guid];
  12469. if (tileLayerData.from === '2D') {
  12470. return false;
  12471. }
  12472. if (!tileLayerData.visible3D) {
  12473. return false;
  12474. }
  12475. if (!map3DViewer.layers[guid]) {
  12476. return false;
  12477. }
  12478. map3DViewer.layers[guid].show = false;
  12479. tileLayerData.visible3D = false;
  12480. }
  12481. }(window, document));
  12482. ;
  12483. (function (window, document, undefined) {
  12484. map3DViewer.DEMBil = {}
  12485. PubSub.subscribe('map3D.DEMTileLayer.addEvent', add3DDEMTileLayerEvent);
  12486. PubSub.subscribe('map3D.DEMTileLayer.add', add3DDEMTileLayer);
  12487. PubSub.subscribe('map3D.DEMTileLayer.remove', remove3DDEMTileLayer);
  12488. /**
  12489. * options={name:"",func:function}
  12490. */
  12491. function add3DDEMTileLayerEvent(msg, options) {
  12492. map3DViewer.DEMBil[options.name] = options.func
  12493. }
  12494. function add3DDEMTileLayer(msg, guid) {
  12495. if (!map3DViewer.inited) {
  12496. return false;
  12497. }
  12498. var DEMTileLayerData = map23DData.DEMLayers[guid];
  12499. if (DEMTileLayerData.from === '2D') {
  12500. return false;
  12501. }
  12502. var terrain = null;
  12503. map3DViewer.map.scene.globe.depthTestAgainstTerrain = false;
  12504. if (DEMTileLayerData.layer.DEMFormat == 'bil') {
  12505. terrain = new map3DViewer.DEMBil.InfoCesiumTerrainProvider({
  12506. url: DEMTileLayerData.layer.url3D,
  12507. maxLevel: DEMTileLayerData.layer.DEMMaxZoom,
  12508. subDomains: DEMTileLayerData.layer.subDomains
  12509. })
  12510. map3DViewer.map.scene.terrainProvider = terrain;
  12511. } else if (DEMTileLayerData.layer.DEMFormat == 'terrain') {
  12512. terrain = new Cesium.CesiumTerrainProvider({
  12513. url: DEMTileLayerData.layer.url3D,
  12514. });
  12515. map3DViewer.map.scene.terrainProvider = terrain;
  12516. }
  12517. };
  12518. function remove3DDEMTileLayer(msg, guid) {
  12519. if (!map3DViewer.inited) {
  12520. return false;
  12521. }
  12522. var DEMTileLayerData = map23DData.DEMLayers[guid];
  12523. if (DEMTileLayerData.from === '2D') {
  12524. return false;
  12525. }
  12526. var terrain = new Cesium.EllipsoidTerrainProvider({});
  12527. map3DViewer.map.scene.terrainProvider = terrain
  12528. };
  12529. }(window, document));
  12530. ;
  12531. (function (window, document, undefined) {
  12532. 'use strict';
  12533. if (typeof (Cesium) == "undefined") {
  12534. return;
  12535. }
  12536. // var Uri = Cesium.Uri;
  12537. var when = Cesium.when;
  12538. var BoundingSphere = Cesium.BoundingSphere;
  12539. var Cartesian3 = Cesium.Cartesian3;
  12540. var Credit = Cesium.Credit;
  12541. var defaultValue = Cesium.defaultValue;
  12542. var defined = Cesium.defined;
  12543. var defineProperties = Object.defineProperties;
  12544. var DeveloperError = Cesium.DeveloperError;
  12545. var Event = Cesium.Event;
  12546. var GeographicTilingScheme = Cesium.GeographicTilingScheme;
  12547. var HeightmapTerrainData = Cesium.HeightmapTerrainData;
  12548. var IndexDatatype = Cesium.IndexDatatype;
  12549. var joinUrls = Cesium.joinUrls;
  12550. var loadJson = Cesium.loadJson;
  12551. var CesiumMath = Cesium.CesiumMath;
  12552. var Matrix3 = Cesium.Matrix3;
  12553. var OrientedBoundingBox = Cesium.OrientedBoundingBox;
  12554. var QuantizedMeshTerrainData = Cesium.QuantizedMeshTerrainData;
  12555. var RuntimeError = Cesium.RuntimeError;
  12556. var TerrainProvider = Cesium.TerrainProvider;
  12557. //var throttleRequestByServer = Cesium.throttleRequestByServer;
  12558. var TileProviderError = Cesium.TileProviderError;
  12559. var domainsIndex = 0;
  12560. /**
  12561. * A {@link TerrainProvider} that access terrain data in a Cesium terrain format.
  12562. * The format is described on the
  12563. * {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Cesium-Terrain-Server|Cesium wiki}.
  12564. *
  12565. * @alias CesiumTerrainProvider
  12566. * @constructor
  12567. *
  12568. * @param {Object} options Object with the following properties:
  12569. * @param {String} options.url The URL of the Cesium terrain server.
  12570. * @param {Proxy} [options.proxy] A proxy to use for requests. This object is expected to have a getURL function which returns the proxied URL, if needed.
  12571. * @param {Boolean} [options.requestVertexNormals=false] Flag that indicates if the client should request additional lighting information from the server, in the form of per vertex normals if available.
  12572. * @param {Boolean} [options.requestWaterMask=false] Flag that indicates if the client should request per tile water masks from the server, if available.
  12573. * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
  12574. * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas.
  12575. *
  12576. *
  12577. * @example
  12578. * // Construct a terrain provider that uses per vertex normals for lighting
  12579. * // to add shading detail to an imagery provider.
  12580. * var terrainProvider = new Cesium.CesiumTerrainProvider({
  12581. * url : 'https://assets.agi.com/stk-terrain/world',
  12582. * requestVertexNormals : true
  12583. * });
  12584. *
  12585. * // Terrain geometry near the surface of the globe is difficult to view when using NaturalEarthII imagery,
  12586. * // unless the TerrainProvider provides additional lighting information to shade the terrain (as shown above).
  12587. * var imageryProvider = Cesium.createTileMapServiceImageryProvider({
  12588. * url : 'http://localhost:8080/Source/Assets/Textures/NaturalEarthII',
  12589. * fileExtension : 'jpg'
  12590. * });
  12591. *
  12592. * var viewer = new Cesium.Viewer('cesiumContainer', {
  12593. * imageryProvider : imageryProvider,
  12594. * baseLayerPicker : false,
  12595. * terrainProvider : terrainProvider
  12596. * });
  12597. *
  12598. * // The globe must enable lighting to make use of the terrain's vertex normals
  12599. * viewer.scene.globe.enableLighting = true;
  12600. *
  12601. * @see TerrainProvider
  12602. */
  12603. function InfoCesiumTerrainProvider(options) {
  12604. //>>includeStart('debug', pragmas.debug)
  12605. if (!defined(options) || !defined(options.url)) {
  12606. throw new DeveloperError('options.url is required.');
  12607. }
  12608. //>>includeEnd('debug');
  12609. this.maxLevel = defaultValue(options.maxLevel, 0);
  12610. this._url = _.clone(options.url);
  12611. this.subDomains = options.subDomains;
  12612. this._proxy = options.proxy;
  12613. this._tilingScheme = new GeographicTilingScheme({
  12614. numberOfLevelZeroTilesX: 2,
  12615. numberOfLevelZeroTilesY: 1,
  12616. ellipsoid: options.ellipsoid
  12617. });
  12618. this._heightmapWidth = 65;
  12619. this._levelZeroMaximumGeometricError = TerrainProvider.getEstimatedLevelZeroGeometricErrorForAHeightmap(this._tilingScheme.ellipsoid, this._heightmapWidth, this._tilingScheme.getNumberOfXTilesAtLevel(0));
  12620. this._heightmapStructure = undefined;
  12621. this._hasWaterMask = false;
  12622. /**
  12623. * Boolean flag that indicates if the Terrain Server can provide vertex normals.
  12624. * @type {Boolean}
  12625. * @default false
  12626. * @private
  12627. */
  12628. this._hasVertexNormals = false;
  12629. /**
  12630. * Boolean flag that indicates if the client should request vertex normals from the server.
  12631. * @type {Boolean}
  12632. * @default false
  12633. * @private
  12634. */
  12635. this._requestVertexNormals = defaultValue(options.requestVertexNormals, false);
  12636. this._littleEndianExtensionSize = true;
  12637. /**
  12638. * Boolean flag that indicates if the client should request tile watermasks from the server.
  12639. * @type {Boolean}
  12640. * @default false
  12641. * @private
  12642. */
  12643. this._requestWaterMask = defaultValue(options.requestWaterMask, false);
  12644. this._errorEvent = new Event();
  12645. var credit = options.credit;
  12646. if (typeof credit === 'string') {
  12647. credit = new Credit(credit);
  12648. }
  12649. this._credit = credit;
  12650. this._ready = false;
  12651. this._readyPromise = when.defer();
  12652. var metadataUrl = this._url;
  12653. if (defined(this._proxy)) {
  12654. metadataUrl = this._proxy.getURL(metadataUrl);
  12655. }
  12656. var that = this;
  12657. var metadataError;
  12658. function metadataSuccess(data) {
  12659. var message;
  12660. if (!data.format) {
  12661. message = 'The tile format is not specified in the layer.json file.';
  12662. metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata);
  12663. return;
  12664. }
  12665. if (!data.tiles || data.tiles.length === 0) {
  12666. message = 'The layer.json file does not specify any tile URL templates.';
  12667. metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata);
  12668. return;
  12669. }
  12670. if (data.format === 'heightmap-1.0') {
  12671. that._heightmapStructure = {
  12672. heightScale: 1.0,
  12673. heightOffset: 5,
  12674. elementsPerHeight: 1,
  12675. stride: 1,
  12676. elementMultiplier: 256.0,
  12677. isBigEndian: false,
  12678. lowestEncodedHeight: 0,
  12679. highestEncodedHeight: 256 * 256 - 1
  12680. };
  12681. that._hasWaterMask = false;
  12682. that._requestWaterMask = false;
  12683. } else if (data.format.indexOf('quantized-mesh-1.') !== 0) {
  12684. message = 'The tile format "' + data.format + '" is invalid or not supported.';
  12685. metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata);
  12686. return;
  12687. }
  12688. that._tileUrlTemplates = that._url; //已更改
  12689. that._availableTiles = data.available;
  12690. if (!defined(that._credit) && defined(data.attribution) && data.attribution !== null) {
  12691. that._credit = new Credit(data.attribution);
  12692. }
  12693. // The vertex normals defined in the 'octvertexnormals' extension is identical to the original
  12694. // contents of the original 'vertexnormals' extension. 'vertexnormals' extension is now
  12695. // deprecated, as the extensionLength for this extension was incorrectly using big endian.
  12696. // We maintain backwards compatibility with the legacy 'vertexnormal' implementation
  12697. // by setting the _littleEndianExtensionSize to false. Always prefer 'octvertexnormals'
  12698. // over 'vertexnormals' if both extensions are supported by the server.
  12699. if (defined(data.extensions) && data.extensions.indexOf('octvertexnormals') !== -1) {
  12700. that._hasVertexNormals = true;
  12701. } else if (defined(data.extensions) && data.extensions.indexOf('vertexnormals') !== -1) {
  12702. that._hasVertexNormals = true;
  12703. that._littleEndianExtensionSize = false;
  12704. }
  12705. if (defined(data.extensions) && data.extensions.indexOf('watermask') !== -1) {
  12706. that._hasWaterMask = true;
  12707. }
  12708. that._ready = true;
  12709. that._readyPromise.resolve(true);
  12710. }
  12711. /****源码更改,不读配置文件,直接初始数据***/
  12712. function metadataIni() {
  12713. metadataSuccess({
  12714. tilejson: '2.1.0',
  12715. format: 'heightmap-1.0',
  12716. version: '1.0.0',
  12717. scheme: 'wtms',
  12718. tiles: [
  12719. '?'
  12720. ]
  12721. });
  12722. return;
  12723. }
  12724. /*
  12725. function metadataFailure(data) {
  12726. // If the metadata is not found, assume this is a pre-metadata heightmap tileset.
  12727. if (defined(data) && data.statusCode === 404) {
  12728. metadataSuccess({
  12729. tilejson: '2.1.0',
  12730. format: 'heightmap-1.0',
  12731. version: '1.0.0',
  12732. scheme: 'tms',
  12733. tiles: [
  12734. '{z}/{x}/{y}.terrain?v={version}'
  12735. ]
  12736. });
  12737. return;
  12738. }
  12739. var message = 'An error occurred while accessing ' + metadataUrl + '.';
  12740. metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata);
  12741. }
  12742. function requestMetadata() {
  12743. var metadata = loadJson(metadataUrl);
  12744. when(metadata, metadataSuccess, metadataFailure);
  12745. }
  12746. requestMetadata();*/
  12747. metadataIni();
  12748. }
  12749. /**
  12750. * When using the Quantized-Mesh format, a tile may be returned that includes additional extensions, such as PerVertexNormals, watermask, etc.
  12751. * This enumeration defines the unique identifiers for each type of extension data that has been appended to the standard mesh data.
  12752. *
  12753. * @exports QuantizedMeshExtensionIds
  12754. * @see CesiumTerrainProvider
  12755. * @private
  12756. */
  12757. var QuantizedMeshExtensionIds = {
  12758. /**
  12759. * Oct-Encoded Per-Vertex Normals are included as an extension to the tile mesh
  12760. *
  12761. * @type {Number}
  12762. * @constant
  12763. * @default 1
  12764. */
  12765. OCT_VERTEX_NORMALS: 1,
  12766. /**
  12767. * A watermask is included as an extension to the tile mesh
  12768. *
  12769. * @type {Number}
  12770. * @constant
  12771. * @default 2
  12772. */
  12773. WATER_MASK: 2
  12774. };
  12775. function getRequestHeader(extensionsList) {
  12776. if (!defined(extensionsList) || extensionsList.length === 0) {
  12777. return {
  12778. Accept: 'application/vnd.quantized-mesh,application/octet-stream;q=0.9,*/*;q=0.01'
  12779. };
  12780. } else {
  12781. var extensions = extensionsList.join('-');
  12782. return {
  12783. Accept: 'application/vnd.quantized-mesh;extensions=' + extensions + ',application/octet-stream;q=0.9,*/*;q=0.01'
  12784. };
  12785. }
  12786. }
  12787. function createHeightmapTerrainData(provider, buffer, level, x, y, tmsY) {
  12788. var hasChildOrNot;
  12789. if (level < provider.maxLevel) {
  12790. hasChildOrNot = new Uint8Array([15])[0];
  12791. } else {
  12792. hasChildOrNot = new Uint8Array([0])[0];
  12793. }
  12794. var yTiles1 = provider._tilingScheme.getNumberOfXTilesAtLevel(level);
  12795. // var yy1 = (yTiles1 - y - 1);
  12796. var yy1 = y;
  12797. var bley = yy1 % 2 == 0 ? true : false;
  12798. var blex = x % 2 == 0 ? true : false;
  12799. if (buffer.byteLength > 0) {
  12800. // var intBuffer0 = new Int16Array(buffer, 0, provider._heightmapWidth * provider._heightmapWidth);
  12801. var intBuffer0 = new Int16Array(129 * 129);
  12802. // var intBuffer0 = new Uint16Array(129* 129);
  12803. //数据高地位字节转换
  12804. /*
  12805. var dataview = new DataView(buffer);
  12806. for(var ii=0;ii<(129*129);){
  12807. var val1=dataview.getInt8(ii);
  12808. var val2=dataview.getInt8(ii+1);
  12809. var val3 = ((val1 & 0xFF)|((val2 & 0xFF)<<8));
  12810. ii = ii+2;
  12811. intBuffer0[ii-1] = val3
  12812. intBuffer0[ii] = val3;
  12813. }
  12814. */
  12815. var dataview = new DataView(buffer);
  12816. for (var ii = 0; ii < (129 * 129 * 2);) {
  12817. var val1 = dataview.getInt8(ii);
  12818. var val2 = dataview.getInt8(ii + 1);
  12819. var val3 = ((val1 & 0xFF) | ((val2 & 0xFF) << 8));
  12820. ii = ii + 2;
  12821. //var val4=[];
  12822. //val4[0]=val3;
  12823. //intBuffer0.set(val4,ii/2-1);
  12824. intBuffer0[ii / 2 - 1] = val3;
  12825. }
  12826. var aabdsk = intBuffer0.subarray(100, 103);
  12827. var intBuffer1;
  12828. var intBuffer = intBuffer0.subarray(0, 65 * 65);
  12829. if (bley) {
  12830. intBuffer1 = intBuffer0.subarray(0, 65 * 129);
  12831. } else {
  12832. intBuffer1 = intBuffer0.subarray(64 * 129, 129 * 129);
  12833. }
  12834. if (blex) {
  12835. for (var i = 0; i < 66; i++) {
  12836. intBuffer.set(intBuffer1.subarray(129 * i, 129 * i + 65), 65 * i);
  12837. }
  12838. } else {
  12839. for (var i = 0; i < 66; i++) {
  12840. intBuffer.set(intBuffer1.subarray(129 * i + 64, 129 * (i + 1)), 65 * i);
  12841. }
  12842. }
  12843. /*
  12844. var temp = 0; //temp用来存储当前高程区块中的最小负值
  12845. for (var i = 0; i < intBuffer.length; i++) {
  12846. if (temp > intBuffer[i]) {
  12847. temp = intBuffer[i];
  12848. }
  12849. }
  12850. var heightBuffer = new Uint16Array(intBuffer.length);
  12851. //该循环将所读取的高程数据中的所有值减去所获取到的高程最小值(该最小值为负值)
  12852. for (var i = 0; i < intBuffer.length; i++) {
  12853. heightBuffer[i] = intBuffer[i] - temp;
  12854. }
  12855. */
  12856. var heightBuffer = intBuffer;
  12857. var heightmapStructure = {
  12858. heightScale: 1,
  12859. heightOffset: 5,
  12860. elementsPerHeight: 1,
  12861. stride: 1,
  12862. elementMultiplier: 256.0,
  12863. isBigEndian: false,
  12864. lowestEncodedHeight: 0,
  12865. highestEncodedHeight: 256 * 256 - 1
  12866. };
  12867. //console.log(temp);
  12868. return new HeightmapTerrainData({
  12869. buffer: heightBuffer,
  12870. childTileMask: hasChildOrNot,
  12871. waterMask: new Uint8Array([0]),
  12872. width: provider._heightmapWidth,
  12873. height: provider._heightmapWidth,
  12874. structure: heightmapStructure
  12875. });
  12876. } else {
  12877. var heightBuffer = new Uint16Array(provider._heightmapWidth * provider._heightmapWidth);
  12878. for (var i = 0; i < heightBuffer.byteLength; i++) {
  12879. heightBuffer[i] = 0;
  12880. }
  12881. return new HeightmapTerrainData({
  12882. buffer: heightBuffer,
  12883. childTileMask: hasChildOrNot,
  12884. waterMask: new Uint8Array([0]),
  12885. width: provider._heightmapWidth,
  12886. height: provider._heightmapWidth,
  12887. structure: provider._heightmapStructure
  12888. });
  12889. }
  12890. }
  12891. function createQuantizedMeshTerrainData(provider, buffer, level, x, y, tmsY) {
  12892. var pos = 0;
  12893. var cartesian3Elements = 3;
  12894. var boundingSphereElements = cartesian3Elements + 1;
  12895. var cartesian3Length = Float64Array.BYTES_PER_ELEMENT * cartesian3Elements;
  12896. var boundingSphereLength = Float64Array.BYTES_PER_ELEMENT * boundingSphereElements;
  12897. var encodedVertexElements = 3;
  12898. var encodedVertexLength = Uint16Array.BYTES_PER_ELEMENT * encodedVertexElements;
  12899. var triangleElements = 3;
  12900. var bytesPerIndex = Uint16Array.BYTES_PER_ELEMENT;
  12901. var triangleLength = bytesPerIndex * triangleElements;
  12902. var view = new DataView(buffer);
  12903. var center = new Cartesian3(view.getFloat64(pos, true), view.getFloat64(pos + 8, true), view.getFloat64(pos + 16, true));
  12904. pos += cartesian3Length;
  12905. var minimumHeight = view.getFloat32(pos, true);
  12906. pos += Float32Array.BYTES_PER_ELEMENT;
  12907. var maximumHeight = view.getFloat32(pos, true);
  12908. pos += Float32Array.BYTES_PER_ELEMENT;
  12909. var boundingSphere = new BoundingSphere(
  12910. new Cartesian3(view.getFloat64(pos, true), view.getFloat64(pos + 8, true), view.getFloat64(pos + 16, true)),
  12911. view.getFloat64(pos + cartesian3Length, true));
  12912. pos += boundingSphereLength;
  12913. var horizonOcclusionPoint = new Cartesian3(view.getFloat64(pos, true), view.getFloat64(pos + 8, true), view.getFloat64(pos + 16, true));
  12914. pos += cartesian3Length;
  12915. var vertexCount = view.getUint32(pos, true);
  12916. pos += Uint32Array.BYTES_PER_ELEMENT;
  12917. var encodedVertexBuffer = new Uint16Array(buffer, pos, vertexCount * 3);
  12918. pos += vertexCount * encodedVertexLength;
  12919. if (vertexCount > 64 * 1024) {
  12920. // More than 64k vertices, so indices are 32-bit.
  12921. bytesPerIndex = Uint32Array.BYTES_PER_ELEMENT;
  12922. triangleLength = bytesPerIndex * triangleElements;
  12923. }
  12924. // Decode the vertex buffer.
  12925. var uBuffer = encodedVertexBuffer.subarray(0, vertexCount);
  12926. var vBuffer = encodedVertexBuffer.subarray(vertexCount, 2 * vertexCount);
  12927. var heightBuffer = encodedVertexBuffer.subarray(vertexCount * 2, 3 * vertexCount);
  12928. var i;
  12929. var u = 0;
  12930. var v = 0;
  12931. var height = 0;
  12932. function zigZagDecode(value) {
  12933. return (value >> 1) ^ (-(value & 1));
  12934. }
  12935. for (i = 0; i < vertexCount; ++i) {
  12936. u += zigZagDecode(uBuffer[i]);
  12937. v += zigZagDecode(vBuffer[i]);
  12938. height += zigZagDecode(heightBuffer[i]);
  12939. uBuffer[i] = u;
  12940. vBuffer[i] = v;
  12941. heightBuffer[i] = height;
  12942. }
  12943. // skip over any additional padding that was added for 2/4 byte alignment
  12944. if (pos % bytesPerIndex !== 0) {
  12945. pos += (bytesPerIndex - (pos % bytesPerIndex));
  12946. }
  12947. var triangleCount = view.getUint32(pos, true);
  12948. pos += Uint32Array.BYTES_PER_ELEMENT;
  12949. var indices = IndexDatatype.createTypedArrayFromArrayBuffer(vertexCount, buffer, pos, triangleCount * triangleElements);
  12950. pos += triangleCount * triangleLength;
  12951. // High water mark decoding based on decompressIndices_ in webgl-loader's loader.js.
  12952. // https://code.google.com/p/webgl-loader/source/browse/trunk/samples/loader.js?r=99#55
  12953. // Copyright 2012 Google Inc., Apache 2.0 license.
  12954. var highest = 0;
  12955. for (i = 0; i < indices.length; ++i) {
  12956. var code = indices[i];
  12957. indices[i] = highest - code;
  12958. if (code === 0) {
  12959. ++highest;
  12960. }
  12961. }
  12962. var westVertexCount = view.getUint32(pos, true);
  12963. pos += Uint32Array.BYTES_PER_ELEMENT;
  12964. var westIndices = IndexDatatype.createTypedArrayFromArrayBuffer(vertexCount, buffer, pos, westVertexCount);
  12965. pos += westVertexCount * bytesPerIndex;
  12966. var southVertexCount = view.getUint32(pos, true);
  12967. pos += Uint32Array.BYTES_PER_ELEMENT;
  12968. var southIndices = IndexDatatype.createTypedArrayFromArrayBuffer(vertexCount, buffer, pos, southVertexCount);
  12969. pos += southVertexCount * bytesPerIndex;
  12970. var eastVertexCount = view.getUint32(pos, true);
  12971. pos += Uint32Array.BYTES_PER_ELEMENT;
  12972. var eastIndices = IndexDatatype.createTypedArrayFromArrayBuffer(vertexCount, buffer, pos, eastVertexCount);
  12973. pos += eastVertexCount * bytesPerIndex;
  12974. var northVertexCount = view.getUint32(pos, true);
  12975. pos += Uint32Array.BYTES_PER_ELEMENT;
  12976. var northIndices = IndexDatatype.createTypedArrayFromArrayBuffer(vertexCount, buffer, pos, northVertexCount);
  12977. pos += northVertexCount * bytesPerIndex;
  12978. var encodedNormalBuffer;
  12979. var waterMaskBuffer;
  12980. while (pos < view.byteLength) {
  12981. var extensionId = view.getUint8(pos, true);
  12982. pos += Uint8Array.BYTES_PER_ELEMENT;
  12983. var extensionLength = view.getUint32(pos, provider._littleEndianExtensionSize);
  12984. pos += Uint32Array.BYTES_PER_ELEMENT;
  12985. if (extensionId === QuantizedMeshExtensionIds.OCT_VERTEX_NORMALS && provider._requestVertexNormals) {
  12986. encodedNormalBuffer = new Uint8Array(buffer, pos, vertexCount * 2);
  12987. } else if (extensionId === QuantizedMeshExtensionIds.WATER_MASK && provider._requestWaterMask) {
  12988. waterMaskBuffer = new Uint8Array(buffer, pos, extensionLength);
  12989. }
  12990. pos += extensionLength;
  12991. }
  12992. var skirtHeight = provider.getLevelMaximumGeometricError(level) * 5.0;
  12993. var rectangle = provider._tilingScheme.tileXYToRectangle(x, y, level);
  12994. var orientedBoundingBox;
  12995. if (rectangle.width < CesiumMath.PI_OVER_TWO + CesiumMath.EPSILON5) {
  12996. // Here, rectangle.width < pi/2, and rectangle.height < pi
  12997. // (though it would still work with rectangle.width up to pi)
  12998. // The skirt is not included in the OBB computation. If this ever
  12999. // causes any rendering artifacts (cracks), they are expected to be
  13000. // minor and in the corners of the screen. It's possible that this
  13001. // might need to be changed - just change to `minimumHeight - skirtHeight`
  13002. // A similar change might also be needed in `upsampleQuantizedTerrainMesh.js`.
  13003. orientedBoundingBox = OrientedBoundingBox.fromRectangle(rectangle, minimumHeight, maximumHeight, provider._tilingScheme.ellipsoid);
  13004. }
  13005. return new QuantizedMeshTerrainData({
  13006. center: center,
  13007. minimumHeight: minimumHeight,
  13008. maximumHeight: maximumHeight,
  13009. boundingSphere: boundingSphere,
  13010. orientedBoundingBox: orientedBoundingBox,
  13011. horizonOcclusionPoint: horizonOcclusionPoint,
  13012. quantizedVertices: encodedVertexBuffer,
  13013. encodedNormals: encodedNormalBuffer,
  13014. indices: indices,
  13015. westIndices: westIndices,
  13016. southIndices: southIndices,
  13017. eastIndices: eastIndices,
  13018. northIndices: northIndices,
  13019. westSkirtHeight: skirtHeight,
  13020. southSkirtHeight: skirtHeight,
  13021. eastSkirtHeight: skirtHeight,
  13022. northSkirtHeight: skirtHeight,
  13023. childTileMask: getChildMaskForTile(provider, level, x, tmsY),
  13024. waterMask: waterMaskBuffer
  13025. });
  13026. }
  13027. /**
  13028. * Requests the geometry for a given tile. This function should not be called before
  13029. * {@link CesiumTerrainProvider#ready} returns true. The result must include terrain data and
  13030. * may optionally include a water mask and an indication of which child tiles are available.
  13031. *
  13032. * @param {Number} x The X coordinate of the tile for which to request geometry.
  13033. * @param {Number} y The Y coordinate of the tile for which to request geometry.
  13034. * @param {Number} level The level of the tile for which to request geometry.
  13035. * @param {Boolean} [throttleRequests=true] True if the number of simultaneous requests should be limited,
  13036. * or false if the request should be initiated regardless of the number of requests
  13037. * already in progress.
  13038. * @returns {Promise.<TerrainData>|undefined} A promise for the requested geometry. If this method
  13039. * returns undefined instead of a promise, it is an indication that too many requests are already
  13040. * pending and the request will be retried later.
  13041. *
  13042. * @exception {DeveloperError} This function must not be called before {@link CesiumTerrainProvider#ready}
  13043. * returns true.
  13044. */
  13045. InfoCesiumTerrainProvider.prototype.requestTileGeometry = function (x, y, level, throttleRequests) {
  13046. //>>includeStart('debug', pragmas.debug)
  13047. if (!this._ready) {
  13048. throw new DeveloperError('requestTileGeometry must not be called before the terrain provider is ready.');
  13049. }
  13050. //>>includeEnd('debug');
  13051. var urlTemplates = _.clone(this._tileUrlTemplates);
  13052. if(this.subDomains){
  13053. var domainLength = this.subDomains.length;
  13054. var domainsIndex = Math.ceil(Math.random()*(domainLength - 1));
  13055. var domainval = this.subDomains[domainsIndex]
  13056. urlTemplates = urlTemplates.replace('{s}',domainval);
  13057. }
  13058. if (urlTemplates.length === 0) {
  13059. return undefined;
  13060. }
  13061. var yTiles = this._tilingScheme.getNumberOfYTilesAtLevel(level);
  13062. // var tmsY = (yTiles - y - 1);
  13063. var tmsY = y;
  13064. // var tmsY = y;
  13065. // var url = urlTemplates + '?l=' + level + '&x=' + x + '&y=' + tmsY + '&ticket=999999';
  13066. // console.log("--->"+y);
  13067. if (level > 1) {
  13068. //tmsY = Math.round(tmsY/2) + Math.pow(2,level-2);
  13069. tmsY = parseInt(y / 2 + yTiles / (4));
  13070. }
  13071. var tmsx = parseInt(x / 2);
  13072. //var url = urlTemplates[(x + tmsY + level) % urlTemplates.length].replace('{z}', level).replace('{x}', x).replace('{y}', x+"_"+tmsY);
  13073. var url = urlTemplates + '?l=' + level + '&x=' + tmsx + '&y=' + tmsY + '&ticket=999999';
  13074. //console.log(yTiles);
  13075. // console.log(tmsY);
  13076. // console.log(level);
  13077. // var url = urlTemplates + '?l=' + level + '&x=' + y + '&y=' + x + '&ticket=999999';
  13078. //console.log(url);
  13079. var proxy = this._proxy;
  13080. if (defined(proxy)) {
  13081. url = proxy.getURL(url);
  13082. }
  13083. var promise;
  13084. var extensionList = [];
  13085. if (this._requestVertexNormals && this._hasVertexNormals) {
  13086. extensionList.push(this._littleEndianExtensionSize ? "octvertexnormals" : "vertexnormals");
  13087. }
  13088. if (this._requestWaterMask && this._hasWaterMask) {
  13089. extensionList.push("watermask");
  13090. }
  13091. function tileLoader(tileUrl) {
  13092. return map3DViewer.DEMBil.loadArrayBuffer(tileUrl, getRequestHeader(extensionList));
  13093. }
  13094. throttleRequests = defaultValue(throttleRequests, true);
  13095. if (throttleRequests) {
  13096. promise = map3DViewer.DEMBil.throttleRequestByServer(url, tileLoader);
  13097. if (!defined(promise)) {
  13098. return undefined;
  13099. }
  13100. } else {
  13101. promise = tileLoader(url);
  13102. }
  13103. var that = this;
  13104. return when(promise, function (buffer) {
  13105. // console.log(buffer.byteLength);
  13106. if (defined(that._heightmapStructure)) {
  13107. return createHeightmapTerrainData(that, buffer, level, x, y, tmsY);
  13108. } else {
  13109. return createQuantizedMeshTerrainData(that, buffer, level, x, y, tmsY);
  13110. }
  13111. });
  13112. };
  13113. defineProperties(InfoCesiumTerrainProvider.prototype, {
  13114. /**
  13115. * Gets an event that is raised when the terrain provider encounters an asynchronous error. By subscribing
  13116. * to the event, you will be notified of the error and can potentially recover from it. Event listeners
  13117. * are passed an instance of {@link TileProviderError}.
  13118. * @memberof CesiumTerrainProvider.prototype
  13119. * @type {Event}
  13120. */
  13121. errorEvent: {
  13122. get: function () {
  13123. return this._errorEvent;
  13124. }
  13125. },
  13126. /**
  13127. * Gets the credit to display when this terrain provider is active. Typically this is used to credit
  13128. * the source of the terrain. This function should not be called before {@link CesiumTerrainProvider#ready} returns true.
  13129. * @memberof CesiumTerrainProvider.prototype
  13130. * @type {Credit}
  13131. */
  13132. credit: {
  13133. get: function () {
  13134. //>>includeStart('debug', pragmas.debug)
  13135. if (!this._ready) {
  13136. throw new DeveloperError('credit must not be called before the terrain provider is ready.');
  13137. }
  13138. //>>includeEnd('debug');
  13139. return this._credit;
  13140. }
  13141. },
  13142. /**
  13143. * Gets the tiling scheme used by this provider. This function should
  13144. * not be called before {@link CesiumTerrainProvider#ready} returns true.
  13145. * @memberof CesiumTerrainProvider.prototype
  13146. * @type {GeographicTilingScheme}
  13147. */
  13148. tilingScheme: {
  13149. get: function () {
  13150. //>>includeStart('debug', pragmas.debug)
  13151. if (!this._ready) {
  13152. throw new DeveloperError('tilingScheme must not be called before the terrain provider is ready.');
  13153. }
  13154. //>>includeEnd('debug');
  13155. return this._tilingScheme;
  13156. }
  13157. },
  13158. /**
  13159. * Gets a value indicating whether or not the provider is ready for use.
  13160. * @memberof CesiumTerrainProvider.prototype
  13161. * @type {Boolean}
  13162. */
  13163. ready: {
  13164. get: function () {
  13165. return this._ready;
  13166. }
  13167. },
  13168. /**
  13169. * Gets a promise that resolves to true when the provider is ready for use.
  13170. * @memberof CesiumTerrainProvider.prototype
  13171. * @type {Promise.<Boolean>}
  13172. * @readonly
  13173. */
  13174. readyPromise: {
  13175. get: function () {
  13176. return this._readyPromise.promise;
  13177. }
  13178. },
  13179. /**
  13180. * Gets a value indicating whether or not the provider includes a water mask. The water mask
  13181. * indicates which areas of the globe are water rather than land, so they can be rendered
  13182. * as a reflective surface with animated waves. This function should not be
  13183. * called before {@link CesiumTerrainProvider#ready} returns true.
  13184. * @memberof CesiumTerrainProvider.prototype
  13185. * @type {Boolean}
  13186. * @exception {DeveloperError} This property must not be called before {@link CesiumTerrainProvider#ready}
  13187. */
  13188. hasWaterMask: {
  13189. get: function () {
  13190. //>>includeStart('debug', pragmas.debug)
  13191. if (!this._ready) {
  13192. throw new DeveloperError('hasWaterMask must not be called before the terrain provider is ready.');
  13193. }
  13194. //>>includeEnd('debug');
  13195. return this._hasWaterMask && this._requestWaterMask;
  13196. }
  13197. },
  13198. /**
  13199. * Gets a value indicating whether or not the requested tiles include vertex normals.
  13200. * This function should not be called before {@link CesiumTerrainProvider#ready} returns true.
  13201. * @memberof CesiumTerrainProvider.prototype
  13202. * @type {Boolean}
  13203. * @exception {DeveloperError} This property must not be called before {@link CesiumTerrainProvider#ready}
  13204. */
  13205. hasVertexNormals: {
  13206. get: function () {
  13207. //>>includeStart('debug', pragmas.debug)
  13208. if (!this._ready) {
  13209. throw new DeveloperError('hasVertexNormals must not be called before the terrain provider is ready.');
  13210. }
  13211. //>>includeEnd('debug');
  13212. // returns true if we can request vertex normals from the server
  13213. return this._hasVertexNormals && this._requestVertexNormals;
  13214. }
  13215. },
  13216. /**
  13217. * Boolean flag that indicates if the client should request vertex normals from the server.
  13218. * Vertex normals data is appended to the standard tile mesh data only if the client requests the vertex normals and
  13219. * if the server provides vertex normals.
  13220. * @memberof CesiumTerrainProvider.prototype
  13221. * @type {Boolean}
  13222. */
  13223. requestVertexNormals: {
  13224. get: function () {
  13225. return this._requestVertexNormals;
  13226. }
  13227. },
  13228. /**
  13229. * Boolean flag that indicates if the client should request a watermask from the server.
  13230. * Watermask data is appended to the standard tile mesh data only if the client requests the watermask and
  13231. * if the server provides a watermask.
  13232. * @memberof CesiumTerrainProvider.prototype
  13233. * @type {Boolean}
  13234. */
  13235. requestWaterMask: {
  13236. get: function () {
  13237. return this._requestWaterMask;
  13238. }
  13239. }
  13240. });
  13241. /**
  13242. * Gets the maximum geometric error allowed in a tile at a given level.
  13243. *
  13244. * @param {Number} level The tile level for which to get the maximum geometric error.
  13245. * @returns {Number} The maximum geometric error.
  13246. */
  13247. InfoCesiumTerrainProvider.prototype.getLevelMaximumGeometricError = function (level) {
  13248. return this._levelZeroMaximumGeometricError / (1 << level);
  13249. };
  13250. function getChildMaskForTile(terrainProvider, level, x, y) {
  13251. var available = terrainProvider._availableTiles;
  13252. if (!available || available.length === 0) {
  13253. return 15;
  13254. }
  13255. var childLevel = level + 1;
  13256. if (childLevel >= available.length) {
  13257. return 0;
  13258. }
  13259. var levelAvailable = available[childLevel];
  13260. var mask = 0;
  13261. mask |= isTileInRange(levelAvailable, 2 * x, 2 * y) ? 1 : 0;
  13262. mask |= isTileInRange(levelAvailable, 2 * x + 1, 2 * y) ? 2 : 0;
  13263. mask |= isTileInRange(levelAvailable, 2 * x, 2 * y + 1) ? 4 : 0;
  13264. mask |= isTileInRange(levelAvailable, 2 * x + 1, 2 * y + 1) ? 8 : 0;
  13265. return mask;
  13266. }
  13267. function isTileInRange(levelAvailable, x, y) {
  13268. for (var i = 0, len = levelAvailable.length; i < len; ++i) {
  13269. var range = levelAvailable[i];
  13270. if (x >= range.startX && x <= range.endX && y >= range.startY && y <= range.endY) {
  13271. return true;
  13272. }
  13273. }
  13274. return false;
  13275. }
  13276. /**
  13277. * Determines whether data for a tile is available to be loaded.
  13278. *
  13279. * @param {Number} x The X coordinate of the tile for which to request geometry.
  13280. * @param {Number} y The Y coordinate of the tile for which to request geometry.
  13281. * @param {Number} level The level of the tile for which to request geometry.
  13282. * @returns {Boolean} Undefined if not supported, otherwise true or false.
  13283. */
  13284. InfoCesiumTerrainProvider.prototype.getTileDataAvailable = function (x, y, level) {
  13285. var available = this._availableTiles;
  13286. if (!available || available.length === 0) {
  13287. return undefined;
  13288. } else {
  13289. if (level >= available.length) {
  13290. return false;
  13291. }
  13292. var levelAvailable = available[level];
  13293. var yTiles = this._tilingScheme.getNumberOfYTilesAtLevel(level);
  13294. var tmsY = (yTiles - y - 1);
  13295. return isTileInRange(levelAvailable, x, tmsY);
  13296. }
  13297. };
  13298. PubSub.publishSync('map3D.DEMTileLayer.addEvent', {
  13299. name: 'InfoCesiumTerrainProvider',
  13300. func: InfoCesiumTerrainProvider
  13301. });
  13302. }(window, document));
  13303. ;
  13304. (function (window, document, undefined) {
  13305. return;
  13306. "use strict";
  13307. if (typeof (Cesium) == "undefined") {
  13308. return;
  13309. }
  13310. var Uri = Cesium.Uri;
  13311. var when = Cesium.when;
  13312. var defaultValue = Cesium.defaultValue;
  13313. var activeRequests = {};
  13314. var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri();
  13315. function getServer(url) {
  13316. var uri = new Uri(url).resolve(pageUri);
  13317. uri.normalize();
  13318. var server = uri.authority;
  13319. if (!/:/.test(server)) {
  13320. server = server + ':' + (uri.scheme === 'https' ? '443' : '80');
  13321. }
  13322. return server;
  13323. }
  13324. /**
  13325. * Because browsers throttle the number of parallel requests allowed to each server,
  13326. * this function tracks the number of active requests in progress to each server, and
  13327. * returns undefined immediately if the request would exceed the maximum, allowing
  13328. * the caller to retry later, instead of queueing indefinitely under the browser's control.
  13329. *
  13330. * @exports throttleRequestByServer
  13331. *
  13332. * @param {String} url The URL to request.
  13333. * @param {throttleRequestByServer~RequestFunction} requestFunction The actual function that
  13334. * makes the request.
  13335. * @returns {Promise.<Object>|undefined} Either undefined, meaning the request would exceed the maximum number of
  13336. * parallel requests, or a Promise for the requested data.
  13337. *
  13338. *
  13339. * @example
  13340. * // throttle requests for an image
  13341. * var url = 'http://madeupserver.example.com/myImage.png';
  13342. * function requestFunction(url) {
  13343. * // in this simple example, loadImage could be used directly as requestFunction.
  13344. * return Cesium.loadImage(url);
  13345. * };
  13346. * var promise = Cesium.throttleRequestByServer(url, requestFunction);
  13347. * if (!Cesium.defined(promise)) {
  13348. * // too many active requests in progress, try again later.
  13349. * } else {
  13350. * promise.then(function(image) {
  13351. * // handle loaded image
  13352. * });
  13353. * }
  13354. *
  13355. * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A}
  13356. */
  13357. function throttleRequestByServer(url, requestFunction) {
  13358. var server = getServer(url);
  13359. var activeRequestsForServer = defaultValue(activeRequests[server], 0);
  13360. if (activeRequestsForServer >= throttleRequestByServer.maximumRequestsPerServer) {
  13361. return undefined;
  13362. }
  13363. activeRequests[server] = activeRequestsForServer + 1;
  13364. return when(requestFunction(url), function (result) {
  13365. activeRequests[server]--;
  13366. return result;
  13367. }).otherwise(function (error) {
  13368. activeRequests[server]--;
  13369. return when.reject(error);
  13370. });
  13371. }
  13372. /**
  13373. * Specifies the maximum number of requests that can be simultaneously open to a single server. If this value is higher than
  13374. * the number of requests per server actually allowed by the web browser, Cesium's ability to prioritize requests will be adversely
  13375. * affected.
  13376. * @type {Number}
  13377. * @default 6
  13378. */
  13379. throttleRequestByServer.maximumRequestsPerServer = 6;
  13380. /**
  13381. * A function that will make a request if there are available slots to the server.
  13382. * @callback throttleRequestByServer~RequestFunction
  13383. *
  13384. * @param {String} url The url to request.
  13385. * @returns {Promise.<Object>} A promise for the requested data.
  13386. */
  13387. PubSub.publishSync('map3D.DEMTileLayer.addEvent', {
  13388. name: 'throttleRequestByServer',
  13389. func: throttleRequestByServer
  13390. });
  13391. }(window, document));
  13392. ;
  13393. (function (window, document, undefined) {
  13394. PubSub.subscribe('map3D.DEMTileLayer.loadArrayBuffer', loadArrayBuffer);
  13395. /**
  13396. * Asynchronously loads the given URL as raw binary data. Returns a promise that will resolve to
  13397. * an ArrayBuffer once loaded, or reject if the URL failed to load. The data is loaded
  13398. * using XMLHttpRequest, which means that in order to make requests to another origin,
  13399. * the server must have Cross-Origin Resource Sharing (CORS) headers enabled.
  13400. *
  13401. * @exports loadArrayBuffer
  13402. *
  13403. * @param {String|Promise.<String>} url The URL of the binary data, or a promise for the URL.
  13404. * @param {Object} [headers] HTTP headers to send with the requests.
  13405. * @returns {Promise.<ArrayBuffer>} a promise that will resolve to the requested data when loaded.
  13406. *
  13407. *
  13408. * @example
  13409. * // load a single URL asynchronously
  13410. * Cesium.loadArrayBuffer('some/url').then(function(arrayBuffer) {
  13411. * // use the data
  13412. * }).otherwise(function(error) {
  13413. * // an error occurred
  13414. * });
  13415. *
  13416. * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing}
  13417. * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A}
  13418. */
  13419. function loadArrayBuffer(url, headers) {
  13420. return map3DViewer.DEMBil.loadWithXhr({
  13421. url: url,
  13422. responseType: 'arraybuffer',
  13423. headers: headers
  13424. })
  13425. }
  13426. PubSub.publishSync('map3D.DEMTileLayer.addEvent', {
  13427. name: 'loadArrayBuffer',
  13428. func: loadArrayBuffer
  13429. });
  13430. }(window, document));
  13431. ;
  13432. (function (window, document, undefined) {
  13433. "use strict";
  13434. if (typeof (Cesium) == "undefined") {
  13435. return;
  13436. }
  13437. var when = Cesium.when;
  13438. var defaultValue = Cesium.defaultValue;
  13439. var defined = Cesium.defined;
  13440. var DeveloperError = Cesium.DeveloperError;
  13441. var RequestErrorEvent = Cesium.RequestErrorEvent;
  13442. var RuntimeError = Cesium.RuntimeError;
  13443. /**
  13444. * Asynchronously loads the given URL. Returns a promise that will resolve to
  13445. * the result once loaded, or reject if the URL failed to load. The data is loaded
  13446. * using XMLHttpRequest, which means that in order to make requests to another origin,
  13447. * the server must have Cross-Origin Resource Sharing (CORS) headers enabled.
  13448. *
  13449. * @exports loadWithXhr
  13450. *
  13451. * @param {Object} options Object with the following properties:
  13452. * @param {String|Promise.<String>} options.url The URL of the data, or a promise for the URL.
  13453. * @param {String} [options.responseType] The type of response. This controls the type of item returned.
  13454. * @param {String} [options.method='GET'] The HTTP method to use.
  13455. * @param {String} [options.data] The data to send with the request, if any.
  13456. * @param {Object} [options.headers] HTTP headers to send with the request, if any.
  13457. * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server.
  13458. * @returns {Promise.<Object>} a promise that will resolve to the requested data when loaded.
  13459. *
  13460. *
  13461. * @example
  13462. * // Load a single URL asynchronously. In real code, you should use loadBlob instead.
  13463. * Cesium.loadWithXhr({
  13464. * url : 'some/url',
  13465. * responseType : 'blob'
  13466. * }).then(function(blob) {
  13467. * // use the data
  13468. * }).otherwise(function(error) {
  13469. * // an error occurred
  13470. * });
  13471. *
  13472. * @see loadArrayBuffer
  13473. * @see loadBlob
  13474. * @see loadJson
  13475. * @see loadText
  13476. * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing}
  13477. * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A}
  13478. */
  13479. function loadWithXhr(options) {
  13480. options = defaultValue(options, defaultValue.EMPTY_OBJECT);
  13481. //>>includeStart('debug', pragmas.debug);
  13482. if (!defined(options.url)) {
  13483. throw new DeveloperError('options.url is required.');
  13484. }
  13485. //>>includeEnd('debug');
  13486. var responseType = options.responseType;
  13487. var method = defaultValue(options.method, 'GET');
  13488. var data = options.data;
  13489. var headers = options.headers;
  13490. var overrideMimeType = options.overrideMimeType;
  13491. return when(options.url, function (url) {
  13492. var deferred = when.defer();
  13493. loadWithXhr.load(url, responseType, method, data, headers, deferred, overrideMimeType);
  13494. return deferred.promise;
  13495. });
  13496. }
  13497. var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;
  13498. function decodeDataUriText(isBase64, data) {
  13499. var result = decodeURIComponent(data);
  13500. if (isBase64) {
  13501. return atob(result);
  13502. }
  13503. return result;
  13504. }
  13505. function decodeDataUriArrayBuffer(isBase64, data) {
  13506. var byteString = decodeDataUriText(isBase64, data);
  13507. var buffer = new ArrayBuffer(byteString.length);
  13508. var view = new Uint8Array(buffer);
  13509. for (var i = 0; i < byteString.length; i++) {
  13510. view[i] = byteString.charCodeAt(i);
  13511. }
  13512. return buffer;
  13513. }
  13514. function decodeDataUri(dataUriRegexResult, responseType) {
  13515. responseType = defaultValue(responseType, '');
  13516. var mimeType = dataUriRegexResult[1];
  13517. var isBase64 = !!dataUriRegexResult[2];
  13518. var data = dataUriRegexResult[3];
  13519. switch (responseType) {
  13520. case '':
  13521. case 'text':
  13522. return decodeDataUriText(isBase64, data);
  13523. case 'arraybuffer':
  13524. return decodeDataUriArrayBuffer(isBase64, data);
  13525. case 'blob':
  13526. var buffer = decodeDataUriArrayBuffer(isBase64, data);
  13527. return new Blob([buffer], {
  13528. type: mimeType
  13529. });
  13530. case 'document':
  13531. var parser = new DOMParser();
  13532. return parser.parseFromString(decodeDataUriText(isBase64, data), mimeType);
  13533. case 'json':
  13534. return JSON.parse(decodeDataUriText(isBase64, data));
  13535. default:
  13536. throw new DeveloperError('Unhandled responseType: ' + responseType);
  13537. }
  13538. }
  13539. // This is broken out into a separate function so that it can be mocked for testing purposes.
  13540. loadWithXhr.load = function (url, responseType, method, data, headers, deferred, overrideMimeType) {
  13541. var dataUriRegexResult = dataUriRegex.exec(url);
  13542. if (dataUriRegexResult !== null) {
  13543. deferred.resolve(decodeDataUri(dataUriRegexResult, responseType));
  13544. return;
  13545. }
  13546. var xhr = new XMLHttpRequest();
  13547. if (defined(overrideMimeType) && defined(xhr.overrideMimeType)) {
  13548. xhr.overrideMimeType(overrideMimeType);
  13549. }
  13550. xhr.open(method, url, true);
  13551. if (defined(headers)) {
  13552. for (var key in headers) {
  13553. if (headers.hasOwnProperty(key)) {
  13554. xhr.setRequestHeader(key, headers[key]);
  13555. }
  13556. }
  13557. }
  13558. if (defined(responseType)) {
  13559. xhr.responseType = responseType;
  13560. }
  13561. xhr.onload = function () {
  13562. if (xhr.status >= 200 && xhr.status < 300) {
  13563. if (defined(xhr.response)) {
  13564. deferred.resolve(xhr.response);
  13565. } else {
  13566. // busted old browsers.
  13567. if (defined(xhr.responseXML) && xhr.responseXML.hasChildNodes()) {
  13568. deferred.resolve(xhr.responseXML);
  13569. } else if (defined(xhr.responseText)) {
  13570. deferred.resolve(xhr.responseText);
  13571. } else {
  13572. deferred.reject(new RuntimeError('unknown XMLHttpRequest response type.'));
  13573. }
  13574. }
  13575. } else {
  13576. deferred.reject(new RequestErrorEvent(xhr.status, xhr.response, xhr.getAllResponseHeaders()));
  13577. }
  13578. };
  13579. xhr.onerror = function (e) {
  13580. deferred.reject(new RequestErrorEvent());
  13581. };
  13582. xhr.send(data);
  13583. };
  13584. loadWithXhr.defaultLoad = loadWithXhr.load;
  13585. PubSub.publishSync('map3D.DEMTileLayer.addEvent', {
  13586. name: 'loadWithXhr',
  13587. func: loadWithXhr
  13588. });
  13589. }(window, document));
  13590. ;
  13591. (function(window, document, undefined) {
  13592. PubSub.subscribe('map23D.circle.add', add2Dcircle);
  13593. PubSub.subscribe('map23D.circle.remove', remove2Dcircle);
  13594. PubSub.subscribe('map23D.circle.update', update2Dcircle);
  13595. PubSub.subscribe('map23D.circle.show', show2Dcircle);
  13596. PubSub.subscribe('map23D.circle.hide', hide2Dcircle);
  13597. PubSub.subscribe('map2D.circle.add', add2Dcircle);
  13598. PubSub.subscribe('map2D.circle.remove', remove2Dcircle);
  13599. PubSub.subscribe('map2D.circle.update', update2Dcircle);
  13600. PubSub.subscribe('map2D.circle.show', show2Dcircle);
  13601. PubSub.subscribe('map2D.circle.hide', hide2Dcircle);
  13602. function add2Dcircle(msg, guid) {
  13603. if (!map2DViewer.inited) {
  13604. return false;
  13605. }
  13606. var circleData = map23DData.circles[guid];
  13607. if (circleData.from === '3D') {
  13608. return false;
  13609. }
  13610. var circle = L.circle(
  13611. map23DUtil.latLngsToReverse(circleData.geojson.geometry.coordinates),
  13612. circleData.geojson.properties.radius,{
  13613. color: circleData.geojson.properties.color,
  13614. weight: circleData.geojson.properties.weight,
  13615. fillColor: circleData.geojson.properties.fillColor,
  13616. opacity: circleData.geojson.properties.opacity,
  13617. fillOpacity: circleData.geojson.properties.fillOpacity,
  13618. title: circleData.geojson.properties.title
  13619. }
  13620. )
  13621. circle.guid = guid;
  13622. if (circleData.geojson.properties.popupContent) {
  13623. circle.bindPopup(circleData.geojson.properties.popupContent)
  13624. }
  13625. if (circleData.groupId) {
  13626. circle.addTo(map2DViewer.groups[circleData.groupId]);
  13627. } else {
  13628. circle.addTo(map2DViewer.map);
  13629. }
  13630. map2DViewer.circles[guid] = circle;
  13631. circleData.add2D = true;
  13632. circleData.visible2D = true;
  13633. };
  13634. function show2Dcircle(msg, guid) {
  13635. if (!map2DViewer.inited) {
  13636. return false;
  13637. }
  13638. var circleData = map23DData.circles[guid];
  13639. if (circleData.from === '3D') {
  13640. return false;
  13641. }
  13642. if(circleData.visible2D){
  13643. return false;
  13644. }
  13645. if (circleData.groupId) {
  13646. map2DViewer.circles[guid].addTo(map2DViewer.groups[circleData.groupId]);
  13647. } else {
  13648. map2DViewer.circles[guid].addTo(map2DViewer.map);
  13649. }
  13650. circleData.visible2D = true;
  13651. };
  13652. function hide2Dcircle(msg, guid) {
  13653. if (!map2DViewer.inited) {
  13654. return false;
  13655. }
  13656. var circleData = map23DData.circles[guid];
  13657. if (circleData.from === '3D') {
  13658. return false;
  13659. }
  13660. if(!circleData.visible2D){
  13661. return false;
  13662. }
  13663. if (circleData.groupId) {
  13664. map2DViewer.groups[circleData.groupId].removeLayer(map2DViewer.circles[guid]);
  13665. } else {
  13666. map2DViewer.map.removeLayer(map2DViewer.circles[guid]);
  13667. }
  13668. circleData.visible2D = false;
  13669. };
  13670. function remove2Dcircle(msg, guid) {
  13671. if (!map2DViewer.inited) {
  13672. return false;
  13673. }
  13674. var circleData = map23DData.circles[guid];
  13675. if (circleData.from === '3D') {
  13676. return false;
  13677. }
  13678. if (circleData.groupId) {
  13679. map2DViewer.groups[circleData.groupId].removeLayer(map2DViewer.circles[guid]);
  13680. } else {
  13681. map2DViewer.map.removeLayer(map2DViewer.circles[guid]);
  13682. }
  13683. delete map2DViewer.circles[guid];
  13684. circleData.add2D = false;
  13685. };
  13686. function update2Dcircle(msg, guid) {
  13687. if (!map2DViewer.inited) {
  13688. return false;
  13689. }
  13690. var circleData = map23DData.circles[guid];
  13691. if (circleData.from === '3D') {
  13692. return false;
  13693. }
  13694. map2DViewer.circles[guid].setStyle(
  13695. circleData.geojson.properties
  13696. );
  13697. if (circleData.geojson.properties.popupContent) {
  13698. map2DViewer.circles[guid].bindPopup(circleData.geojson.properties.popupContent)
  13699. }
  13700. if(circleData.geojson.hasOwnProperty('geometry')){
  13701. map2DViewer.circles[guid].setLatLng(map23DUtil.latLngsToReverse(circleData.geojson.geometry.coordinates));
  13702. map2DViewer.circles[guid].setRadius(circleData.geojson.properties.radius);
  13703. }
  13704. };
  13705. }(window, document));
  13706. ;
  13707. (function(window, document, undefined) {
  13708. PubSub.subscribe('map2D.circleMarker.add', add2DcircleMarker);
  13709. PubSub.subscribe('map2D.circleMarker.remove', remove2DcircleMarker);
  13710. PubSub.subscribe('map2D.circleMarker.update', update2DcircleMarker);
  13711. PubSub.subscribe('map2D.circleMarker.show', show2DcircleMarker);
  13712. PubSub.subscribe('map2D.circleMarker.hide', hide2DcircleMarker);
  13713. function add2DcircleMarker(msg, guid) {
  13714. if (!map2DViewer.inited) {
  13715. return false;
  13716. }
  13717. var circleMarkerData = map23DData.circleMarkers[guid];
  13718. if (circleMarkerData.from === '3D') {
  13719. return false;
  13720. }
  13721. var circleMarker = L.circleMarker(
  13722. map23DUtil.latLngsToReverse(circleMarkerData.geojson.geometry.coordinates),{
  13723. radius: circleMarkerData.geojson.properties.radius,
  13724. color: circleMarkerData.geojson.properties.color,
  13725. weight: circleMarkerData.geojson.properties.weight,
  13726. fillColor: circleMarkerData.geojson.properties.fillColor,
  13727. opacity: circleMarkerData.geojson.properties.opacity,
  13728. fillOpacity: circleMarkerData.geojson.properties.fillOpacity,
  13729. title: circleMarkerData.geojson.properties.title
  13730. }
  13731. )
  13732. circleMarker.guid = guid;
  13733. if (circleMarkerData.geojson.properties.popupContent) {
  13734. circleMarker.bindPopup(circleMarkerData.geojson.properties.popupContent)
  13735. }
  13736. if (circleMarkerData.groupId) {
  13737. circleMarker.addTo(map2DViewer.groups[circleMarkerData.groupId]);
  13738. } else {
  13739. circleMarker.addTo(map2DViewer.map);
  13740. }
  13741. map2DViewer.circleMarkers[guid] = circleMarker;
  13742. circleMarkerData.add2D = true;
  13743. circleMarkerData.visible2D = true;
  13744. };
  13745. function show2DcircleMarker(msg, guid) {
  13746. if (!map2DViewer.inited) {
  13747. return false;
  13748. }
  13749. var circleMarkerData = map23DData.circleMarkers[guid];
  13750. if (circleMarkerData.from === '3D') {
  13751. return false;
  13752. }
  13753. if(circleMarkerData.visible2D){
  13754. return false;
  13755. }
  13756. if (circleMarkerData.groupId) {
  13757. map2DViewer.circleMarkers[guid].addTo(map2DViewer.groups[circleMarkerData.groupId]);
  13758. } else {
  13759. map2DViewer.circleMarkers[guid].addTo(map2DViewer.map);
  13760. }
  13761. circleMarkerData.visible2D = true;
  13762. };
  13763. function hide2DcircleMarker(msg, guid) {
  13764. if (!map2DViewer.inited) {
  13765. return false;
  13766. }
  13767. var circleMarkerData = map23DData.circleMarkers[guid];
  13768. if (circleMarkerData.from === '3D') {
  13769. return false;
  13770. }
  13771. if(!circleMarkerData.visible2D){
  13772. return false;
  13773. }
  13774. if (circleMarkerData.groupId) {
  13775. map2DViewer.groups[circleMarkerData.groupId].removeLayer(map2DViewer.circleMarkers[guid]);
  13776. } else {
  13777. map2DViewer.map.removeLayer(map2DViewer.circleMarkers[guid]);
  13778. }
  13779. circleMarkerData.visible2D = false;
  13780. };
  13781. function remove2DcircleMarker(msg, guid) {
  13782. if (!map2DViewer.inited) {
  13783. return false;
  13784. }
  13785. var circleMarkerData = map23DData.circleMarkers[guid];
  13786. if (circleMarkerData.from === '3D') {
  13787. return false;
  13788. }
  13789. if (circleMarkerData.groupId) {
  13790. map2DViewer.groups[circleMarkerData.groupId].removeLayer(map2DViewer.circleMarkers[guid]);
  13791. } else {
  13792. map2DViewer.map.removeLayer(map2DViewer.circleMarkers[guid]);
  13793. }
  13794. delete map2DViewer.circleMarkers[guid];
  13795. circleMarkerData.add2D = false;
  13796. };
  13797. function update2DcircleMarker(msg, guid) {
  13798. if (!map2DViewer.inited) {
  13799. return false;
  13800. }
  13801. var circleMarkerData = map23DData.circleMarkers[guid];
  13802. if (circleMarkerData.from === '3D') {
  13803. return false;
  13804. }
  13805. map2DViewer.circleMarkers[guid].setStyle(
  13806. circleMarkerData.geojson.properties
  13807. );
  13808. if (circleMarkerData.geojson.properties.popupContent) {
  13809. circleMarker.bindPopup(circleMarkerData.geojson.properties.popupContent)
  13810. }
  13811. if(circleMarkerData.geojson.hasOwnProperty('geometry')){
  13812. map2DViewer.circleMarkers[guid].setLatLng(map23DUtil.latLngsToReverse(circleMarkerData.geojson.geometry.coordinates));
  13813. map2DViewer.circleMarkers[guid].setRadius(circleMarkerData.geojson.properties.radius);
  13814. }
  13815. };
  13816. }(window, document));
  13817. ;
  13818. (function (window, document, undefined) {
  13819. PubSub.subscribe('map23D.circle.add', add3DCircle);
  13820. PubSub.subscribe('map23D.circle.update', update3DCircle);
  13821. PubSub.subscribe('map23D.circle.remove', remove3DCircle);
  13822. PubSub.subscribe('map23D.circle.show', show3DCircle);
  13823. PubSub.subscribe('map23D.circle.hide', hide3DCircle);
  13824. PubSub.subscribe('map3D.circle.add', add3DCircle);
  13825. PubSub.subscribe('map3D.circle.update', update3DCircle);
  13826. PubSub.subscribe('map3D.circle.remove', remove3DCircle);
  13827. PubSub.subscribe('map3D.circle.show', show3DCircle);
  13828. PubSub.subscribe('map3D.circle.hide', hide3DCircle);
  13829. function add3DCircle(msg, guid) {
  13830. if (!map3DViewer.inited) {
  13831. return false;
  13832. }
  13833. var circleData = map23DData.circles[guid];
  13834. if (circleData.from === '2D') {
  13835. return false;
  13836. }
  13837. var properties = circleData.geojson.properties;
  13838. var geometry = circleData.geojson.geometry;
  13839. if (properties.altitudeMode == 0 || !properties.altitudeMode) {
  13840. var position = Cesium.Cartesian3.fromDegrees(geometry.coordinates[0], geometry.coordinates[1]);
  13841. } else {
  13842. var position = Cesium.Cartesian3.fromDegrees(geometry.coordinates[0], geometry.coordinates[1], properties.altitude);
  13843. }
  13844. if (!properties.title) {
  13845. var name = ''
  13846. } else {
  13847. var name = properties.title.toString() || ''
  13848. }
  13849. if (!properties.height || properties.height == 0)
  13850. properties.height = 1
  13851. if (!properties.extrudedHeight || properties.extrudedHeight == 0)
  13852. properties.extrudedHeight = 0
  13853. if (properties.weight > 0 || !properties.weight.toString()) {
  13854. var outlineJudge = true;
  13855. } else {
  13856. var outlineJudge = false;
  13857. }
  13858. var ellipse = map3DViewer.map.entities.add({
  13859. id: guid,
  13860. name: name,
  13861. position: position,
  13862. ellipse: {
  13863. show: true,
  13864. semiMinorAxis: properties.radius, // 长半轴
  13865. semiMajorAxis: properties.radius, // 短半轴
  13866. height: properties.height, // 距地面高度,默认为0,贴地
  13867. extrudedHeight: properties.extrudedHeight, // 高度,默认为0
  13868. fill: true, // 是否用材质填充
  13869. material: Cesium.Color.fromCssColorString(properties.fillColor).withAlpha(properties.fillOpacity), // 填充色
  13870. outline: outlineJudge, // 外边线
  13871. outlineColor: Cesium.Color.fromCssColorString(properties.color), // 外边线颜色
  13872. outlineWidth: properties.weight //外边线宽度
  13873. }
  13874. });
  13875. delete circleData.action;
  13876. map3DViewer.circles[guid] = ellipse;
  13877. if (circleData.groupId) {
  13878. map3DViewer.groups[circleData.groupId].add(ellipse);
  13879. }
  13880. circleData.add3D = true;
  13881. circleData.visible3D = true;
  13882. };
  13883. function remove3DCircle(msg, guid) {
  13884. if (!map3DViewer.inited) {
  13885. return false;
  13886. }
  13887. var circleData = map23DData.circles[guid];
  13888. if (circleData.from === '2D') {
  13889. return false;
  13890. }
  13891. if (!map3DViewer.circles[guid]) {
  13892. return false;
  13893. }
  13894. var circle = map3DViewer.circles[guid];
  13895. map3DViewer.map.entities.remove(circle);
  13896. if (circleData.groupId) {
  13897. map3DViewer.groups[circleData.groupId].remove(circle)
  13898. }
  13899. delete map3DViewer.circles[guid];
  13900. circleData.add3D = false;
  13901. };
  13902. function update3DCircle(msg, guid) {
  13903. if (!map3DViewer.inited) {
  13904. return false;
  13905. }
  13906. var circleData = map23DData.circles[guid];
  13907. if (circleData.from === '2D') {
  13908. return false;
  13909. }
  13910. if (!map3DViewer.circles[guid]) {
  13911. return false;
  13912. }
  13913. var properties = circleData.geojson.properties;
  13914. var geometry = circleData.geojson.geometry;
  13915. if (geometry) {
  13916. var altitude = properties.altitude || circleData.geojson.properties.altitude;
  13917. if (properties.altitudeMode == 0 || !properties.altitudeMode) {
  13918. var position = Cesium.Cartesian3.fromDegrees(geometry.coordinates[0], geometry.coordinates[1]);
  13919. } else {
  13920. var position = Cesium.Cartesian3.fromDegrees(geometry.coordinates[0], geometry.coordinates[1], properties.altitude);
  13921. }
  13922. map3DViewer.circles[guid].position = position;
  13923. }
  13924. if (!properties.height || properties.height == 0)
  13925. properties.height = 0
  13926. if (!properties.extrudedHeight || properties.extrudedHeight == 0)
  13927. properties.extrudedHeight = 0
  13928. if (properties.weight > 0 || !properties.weight.toString()) {
  13929. var outlineJudge = true;
  13930. } else {
  13931. var outlineJudge = false;
  13932. }
  13933. var circle = map3DViewer.circles[guid].ellipse;
  13934. circle.semiMinorAxis = properties.radius;
  13935. circle.semiMajorAxis = properties.radius;
  13936. circle.height = properties.height;
  13937. circle.extrudedHeight = properties.extrudedHeight;
  13938. circle.material = Cesium.Color.fromCssColorString(properties.fillColor).withAlpha(properties.fillOpacity);
  13939. circle.outline = outlineJudge
  13940. circle.outlineWidth = properties.weight;
  13941. circle.outlineColor = Cesium.Color.fromCssColorString(properties.color).withAlpha(properties.opacity);
  13942. delete circleData.action;
  13943. }
  13944. function show3DCircle(msg, guid) {
  13945. if (!map3DViewer.inited) {
  13946. return false;
  13947. }
  13948. var circleData = map23DData.circles[guid];
  13949. if (circleData.from === '2D') {
  13950. return false;
  13951. }
  13952. if (circleData.visible3D) {
  13953. return false;
  13954. }
  13955. if (!map3DViewer.circles[guid]) {
  13956. return false;
  13957. }
  13958. var circle = map3DViewer.circles[guid];
  13959. circle.show = true;
  13960. if (circleData.groupId) {
  13961. map3DViewer.groups[circleData.groupId].getById(guid).show = true;
  13962. }
  13963. circleData.visible3D = true;
  13964. };
  13965. function hide3DCircle(msg, guid) {
  13966. if (!map3DViewer.inited) {
  13967. return false;
  13968. }
  13969. var circleData = map23DData.circles[guid];
  13970. if (circleData.from === '2D') {
  13971. return false;
  13972. }
  13973. if (!circleData.visible3D) {
  13974. return false;
  13975. }
  13976. if (!map3DViewer.circles[guid]) {
  13977. return false;
  13978. }
  13979. var circle = map3DViewer.circles[guid];
  13980. circle.show = false;
  13981. if (circleData.groupId) {
  13982. map3DViewer.groups[circleData.groupId].getById(guid).show = false;
  13983. }
  13984. circleData.visible3D = false;
  13985. };
  13986. }(window, document));
  13987. ;
  13988. (function (window, document, undefined) {
  13989. PubSub.subscribe('map3D.model.add', addModel);
  13990. PubSub.subscribe('map3D.model.update', updateModel);
  13991. PubSub.subscribe('map3D.model.remove', removeModel);
  13992. PubSub.subscribe('map3D.model.show', showModel);
  13993. PubSub.subscribe('map3D.model.hide', hideModel);
  13994. function addModel(msg, guid) {
  13995. if (!map3DViewer.inited) {
  13996. return false;
  13997. }
  13998. var modelData = map23DData.models[guid];
  13999. if (modelData.from === '2D') {
  14000. return false;
  14001. }
  14002. var modelGeometry = modelData.geojson.geometry;
  14003. var modelProperty = modelData.geojson.properties;
  14004. if (modelProperty.anination) {
  14005. var property = new Cesium.SampledPositionProperty();
  14006. for (var i = 0; i < modelGeometry.coordinates.length; i++) {
  14007. var item = {
  14008. longitude: JSON.parse(modelGeometry.coordinates[i][0]),
  14009. dimension: JSON.parse(modelGeometry.coordinates[i][1]),
  14010. height: modelProperty.altitude[i] || 0,
  14011. time: modelGeometry.timeLine[i] - modelGeometry.timeLine[0]
  14012. }
  14013. var start = null
  14014. if (i == 0) {
  14015. start = Cesium.JulianDate.fromDate(modelGeometry.timeLine[i])
  14016. }
  14017. var time = Cesium.JulianDate.addSeconds(start, item.time, new Cesium.JulianDate);
  14018. var position = Cesium.Cartesian3.fromDegrees(item.longitude, item.dimension, item.height);
  14019. // 添加位置,和时间对应
  14020. property.addSample(time, position);
  14021. }
  14022. var scale = modelProperty.scale || 1;
  14023. var model = map3DViewer.map.entities.add({
  14024. // 和时间轴关联
  14025. availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
  14026. start: map3DViewer.map.clock.startTime,
  14027. stop: map3DViewer.map.clock.stopTime
  14028. })]),
  14029. position: property,
  14030. // 根据所提供的速度计算点
  14031. orientation: new Cesium.VelocityOrientationProperty(property),
  14032. // 模型数据
  14033. model: {
  14034. scale: scale,
  14035. uri: modelProperty.url,
  14036. minimumPixelSize: 128
  14037. },
  14038. path: {
  14039. resolution: 1,
  14040. material: new Cesium.PolylineGlowMaterialProperty({
  14041. glowPower: 0.1,
  14042. color: Cesium.Color.fromCssColorString(modelProperty.pathColor)
  14043. }),
  14044. width: modelProperty.pathWidth
  14045. }
  14046. });
  14047. if (!modelProperty.path) {
  14048. model.path.show = false;
  14049. }
  14050. } else {
  14051. var height = modelProperty.altitude[0] || 0;
  14052. var scale = modelProperty.scale || 1;
  14053. var position = Cesium.Cartesian3.fromDegrees(modelGeometry.coordinates[0][0], modelGeometry.coordinates[0][1], height);
  14054. var model = map3DViewer.map.entities.add({
  14055. position: position,
  14056. model: {
  14057. scale: scale,
  14058. uri: modelProperty.url,
  14059. minimumPixelSize: 128
  14060. }
  14061. });
  14062. }
  14063. delete modelData.action;
  14064. map3DViewer.models[guid] = model;
  14065. if (modelData.groupId) {
  14066. map3DViewer.groups[modelData.groupId].add(model);
  14067. }
  14068. modelData.add3D = true;
  14069. modelData.visible3D = true;
  14070. };
  14071. function removeModel(msg, guid) {
  14072. if (!map3DViewer.inited) {
  14073. return false;
  14074. }
  14075. var modelData = map23DData.models[guid];
  14076. if (modelData.from === '2D') {
  14077. return false;
  14078. }
  14079. if (!map3DViewer.models[guid]) {
  14080. return false;
  14081. }
  14082. var model = map3DViewer.models[guid];
  14083. map3DViewer.map.entities.remove(model);
  14084. if (modelData.groupId) {
  14085. map3DViewer.groups[modelData.groupId].remove(model)
  14086. }
  14087. delete map3DViewer.models[guid];
  14088. modelData.add3D = false;
  14089. };
  14090. function updateModel(msg, guid) {
  14091. if (!map3DViewer.inited) {
  14092. return false;
  14093. }
  14094. var modelData = map23DData.models[guid];
  14095. if (modelData.from === '2D') {
  14096. return false;
  14097. }
  14098. if (!map3DViewer.models[guid]) {
  14099. return false;
  14100. }
  14101. var model = map3DViewer.models[guid];
  14102. }
  14103. function showModel(msg, guid) {
  14104. if (!map3DViewer.inited) {
  14105. return false;
  14106. }
  14107. var modelData = map23DData.models[guid];
  14108. if (modelData.from === '2D') {
  14109. return false;
  14110. }
  14111. if (!map3DViewer.models[guid]) {
  14112. return false;
  14113. }
  14114. var model = map3DViewer.models[guid];
  14115. model.show = true;
  14116. if (modelData.groupId) {
  14117. map3DViewer.groups[modelData.groupId].getById(guid).show = true
  14118. }
  14119. modelData.visible3D = true;
  14120. }
  14121. function hideModel(msg, guid) {
  14122. if (!map3DViewer.inited) {
  14123. return false;
  14124. }
  14125. var modelData = map23DData.models[guid];
  14126. if (modelData.from === '2D') {
  14127. return false;
  14128. }
  14129. if (!map3DViewer.models[guid]) {
  14130. return false;
  14131. }
  14132. var model = map3DViewer.models[guid];
  14133. model.show = false;
  14134. if (modelData.groupId) {
  14135. map3DViewer.groups[modelData.groupId].getById(guid).show = false
  14136. }
  14137. modelData.visible3D = false;
  14138. }
  14139. }(window, document));
  14140. ;
  14141. (function (window, document, undefined) {
  14142. PubSub.subscribe('map3D.measureArea.add', init);
  14143. PubSub.subscribe('map3D.measureArea.remove', removeMeasureArea);
  14144. PubSub.subscribe('map3D.measureArea.clear', clearMeasureArea);
  14145. var modValue = {
  14146. handler: null,
  14147. tempPoints: [],
  14148. viewer: null,
  14149. tempEntities: {},
  14150. areaIndex: 0,
  14151. area: null,
  14152. polygon: {},
  14153. afterMeasureJudgeContinue: false,
  14154. tips: $('<div class="measureArea_tips map3D">左键添加点,右键结束</div>')
  14155. }
  14156. function init(msg, options) {
  14157. if (options.action == 'add') {
  14158. modValue.viewer = options.viewer;
  14159. modValue.afterMeasureJudgeContinue = options.afterMeasureJudgeContinue || false
  14160. addMeasureArea();
  14161. modValue.tips.appendTo(modValue.viewer._container);
  14162. } else if (options.action == 'remove') {
  14163. removeMeasureArea();
  14164. }
  14165. };
  14166. function addMeasureArea() {
  14167. if (!modValue.handler) {
  14168. modValue.tempPoints = [];
  14169. modValue.areaIndex++;
  14170. modValue.tempEntities[modValue.areaIndex] = [];
  14171. modValue.handler = new Cesium.ScreenSpaceEventHandler(modValue.viewer.scene.canvas);
  14172. modValue.handler.setInputAction(function (event) {
  14173. var wp = event.endPosition;
  14174. if (!Cesium.defined(wp)) {
  14175. return;
  14176. }
  14177. var ray = modValue.viewer.camera.getPickRay(wp);
  14178. if (!Cesium.defined(ray)) {
  14179. return;
  14180. }
  14181. var cartesian = modValue.viewer.scene.globe.pick(ray, modValue.viewer.scene);
  14182. if (!Cesium.defined(cartesian)) {
  14183. return;
  14184. }
  14185. $('#' + modValue.viewer._container.id + ' .measureArea_tips').css({
  14186. "left": wp.x + 20,
  14187. 'top': wp.y + 10
  14188. })
  14189. }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  14190. modValue.handler.setInputAction(function (click) {
  14191. var latlng = screenToLatLng(click.position.x, click.position.y)
  14192. if (latlng) {
  14193. modValue.tempPoints.push({
  14194. lon: latlng.lng,
  14195. lat: latlng.lat,
  14196. alt: latlng.alt
  14197. });
  14198. var tempLength = modValue.tempPoints.length;
  14199. drawPoint(modValue.tempPoints[modValue.tempPoints.length - 1]);
  14200. if (tempLength > 2) {
  14201. drawPoly(modValue.tempPoints);
  14202. }
  14203. }
  14204. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  14205. modValue.handler.setInputAction(function (click) {
  14206. var cartesian = modValue.viewer.camera.pickEllipsoid(click.position, modValue.viewer.scene.globe.ellipsoid);
  14207. if (cartesian) {
  14208. var tempLength = modValue.tempPoints.length;
  14209. if (tempLength < 3) {
  14210. alert('请选择3个以上的点再执行闭合操作命令');
  14211. } else {
  14212. drawPoly(modValue.tempPoints);
  14213. // highLightAssetsInArea(_this.modValue.tempPoints)
  14214. var ent =
  14215. modValue.viewer.entities.add({
  14216. position: Cesium.Cartesian3.fromDegrees(modValue.tempPoints[modValue.tempPoints.length - 1].lon, modValue.tempPoints[modValue.tempPoints.length - 1].lat),
  14217. label: {
  14218. text: SphericalPolygonAreaMeters(modValue.tempPoints),
  14219. font: '22px Helvetica',
  14220. heightReference: 2,
  14221. pixelOffset: new Cesium.Cartesian2(0, -22),
  14222. fillColor: Cesium.Color.WHITE,
  14223. verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
  14224. }
  14225. });
  14226. modValue.tempEntities[modValue.areaIndex].push(ent);
  14227. modValue.tempPoints = [];
  14228. removeMeasureArea('', modValue.afterMeasureJudgeContinue);
  14229. }
  14230. }
  14231. }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  14232. }
  14233. }
  14234. function removeMeasureArea(msg, callback) {
  14235. if (!modValue.viewer) {
  14236. return;
  14237. }
  14238. $('#' + modValue.viewer._container.id + ' .measureArea_tips').remove();
  14239. if (modValue.handler) {
  14240. modValue.tempPoints = [];
  14241. modValue.handler.destroy();
  14242. modValue.handler = null;
  14243. }
  14244. if (callback) {
  14245. init('', {
  14246. action: 'add',
  14247. viewer: modValue.viewer
  14248. })
  14249. }
  14250. }
  14251. function drawPoint(point) {
  14252. var entity =
  14253. modValue.viewer.entities.add({
  14254. position: Cesium.Cartesian3.fromDegrees(point.lon, point.lat),
  14255. point: {
  14256. pixelSize: 10,
  14257. heightReference: 2,
  14258. color: Cesium.Color.RED,
  14259. }
  14260. });
  14261. modValue.tempEntities[modValue.areaIndex].push(entity);
  14262. }
  14263. function drawPoly(points) {
  14264. var pArray = [];
  14265. for (var i = 0; i <= points.length; i++) {
  14266. if (i < points.length) {
  14267. pArray.push(points[i].lon);
  14268. pArray.push(points[i].lat);
  14269. pArray.push(points[i].alt);
  14270. }
  14271. }
  14272. if (modValue.polygon[modValue.areaIndex]) {
  14273. modValue.polygon[modValue.areaIndex].polygon.hierarchy.setValue(new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(pArray)));
  14274. } else {
  14275. modValue.polygon[modValue.areaIndex] = modValue.viewer.entities.add({
  14276. polygon: {
  14277. hierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(pArray)),
  14278. heightReference: 0,
  14279. //height : 5,
  14280. material: Cesium.Color.CHARTREUSE.withAlpha(0.5),
  14281. outline: true,
  14282. outlineColor: Cesium.Color.YELLOW,
  14283. outlineWidth: 2
  14284. }
  14285. });
  14286. modValue.tempEntities[modValue.areaIndex].push(modValue.polygon[modValue.areaIndex]);
  14287. }
  14288. }
  14289. function SphericalPolygonAreaMeters(points) {
  14290. var latLngs = points;
  14291. var pointsCount = latLngs.length,
  14292. area = 0.0,
  14293. d2r = Math.PI / 180,
  14294. p1, p2;
  14295. if (pointsCount > 2) {
  14296. for (var i = 0; i < pointsCount; i++) {
  14297. p1 = latLngs[i];
  14298. p2 = latLngs[(i + 1) % pointsCount];
  14299. area += ((p2.lon - p1.lon) * d2r) *
  14300. (2 + Math.sin(p1.lat * d2r) + Math.sin(p2.lat * d2r));
  14301. }
  14302. area = area * 6378137.0 * 6378137.0 / 2.0;
  14303. }
  14304. area = Math.abs(area);
  14305. if (area > 1000000) {
  14306. area = (area * 0.000001).toFixed(2) + ' 平方公里';
  14307. } else {
  14308. area = area.toFixed(2) + '平方米';
  14309. }
  14310. return area;
  14311. }
  14312. function screenToLatLng(x, y) {
  14313. var pick1 = new Cesium.Cartesian2(x, y);
  14314. var cartesian = modValue.viewer.scene.globe.pick(modValue.viewer.camera.getPickRay(pick1), modValue.viewer.scene);
  14315. if (cartesian) {
  14316. var cartographic = modValue.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
  14317. var lat = Cesium.Math.toDegrees(cartographic.latitude);
  14318. var lng = Cesium.Math.toDegrees(cartographic.longitude);
  14319. var alt = cartographic.height;
  14320. var position = {
  14321. lat: lat,
  14322. lng: lng,
  14323. alt: alt
  14324. }
  14325. } else {
  14326. var position = false
  14327. }
  14328. return position;
  14329. }
  14330. function clearMeasureArea(msg, options) {
  14331. $.each(modValue.tempEntities, function (i, t) {
  14332. for (var j = 0; j < t.length; j++) {
  14333. modValue.viewer.entities.removeById(t[j]._id);
  14334. }
  14335. })
  14336. }
  14337. }(window, document));
  14338. ;
  14339. (function (window, document, undefined) {
  14340. PubSub.subscribe('map3D.measureDistance.add', init);
  14341. PubSub.subscribe('map3D.measureDistance.remove', removeMeasureDistance);
  14342. PubSub.subscribe('map3D.measureDistance.clear', clearMeasureDistance);
  14343. var modValue = {
  14344. handler: null,
  14345. tempPoints: [],
  14346. viewer: null,
  14347. tempEntities: {},
  14348. distanceIndex: 0,
  14349. distance: null,
  14350. afterMeasureJudgeContinue: false,
  14351. tips: $('<div class="measureDistance_tips map3D">左键添加点,右键结束</div>')
  14352. }
  14353. function init(msg, options) {
  14354. if (options.action == 'add') {
  14355. modValue.viewer = options.viewer;
  14356. modValue.afterMeasureJudgeContinue = options.afterMeasureJudgeContinue || false
  14357. addMeasureDistance();
  14358. modValue.tips.appendTo(modValue.viewer._container);
  14359. } else if (options.action == 'remove') {
  14360. removeMeasureDistance();
  14361. }
  14362. };
  14363. function addMeasureDistance() {
  14364. if (!modValue.handler) {
  14365. modValue.distanceIndex++;
  14366. modValue.distance = null;
  14367. modValue.tempEntities[modValue.distanceIndex] = [];
  14368. modValue.handler = new Cesium.ScreenSpaceEventHandler(modValue.viewer.scene.canvas);
  14369. modValue.handler.setInputAction(function (event) {
  14370. var wp = event.endPosition;
  14371. if (!Cesium.defined(wp)) {
  14372. return;
  14373. }
  14374. var ray = modValue.viewer.camera.getPickRay(wp);
  14375. if (!Cesium.defined(ray)) {
  14376. return;
  14377. }
  14378. var cartesian = modValue.viewer.scene.globe.pick(ray, modValue.viewer.scene);
  14379. if (!Cesium.defined(cartesian)) {
  14380. return;
  14381. }
  14382. $('#' + modValue.viewer._container.id + ' .measureDistance_tips').css({
  14383. "left": wp.x + 20,
  14384. 'top': wp.y + 10
  14385. })
  14386. }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  14387. modValue.handler.setInputAction(function (click) {
  14388. var latlng = screenToLatLng(click.position.x, click.position.y)
  14389. if (latlng) {
  14390. modValue.tempPoints.push({
  14391. lon: latlng.lng,
  14392. lat: latlng.lat
  14393. });
  14394. var tempLength = modValue.tempPoints.length;
  14395. drawPoint(modValue.tempPoints[modValue.tempPoints.length - 1]);
  14396. if (tempLength > 1) {
  14397. drawLine(modValue.tempPoints[modValue.tempPoints.length - 2], modValue.tempPoints[modValue.tempPoints.length - 1], true);
  14398. }
  14399. }
  14400. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  14401. modValue.handler.setInputAction(function (click) {
  14402. removeMeasureDistance('', modValue.afterMeasureJudgeContinue);
  14403. }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  14404. }
  14405. }
  14406. function removeMeasureDistance(msg, callback) {
  14407. if (!modValue.viewer) {
  14408. return;
  14409. }
  14410. $('#' + modValue.viewer._container.id + ' .measureDistance_tips').remove();
  14411. if (modValue.handler) {
  14412. modValue.tempPoints = [];
  14413. modValue.handler.destroy();
  14414. modValue.handler = null;
  14415. }
  14416. if (callback) {
  14417. init('', {
  14418. action: 'add',
  14419. viewer: modValue.viewer
  14420. })
  14421. }
  14422. }
  14423. function drawLine(point1, point2, showDistance) {
  14424. var entity =
  14425. modValue.viewer.entities.add({
  14426. polyline: {
  14427. positions: [Cesium.Cartesian3.fromDegrees(point1.lon, point1.lat), Cesium.Cartesian3.fromDegrees(point2.lon, point2.lat)],
  14428. width: 10.0,
  14429. material: new Cesium.PolylineGlowMaterialProperty({
  14430. color: Cesium.Color.CHARTREUSE.withAlpha(.5)
  14431. }),
  14432. clampToGround: true
  14433. }
  14434. });
  14435. modValue.tempEntities[modValue.distanceIndex].push(entity);
  14436. if (showDistance) {
  14437. var curdistance = getFlatternDistance(point1.lat, point1.lon, point2.lat, point2.lon);
  14438. if (modValue.distance) {
  14439. modValue.distance = modValue.distance + curdistance
  14440. } else {
  14441. modValue.distance = curdistance;
  14442. }
  14443. if (modValue.distance <= 1000) {
  14444. var showDistance = modValue.distance.toFixed(1) + 'm';
  14445. } else {
  14446. var showDistance = (modValue.distance / 1000).toFixed(3) + 'km';
  14447. }
  14448. entity =
  14449. modValue.viewer.entities.add({
  14450. position: Cesium.Cartesian3.fromDegrees(point2.lon, point2.lat),
  14451. label: {
  14452. text: showDistance,
  14453. heightReference: 2,
  14454. font: '22px Helvetica',
  14455. fillColor: Cesium.Color.WHITE,
  14456. pixelOffset: new Cesium.Cartesian2(0, -22),
  14457. verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
  14458. }
  14459. });
  14460. modValue.tempEntities[modValue.distanceIndex].push(entity);
  14461. }
  14462. }
  14463. function drawPoint(point) {
  14464. var entity =
  14465. modValue.viewer.entities.add({
  14466. position: Cesium.Cartesian3.fromDegrees(point.lon, point.lat),
  14467. point: {
  14468. pixelSize: 10,
  14469. heightReference: 2,
  14470. color: Cesium.Color.RED,
  14471. }
  14472. });
  14473. modValue.tempEntities[modValue.distanceIndex].push(entity);
  14474. }
  14475. function getFlatternDistance(lat1, lng1, lat2, lng2) {
  14476. var EARTH_RADIUS = 6378137.0; //单位M
  14477. var PI = Math.PI;
  14478. function getRad(d) {
  14479. return d * PI / 180.0;
  14480. }
  14481. var f = getRad((lat1 + lat2) / 2);
  14482. var g = getRad((lat1 - lat2) / 2);
  14483. var l = getRad((lng1 - lng2) / 2);
  14484. var sg = Math.sin(g);
  14485. var sl = Math.sin(l);
  14486. var sf = Math.sin(f);
  14487. var s, c, w, r, d, h1, h2;
  14488. var a = EARTH_RADIUS;
  14489. var fl = 1 / 298.257;
  14490. sg = sg * sg;
  14491. sl = sl * sl;
  14492. sf = sf * sf;
  14493. s = sg * (1 - sl) + (1 - sf) * sl;
  14494. c = (1 - sg) * (1 - sl) + sf * sl;
  14495. w = Math.atan(Math.sqrt(s / c));
  14496. r = Math.sqrt(s * c) / w;
  14497. d = 2 * w * a;
  14498. h1 = (3 * r - 1) / 2 / c;
  14499. h2 = (3 * r + 1) / 2 / s;
  14500. return d * (1 + fl * (h1 * sf * (1 - sg) - h2 * (1 - sf) * sg));
  14501. }
  14502. function screenToLatLng(x, y) {
  14503. var pick1 = new Cesium.Cartesian2(x, y);
  14504. var cartesian = modValue.viewer.scene.globe.pick(modValue.viewer.camera.getPickRay(pick1), modValue.viewer.scene);
  14505. if (cartesian) {
  14506. var cartographic = modValue.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
  14507. var lat = Cesium.Math.toDegrees(cartographic.latitude);
  14508. var lng = Cesium.Math.toDegrees(cartographic.longitude);
  14509. var alt = cartographic.height;
  14510. var position = {
  14511. lat: lat,
  14512. lng: lng,
  14513. alt: alt
  14514. }
  14515. } else {
  14516. var position = false
  14517. }
  14518. return position;
  14519. }
  14520. function clearMeasureDistance(msg, options) {
  14521. $.each(modValue.tempEntities, function (i, t) {
  14522. for (var j = 0; j < t.length; j++) {
  14523. modValue.viewer.entities.removeById(t[j]._id);
  14524. }
  14525. })
  14526. }
  14527. }(window, document));
  14528. ;
  14529. (function (window, document, undefined) {
  14530. map3DViewer.measureHeight = function (options) {
  14531. var defaultData = {
  14532. action: options.action,
  14533. viewer: map3DViewer.map,
  14534. }
  14535. defaultData = Object.assign({}, defaultData, options)
  14536. switch (defaultData.action) {
  14537. case 'add':
  14538. if (!this.distanceTool) {
  14539. this.distanceTool = new measure3DHeight(defaultData)
  14540. }
  14541. this.distanceTool.start();
  14542. return this.distanceTool;
  14543. break;
  14544. case 'remove':
  14545. if (!this.distanceTool)
  14546. break;
  14547. this.distanceTool.remove();
  14548. break;
  14549. case 'clear':
  14550. if (!this.distanceTool)
  14551. break;
  14552. this.distanceTool.clear();
  14553. break;
  14554. case 'stop':
  14555. if (!this.distanceTool)
  14556. break;
  14557. this.distanceTool.stop();
  14558. break;
  14559. case 'restart':
  14560. if (!this.distanceTool)
  14561. break;
  14562. this.distanceTool.remove();
  14563. this.distanceTool.start();
  14564. }
  14565. }
  14566. function measure3DHeight(options) {
  14567. this.init.apply(this, arguments);
  14568. }
  14569. measure3DHeight.prototype = {
  14570. init: function (options) {
  14571. this.measure_entities = new Cesium.Entity({
  14572. id: 'name_tile',
  14573. show: true
  14574. })
  14575. this.viewer = options.viewer;
  14576. this.handler = null;
  14577. this.finished = true;
  14578. this.removed = false;
  14579. this.index = 0;
  14580. this.tempEntities = {};
  14581. this.popupArr = {};
  14582. this.afterMeasureJudgeContinue = (typeof options.afterMeasureJudgeContinue == "boolean") ? options.afterMeasureJudgeContinue : false;
  14583. this.buttonClass = "measureTips measureHeight"
  14584. },
  14585. start: function () {
  14586. var that = this;
  14587. this.depthTestAgainstTerrain = null;
  14588. this.depthTestAgainstTerrain = this.viewer.scene.globe.depthTestAgainstTerrain
  14589. this.viewer.scene.globe.depthTestAgainstTerrain = true;
  14590. if (!this.handler) {
  14591. this.index++;
  14592. this.tempEntities[this.index] = {
  14593. zhixian: null,
  14594. gengxin: null,
  14595. floatingPoint_g: null,
  14596. };
  14597. this.popupArr[this.index] = {}
  14598. this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
  14599. var positions = [];
  14600. var height = 0;
  14601. var cartesian = null;
  14602. this.handler.setInputAction(function (movement) {
  14603. that.finished = false
  14604. cartesian = that.viewer.scene.pickPosition(movement.position);
  14605. if (positions.length == 0) {
  14606. positions.push(cartesian.clone());
  14607. that.tempEntities[that.index].floatingPoint_g = that.viewer.entities.add({
  14608. parent: that.measure_entities,
  14609. name: '高度',
  14610. position: positions[0],
  14611. point: {
  14612. pixelSize: 5,
  14613. color: Cesium.Color.RED,
  14614. outlineColor: Cesium.Color.WHITE,
  14615. outlineWidth: 2,
  14616. heightReference: Cesium.HeightReference.none
  14617. }
  14618. });
  14619. that.stopCamereChange();
  14620. } else {
  14621. positions.push(cartesian);
  14622. height = that.getHeight(positions);
  14623. that.buildPolylineAndPoint(positions, height);
  14624. }
  14625. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  14626. }
  14627. },
  14628. stopCamereChange: function () {
  14629. this.viewer.scene.screenSpaceCameraController.enableTilt = false;
  14630. this.viewer.scene.screenSpaceCameraController.enableRotate = false;
  14631. this.viewer.scene.screenSpaceCameraController.enableZoom = false;
  14632. },
  14633. startCamereChange: function () {
  14634. this.viewer.scene.screenSpaceCameraController.enableTilt = true;
  14635. this.viewer.scene.screenSpaceCameraController.enableRotate = true;
  14636. this.viewer.scene.screenSpaceCameraController.enableZoom = true;
  14637. },
  14638. getHeight: function (position) {
  14639. var cartographic = Cesium.Cartographic.fromCartesian(position[0]);
  14640. var cartographic1 = Cesium.Cartographic.fromCartesian(position[1]);
  14641. var height_temp = cartographic1.height - cartographic.height;
  14642. return height_temp.toFixed(2);
  14643. },
  14644. buildPolylineAndPoint: function (positions, height) {
  14645. var that = this;
  14646. var endPoint = positions[1].clone();
  14647. if (height < 0) {
  14648. height = -1 * height;
  14649. var mid = positions[0];
  14650. positions[0] = positions[1];
  14651. positions[1] = mid;
  14652. }
  14653. var textDisance = height + "米";
  14654. var point1cartographic = Cesium.Cartographic.fromCartesian(positions[0]);
  14655. var point2cartographic = Cesium.Cartographic.fromCartesian(positions[1]);
  14656. var point_temp = Cesium.Cartesian3.fromDegrees(Cesium.Math.toDegrees(point1cartographic.longitude), Cesium.Math.toDegrees(point1cartographic.latitude), point2cartographic.height);
  14657. var temp_position = [];
  14658. temp_position.push(positions[0]);
  14659. temp_position.push(point_temp);
  14660. //添加高程点和label信息
  14661. this.tempEntities[this.index].zhixian = this.viewer.entities.add({
  14662. parent: this.measure_entities,
  14663. name: '直线距离',
  14664. position: point_temp,
  14665. point: {
  14666. pixelSize: 5,
  14667. color: Cesium.Color.RED,
  14668. outlineColor: Cesium.Color.WHITE,
  14669. outlineWidth: 2,
  14670. heightReference: Cesium.HeightReference.none
  14671. },
  14672. label: {
  14673. text: textDisance,
  14674. font: '18px sans-serif',
  14675. fillColor: Cesium.Color.GOLD,
  14676. style: Cesium.LabelStyle.FILL_AND_OUTLINE,
  14677. outlineWidth: 2,
  14678. verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
  14679. pixelOffset: new Cesium.Cartesian2(20, -20)
  14680. },
  14681. polyline: {
  14682. show: true,
  14683. positions: temp_position,
  14684. material: Cesium.Color.AQUA,
  14685. width: 2
  14686. }
  14687. });
  14688. //添加圆和高程线
  14689. this.tempEntities[this.index].gengxin = this.viewer.entities.add({
  14690. parent: this.measure_entities,
  14691. name: '直线距离',
  14692. position: endPoint,
  14693. point: {
  14694. pixelSize: 5,
  14695. color: Cesium.Color.RED,
  14696. outlineColor: Cesium.Color.WHITE,
  14697. outlineWidth: 2,
  14698. heightReference: Cesium.HeightReference.none
  14699. },
  14700. polyline: {
  14701. show: true,
  14702. positions: [point_temp, positions[1]],
  14703. material: Cesium.Color.AQUA,
  14704. width: 2
  14705. }
  14706. })
  14707. var divEle = that.createdDiv("删除", {
  14708. params: {
  14709. index: this.index
  14710. },
  14711. onclick: function () {
  14712. var params = JSON.parse(this.getAttribute("params"))
  14713. that.del(params.index)
  14714. }
  14715. })
  14716. // that.popupArr[that.index] = map3DViewer.setPopup({
  14717. // viewer: that.viewer,
  14718. // cartesian: positions[1],
  14719. // show: true,
  14720. // offset: [10, -14.5],
  14721. // html: divEle
  14722. // })
  14723. this.finished = true;
  14724. this.detach(this.afterMeasureJudgeContinue)
  14725. this.startCamereChange()
  14726. },
  14727. createdDiv: function (text, eventObj) {
  14728. //创建一个div
  14729. var div = document.createElement("div");
  14730. //为div创建属性class = "test"
  14731. var divattr = document.createAttribute("class");
  14732. divattr.value = this.buttonClass;
  14733. div.setAttributeNode(divattr);
  14734. var divParams = document.createAttribute("params");
  14735. divParams.value = JSON.stringify(eventObj.params)
  14736. div.setAttributeNode(divParams);
  14737. //为div添加样式
  14738. var style = document.createAttribute("style");
  14739. div.setAttributeNode(style);
  14740. div.style.backgroundColor = "#ffffff";
  14741. div.style.cursor = "pointer";
  14742. //创建一hello,world个文本节点
  14743. var text = document.createTextNode(text);
  14744. div.appendChild(text);
  14745. div.onclick = eventObj.onclick;
  14746. return div;
  14747. },
  14748. remove: function () {
  14749. this.stop();
  14750. this.clear();
  14751. },
  14752. stop: function () {
  14753. this.removed = true
  14754. if (!this.finished) {
  14755. this.del(this.index)
  14756. this.finished = true;
  14757. }
  14758. this.detach();
  14759. this.startCamereChange()
  14760. },
  14761. detach: function (judge) {
  14762. if (this.handler) {
  14763. this.handler.destroy();
  14764. this.handler = null;
  14765. }
  14766. this.viewer.scene.globe.depthTestAgainstTerrain = this.depthTestAgainstTerrain
  14767. if (judge) {
  14768. this.start()
  14769. }
  14770. },
  14771. clear: function () {
  14772. var items = this.tempEntities
  14773. for (var key1 in items) {
  14774. if (items.hasOwnProperty(key1)) {
  14775. if (items[key1].zhixian)
  14776. this.viewer.entities.remove(items[key1].zhixian);
  14777. if (items[key1].gengxin)
  14778. this.viewer.entities.remove(items[key1].gengxin);
  14779. if (items[key1].floatingPoint_g)
  14780. this.viewer.entities.remove(items[key1].floatingPoint_g);
  14781. }
  14782. }
  14783. this.tempEntities = {}
  14784. var items_popup = this.popupArr
  14785. for (var key2 in items_popup) {
  14786. if (items_popup.hasOwnProperty(key2)) {
  14787. if (Object.getOwnPropertyNames(items_popup[key2]).length != 0) {
  14788. items_popup[key2].close();
  14789. }
  14790. }
  14791. }
  14792. this.popupArr = {}
  14793. },
  14794. del: function (index) {
  14795. var item = this.tempEntities[index]
  14796. if (item.zhixian)
  14797. this.viewer.entities.remove(item.zhixian);
  14798. if (item.gengxin)
  14799. this.viewer.entities.remove(item.gengxin);
  14800. if (item.floatingPoint_g)
  14801. this.viewer.entities.remove(item.floatingPoint_g);
  14802. item.zhixian = null
  14803. item.gengxin = null
  14804. item.floatingPoint_g = null
  14805. if (Object.getOwnPropertyNames(this.popupArr).length > 0) {
  14806. var popup = this.popupArr[index]
  14807. if (Object.getOwnPropertyNames(popup).length != 0) {
  14808. popup.close();
  14809. delete popup
  14810. }
  14811. }
  14812. delete item
  14813. },
  14814. }
  14815. }(window, document));
  14816. function drawPoint_Ceisum() {
  14817. this.init.apply(this, arguments)
  14818. }
  14819. drawPoint_Ceisum.prototype = {
  14820. viewer: null,
  14821. handler: null,
  14822. callback: null,
  14823. init: function (params) {
  14824. this.viewer = params.viewer;
  14825. this.callback = params.callback;
  14826. },
  14827. start: function () {
  14828. var _this = this;
  14829. if (!this.handler)
  14830. this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
  14831. this.handler.setInputAction(function (click) {
  14832. var pick1 = new Cesium.Cartesian2(click.position.x, click.position.y);
  14833. var cartesian = _this.viewer.scene.globe.pick(_this.viewer.camera.getPickRay(pick1), _this.viewer.scene);
  14834. if (cartesian) {
  14835. var cartographic = _this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
  14836. var lat = Cesium.Math.toDegrees(cartographic.latitude);
  14837. var lng = Cesium.Math.toDegrees(cartographic.longitude);
  14838. var alt = cartographic.height;
  14839. if (_this.callback) _this.callback({
  14840. lon: lng,
  14841. lat: lat
  14842. });
  14843. }
  14844. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  14845. },
  14846. stop: function () {
  14847. if (this.handler)
  14848. this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
  14849. this.handler = null
  14850. },
  14851. }
  14852. map3DViewer.setDrawPoint = function (options) {
  14853. return (function () {
  14854. var defaultData = {
  14855. action: 'add',
  14856. viewer: null,
  14857. callback: null,
  14858. }
  14859. defaultData = Object.assign({}, defaultData, options)
  14860. switch (defaultData.action) {
  14861. case 'add':
  14862. this.drawPoint = new drawPoint_Ceisum(defaultData)
  14863. this.drawPoint.start();
  14864. return this;
  14865. break;
  14866. case 'remove':
  14867. this.drawPoint.stop();
  14868. delete this.drawPoint
  14869. break;
  14870. }
  14871. })()
  14872. }
  14873. function drawPolyline_Ceisum() {
  14874. this.init.apply(this, arguments)
  14875. }
  14876. drawPolyline_Ceisum.prototype = {
  14877. viewer: null,
  14878. handler: null,
  14879. callback: null,
  14880. tempPoints: [],
  14881. tempEntitiesPoints: [],
  14882. tempEntitiesLines: [],
  14883. completeBotton: '<div class="ZH" style="padding: 5px;border-radius: 5px;background: #fff;cursor:pointer;" onclick="map3DViewer.setDrawPolyline({action:\'finish\'})">完成</div>',
  14884. init: function (params) {
  14885. this.viewer = params.viewer;
  14886. this.callback = params.callback;
  14887. this.completeBotton = params.completeBotton || this.completeBotton;
  14888. },
  14889. start: function () {
  14890. var _this = this;
  14891. if (!this.handler)
  14892. this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
  14893. this.handler.setInputAction(function (click) {
  14894. var pick1 = new Cesium.Cartesian2(click.position.x, click.position.y);
  14895. var cartesian = _this.viewer.scene.globe.pick(_this.viewer.camera.getPickRay(pick1), _this.viewer.scene);
  14896. if (cartesian) {
  14897. var cartographic = _this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
  14898. var lat = Cesium.Math.toDegrees(cartographic.latitude);
  14899. var lng = Cesium.Math.toDegrees(cartographic.longitude);
  14900. _this.tempPoints.push({
  14901. lng: lng,
  14902. lat: lat
  14903. });
  14904. var tempLength = _this.tempPoints.length;
  14905. _this.drawPoint();
  14906. if (tempLength > 1) {
  14907. _this.drawLine();
  14908. if (!_this.popup) {
  14909. _this.popup = new map3DViewer.setPopup({
  14910. viewer: _this.viewer,
  14911. cartesian: Cesium.Cartesian3.fromDegrees(lng, lat),
  14912. show: true,
  14913. offset: [10, -14.5],
  14914. html: _this.completeBotton
  14915. })
  14916. } else {
  14917. _this.popup.refreshRender({
  14918. cartesian: Cesium.Cartesian3.fromDegrees(lng, lat),
  14919. html: _this.completeBotton
  14920. })
  14921. }
  14922. }
  14923. }
  14924. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  14925. },
  14926. drawPoint: function () {
  14927. var a = this.tempPoints[this.tempPoints.length - 1]
  14928. var entity =
  14929. this.viewer.entities.add({
  14930. position: Cesium.Cartesian3.fromDegrees(a.lng, a.lat),
  14931. point: {
  14932. pixelSize: 10,
  14933. heightReference: 2,
  14934. color: Cesium.Color.RED,
  14935. }
  14936. });
  14937. this.tempEntitiesPoints.push(entity);
  14938. },
  14939. drawLine: function (a, b) {
  14940. var a = this.tempPoints[this.tempPoints.length - 2]
  14941. var b = this.tempPoints[this.tempPoints.length - 1]
  14942. var entity =
  14943. this.viewer.entities.add({
  14944. polyline: {
  14945. clampToGround: true,
  14946. positions: Cesium.Cartesian3.fromDegreesArray([a.lng, a.lat, b.lng, b.lat]),
  14947. width: 10.0,
  14948. material: new Cesium.PolylineGlowMaterialProperty({
  14949. color: Cesium.Color.CHARTREUSE.withAlpha(.5)
  14950. }),
  14951. clampToGround: true
  14952. }
  14953. });
  14954. this.tempEntitiesLines.push(entity);
  14955. },
  14956. finish: function () {
  14957. this.callback(JSON.parse(JSON.stringify(this.tempPoints)))
  14958. this.clear()
  14959. },
  14960. clear: function () {
  14961. var _this = this
  14962. $.each(this.tempEntitiesPoints, function (i, t) {
  14963. _this.viewer.entities.removeById(t._id);
  14964. })
  14965. $.each(this.tempEntitiesLines, function (i, t) {
  14966. _this.viewer.entities.removeById(t._id);
  14967. })
  14968. this.tempPoints.length = 0
  14969. this.tempEntitiesPoints.length = 0
  14970. this.tempEntitiesLines.length = 0
  14971. this.popup.close();
  14972. delete this.popup;
  14973. },
  14974. stop: function () {
  14975. if (this.handler)
  14976. this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
  14977. this.handler = null
  14978. },
  14979. }
  14980. map3DViewer.setDrawPolyline = function (options) {
  14981. return (function () {
  14982. var defaultData = {
  14983. action: 'add',
  14984. viewer: null,
  14985. callback: null,
  14986. }
  14987. defaultData = Object.assign({}, defaultData, options)
  14988. switch (defaultData.action) {
  14989. case 'add':
  14990. this.drawPolyline = new drawPolyline_Ceisum(defaultData)
  14991. this.drawPolyline.start();
  14992. return this;
  14993. break;
  14994. case 'finish':
  14995. this.drawPolyline.finish();
  14996. break;
  14997. case 'remove':
  14998. this.drawPolyline.stop();
  14999. delete this.drawPolyline
  15000. break;
  15001. }
  15002. })()
  15003. }
  15004. function drawPolygon_Ceisum() {
  15005. this.init.apply(this, arguments)
  15006. }
  15007. drawPolygon_Ceisum.prototype = {
  15008. viewer: null,
  15009. handler: null,
  15010. callback: null,
  15011. tempPoints: [],
  15012. tempEntitiesPoints: [],
  15013. tempEntityPolyline: null,
  15014. tempEntityPolygon: null,
  15015. completeBotton: '<div class="ZH" style="padding: 5px;border-radius: 5px;background: #fff;cursor:pointer;" onclick="map3DViewer.setDrawPolygon({action:\'finish\'})">完成</div>',
  15016. init: function (params) {
  15017. this.viewer = params.viewer;
  15018. this.callback = params.callback;
  15019. this.completeBotton = params.completeBotton || this.completeBotton
  15020. },
  15021. start: function () {
  15022. var _this = this;
  15023. if (!this.handler)
  15024. this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
  15025. this.handler.setInputAction(function (click) {
  15026. var pick1 = new Cesium.Cartesian2(click.position.x, click.position.y);
  15027. var cartesian = _this.viewer.scene.globe.pick(_this.viewer.camera.getPickRay(pick1), _this.viewer.scene);
  15028. if (cartesian) {
  15029. var cartographic = _this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
  15030. var lat = Cesium.Math.toDegrees(cartographic.latitude);
  15031. var lng = Cesium.Math.toDegrees(cartographic.longitude);
  15032. _this.tempPoints.push({
  15033. lng: lng,
  15034. lat: lat
  15035. });
  15036. _this.drawPoint();
  15037. if (_this.tempPoints.length == 2) {
  15038. _this.drawPolyline();
  15039. } else if (_this.tempPoints.length > 2) {
  15040. if (_this.tempEntityPolyline) {
  15041. _this.viewer.entities.removeById(_this.tempEntityPolyline._id)
  15042. _this.tempEntityPolyline = null;
  15043. }
  15044. _this.drawPolygon();
  15045. }
  15046. if (!_this.popup) {
  15047. _this.popup = new Popup({
  15048. viewer: _this.viewer,
  15049. cartesian: Cesium.Cartesian3.fromDegrees(lng, lat),
  15050. show: true,
  15051. offset: [10, -14.5],
  15052. html: _this.completeBotton
  15053. })
  15054. } else {
  15055. _this.popup.refreshRender({
  15056. cartesian: Cesium.Cartesian3.fromDegrees(lng, lat),
  15057. html: _this.completeBotton
  15058. })
  15059. }
  15060. }
  15061. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  15062. },
  15063. drawPoint: function () {
  15064. var a = this.tempPoints[this.tempPoints.length - 1];
  15065. var entity =
  15066. this.viewer.entities.add({
  15067. position: Cesium.Cartesian3.fromDegrees(a.lng, a.lat),
  15068. point: {
  15069. pixelSize: 10,
  15070. heightReference: 2,
  15071. color: Cesium.Color.RED,
  15072. }
  15073. });
  15074. this.tempEntitiesPoints.push(entity);
  15075. },
  15076. drawPolyline: function () {
  15077. var pArray = this.tempPoints.map(function (item, index, array) {
  15078. return [item.lng, item.lat]
  15079. })
  15080. pArray = pArray.reduce(function (a, b) {
  15081. return a.concat(b)
  15082. })
  15083. var entity =
  15084. this.viewer.entities.add({
  15085. polyline: {
  15086. clampToGround: true,
  15087. positions: Cesium.Cartesian3.fromDegreesArray(pArray),
  15088. width: 10.0,
  15089. material: new Cesium.PolylineGlowMaterialProperty({
  15090. color: Cesium.Color.CHARTREUSE.withAlpha(.5)
  15091. }),
  15092. clampToGround: true
  15093. }
  15094. });
  15095. this.tempEntityPolyline = entity
  15096. },
  15097. drawPolygon: function () {
  15098. var pArray = this.tempPoints.map(function (item, index, array) {
  15099. return [item.lng, item.lat]
  15100. })
  15101. pArray = pArray.reduce(function (a, b) {
  15102. return a.concat(b)
  15103. })
  15104. if (this.tempEntityPolygon) {
  15105. this.tempEntityPolygon.polygon.hierarchy.setValue(new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(pArray)));
  15106. } else {
  15107. var entity = this.viewer.entities.add({
  15108. polygon: {
  15109. hierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(pArray)),
  15110. heightReference: 0,
  15111. //height : 5,
  15112. material: Cesium.Color.CHARTREUSE.withAlpha(0.5),
  15113. outline: true,
  15114. outlineColor: Cesium.Color.YELLOW,
  15115. outlineWidth: 2
  15116. }
  15117. });
  15118. this.tempEntityPolygon = entity;
  15119. }
  15120. },
  15121. finish: function () {
  15122. this.callback(JSON.parse(JSON.stringify(this.tempPoints)))
  15123. this.clear()
  15124. },
  15125. clear: function () {
  15126. var _this = this
  15127. $.each(this.tempEntitiesPoints, function (i, t) {
  15128. _this.viewer.entities.removeById(t._id);
  15129. })
  15130. if (_this.tempEntityPolyline)
  15131. _this.viewer.entities.removeById(_this.tempEntityPolyline._id)
  15132. _this.tempEntityPolyline = null;
  15133. if (_this.tempEntityPolygon)
  15134. _this.viewer.entities.removeById(_this.tempEntityPolygon._id)
  15135. _this.tempEntityPolygon = null;
  15136. this.tempPoints = []
  15137. this.tempEntitiesPoints = []
  15138. this.tempEntityPolyline = null
  15139. this.tempEntityPolygon = null
  15140. this.popup.close();
  15141. delete this.popup;
  15142. },
  15143. stop: function () {
  15144. if (this.handler)
  15145. this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
  15146. this.handler = null
  15147. },
  15148. }
  15149. map3DViewer.setDrawPolygon = function (options) {
  15150. return (function () {
  15151. var defaultData = {
  15152. action: 'add',
  15153. viewer: null,
  15154. callback: null,
  15155. }
  15156. defaultData = Object.assign({}, defaultData, options)
  15157. switch (defaultData.action) {
  15158. case 'add':
  15159. this.drawPolygon = new drawPolygon_Ceisum(defaultData)
  15160. this.drawPolygon.start();
  15161. return this;
  15162. break;
  15163. case 'finish':
  15164. this.drawPolygon.finish();
  15165. break;
  15166. case 'remove':
  15167. this.drawPolygon.stop();
  15168. delete this.drawPolygon
  15169. break;
  15170. }
  15171. })()
  15172. }
  15173. ;
  15174. (function (window, document, undefined) {
  15175. PubSub.subscribe('map3D.flightSimulation.add', init);
  15176. PubSub.subscribe('map3D.flightSimulation.changeView', changeView);
  15177. PubSub.subscribe('map3D.flightSimulation.remove', remove);
  15178. var flightSimulation = map23DControl.flightSimulation;
  15179. if (typeof module === 'object' && typeof module.exports === 'object') {
  15180. module.exports = flightSimulation;
  15181. } else if (typeof define === 'function' && define.amd) {
  15182. define(flightSimulation);
  15183. }
  15184. // 模拟飞行
  15185. map3DViewer.flightSimulation = function (options) {
  15186. switch (options.action) {
  15187. case 'add':
  15188. return init(options);
  15189. break;
  15190. case 'changeView':
  15191. return changeView(options);
  15192. break;
  15193. case 'resetCondition':
  15194. return resetCondition(options);
  15195. break;
  15196. case 'remove':
  15197. return remove(options);
  15198. break;
  15199. }
  15200. }
  15201. var modValue = {}
  15202. function reset(options) {
  15203. var obj = {
  15204. minPitch: -Cesium.Math.PI_OVER_TWO,
  15205. maxPitch: -0.175,
  15206. scale: 1,
  15207. minHeight: 200,
  15208. tangle: []
  15209. }
  15210. modValue = Object.assign({}, modValue, obj, options)
  15211. //获取屏幕最下方中部像素坐标
  15212. modValue.wx = window.innerWidth;
  15213. modValue.wy = window.innerWidth;
  15214. modValue.wx = modValue.wx / 2;
  15215. modValue.wy = modValue.wy / 2;
  15216. modValue.hpRoll = new Cesium.HeadingPitchRoll();
  15217. modValue.speedVector = new Cesium.Cartesian3();
  15218. modValue.deltaRadians = Cesium.Math.toRadians(3.0);
  15219. modValue.fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator(
  15220. "north",
  15221. "west"
  15222. );
  15223. if (modValue.daqiaoModel) {
  15224. modValue.viewer.entities.removeById(modValue.daqiaoModel._id)
  15225. }
  15226. modValue.daqiaoModel = null
  15227. if (modValue.moniPolyline) {
  15228. modValue.viewer.entities.removeById(modValue.moniPolyline._id)
  15229. }
  15230. modValue.moniPolyline = null;
  15231. modValue.viewer.clock.onTick.removeEventListener(event1)
  15232. modValue.viewer.clock.onTick.removeEventListener(event2)
  15233. }
  15234. function init(params) {
  15235. delete params.action
  15236. var options = Object.assign({}, {
  15237. viewer: map3DViewer.map
  15238. }, params);
  15239. modValue = {}
  15240. modValue.viewer = options.viewer
  15241. reset(options)
  15242. modValue.eyeslook = options.eyeslook || "god"
  15243. modValue.height = options.height || 5000
  15244. modValue.speed = options.speed || 200
  15245. modValue.lineCoor = options.lineCoor
  15246. modValue.callback = options.callback || null;
  15247. modValue.showLine = typeof options.showLine == "boolean" ? options.showLine : false;
  15248. modValue.position = Cesium.Cartesian3.fromDegrees(modValue.lineCoor[0][0], modValue.lineCoor[0][1], options.height);
  15249. modValue.lineTurf = turf.lineString(modValue.lineCoor);
  15250. var cline = [];
  15251. for (var i = 0; i < modValue.lineCoor.length; i++) {
  15252. cline.push(modValue.lineCoor[i][0]);
  15253. cline.push(modValue.lineCoor[i][1]);
  15254. cline.push(modValue.height);
  15255. }
  15256. modValue.lineColor = options.lineColor || '#00ffcc'
  15257. modValue.outlineColor = options.outlineColor || '#FFFFFF'
  15258. if (!Cesium.Color.fromCssColorString(modValue.lineColor)) throw "lineColor has wrong format"
  15259. if (!Cesium.Color.fromCssColorString(modValue.outlineColor)) throw "outlineColor has wrong format"
  15260. var color = Cesium.Color.fromCssColorString(modValue.lineColor) || Cesium.Color.fromCssColorString('#00ffcc')
  15261. var outlineColor = Cesium.Color.fromCssColorString(modValue.outlineColor) || Cesium.Color.fromCssColorString('#FFFFFF')
  15262. var positionline = Cesium.Cartesian3.fromDegreesArrayHeights(cline);
  15263. modValue.moniPolyline = modValue.viewer.entities.add({
  15264. name: '模拟飞行线',
  15265. polyline: {
  15266. show: modValue.showLine,
  15267. clampToGround: false,
  15268. positions: positionline,
  15269. width: 3,
  15270. material: new Cesium.PolylineOutlineMaterialProperty({
  15271. color: color,
  15272. outlineWidth: 0,
  15273. outlineColor: outlineColor
  15274. })
  15275. }
  15276. });
  15277. modValue.daqiaoModel = modValue.viewer.entities.add({
  15278. position: modValue.position,
  15279. orientation: Cesium.Transforms.headingPitchRollQuaternion(
  15280. modValue.position,
  15281. modValue.hpRoll
  15282. ),
  15283. model: {
  15284. show: true,
  15285. uri: options.modelUrl,
  15286. minimumPixelSize: 150,
  15287. scale: modValue.scale
  15288. },
  15289. });
  15290. if (options.entity) modValue.daqiaoModel = options.entity
  15291. modValue.viewer.clock.onTick.addEventListener(event1)
  15292. modValue.viewer.clock.onTick.addEventListener(event2)
  15293. calculationEveryLineNorthPoint();
  15294. return modValue.daqiaoModel
  15295. }
  15296. function changeView(options) {
  15297. delete options.action
  15298. if (!options.eyeslook) throw "eyeslook is undefined!"
  15299. if (!modValue.daqiaoModel) throw "Flight simulation is not initialized!"
  15300. modValue.eyeslook = options.eyeslook
  15301. if (modValue.eyeslook == "one") {
  15302. modValue.daqiaoModel.model.show = false;
  15303. } else {
  15304. modValue.daqiaoModel.model.show = true;
  15305. }
  15306. }
  15307. function remove() {
  15308. if (!modValue.viewer)
  15309. return
  15310. if (modValue.daqiaoModel) {
  15311. modValue.viewer.entities.remove(modValue.daqiaoModel)
  15312. }
  15313. modValue.daqiaoModel = null
  15314. if (modValue.moniPolyline) {
  15315. modValue.viewer.entities.remove(modValue.moniPolyline)
  15316. }
  15317. modValue.moniPolyline = null;
  15318. modValue.viewer.clock.onTick.removeEventListener(event1)
  15319. modValue.viewer.clock.onTick.removeEventListener(event2)
  15320. }
  15321. function event1() {
  15322. var viewer = modValue.viewer;
  15323. if (viewer.camera._suspendTerrainAdjustment && viewer.scene.mode === Cesium.SceneMode.SCENE3D) {
  15324. viewer.camera._suspendTerrainAdjustment = false;
  15325. viewer.camera._adjustHeightForTerrain();
  15326. }
  15327. // Keep camera in a reasonable pitch range
  15328. var pitch = viewer.camera.pitch;
  15329. //将像素坐标转为笛卡尔坐标
  15330. var pick1 = new Cesium.Cartesian2(modValue.wx, modValue.wy);
  15331. var cartesian = viewer.scene.globe.pick(viewer.camera.getPickRay(pick1), viewer.scene);
  15332. if (cartesian) {
  15333. var cartographic1 = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian);
  15334. var lon = Cesium.Math.toDegrees(cartographic1.longitude);
  15335. var lat = Cesium.Math.toDegrees(cartographic1.latitude);
  15336. var height = cartographic1.height;
  15337. modValue.minHeight = height + 300;
  15338. }
  15339. var cameraPosition = viewer.camera.positionCartographic;
  15340. if (pitch > modValue.maxPitch || pitch < modValue.minPitch || cameraPosition.height < modValue.minHeight) {
  15341. viewer.scene.screenSpaceCameraController.enableTilt = false;
  15342. // clamp the pitch
  15343. if (pitch > modValue.maxPitch) {
  15344. pitch = modValue.maxPitch;
  15345. } else if (pitch < modValue.minPitch) {
  15346. pitch = modValue.minPitch;
  15347. }
  15348. var destination = Cesium.Cartesian3.fromRadians(
  15349. cameraPosition.longitude,
  15350. cameraPosition.latitude,
  15351. Math.max(cameraPosition.height, modValue.minHeight));
  15352. viewer.camera.setView({
  15353. destination: destination,
  15354. orientation: {
  15355. pitch: pitch
  15356. }
  15357. });
  15358. viewer.scene.screenSpaceCameraController.enableTilt = true;
  15359. }
  15360. }
  15361. function resetCondition(options) {
  15362. if (!isNaN(Number(options.speed))) {
  15363. modValue.speed = options.speed
  15364. } else {
  15365. // throw "speed is error!"
  15366. }
  15367. if (!isNaN(Number(options.height))) {
  15368. modValue.height = options.height
  15369. var position = modValue.viewer.scene.globe.ellipsoid.cartesianToCartographic(modValue.position)
  15370. position.height = modValue.height
  15371. modValue.position = modValue.viewer.scene.globe.ellipsoid.cartographicToCartesian(position)
  15372. } else {
  15373. // throw "height is error!"
  15374. }
  15375. }
  15376. function event2() {
  15377. var viewer = modValue.viewer;
  15378. modValue.speedVector = Cesium.Cartesian3.multiplyByScalar(
  15379. Cesium.Cartesian3.UNIT_X,
  15380. modValue.speed / 10,
  15381. modValue.speedVector
  15382. );
  15383. modValue.position = Cesium.Matrix4.multiplyByPoint(
  15384. modValue.daqiaoModel.computeModelMatrix(),
  15385. modValue.speedVector,
  15386. modValue.position
  15387. );
  15388. //重置飞机角度
  15389. resetPlanHeading(modValue.position.x, modValue.position.y, modValue.position.z);
  15390. if (modValue.eyeslook == "one") {
  15391. viewer.trackedEntity = undefined;
  15392. // viewer.zoomTo(daqiaoModel);
  15393. viewer.camera.setView({
  15394. destination: modValue.daqiaoModel.position.getValue(), // 设置位置
  15395. orientation: {
  15396. heading: modValue.hpRoll.heading + (Cesium.Math.PI / 2), // 方向
  15397. pitch: modValue.hpRoll.pitch, // 倾斜角度
  15398. roll: modValue.hpRoll.roll
  15399. }
  15400. })
  15401. } else if (modValue.eyeslook == "two") {
  15402. if (!viewer.trackedEntity) {
  15403. viewer.zoomTo(modValue.daqiaoModel, new Cesium.HeadingPitchRange(0, 0, 5000));
  15404. }
  15405. } else {
  15406. viewer.trackedEntity = undefined;
  15407. viewer.zoomTo(modValue.moniPolyline);
  15408. }
  15409. // viewer.zoomTo(modValue.daqiaoModel);
  15410. }
  15411. function calculationEveryLineNorthPoint() {
  15412. //计算每段线路偏北角
  15413. for (var i = 0; i < modValue.lineCoor.length - 1; i++) {
  15414. var point1 = turf.point(modValue.lineCoor[i]);
  15415. var point2 = turf.point(modValue.lineCoor[i + 1]);
  15416. var bearing = turf.bearing(point1, point2);
  15417. modValue.tangle.push(bearing);
  15418. }
  15419. modValue.hpRoll.heading = Cesium.Math.toRadians(modValue.tangle[0] - 90);
  15420. modValue.daqiaoModel.orientation.setValue(Cesium.Transforms.headingPitchRollQuaternion(
  15421. modValue.position,
  15422. modValue.hpRoll
  15423. ))
  15424. }
  15425. /**
  15426. * [resetPlanHeading description]
  15427. * @return {[type]} [description]
  15428. * 重置飞机飞行角度
  15429. * 根据飞机笛卡尔坐标计算出飞机经纬度坐标
  15430. * 根据经纬度计算飞机现在处于哪条线段
  15431. * 根据线段的index得出飞机的heading
  15432. * 如果飞机heading发生变化,重置飞机飞行角度
  15433. */
  15434. function resetPlanHeading(x, y, z) {
  15435. var tranPosition = cartesian3ToLatLng(x, y, z);
  15436. var alt = tranPosition.alt;
  15437. tranPosition = getLineIndex(tranPosition.lat, tranPosition.lng);
  15438. var lineindex = tranPosition.properties.index;
  15439. tranPosition = tranPosition.geometry.coordinates;
  15440. // position1 = Cesium.Cartesian3.fromDegrees(tranPosition[0], tranPosition[1], alt);
  15441. modValue.daqiaoModel.position.setValue(modValue.position);
  15442. if (lineindex < modValue.tangle.length) {
  15443. var curHeading = modValue.tangle[lineindex];
  15444. modValue.hpRoll.heading = Cesium.Math.toRadians(curHeading - 90);
  15445. modValue.daqiaoModel.orientation.setValue(Cesium.Transforms.headingPitchRollQuaternion(
  15446. modValue.position,
  15447. modValue.hpRoll
  15448. ))
  15449. }
  15450. }
  15451. function getLineIndex(lat, lng) {
  15452. var pt = turf.point([lng, lat]);
  15453. var snapped = turf.nearestPointOnLine(modValue.lineTurf, pt, {
  15454. units: 'miles'
  15455. });
  15456. return snapped;
  15457. }
  15458. //世界坐标转经纬度坐标
  15459. function cartesian3ToLatLng(x, y, z) {
  15460. var ellipsoid = modValue.viewer.scene.globe.ellipsoid;
  15461. var Cartesian3 = new Cesium.Cartesian3(x, y, z);
  15462. var cartographic = ellipsoid.cartesianToCartographic(Cartesian3);
  15463. var lat = Cesium.Math.toDegrees(cartographic.latitude);
  15464. var lng = Cesium.Math.toDegrees(cartographic.longitude);
  15465. var alt = cartographic.height;
  15466. var position = {
  15467. lat: lat,
  15468. lng: lng,
  15469. alt: alt
  15470. }
  15471. return position;
  15472. }
  15473. }(window, document));
  15474. ;
  15475. (function (window, document, undefined) {
  15476. PubSub.subscribe('map3D.lookAroundAnalysis.add', init);
  15477. PubSub.subscribe('map3D.lookAroundAnalysis.draw', draw);
  15478. PubSub.subscribe('map3D.lookAroundAnalysis.start', start);
  15479. PubSub.subscribe('map3D.lookAroundAnalysis.stop', stop);
  15480. PubSub.subscribe('map3D.lookAroundAnalysis.remove', remove);
  15481. PubSub.subscribe('map3D.lookAroundAnalysis.clear', clear);
  15482. var modValue = {}
  15483. function init(msg, options) {
  15484. modValue.viewer = options.viewer
  15485. modValue.scene = modValue.viewer.scene
  15486. modValue.callback = options.callback
  15487. modValue.tempEntities = {}
  15488. modValue.calcIndex = 0
  15489. modValue.viewHeight = 0
  15490. modValue.pointArr = [];
  15491. modValue.maxIndex = null;
  15492. modValue.index = 0;
  15493. }
  15494. // 经度 纬度 距离 直接绘制
  15495. function draw(msg, options) {
  15496. modValue.calcIndex++
  15497. modValue.index = 0
  15498. modValue.tempEntities[modValue.calcIndex] = [];
  15499. modValue.startPoint = null
  15500. modValue.viewHeight = options.viewHeight || 2
  15501. modValue.angleInterval = options.angleInterval || 2
  15502. var center = [options.lng, options.lat];
  15503. var option = {
  15504. steps: 360 / modValue.angleInterval,
  15505. units: 'meters',
  15506. };
  15507. if (!options.lng) throw "lng is undefined!"
  15508. if (!options.lat) throw "lat is undefined!"
  15509. if (!options.distance) throw "distance is undefined!"
  15510. var circle = turf.circle(center, options.distance, option);
  15511. modValue.pointArr = circle.geometry.coordinates[0];
  15512. modValue.maxIndex = modValue.pointArr.length - 1;
  15513. // modValue.depthTestAgainstTerrain = modValue.viewer.scene.globe.depthTestAgainstTerrain
  15514. // modValue.viewer.scene.globe.depthTestAgainstTerrain = true;
  15515. var positions = [Cesium.Cartographic.fromDegrees(options.lng, options.lat)];
  15516. var promise = new Cesium.sampleTerrain(modValue.viewer.terrainProvider, 13, positions);
  15517. Cesium.when(promise, function (updatedPositionsArr) {
  15518. var height = updatedPositionsArr[0].height + modValue.viewHeight;
  15519. var cartesian_ = Cesium.Ellipsoid.WGS84.cartographicToCartesian({
  15520. longitude: updatedPositionsArr[0].longitude,
  15521. latitude: updatedPositionsArr[0].latitude,
  15522. height: height
  15523. })
  15524. modValue.startPoint = {
  15525. cartesian: cartesian_
  15526. }
  15527. var drawCircle = turf.circle(center, options.distance, {
  15528. steps: 360 / 2,
  15529. units: 'meters',
  15530. });
  15531. var entity = addCircle(drawCircle.geometry.coordinates[0]);
  15532. modValue.tempEntities[modValue.calcIndex].push(entity)
  15533. // modValue.tempEntities[modValue.calcIndex].push(entity)
  15534. // var entity = drawPoint(modValue.startPoint.cartesian, "start")
  15535. // modValue.tempEntities[modValue.calcIndex].push(entity)
  15536. stopCameraController(false);
  15537. circulateIndex(0);
  15538. });
  15539. }
  15540. function start(msg, options) {
  15541. modValue.calcIndex++;
  15542. modValue.index = 0
  15543. modValue.tempEntities[modValue.calcIndex] = [];
  15544. modValue.startPoint = null
  15545. // modValue.depthTestAgainstTerrain = modValue.viewer.scene.globe.depthTestAgainstTerrain
  15546. // modValue.viewer.scene.globe.depthTestAgainstTerrain = true;
  15547. modValue.viewHeight = options.viewHeight || 2
  15548. modValue.angleInterval = options.angleInterval || 2
  15549. recordCameraController();
  15550. if (!modValue.handler) {
  15551. modValue.handler = new Cesium.ScreenSpaceEventHandler(modValue.viewer.scene.canvas);
  15552. modValue.handler.setInputAction(function (evt) {
  15553. // 像素点坐标,evt.position
  15554. var cartesian = modValue.scene.pickPosition(evt.position);
  15555. if (Cesium.defined(cartesian)) {
  15556. if (!modValue.startPoint) {
  15557. modValue.startPoint = {}
  15558. modValue.startPoint.pixelCoordinates = {
  15559. x: evt.position.x,
  15560. y: evt.position.y
  15561. };
  15562. var pick = new Cesium.Cartesian2(evt.position.x, evt.position.y);
  15563. var cartesian = modValue.scene.globe.pick(modValue.viewer.camera.getPickRay(pick), modValue.scene);
  15564. var obj = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian)
  15565. modValue.startPoint.pixelCoordinates.height = obj.height + modValue.viewHeight
  15566. var cartesian_ = Cesium.Ellipsoid.WGS84.cartographicToCartesian({
  15567. longitude: obj.longitude,
  15568. latitude: obj.latitude,
  15569. height: obj.height + modValue.viewHeight
  15570. })
  15571. modValue.startPoint.cartesian = cartesian_
  15572. // var entity = drawPoint(modValue.startPoint.cartesian, "start")
  15573. // modValue.tempEntities[modValue.calcIndex].push(entity)
  15574. } else {
  15575. var pick = new Cesium.Cartesian2(evt.position.x, evt.position.y);
  15576. var cartesian = modValue.scene.globe.pick(modValue.viewer.camera.getPickRay(pick), modValue.scene);
  15577. var Cartographic_end = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian)
  15578. var lng_end = Cesium.Math.toDegrees(Cartographic_end.longitude)
  15579. var lat_end = Cesium.Math.toDegrees(Cartographic_end.latitude)
  15580. var Cartographic_start = Cesium.Ellipsoid.WGS84.cartesianToCartographic(modValue.startPoint.cartesian)
  15581. var lng_start = Cesium.Math.toDegrees(Cartographic_start.longitude)
  15582. var lat_start = Cesium.Math.toDegrees(Cartographic_start.latitude)
  15583. var from = turf.point([lng_start, lat_start]);
  15584. var to = turf.point([lng_end, lat_end]);
  15585. var options = {
  15586. units: 'meters'
  15587. };
  15588. var distance = turf.distance(from, to, options);
  15589. var center = [lng_start, lat_start];
  15590. var options = {
  15591. steps: 360 / modValue.angleInterval,
  15592. units: 'meters',
  15593. };
  15594. var circle = turf.circle(center, distance, options);
  15595. modValue.pointArr = circle.geometry.coordinates[0];
  15596. modValue.maxIndex = modValue.pointArr.length - 1;
  15597. var drawCircle = turf.circle(center, distance, {
  15598. steps: 360 / 2,
  15599. units: 'meters',
  15600. });
  15601. var entity = addCircle(drawCircle.geometry.coordinates[0]);
  15602. modValue.tempEntities[modValue.calcIndex].push(entity)
  15603. stopCameraController(false);
  15604. circulateIndex(0);
  15605. }
  15606. }
  15607. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  15608. }
  15609. }
  15610. function circulateIndex(index) {
  15611. getHeigthByLonLat(modValue.pointArr[index][0], modValue.pointArr[index][1]);
  15612. }
  15613. function getHeigthByLonLat(lon, lat) {
  15614. var positions = [Cesium.Cartographic.fromDegrees(lon, lat)];
  15615. var promise = new Cesium.sampleTerrain(modValue.viewer.terrainProvider, 13, positions);
  15616. Cesium.when(promise, function (updatedPositionsArr) {
  15617. var cartesian = Cesium.Ellipsoid.WGS84.cartographicToCartesian(updatedPositionsArr[0])
  15618. ray(modValue.startPoint.cartesian, cartesian)
  15619. if (modValue.maxIndex > modValue.index) {
  15620. // var entity = drawPoint(cartesian, "end")
  15621. // modValue.tempEntities[modValue.calcIndex].push(entity)
  15622. modValue.index++;
  15623. circulateIndex(modValue.index);
  15624. } else {
  15625. if (modValue.callback) {
  15626. detach();
  15627. modValue.callback();
  15628. }
  15629. }
  15630. });
  15631. }
  15632. function ray(start, end) {
  15633. var direction = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(end, start, new Cesium.Cartesian3()), new Cesium.Cartesian3());
  15634. var ray = new Cesium.Ray(start, direction);
  15635. var result1 = map3DViewer.map.scene.globe.pick(ray, map3DViewer.map.scene);
  15636. var arr = Object.values(modValue.tempEntities).map(function (item) {
  15637. return Object.values(item)
  15638. })
  15639. var removeArr = arr.reduce(function (a, b) {
  15640. return a.concat(b)
  15641. })
  15642. var result2 = map3DViewer.map.scene.pickFromRay(ray, removeArr);
  15643. var result;
  15644. if (result2) {
  15645. result2 = result2.position;
  15646. }
  15647. //计算出距离起始点最近的点
  15648. if (result1) {
  15649. if (result2) {
  15650. result = getResult(start, end, [result1, result2])
  15651. } else {
  15652. result = getResult(start, end, [result1]);
  15653. }
  15654. } else if (result2) {
  15655. result = getResult(start, end, [result2]);
  15656. } else {
  15657. // result = end;
  15658. }
  15659. showIntersection(start, result, end);
  15660. }
  15661. function getResult(start, end, arr) {
  15662. var result;
  15663. startC = getLatlng(start);
  15664. endC = getLatlng(end);
  15665. var betweenStartAndEndDis = getFlatternDistance(startC.lat, startC.lng, endC.lat, endC.lng);
  15666. if (arr.length == 2) {
  15667. var dresult1 = getLatlng(arr[0]);
  15668. var dresult2 = getLatlng(arr[1]);
  15669. var dis1 = getFlatternDistance(startC.lat, startC.lng, dresult1.lat, dresult1.lng);
  15670. var dis2 = getFlatternDistance(startC.lat, startC.lng, dresult2.lat, dresult2.lng);
  15671. if (dis1 > betweenStartAndEndDis && dis2 > betweenStartAndEndDis) {
  15672. result = end;
  15673. } else if (betweenStartAndEndDis > dis1 && dis2 > betweenStartAndEndDis) {
  15674. result = arr[0];
  15675. } else if (dis1 > betweenStartAndEndDis && betweenStartAndEndDis > dis2) {
  15676. result = arr[1];
  15677. } else {
  15678. if (dis1 <= dis2) {
  15679. result = arr[0];
  15680. } else {
  15681. result = arr[1];
  15682. }
  15683. }
  15684. } else {
  15685. var dresult1 = getLatlng(arr[0]);
  15686. var dis1 = getFlatternDistance(startC.lat, startC.lng, dresult1.lat, dresult1.lng);
  15687. if (dis1 >= betweenStartAndEndDis) {
  15688. result = end;
  15689. } else {
  15690. result = arr[0];
  15691. }
  15692. }
  15693. return result;
  15694. }
  15695. function getLatlng(c) {
  15696. var ellipsoid = map3DViewer.map.scene.globe.ellipsoid;
  15697. var Cartesian3 = c;
  15698. var cartographic = ellipsoid.cartesianToCartographic(Cartesian3);
  15699. var lat = Cesium.Math.toDegrees(cartographic.latitude);
  15700. var lng = Cesium.Math.toDegrees(cartographic.longitude);
  15701. var alt = cartographic.height;
  15702. var position = {
  15703. lat: lat,
  15704. lng: lng,
  15705. alt: alt
  15706. }
  15707. return position;
  15708. }
  15709. function addCircle(array) {
  15710. var positions = []
  15711. for (var i = 0; i < array.length; i++) {
  15712. positions.push(array[i][0])
  15713. positions.push(array[i][1])
  15714. }
  15715. var position = Cesium.Cartesian3.fromDegreesArray(positions)
  15716. var entity = map3DViewer.map.entities.add({
  15717. polyline: {
  15718. positions: position,
  15719. clampToGround: true,
  15720. width: 2,
  15721. material: Cesium.Color.fromCssColorString('#D0CE00'),
  15722. }
  15723. })
  15724. return entity
  15725. }
  15726. // 处理交互点
  15727. function showIntersection(start, result, end) {
  15728. if (result) {
  15729. var entity1 = drawLinew(start, result, Cesium.Color.GREEN); // 可视区域
  15730. modValue.tempEntities[modValue.calcIndex].push(entity1)
  15731. var entity2 = drawLinew(result, end, Cesium.Color.RED); // 不可视区域
  15732. modValue.tempEntities[modValue.calcIndex].push(entity2)
  15733. } else {
  15734. var entity = drawLinew(start, end, Cesium.Color.GREEN); // 可视区域
  15735. modValue.tempEntities[modValue.calcIndex].push(entity)
  15736. }
  15737. }
  15738. function drawLinew(leftPoint, secPoint, color) {
  15739. var entity = map3DViewer.map.entities.add({
  15740. polyline: {
  15741. positions: [leftPoint, secPoint],
  15742. arcType: Cesium.ArcType.NONE,
  15743. width: 2,
  15744. material: color,
  15745. // clampToGround: true
  15746. }
  15747. })
  15748. return entity
  15749. }
  15750. function getFlatternDistance(lat1, lng1, lat2, lng2) {
  15751. var EARTH_RADIUS = 6378137.0; //单位M
  15752. var PI = Math.PI;
  15753. function getRad(d) {
  15754. return d * PI / 180.0;
  15755. }
  15756. var f = getRad((lat1 + lat2) / 2);
  15757. var g = getRad((lat1 - lat2) / 2);
  15758. var l = getRad((lng1 - lng2) / 2);
  15759. var sg = Math.sin(g);
  15760. var sl = Math.sin(l);
  15761. var sf = Math.sin(f);
  15762. var s, c, w, r, d, h1, h2;
  15763. var a = EARTH_RADIUS;
  15764. var fl = 1 / 298.257;
  15765. sg = sg * sg;
  15766. sl = sl * sl;
  15767. sf = sf * sf;
  15768. s = sg * (1 - sl) + (1 - sf) * sl;
  15769. c = (1 - sg) * (1 - sl) + sf * sl;
  15770. w = Math.atan(Math.sqrt(s / c));
  15771. r = Math.sqrt(s * c) / w;
  15772. d = 2 * w * a;
  15773. h1 = (3 * r - 1) / 2 / c;
  15774. h2 = (3 * r + 1) / 2 / s;
  15775. return d * (1 + fl * (h1 * sf * (1 - sg) - h2 * (1 - sf) * sg));
  15776. }
  15777. function stop() {
  15778. detach();
  15779. }
  15780. function remove() {
  15781. detach();
  15782. clear();
  15783. }
  15784. function detach() {
  15785. recoveryCameraController();
  15786. if (modValue.handler) {
  15787. modValue.handler.destroy();
  15788. modValue.handler = null
  15789. }
  15790. // if (callback) {
  15791. // modValue.start()
  15792. // }
  15793. }
  15794. function clear() {
  15795. modValue.startPoint = null;
  15796. for (var key in modValue.tempEntities) {
  15797. if (modValue.tempEntities.hasOwnProperty(key)) {
  15798. for (var i = 0; i < modValue.tempEntities[key].length; i++) {
  15799. if (modValue.tempEntities[key][i])
  15800. modValue.viewer.entities.removeById(modValue.tempEntities[key][i]._id)
  15801. }
  15802. }
  15803. }
  15804. modValue.tempEntities = {}
  15805. modValue.calcIndex = 0
  15806. modValue.viewHeight = 0
  15807. modValue.angleInterval = 2
  15808. modValue.pointArr = [];
  15809. modValue.maxIndex = null;
  15810. modValue.mapCameraControllerObj = null
  15811. modValue.mapCameraControllerObj = null
  15812. }
  15813. function drawPoint(position, type) {
  15814. var point = null;
  15815. if (type == "start") {
  15816. point = {
  15817. pixelSize: 10,
  15818. heightReference: 1,
  15819. color: Cesium.Color.YELLOW,
  15820. }
  15821. } else {
  15822. point = {
  15823. pixelSize: 10,
  15824. heightReference: 1,
  15825. color: Cesium.Color.RED,
  15826. }
  15827. }
  15828. var entity =
  15829. modValue.viewer.entities.add({
  15830. position: position,
  15831. point: point
  15832. });
  15833. return entity
  15834. // modValue.tempEntities = modValue.tempEntities.concat([entity])
  15835. }
  15836. function stopCameraController(judge) {
  15837. // 如果为真,则允许用户旋转相机。如果为假,相机将锁定到当前标题。此标志仅适用于2D和3D。
  15838. modValue.scene.screenSpaceCameraController.enableRotate = judge;
  15839. // 如果为true,则允许用户平移地图。如果为假,相机将保持锁定在当前位置。此标志仅适用于2D和Columbus视图模式。
  15840. modValue.scene.screenSpaceCameraController.enableTranslate = judge;
  15841. // 如果为真,允许用户放大和缩小。如果为假,相机将锁定到距离椭圆体的当前距离
  15842. modValue.scene.screenSpaceCameraController.enableZoom = judge;
  15843. // 如果为真,则允许用户倾斜相机。如果为假,相机将锁定到当前标题。这个标志只适用于3D和哥伦布视图。
  15844. modValue.scene.screenSpaceCameraController.enableTilt = judge;
  15845. }
  15846. function recordCameraController() {
  15847. modValue.mapCameraControllerObj = {
  15848. enableRotate: null,
  15849. enableTranslate: null,
  15850. enableZoom: null,
  15851. enableTilt: null
  15852. }
  15853. modValue.mapCameraControllerObj.enableRotate = modValue.scene.screenSpaceCameraController.enableRotate
  15854. modValue.mapCameraControllerObj.enableTranslate = modValue.scene.screenSpaceCameraController.enableTranslate
  15855. modValue.mapCameraControllerObj.enableZoom = modValue.scene.screenSpaceCameraController.enableZoom
  15856. modValue.mapCameraControllerObj.enableTilt = modValue.scene.screenSpaceCameraController.enableTilt
  15857. }
  15858. function recoveryCameraController() {
  15859. if (modValue.scene && modValue.mapCameraControllerObj) {
  15860. modValue.scene.screenSpaceCameraController.enableRotate = modValue.mapCameraControllerObj.enableRotate;
  15861. modValue.scene.screenSpaceCameraController.enableTranslate = modValue.mapCameraControllerObj.enableTranslate;
  15862. modValue.scene.screenSpaceCameraController.enableZoom = modValue.mapCameraControllerObj.enableZoom;
  15863. modValue.scene.screenSpaceCameraController.enableTilt = modValue.mapCameraControllerObj.enableTilt;
  15864. }
  15865. }
  15866. // function judgeBetweenPoint(start, end) {
  15867. // var rad1 = start
  15868. // var rad2 = end
  15869. // var xy = true;
  15870. // function createEquation(obj1, obj2) {
  15871. // var d = function (x) {
  15872. // return (x - obj1.x) / (obj2.x - obj1.x) * (obj2.y - obj1.y) + obj1.y
  15873. // }
  15874. // d.__proto__.obj1 = obj1
  15875. // d.__proto__.obj2 = obj2
  15876. // return d
  15877. // }
  15878. // var equation = null
  15879. // if (Math.abs(rad1.x - rad2.x) >= Math.abs(rad1.y - rad2.y)) {
  15880. // xy = true;
  15881. // interpolationAccuracy = Math.ceil(Math.abs(rad1.x - rad2.x))
  15882. // equation = createEquation({
  15883. // x: rad1.x,
  15884. // y: rad1.y,
  15885. // }, {
  15886. // x: rad2.x,
  15887. // y: rad2.y,
  15888. // })
  15889. // } else {
  15890. // xy = false;
  15891. // interpolationAccuracy = Math.ceil(Math.abs(rad1.y - rad2.y))
  15892. // equation = createEquation({
  15893. // x: rad1.y,
  15894. // y: rad1.x,
  15895. // }, {
  15896. // x: rad2.y,
  15897. // y: rad2.x,
  15898. // })
  15899. // }
  15900. // var gaodu = null;
  15901. // var judge = {
  15902. // coordinates: null,
  15903. // judge: false
  15904. // }
  15905. // for (var k = 0; k < interpolationAccuracy; k++) {
  15906. // gaodu = rad1.height - (rad1.height - rad2.height) * 1 / interpolationAccuracy * (k + 1);
  15907. // var x = null,
  15908. // y = null
  15909. // if (xy) {
  15910. // x = Math.round(rad1.x - (rad1.x - rad2.x) * 1 / interpolationAccuracy * (k + 1))
  15911. // y = Math.round(equation(x))
  15912. // } else {
  15913. // y = Math.round(rad1.y - (rad1.y - rad2.y) * 1 / interpolationAccuracy * (k + 1))
  15914. // x = Math.round(equation(y))
  15915. // }
  15916. // var _cartesian = modValue.viewer.scene.globe.pick(modValue.viewer.camera.getPickRay({
  15917. // x: x,
  15918. // y: y
  15919. // }), modValue.viewer.scene);
  15920. // if (_cartesian) {
  15921. // var pick = Cesium.Ellipsoid.WGS84.cartesianToCartographic(_cartesian)
  15922. // var gaocheng = pick.height
  15923. // if (gaocheng > gaodu) {
  15924. // //经纬度高程 转 笛卡尔
  15925. // judge.coordinates = _cartesian
  15926. // judge.judge = true;
  15927. // break
  15928. // } else {
  15929. // continue
  15930. // }
  15931. // } else {
  15932. // continue
  15933. // }
  15934. // }
  15935. // return judge
  15936. // }
  15937. // function drawLine(start, end, cannotSee) {
  15938. // if (!cannotSee) {
  15939. // var entity = modValue.viewer.entities.add({
  15940. // polyline: {
  15941. // positions: [
  15942. // start,
  15943. // end
  15944. // ],
  15945. // arcType: Cesium.ArcType.NONE,
  15946. // width: 5,
  15947. // material: Cesium.Color.GREEN,
  15948. // // depthFailMaterial: Cesium.Color.GREEN
  15949. // }
  15950. // })
  15951. // modValue.tempEntities = modValue.tempEntities.concat([entity])
  15952. // } else {
  15953. // var entity1 = modValue.viewer.entities.add({
  15954. // polyline: {
  15955. // positions: [
  15956. // start,
  15957. // cannotSee
  15958. // ],
  15959. // arcType: Cesium.ArcType.NONE,
  15960. // width: 5,
  15961. // material: Cesium.Color.GREEN,
  15962. // // depthFailMaterial: Cesium.Color.GREEN
  15963. // }
  15964. // })
  15965. // var entity2 = modValue.viewer.entities.add({
  15966. // polyline: {
  15967. // positions: [
  15968. // cannotSee,
  15969. // end,
  15970. // ],
  15971. // arcType: Cesium.ArcType.NONE,
  15972. // width: 5,
  15973. // material: Cesium.Color.RED,
  15974. // // depthFailMaterial: Cesium.Color.RED
  15975. // }
  15976. // })
  15977. // modValue.tempEntities = modValue.tempEntities.concat([entity1, entity2])
  15978. // }
  15979. // }
  15980. }(window, document));
  15981. ;
  15982. (function (window, document, undefined) {
  15983. // PubSub.subscribe('map3D.modelControl.add', init);
  15984. // PubSub.subscribe('map3D.modelControl.changeView', changeView);
  15985. var modelControl = map23DControl.modelControl;
  15986. if (typeof module === 'object' && typeof module.exports === 'object') {
  15987. module.exports = modelControl;
  15988. } else if (typeof define === 'function' && define.amd) {
  15989. define(modelControl);
  15990. }
  15991. // 模型控制
  15992. map3DViewer.modelControl = function (options) {
  15993. switch (options.action) {
  15994. case 'add':
  15995. return init(options);
  15996. break;
  15997. case 'change':
  15998. return change(options);
  15999. break;
  16000. case 'control':
  16001. return control(options);
  16002. break;
  16003. case 'update':
  16004. return update(options);
  16005. break;
  16006. case 'delete':
  16007. return deleteGuid(options);
  16008. break;
  16009. case 'remove':
  16010. return remove(options);
  16011. break;
  16012. }
  16013. }
  16014. var guid = null;
  16015. function init(options) {
  16016. guid = options.guid || map23DControl.buildGuid('modelControl3D');
  16017. // if (!options.entity) throw "entity is undefined!"
  16018. // entity = options.entity
  16019. var entity = null;
  16020. if (options.modelGuid) {
  16021. entity = map3DViewer.models[options.modelGuid]
  16022. } else {
  16023. if (!options.entity) throw "entity is undefined!"
  16024. entity = options.entity
  16025. }
  16026. if (!options.modelGuid && !options.entity) {
  16027. throw "No model in parameters"
  16028. }
  16029. map3DViewer.modelControlObj[guid] = {}
  16030. var radianInterval = null
  16031. if (options.radianInterval) {
  16032. radianInterval = Cesium.Math.toRadians(options.radianInterval)
  16033. } else {
  16034. radianInterval = Cesium.Math.toRadians(3.0)
  16035. }
  16036. var scaleInterval = options.scaleInterval || 2
  16037. var scaleMax = options.scaleMax || 10
  16038. var scaleInit = options.scaleInit || 1
  16039. var heading = options.heading || 0
  16040. var pitch = options.pitch || 0
  16041. var roll = options.roll || 0
  16042. map3DViewer.modelControlObj[guid] = {
  16043. scale: scaleInit,
  16044. keyboardControl: options.keyboardControl || false,
  16045. customizeControl: options.customizeControl || true,
  16046. // hpRoll: new Cesium.HeadingPitchRoll().fromDegrees(heading, pitch, roll),
  16047. hpRoll: Cesium.HeadingPitchRoll.fromDegrees(heading, pitch, roll),
  16048. radianInterval: radianInterval,
  16049. scaleInterval: scaleInterval,
  16050. scaleMax: scaleMax,
  16051. scaleInit: scaleInit,
  16052. entity: entity,
  16053. viewer: options.viewer || map3DViewer.map,
  16054. callback: options.callback || null
  16055. }
  16056. document.addEventListener("keydown", event);
  16057. return guid
  16058. }
  16059. function deleteGuid(options) {
  16060. delete map3DViewer.modelControlObj[options.guid]
  16061. }
  16062. function remove() {
  16063. document.removeEventListener("keydown", event);
  16064. for (var key in map3DViewer.modelControlObj) {
  16065. if (object.hasOwnProperty(key)) {
  16066. delete map3DViewer.modelControlObj[key]
  16067. }
  16068. }
  16069. guid = null
  16070. }
  16071. function update(options) {
  16072. if (options.guid || !map3DViewer.modelControlObj[options.guid]) throw "guid is undefined!"
  16073. map3DViewer.modelControlObj[options.guid] = Object.assign({}, map3DViewer.modelControlObj[options.guid], options)
  16074. }
  16075. function change(options) {
  16076. if (!options.guid) throw "guid is undefined!"
  16077. if (!map3DViewer.modelControlObj[options.guid]) throw "guid is undefined!"
  16078. if (!map3DViewer.modelControlObj[options.guid].entity) throw "entity is undefined!"
  16079. guid = options.guid
  16080. }
  16081. function control(options) {
  16082. if (!map3DViewer.modelControlObj[guid].customizeControl) return
  16083. change(options)
  16084. if (!options.behavior) throw "behavior is undefined!"
  16085. if (!map3DViewer.modelControlObj[options.guid].entity) throw "entity is undefined!"
  16086. if (!map3DViewer.modelControlObj[guid]) throw "guid is undefined!"
  16087. mod(options.behavior);
  16088. }
  16089. function event(e) {
  16090. if (!map3DViewer.modelControlObj[guid]) throw "guid is undefined!"
  16091. if (!map3DViewer.modelControlObj[guid].keyboardControl) return
  16092. var obj = map3DViewer.modelControlObj[guid]
  16093. switch (e.keyCode) {
  16094. case 40:
  16095. if (e.ctrlKey) {
  16096. mod("BeSmaller")
  16097. } else {
  16098. // pitch down
  16099. mod("PitchDown")
  16100. }
  16101. break;
  16102. case 38:
  16103. if (e.ctrlKey) {
  16104. mod("BeLarger")
  16105. } else {
  16106. // pitch up
  16107. mod("PitchUp")
  16108. }
  16109. break;
  16110. case 39:
  16111. if (e.shiftKey) {
  16112. // roll right
  16113. mod("RollRight")
  16114. } else {
  16115. // turn right
  16116. mod("TurnRight")
  16117. }
  16118. break;
  16119. case 37:
  16120. if (e.shiftKey) {
  16121. // roll left until
  16122. mod("RollLeft")
  16123. } else {
  16124. // turn left
  16125. mod("TurnLeft")
  16126. }
  16127. break;
  16128. default:
  16129. }
  16130. }
  16131. function mod(behavior) {
  16132. var obj = map3DViewer.modelControlObj[guid]
  16133. if (!map3DViewer.modelControlObj[guid].viewer.entities.getById(obj.entity._id)) {
  16134. delete map3DViewer.modelControlObj[guid]
  16135. return
  16136. }
  16137. switch (behavior) {
  16138. case "BeLarger":
  16139. var scale = obj.scale + obj.scaleInterval;
  16140. obj.scale = scale <= obj.scaleMax ? scale : obj.scaleMax;
  16141. obj.entity.model.scale.setValue(obj.scale)
  16142. break;
  16143. case "BeSmaller":
  16144. var scale = obj.scale - obj.scaleInterval;
  16145. obj.scale = scale >= obj.scaleInit ? scale : obj.scaleInit;
  16146. obj.entity.model.scale.setValue(obj.scale)
  16147. break;
  16148. case "PitchUp":
  16149. // pitch up
  16150. obj.hpRoll.pitch += obj.radianInterval;
  16151. if (obj.hpRoll.pitch > Cesium.Math.TWO_PI) {
  16152. obj.hpRoll.pitch -= Cesium.Math.TWO_PI;
  16153. }
  16154. obj.entity.orientation.setValue(Cesium.Transforms.headingPitchRollQuaternion(
  16155. obj.entity._position.getValue(),
  16156. obj.hpRoll
  16157. ))
  16158. break;
  16159. case "PitchDown":
  16160. // pitch down
  16161. obj.hpRoll.pitch -= obj.radianInterval;
  16162. if (obj.hpRoll.pitch < -Cesium.Math.TWO_PI) {
  16163. obj.hpRoll.pitch += Cesium.Math.TWO_PI;
  16164. }
  16165. obj.entity.orientation.setValue(Cesium.Transforms.headingPitchRollQuaternion(
  16166. obj.entity._position.getValue(),
  16167. obj.hpRoll
  16168. ))
  16169. break;
  16170. case "RollRight":
  16171. // roll right
  16172. obj.hpRoll.roll += obj.radianInterval;
  16173. if (obj.hpRoll.roll > Cesium.Math.TWO_PI) {
  16174. obj.hpRoll.roll -= Cesium.Math.TWO_PI;
  16175. }
  16176. obj.entity.orientation.setValue(Cesium.Transforms.headingPitchRollQuaternion(
  16177. obj.entity._position.getValue(),
  16178. obj.hpRoll
  16179. ))
  16180. break;
  16181. case "RollLeft":
  16182. // roll left until
  16183. obj.hpRoll.roll -= obj.radianInterval;
  16184. if (obj.hpRoll.roll < 0.0) {
  16185. obj.hpRoll.roll += Cesium.Math.TWO_PI;
  16186. }
  16187. obj.entity.orientation.setValue(Cesium.Transforms.headingPitchRollQuaternion(
  16188. obj.entity._position.getValue(),
  16189. obj.hpRoll
  16190. ))
  16191. break;
  16192. case "TurnRight":
  16193. // turn right
  16194. obj.hpRoll.heading += obj.radianInterval;
  16195. if (obj.hpRoll.heading > Cesium.Math.TWO_PI) {
  16196. obj.hpRoll.heading -= Cesium.Math.TWO_PI;
  16197. }
  16198. obj.entity.orientation.setValue(Cesium.Transforms.headingPitchRollQuaternion(
  16199. obj.entity._position.getValue(),
  16200. obj.hpRoll
  16201. ))
  16202. break;
  16203. case "TurnLeft":
  16204. // turn left
  16205. obj.hpRoll.heading -= obj.radianInterval;
  16206. if (obj.hpRoll.heading < 0.0) {
  16207. obj.hpRoll.heading += Cesium.Math.TWO_PI;
  16208. }
  16209. obj.entity.orientation.setValue(Cesium.Transforms.headingPitchRollQuaternion(
  16210. obj.entity._position.getValue(),
  16211. obj.hpRoll
  16212. ))
  16213. break;
  16214. default:
  16215. break;
  16216. }
  16217. if (map3DViewer.modelControlObj[guid].callback) {
  16218. // map3DViewer.modelControlObj[guid]
  16219. map3DViewer.modelControlObj[guid].callback({
  16220. scale: obj.scale,
  16221. heading: obj.hpRoll.heading / Cesium.Math.TWO_PI * 360,
  16222. roll: obj.hpRoll.roll / Cesium.Math.TWO_PI * 360,
  16223. pitch: obj.hpRoll.pitch / Cesium.Math.TWO_PI * 360,
  16224. })
  16225. }
  16226. }
  16227. }(window, document));
  16228. ;
  16229. (function (window, document, undefined) {
  16230. PubSub.subscribe('map3D.visualAnalysis.add', init);
  16231. PubSub.subscribe('map3D.visualAnalysis.start', start);
  16232. PubSub.subscribe('map3D.visualAnalysis.stop', stop);
  16233. PubSub.subscribe('map3D.visualAnalysis.remove', remove);
  16234. PubSub.subscribe('map3D.visualAnalysis.clear', clear);
  16235. var modValue = {}
  16236. function init(msg, options) {
  16237. modValue.viewer = options.viewer
  16238. modValue.scene = modValue.viewer.scene
  16239. modValue.callback = options.callback
  16240. modValue.index = 0
  16241. modValue.tempEntities = {}
  16242. }
  16243. function start(msg, options) {
  16244. modValue.startPoint = null;
  16245. modValue.endPoint = null;
  16246. modValue.index++;
  16247. modValue.tempEntities[modValue.index] = [];
  16248. modValue.depthTestAgainstTerrain = modValue.viewer.scene.globe.depthTestAgainstTerrain
  16249. modValue.viewer.scene.globe.depthTestAgainstTerrain = true;
  16250. modValue.viewHeight = options.viewHeight || 2
  16251. if (!modValue.handler) {
  16252. modValue.handler = new Cesium.ScreenSpaceEventHandler(modValue.viewer.scene.canvas);
  16253. modValue.handler.setInputAction(function (evt) {
  16254. // 像素点坐标,evt.position
  16255. var cartesian = modValue.scene.pickPosition(evt.position);
  16256. if (Cesium.defined(cartesian)) {
  16257. if (!modValue.startPoint) {
  16258. modValue.startPoint = {}
  16259. modValue.startPoint.pixelCoordinates = {
  16260. x: evt.position.x,
  16261. y: evt.position.y
  16262. };
  16263. var pick = evt.position;
  16264. var cartesian = modValue.scene.pickPosition(pick);
  16265. var obj = Cesium.Cartographic.fromCartesian(cartesian);
  16266. modValue.startPoint.pixelCoordinates.height = obj.height + modValue.viewHeight;
  16267. var cartesian_ = Cesium.Ellipsoid.WGS84.cartographicToCartesian({
  16268. longitude: obj.longitude,
  16269. latitude: obj.latitude,
  16270. height: obj.height + modValue.viewHeight
  16271. })
  16272. modValue.startPoint.cartesian = cartesian_
  16273. var entity = drawPoint(modValue.startPoint.cartesian, "start");
  16274. modValue.tempEntities[modValue.index].push(entity);
  16275. } else {
  16276. modValue.endPoint = {}
  16277. modValue.endPoint.pixelCoordinates = {
  16278. x: evt.position.x,
  16279. y: evt.position.y
  16280. };
  16281. var pick = evt.position;
  16282. var cartesian = modValue.scene.pickPosition(pick);
  16283. modValue.endPoint.cartesian = cartesian
  16284. modValue.endPoint.pixelCoordinates.height = Cesium.Cartographic.fromCartesian(cartesian).height;
  16285. var entity = drawPoint(modValue.endPoint.cartesian, "end")
  16286. modValue.tempEntities[modValue.index].push(entity);
  16287. var result = ray(modValue.startPoint.cartesian, modValue.endPoint.cartesian)
  16288. if (modValue.callback) {
  16289. detach()
  16290. modValue.callback();
  16291. }
  16292. }
  16293. }
  16294. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  16295. }
  16296. }
  16297. function ray(start, end) {
  16298. var direction = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(end, start, new Cesium.Cartesian3()), new Cesium.Cartesian3());
  16299. var ray = new Cesium.Ray(start, direction);
  16300. var result1 = map3DViewer.map.scene.globe.pick(ray, map3DViewer.map.scene);
  16301. var result2 = map3DViewer.map.scene.pickFromRay(ray, modValue.tempEntities[modValue.index]);
  16302. if (result2) {
  16303. result2 = result2.position;
  16304. }
  16305. //计算出距离起始点最近的点
  16306. if (result1) {
  16307. if (result2) {
  16308. result = getResult(start, end, [result1, result2])
  16309. } else {
  16310. result = getResult(start, end, [result1]);
  16311. }
  16312. } else if (result2) {
  16313. result = getResult(start, end, [result2]);
  16314. } else {
  16315. // result = end;
  16316. }
  16317. showIntersection(start, result, end);
  16318. return result
  16319. }
  16320. function getResult(start, end, arr) {
  16321. var result;
  16322. startC = getLatlng(start);
  16323. endC = getLatlng(end);
  16324. var betweenStartAndEndDis = getFlatternDistance(startC.lat, startC.lng, endC.lat, endC.lng);
  16325. if (arr.length == 2) {
  16326. var dresult1 = getLatlng(arr[0]);
  16327. var dresult2 = getLatlng(arr[1]);
  16328. var dis1 = getFlatternDistance(startC.lat, startC.lng, dresult1.lat, dresult1.lng);
  16329. var dis2 = getFlatternDistance(startC.lat, startC.lng, dresult2.lat, dresult2.lng);
  16330. if (dis1 > betweenStartAndEndDis && dis2 > betweenStartAndEndDis) {
  16331. result = end;
  16332. } else if (betweenStartAndEndDis > dis1 && dis2 > betweenStartAndEndDis) {
  16333. result = arr[0];
  16334. } else if (dis1 > betweenStartAndEndDis && betweenStartAndEndDis > dis2) {
  16335. result = arr[1];
  16336. } else {
  16337. if (dis1 <= dis2) {
  16338. result = arr[0];
  16339. } else {
  16340. result = arr[1];
  16341. }
  16342. }
  16343. } else {
  16344. var dresult1 = getLatlng(arr[0]);
  16345. var dis1 = getFlatternDistance(startC.lat, startC.lng, dresult1.lat, dresult1.lng);
  16346. if (dis1 >= betweenStartAndEndDis) {
  16347. result = end;
  16348. } else {
  16349. result = arr[0];
  16350. }
  16351. }
  16352. return result;
  16353. }
  16354. function getLatlng(c) {
  16355. var ellipsoid = map3DViewer.map.scene.globe.ellipsoid;
  16356. var Cartesian3 = c;
  16357. var cartographic = ellipsoid.cartesianToCartographic(Cartesian3);
  16358. var lat = Cesium.Math.toDegrees(cartographic.latitude);
  16359. var lng = Cesium.Math.toDegrees(cartographic.longitude);
  16360. var alt = cartographic.height;
  16361. var position = {
  16362. lat: lat,
  16363. lng: lng,
  16364. alt: alt
  16365. }
  16366. return position;
  16367. }
  16368. // 处理交互点
  16369. function showIntersection(start, result, end) {
  16370. // // 如果是场景模型的交互点,排除交互点是地球表面
  16371. // drawLinew(result, viewPoint, Cesium.Color.GREEN); // 可视区域
  16372. // drawLinew(result, destPoint, Cesium.Color.RED); // 不可视区域
  16373. if (result) {
  16374. var entity1 = drawLinew(start, result, Cesium.Color.GREEN); // 可视区域
  16375. modValue.tempEntities[modValue.index].push(entity1)
  16376. var entity2 = drawLinew(result, end, Cesium.Color.RED); // 不可视区域
  16377. modValue.tempEntities[modValue.index].push(entity2)
  16378. } else {
  16379. var entity = drawLinew(start, end, Cesium.Color.GREEN); // 可视区域
  16380. modValue.tempEntities[modValue.index].push(entity)
  16381. }
  16382. }
  16383. function drawLinew(leftPoint, secPoint, color) {
  16384. var entity = map3DViewer.map.entities.add({
  16385. polyline: {
  16386. positions: [leftPoint, secPoint],
  16387. arcType: Cesium.ArcType.NONE,
  16388. width: 5,
  16389. material: color,
  16390. // clampToGround: true
  16391. }
  16392. })
  16393. modValue.tempEntities[modValue.index].push(entity)
  16394. // modValue.tempEntities = modValue.tempEntities.concat([entity])
  16395. }
  16396. function stop() {
  16397. detach();
  16398. }
  16399. function remove() {
  16400. detach();
  16401. clear();
  16402. }
  16403. function detach() {
  16404. if (modValue.handler) {
  16405. modValue.handler.destroy();
  16406. modValue.handler = null
  16407. }
  16408. // if (callback) {
  16409. // modValue.start()
  16410. // }
  16411. }
  16412. function clear() {
  16413. modValue.startPoint = null;
  16414. modValue.endPoint = null;
  16415. if (modValue.tempEntities)
  16416. for (var key in modValue.tempEntities) {
  16417. if (modValue.tempEntities.hasOwnProperty(key)) {
  16418. for (var i = 0; i < modValue.tempEntities[key].length; i++) {
  16419. if (modValue.tempEntities[key][i])
  16420. modValue.viewer.entities.removeById(modValue.tempEntities[key][i]._id)
  16421. }
  16422. }
  16423. }
  16424. modValue.tempEntities = {};
  16425. modValue.index = 0;
  16426. modValue.viewHeight = 2
  16427. if (modValue.scene)
  16428. modValue.scene.globe.depthTestAgainstTerrain = modValue.depthTestAgainstTerrain;
  16429. modValue.depthTestAgainstTerrain = null
  16430. }
  16431. function getFlatternDistance(lat1, lng1, lat2, lng2) {
  16432. var EARTH_RADIUS = 6378137.0; //单位M
  16433. var PI = Math.PI;
  16434. function getRad(d) {
  16435. return d * PI / 180.0;
  16436. }
  16437. var f = getRad((lat1 + lat2) / 2);
  16438. var g = getRad((lat1 - lat2) / 2);
  16439. var l = getRad((lng1 - lng2) / 2);
  16440. var sg = Math.sin(g);
  16441. var sl = Math.sin(l);
  16442. var sf = Math.sin(f);
  16443. var s, c, w, r, d, h1, h2;
  16444. var a = EARTH_RADIUS;
  16445. var fl = 1 / 298.257;
  16446. sg = sg * sg;
  16447. sl = sl * sl;
  16448. sf = sf * sf;
  16449. s = sg * (1 - sl) + (1 - sf) * sl;
  16450. c = (1 - sg) * (1 - sl) + sf * sl;
  16451. w = Math.atan(Math.sqrt(s / c));
  16452. r = Math.sqrt(s * c) / w;
  16453. d = 2 * w * a;
  16454. h1 = (3 * r - 1) / 2 / c;
  16455. h2 = (3 * r + 1) / 2 / s;
  16456. return d * (1 + fl * (h1 * sf * (1 - sg) - h2 * (1 - sf) * sg));
  16457. }
  16458. function drawPoint(position, type) {
  16459. var point = null;
  16460. if (type == "start") {
  16461. point = {
  16462. pixelSize: 10,
  16463. heightReference: 0,
  16464. color: Cesium.Color.YELLOW,
  16465. }
  16466. } else {
  16467. point = {
  16468. pixelSize: 10,
  16469. heightReference: 0,
  16470. color: Cesium.Color.RED,
  16471. }
  16472. }
  16473. var entity =
  16474. modValue.viewer.entities.add({
  16475. position: position,
  16476. point: point
  16477. });
  16478. return entity
  16479. // modValue.tempEntities = modValue.tempEntities.concat([entity])
  16480. }
  16481. }(window, document));
  16482. /*
  16483. * L.Control.Zoom is used for the default zoom buttons on the map.
  16484. */
  16485. L.Control.Zoom = L.Control.extend({
  16486. options: {
  16487. position: 'bottomleft'
  16488. },
  16489. onAdd: function (map) {
  16490. var zoomName = 'leaflet-control-zoom',
  16491. container = L.DomUtil.create('div', zoomName + ' leaflet-bar');
  16492. this._map = map;
  16493. this._zoomInButton = this._createButton(
  16494. '+', '放大', zoomName + '-in', container, this._zoomIn, this);
  16495. this._zoomNum = L.DomUtil.create('div','zoom-num',container);
  16496. this._zoomNum.innerHTML = this._map.getZoom();
  16497. this._zoomOutButton = this._createButton(
  16498. '-', '缩小', zoomName + '-out', container, this._zoomOut, this);
  16499. map.on('zoomend zoomlevelschange', this._updateDisabled, this);
  16500. L.DomEvent.on(container,'contextmenu',L.DomEvent.stopPropagation);
  16501. return container;
  16502. },
  16503. onRemove: function (map) {
  16504. map.off('zoomend zoomlevelschange', this._updateDisabled, this);
  16505. },
  16506. _zoomIn: function (e) {
  16507. this._map.zoomIn(e.shiftKey ? 3 : 1);
  16508. },
  16509. _zoomOut: function (e) {
  16510. this._map.zoomOut(e.shiftKey ? 3 : 1);
  16511. },
  16512. _createButton: function (html, title, className, container, fn, context) {
  16513. var link = L.DomUtil.create('a', className, container);
  16514. link.innerHTML = html;
  16515. link.title = title;
  16516. var stop = L.DomEvent.stopPropagation;
  16517. L.DomEvent
  16518. .on(link, 'click', stop)
  16519. .on(link, 'mousedown', stop)
  16520. .on(link, 'dblclick', stop)
  16521. .on(link, 'click', L.DomEvent.preventDefault)
  16522. .on(link, 'click', fn, context)
  16523. .on(link, 'click', this._refocusOnMap, context);
  16524. return link;
  16525. },
  16526. _updateDisabled: function () {
  16527. var map = this._map,
  16528. className = 'leaflet-disabled';
  16529. L.DomUtil.removeClass(this._zoomInButton, className);
  16530. L.DomUtil.removeClass(this._zoomOutButton, className);
  16531. if (map._zoom === map.getMinZoom()) {
  16532. L.DomUtil.addClass(this._zoomOutButton, className);
  16533. }
  16534. if (map._zoom === map.getMaxZoom()) {
  16535. L.DomUtil.addClass(this._zoomInButton, className);
  16536. }
  16537. this._zoomNum.innerHTML = map._zoom;
  16538. }
  16539. });
  16540. L.Map.mergeOptions({
  16541. zoomControl: false
  16542. });
  16543. L.Map.addInitHook(function () {
  16544. if (this.options.zoomControl) {
  16545. this.zoomControl = new L.Control.Zoom();
  16546. this.addControl(this.zoomControl);
  16547. }
  16548. });
  16549. L.control.zoom = function (options) {
  16550. return new L.Control.Zoom(options);
  16551. };
  16552. /**
  16553. * 添加缩放等级控件
  16554. * @param {[type]} options [description]
  16555. * @return {[type]} [description]
  16556. */
  16557. map2DViewer.setZoomControl = function(options) {
  16558. var defaultData = {
  16559. action: 'add',
  16560. position: 'topleft',
  16561. offset: [10, 10]
  16562. }
  16563. _.merge(defaultData, options);
  16564. switch (defaultData.action) {
  16565. case 'add':
  16566. this.zoomControl = new L.Control.Zoom({
  16567. position: defaultData.position,
  16568. offset: defaultData.offset
  16569. }).addTo(this.map);
  16570. return this.zoomControl;
  16571. break;
  16572. case 'remove':
  16573. this.map.removeControl(this.zoomControl)
  16574. break;
  16575. }
  16576. }
  16577. var Knob = L.Draggable.extend({
  16578. initialize: function (element, stepWidth, knobWidth) {
  16579. L.Draggable.prototype.initialize.call(this, element, element);
  16580. this._element = element;
  16581. this._stepWidth = stepWidth;
  16582. this._knobWidth = knobWidth;
  16583. this.on('predrag', function () {
  16584. this._newPos.y = 0;
  16585. this._newPos.x = this._adjust(this._newPos.x);
  16586. }, this);
  16587. },
  16588. _adjust: function (x) {
  16589. var value = Math.round(this._toValue(x));
  16590. value = Math.max(0, Math.min(this._maxValue, value));
  16591. return this._toX(value);
  16592. },
  16593. // x = k*v + m
  16594. _toX: function (value) {
  16595. return this._k * value + this._m;
  16596. },
  16597. // v = (x - m) / k
  16598. _toValue: function (x) {
  16599. return (x - this._m) / this._k;
  16600. },
  16601. setSteps: function (steps) {
  16602. var sliderWidth = steps * this._stepWidth;
  16603. this._maxValue = steps - 1;
  16604. // conversion parameters
  16605. // the conversion is just a common linear function.
  16606. this._k = this._stepWidth;
  16607. this._m = (this._stepWidth ) / 2;
  16608. },
  16609. setPosition: function (x) {
  16610. L.DomUtil.setPosition(this._element,
  16611. L.point(this._adjust(x),0));
  16612. },
  16613. setValue: function (v) {
  16614. this.setPosition(this._toX(v));
  16615. },
  16616. getValue: function () {
  16617. return this._toValue(L.DomUtil.getPosition(this._element).x);
  16618. }
  16619. });
  16620. L.Control.Zoomslider = L.Control.extend({
  16621. options: {
  16622. position: 'topleft',
  16623. // Height of zoom-slider.png in px
  16624. stepWidth: 8,
  16625. // Height of the knob div in px (including border)
  16626. knobWidth: 12,
  16627. styleNS: 'leaflet-control-zoomslider',
  16628. offset:[10,10],
  16629. showZoomInfo:true
  16630. },
  16631. onAdd: function (map) {
  16632. this._map = map;
  16633. this._ui = this._createUI();
  16634. this._knob = new Knob(this._ui.knob,
  16635. this.options.stepWidth,
  16636. this.options.knobWidth);
  16637. map.whenReady(this._initKnob, this)
  16638. .whenReady(this._initEvents, this)
  16639. .whenReady(this._updateSize, this)
  16640. .whenReady(this._updateKnobValue, this)
  16641. .whenReady(this._updateDisabled, this);
  16642. switch(this.options.position){
  16643. case 'topleft':
  16644. this._ui.bar.style.marginLeft = this.options.offset[0]+'px';
  16645. this._ui.bar.style.marginTop = this.options.offset[1]+'px';
  16646. break;
  16647. case 'topright':
  16648. this._ui.bar.style.marginRight = this.options.offset[0]+'px';
  16649. this._ui.bar.style.marginTop = this.options.offset[1]+'px';
  16650. break;
  16651. case 'bottomleft':
  16652. this._ui.bar.style.marginLeft = this.options.offset[0]+'px';
  16653. this._ui.bar.style.marginBottom = this.options.offset[1]+'px';
  16654. break;
  16655. case 'bottomright':
  16656. this._ui.bar.style.marginRight = this.options.offset[0]+'px';
  16657. this._ui.bar.style.marginBottom = this.options.offset[1]+'px';
  16658. break;
  16659. }
  16660. return this._ui.bar;
  16661. },
  16662. onRemove: function (map) {
  16663. map.off('zoomlevelschange', this._updateSize, this)
  16664. .off('zoomend zoomlevelschange', this._updateKnobValue, this)
  16665. .off('zoomend zoomlevelschange', this._updateDisabled, this);
  16666. },
  16667. _createUI: function () {
  16668. var ui = {},
  16669. ns = this.options.styleNS;
  16670. ui.bar = L.DomUtil.create('div', ns + ' leaflet-bar');
  16671. ui.zoomOut = this._createZoomBtn('out', 'bottom', ui.bar);
  16672. ui.wrap = L.DomUtil.create('div', ns + '-wrap leaflet-bar-part', ui.bar);
  16673. ui.zoomIn = this._createZoomBtn('in', 'top', ui.bar);
  16674. ui.body = L.DomUtil.create('div', ns + '-body', ui.wrap);
  16675. ui.knob = L.DomUtil.create('div', ns + '-knob');
  16676. ui.zoomNum = L.DomUtil.create('div', ns + '-zoomNum',ui.knob);
  16677. if(!this.options.showZoomInfo){
  16678. ui.zoomNum.style.display = 'none';
  16679. }
  16680. L.DomEvent.disableClickPropagation(ui.bar);
  16681. L.DomEvent.disableClickPropagation(ui.knob);
  16682. return ui;
  16683. },
  16684. _createZoomBtn: function (zoomDir, end, container) {
  16685. var classDef = this.options.styleNS + '-' + zoomDir +
  16686. ' leaflet-bar-part' +
  16687. ' leaflet-bar-part-' + end,
  16688. link = L.DomUtil.create('a', classDef, container);
  16689. link.href = '#';
  16690. link.title = 'Zoom ' + zoomDir;
  16691. L.DomEvent.on(link, 'click', L.DomEvent.preventDefault);
  16692. return link;
  16693. },
  16694. _initKnob: function () {
  16695. this._knob.enable();
  16696. this._ui.body.appendChild(this._ui.knob);
  16697. },
  16698. _initEvents: function () {
  16699. this._map
  16700. .on('zoomlevelschange', this._updateSize, this)
  16701. .on('zoomend zoomlevelschange', this._updateKnobValue, this)
  16702. .on('zoomend zoomlevelschange', this._updateDisabled, this);
  16703. L.DomEvent.on(this._ui.body, 'click', this._onSliderClick, this);
  16704. L.DomEvent.on(this._ui.zoomIn, 'click', this._zoomIn, this);
  16705. L.DomEvent.on(this._ui.zoomOut, 'click', this._zoomOut, this);
  16706. this._knob.on('dragend', this._updateMapZoom, this);
  16707. },
  16708. _onSliderClick: function (e) {
  16709. var first = (e.touches && e.touches.length === 1 ? e.touches[0] : e),
  16710. x = L.DomEvent.getMousePosition(first, this._ui.body).x;
  16711. this._knob.setPosition(x);
  16712. this._updateMapZoom();
  16713. },
  16714. _zoomIn: function (e) {
  16715. this._map.zoomIn(e.shiftKey ? 3 : 1);
  16716. },
  16717. _zoomOut: function (e) {
  16718. this._map.zoomOut(e.shiftKey ? 3 : 1);
  16719. },
  16720. _zoomLevels: function () {
  16721. var zoomLevels = this._map.getMaxZoom() - this._map.getMinZoom() + 1;
  16722. return zoomLevels < Infinity ? zoomLevels : 0;
  16723. },
  16724. _toZoomLevel: function (value) {
  16725. return value + this._map.getMinZoom();
  16726. },
  16727. _toValue: function (zoomLevel) {
  16728. return zoomLevel - this._map.getMinZoom();
  16729. },
  16730. _updateSize: function () {
  16731. var steps = this._zoomLevels();
  16732. this._ui.body.style.width = this.options.stepWidth * steps + 'px';
  16733. this._knob.setSteps(steps);
  16734. },
  16735. _updateMapZoom: function () {
  16736. this._map.setZoom(this._toZoomLevel(this._knob.getValue()));
  16737. },
  16738. _updateKnobValue: function () {
  16739. this._knob.setValue(this._toValue(this._map.getZoom()));
  16740. this._ui.zoomNum.innerHTML = this._map.getZoom();
  16741. },
  16742. _updateDisabled: function () {
  16743. var zoomLevel = this._map.getZoom(),
  16744. className = this.options.styleNS + '-disabled';
  16745. L.DomUtil.removeClass(this._ui.zoomIn, className);
  16746. L.DomUtil.removeClass(this._ui.zoomOut, className);
  16747. if (zoomLevel === this._map.getMinZoom()) {
  16748. L.DomUtil.addClass(this._ui.zoomOut, className);
  16749. }
  16750. if (zoomLevel === this._map.getMaxZoom()) {
  16751. L.DomUtil.addClass(this._ui.zoomIn, className);
  16752. }
  16753. }
  16754. });
  16755. L.Map.addInitHook(function () {
  16756. if (this.options.zoomsliderControl) {
  16757. this.zoomsliderControl = new L.Control.Zoomslider();
  16758. this.addControl(this.zoomsliderControl);
  16759. }
  16760. });
  16761. L.control.zoomslider = function (options) {
  16762. return new L.Control.Zoomslider(options);
  16763. };
  16764. /**
  16765. * 添加缩放等级滑动条
  16766. * @param {[type]} options [description]
  16767. */
  16768. map2DViewer.setNavigationControl = function(options) {
  16769. var _this = map2DViewer;
  16770. var defaultData = {
  16771. action: 'add',
  16772. position: 'bottomright',
  16773. offset: [10, 10]
  16774. }
  16775. _.merge(defaultData, options);
  16776. switch (defaultData.action) {
  16777. case 'add':
  16778. this.navigationControl = new L.Control.Zoomslider({
  16779. position: defaultData.position,
  16780. offset: defaultData.offset
  16781. }).addTo(this.map);
  16782. return this.navigationControl;
  16783. break;
  16784. case 'remove':
  16785. this.map.removeControl(this.navigationControl)
  16786. break;
  16787. }
  16788. }
  16789. /*
  16790. * L.Control.Scale is used for displaying metric/imperial scale on the map.
  16791. */
  16792. L.Control.Scale = L.Control.extend({
  16793. options: {
  16794. position: 'bottomleft',
  16795. maxWidth: 100,
  16796. metric: false,
  16797. imperial: true,
  16798. updateWhenIdle: false,
  16799. offset:[10,10]
  16800. },
  16801. initialize: function (options) {
  16802. L.setOptions(this, options);
  16803. },
  16804. onAdd: function (map) {
  16805. this._map = map;
  16806. var className = 'leaflet-control-scale',
  16807. container = L.DomUtil.create('div', className),
  16808. options = this.options;
  16809. switch(this.options.position){
  16810. case 'topleft':
  16811. container.style.marginLeft = this.options.offset[0]+'px';
  16812. container.style.marginTop = this.options.offset[1]+'px';
  16813. break;
  16814. case 'topright':
  16815. container.style.marginRight = this.options.offset[0]+'px';
  16816. container.style.marginTop = this.options.offset[1]+'px';
  16817. break;
  16818. case 'bottomleft':
  16819. container.style.marginLeft = this.options.offset[0]+'px';
  16820. container.style.marginBottom = this.options.offset[1]+'px';
  16821. break;
  16822. case 'bottomright':
  16823. container.style.marginRight = this.options.offset[0]+'px';
  16824. container.style.marginBottom = this.options.offset[1]+'px';
  16825. break;
  16826. }
  16827. this._addScales(options, className, container);
  16828. map.on(options.updateWhenIdle ? 'moveend' : 'move', this._update, this);
  16829. map.whenReady(this._update, this);
  16830. L.DomEvent.on(container,'contextmenu',L.DomEvent.stopPropagation);
  16831. return container;
  16832. },
  16833. onRemove: function (map) {
  16834. map.off(this.options.updateWhenIdle ? 'moveend' : 'move', this._update, this);
  16835. },
  16836. getUnit:function(){
  16837. return this.options.metric?'metric':'imperial'
  16838. },
  16839. setUnit:function(unit){
  16840. if(unit == 'metric'){
  16841. this.options.metric = true;
  16842. this.options.imperial = false;
  16843. this._mScale.style.display = 'block';
  16844. this._iScale.style.display = 'none';
  16845. }
  16846. if(unit == 'imperial'){
  16847. this.options.metric = false;
  16848. this.options.imperial = true;
  16849. this._iScale.style.display = 'block';
  16850. this._mScale.style.display = 'none';
  16851. }
  16852. this._update();
  16853. },
  16854. _addScales: function (options, className, container) {
  16855. this._mScale = L.DomUtil.create('div', className + '-line', container);
  16856. this._iScale = L.DomUtil.create('div', className + '-line', container);
  16857. if (options.metric) {
  16858. this._mScale.style.display = 'block';
  16859. this._iScale.style.display = 'none';
  16860. }
  16861. if (options.imperial) {
  16862. this._iScale.style.display = 'block';
  16863. this._mScale.style.display = 'none';
  16864. }
  16865. },
  16866. _update: function () {
  16867. var bounds = this._map.getBounds(),
  16868. centerLat = bounds.getCenter().lat,
  16869. halfWorldMeters = 6378137 * Math.PI * Math.cos(centerLat * Math.PI / 180),
  16870. dist = halfWorldMeters * (bounds.getNorthEast().lng - bounds.getSouthWest().lng) / 180,
  16871. size = this._map.getSize(),
  16872. options = this.options,
  16873. maxMeters = 0;
  16874. if (size.x > 0) {
  16875. maxMeters = dist * (options.maxWidth / size.x);
  16876. }
  16877. this._updateScales(options, maxMeters);
  16878. },
  16879. _updateScales: function (options, maxMeters) {
  16880. if (options.metric && maxMeters) {
  16881. this._updateMetric(maxMeters);
  16882. }
  16883. if (options.imperial && maxMeters) {
  16884. this._updateImperial(maxMeters);
  16885. }
  16886. },
  16887. _updateMetric: function (maxMeters) {
  16888. var meters = this._getRoundNum(maxMeters);
  16889. this._mScale.style.width = this._getScaleWidth(meters / maxMeters) + 'px';
  16890. this._mScale.innerHTML = meters < 1000 ? '<span>'+meters + ' 米</span>' : '<span>'+(meters / 1000) + ' 公里</span>';
  16891. },
  16892. _updateImperial: function (maxMeters) {
  16893. var maxFeet = maxMeters * 3.2808399,
  16894. scale = this._iScale,
  16895. maxMiles, miles, feet;
  16896. feet = this._getRoundNum(maxFeet);
  16897. scale.style.width = this._getScaleWidth(feet / maxFeet) + 'px';
  16898. scale.innerHTML = '<span>'+feet + ' 英尺</span>';
  16899. },
  16900. _getScaleWidth: function (ratio) {
  16901. return Math.round(this.options.maxWidth * ratio) - 10;
  16902. },
  16903. _getRoundNum: function (num) {
  16904. var pow10 = Math.pow(10, (Math.floor(num) + '').length - 1),
  16905. d = num / pow10;
  16906. d = d >= 10 ? 10 : d >= 5 ? 5 : d >= 3 ? 3 : d >= 2 ? 2 : 1;
  16907. return pow10 * d;
  16908. }
  16909. });
  16910. L.Map.addInitHook(function () {
  16911. if (this.options.scaleControl) {
  16912. this.scaleControl = new L.Control.Scale();
  16913. this.addControl(this.scaleControl);
  16914. }
  16915. });
  16916. L.control.scale = function (options) {
  16917. return new L.Control.Scale(options);
  16918. };
  16919. /**
  16920. * 添加比例尺控件
  16921. * @param {[type]} options [description]
  16922. * @return {[type]} [description]
  16923. */
  16924. map2DViewer.setScaleControl = function(options) {
  16925. var defaultData = {
  16926. action: 'add',
  16927. position: 'bottomleft',
  16928. offset: [10, 10]
  16929. }
  16930. _.merge(defaultData, options);
  16931. switch (defaultData.action) {
  16932. case 'add':
  16933. this.scaleControl = new L.Control.Scale({
  16934. position: defaultData.position,
  16935. offset: defaultData.offset,
  16936. metric: defaultData.metric,
  16937. imperial: defaultData.imperial,
  16938. }).addTo(this.map);
  16939. return this.scaleControl;
  16940. break;
  16941. case 'remove':
  16942. this.map.removeControl(this.scaleControl)
  16943. break;
  16944. }
  16945. }
  16946. L.Control.MeasureArea = L.Control.extend({
  16947. //是否初始化
  16948. _initialized: false,
  16949. //统计
  16950. _mC: 0,
  16951. //marker统计
  16952. AreaMarker: {},
  16953. //测
  16954. _measureAObjs: {},
  16955. //是否已经显示测面
  16956. isshowpolygonArea: false,
  16957. //是否完成当前测绘
  16958. _finished: true,
  16959. /**
  16960. * 是否是新的测量事件
  16961. * @type {Boolean}
  16962. * @default true
  16963. * @private
  16964. */
  16965. _isNewMeasure: true,
  16966. options: {
  16967. position: 'topright',
  16968. autoZIndex: true,
  16969. offset: [10, 40],
  16970. background: "#000",
  16971. color: "#fff",
  16972. size: 14,
  16973. closeButton: true,
  16974. tips: $('<div class="measureArea_tips map2D">单击添加点,双击结束</div>')
  16975. },
  16976. initialize: function (options) {
  16977. L.setOptions(this, options);
  16978. return this;
  16979. },
  16980. onAdd: function (map) {
  16981. this._map = map;
  16982. this._addMeasureGroup();
  16983. this.start();
  16984. this._createControl();
  16985. this._map.on('measure-area-start', this.stop, this);
  16986. switch (this.options.position) {
  16987. case 'topleft':
  16988. this._container.style.marginLeft = this.options.offset[0] + 'px';
  16989. this._container.style.marginTop = this.options.offset[1] + 'px';
  16990. break;
  16991. case 'topright':
  16992. this._container.style.marginRight = this.options.offset[0] + 'px';
  16993. this._container.style.marginTop = this.options.offset[1] + 'px';
  16994. break;
  16995. case 'bottomleft':
  16996. this._container.style.marginLeft = this.options.offset[0] + 'px';
  16997. this._container.style.marginBottom = this.options.offset[1] + 'px';
  16998. break;
  16999. case 'bottomright':
  17000. this._container.style.marginRight = this.options.offset[0] + 'px';
  17001. this._container.style.marginBottom = this.options.offset[1] + 'px';
  17002. break;
  17003. }
  17004. return this._container;
  17005. },
  17006. _addTip: function (param) {
  17007. param.options.tips.appendTo(param._map.getContainer());
  17008. param._map.on('mousemove', param._onMovePoint, this);
  17009. },
  17010. _createControl: function () {
  17011. var _this = this;
  17012. this._container = L.DomUtil.create('div', 'leaflet-bar leaflet-control-measure-area');
  17013. this._container.style.display = "none"
  17014. var link = L.DomUtil.create('a', 'leaflet-control-measure-area-link', this._container);
  17015. link.title = '测面积';
  17016. L.DomUtil.create('span', '', link);
  17017. L.DomEvent
  17018. .on(this._container, 'contextmenu', L.DomEvent.stopPropagation)
  17019. .on(link, 'click', L.DomEvent.stopPropagation)
  17020. .on(link, 'click', function () {
  17021. if (!_this._finished) {
  17022. _this._finished = true;
  17023. L.DomUtil.removeClass(_this._container, 'active');
  17024. _this._removeMeasureGroup();
  17025. _this._map.getContainer().style.cursor = 'auto';
  17026. } else {
  17027. _this._finished = false;
  17028. L.DomUtil.addClass(_this._container, 'active');
  17029. _this._addMeasureGroup();
  17030. if (L.Browser.ie || L.Browser.firefox) {
  17031. _this._map.getContainer().style.cursor = 'url(' + L.DefaultImagePath + '/cur-ruler.cur),auto';
  17032. } else {
  17033. _this._map.getContainer().style.cursor = 'url(' + L.DefaultImagePath + '/cur-ruler.cur) 5 5,auto';
  17034. }
  17035. }
  17036. })
  17037. },
  17038. start: function () {
  17039. var _this = this;
  17040. if (!_this._finished) {
  17041. _this._finished = true;
  17042. //L.DomUtil.removeClass(_this._container, 'active');
  17043. _this._removeMeasureGroup();
  17044. _this._map.getContainer().style.cursor = 'auto';
  17045. }
  17046. _this._finished = false;
  17047. _this.isshowpolygonArea = false;
  17048. _this._mC++
  17049. //L.DomUtil.addClass(_this._container, 'active');
  17050. _this._addTip(_this);
  17051. _this._map.on('click', _this._onClickPoint, this);
  17052. if (L.Browser.ie || L.Browser.firefox) {
  17053. _this._map.getContainer().style.cursor = 'url(' + L.DefaultImagePath + '/cur-ruler.cur),auto';
  17054. } else {
  17055. _this._map.getContainer().style.cursor = 'url(' + L.DefaultImagePath + '/cur-ruler.cur) 5 5,auto';
  17056. }
  17057. },
  17058. _addMeasureGroup: function () {
  17059. var _this = this;
  17060. if (!_this._initialized) {
  17061. _this._measureGroup = new L.featureGroup();
  17062. _this._measureGroup.addTo(_this._map);
  17063. _this._initialized = true;
  17064. }
  17065. _this._map.doubleClickZoom.disable();
  17066. },
  17067. /**
  17068. * 鼠标单击添加多边形的点
  17069. * @type {Function}
  17070. * @param e
  17071. * @private
  17072. */
  17073. _onClickPoint: function (e) {
  17074. var _this = this;
  17075. e.latlng = L.Util.formatEarthLatLng(e.latlng);
  17076. if (_this._isNewMeasure) {
  17077. //_this._mC++;
  17078. _this._measureAObjs[_this._mC] = new L.FeatureGroup();
  17079. _this._measureAObjs[_this._mC].addTo(_this._measureGroup);
  17080. _this._measureAObjs[_this._mC].measurePoints = [];
  17081. _this._measureAObjs[_this._mC].polygon = new L.polygon([
  17082. [0, 0],
  17083. [0, 0],
  17084. [0, 0]
  17085. ], {
  17086. fillColor: "blue",
  17087. color: "#00b7ef",
  17088. opacity: 0.8,
  17089. weight: 3
  17090. });
  17091. _this._measureAObjs[_this._mC].polygon.addTo(_this._measureGroup);
  17092. _this._measureAObjs[_this._mC].polygon.on('click', _this._onClickPoint, this);
  17093. _this._isNewMeasure = false;
  17094. }
  17095. _this._measureAObjs[_this._mC].measurePoints.push(e.latlng);
  17096. if (_this._measureAObjs[_this._mC].measurePoints.length > 1) {
  17097. _this._drawPolygon();
  17098. _this._map.on('mousemove', _this._onMovePoint, this);
  17099. }
  17100. _this._buildMarker(e).addTo(_this._measureAObjs[_this._mC]);
  17101. },
  17102. /**
  17103. * 鼠标移动重绘多边形 //todo 这里应该 新建立一个临时 坐标组
  17104. * @type {Function}
  17105. * @param e
  17106. * @private
  17107. */
  17108. _onMovePoint: function (e) {
  17109. var _this = this;
  17110. var wp = _this._map.latLngToContainerPoint(e.latlng)
  17111. $(".measureArea_tips").css({
  17112. "left": wp.x + 20,
  17113. 'top': wp.y + 10
  17114. })
  17115. if (Object.getOwnPropertyNames(_this._measureAObjs).length > 0) {
  17116. if (_this._measureAObjs[_this._mC]) {
  17117. if (_this._measureAObjs[_this._mC].measurePoints.length > 0) {
  17118. var tempPoint = [];
  17119. tempPoint = _this._measureAObjs[_this._mC].measurePoints.concat();
  17120. _this._measureAObjs[_this._mC].measurePoints.push(e.latlng);
  17121. _this._drawPolygon();
  17122. _this._measureAObjs[_this._mC].measurePoints = tempPoint.concat();
  17123. }
  17124. }
  17125. }
  17126. },
  17127. /**
  17128. * 鼠标双击结束多边形点添加
  17129. * @type {Function}
  17130. * @param e
  17131. * @private
  17132. */
  17133. _onFinishClick: function (e) {
  17134. var _this = this;
  17135. _this._map.off('mousemove', _this._onMovePoint, this);
  17136. _this._measureAObjs[_this._mC].measurePoints.push(e.latlng);
  17137. if (_this._measureAObjs[_this._mC].measurePoints.length > 1) {
  17138. _this._drawPolygon();
  17139. }
  17140. _this._measureAObjs[_this._mC].polygon.off('click', _this._onClickPoint, this);
  17141. _this._isNewMeasure = true;
  17142. if (!_this.isshowpolygonArea) {
  17143. _this._countArea(e);
  17144. _this.isshowpolygonArea = true;
  17145. }
  17146. _this._finished = true;
  17147. _this._removeMeasureGroup();
  17148. _this._map.getContainer().style.cursor = 'auto';
  17149. _this._restartMearing();
  17150. },
  17151. /**
  17152. * [cleanAllMeasure description]
  17153. * @return {[type]} [description]
  17154. */
  17155. cleanAllMeasure: function () {
  17156. var _this = this;
  17157. for (var item in _this._measureAObjs) {
  17158. _this.del(item);
  17159. }
  17160. },
  17161. /**
  17162. * 重绘多边形
  17163. * @type {Function}
  17164. * @private
  17165. */
  17166. _drawPolygon: function () {
  17167. var _this = this;
  17168. _this._measureAObjs[_this._mC].polygon.setLatLngs(_this._measureAObjs[_this._mC].measurePoints);
  17169. _this._measureAObjs[_this._mC].polygon.redraw();
  17170. },
  17171. /**
  17172. * 创建一个marker 并返回该marker
  17173. * @type {Function}
  17174. * @param obj {Object} {latlng}
  17175. * @returns {L.Marker}
  17176. * @private
  17177. */
  17178. _buildMarker: function (obj) {
  17179. var _this = this;
  17180. var marker = L.marker(
  17181. obj.latlng, {
  17182. icon: L.divIcon({
  17183. //className: 'my-div-icon1',
  17184. //iconUrl: L.DefaultImagePath+'/icon-linePoint.png',
  17185. iconSize: [5, 5]
  17186. })
  17187. }
  17188. );
  17189. marker.on('dblclick', function (e) {
  17190. if (_this._measureAObjs[_this._mC].measurePoints.length < 2) {
  17191. return false;
  17192. }
  17193. //与上一个点相同,测量完成
  17194. //if(e.latlng == _this._measureAObjs[_this._mC].measurePoints[_this._measureAObjs[_this._mC].measurePoints.length-1] ){
  17195. _this._onFinishClick({
  17196. latlng: _this._measureAObjs[_this._mC].measurePoints[_this._measureAObjs[_this._mC].measurePoints.length - 1]
  17197. });
  17198. return false;
  17199. //}
  17200. });
  17201. _this.AreaMarker[_this._mC] = marker;
  17202. return marker;
  17203. },
  17204. /**
  17205. * 测量面积
  17206. * @type {Function}
  17207. * @param e
  17208. * @private
  17209. */
  17210. _countArea: function (e) {
  17211. var _this = this;
  17212. var areaLabel = L.DomUtil.create('span', 'area');
  17213. areaLabel.style.color = 'red';
  17214. areaLabel.style.fontWeight = 'bold';
  17215. areaLabel.innerHTML = '面积:' + _this._getArea();
  17216. //console.log(areaLabel.innerHTML);
  17217. areaLabel.mid = _this._mC;
  17218. //添加结束信息
  17219. var oLabelObjContent = L.DomUtil.create('div', 'measure-area-content');
  17220. var oLabelObj = L.DomUtil.create('p');
  17221. var delLabel = L.DomUtil.create('div', 'distance-ico-del');
  17222. //delLabel.innerHTML = '删除';
  17223. delLabel.lC = _this._mC;
  17224. oLabelObj.lC = _this._mC;
  17225. L.DomEvent.on(delLabel, 'click', function (e) {
  17226. L.DomEvent.stopPropagation(e);
  17227. _this.del(delLabel.lC)
  17228. });
  17229. oLabelObj.appendChild(areaLabel);
  17230. L.DomEvent.on(oLabelObj, 'dblclick', function () {
  17231. L.DomEvent.stopPropagation(e);
  17232. _this.del(oLabelObj.lC);
  17233. });
  17234. oLabelObjContent.appendChild(oLabelObj);
  17235. if (_this.options.closeButton) {
  17236. oLabelObjContent.appendChild(delLabel);
  17237. }
  17238. L.marker(e.latlng, {
  17239. icon: L.divIcon({
  17240. className: 'distance-div-icon'
  17241. })
  17242. }).bindLabel(oLabelObjContent, {
  17243. noHide: true,
  17244. clickable: true,
  17245. className: 'measure-distance-tip',
  17246. offset: [0, 0]
  17247. }).addTo(_this._measureAObjs[_this._mC]);
  17248. _this.editerCSS();
  17249. },
  17250. /**
  17251. * 修改测距样式
  17252. */
  17253. editerCSS: function () {
  17254. var _this = this;
  17255. $(".measure-area-content span").css({
  17256. "color": _this.options.color,
  17257. })
  17258. $(".measure-area-content span").css({
  17259. "font-size": _this.options.font_size,
  17260. })
  17261. $(".measure-area-content").css({
  17262. "background": _this.options.background
  17263. });
  17264. },
  17265. /**
  17266. * 合并样式
  17267. */
  17268. addCss: function (options) {
  17269. var _this = this;
  17270. _.merge(this.options, options);
  17271. _this.editerCSS();
  17272. },
  17273. /**
  17274. * 通过坐标点计算面积
  17275. * @type {Function}
  17276. * @returns {Number} 面积
  17277. * @private
  17278. */
  17279. _getArea: function () {
  17280. var _this = this;
  17281. var latLngs = _this._measureAObjs[_this._mC].measurePoints;
  17282. var pointsCount = latLngs.length,
  17283. area = 0.0,
  17284. d2r = Math.PI / 180,
  17285. p1, p2;
  17286. if (pointsCount > 2) {
  17287. for (var i = 0; i < pointsCount; i++) {
  17288. p1 = latLngs[i];
  17289. p2 = latLngs[(i + 1) % pointsCount];
  17290. area += ((p2.lng - p1.lng) * d2r) *
  17291. (2 + Math.sin(p1.lat * d2r) + Math.sin(p2.lat * d2r));
  17292. }
  17293. area = area * 6378137.0 * 6378137.0 / 2.0;
  17294. }
  17295. area = Math.abs(area);
  17296. if (area > 1000000) {
  17297. area = (area * 0.000001).toFixed(2) + ' 平方公里';
  17298. } else {
  17299. area = area.toFixed(2) + ' 米&sup2;';
  17300. }
  17301. return area;
  17302. },
  17303. _removeMeasureGroup: function () {
  17304. var _this = this;
  17305. _this._map.doubleClickZoom.enable();
  17306. $('#' + _this._map._container.id + ' .measureArea_tips').remove();
  17307. _this._map.off('click', _this._onClickPoint, this);
  17308. },
  17309. /**
  17310. * 重启测面
  17311. * [_restartMearing description]
  17312. * @return {[type]} [description]
  17313. */
  17314. _restartMearing: function () {
  17315. var _this = this;
  17316. _this.start();
  17317. },
  17318. /**
  17319. * 删除对应iC的测距
  17320. * @type {Function}
  17321. */
  17322. del: function (mC) {
  17323. var _this = this;
  17324. /*
  17325. var event = event || window.event;
  17326. L.DomEvent.stop(event);*/
  17327. _this._measureGroup.removeLayer(_this._measureAObjs[mC].polygon);
  17328. _this._measureGroup.removeLayer(_this._measureAObjs[mC]);
  17329. delete _this._measureAObjs[mC];
  17330. },
  17331. });
  17332. L.control.measureArea = function (options) {
  17333. return new L.Control.MeasureArea(options);
  17334. }
  17335. /**
  17336. * 测量工具
  17337. */
  17338. map2DViewer.setAreaToolStyle = function (options) {
  17339. this.areaTool.addCss(options);
  17340. }
  17341. map2DViewer.areaToolFire = function (data) {};
  17342. map2DViewer.areaToolDelFire = function (data) {};
  17343. map2DViewer.measureArea = function (options) {
  17344. var defaultData = {
  17345. action: 'add',
  17346. position: 'topleft',
  17347. offset: [10, 40],
  17348. background: "#fff",
  17349. color: "#000",
  17350. font_size: "14px",
  17351. closeButton: true
  17352. }
  17353. _.merge(defaultData, options);
  17354. switch (defaultData.action) {
  17355. case 'add':
  17356. this.areaTool = new L.Control.MeasureArea({
  17357. position: defaultData.position,
  17358. offset: defaultData.offset,
  17359. background: defaultData.background,
  17360. color: defaultData.color,
  17361. font_size: defaultData.font_size,
  17362. closeButton: defaultData.closeButton
  17363. }).addTo(this.map);
  17364. this.map.on('measure-distance-result', map2DViewer.areaToolFire);
  17365. this.map.on('measure-distance-delete', map2DViewer.areaToolDelFire);
  17366. return this.areaTool;
  17367. break;
  17368. case 'restart':
  17369. if (!this.areaTool)
  17370. break;
  17371. this.areaTool._restartMearing();
  17372. break;
  17373. case 'clear':
  17374. if (!this.areaTool)
  17375. break;
  17376. this.areaTool.cleanAllMeasure();
  17377. this.areaTool._removeMeasureGroup();
  17378. this.map.removeControl(this.areaTool);
  17379. break;
  17380. case 'remove':
  17381. if (!this.areaTool)
  17382. break;
  17383. this.areaTool._removeMeasureGroup();
  17384. this.map.off('measure-distance-result', map2DViewer.areaToolFire);
  17385. this.map.off('measure-distance-delete', map2DViewer.areaToolDelFire);
  17386. break;
  17387. }
  17388. }
  17389. L.Control.MeasureDistance = L.Control.extend({
  17390. //是否初始化
  17391. _initialized: false,
  17392. //统计
  17393. _lC: 0,
  17394. //测
  17395. _measureObjs: {},
  17396. //是否完成当前测绘
  17397. _finished: true,
  17398. isNewElevation: true,
  17399. options: {
  17400. position: 'topright',
  17401. autoZIndex: true,
  17402. offset: [10, 10],
  17403. background: "#000",
  17404. color: "#fff",
  17405. size: 14,
  17406. closeButton: true,
  17407. tips: $('<div class="measureDistance_tips map2D">单击添加点,双击结束</div>')
  17408. },
  17409. initialize: function (options) {
  17410. L.setOptions(this, options);
  17411. return this;
  17412. },
  17413. onAdd: function (map) {
  17414. this._map = map;
  17415. this._addMeasureGroup();
  17416. this.start();
  17417. this._createControl();
  17418. this._map.on('measure-area-start', this.stop, this);
  17419. switch (this.options.position) {
  17420. case 'topleft':
  17421. this._container.style.marginLeft = this.options.offset[0] + 'px';
  17422. this._container.style.marginTop = this.options.offset[1] + 'px';
  17423. break;
  17424. case 'topright':
  17425. this._container.style.marginRight = this.options.offset[0] + 'px';
  17426. this._container.style.marginTop = this.options.offset[1] + 'px';
  17427. break;
  17428. case 'bottomleft':
  17429. this._container.style.marginLeft = this.options.offset[0] + 'px';
  17430. this._container.style.marginBottom = this.options.offset[1] + 'px';
  17431. break;
  17432. case 'bottomright':
  17433. this._container.style.marginRight = this.options.offset[0] + 'px';
  17434. this._container.style.marginBottom = this.options.offset[1] + 'px';
  17435. break;
  17436. }
  17437. return this._container;
  17438. },
  17439. _addTip: function (param) {
  17440. param.options.tips.appendTo(param._map.getContainer());
  17441. param._map.on('mousemove', param._onMoveLine, this);
  17442. },
  17443. _createControl: function () {
  17444. var _this = this;
  17445. this._container = L.DomUtil.create('div', 'leaflet-bar leaflet-control-measure-distance');
  17446. this._container.style.display = "none"
  17447. var link = L.DomUtil.create('a', 'leaflet-control-measure-distance-link', this._container);
  17448. link.title = '两点测量距离';
  17449. L.DomUtil.create('span', '', link);
  17450. L.DomEvent
  17451. .on(this._container, 'contextmenu', L.DomEvent.stopPropagation)
  17452. .on(link, 'click', L.DomEvent.stopPropagation)
  17453. .on(link, 'click', function () {
  17454. if (!_this._finished) {
  17455. if (_this._measureObjs[_this._lC].distancePoints.length > 0) {
  17456. _this._onFinishClick();
  17457. }
  17458. _this._finished = true;
  17459. L.DomUtil.removeClass(_this._container, 'active');
  17460. _this._removeMeasureGroup();
  17461. _this._map.fire('measure-distance-stop');
  17462. _this._map.getContainer().style.cursor = 'auto';
  17463. } else {
  17464. _this._finished = false;
  17465. L.DomUtil.addClass(_this._container, 'active');
  17466. _this._addMeasureGroup();
  17467. _this._map.fire('measure-distance-start');
  17468. if (L.Browser.ie || L.Browser.firefox) {
  17469. _this._map.getContainer().style.cursor = 'url(' + L.DefaultImagePath + '/cur-ruler.cur),auto';
  17470. } else {
  17471. _this._map.getContainer().style.cursor = 'url(' + L.DefaultImagePath + '/cur-ruler.cur) 5 5,auto';
  17472. }
  17473. }
  17474. })
  17475. },
  17476. start: function () {
  17477. var _this = this;
  17478. if (!_this._finished) {
  17479. if (_this._measureObjs[_this._lC]) {
  17480. if (_this._measureObjs[_this._lC].distancePoints) {
  17481. if (_this._measureObjs[_this._lC].distancePoints.length > 0) {
  17482. _this._onFinishClick();
  17483. }
  17484. }
  17485. }
  17486. _this._finished = true;
  17487. //L.DomUtil.removeClass(_this._container, 'active');
  17488. _this._removeMeasureGroup();
  17489. _this._map.fire('measure-distance-stop');
  17490. }
  17491. _this._finished = false;
  17492. _this._lC++;
  17493. //L.DomUtil.addClass(_this._container, 'active');
  17494. _this._addTip(_this);
  17495. _this._map.fire('measure-distance-start');
  17496. _this._map.on('click', _this._onClickPoint, this);
  17497. if (L.Browser.ie || L.Browser.firefox) {
  17498. _this._map.getContainer().style.cursor = 'url(' + L.DefaultImagePath + '/cur-ruler.cur),auto';
  17499. } else {
  17500. _this._map.getContainer().style.cursor = 'url(' + L.DefaultImagePath + '/cur-ruler.cur) 5 5,auto';
  17501. }
  17502. _this._map.doubleClickZoom.disable();
  17503. },
  17504. stopMasuring: function () {
  17505. var _this = this;
  17506. _this._finished = true;
  17507. _this._initialized = false;
  17508. //L.DomUtil.removeClass(_this._container, 'active');
  17509. _this._removeMeasureGroup();
  17510. //_this._map.getContainer().style.cursor = 'auto';
  17511. },
  17512. stop: function () {
  17513. var _this = this;
  17514. if (!_this._finished) {
  17515. if (_this._measureObjs[_this._lC].distancePoints.length > 0) {
  17516. _this._onFinishClick();
  17517. }
  17518. _this._finished = true;
  17519. //L.DomUtil.removeClass(_this._container, 'active');
  17520. _this._removeMeasureGroup();
  17521. _this._map.fire('measure-distance-stop');
  17522. _this._map.getContainer().style.cursor = 'auto';
  17523. }
  17524. },
  17525. measurePoints: function (startPoint, endPoint) {
  17526. var _this = this;
  17527. _this.start();
  17528. _this._onClickPoint({
  17529. latlng: startPoint
  17530. });
  17531. _this._onClickPoint({
  17532. latlng: endPoint
  17533. });
  17534. },
  17535. updatelC: function (lC, startPoint, endPoint) {
  17536. var _this = this;
  17537. _this._measureObjs[lC].distancePoints = [startPoint, endPoint];
  17538. _this._measureObjs[lC].linePoints = [startPoint, endPoint];
  17539. _this._measureObjs[lC].lineDistance = new L.LatLng(startPoint[0], startPoint[1]).distanceTo(new L.LatLng(endPoint[0], endPoint[1]));
  17540. var newPos = _this._getCurvePoints([new L.LatLng(startPoint[0], startPoint[1]), new L.LatLng(endPoint[0], endPoint[1])]);
  17541. _this._measureObjs[lC].polyLine.setLatLngs(newPos);
  17542. _this._measureObjs[lC].polyLine.redraw();
  17543. _this._measureObjs[lC].resultMarker.setLatLng(new L.LatLng(endPoint[0], endPoint[1]));
  17544. var lineDistance = _this._measureObjs[lC].lineDistance;
  17545. var lineDistanceStr = lineDistance > 1000 ? (lineDistance / 1000).toFixed(2) + '公里' : Math.ceil(lineDistance) + '米';
  17546. var pointAngle = L.Util.getAngleByLatLng(startPoint[1], startPoint[0], endPoint[1], endPoint[0]);
  17547. pointAngle += '度';
  17548. //添加结束信息
  17549. var pointText = L.DomUtil.create('div', 'measure-distance-result-text');
  17550. pointText.innerHTML = lineDistanceStr + '<br/>' + pointAngle;
  17551. pointText.lC = _this._lC;
  17552. L.DomEvent.on(pointText, 'dblclick', function (e) {
  17553. L.DomEvent.stopPropagation(e);
  17554. _this.del(pointText.lC)
  17555. });
  17556. _this._measureObjs[lC].removeLayer(_this._measureObjs[lC].resultMarker);
  17557. _this._measureObjs[lC].resultMarker = L.marker(endPoint, {
  17558. icon: L.divIcon({
  17559. iconSize: [5, 5]
  17560. })
  17561. }).bindLabel(pointText, {
  17562. noHide: true,
  17563. clickable: true,
  17564. className: 'measure-distance-tip',
  17565. offset: [0, 0]
  17566. }).addTo(_this._measureObjs[lC]);
  17567. _this._map.fire('measure-distance-result', {
  17568. lC: lC,
  17569. distance: lineDistanceStr,
  17570. angle: pointAngle,
  17571. distancePoints: _this._measureObjs[lC].distancePoints
  17572. });
  17573. },
  17574. /**
  17575. * 清除所有的量算
  17576. * @return {[type]} [description]
  17577. */
  17578. cleanAllMeasure: function () {
  17579. var _this = this;
  17580. for (var item in _this._measureObjs) {
  17581. _this.del(item);
  17582. }
  17583. },
  17584. _addMeasureGroup: function () {
  17585. var _this = this;
  17586. if (!_this._initialized) {
  17587. _this._measureGroup = new L.featureGroup();
  17588. _this._measureGroup.addTo(_this._map);
  17589. _this._initialized = true;
  17590. }
  17591. _this._map.doubleClickZoom.disable();
  17592. },
  17593. _removeMeasureGroup: function () {
  17594. var _this = this;
  17595. _this._map.getContainer().style.cursor = 'auto';
  17596. $('#' + _this._map._container.id + ' .measureDistance_tips').remove();
  17597. _this._map.off('mousemove', _this._onMoveLine, this);
  17598. _this._map.off('click', _this._onClickPoint, this);
  17599. },
  17600. _removeMeasure: function () {
  17601. var _this = this;
  17602. if (!_this._finished) {
  17603. if (_this._measureObjs[_this._lC]) {
  17604. if (_this._measureObjs[_this._lC].distancePoints) {
  17605. if (_this._measureObjs[_this._lC].distancePoints.length > 0) {
  17606. _this._onMoveLineRemove();
  17607. _this._onFinishClick({
  17608. latlng: _this._measureObjs[_this._lC].distancePoints[_this._measureObjs[_this._lC].distancePoints.length - 1]
  17609. });
  17610. }
  17611. }
  17612. }
  17613. _this._removeMeasureGroup();
  17614. _this._map.fire('measure-distance-stop');
  17615. } else {
  17616. _this._removeMeasureGroup();
  17617. }
  17618. },
  17619. _restartMearing: function () {
  17620. var _this = this;
  17621. _this.start()
  17622. },
  17623. /**
  17624. * 鼠标单击事件,如果是第一次,则设置为初始点 如果产生第二个点表示测量完成
  17625. * @param e
  17626. * @returns {boolean}
  17627. * @private
  17628. */
  17629. _onClickPoint: function (e) {
  17630. var _this = this;
  17631. e.latlng = L.Util.formatEarthLatLng(e.latlng);
  17632. if (_this.isNewElevation) {
  17633. //_this._lC++;
  17634. _this._measureObjs[_this._lC] = new L.FeatureGroup();
  17635. _this._measureObjs[_this._lC].tempLine = new L.Polyline([
  17636. [0, 0],
  17637. [0, 0]
  17638. ], {
  17639. clickable: false,
  17640. color: '#ff0000',
  17641. weight: 2,
  17642. opacity: 1
  17643. }).addTo(_this._measureObjs[_this._lC]);
  17644. _this._measureObjs[_this._lC].addTo(_this._measureGroup);
  17645. _this._measureObjs[_this._lC].distancePoints = [];
  17646. _this._measureObjs[_this._lC].linePoints = [];
  17647. _this._measureObjs[_this._lC].lineDistance = 0;
  17648. _this.isNewElevation = false;
  17649. }
  17650. if (_this._measureObjs[_this._lC].distancePoints.length > 0) {
  17651. _this.dblclickFirst = true;
  17652. _this._measureObjs[_this._lC].distancePoints.push(e.latlng);
  17653. var _sPoint = _this._measureObjs[_this._lC].distancePoints[_this._measureObjs[_this._lC].distancePoints.length - 2];
  17654. var qPoints = _this._getCurvePoints([_sPoint, e.latlng]);
  17655. _this._measureObjs[_this._lC].linePoints.push(qPoints);
  17656. var lineDistance = _sPoint.distanceTo(e.latlng) + _this._measureObjs[_this._lC].lineDistance;
  17657. _this._measureObjs[_this._lC].lineDistance = lineDistance;
  17658. var _lastPoint = _this._measureObjs[_this._lC].distancePoints[_this._measureObjs[_this._lC].distancePoints.length - 1];
  17659. _this._measureObjs[_this._lC].lineDistance = lineDistance;
  17660. var lineDistanceStr = lineDistance > 1000 ? (lineDistance / 1000).toFixed(2) + '公里' : Math.ceil(lineDistance) + '米';
  17661. var pointAngle = L.Util.getAngleByLatLng(_sPoint.lng, _sPoint.lat, _lastPoint.lng, _lastPoint.lat);
  17662. //添加结束信息
  17663. var oLabelObj = L.DomUtil.create('div', 'measure-distance-content');
  17664. var delLabel = L.DomUtil.create('span', 'distance-ico-del');
  17665. var pointText = L.DomUtil.create('span', 'measure-distance-result-text');
  17666. delLabel.innerHTML = '删除';
  17667. delLabel.lC = _this._lC;
  17668. L.DomEvent.on(delLabel, 'click', function (e) {
  17669. L.DomEvent.stopPropagation(e);
  17670. _this.del(delLabel.lC)
  17671. });
  17672. pointText.innerHTML = lineDistanceStr + '<br/>' + pointAngle + '度';
  17673. pointText.lC = _this._lC;
  17674. oLabelObj.appendChild(pointText);
  17675. _this._measureObjs[_this._lC].resultMarker = _this._buildMarker(_lastPoint).bindLabel(oLabelObj, {
  17676. noHide: true,
  17677. clickable: true,
  17678. className: 'measure-distance-tip',
  17679. offset: [0, 0]
  17680. }).addTo(_this._measureObjs[_this._lC]);
  17681. } else {
  17682. _this._measureObjs[_this._lC].resultMarker = _this._buildMarker(e.latlng).addTo(_this._measureObjs[_this._lC]);
  17683. _this._measureObjs[_this._lC].distancePoints.push(e.latlng);
  17684. _this._map.on('mousemove', _this._onMoveLine, this);
  17685. }
  17686. _this.editerCSS();
  17687. },
  17688. /**
  17689. * 创建一个marker 并返回该marker
  17690. * @type {Function}
  17691. * @param obj {Object} {latlng}
  17692. * @returns {L.Marker}
  17693. * @private
  17694. */
  17695. _buildMarker: function (obj) {
  17696. var _this = this;
  17697. var marker = L.marker(
  17698. obj, {
  17699. icon: L.divIcon({
  17700. iconSize: [5, 5]
  17701. })
  17702. }
  17703. );
  17704. marker.on('click', function (e) {
  17705. if (_this._measureObjs[_this._lC].distancePoints.length < 2) {
  17706. return false;
  17707. }
  17708. //与上一个点相同,测量完成
  17709. if (e.latlng == _this._measureObjs[_this._lC].distancePoints[_this._measureObjs[_this._lC].distancePoints.length - 1]) {
  17710. _this._onFinishClick(e);
  17711. return false;
  17712. }
  17713. });
  17714. return marker;
  17715. },
  17716. /**
  17717. * 给起始点和目的点的鼠标画线
  17718. * @type {Function}
  17719. * @param e
  17720. * @private
  17721. */
  17722. _onMoveLine: function (e) {
  17723. var _this = this;
  17724. var wp = _this._map.latLngToContainerPoint(e.latlng)
  17725. $(".measureDistance_tips").css({
  17726. "left": wp.x + 20,
  17727. 'top': wp.y + 10
  17728. })
  17729. if (Object.getOwnPropertyNames(_this._measureObjs).length > 0) {
  17730. if (_this._measureObjs[_this._lC]) {
  17731. if (_this._measureObjs[_this._lC].distancePoints.length > 0) {
  17732. var length = _this._measureObjs[_this._lC].distancePoints.length;
  17733. var _startPoint = _this._measureObjs[_this._lC].distancePoints[length - 2];
  17734. var _endPoint = e.latlng;
  17735. _this._drawLine(_startPoint, _endPoint);
  17736. }
  17737. }
  17738. }
  17739. },
  17740. /**
  17741. * 更新画线
  17742. * @type {Function}
  17743. * @param start {Object} 开始点
  17744. * @param end {Object} 结束点
  17745. * @private
  17746. */
  17747. _drawLine: function (start, end) {
  17748. var _this = this;
  17749. _this._measureObjs[_this._lC].distancePoints.push(end);
  17750. var newPos = _this._measureObjs[_this._lC].distancePoints;
  17751. _this._measureObjs[_this._lC].tempLine.setLatLngs(newPos);
  17752. _this._measureObjs[_this._lC].tempLine.redraw();
  17753. var length = _this._measureObjs[_this._lC].distancePoints.length;
  17754. _this._measureObjs[_this._lC].distancePoints.splice(length - 1, 1);
  17755. },
  17756. // 未完成绘制就取消绘制时,删除最后一段
  17757. _onMoveLineRemove: function () {
  17758. var _this = this
  17759. _this._measureObjs[_this._lC].tempLine.setLatLngs(_this._measureObjs[_this._lC].distancePoints);
  17760. _this._measureObjs[_this._lC].tempLine.redraw();
  17761. },
  17762. _upDateLine: function (lC) {
  17763. var _this = this;
  17764. var linePoints = _this._measureObjs[_this._lC].linePoints;
  17765. var allPoints = [];
  17766. for (var i = 0, l = linePoints.length; i < l; i++) {
  17767. allPoints = allPoints.concat(linePoints[i]);
  17768. }
  17769. if (_this._measureObjs[lC].polyLine) {
  17770. _this._measureObjs[lC].polyLine.setLatLngs(allPoints);
  17771. } else {
  17772. _this._measureObjs[lC].polyLine = L.polyline(allPoints, {
  17773. color: '#ff0000',
  17774. weight: 2,
  17775. opacity: 1,
  17776. clickable: false
  17777. })
  17778. .addTo(_this._measureObjs[lC]);
  17779. }
  17780. },
  17781. /**
  17782. * 结束当前线条画线测距
  17783. * @param e
  17784. * @private
  17785. */
  17786. _onFinishClick: function (e) {
  17787. var _this = this;
  17788. _this._map.off('click', _this._onClickPoint, this);
  17789. if (e && _this.dblclickFirst) {
  17790. _this.dblclickFirst = false;
  17791. _this._measureObjs[_this._lC].distancePoints.push(e.latlng);
  17792. var _sPoint = _this._measureObjs[_this._lC].distancePoints[_this._measureObjs[_this._lC].distancePoints.length - 3];
  17793. var qPoints = _this._getCurvePoints([_sPoint, e.latlng]);
  17794. _this._measureObjs[_this._lC].linePoints.push(qPoints);
  17795. //var lineDistance = _sPoint.distanceTo(e.latlng) + _this._measureObjs[_this._lC].lineDistance;
  17796. var lineDistance = _this._measureObjs[_this._lC].lineDistance;
  17797. _this._measureObjs[_this._lC].lineDistance = lineDistance;
  17798. var _lastPoint = _this._measureObjs[_this._lC].distancePoints[_this._measureObjs[_this._lC].distancePoints.length - 2];
  17799. _this._measureObjs[_this._lC].lineDistance = lineDistance;
  17800. var lineDistanceStr = lineDistance > 1000 ? (lineDistance / 1000).toFixed(2) + '公里' : Math.ceil(lineDistance) + '米';
  17801. var pointAngle = L.Util.getAngleByLatLng(_sPoint.lng, _sPoint.lat, _lastPoint.lng, _lastPoint.lat);
  17802. //添加结束信息
  17803. var oLabelObj = L.DomUtil.create('div', 'measure-distance-content');
  17804. var delLabel = L.DomUtil.create('div', 'distance-ico-del');
  17805. var pointText = L.DomUtil.create('span', 'measure-distance-result-text');
  17806. //delLabel.innerHTML = '删除';
  17807. delLabel.lC = _this._lC;
  17808. L.DomEvent.on(delLabel, 'click', function (e) {
  17809. L.DomEvent.stopPropagation(e);
  17810. _this.del(delLabel.lC)
  17811. });
  17812. pointText.innerHTML = lineDistanceStr + '<br/>' + pointAngle + '度';
  17813. pointText.lC = _this._lC;
  17814. L.DomEvent.on(pointText, 'dblclick', function (e) {
  17815. L.DomEvent.stopPropagation(e);
  17816. _this.del(pointText.lC)
  17817. });
  17818. oLabelObj.appendChild(pointText);
  17819. if (_this.options.closeButton) {
  17820. oLabelObj.appendChild(delLabel);
  17821. }
  17822. _this._measureObjs[_this._lC].resultMarker.unbindLabel();
  17823. _this._measureObjs[_this._lC].resultMarker = L.marker(_lastPoint, {
  17824. icon: L.divIcon({
  17825. iconSize: [5, 5]
  17826. })
  17827. }).bindLabel(oLabelObj, {
  17828. noHide: true,
  17829. clickable: true,
  17830. className: 'measure-distance-tip',
  17831. offset: [0, 0]
  17832. }).addTo(_this._measureObjs[_this._lC]);
  17833. }
  17834. _this._map.off('mousemove', _this._onMoveLine, this);
  17835. $('#' + _this._map._container.id + ' .measureDistance_tips').remove();
  17836. _this.isNewElevation = true;
  17837. _this.editerCSS();
  17838. _this.stopMasuring();
  17839. _this._restartMearing();
  17840. },
  17841. /**
  17842. * 修改测距样式
  17843. */
  17844. editerCSS: function () {
  17845. var _this = this;
  17846. $(".measure-distance-content span").css({
  17847. "color": _this.options.color,
  17848. })
  17849. $(".measure-distance-content span").css({
  17850. "font-size": _this.options.font_size,
  17851. })
  17852. $(".measure-distance-content").css({
  17853. "background": _this.options.background
  17854. });
  17855. },
  17856. /**
  17857. * 合并样式
  17858. */
  17859. addCss: function (options) {
  17860. var _this = this;
  17861. _.merge(this.options, options);
  17862. _this.editerCSS();
  17863. },
  17864. /**
  17865. * 删除对应lC的测距
  17866. */
  17867. del: function (lC) {
  17868. var _this = this;
  17869. if (_this._measureObjs[lC]) {
  17870. _this._measureGroup.removeLayer(_this._measureObjs[lC]);
  17871. delete _this._measureObjs[lC];
  17872. _this._map.fire('measure-distance-delete', {
  17873. lC: lC
  17874. });
  17875. }
  17876. },
  17877. /**
  17878. * 获取弧线的节点坐标数组
  17879. * @type {Function}
  17880. * @param points
  17881. * @returns {Array}
  17882. * @private
  17883. */
  17884. _getCurvePoints: function (points) {
  17885. var _this = this;
  17886. var curvePoints = [];
  17887. for (var i = 0; i < points.length - 1; i++) {
  17888. if (points[i]['lat'] == points[i + 1]['lat'] && points[i]['lng'] == points[i + 1]['lng']) {
  17889. curvePoints = curvePoints.concat(points[i]);
  17890. } else {
  17891. var p = _this._getCurve(points[i], points[i + 1], 20);
  17892. if (p && p.length > 0) {
  17893. curvePoints = curvePoints.concat(p);
  17894. }
  17895. }
  17896. }
  17897. return curvePoints;
  17898. },
  17899. /**
  17900. * 根据两点获取曲线坐标点数组
  17901. * @type {Function}
  17902. * @param start {Object} 起点
  17903. * @param finish {Object} 终点
  17904. * @param segments {Number} 拐点数量
  17905. * @returns {*}
  17906. * @private
  17907. */
  17908. _getCurve: function (start, finish, segments) {
  17909. var startlat = start.lat;
  17910. var startlon = start.lng;
  17911. var finishlat = finish.lat;
  17912. var finishlon = finish.lng;
  17913. var segments = segments;
  17914. var curveAry = [];
  17915. var lat1 = startlat * (Math.PI / 180);
  17916. var lon1 = startlon * (Math.PI / 180);
  17917. var lat2 = finishlat * (Math.PI / 180);
  17918. var lon2 = finishlon * (Math.PI / 180);
  17919. var d = 2 * Math.asin(Math.sqrt(Math.pow((Math.sin((lat1 - lat2) / 2)), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow((Math.sin((lon1 - lon2) / 2)), 2)));
  17920. for (var n = 0; n < segments + 1; n++) {
  17921. var f = (1 / segments) * n;
  17922. var A = Math.sin((1 - f) * d) / Math.sin(d);
  17923. var B = Math.sin(f * d) / Math.sin(d);
  17924. var x = A * Math.cos(lat1) * Math.cos(lon1) + B * Math.cos(lat2) * Math.cos(lon2);
  17925. var y = A * Math.cos(lat1) * Math.sin(lon1) + B * Math.cos(lat2) * Math.sin(lon2);
  17926. var z = A * Math.sin(lat1) + B * Math.sin(lat2);
  17927. var lat = Math.atan2(z, Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));
  17928. var lon = Math.atan2(y, x);
  17929. try {
  17930. var temp = L.latLng(lat / (Math.PI / 180), lon / (Math.PI / 180));
  17931. curveAry.push(temp);
  17932. } catch (e) {
  17933. }
  17934. }
  17935. return curveAry;
  17936. },
  17937. onRemove: function (map) {
  17938. return this;
  17939. }
  17940. });
  17941. L.control.measureDistance = function (options) {
  17942. return new L.Control.MeasureDistance(options);
  17943. }
  17944. /**
  17945. * 测量工具
  17946. */
  17947. map2DViewer.distanceToolFire = function (data) {};
  17948. map2DViewer.distanceToolDelFire = function (data) {};
  17949. map2DViewer.measureDistance = function (options) {
  17950. var defaultData = {
  17951. action: 'add',
  17952. position: 'topleft',
  17953. offset: [10, 10],
  17954. background: "#fff",
  17955. color: "#000",
  17956. font_size: "14px",
  17957. closeButton: true
  17958. }
  17959. _.merge(defaultData, options);
  17960. switch (defaultData.action) {
  17961. case 'add':
  17962. this.distanceTool = new L.Control.MeasureDistance({
  17963. position: defaultData.position,
  17964. offset: defaultData.offset,
  17965. background: defaultData.background,
  17966. color: defaultData.color,
  17967. font_size: defaultData.font_size,
  17968. closeButton: defaultData.closeButton
  17969. }).addTo(this.map);
  17970. this.map.on('measure-distance-result', map2DViewer.distanceToolFire);
  17971. this.map.on('measure-distance-delete', map2DViewer.distanceToolDelFire);
  17972. return this.distanceTool;
  17973. break;
  17974. case 'remove':
  17975. if (!this.distanceTool)
  17976. break;
  17977. this.distanceTool._removeMeasure();
  17978. this.map.doubleClickZoom.enable();
  17979. this.map.off('measure-distance-result', map2DViewer.distanceToolFire);
  17980. this.map.off('measure-distance-delete', map2DViewer.distanceToolDelFire);
  17981. break;
  17982. case 'clean':
  17983. if (!this.distanceTool)
  17984. break;
  17985. this.distanceTool.cleanAllMeasure();
  17986. this.distanceTool._removeMeasure();
  17987. this.map.doubleClickZoom.enable();
  17988. this.map.removeControl(this.distanceTool);
  17989. break;
  17990. case 'restart':
  17991. if (!this.distanceTool)
  17992. break;
  17993. this.distanceTool._restartMearing();
  17994. }
  17995. }
  17996. L.RadarCircleTimer = {
  17997. count:0,
  17998. start:0,
  17999. speed:50,
  18000. timer:null,
  18001. initialize:false,
  18002. init:function(options){
  18003. var _this = L.RadarCircleTimer;
  18004. _this.count += 1;
  18005. _this.map = options.map;
  18006. if(_this.initialize){
  18007. return true;
  18008. }
  18009. _this.initialize = true;
  18010. _this.timer = setInterval(function(){
  18011. _this.start += 5;
  18012. _this.map.fire('radarCircleTimer')
  18013. }, _this.speed);
  18014. },
  18015. clear:function(){
  18016. var _this = L.RadarCircleTimer;
  18017. _this.count -= 1;
  18018. if(_this.count == 0){
  18019. _this.timer = clearInterval(_this.timer);
  18020. _this.initialize = false;
  18021. _this.start = 0;
  18022. }
  18023. }
  18024. }
  18025. L.RadarCircle = function(options){
  18026. this._featureGroup = new L.FeatureGroup();
  18027. this.options = {
  18028. angle:30,
  18029. //speed:50,
  18030. center:[0,0],
  18031. color:'#0033ff',
  18032. opacity:0.5,
  18033. fillColor:'#0033ff',
  18034. weight:1,
  18035. fillOpacity:0.1,
  18036. radius:10000,
  18037. //start:0
  18038. }
  18039. L.setOptions(this, options);
  18040. this.wCircle = new L.circle(this.options.center,this.options.radius,this.options).addTo(this._featureGroup);
  18041. this.nCircle = new L.circle(this.options.center,this.options.radius,this.options).addTo(this._featureGroup);
  18042. this.nCircle.setStyle({
  18043. fillOpacity:0.3,
  18044. weight:0
  18045. })
  18046. var _this = this;
  18047. L.RadarCircleTimer.init({map:this.options.map})
  18048. this.options.map.on('radarCircleTimer',function(){
  18049. _this.nCircle.setDirection(L.RadarCircleTimer.start,_this.options.angle)
  18050. })
  18051. this._featureGroup.onRemove = function(){
  18052. L.RadarCircleTimer.clear();
  18053. L.FeatureGroup.prototype.onRemove.call(this, this._map);
  18054. }
  18055. this._featureGroup.bindPlabel = function(options){
  18056. _this.wCircle.bindPlabel(options);
  18057. _this._featureGroup.plabel = _this.wCircle.plabel;
  18058. }
  18059. this._featureGroup.showPlabel = function(){
  18060. _this.wCircle.showPlabel();
  18061. }
  18062. this._featureGroup.hidePlabel = function(){
  18063. _this.wCircle.hidePlabel();
  18064. }
  18065. return this._featureGroup
  18066. }
  18067. L.radarCircle = function (options) {
  18068. return new L.RadarCircle(options);
  18069. };
  18070. /**
  18071. * 设置雷达圆
  18072. * @param {[type]} options [description]
  18073. */
  18074. map2DViewer.setRadarCircle = function(options) {
  18075. var _this = map2DViewer;
  18076. var defaultData = {
  18077. action: 'add',
  18078. options: {
  18079. angle: 30,
  18080. speed: 50,
  18081. center: [0, 0],
  18082. color: '#0033ff',
  18083. opacity: 0.5,
  18084. fillColor: '#0033ff',
  18085. weight: 2,
  18086. fillOpacity: 0.1,
  18087. radius: 10000,
  18088. map: _this.map
  18089. }
  18090. }
  18091. _.merge(defaultData, options);
  18092. switch (defaultData.action) {
  18093. case 'add':
  18094. var _guid = map23DControl.buildGuid('radarCircle');
  18095. var _radarCircle = L.radarCircle(defaultData.options).addTo(_this.map);
  18096. _radarCircle.guid = _guid;
  18097. _this.circles[_guid] = _radarCircle;
  18098. return _radarCircle;
  18099. break;
  18100. case 'bringToFront':
  18101. this.circles[defaultData.guid].bringToFront();
  18102. break;
  18103. case 'bringToBack':
  18104. this.circles[defaultData.guid].bringToBack();
  18105. break;
  18106. case 'remove':
  18107. this.map.removeLayer(this.circles[defaultData.guid]);
  18108. break;
  18109. }
  18110. }
  18111. L.Control.MiniMap = L.Control.extend({
  18112. options: {
  18113. position: 'bottomright',
  18114. zoomLevelOffset: -4,
  18115. zoomLevelFixed: false,
  18116. zoomAnimation: false,
  18117. autoToggleDisplay: true,
  18118. width: 150,
  18119. height: 150,
  18120. maxWidth: 300,
  18121. minWidth: 150,
  18122. offset:[10,10],
  18123. aimingRectOptions: {color: "#ff7800", weight: 1, clickable: false},
  18124. shadowRectOptions: {color: "#00b7ef", weight: 1, clickable: false, opacity:0, fillOpacity:0}
  18125. },
  18126. hideText: '隐藏',
  18127. showText: '显示鹰眼地图',
  18128. timeOut: null,
  18129. //layer is the map layer to be shown in the minimap
  18130. initialize: function (layer, options) {
  18131. L.Util.setOptions(this, options);
  18132. //Make sure the aiming rects are non-clickable even if the user tries to set them clickable (most likely by forgetting to specify them false)
  18133. this.options.aimingRectOptions.clickable = false;
  18134. this.options.shadowRectOptions.clickable = false;
  18135. this._layer = layer;
  18136. },
  18137. onAdd: function (map) {
  18138. this._mainMap = map;
  18139. //Creating the container and stopping events from spilling through to the main map.
  18140. this._container = L.DomUtil.create('div', 'leaflet-control-minimap');
  18141. this._mapContainer = L.DomUtil.create('div', 'leaflet-control-minimap-wrap',this._container);
  18142. this._container.style.width = '26px';
  18143. this._container.style.height = '26px';
  18144. L.DomEvent.disableClickPropagation(this._container);
  18145. L.DomEvent.on(this._container, 'mousewheel', L.DomEvent.stopPropagation)
  18146. .on(this._container,'contextmenu',L.DomEvent.stopPropagation);
  18147. this._miniMap = new L.Map(this._mapContainer,
  18148. {
  18149. attributionControl: false,
  18150. zoomControl: false,
  18151. zoomAnimation: this.options.zoomAnimation,
  18152. autoToggleDisplay: this.options.autoToggleDisplay,
  18153. touchZoom: !this.options.zoomLevelFixed,
  18154. scrollWheelZoom: !this.options.zoomLevelFixed,
  18155. doubleClickZoom: !this.options.zoomLevelFixed,
  18156. boxZoom: !this.options.zoomLevelFixed,
  18157. crs: map.options.crs,
  18158. inertia:false,
  18159. fadeAnimation:false
  18160. });
  18161. this._miniMap.addLayer(this._layer);
  18162. //These bools are used to prevent infinite loops of the two maps notifying each other that they've moved.
  18163. this._mainMapMoving = false;
  18164. this._miniMapMoving = false;
  18165. //Keep a record of this to prevent auto toggling when the user explicitly doesn't want it.
  18166. this._minimized = true;
  18167. this._addToggleButton();
  18168. this._miniMap.whenReady(L.Util.bind(function () {
  18169. this._aimingRect = L.rectangle(this._mainMap.getBounds(), this.options.aimingRectOptions).addTo(this._miniMap);
  18170. this._shadowRect = L.rectangle(this._mainMap.getBounds(), this.options.shadowRectOptions).addTo(this._miniMap);
  18171. this._mainMap.on('moveend', this._onMainMapMoved, this);
  18172. this._mainMap.on('move', this._onMainMapMoving, this);
  18173. this._miniMap.on('movestart', this._onMiniMapMoveStarted, this);
  18174. this._miniMap.on('move', this._onMiniMapMoving, this);
  18175. this._miniMap.on('moveend', this._onMiniMapMoved, this);
  18176. this._mainMap.on('resize',this._onMainResize,this);
  18177. this._mainMap.on('hideMiniMap',this._minimize,this);
  18178. this._mainMap.on('miniMap:changeLayer',this.changeLayer,this);
  18179. }, this));
  18180. this._copanel = L.DomUtil.create('div','leaflet-control-minimap-copanel',this._container);
  18181. this._l_1_btn = L.DomUtil.create('span','level_1_abtn active-1',this._copanel);
  18182. this._l_1_btn.title = '1倍';
  18183. var _this = this;
  18184. L.DomEvent.on(this._l_1_btn,'click',function(){
  18185. _this.options.zoomLevelOffset = -4;
  18186. _this._miniMap.setView(_this._mainMap.getCenter(), _this._decideZoom(true));
  18187. L.DomUtil.addClass(_this._l_1_btn,'active-1');
  18188. L.DomUtil.removeClass(_this._l_2_btn,'active-2');
  18189. L.DomUtil.removeClass(_this._l_4_btn,'active-4');
  18190. });
  18191. this._l_2_btn = L.DomUtil.create('span','level_2_abtn',this._copanel);
  18192. this._l_2_btn.title = '2倍';
  18193. L.DomEvent.on(this._l_2_btn,'click',function(){
  18194. _this.options.zoomLevelOffset = -6;
  18195. _this._miniMap.setView(_this._mainMap.getCenter(), _this._decideZoom(true));
  18196. L.DomUtil.addClass(_this._l_2_btn,'active-2');
  18197. L.DomUtil.removeClass(_this._l_1_btn,'active-1');
  18198. L.DomUtil.removeClass(_this._l_4_btn,'active-4');
  18199. });
  18200. this._l_4_btn = L.DomUtil.create('span','level_4_abtn',this._copanel);
  18201. this._l_4_btn.title = '4倍';
  18202. L.DomEvent.on(this._l_4_btn,'click',function(){
  18203. _this.options.zoomLevelOffset = -8;
  18204. _this._miniMap.setView(_this._mainMap.getCenter(), _this._decideZoom(true));
  18205. L.DomUtil.addClass(_this._l_4_btn,'active-4');
  18206. L.DomUtil.removeClass(_this._l_2_btn,'active-2');
  18207. L.DomUtil.removeClass(_this._l_1_btn,'active-1');
  18208. });
  18209. switch(this.options.position){
  18210. case 'topleft':
  18211. this._container.style.marginLeft = this.options.offset[0]+'px';
  18212. this._container.style.marginTop = this.options.offset[1]+'px';
  18213. this._toggleDisplayButton.style.left = '0px';
  18214. this._toggleDisplayButton.style.top = '0px';
  18215. break;
  18216. case 'topright':
  18217. this._container.style.marginRight = this.options.offset[0]+'px';
  18218. this._container.style.marginTop = this.options.offset[1]+'px';
  18219. this._toggleDisplayButton.style.right = '0px';
  18220. this._toggleDisplayButton.style.top = '0px';
  18221. break;
  18222. case 'bottomleft':
  18223. this._container.style.marginLeft = this.options.offset[0]+'px';
  18224. this._container.style.marginBottom = this.options.offset[1]+'px';
  18225. this._toggleDisplayButton.style.bottom = '0px';
  18226. this._toggleDisplayButton.style.left = '0px';
  18227. break;
  18228. case 'bottomright':
  18229. this._container.style.marginRight = this.options.offset[0]+'px';
  18230. this._container.style.marginBottom = this.options.offset[1]+'px';
  18231. this._toggleDisplayButton.style.bottom = '0px';
  18232. this._toggleDisplayButton.style.right = '0px';
  18233. break;
  18234. }
  18235. return this._container;
  18236. },
  18237. addTo: function (map) {
  18238. L.Control.prototype.addTo.call(this, map);
  18239. //this._container.parentElement.style.marginRight = '28px';
  18240. //this._container.style.marginRight = '-28px';
  18241. return this;
  18242. },
  18243. onRemove: function () {
  18244. this._mainMap.off('moveend', this._onMainMapMoved, this);
  18245. this._mainMap.off('move', this._onMainMapMoving, this);
  18246. this._miniMap.off('moveend', this._onMiniMapMoved, this);
  18247. this._mainMap.off('resize',this._onMainResize,this);
  18248. this._mainMap.off('hideMiniMap',this._minimize,this);
  18249. this._mainMap.off('miniMap:changeLayer',this.changeLayer,this);
  18250. this._miniMap.removeLayer(this._layer);
  18251. },
  18252. _onMainResize: function(){
  18253. if(this._minimized) {
  18254. return false;
  18255. }else {
  18256. this._restore();
  18257. }
  18258. },
  18259. changeLayer: function (layer) {
  18260. this._miniMap.removeLayer(this._layer);
  18261. this._layer = layer;
  18262. this._miniMap.addLayer(this._layer);
  18263. },
  18264. _addToggleButton: function () {
  18265. this._toggleDisplayButton = this._createButton(
  18266. '', this.showText, 'leaflet-control-minimap-toggle-display minimized', this._container, this._toggleDisplayButtonClicked, this);
  18267. },
  18268. _createButton: function (html, title, className, container, fn, context) {
  18269. var link = L.DomUtil.create('a', className, container);
  18270. link.innerHTML = html;
  18271. link.title = title;
  18272. var stop = L.DomEvent.stopPropagation;
  18273. L.DomEvent
  18274. .on(link, 'click', stop)
  18275. .on(link, 'mousedown', stop)
  18276. .on(link, 'dblclick', stop)
  18277. .on(link, 'click', L.DomEvent.preventDefault)
  18278. .on(link, 'click', fn, context);
  18279. return link;
  18280. },
  18281. _toggleDisplayButtonClicked: function () {
  18282. if (!this._minimized) {
  18283. this._minimize();
  18284. this._toggleDisplayButton.title = this.showText;
  18285. }
  18286. else {
  18287. this._restore();
  18288. this._toggleDisplayButton.title = this.hideText;
  18289. }
  18290. },
  18291. _setDisplay: function (minimize) {
  18292. if (minimize != this._minimized) {
  18293. if (!this._minimized) {
  18294. this._minimize();
  18295. }
  18296. else {
  18297. this._restore();
  18298. }
  18299. }
  18300. },
  18301. _minimize: function () {
  18302. // hide the minimap
  18303. this._container.style.width = '26px';
  18304. this._container.style.height = '26px';
  18305. this._toggleDisplayButton.className += ' minimized';
  18306. //this._container.parentElement.style.marginRight = '28px';
  18307. //this._container.style.marginRight = '-28px';
  18308. this._copanel.style.display = 'none';
  18309. this._minimized = true;
  18310. },
  18311. _restore: function () {
  18312. var _this = this;
  18313. this.options.width = parseInt(this._mainMap.getContainer().offsetWidth/this._mainMap.getContainer().offsetHeight*this.options.height);
  18314. if(this.options.width > this.options.maxWidth){this.options.width = this.options.maxWidth}
  18315. if(this.options.width < this.options.minWidth){this.options.width = this.options.minWidth}
  18316. this._container.style.width = this.options.width + 'px';
  18317. this._container.style.height = this.options.height + 'px';
  18318. this._toggleDisplayButton.className = this._toggleDisplayButton.className
  18319. .replace(/(?:^|\s)minimized(?!\S)/g, '');
  18320. clearTimeout(this.timeOut);
  18321. this.timeOut = setTimeout(function(){
  18322. _this._miniMap.setView(_this._mainMap.getCenter(), _this._decideZoom(true),{animate:false,pan:{animate:false},zoom:{animate:false}}).invalidateSize();
  18323. }, 300);
  18324. //this._container.parentElement.style.marginRight = this.options.width+2 + 'px';
  18325. //this._container.style.marginRight = -this.options.width-2 + 'px';
  18326. this._copanel.style.display = 'block';
  18327. this._minimized = false;
  18328. },
  18329. _onMainMapMoved: function () {
  18330. if (!this._miniMapMoving) {
  18331. this._mainMapMoving = true;
  18332. this._miniMap.setView(this._mainMap.getCenter(), this._decideZoom(true),{animate:false,pan:{animate:false},zoom:{animate:false}});
  18333. this._setDisplay(this._decideMinimized());
  18334. } else {
  18335. this._miniMapMoving = false;
  18336. }
  18337. this._aimingRect.setBounds(this._mainMap.getBounds());
  18338. },
  18339. _onMainMapMoving: function () {
  18340. this._aimingRect.setBounds(this._mainMap.getBounds());
  18341. },
  18342. _onMiniMapMoveStarted:function () {
  18343. var lastAimingRect = this._aimingRect.getBounds();
  18344. var sw = this._miniMap.latLngToContainerPoint(lastAimingRect.getSouthWest());
  18345. var ne = this._miniMap.latLngToContainerPoint(lastAimingRect.getNorthEast());
  18346. this._lastAimingRectPosition = {sw:sw,ne:ne};
  18347. },
  18348. _onMiniMapMoving: function () {
  18349. if (!this._mainMapMoving && this._lastAimingRectPosition) {
  18350. this._shadowRect.setBounds(new L.LatLngBounds(this._miniMap.containerPointToLatLng(this._lastAimingRectPosition.sw),this._miniMap.containerPointToLatLng(this._lastAimingRectPosition.ne)));
  18351. this._shadowRect.setStyle({opacity:1,fillOpacity:0.3});
  18352. }
  18353. },
  18354. _onMiniMapMoved: function () {
  18355. if (!this._mainMapMoving) {
  18356. this._miniMapMoving = true;
  18357. this._mainMap.setView(this._miniMap.getCenter(), this._decideZoom(false));
  18358. this._shadowRect.setStyle({opacity:0,fillOpacity:0});
  18359. } else {
  18360. this._mainMapMoving = false;
  18361. }
  18362. },
  18363. _decideZoom: function (fromMaintoMini) {
  18364. if (!this.options.zoomLevelFixed) {
  18365. if (fromMaintoMini)
  18366. return this._mainMap.getZoom() + this.options.zoomLevelOffset;
  18367. else {
  18368. var currentDiff = this._miniMap.getZoom() - this._mainMap.getZoom();
  18369. var proposedZoom = this._miniMap.getZoom() - this.options.zoomLevelOffset;
  18370. var toRet;
  18371. if (currentDiff > this.options.zoomLevelOffset && this._mainMap.getZoom() < this._miniMap.getMinZoom() - this.options.zoomLevelOffset) {
  18372. //This means the miniMap is zoomed out to the minimum zoom level and can't zoom any more.
  18373. if (this._miniMap.getZoom() > this._lastMiniMapZoom) {
  18374. //This means the user is trying to zoom in by using the minimap, zoom the main map.
  18375. toRet = this._mainMap.getZoom() + 1;
  18376. //Also we cheat and zoom the minimap out again to keep it visually consistent.
  18377. this._miniMap.setZoom(this._miniMap.getZoom() -1);
  18378. } else {
  18379. //Either the user is trying to zoom out past the mini map's min zoom or has just panned using it, we can't tell the difference.
  18380. //Therefore, we ignore it!
  18381. toRet = this._mainMap.getZoom();
  18382. }
  18383. } else {
  18384. //This is what happens in the majority of cases, and always if you configure the min levels + offset in a sane fashion.
  18385. toRet = proposedZoom;
  18386. }
  18387. this._lastMiniMapZoom = this._miniMap.getZoom();
  18388. return toRet;
  18389. }
  18390. } else {
  18391. if (fromMaintoMini)
  18392. return this.options.zoomLevelFixed;
  18393. else
  18394. return this._mainMap.getZoom();
  18395. }
  18396. },
  18397. _decideMinimized: function () {
  18398. if (this._mainMap.getBounds().contains(this._miniMap.getBounds())) {
  18399. return true;
  18400. }
  18401. return this._minimized;
  18402. }
  18403. });
  18404. L.Map.mergeOptions({
  18405. miniMapControl: false
  18406. });
  18407. L.Map.addInitHook(function () {
  18408. if (this.options.miniMapControl) {
  18409. this.miniMapControl = (new L.Control.MiniMap()).addTo(this);
  18410. }
  18411. });
  18412. L.control.minimap = function (options) {
  18413. return new L.Control.MiniMap(options);
  18414. };
  18415. /**
  18416. * 设置小地图
  18417. * @param {[type]} options [description]
  18418. */
  18419. map2DViewer.setMiniMap = function(options) {
  18420. var defaultData = {
  18421. action: 'add',
  18422. layer: L.tileLayer(map23DConfig.tileServerUrl + '/gm?l={z}&x={x}&y={y}', {
  18423. minZoom: 1,
  18424. maxZoom: 19,
  18425. maxNativeZoom: 19
  18426. }),
  18427. position: 'bottomright',
  18428. offset: [10, 10],
  18429. autoToggleDisplay: true,
  18430. width: 150, //宽
  18431. height: 150, //高
  18432. maxWidth: 300, //最大宽
  18433. minWidth: 150 //最大高
  18434. }
  18435. _.merge(defaultData, options);
  18436. switch (defaultData.action) {
  18437. case 'add':
  18438. if (!this.miniMap) {
  18439. this.miniMap = new L.Control.MiniMap(defaultData.layer, {
  18440. position: defaultData.position,
  18441. offset: defaultData.offset,
  18442. autoToggleDisplay: defaultData.autoToggleDisplay,
  18443. width: defaultData.width,
  18444. height: defaultData.height,
  18445. maxWidth: defaultData.maxWidth,
  18446. minWidth: defaultData.minWidth
  18447. }).addTo(this.map);
  18448. }
  18449. return this.miniMap;
  18450. break;
  18451. case 'remove':
  18452. this.map.removeControl(this.miniMap);
  18453. break;
  18454. }
  18455. }
  18456. L.Control.DrawCircles = L.Control.extend({
  18457. //是否初始化
  18458. _initialized:false,
  18459. //是否完成当前测绘
  18460. _finished:true,
  18461. curcircles:null,
  18462. circlesdata:{
  18463. startpoint:null,
  18464. stoppoint:null,
  18465. radius:null,
  18466. },
  18467. options:{
  18468. position:'topright',
  18469. autoZIndex:true,
  18470. offset:[10,40]
  18471. },
  18472. initialize:function(options){
  18473. L.setOptions(this, options);
  18474. return this;
  18475. },
  18476. onAdd:function(map){
  18477. this._map = map;
  18478. this._createControl();
  18479. switch(this.options.position){
  18480. case 'topleft':
  18481. this._container.style.marginLeft = this.options.offset[0]+'px';
  18482. this._container.style.marginTop = this.options.offset[1]+'px';
  18483. break;
  18484. case 'topright':
  18485. this._container.style.marginRight = this.options.offset[0]+'px';
  18486. this._container.style.marginTop = this.options.offset[1]+'px';
  18487. break;
  18488. case 'bottomleft':
  18489. this._container.style.marginLeft = this.options.offset[0]+'px';
  18490. this._container.style.marginBottom = this.options.offset[1]+'px';
  18491. break;
  18492. case 'bottomright':
  18493. this._container.style.marginRight = this.options.offset[0]+'px';
  18494. this._container.style.marginBottom = this.options.offset[1]+'px';
  18495. break;
  18496. }
  18497. return this._container;
  18498. },
  18499. _createControl:function(){
  18500. var _this = this;
  18501. this._container = L.DomUtil.create('div','leaflet-bar leaflet-control-measure-drawcircles');
  18502. var link = L.DomUtil.create('a','leaflet-control-measure-drawcircles-link',this._container);
  18503. link.title = '画圆';
  18504. var drawSpan = L.DomUtil.create('span','',link);
  18505. drawSpan.innerHTML = "圆";
  18506. L.DomEvent
  18507. .on(this._container,'contextmenu',L.DomEvent.stopPropagation)
  18508. .on(link,'click', L.DomEvent.stopPropagation)
  18509. .on(link,'click',function(){
  18510. _this.start();
  18511. })
  18512. },
  18513. start:function(){
  18514. var _this = this;
  18515. L.DomUtil.addClass(_this._container,'active');
  18516. if(L.Browser.ie || L.Browser.firefox){
  18517. _this._map.getContainer().style.cursor = 'url('+L.DefaultImagePath+'/cur-ruler.cur),auto';
  18518. }else{
  18519. _this._map.getContainer().style.cursor = 'url('+L.DefaultImagePath+'/cur-ruler.cur) 5 5,auto';
  18520. }
  18521. map2DViewer.map.on('measure-drawCircle-result', map2DViewer.drawCircleResult);
  18522. _this._map.dragging.disable();
  18523. _this._map.on("mousedown",_this.circleMousedown,this)
  18524. .on("mouseup",_this.circleUp,this);
  18525. },
  18526. //画圆结束
  18527. stop:function(){
  18528. var _this = this;
  18529. map2DViewer.map.getContainer().style.cursor = 'auto';
  18530. _this._map.dragging.enable();
  18531. _this._map.off("mousedown",_this.circleMousedown,this)
  18532. .off("mousemove",_this.circleMove,this)
  18533. .off("mouseup",_this.circleUp,this);
  18534. _this._map.fire('measure-drawCircle-result',_this.circlesdata);
  18535. if(_this.curcircles){
  18536. _this._map.removeLayer(_this.curcircles);
  18537. }
  18538. },
  18539. circleUp:function(){
  18540. var _this = this;
  18541. _this._map.dragging.enable();
  18542. _this._map.off("mousedown",_this.circleMousedown,this)
  18543. .off("mousemove",_this.circleMove,this)
  18544. .off("mouseup",_this.circleUp,this);
  18545. _this._map.fire('measure-drawCircle-result',_this.circlesdata);
  18546. _this._map.off('measure-drawCircle-result', map2DViewer.drawCircleResult);
  18547. _this._map.removeLayer(_this.curcircles);
  18548. map2DViewer.map.getContainer().style.cursor = 'auto';
  18549. },
  18550. circleMousedown:function(e){
  18551. var _this = this;
  18552. _this.circlesdata.startpoint = [e.latlng.lat,e.latlng.lng];
  18553. _this.curcircles = L.circle(
  18554. _this.circlesdata.startpoint,
  18555. 0,
  18556. {
  18557. color: '#ff0000',
  18558. weight: 3,
  18559. fillColor: '#ff6600',
  18560. opacity: 0.7,
  18561. fillOpacity: 0.2,
  18562. }
  18563. ).addTo(_this._map);
  18564. _this._map.on("mousemove",_this.circleMove,this);
  18565. },
  18566. circleMove:function(e){
  18567. var _this = this;
  18568. _this.circlesdata.stoppoint = [e.latlng.lat,e.latlng.lng];
  18569. var distance = new L.LatLng(_this.circlesdata.startpoint[1],_this.circlesdata.startpoint[0]).distanceTo(new L.LatLng(_this.circlesdata.stoppoint[1],_this.circlesdata.stoppoint[0]));
  18570. _this.curcircles.setRadius(distance);
  18571. _this.circlesdata.radius = distance;
  18572. }
  18573. });
  18574. L.control.drawcircles = function(options){
  18575. return new L.Control.DrawCircles(options);
  18576. }
  18577. //2D画圆
  18578. map2DViewer.drawCircleResult = function(data) {};
  18579. map2DViewer.drawCircle = function(options){
  18580. this.DrawCircles = new L.Control.DrawCircles({
  18581. position: 'topleft',
  18582. autoZIndex:true,
  18583. offset:[150,50]
  18584. }).addTo(this.map);
  18585. }
  18586. map2DViewer.removeCircle = function(){
  18587. this.DrawCircles.stop();
  18588. this.map.removeControl(this.DrawCircles);
  18589. }
  18590. L.Control.Drawpolygon = L.Control.extend({
  18591. //是否初始化
  18592. _initialized:false,
  18593. //统计
  18594. _pmC:0,
  18595. //marker统计
  18596. DrawAreaMarker:{},
  18597. //测
  18598. _measureDrawObjs:{},
  18599. //是否完成当前测绘
  18600. _finished:true,
  18601. /**
  18602. * 是否是新的测量事件
  18603. * @type {Boolean}
  18604. * @default true
  18605. * @private
  18606. */
  18607. _isNewMeasure:true,
  18608. options:{
  18609. position:'topright',
  18610. autoZIndex:true,
  18611. offset:[10,40]
  18612. },
  18613. initialize:function(options){
  18614. L.setOptions(this, options);
  18615. return this;
  18616. },
  18617. onAdd:function(map){
  18618. this._map = map;
  18619. this._createControl();
  18620. this._map.on('measure-drawpolygon-start',this.stop,this);
  18621. switch(this.options.position){
  18622. case 'topleft':
  18623. this._container.style.marginLeft = this.options.offset[0]+'px';
  18624. this._container.style.marginTop = this.options.offset[1]+'px';
  18625. break;
  18626. case 'topright':
  18627. this._container.style.marginRight = this.options.offset[0]+'px';
  18628. this._container.style.marginTop = this.options.offset[1]+'px';
  18629. break;
  18630. case 'bottomleft':
  18631. this._container.style.marginLeft = this.options.offset[0]+'px';
  18632. this._container.style.marginBottom = this.options.offset[1]+'px';
  18633. break;
  18634. case 'bottomright':
  18635. this._container.style.marginRight = this.options.offset[0]+'px';
  18636. this._container.style.marginBottom = this.options.offset[1]+'px';
  18637. break;
  18638. }
  18639. return this._container;
  18640. },
  18641. _createControl:function(){
  18642. var _this = this;
  18643. this._container = L.DomUtil.create('div','leaflet-bar leaflet-control-measure-drawpolygon');
  18644. var link = L.DomUtil.create('a','leaflet-control-measure-drawpolygon-link',this._container);
  18645. link.title = '画面';
  18646. var drawSpan = L.DomUtil.create('span','',link);
  18647. drawSpan.innerHTML = "面";
  18648. L.DomEvent
  18649. .on(this._container,'contextmenu',L.DomEvent.stopPropagation)
  18650. .on(link,'click', L.DomEvent.stopPropagation)
  18651. .on(link,'click',function(){
  18652. _this.start();
  18653. })
  18654. },
  18655. _addMeasureGroup:function(){
  18656. var _this = this;
  18657. if(!_this._initialized){
  18658. _this._measureGroup = new L.featureGroup();
  18659. _this._measureGroup.addTo(_this._map);
  18660. _this._initialized = true;
  18661. }
  18662. _this._map.doubleClickZoom.disable();
  18663. _this._map.on('click',_this._onClickPoint,this);
  18664. },
  18665. /**
  18666. * 鼠标移动重绘多边形 //todo 这里应该 新建立一个临时 坐标组
  18667. * @type {Function}
  18668. * @param e
  18669. * @private
  18670. */
  18671. _onMovePoint:function(e){
  18672. var _this = this;
  18673. var tempPoint = [];
  18674. tempPoint = _this._measureDrawObjs[_this._pmC].measurePoints.concat();
  18675. _this._measureDrawObjs[_this._pmC].measurePoints.push(e.latlng);
  18676. _this._drawPolygon();
  18677. _this._measureDrawObjs[_this._pmC].measurePoints = tempPoint.concat();
  18678. },
  18679. /**
  18680. * 鼠标单击添加多边形的点
  18681. * @type {Function}
  18682. * @param e
  18683. * @private
  18684. */
  18685. _onClickPoint:function(e){
  18686. var _this = this;
  18687. e.latlng = L.Util.formatEarthLatLng(e.latlng);
  18688. if(_this._isNewMeasure){
  18689. _this._pmC++;
  18690. _this._measureDrawObjs[_this._pmC] = new L.FeatureGroup();
  18691. _this._measureDrawObjs[_this._pmC].addTo(_this._measureGroup);
  18692. _this._measureDrawObjs[_this._pmC].measurePoints = [];
  18693. _this._measureDrawObjs[_this._pmC].polygon = new L.polygon([[0,0],[0,0],[0,0]],{fillColor:_this.options.properties.fillColor,color:_this.options.properties.color,opacity:_this.options.properties.opacity,weight:_this.options.properties.weight});
  18694. _this._measureDrawObjs[_this._pmC].polygon.addTo(_this._measureGroup);
  18695. //_this._measureDrawObjs[_this._pmC].polygon.on('click',_this._onClickPoint,this);
  18696. _this._isNewMeasure = false;
  18697. }
  18698. _this._measureDrawObjs[_this._pmC].measurePoints.push(e.latlng);
  18699. if(_this._measureDrawObjs[_this._pmC].measurePoints.length > 1){
  18700. _this._drawPolygon();
  18701. _this._map.on('mousemove',_this._onMovePoint,this);
  18702. }
  18703. _this._buildMarker(e).addTo(_this._measureDrawObjs[_this._pmC]);
  18704. },
  18705. /**
  18706. * 鼠标双击结束多边形点添加
  18707. * @type {Function}
  18708. * @param e
  18709. * @private
  18710. */
  18711. stop:function(e){
  18712. var _this = this;
  18713. if(e){
  18714. _this._map.off('mousemove',_this._onMovePoint,this);
  18715. _this._measureDrawObjs[_this._pmC].measurePoints.push(e.latlng);
  18716. if(_this._measureDrawObjs[_this._pmC].measurePoints.length > 1){
  18717. _this._drawPolygon();
  18718. }
  18719. _this._measureDrawObjs[_this._pmC].polygon.off('click',_this._onClickPoint,this);
  18720. _this._isNewMeasure = true;
  18721. _this._map.fire('measure-drawpolygon-result',{options:_this.options.properties,coordinates:_this._measureDrawObjs[_this._pmC].measurePoints});
  18722. _this._removeMeasureGroup();
  18723. _this._measureGroup.removeLayer(_this._measureDrawObjs[_this._pmC].polygon);
  18724. _this._measureGroup.removeLayer(_this._measureDrawObjs[_this._pmC]);
  18725. delete _this._measureDrawObjs[_this._pmC];
  18726. _this._finished = true;
  18727. _this._removeMeasureGroup();
  18728. _this._map.getContainer().style.cursor = 'auto';
  18729. }else{
  18730. if(_this._measureDrawObjs[_this._pmC]){
  18731. _this._map.off('mousemove',_this._onMovePoint,this);
  18732. _this._removeMeasureGroup();
  18733. _this._isNewMeasure = true;
  18734. _this._measureGroup.removeLayer(_this._measureDrawObjs[_this._pmC].polygon);
  18735. _this._measureGroup.removeLayer(_this._measureDrawObjs[_this._pmC]);
  18736. delete _this._measureDrawObjs[_this._pmC];
  18737. _this._finished = true;
  18738. _this._removeMeasureGroup();
  18739. _this._map.getContainer().style.cursor = 'auto';
  18740. }else{
  18741. _this._map.getContainer().style.cursor = 'auto';
  18742. }
  18743. }
  18744. _this._map.off('measure-drawpolygon-result', map2DViewer.drawpolygonFire);
  18745. },
  18746. start:function(){
  18747. var _this = this;
  18748. if(!_this._finished){
  18749. _this._finished = true;
  18750. L.DomUtil.removeClass(_this._container,'active');
  18751. _this._removeMeasureGroup();
  18752. _this._map.getContainer().style.cursor = 'auto';
  18753. }else {
  18754. _this._finished = false;
  18755. L.DomUtil.addClass(_this._container,'active');
  18756. _this._addMeasureGroup();
  18757. if(L.Browser.ie || L.Browser.firefox){
  18758. _this._map.getContainer().style.cursor = 'url('+L.DefaultImagePath+'/cur-ruler.cur),auto';
  18759. }else{
  18760. _this._map.getContainer().style.cursor = 'url('+L.DefaultImagePath+'/cur-ruler.cur) 5 5,auto';
  18761. }
  18762. _this._map.on('measure-drawpolygon-result', map2DViewer.drawpolygonFire);
  18763. }
  18764. },
  18765. /**
  18766. * 重绘多边形
  18767. * @type {Function}
  18768. * @private
  18769. */
  18770. _drawPolygon:function(){
  18771. var _this = this;
  18772. _this._measureDrawObjs[_this._pmC].polygon.setLatLngs(_this._measureDrawObjs[_this._pmC].measurePoints);
  18773. _this._measureDrawObjs[_this._pmC].polygon.redraw();
  18774. },
  18775. /**
  18776. * 创建一个marker 并返回该marker
  18777. * @type {Function}
  18778. * @param obj {Object} {latlng}
  18779. * @returns {L.Marker}
  18780. * @private
  18781. */
  18782. _buildMarker:function(obj){
  18783. var _this = this;
  18784. var marker = new L.Marker(
  18785. obj.latlng,
  18786. {icon: L.divIcon({
  18787. //className: 'my-div-icon1',
  18788. //iconUrl: L.DefaultImagePath+'/icon-linePoint.png',
  18789. iconSize: [5, 5]
  18790. })}
  18791. );
  18792. marker.on('dblclick',function(e){
  18793. if(_this._measureDrawObjs[_this._pmC].measurePoints.length<2){
  18794. return false;
  18795. }
  18796. //与上一个点相同,测量完成
  18797. //if(e.latlng == _this._measureDrawObjs[_this._pmC].measurePoints[_this._measureDrawObjs[_this._pmC].measurePoints.length-1] ){
  18798. _this.stop({latlng:_this._measureDrawObjs[_this._pmC].measurePoints[_this._measureDrawObjs[_this._pmC].measurePoints.length-1]});
  18799. return false;
  18800. //}
  18801. });
  18802. return marker;
  18803. },
  18804. _removeMeasureGroup:function(){
  18805. var _this = this;
  18806. _this._map.doubleClickZoom.enable();
  18807. _this._map.off('click',_this._onClickPoint,this);
  18808. },
  18809. });
  18810. L.control.drawpolygon = function(options){
  18811. return new L.Control.Drawpolygon(options);
  18812. }
  18813. // 地图上画面
  18814. map2DViewer.drawpolygonFire = function(data) {};
  18815. map2DViewer.setDrawPolygon = function(options) {
  18816. var defaultData = {
  18817. action: 'add',
  18818. position: 'topleft',
  18819. offset: [10, 10],
  18820. properties: {
  18821. color: '#ff0000',
  18822. weight: 3,
  18823. fillColor: '#ff6600',
  18824. opacity: 1,
  18825. fillOpacity: 0.5
  18826. },
  18827. }
  18828. _.merge(defaultData, options);
  18829. switch (defaultData.action) {
  18830. case 'add':
  18831. this.drawpolygon = new L.Control.Drawpolygon({
  18832. position: defaultData.position,
  18833. offset: defaultData.offset,
  18834. properties: defaultData.properties,
  18835. }).addTo(this.map);
  18836. return this.drawpolygon;
  18837. break;
  18838. case 'add_start':
  18839. this.drawpolygon = new L.Control.Drawpolygon({
  18840. position: defaultData.position,
  18841. offset: defaultData.offset,
  18842. properties: defaultData.properties,
  18843. }).addTo(this.map);
  18844. this.drawpolygon.start();
  18845. return this.drawpolygon;
  18846. break;
  18847. case 'stop':
  18848. this.drawpolygon.stop();
  18849. case 'remove':
  18850. this.map.removeControl(this.drawpolygon);
  18851. break;
  18852. }
  18853. }
  18854. L.Control.DrawPolyline = L.Control.extend({
  18855. //是否初始化
  18856. _initialized:false,
  18857. //是否完成当前测绘
  18858. _finished:true,
  18859. polylines:null,
  18860. polylinesdata:{
  18861. latlng:[],
  18862. _latlng:[]
  18863. },
  18864. options:{
  18865. position:'topright',
  18866. autoZIndex:true,
  18867. offset:[10,40]
  18868. },
  18869. initialize:function(options){
  18870. L.setOptions(this, options);
  18871. return this;
  18872. },
  18873. onAdd:function(map){
  18874. this._map = map;
  18875. this._createControl();
  18876. switch(this.options.position){
  18877. case 'topleft':
  18878. this._container.style.marginLeft = this.options.offset[0]+'px';
  18879. this._container.style.marginTop = this.options.offset[1]+'px';
  18880. break;
  18881. case 'topright':
  18882. this._container.style.marginRight = this.options.offset[0]+'px';
  18883. this._container.style.marginTop = this.options.offset[1]+'px';
  18884. break;
  18885. case 'bottomleft':
  18886. this._container.style.marginLeft = this.options.offset[0]+'px';
  18887. this._container.style.marginBottom = this.options.offset[1]+'px';
  18888. break;
  18889. case 'bottomright':
  18890. this._container.style.marginRight = this.options.offset[0]+'px';
  18891. this._container.style.marginBottom = this.options.offset[1]+'px';
  18892. break;
  18893. }
  18894. return this._container;
  18895. },
  18896. _createControl:function(){
  18897. var _this = this;
  18898. this._container = L.DomUtil.create('div','leaflet-bar leaflet-control-polylines');
  18899. var link = L.DomUtil.create('a','leaflet-control-polylines-link',this._container);
  18900. link.title = '画线';
  18901. var drawSpan = L.DomUtil.create('span','',link);
  18902. drawSpan.innerHTML = "线";
  18903. L.DomEvent
  18904. .on(this._container,'contextmenu',L.DomEvent.stopPropagation)
  18905. .on(link,'click', L.DomEvent.stopPropagation)
  18906. .on(link,'click',function(){
  18907. _this.start();
  18908. })
  18909. },
  18910. start:function(){
  18911. var _this = this;
  18912. _this.polylinesdata.latlng = [];
  18913. _this.polylinesdata._latlng = [];
  18914. L.DomUtil.addClass(_this._container,'active');
  18915. if(L.Browser.ie || L.Browser.firefox){
  18916. _this._map.getContainer().style.cursor = 'url('+L.DefaultImagePath+'/cur-ruler.cur),auto';
  18917. }else{
  18918. _this._map.getContainer().style.cursor = 'url('+L.DefaultImagePath+'/cur-ruler.cur) 5 5,auto';
  18919. }
  18920. _this._map.doubleClickZoom.disable();
  18921. map2DViewer.map.on('measure-polylines-result', map2DViewer.drawpolylineFire);
  18922. _this._map.on("click",_this.polylineMouseclick,this)
  18923. .on("dblclick",_this.polylineDblclick,this);
  18924. },
  18925. polylineDblclick:function(){
  18926. var _this = this;
  18927. _this._map.doubleClickZoom.enable();
  18928. _this._map.off("click",_this.polylineMouseclick,this)
  18929. .off("mousemove",_this.polylineMove,this)
  18930. .off("dblclick",_this.polylineDblclick,this);
  18931. _this._map.fire('measure-polylines-result',_this.polylinesdata._latlng);
  18932. _this._map.off('measure-polylines-result', map2DViewer.drawPolylinesResult);
  18933. _this._map.removeLayer(_this.polylines);
  18934. map2DViewer.map.getContainer().style.cursor = 'auto';
  18935. },
  18936. stop:function(){
  18937. var _this = this;
  18938. _this._map.doubleClickZoom.enable();
  18939. _this._map.off("click",_this.polylineMouseclick,this)
  18940. .off("mousemove",_this.polylineMove,this)
  18941. .off("dblclick",_this.polylineDblclick,this);
  18942. _this._map.off('measure-polylines-result', map2DViewer.drawPolylinesResult);
  18943. if(_this.polylines){
  18944. _this._map.removeLayer(_this.polylines);
  18945. }
  18946. map2DViewer.map.getContainer().style.cursor = 'auto';
  18947. },
  18948. polylineMouseclick:function(e){
  18949. var _this = this;
  18950. _this.polylinesdata.latlng.push([e.latlng.lat,e.latlng.lng]);
  18951. _this.polylinesdata._latlng.push([e.latlng.lng,e.latlng.lat]);
  18952. if(_this.polylinesdata.latlng.length<2){
  18953. _this.polylines = L.polyline(
  18954. _this.polylinesdata.latlng,
  18955. {
  18956. color: '#ff0000',
  18957. weight: 3,
  18958. opacity: 0.7,
  18959. }
  18960. ).addTo(_this._map);
  18961. _this._map.on("mousemove",_this.polylineMove,this);
  18962. }else{
  18963. _this.polylines.setLatLngs(_this.polylinesdata.latlng);
  18964. }
  18965. },
  18966. polylineMove:function(e){
  18967. var _this = this;
  18968. var movelatlng = [e.latlng.lat,e.latlng.lng];
  18969. _this.polylinesdata.latlng.push(movelatlng);
  18970. _this.polylinesdata._latlng.push([e.latlng.lng,e.latlng.lat]);
  18971. _this.polylines.setLatLngs(_this.polylinesdata.latlng);
  18972. var latlng_length = _this.polylinesdata.latlng.length-1;
  18973. _this.polylinesdata.latlng.splice(latlng_length,1);
  18974. _this.polylinesdata._latlng.splice(latlng_length,1);
  18975. }
  18976. });
  18977. L.control.drawpolyline = function(options){
  18978. return new L.Control.DrawPolyline(options);
  18979. }
  18980. //地图画线
  18981. map2DViewer.drawpolylineFire = function(data) {};
  18982. map2DViewer.setDrawPolyline = function(options) {
  18983. var defaultData = {
  18984. action: 'add',
  18985. position: 'topleft',
  18986. offset: [10, 10],
  18987. properties: {
  18988. color: '#ff0000',
  18989. weight: 3,
  18990. opacity: 1,
  18991. },
  18992. }
  18993. _.merge(defaultData, options);
  18994. switch (defaultData.action) {
  18995. case 'add':
  18996. this.drawpolyline = new L.Control.DrawPolyline({
  18997. position: defaultData.position,
  18998. offset: defaultData.offset,
  18999. properties: defaultData.properties,
  19000. }).addTo(this.map);
  19001. return this.drawpolyline;
  19002. break;
  19003. case 'add_start':
  19004. this.drawpolyline = new L.Control.DrawPolyline({
  19005. position: defaultData.position,
  19006. offset: defaultData.offset,
  19007. properties: defaultData.properties,
  19008. }).addTo(this.map);
  19009. this.drawpolyline.start();
  19010. return this.drawpolyline;
  19011. break;
  19012. case 'remove':
  19013. this.map.removeControl(this.drawpolyline);
  19014. break;
  19015. }
  19016. }
  19017. L.Control.DrawRectangle = L.Control.extend({
  19018. //是否初始化
  19019. _initialized:false,
  19020. //是否完成当前测绘
  19021. _finished:true,
  19022. drawrectangle:null,
  19023. drawrectangledata:{
  19024. _latlng:[],
  19025. bounds:[]
  19026. },
  19027. options:{
  19028. position:'topright',
  19029. autoZIndex:true,
  19030. offset:[10,40]
  19031. },
  19032. initialize:function(options){
  19033. L.setOptions(this, options);
  19034. return this;
  19035. },
  19036. onAdd:function(map){
  19037. this._map = map;
  19038. this._createControl();
  19039. switch(this.options.position){
  19040. case 'topleft':
  19041. this._container.style.marginLeft = this.options.offset[0]+'px';
  19042. this._container.style.marginTop = this.options.offset[1]+'px';
  19043. break;
  19044. case 'topright':
  19045. this._container.style.marginRight = this.options.offset[0]+'px';
  19046. this._container.style.marginTop = this.options.offset[1]+'px';
  19047. break;
  19048. case 'bottomleft':
  19049. this._container.style.marginLeft = this.options.offset[0]+'px';
  19050. this._container.style.marginBottom = this.options.offset[1]+'px';
  19051. break;
  19052. case 'bottomright':
  19053. this._container.style.marginRight = this.options.offset[0]+'px';
  19054. this._container.style.marginBottom = this.options.offset[1]+'px';
  19055. break;
  19056. }
  19057. return this._container;
  19058. },
  19059. _createControl:function(){
  19060. var _this = this;
  19061. this._container = L.DomUtil.create('div','leaflet-bar leaflet-control-drawrectangle');
  19062. var link = L.DomUtil.create('a','leaflet-control-drawrectangle-link',this._container);
  19063. link.title = '画矩形';
  19064. var drawSpan = L.DomUtil.create('span','',link);
  19065. drawSpan.innerHTML = "矩";
  19066. L.DomEvent
  19067. .on(this._container,'contextmenu',L.DomEvent.stopPropagation)
  19068. .on(link,'click', L.DomEvent.stopPropagation)
  19069. .on(link,'click',function(){
  19070. _this.start();
  19071. })
  19072. },
  19073. start:function(){
  19074. var _this = this;
  19075. L.DomUtil.addClass(_this._container,'active');
  19076. if(L.Browser.ie || L.Browser.firefox){
  19077. _this._map.getContainer().style.cursor = 'url('+L.DefaultImagePath+'/cur-ruler.cur),auto';
  19078. }else{
  19079. _this._map.getContainer().style.cursor = 'url('+L.DefaultImagePath+'/cur-ruler.cur) 5 5,auto';
  19080. }
  19081. map2DViewer.map.on('measure-drawrectangle-result', map2DViewer.drawrectangleFire);
  19082. _this._map.dragging.disable();
  19083. _this._map.on("mousedown",_this.rectangleMousedown,this)
  19084. .on("mouseup",_this.rectangleUp,this);
  19085. },
  19086. stop:function(){
  19087. var _this = this;
  19088. _this._map.dragging.enable();
  19089. map2DViewer.map.getContainer().style.cursor = 'auto';
  19090. _this._map.off("mousedown",_this.rectangleMousedown,this)
  19091. .off("mousemove",_this.rectangleMove,this)
  19092. .off("mouseup",_this.rectangleUp,this);
  19093. _this._map.off('measure-drawrectangle-result', map2DViewer.drawrectangleFire);
  19094. if(_this.rectangle){
  19095. _this._map.removeLayer(_this.rectangle);
  19096. }
  19097. },
  19098. rectangleUp:function(){
  19099. var _this = this;
  19100. _this._map.dragging.enable();
  19101. _this._map.off("mousedown",_this.rectangleMousedown,this)
  19102. .off("mousemove",_this.rectangleMove,this)
  19103. .off("mouseup",_this.rectangleUp,this);
  19104. var recdata = _this.drawrectangledata.bounds;
  19105. map2DViewer.map.getContainer().style.cursor = 'auto';
  19106. _this._map.removeLayer(_this.rectangle);
  19107. if(recdata.length<2){
  19108. return;
  19109. }
  19110. _this.drawrectangledata._latlng = [];
  19111. _this.drawrectangledata._latlng.push([recdata[0][1],recdata[0][0]]);
  19112. _this.drawrectangledata._latlng.push([recdata[0][1],recdata[1][0]]);
  19113. _this.drawrectangledata._latlng.push([recdata[1][1],recdata[1][0]]);
  19114. _this.drawrectangledata._latlng.push([recdata[1][1],recdata[0][0]]);
  19115. _this._map.fire('measure-drawrectangle-result',_this.drawrectangledata);
  19116. _this._map.off('measure-drawrectangle-result', map2DViewer.drawrectangleFire);
  19117. },
  19118. rectangleMousedown:function(e){
  19119. var _this = this;
  19120. _this.drawrectangledata.bounds[0] = [e.latlng.lat,e.latlng.lng];
  19121. _this.rectangle = L.rectangle(
  19122. _this.drawrectangledata.bounds,
  19123. {
  19124. color: '#ff0000',
  19125. weight: 3,
  19126. fillColor: '#ff6600',
  19127. opacity: 0.7,
  19128. fillOpacity: 0.2,
  19129. }
  19130. ).addTo(_this._map);
  19131. _this._map.on("mousemove",_this.rectangleMove,this);
  19132. },
  19133. rectangleMove:function(e){
  19134. var _this = this;
  19135. _this.drawrectangledata.bounds[1] = [e.latlng.lat,e.latlng.lng];
  19136. _this.rectangle.setBounds(_this.drawrectangledata.bounds);
  19137. }
  19138. });
  19139. L.control.drawrectangle = function(options){
  19140. return new L.Control.DrawRectangle(options);
  19141. }
  19142. //地图画矩形
  19143. map2DViewer.drawrectangleFire = function(data) {};
  19144. map2DViewer.setDrawRectangle = function(options) {
  19145. var defaultData = {
  19146. action: 'add',
  19147. position: 'topleft',
  19148. offset: [10, 10],
  19149. properties: {
  19150. color: '#ff0000',
  19151. weight: 3,
  19152. opacity: 1,
  19153. },
  19154. }
  19155. _.merge(defaultData, options);
  19156. switch (defaultData.action) {
  19157. case 'add':
  19158. this.drawrectangle = new L.Control.DrawRectangle({
  19159. position: defaultData.position,
  19160. offset: defaultData.offset,
  19161. properties: defaultData.properties,
  19162. }).addTo(this.map);
  19163. return this.drawrectangle;
  19164. break;
  19165. case 'add_start':
  19166. this.drawrectangle = new L.Control.DrawRectangle({
  19167. position: defaultData.position,
  19168. offset: defaultData.offset,
  19169. properties: defaultData.properties,
  19170. }).addTo(this.map);
  19171. this.drawrectangle.start();
  19172. return this.drawrectangle;
  19173. break;
  19174. case 'remove':
  19175. this.drawrectangle.stop();
  19176. this.map.removeControl(this.drawrectangle);
  19177. break;
  19178. }
  19179. }
  19180. L.Control.AltitudeTool = L.Control.extend({
  19181. /**
  19182. * 线条统计
  19183. * @type {Number}
  19184. * @default 0
  19185. * @private
  19186. */
  19187. _lC:0,
  19188. /**
  19189. * 量算集合
  19190. * @type {Object}
  19191. * @default {}
  19192. * @private
  19193. */
  19194. _altitudeObjs:{},
  19195. /**
  19196. * 点和线容器
  19197. * @type {Object}
  19198. * @private
  19199. */
  19200. _altitudeGroup: new L.FeatureGroup(),
  19201. /**
  19202. * 正在进行量算的
  19203. * @type {[type]}
  19204. */
  19205. _curElevIC:null,
  19206. /**
  19207. * 是否是新的量算事件
  19208. * @type {Boolean}
  19209. * @default true
  19210. * @private
  19211. */
  19212. _isNewaltitude:true,
  19213. /**
  19214. * 布局参数
  19215. * @type {Object}
  19216. */
  19217. options:{
  19218. position:'topright',
  19219. autoZIndex:true,
  19220. offset:[10,10]
  19221. },
  19222. initialize:function(options){
  19223. L.setOptions(this, options);
  19224. return this;
  19225. },
  19226. onAdd:function(map){
  19227. this._map = map;
  19228. this._altitudeGroup.addTo(this._map);
  19229. this._createControl();
  19230. switch(this.options.position){
  19231. case 'topleft':
  19232. this._container.style.marginLeft = this.options.offset[0]+'px';
  19233. this._container.style.marginTop = this.options.offset[1]+'px';
  19234. break;
  19235. case 'topright':
  19236. this._container.style.marginRight = this.options.offset[0]+'px';
  19237. this._container.style.marginTop = this.options.offset[1]+'px';
  19238. break;
  19239. case 'bottomleft':
  19240. this._container.style.marginLeft = this.options.offset[0]+'px';
  19241. this._container.style.marginBottom = this.options.offset[1]+'px';
  19242. break;
  19243. case 'bottomright':
  19244. this._container.style.marginRight = this.options.offset[0]+'px';
  19245. this._container.style.marginBottom = this.options.offset[1]+'px';
  19246. break;
  19247. }
  19248. return this._container;
  19249. },
  19250. _createControl:function(){
  19251. var _this = this;
  19252. this._container = L.DomUtil.create('div','leaflet-bar leaflet-control-altitude-tool');
  19253. var link = L.DomUtil.create('a','leaflet-control-altitude-tool-link',this._container);
  19254. link.title = '高程量算';
  19255. link.innerHTML = 'G'
  19256. L.DomUtil.create('span','',link);
  19257. L.DomEvent.on(this._container,'contextmenu',L.DomEvent.stopPropagation);
  19258. L.DomEvent
  19259. .on(link,'click', L.DomEvent.stopPropagation)
  19260. .on(link,'click', L.DomEvent.preventDefault)
  19261. .on(link,'click',function(){
  19262. if(!_this._isNewaltitude){
  19263. _this.remove();
  19264. }else {
  19265. _this._isNewaltitude = false;
  19266. L.DomUtil.addClass(_this._container,'active');
  19267. _this._map.doubleClickZoom.disable();
  19268. _this._map.on('click',_this._onClickPoint,_this);
  19269. if(L.Browser.ie || L.Browser.firefox){
  19270. _this._map.getContainer().style.cursor = 'url('+L.DefaultImagePath+'/cur-ruler.cur),auto';
  19271. }else{
  19272. _this._map.getContainer().style.cursor = 'url('+L.DefaultImagePath+'/cur-ruler.cur) 5 5,auto';
  19273. }
  19274. }
  19275. })
  19276. },
  19277. /**
  19278. * 鼠标单击事件
  19279. * @param e
  19280. * @returns {boolean}
  19281. * @private
  19282. */
  19283. _onClickPoint:function(e){
  19284. var _this = this;
  19285. _this._lC++;
  19286. _this._altitudeObjs[_this._lC] = new L.FeatureGroup();
  19287. _this._altitudeObjs[_this._lC].addTo(_this._altitudeGroup);
  19288. //e.latlng
  19289. _this._buildMarker({latlng: e.latlng});
  19290. },
  19291. /**
  19292. * 删除对应iC的测距
  19293. */
  19294. del:function(event,iC){
  19295. var _this = this;
  19296. var event = event || window.event;
  19297. L.DomEvent.stop(event);
  19298. _this._altitudeGroup.removeLayer(_this._altitudeObjs[iC]);
  19299. delete _this._altitudeObjs[iC];
  19300. },
  19301. /**
  19302. * 清除所有的测距
  19303. * @type {Function}
  19304. */
  19305. clearAllelevation:function(){
  19306. var _this = this;
  19307. _this._altitudeGroup.clearLayers();
  19308. _this._altitudeObjs = {};
  19309. },
  19310. /**
  19311. * 进行剖面量算
  19312. * @param {[type]} event [description]
  19313. * @param {[type]} iC [description]
  19314. * @return {[type]} [description]
  19315. */
  19316. run:function(latlng,callBackFunc){
  19317. var _this = this;
  19318. var url = map23DConfig.altitudeServerUrl+'/terrain/elevation';
  19319. var ajaxData = {
  19320. lat:latlng.lat,
  19321. lon:latlng.lng,
  19322. zoom:_this._map.getZoom(),
  19323. delta_zoom:0
  19324. };
  19325. $.ajax({
  19326. type:"post",
  19327. dataType:'json',
  19328. data:ajaxData,
  19329. url:url,
  19330. success:function(data){
  19331. callBackFunc(data);
  19332. }
  19333. });
  19334. },
  19335. /**
  19336. * 创建一个marker 并返回该marker
  19337. * @param obj
  19338. * @returns {L.Marker}
  19339. * @private
  19340. */
  19341. _buildMarker:function(obj){
  19342. var _this = this;
  19343. _this.run(obj.latlng,function(data){
  19344. var altitudeLabel = L.DomUtil.create('span','altitude-span');
  19345. altitudeLabel.lid = _this._lC
  19346. altitudeLabel.style.color = 'red';
  19347. altitudeLabel.innerHTML = '高程:'+data.data+ '米';
  19348. L.DomEvent.on(altitudeLabel,'dblclick',function(e){
  19349. L.DomEvent.stopPropagation(e);
  19350. var lid = e.target? e.target.lid: e.srcElement.lid;
  19351. _this.del(e,lid)
  19352. });
  19353. new L.Marker(
  19354. obj.latlng,
  19355. {icon: L.icon({
  19356. iconUrl: L.DefaultImagePath+'/icon-linePoint.png',
  19357. iconSize: [15, 15],
  19358. iconAnchor: [7, 7],
  19359. popupAnchor: [0, -7]
  19360. }),
  19361. clickable:false
  19362. }
  19363. ).bindLabel(altitudeLabel,{
  19364. noHide:true,
  19365. }).addTo(_this._altitudeObjs[_this._lC]);
  19366. });
  19367. _this.remove();
  19368. },
  19369. /**
  19370. * 计算完成
  19371. * @type {Function}
  19372. */
  19373. remove:function(){
  19374. // var _this = this;
  19375. // _this._map.doubleClickZoom.enable();
  19376. // _this._map.getContainer().style.cursor = 'auto';
  19377. // _this._isNewaltitude = true;
  19378. // _this._map.off('click',_this._onClickPoint,this);
  19379. // L.DomUtil.removeClass(_this._container,'active');
  19380. }
  19381. });
  19382. L.control.altitudeTool = function(options){
  19383. return new L.Control.AltitudeTool(options);
  19384. }
  19385. /**
  19386. * 高程量算
  19387. */
  19388. map2DViewer.altitudeToolsFire = function(data) {};
  19389. map2DViewer.setAltitudeTools = function(options) {
  19390. var defaultData = {
  19391. action: 'add',
  19392. position: 'topleft',
  19393. offset: [10, 10]
  19394. }
  19395. _.merge(defaultData, options);
  19396. switch (defaultData.action) {
  19397. case 'add':
  19398. this.altitudeTools = new L.Control.AltitudeTool({
  19399. position: defaultData.position,
  19400. offset: defaultData.offset
  19401. }).addTo(this.map);
  19402. this.map.on('measure-distance-result', map2DViewer.altitudeToolsFire);
  19403. return this.altitudeTools;
  19404. break;
  19405. case 'remove':
  19406. this.altitudeTools.cleanAllMeasure();
  19407. this.map.removeControl(this.altitudeTools);
  19408. this.map.off('measure-distance-result', map2DViewer.altitudeToolsFire);
  19409. break;
  19410. }
  19411. };
  19412. L.MagnifyingGlass = L.Layer.extend({
  19413. options: {
  19414. radius: 150,
  19415. zoomOffset: 3,
  19416. layers: [],
  19417. fixedPosition: false,
  19418. latLng: [0, 0],
  19419. fixedZoom: -1
  19420. },
  19421. initialize: function(options) {
  19422. L.Util.setOptions(this, options);
  19423. this._fixedZoom = (this.options.fixedZoom != -1);
  19424. this._mainMap = null;
  19425. this._glassMap = null;
  19426. },
  19427. getMap: function() {
  19428. return this._glassMap;
  19429. },
  19430. _createMiniMap: function(elt) {
  19431. return new L.Map(elt, {
  19432. //layers: this.options.layers,
  19433. zoom: this._getZoom(),
  19434. maxZoom: this._mainMap.getMaxZoom(),
  19435. minZoom: this._mainMap.getMinZoom(),
  19436. crs: this._mainMap.options.crs,
  19437. fadeAnimation: false,
  19438. attributionControl: false,
  19439. zoomControl: false,
  19440. boxZoom: false,
  19441. touchZoom: false,
  19442. scrollWheelZoom: false,
  19443. doubleClickZoom: false,
  19444. dragging: false,
  19445. keyboard: false,
  19446. });
  19447. },
  19448. _getZoom: function() {
  19449. return (this._fixedZoom) ?
  19450. this.options.fixedZoom :
  19451. this._mainMap.getZoom() + this.options.zoomOffset;
  19452. },
  19453. _updateZoom: function() {
  19454. this._glassMap.setZoom(this._getZoom());
  19455. },
  19456. setRadius: function(radius) {
  19457. this.options.radius = radius;
  19458. if (this._wrapperElt) {
  19459. this._wrapperElt.style.width = this.options.radius * 2 + 'px';
  19460. this._wrapperElt.style.height = this.options.radius * 2 + 'px';
  19461. }
  19462. },
  19463. setLatLng: function(latLng) {
  19464. this.options.latLng = latLng;
  19465. this._update(latLng);
  19466. },
  19467. _updateFromMouse: function(evt) {
  19468. this._update(evt.latlng, evt.layerPoint);
  19469. },
  19470. _updateFixed: function() {
  19471. this._update(this.options.latLng);
  19472. },
  19473. _update: function(latLng, layerPoint) {
  19474. // update mini map view, forcing no animation
  19475. this._glassMap.setView(latLng, this._getZoom(), {
  19476. pan: { animate: false }
  19477. });
  19478. // update the layer element position on the main map,
  19479. // using the one provided or reprojecting it
  19480. layerPoint = layerPoint || this._mainMap.latLngToLayerPoint(latLng);
  19481. this._wrapperElt.style.left = layerPoint.x - this.options.radius + 'px';
  19482. this._wrapperElt.style.top = layerPoint.y - this.options.radius + 'px';
  19483. },
  19484. /**
  19485. As defined by ILayer
  19486. */
  19487. onAdd: function(map) {
  19488. this._mainMap = map;
  19489. // create a wrapper element and a container for the map inside it
  19490. this._wrapperElt = L.DomUtil.create('div', 'leaflet-magnifying-glass');
  19491. var glassMapEltPicture = L.DomUtil.create('div', 'leaflet-magnifying-glass-webkitPicture', this._wrapperElt);
  19492. var glassMapElt = L.DomUtil.create('div', 'leaflet-magnifying-glass-webkit', glassMapEltPicture);
  19493. // Webkit border-radius clipping workaround (see CSS)
  19494. if (L.Browser.webkit || L.Browser.ie)
  19495. L.DomEvent.on(glassMapElt, 'dblclick', L.DomEvent.stopPropagation)
  19496. .on(glassMapElt, 'dblclick', function() {
  19497. map2DViewer.map.removeLayer(map2DViewer.magnifyingGlass);
  19498. delete map2DViewer.magnifyingGlass;
  19499. });
  19500. // build the map
  19501. this._glassMap = this._createMiniMap(glassMapElt);
  19502. if (L.Browser.ie || L.Browser.firefox) {
  19503. this._glassMap.getContainer().style.cursor = 'url(' + L.DefaultImagePath + '/cur-none.cur),auto';
  19504. } else {
  19505. this._glassMap.getContainer().style.cursor = 'url(' + L.DefaultImagePath + '/cur-none.cur) 5 5,auto';
  19506. }
  19507. // forward some DOM events as Leaflet events
  19508. L.DomEvent.addListener(this._wrapperElt, 'click', this._fireClick, this);
  19509. var opts = this.options;
  19510. this.setRadius(opts.radius);
  19511. this.setLatLng(opts.latLng);
  19512. this._glassMap.whenReady(function() {
  19513. if (opts.fixedPosition) {
  19514. this._mainMap.on('zoomend', this._updateFixed, this);
  19515. L.DomUtil.addClass(this._wrapperElt, ('leaflet-zoom-hide'));
  19516. } else {
  19517. this._mainMap.on('mousemove', this._updateFromMouse, this);
  19518. if (!this._fixedZoom) {
  19519. this._mainMap.on('zoomend', this._updateZoom, this);
  19520. }
  19521. }
  19522. }, this);
  19523. // add the magnifying glass as a layer to the top-most pane
  19524. map.getPanes().popupPane.appendChild(this._wrapperElt);
  19525. // needed after the element has been added, otherwise tile loading is messy
  19526. this._glassMap.invalidateSize();
  19527. var group = L.featureGroup();
  19528. map2DViewer.groups['glassGroup'] = group;
  19529. group.addTo(this._glassMap);
  19530. map2DViewer.magnifyingGlass.addLayersGlass();
  19531. return this;
  19532. },
  19533. //图层加载
  19534. addLayersGlass: function() {
  19535. $.each(map2DViewer.map._layers, function(name, item) {
  19536. if (item.hasOwnProperty('guid') && item.hasOwnProperty('_url')) {
  19537. var itemLayer = L.tileLayer(item._url, {
  19538. minZoom: item.options.minZoom,
  19539. maxZoom: item.options.maxZoom,
  19540. maxNativeZoom: item.options.maxZoom
  19541. });
  19542. itemLayer.addTo(map2DViewer.magnifyingGlass._glassMap);
  19543. if (item.guid === "tileLayer2DDefault") {
  19544. itemLayer.bringToBack()
  19545. }
  19546. if (item.guid === "oasaMapLayer") {
  19547. itemLayer.bringToFront()
  19548. }
  19549. }
  19550. })
  19551. },
  19552. _fireClick: function(domMouseEvt) {
  19553. this.fire('click', domMouseEvt);
  19554. L.DomEvent.stopPropagation(domMouseEvt);
  19555. },
  19556. MagnifyingGlassFunction: function(defaultData) {
  19557. map2DViewer.magnifyingGlass._glassMap.on('moveend', function() {
  19558. map2DViewer.groups.glassGroup.clearLayers();
  19559. $.each(map23DData, function(name, item) {
  19560. switch (name) {
  19561. case 'polylines':
  19562. return map2DViewer.magnifyingGlass.addpolylinesOnGlass(item, defaultData);
  19563. break;
  19564. case 'polygons':
  19565. return map2DViewer.magnifyingGlass.addpolygonsOnGlass(item, defaultData);
  19566. break;
  19567. case 'markers':
  19568. return map2DViewer.magnifyingGlass.addmarkersOnGlass(item, defaultData);
  19569. break;
  19570. case 'circles':
  19571. return map2DViewer.magnifyingGlass.addcirclesOnGlass(item, defaultData);;
  19572. break;
  19573. case 'circleMarkers':
  19574. return map2DViewer.magnifyingGlass.addcircleMarkersOnGlass(item, defaultData);;
  19575. break;
  19576. }
  19577. })
  19578. })
  19579. },
  19580. addcircleMarkersOnGlass: function(item, defaultData) {
  19581. $.each(item, function(name, curt) {
  19582. if(curt.groupId){
  19583. if(!map23DData.groups[curt.groupId].visible2D){
  19584. return false;
  19585. }
  19586. }
  19587. if(curt.visible2D){
  19588. var GlassBounds = map2DViewer.magnifyingGlass.magnifyingGlassbouns(map2DViewer.magnifyingGlass._glassMap.getBounds());
  19589. var judgeAddGlass = map2DViewer.magnifyingGlass.pointInPolygon(curt.geojson.geometry.coordinates, GlassBounds);
  19590. if (judgeAddGlass) {
  19591. var circleMarker = L.circleMarker(
  19592. map23DUtil.latLngsToReverse(curt.geojson.geometry.coordinates), {
  19593. radius: curt.geojson.properties.radius,
  19594. color: curt.geojson.properties.color,
  19595. weight: curt.geojson.properties.weight + defaultData.widthOffset,
  19596. fillColor: curt.geojson.properties.fillColor,
  19597. opacity: curt.geojson.properties.opacity,
  19598. fillOpacity: curt.geojson.properties.fillOpacity,
  19599. title: curt.geojson.properties.title
  19600. }
  19601. );
  19602. circleMarker.addTo(map2DViewer.groups['glassGroup']);
  19603. if (map2DViewer.circleMarkers[name].hasOwnProperty('plabel')) {
  19604. if (map2DViewer.circleMarkers[name].plabel._isOpen) {
  19605. circleMarker.bindPlabel(map2DViewer.circleMarkers[name].plabel._content,
  19606. map2DViewer.circleMarkers[name].plabel.options);
  19607. circleMarker.showPlabel();
  19608. }
  19609. }
  19610. }
  19611. }
  19612. })
  19613. },
  19614. addcirclesOnGlass: function(item, defaultData) {
  19615. $.each(item, function(name, curt) {
  19616. if(curt.groupId){
  19617. if(!map23DData.groups[curt.groupId].visible2D){
  19618. return false;
  19619. }
  19620. }
  19621. if(curt.visible2D){
  19622. var circle = L.circle(
  19623. map23DUtil.latLngsToReverse(curt.geojson.geometry.coordinates),
  19624. curt.geojson.properties.radius, {
  19625. color: curt.geojson.properties.color,
  19626. weight: curt.geojson.properties.weight + defaultData.widthOffset,
  19627. fillColor: curt.geojson.properties.fillColor,
  19628. opacity: curt.geojson.properties.opacity,
  19629. fillOpacity: curt.geojson.properties.fillOpacity,
  19630. title: curt.geojson.properties.title
  19631. }
  19632. );
  19633. circle.addTo(map2DViewer.groups['glassGroup']);
  19634. }
  19635. })
  19636. },
  19637. addpolygonsOnGlass: function(item, defaultData) {
  19638. $.each(item, function(name, curt) {
  19639. if(curt.groupId){
  19640. if(!map23DData.groups[curt.groupId].visible2D){
  19641. return false;
  19642. }
  19643. }
  19644. if(curt.visible2D){
  19645. var polygon = L.polygon(
  19646. map23DUtil.latLngsToReverse(curt.geojson.geometry.coordinates[0]), {
  19647. color: curt.geojson.properties.color,
  19648. weight: curt.geojson.properties.weight + defaultData.widthOffset,
  19649. fillColor: curt.geojson.properties.fillColor,
  19650. opacity: curt.geojson.properties.opacity,
  19651. fillOpacity: curt.geojson.properties.fillOpacity,
  19652. title: curt.geojson.properties.title
  19653. }
  19654. );
  19655. polygon.addTo(map2DViewer.groups['glassGroup']);
  19656. }
  19657. })
  19658. },
  19659. //marker icon
  19660. glassmarker_icon: function(markerData) {
  19661. if (markerData.geojson.properties.fontIcon) {
  19662. var icon_html = '<div width="' + markerData.geojson.properties.iconSize[0] + '" \
  19663. height="' + markerData.geojson.properties.iconSize[1] + '" \
  19664. style="color:' + markerData.geojson.properties.fontColor + ';\
  19665. line-height:1;\
  19666. font-weight:' + markerData.geojson.properties.fontWeight + '; \
  19667. font-size:' + markerData.geojson.properties.fontSize + 'px; \
  19668. -webkit-transform: rotate(' + markerData.geojson.properties.iconRorate + 'deg); \
  19669. transform-origin:' + markerData.geojson.properties.iconAnchor[0] + 'px ' + markerData.geojson.properties.iconAnchor[1] + 'px;\
  19670. -ms-transform-origin:' + markerData.geojson.properties.iconAnchor[0] + 'px ' + markerData.geojson.properties.iconAnchor[1] + 'px;\
  19671. -moz-transform:rotate(' + markerData.geojson.properties.iconRorate + 'deg);\
  19672. -ms-transform:rotate(' + markerData.geojson.properties.iconRorate + 'deg);">' + markerData.geojson.properties.fontIcon +
  19673. '</div>';
  19674. } else {
  19675. var icon_html = '<img width="' + markerData.geojson.properties.iconSize[0] + '" \
  19676. height="' + markerData.geojson.properties.iconSize[1] + '" \
  19677. src="' + markerData.geojson.properties.iconUrl + '" \
  19678. style=" -webkit-transform: rotate(' + markerData.geojson.properties.iconRorate + 'deg); \
  19679. transform-origin:' + markerData.geojson.properties.iconAnchor[0] + 'px ' + markerData.geojson.properties.iconAnchor[1] + 'px;\
  19680. -ms-transform-origin:' + markerData.geojson.properties.iconAnchor[0] + 'px ' + markerData.geojson.properties.iconAnchor[1] + 'px;\
  19681. -moz-transform:rotate(' + markerData.geojson.properties.iconRorate + 'deg);\
  19682. -ms-transform:rotate(' + markerData.geojson.properties.iconRorate + 'deg);" />';
  19683. }
  19684. return icon_html;
  19685. },
  19686. addmarkersOnGlass: function(item, defaultData) {
  19687. $.each(item, function(name, curt) {
  19688. if(curt.groupId){
  19689. if(!map23DData.groups[curt.groupId].visible2D){
  19690. return false;
  19691. }
  19692. }
  19693. if(curt.visible2D){
  19694. var GlassBounds = map2DViewer.magnifyingGlass.magnifyingGlassbouns(map2DViewer.magnifyingGlass._glassMap.getBounds());
  19695. var judgeAddGlass = map2DViewer.magnifyingGlass.pointInPolygon(curt.geojson.geometry.coordinates, GlassBounds);
  19696. if (judgeAddGlass) {
  19697. var icon_html = map2DViewer.magnifyingGlass.glassmarker_icon(curt);
  19698. var setDivIcon = L.divIcon({
  19699. className: 'rorate_div',
  19700. html: icon_html,
  19701. iconAnchor: curt.geojson.properties.iconAnchor,
  19702. iconSize: curt.geojson.properties.iconSize,
  19703. popupAnchor: curt.geojson.properties.popupAnchor
  19704. });
  19705. var marker = L.marker(
  19706. map23DUtil.latLngsToReverse(curt.geojson.geometry.coordinates), {
  19707. icon: setDivIcon,
  19708. title: curt.geojson.properties.title
  19709. }
  19710. )
  19711. marker.addTo(map2DViewer.groups['glassGroup']);
  19712. if (map2DViewer.markers[name].hasOwnProperty('plabel')) {
  19713. if (map2DViewer.markers[name].plabel._isOpen) {
  19714. marker.bindPlabel(map2DViewer.markers[name].plabel._content,
  19715. map2DViewer.markers[name].plabel.options);
  19716. marker.showPlabel();
  19717. }
  19718. }
  19719. }
  19720. }
  19721. })
  19722. },
  19723. addpolylinesOnGlass: function(item, defaultData) {
  19724. $.each(item, function(name, curt) {
  19725. if(curt.groupId){
  19726. if(!map23DData.groups[curt.groupId].visible2D){
  19727. return false;
  19728. }
  19729. }
  19730. if(curt.visible2D){
  19731. var polyline = L.polyline(
  19732. map23DUtil.latLngsToReverse(curt.geojson.geometry.coordinates), {
  19733. color: curt.geojson.properties.color,
  19734. weight: curt.geojson.properties.weight + defaultData.widthOffset,
  19735. opacity: curt.geojson.properties.opacity,
  19736. title: curt.geojson.properties.title,
  19737. dashArray: curt.geojson.properties.dashArray,
  19738. lineJoin: 'miter',
  19739. lineCap: 'butt'
  19740. }
  19741. );
  19742. polyline.addTo(map2DViewer.groups['glassGroup']);
  19743. }
  19744. })
  19745. },
  19746. //创建放大镜范围
  19747. magnifyingGlassbouns: function(bouns) {
  19748. var ne = [bouns._northEast.lng, bouns._northEast.lat];
  19749. var se = [bouns._northEast.lng, bouns._southWest.lat];
  19750. var sw = [bouns._southWest.lng, bouns._southWest.lat];
  19751. var nw = [bouns._southWest.lng, bouns._northEast.lat];
  19752. var mabounds = [ne, se, sw, nw, ne];
  19753. return mabounds;
  19754. },
  19755. //判断坐标位置是否在放大镜中
  19756. pointInPolygon: function(point, vs) {
  19757. var x = point[0],
  19758. y = point[1];
  19759. var inside = false;
  19760. for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
  19761. var xi = vs[i][0],
  19762. yi = vs[i][1];
  19763. var xj = vs[j][0],
  19764. yj = vs[j][1];
  19765. var intersect = ((yi > y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
  19766. if (intersect) inside = !inside;
  19767. }
  19768. return inside;
  19769. },
  19770. /**
  19771. As defined by ILayer
  19772. */
  19773. onRemove: function(map) {
  19774. map.off('viewreset', this._updateFixed, this);
  19775. map.off('mousemove', this._updateFromMouse, this);
  19776. map.off('zoomend', this._updateZoom, this);
  19777. for (var i = 0, l = this.options.layers.length; i < l; i++) {
  19778. this._glassMap.removeLayer(this.options.layers[i]);
  19779. }
  19780. this._glassMap.remove();
  19781. L.DomEvent.removeListener(this._wrapperElt, 'click', this._fireClick);
  19782. map.getPanes().popupPane.removeChild(this._wrapperElt);
  19783. this._mainMap = null;
  19784. return this;
  19785. }
  19786. });
  19787. L.magnifyingGlass = function(options) {
  19788. return new L.MagnifyingGlass(options);
  19789. };
  19790. /**
  19791. * 放大镜
  19792. * @param {[type]} options [description]
  19793. * @return {[type]} [description]
  19794. */
  19795. //调用示例 map23DControl.show2DMagnifyingGlass(true)
  19796. map2DViewer.setMagnifyingGlass = function(options) {
  19797. var defaultData = {
  19798. action: 'add',
  19799. zoomOffset: 3,
  19800. widthOffset:5
  19801. }
  19802. _.merge(defaultData, options);
  19803. switch (defaultData.action) {
  19804. case 'add':
  19805. if (!this.magnifyingGlass) {
  19806. this.magnifyingGlass = L.magnifyingGlass(defaultData)
  19807. }
  19808. if (!this.map.hasLayer(this.magnifyingGlass)) {
  19809. this.map.addLayer(this.magnifyingGlass);
  19810. }
  19811. map2DViewer.magnifyingGlass.MagnifyingGlassFunction(defaultData);
  19812. return this.magnifyingGlass;
  19813. break;
  19814. case 'remove':
  19815. if (this.map.hasLayer(this.magnifyingGlass)) {
  19816. this.map.removeLayer(this.magnifyingGlass);
  19817. this.magnifyingGlass = null;
  19818. delete this.magnifyingGlass;
  19819. }
  19820. break;
  19821. }
  19822. }
  19823. var ScrollBar = {
  19824. timelineHtml:
  19825. '<div class="Demo">'+
  19826. ' <div class="Main">'+
  19827. ' <div class="scrollBar">'+
  19828. ' <div class="scroll_Track"></div>'+
  19829. ' <div class="scroll_Thumb"></div>'+
  19830. ' </div>'+
  19831. //' <p class="scrollBarTxt" style="text-align:center;"></p>'+
  19832. ' </div>'+
  19833. '</div>',
  19834. value: 0,
  19835. maxValue: 200,
  19836. currentX: 0,
  19837. init:function(options){
  19838. ScrollBar.value = 0;
  19839. ScrollBar.maxValue = options.maxLength;
  19840. $('<li id="'+options.id+'">'+ScrollBar.timelineHtml+'</li>').appendTo($("#TimeLineContainer ul"));
  19841. //$("#"+options.id+" .scrollBarTxt").html(options);
  19842. ScrollBar.Initialize(options);
  19843. },
  19844. Initialize: function(options) {
  19845. if (ScrollBar.value > ScrollBar.maxValue) {
  19846. alert("给定当前值大于了最大值");
  19847. return;
  19848. }
  19849. ScrollBar.GetValue();
  19850. $(""+options.id+" .scroll_Track").css("width", ScrollBar.currentX + 2 + "px");
  19851. $(""+options.id+" .scroll_Thumb").css("margin-left", ScrollBar.currentX + "px");
  19852. ScrollBar.Value();
  19853. //$(""+options.id+" .scrollBarTxt").html(ScrollBar.value + "/" + ScrollBar.maxValue);
  19854. },
  19855. Value: function() {
  19856. var valite = false;
  19857. var currentValue;
  19858. $("#TimeLineContainer .scroll_Thumb").unbind('mousedown').bind('mousedown',function() {
  19859. valite = true;
  19860. $('#TimeLineContainer li').unbind('mousemove').bind('mousemove',function(event) {
  19861. var _this = $(this);
  19862. if (valite == false) return;
  19863. var changeX = event.clientX - ScrollBar.currentX;
  19864. currentValue = changeX - ScrollBar.currentX-$(".Demo").offset().left;
  19865. $("#"+_this[0].id+" .scroll_Thumb").css("left", currentValue -32 + "px");
  19866. $("#"+_this[0].id+" .scroll_Track").css("width", currentValue + "px");
  19867. if ((currentValue ) >= $(".Demo").width()) {
  19868. $("#"+_this[0].id+" .scroll_Thumb").css("left", $(".Demo").width() -32 + "px");
  19869. $("#"+_this[0].id+" .scroll_Track").css("width", $(".Demo").width() + "px");
  19870. ScrollBar.value = map2DViewer.markers[_this[0].id]._latlngs.length;
  19871. } else if (currentValue <= 0) {
  19872. $("#"+_this[0].id+" .scroll_Thumb").css("margin-left", "0px");
  19873. $("#"+_this[0].id+" .scroll_Track").css("width", "0px");
  19874. } else {
  19875. ScrollBar.value = Math.round(map2DViewer.markers[_this[0].id]._latlngs.length * (currentValue / $(".Demo").width()));
  19876. }
  19877. //$("#"+_this[0].id+" .scrollBarTxt").html(ScrollBar.value + "/" + ScrollBar.maxValue);
  19878. if(ScrollBar.value >= map2DViewer.markers[_this[0].id]._latlngs.length){
  19879. ScrollBar.value = map2DViewer.markers[_this[0].id]._latlngs.length - 1;
  19880. map23DData.timeLineData[_this[0].id]={'_i':ScrollBar.value};
  19881. map2DViewer.markers[_this[0].id].setLatLng(map2DViewer.markers[_this[0].id]._latlngs[ScrollBar.value]);
  19882. map2DViewer.markers[_this[0].id]['_i'] = 0;
  19883. if(window.marker_Animate){
  19884. map2DViewer.markers[_this[0].id].stop();
  19885. map2DViewer.markers[_this[0].id].start();
  19886. }
  19887. }else{
  19888. map23DData.timeLineData[_this[0].id]={'_i':ScrollBar.value};
  19889. map2DViewer.markers[_this[0].id].setLatLng(map2DViewer.markers[_this[0].id]._latlngs[ScrollBar.value]);
  19890. map2DViewer.markers[_this[0].id]['_i'] = ScrollBar.value;
  19891. if(window.marker_Animate){
  19892. map2DViewer.markers[_this[0].id].stop();
  19893. map2DViewer.markers[_this[0].id].start();
  19894. }
  19895. }
  19896. });
  19897. });
  19898. $('#TimeLineContainer li').unbind('mouseleave').bind('mouseleave',function() {
  19899. var _this = $(this);
  19900. ScrollBar.value = Math.round(ScrollBar.maxValue * (currentValue / $(".Demo").width()));
  19901. valite = false;
  19902. if (ScrollBar.value >= ScrollBar.maxValue) ScrollBar.value = ScrollBar.maxValue;
  19903. if (ScrollBar.value <= 0) ScrollBar.value = 0;
  19904. //$("#"+_this[0].id+" .scrollBarTxt").html(ScrollBar.value + "/" + ScrollBar.maxValue);
  19905. });
  19906. $('#TimeLineContainer li').unbind('mouseup').bind('mouseup',function() {
  19907. var _this = $(this);
  19908. ScrollBar.value = Math.round(ScrollBar.maxValue * (currentValue / $(".Demo").width()));
  19909. valite = false;
  19910. if (ScrollBar.value >= ScrollBar.maxValue) ScrollBar.value = ScrollBar.maxValue;
  19911. if (ScrollBar.value <= 0) ScrollBar.value = 0;
  19912. //$("#"+_this[0].id+" .scrollBarTxt").html(ScrollBar.value + "/" + ScrollBar.maxValue);
  19913. });
  19914. },
  19915. GetValue: function() {
  19916. ScrollBar.currentX = $(".Demo").width() * (ScrollBar.value / ScrollBar.maxValue);
  19917. },
  19918. //设置路径回放位置
  19919. setRoutBcakView:function(options){
  19920. var marker_guid = map2DViewer.routeBackGroup[options.guid].marker;
  19921. map2DViewer.markers[marker_guid]['_i'] = options.step;
  19922. var maxlength = $("#"+marker_guid+" .Main").width();
  19923. var curlength = Math.round((options.step/(map2DViewer.markers[marker_guid]._latlngs.length-1))*maxlength);
  19924. $("#"+marker_guid+" .scroll_Thumb").css("left", curlength -32+ "px");
  19925. $("#"+marker_guid+" .scroll_Track").css("width", curlength + "px");
  19926. }
  19927. }
  19928. /**
  19929. * 路径回放
  19930. */
  19931. map2DViewer.routeBackGroup = {};
  19932. var hasRB = false;
  19933. map2DViewer.routeBack = function(markerOptions, lineOptions) {
  19934. var RBkey = map23DControl.buildGuid('routeBackGroup');
  19935. map2DViewer.routeBackGroup[RBkey] = {
  19936. polyline: null,
  19937. marker: null,
  19938. isEnd:false
  19939. };
  19940. map2DViewer.routeBackGroup[RBkey].polyline = map23DControl.polyline({
  19941. action: 'add',
  19942. geojson: lineOptions.geojson,
  19943. });
  19944. map2DViewer.routeBackGroup[RBkey].marker = map23DControl.marker({
  19945. action: 'add',
  19946. animate: true,
  19947. RBkey: RBkey,
  19948. geojson: markerOptions.geojson
  19949. })
  19950. map2DViewer.markers[map2DViewer.routeBackGroup[RBkey].marker].start();
  19951. var maxLength = lineOptions.geojson.properties.times.length;
  19952. var ScrollBarOptions = {
  19953. 'id': map2DViewer.routeBackGroup[RBkey].marker,
  19954. 'maxLength': maxLength
  19955. };
  19956. ScrollBar.init(ScrollBarOptions);
  19957. if(!hasRB){
  19958. PubSub.subscribe('payBackEnd',map2DViewer.paybackGOn);
  19959. PubSub.subscribe('curMarkerOptions',map2DViewer.changeCurOptions);
  19960. //this.map.on('zoomend',function(e){
  19961. /*$.each(map2DViewer.routeBackGroup,function(i,t){
  19962. var animate_data = map2DViewer.routeBackGroup[i].marker;
  19963. if(map23DData.markers[animate_data].visible2D){
  19964. var _this = map2DViewer.markers[animate_data];
  19965. if (L.DomUtil.TRANSITION) {
  19966. if (_this._icon) { _this._icon.style[L.DomUtil.TRANSITION] = ('all ' + 1 + 'ms linear'); }
  19967. if (_this._shadow) { _this._shadow.style[L.DomUtil.TRANSITION] = 'all ' + 1 + 'ms linear'; }
  19968. }
  19969. if(_this._i < _this._latlngs.length){
  19970. _this.setLatLng(_this._latlngs[_this._i]);
  19971. _this['_i'] = _this._i;
  19972. }
  19973. }
  19974. }) */
  19975. //})
  19976. hasRB = true;
  19977. }
  19978. return RBkey;
  19979. };
  19980. map2DViewer.paybackGOn = function(msg,guid){};
  19981. map2DViewer.changeCurOptions = function(msg,guid){
  19982. }
  19983. /**
  19984. * 暂停回放
  19985. */
  19986. map2DViewer.stopRouteBack = function(RBkey) {
  19987. var animate_data = map2DViewer.routeBackGroup[RBkey].marker;
  19988. map2DViewer.markers[animate_data].stop();
  19989. };
  19990. /**
  19991. * 继续回放
  19992. */
  19993. map2DViewer.goonRouteBack = function(RBkey) {
  19994. var animate_data = map2DViewer.routeBackGroup[RBkey].marker;
  19995. map2DViewer.markers[animate_data].stop();
  19996. map2DViewer.markers[animate_data].start();
  19997. };
  19998. /**
  19999. * 重放路径回放
  20000. */
  20001. map2DViewer.reStartRouteBack = function(RBkey){
  20002. var animate_data = map2DViewer.routeBackGroup[RBkey].marker;
  20003. map2DViewer.markers[animate_data].restart();
  20004. }
  20005. /**
  20006. * 移除回放
  20007. */
  20008. map2DViewer.removeRouteBack = function(RBkey) {
  20009. var animate_data = map2DViewer.routeBackGroup[RBkey];
  20010. delete map2DViewer.routeBackGroup[RBkey];
  20011. map23DControl.marker({
  20012. action: 'remove',
  20013. guid: animate_data.marker
  20014. });
  20015. map23DControl.polyline({
  20016. action: 'remove',
  20017. guid: animate_data.polyline
  20018. });
  20019. };
  20020. /*
  20021. (c) 2014, Vladimir Agafonkin
  20022. simpleheat, a tiny JavaScript library for drawing heatmaps with Canvas
  20023. https://github.com/mourner/simpleheat
  20024. */
  20025. !function(){"use strict";function t(i){return this instanceof t?(this._canvas=i="string"==typeof i?document.getElementById(i):i,this._ctx=i.getContext("2d"),this._width=i.width,this._height=i.height,this._max=1,void this.clear()):new t(i)}t.prototype={defaultRadius:25,defaultGradient:{.4:"blue",.6:"cyan",.7:"lime",.8:"yellow",1:"red"},data:function(t,i){return this._data=t,this},max:function(t){return this._max=t,this},add:function(t){return this._data.push(t),this},clear:function(){return this._data=[],this},radius:function(t,i){i=i||15;var a=this._circle=document.createElement("canvas"),s=a.getContext("2d"),e=this._r=t+i;return a.width=a.height=2*e,s.shadowOffsetX=s.shadowOffsetY=200,s.shadowBlur=i,s.shadowColor="black",s.beginPath(),s.arc(e-200,e-200,t,0,2*Math.PI,!0),s.closePath(),s.fill(),this},gradient:function(t){var i=document.createElement("canvas"),a=i.getContext("2d"),s=a.createLinearGradient(0,0,0,256);i.width=1,i.height=256;for(var e in t)s.addColorStop(e,t[e]);return a.fillStyle=s,a.fillRect(0,0,1,256),this._grad=a.getImageData(0,0,1,256).data,this},draw:function(t){this._circle||this.radius(this.defaultRadius),this._grad||this.gradient(this.defaultGradient);var i=this._ctx;i.clearRect(0,0,this._width,this._height);for(var a,s=0,e=this._data.length;e>s;s++)a=this._data[s],i.globalAlpha=Math.max(a[2]/this._max,t||.05),i.drawImage(this._circle,a[0]-this._r,a[1]-this._r);var n=i.getImageData(0,0,this._width,this._height);return this._colorize(n.data,this._grad),i.putImageData(n,0,0),this},_colorize:function(t,i){for(var a,s=3,e=t.length;e>s;s+=4)a=4*t[s],a&&(t[s-3]=i[a],t[s-2]=i[a+1],t[s-1]=i[a+2])}},window.simpleheat=t}(),/*
  20026. (c) 2014, Vladimir Agafonkin
  20027. Leaflet.heat, a tiny and fast heatmap plugin for Leaflet.
  20028. https://github.com/Leaflet/Leaflet.heat
  20029. */
  20030. L.HeatLayer=(L.Layer?L.Layer:L.Class).extend({initialize:function(t,i){this._latlngs=t,L.setOptions(this,i)},setLatLngs:function(t){return this._latlngs=t,this.redraw()},addLatLng:function(t){return this._latlngs.push(t),this.redraw()},setOptions:function(t){return L.setOptions(this,t),this._heat&&this._updateOptions(),this.redraw()},redraw:function(){return!this._heat||this._frame||this._map._animating||(this._frame=L.Util.requestAnimFrame(this._redraw,this)),this},onAdd:function(t){this._map=t,this._canvas||this._initCanvas(),t._panes.overlayPane.appendChild(this._canvas),t.on("moveend",this._reset,this),t.options.zoomAnimation&&L.Browser.any3d&&t.on("zoomanim",this._animateZoom,this),this._reset()},onRemove:function(t){t.getPanes().overlayPane.removeChild(this._canvas),t.off("moveend",this._reset,this),t.options.zoomAnimation&&t.off("zoomanim",this._animateZoom,this)},addTo:function(t){return t.addLayer(this),this},_initCanvas:function(){var t=this._canvas=L.DomUtil.create("canvas","leaflet-heatmap-layer leaflet-layer"),i=L.DomUtil.testProp(["transformOrigin","WebkitTransformOrigin","msTransformOrigin"]);t.style[i]="50% 50%";var a=this._map.getSize();t.width=a.x,t.height=a.y;var s=this._map.options.zoomAnimation&&L.Browser.any3d;L.DomUtil.addClass(t,"leaflet-zoom-"+(s?"animated":"hide")),this._heat=simpleheat(t),this._updateOptions()},_updateOptions:function(){this._heat.radius(this.options.radius||this._heat.defaultRadius,this.options.blur),this.options.gradient&&this._heat.gradient(this.options.gradient),this.options.max&&this._heat.max(this.options.max)},_reset:function(){var t=this._map.containerPointToLayerPoint([0,0]);L.DomUtil.setPosition(this._canvas,t);var i=this._map.getSize();this._heat._width!==i.x&&(this._canvas.width=this._heat._width=i.x),this._heat._height!==i.y&&(this._canvas.height=this._heat._height=i.y),this._redraw()},_redraw:function(){var t,i,a,s,e,n,h,o,r,d=[],_=this._heat._r,l=this._map.getSize(),m=new L.Bounds(L.point([-_,-_]),l.add([_,_])),c=void 0===this.options.max?1:this.options.max,u=void 0===this.options.maxZoom?this._map.getMaxZoom():this.options.maxZoom,f=1/Math.pow(2,Math.max(0,Math.min(u-this._map.getZoom(),12))),g=_/2,p=[],v=this._map._getMapPanePos(),w=v.x%g,y=v.y%g;for(t=0,i=this._latlngs.length;i>t;t++)if(a=this._map.latLngToContainerPoint(this._latlngs[t]),m.contains(a)){e=Math.floor((a.x-w)/g)+2,n=Math.floor((a.y-y)/g)+2;var x=void 0!==this._latlngs[t].alt?this._latlngs[t].alt:void 0!==this._latlngs[t][2]?+this._latlngs[t][2]:1;r=x*f,p[n]=p[n]||[],s=p[n][e],s?(s[0]=(s[0]*s[2]+a.x*r)/(s[2]+r),s[1]=(s[1]*s[2]+a.y*r)/(s[2]+r),s[2]+=r):p[n][e]=[a.x,a.y,r]}for(t=0,i=p.length;i>t;t++)if(p[t])for(h=0,o=p[t].length;o>h;h++)s=p[t][h],s&&d.push([Math.round(s[0]),Math.round(s[1]),Math.min(s[2],c)]);this._heat.data(d).draw(this.options.minOpacity),this._frame=null},_animateZoom:function(t){var i=this._map.getZoomScale(t.zoom),a=this._map._getCenterOffset(t.center)._multiplyBy(-i).subtract(this._map._getMapPanePos());L.DomUtil.setTransform?L.DomUtil.setTransform(this._canvas,a,i):this._canvas.style[L.DomUtil.TRANSFORM]=L.DomUtil.getTranslateString(a)+" scale("+i+")"}}),L.heatLayer=function(t,i){return new L.HeatLayer(t,i)};
  20031. L.Control.MouseBlur = L.Control.extend({
  20032. //是否初始化
  20033. _initialized:false,
  20034. options:{
  20035. weight:1,
  20036. color:'#000000',
  20037. },
  20038. linesData:{
  20039. lineX:null,
  20040. lineY:null
  20041. },
  20042. initialize:function(options){
  20043. L.setOptions(this, options);
  20044. return this;
  20045. },
  20046. onAdd:function(map){
  20047. this._map = map;
  20048. this.craetMouse();
  20049. this._map.on('mousemove',this.mouseMove,this);
  20050. this._container = L.DomUtil.create('div','leaflet-bar leaflet-cross');
  20051. this._container.style.display = 'none';
  20052. return this._container;
  20053. },
  20054. craetMouse:function(){
  20055. var _this = this;
  20056. _this.printBounds = _this._map.getBounds();
  20057. _this.center = _this._map.getCenter();
  20058. _this.linesData.lineX = [[_this.center.lat,_this.printBounds._northEast.lng],[_this.center.lat,_this.printBounds._southWest.lng]];
  20059. _this.linesData.lineY = [[_this.printBounds._northEast.lat,_this.center.lng],[_this.printBounds._southWest.lat,_this.center.lng]];
  20060. _this.crosslineX = L.polyline(
  20061. _this.linesData.lineX,
  20062. _this.options
  20063. ).addTo(_this._map);
  20064. _this.crosslineY = L.polyline(
  20065. _this.linesData.lineY,
  20066. _this.options
  20067. ).addTo(_this._map);
  20068. if(L.Browser.ie || L.Browser.firefox){
  20069. _this._map.getContainer().style.cursor = 'url('+L.DefaultImagePath+'/cur-none.cur),auto';
  20070. }else{
  20071. _this._map.getContainer().style.cursor = 'url('+L.DefaultImagePath+'/cur-none.cur) 5 5,auto';
  20072. }
  20073. },
  20074. mouseMove:function(e){
  20075. var _this = this;
  20076. _this.center = e.latlng;
  20077. _this.linesData.lineX = [[_this.center.lat,180],[_this.center.lat,-180]];
  20078. _this.linesData.lineY = [[90,_this.center.lng],[-90,_this.center.lng]];
  20079. _this.crosslineX.setLatLngs(_this.linesData.lineX);
  20080. _this.crosslineY.setLatLngs(_this.linesData.lineY);
  20081. },
  20082. onRemove: function (map) {
  20083. var _this = this;
  20084. map.off('mousemove', this.mouseMove, this);
  20085. this._map.removeLayer(this.crosslineX);
  20086. this._map.removeLayer(this.crosslineY);
  20087. _this._map.getContainer().style.cursor = '';
  20088. }
  20089. });
  20090. L.control.mouseblur = function(options){
  20091. return new L.Control.MouseBlur(options);
  20092. }
  20093. /**
  20094. * 添加鼠标十字线
  20095. * @param {[type]} options [description]
  20096. */
  20097. map2DViewer.setMouseBlur = function(options) {
  20098. var _this = map2DViewer;
  20099. var defaultData = {
  20100. color:'#000000',
  20101. weight:1
  20102. }
  20103. _.merge(defaultData, options);
  20104. switch (defaultData.action) {
  20105. case 'add':
  20106. this.mouseBlur = new L.Control.MouseBlur(defaultData).addTo(this.map);
  20107. return this.mouseBlur;
  20108. break;
  20109. case 'remove':
  20110. this.map.removeControl(this.mouseBlur)
  20111. break;
  20112. }
  20113. }