map23dlib-nolib_bak.js 593 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054
  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:500,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. L.Util.getCirclePoint = function(x, y, radius) {
  31. var pointArr = []
  32. for (var i = 0; i < 361; i++) {
  33. if(i<360){
  34. pointArr.push({
  35. x: x + radius * Math.cos(i * 2 * Math.PI / 360),
  36. y: y + radius * Math.sin(i * 2 * Math.PI / 360)
  37. })
  38. }else{
  39. pointArr.push({
  40. x: x + radius * Math.cos(0 * 2 * Math.PI / 360),
  41. y: y + radius * Math.sin(0 * 2 * Math.PI / 360)
  42. })
  43. }
  44. }
  45. return pointArr; //x - y
  46. };
  47. /**
  48. * 航向量算
  49. */
  50. L.Util.getAngleByLatLng = function(startLong,startLat,endLong,endLat){
  51. startLong = parseFloat(startLong);
  52. startLat = parseFloat(startLat);
  53. endLong = parseFloat(endLong);
  54. endLat = parseFloat(endLat);
  55. var stsrtP = {
  56. x:startLong,
  57. y:startLat
  58. };
  59. var endP = {};
  60. endP.x=endLong;
  61. endP.y=endLat;
  62. var startPX_LatLongCoords = startLong;
  63. var startPY_LatLongCoords = startLat;
  64. var endPX_LatLongCoords = endLong;
  65. var endPY_LatLongCoords = endLat;
  66. var zhongjianX;
  67. var zhongjianY;
  68. zhongjianX = startPX_LatLongCoords > endPX_LatLongCoords ? startPX_LatLongCoords : endPX_LatLongCoords;
  69. zhongjianY = startPX_LatLongCoords > endPX_LatLongCoords ? startPY_LatLongCoords : endPY_LatLongCoords;
  70. var thirdX = zhongjianX;
  71. var thirdY = zhongjianY + 0.001;
  72. var prjParaPointC = {};
  73. prjParaPointC.x=thirdX;
  74. prjParaPointC.y=thirdY;
  75. stsrtP = L.Util.transformMercator(stsrtP);
  76. endP = L.Util.transformMercator(endP);
  77. var startPX = stsrtP.x;
  78. var startPY = stsrtP.y;
  79. var endPX = endP.x;
  80. var endPY = endP.y;
  81. prjParaPointC = L.Util.transformMercator(prjParaPointC);
  82. var objChangeCx = prjParaPointC.x;
  83. var objChangeCy = prjParaPointC.y;
  84. //有三点计算角度,使用向量方法
  85. var mx, my, ax, ay, bx, by, ma_x, ma_y, mb_x, mb_y;
  86. mx = startPX_LatLongCoords > endPX_LatLongCoords ? startPX : endPX;
  87. my = startPX_LatLongCoords > endPX_LatLongCoords ? startPY : endPY;
  88. if (mx == startPX && my == startPY) {
  89. ax = endPX;
  90. ay = endPY;
  91. } else {
  92. ax = startPX;
  93. ay = startPY;
  94. }
  95. bx = objChangeCx;
  96. by = objChangeCy;
  97. ma_x = ax - mx;
  98. ma_y = ay - my;
  99. mb_x = bx - mx;
  100. mb_y = by - my;
  101. var v1 = (ma_x * mb_x) + (ma_y * mb_y);
  102. var ma_val = Math.sqrt(ma_x * ma_x + ma_y * ma_y);
  103. var mb_val = Math.sqrt(mb_x * mb_x + mb_y * mb_y);
  104. var cosM = v1 / (ma_val * mb_val);
  105. var angleAMB = Math.acos(cosM) * 180 / Math.PI;
  106. var xiangxian = 0; // 定义象限变量
  107. var lastAngle = 0;
  108. if ((endPY_LatLongCoords - startPY_LatLongCoords) > 0 && (endPX_LatLongCoords - startPX_LatLongCoords) == 0) {
  109. lastAngle = 0;
  110. } else if ((endPY_LatLongCoords - startPY_LatLongCoords) == 0
  111. && (endPX_LatLongCoords - startPX_LatLongCoords) > 0) {
  112. lastAngle = 90;
  113. } else if ((endPY_LatLongCoords - startPY_LatLongCoords) < 0
  114. && (endPX_LatLongCoords - startPX_LatLongCoords) == 0) {
  115. lastAngle = 180;
  116. } else if ((endPY_LatLongCoords - startPY_LatLongCoords) == 0
  117. && (endPX_LatLongCoords - startPX_LatLongCoords) < 0) {
  118. lastAngle = 270;
  119. } else if ((endPY_LatLongCoords - startPY_LatLongCoords) > 0
  120. && (endPX_LatLongCoords - startPX_LatLongCoords) > 0) {
  121. xiangxian = 1;
  122. } else if ((endPY_LatLongCoords - startPY_LatLongCoords) > 0
  123. && (endPX_LatLongCoords - startPX_LatLongCoords) < 0) {
  124. xiangxian = 2;
  125. } else if ((endPY_LatLongCoords - startPY_LatLongCoords) < 0
  126. && (endPX_LatLongCoords - startPX_LatLongCoords) < 0) {
  127. xiangxian = 3;
  128. } else if ((endPY_LatLongCoords - startPY_LatLongCoords) < 0
  129. && (endPX_LatLongCoords - startPX_LatLongCoords) > 0) {
  130. xiangxian = 4;
  131. };
  132. switch (xiangxian) {
  133. case 1:
  134. lastAngle = 180 - angleAMB;
  135. break;
  136. case 2:
  137. lastAngle = 360 - angleAMB;
  138. break;
  139. case 3:
  140. lastAngle = 360 - angleAMB;
  141. break;
  142. case 4:
  143. lastAngle = 180 - angleAMB;
  144. break;
  145. default:
  146. //alert("none");
  147. }
  148. return parseInt(Math.round(lastAngle));
  149. }
  150. /**
  151. * 判断是否是合法的经纬度
  152. * @param {[type]} lat [纬度]
  153. * @param {[type]} lng [经度]
  154. * @return {[type]} [布尔值]
  155. */
  156. L.Util.verifyLatLng = function(lat, lng) {
  157. if (parseFloat(lat) >= -90 && parseFloat(lat) <= 90 && parseFloat(lng) >= -180 && parseFloat(lng) <= 180) {
  158. return true;
  159. } else {
  160. return false;
  161. }
  162. };
  163. /**
  164. * 地球坐标纠正
  165. * @param {[type]} latlng [description]
  166. * @return {[type]} [description]
  167. */
  168. L.Util.formatEarthLatLng = function(latlng){
  169. var lat = latlng.hasOwnProperty('lat') ? latlng.lat : latlng[0];
  170. var lng = latlng.hasOwnProperty('lng') ? latlng.lng : latlng[1];
  171. lng = lng%360;
  172. if(lng>180){
  173. lng = (lng%180)-180;
  174. }else if(lng<-180){
  175. lng = 180+(lng%180);
  176. }
  177. return new L.LatLng(lat,lng);
  178. };
  179. /**
  180. * 十进制经纬度转度分秒
  181. * @param {[type]} latlng [对象或数组]
  182. * @return {[type]} [度分秒]
  183. */
  184. L.Util.formatHMS = function(latlng) {
  185. var lat = latlng.hasOwnProperty('lat') ? latlng.lat : latlng[0];
  186. var lng = latlng.hasOwnProperty('lng') ? latlng.lng : latlng[1];
  187. lng = lng%360;
  188. if(lng>180){
  189. lng = (lng%180)-180;
  190. }else if(lng<-180){
  191. lng = 180+(lng%180);
  192. }
  193. function setHMS(f) {
  194. f = parseInt(f * 3600);
  195. var h = parseInt(f / 3600);
  196. var m = parseInt((f - h * 3600) / 60);
  197. var s = parseInt((f - h * 3600 - m * 60));
  198. if (m.toString().length == 1) {
  199. m = '0' + m.toString();
  200. }
  201. if (s.toString().length == 1) {
  202. s = '0' + s.toString();
  203. }
  204. return h + '\u00b0' + m + '\u2032' + s + '\u2033';
  205. }
  206. var nLat = '';
  207. var nLng = '';
  208. if (lat < 0) {
  209. nLat = setHMS(lat * -1)+'S';
  210. } else {
  211. nLat = setHMS(lat)+'N';
  212. }
  213. if (lng < 0) {
  214. nLng = setHMS(lng * -1)+'W';
  215. } else {
  216. nLng = setHMS(lng)+'E';
  217. }
  218. return {
  219. lat: nLat,
  220. lng: nLng
  221. };
  222. };
  223. /**
  224. * 度分秒转经纬度
  225. * @param {[type]} p [方位]
  226. * @param {[type]} d [度]
  227. * @param {[type]} f [分]
  228. * @param {[type]} m [秒]
  229. */
  230. L.Util.HMStoLatLng = function(p, d, f, m) {
  231. var dfm = parseFloat(d) + parseFloat(f) / 60 + parseFloat(m) / 3600;
  232. if (p.toLowerCase() === 'w' || p.toLowerCase() === 's') {
  233. dfm = -1 * dfm;
  234. }
  235. return dfm;
  236. };
  237. /**
  238. * 获取弧线的节点坐标数组
  239. * @type {Function}
  240. * @param points
  241. * @returns {Array}
  242. * @private
  243. */
  244. L.Util.getCurvePoints = function(points){
  245. var getCurve = function(start,finish,segments){
  246. var startlat = start.lat;
  247. var startlon = start.lng;
  248. var finishlat = finish.lat;
  249. var finishlon = finish.lng;
  250. var segments = segments;
  251. var curveAry = [];
  252. var lat1 = startlat * (Math.PI / 180);
  253. var lon1 = startlon * (Math.PI / 180);
  254. var lat2 = finishlat * (Math.PI / 180);
  255. var lon2 = finishlon * (Math.PI / 180);
  256. 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)));
  257. for(var n= 0; n<segments+1;n++){
  258. var f = (1/segments)*n;
  259. var A = Math.sin((1-f)*d)/Math.sin(d);
  260. var B = Math.sin(f*d)/Math.sin(d);
  261. var x = A * Math.cos(lat1)*Math.cos(lon1) + B*Math.cos(lat2)*Math.cos(lon2);
  262. var y = A * Math.cos(lat1)*Math.sin(lon1) + B*Math.cos(lat2)*Math.sin(lon2);
  263. var z = A * Math.sin(lat1) + B * Math.sin(lat2);
  264. var lat = Math.atan2(z,Math.sqrt(Math.pow(x,2)+Math.pow(y,2)));
  265. var lon = Math.atan2(y,x);
  266. try{
  267. var temp = L.latLng(lat/(Math.PI/180),lon/(Math.PI/180));
  268. curveAry.push(temp);
  269. }catch (e){
  270. }
  271. }
  272. return curveAry;
  273. };
  274. var curvePoints = [];
  275. for(var i = 0; i < points.length-1;i++){
  276. if(points[i]['lat'] == points[i+1]['lat'] && points[i]['lng'] == points[i+1]['lng']){
  277. curvePoints = curvePoints.concat(points[i]);
  278. }else {
  279. var p = getCurve(points[i],points[i+1],20);
  280. if(p && p.length > 0){
  281. curvePoints = curvePoints.concat(p);
  282. }
  283. }
  284. }
  285. return curvePoints;
  286. },
  287. /**
  288. * 画大圆标注坐标转换
  289. */
  290. L.Util.circleDrawLatlng = function(poly){
  291. var distance = [];
  292. var lineDistance;
  293. if(poly._latlngs.length ===1){
  294. poly._latlngs = poly._latlngs[0];
  295. for(i=0,l=poly._latlngs.length;i<l;i++){
  296. if(i<poly._latlngs.length-1){
  297. lineDistance = poly._latlngs[i].distanceTo(poly._latlngs[i+1]);
  298. }
  299. else{
  300. lineDistance = poly._latlngs[i].distanceTo(poly._latlngs[0]);
  301. }
  302. distance.push(lineDistance);
  303. }
  304. }else{
  305. for(i=0,l=poly._latlngs.length;i<l;i++){
  306. if(i<poly._latlngs.length-1){
  307. lineDistance = poly._latlngs[i].distanceTo(poly._latlngs[i+1]);
  308. distance.push(lineDistance);
  309. }
  310. }
  311. }
  312. var segments;
  313. var bigcurveAry = [];
  314. for (i = 0, l = poly._latlngs.length; i < l ; i++) {
  315. var startlat = poly._latlngs[i].lat;
  316. var startlon = poly._latlngs[i].lng;
  317. if(i==poly._latlngs.length-1){
  318. var finishlat = poly._latlngs[0].lat;
  319. var finishlon = poly._latlngs[0].lng;
  320. }
  321. else{
  322. var finishlat = poly._latlngs[i + 1].lat;
  323. var finishlon = poly._latlngs[i + 1].lng;
  324. }
  325. var curveAry = [];
  326. var lat1 = startlat * (Math.PI / 180);
  327. var lon1 = startlon * (Math.PI / 180);
  328. var lat2 = finishlat * (Math.PI / 180);
  329. var lon2 = finishlon * (Math.PI / 180);
  330. 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)));
  331. segments = Math.ceil((distance[i] / 1000) / 100);
  332. for (var n = 0; n < segments + 1; n++) {
  333. var f = (1 / segments) * n;
  334. var A = Math.sin((1 - f) * d) / Math.sin(d);
  335. var B = Math.sin(f * d) / Math.sin(d);
  336. var x = A * Math.cos(lat1) * Math.cos(lon1) + B * Math.cos(lat2) * Math.cos(lon2);
  337. var y = A * Math.cos(lat1) * Math.sin(lon1) + B * Math.cos(lat2) * Math.sin(lon2);
  338. var z = A * Math.sin(lat1) + B * Math.sin(lat2);
  339. var lat = Math.atan2(z, Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));
  340. var lon = Math.atan2(y, x);
  341. try {
  342. var temp = L.latLng(lat / (Math.PI / 180), lon / (Math.PI / 180));
  343. curveAry.push(temp);
  344. bigcurveAry.push(temp);
  345. } catch (e) {
  346. }
  347. }
  348. }
  349. //return bigcurveAry;
  350. poly.setLatLngs(bigcurveAry);
  351. },
  352. /**
  353. * ajax 方法 支持jsonp
  354. * @param {[type]} url [提交url]
  355. * @param {[type]} options [参数]
  356. * @param {Function} cb [回调方法]
  357. * @return {[type]} [description]
  358. */
  359. L.Util.ajax = function (url,options, cb) {
  360. var cbName,ourl,cbSuffix,scriptNode, head, cbParam, XMHreq;
  361. try{
  362. if(typeof options === "function"){
  363. cb = options;
  364. options = {};
  365. }
  366. if(options.jsonp){
  367. head = document.getElementsByTagName('head')[0];
  368. cbParam = options.cbParam || "callback";
  369. if(options.callbackName){
  370. cbName= options.callbackName;
  371. }else{
  372. cbSuffix = "_" + ("" + Math.random()).slice(2);
  373. cbName = "L.Util.ajax.cb." + cbSuffix;
  374. }
  375. scriptNode = document.createElement('script');
  376. scriptNode.setAttribute('type','text/javascript');
  377. if (url.indexOf("?") === -1 ){
  378. ourl = url+"?"+cbParam+"="+cbName;
  379. }else{
  380. ourl = url+"&"+cbParam+"="+cbName;
  381. }
  382. scriptNode.setAttribute('src',ourl);
  383. head.appendChild(scriptNode);
  384. if(cbSuffix) {
  385. L.Util.ajax.cb[cbSuffix] = function(data){
  386. delete L.Util.ajax.cb[cbSuffix];
  387. cb(data);
  388. head.removeChild(scriptNode);
  389. };
  390. }
  391. return {abort:function(){return false;}};
  392. }else{
  393. // the following is from JavaScript: The Definitive Guide
  394. if (window.XMLHttpRequest === undefined) {
  395. XMHreq = function() {
  396. try {
  397. return new ActiveXObject("Microsoft.XMLHTTP");
  398. //return new ActiveXObject("Microsoft.XMLHTTP.6.0");
  399. }
  400. catch (e1) {
  401. try {
  402. return new ActiveXObject("Microsoft.XMLHTTP.3.0");
  403. }
  404. catch (e2) {
  405. throw new Error("XMLHttpRequest is not supported");
  406. }
  407. }
  408. };
  409. }else{
  410. XMHreq = window.XMLHttpRequest;
  411. }
  412. var response, request = new XMHreq();
  413. request.open("GET", url);
  414. request.onreadystatechange = function() {
  415. if (request.readyState === 4 && request.status === 200) {
  416. if(window.JSON) {
  417. response = JSON.parse(request.responseText);
  418. } else {
  419. response = eval("("+ request.responseText + ")");
  420. }
  421. cb(response);
  422. }
  423. };
  424. request.send();
  425. return request;
  426. }
  427. }catch (e){
  428. cb(e);
  429. }
  430. };
  431. L.Util.ajax.cb = {};
  432. L.DefaultImagePath = (function () {
  433. var scripts = document.getElementsByTagName('script'),
  434. leafletRe = /[\/^]map23dlib[\-\._]?([\w\-\._]*)\.js\??/;
  435. var i, len, src, path;
  436. for (i = 0, len = scripts.length; i < len; i++) {
  437. src = scripts[i].src || '';
  438. if (src.match(leafletRe)) {
  439. path = src.split(leafletRe)[0];
  440. return (path ? path + '/' : '') + 'images';
  441. }
  442. }
  443. }());
  444. if(!L.DefaultImagePath){
  445. L.DefaultImagePath = '/dist/images'
  446. }
  447. L.Map.include({
  448. setZoomScope:function(minZoom,maxZoom){
  449. if(maxZoom >= minZoom){
  450. this.options.minZoom = minZoom;
  451. this.options.maxZoom = maxZoom;
  452. this.fire('zoomlevelschange');
  453. }
  454. }
  455. });
  456. L.Control.include({
  457. addTo: function (map) {
  458. this.remove();
  459. this._map = map;
  460. var container = this._container = this.onAdd(map),
  461. pos = this.getPosition(),
  462. corner = map._controlCorners[pos];
  463. L.DomUtil.addClass(container, 'leaflet-control');
  464. if (pos.indexOf('bottom') !== -1) {
  465. corner.insertBefore(container, corner.firstChild);
  466. } else {
  467. corner.appendChild(container);
  468. }
  469. if(this._callBack){
  470. this._callBack();
  471. }
  472. return this;
  473. }
  474. });
  475. L.Map.include({
  476. _initControlPos: function () {
  477. var corners = this._controlCorners = {},
  478. l = 'leaflet-',
  479. container = this._controlContainer =
  480. L.DomUtil.create('div', l + 'control-container', this._container);
  481. function createCorner(vSide, hSide) {
  482. var className = l + vSide + ' ' + l + hSide;
  483. corners[vSide + hSide] = L.DomUtil.create('div', className, container);
  484. }
  485. createCorner('top', 'left');
  486. createCorner('top', 'center');
  487. createCorner('top', 'right');
  488. createCorner('bottom', 'left');
  489. createCorner('bottom', 'center');
  490. createCorner('bottom', 'right');
  491. }
  492. });
  493. /*!
  494. * Copyright (c) 2012, Smartrak, David Leaver
  495. * Leaflet.utfgrid is an open-source JavaScript library that provides utfgrid interaction on leaflet powered maps.
  496. * https://github.com/danzel/Leaflet.utfgrid
  497. *
  498. * @license MIT
  499. */
  500. (function (window, undefined) {
  501. L.Util.utfgridAjax = function (url, success, error) {
  502. // the following is from JavaScript: The Definitive Guide
  503. // and https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest_in_IE6
  504. if (window.XMLHttpRequest === undefined) {
  505. window.XMLHttpRequest = function () {
  506. /*global ActiveXObject:true */
  507. try {
  508. return new ActiveXObject("Microsoft.XMLHTTP");
  509. }
  510. catch (e) {
  511. throw new Error("XMLHttpRequest is not supported");
  512. }
  513. };
  514. }
  515. var response, request = new XMLHttpRequest();
  516. request.open("GET", url);
  517. request.onreadystatechange = function () {
  518. /*jshint evil: true */
  519. if (request.readyState === 4) {
  520. if (request.status === 200) {
  521. if (window.JSON) {
  522. response = JSON.parse(request.responseText);
  523. } else {
  524. response = eval("(" + request.responseText + ")");
  525. }
  526. success(response);
  527. } else if (request.status !== 0 && error !== undefined) {
  528. error(request.status);
  529. }
  530. }
  531. };
  532. request.ontimeout = function () { error('timeout'); };
  533. request.send();
  534. return request;
  535. };
  536. L.UtfGrid = (L.Layer || L.Class).extend({
  537. includes: L.Mixin.Events,
  538. options: {
  539. subdomains: map23DConfig.tileSubdomains||'',
  540. minZoom: 0,
  541. maxZoom: 18,
  542. tileSize: 256,
  543. resolution: 4,
  544. useJsonP: true,
  545. pointerCursor: true,
  546. maxRequests: 4,
  547. requestTimeout: 60000
  548. },
  549. //The thing the mouse is currently on
  550. _mouseOn: null,
  551. initialize: function (url, options) {
  552. L.Util.setOptions(this, options);
  553. // The requests
  554. this._requests = {};
  555. this._request_queue = [];
  556. this._requests_in_process = [];
  557. this._url = url;
  558. this._cache = {};
  559. //Find a unique id in window we can use for our callbacks
  560. //Required for jsonP
  561. var i = 0;
  562. while (window['lu' + i]) {
  563. i++;
  564. }
  565. this._windowKey = 'lu' + i;
  566. window[this._windowKey] = {};
  567. var subdomains = this.options.subdomains;
  568. if (typeof this.options.subdomains === 'string') {
  569. this.options.subdomains = subdomains.split('');
  570. }
  571. },
  572. onAdd: function (map) {
  573. this._map = map;
  574. this._container = this._map._container;
  575. this._update();
  576. var zoom = Math.round(this._map.getZoom());
  577. if (zoom > this.options.maxZoom || zoom < this.options.minZoom) {
  578. return;
  579. }
  580. map.on('click', this._click, this);
  581. map.on('mousemove', this._move, this);
  582. map.on('moveend', this._update, this);
  583. },
  584. onRemove: function () {
  585. var map = this._map;
  586. map.off('click', this._click, this);
  587. map.off('mousemove', this._move, this);
  588. map.off('moveend', this._update, this);
  589. if (this.options.pointerCursor) {
  590. this._container.style.cursor = '';
  591. }
  592. },
  593. setUrl: function (url, noRedraw) {
  594. this._url = url;
  595. if (!noRedraw) {
  596. this.redraw();
  597. }
  598. return this;
  599. },
  600. redraw: function () {
  601. // Clear cache to force all tiles to reload
  602. this._request_queue = [];
  603. for (var req_key in this._requests) {
  604. if (this._requests.hasOwnProperty(req_key)) {
  605. this._abort_request(req_key);
  606. }
  607. }
  608. this._cache = {};
  609. this._update();
  610. },
  611. _click: function (e) {
  612. this.fire('click', this._objectForEvent(e));
  613. },
  614. _move: function (e) {
  615. var on = this._objectForEvent(e);
  616. if (on.data !== this._mouseOn) {
  617. if (this._mouseOn) {
  618. this.fire('mouseout', { latlng: e.latlng, data: this._mouseOn });
  619. if (this.options.pointerCursor) {
  620. this._container.style.cursor = '';
  621. }
  622. }
  623. if (on.data) {
  624. this.fire('mouseover', on);
  625. if (this.options.pointerCursor) {
  626. this._container.style.cursor = 'pointer';
  627. }
  628. }
  629. this._mouseOn = on.data;
  630. } else if (on.data) {
  631. this.fire('mousemove', on);
  632. }
  633. },
  634. _objectForEvent: function (e) {
  635. var map = this._map,
  636. point = map.project(e.latlng),
  637. tileSize = this.options.tileSize,
  638. resolution = this.options.resolution,
  639. x = Math.floor(point.x / tileSize),
  640. y = Math.floor(point.y / tileSize),
  641. gridX = Math.floor((point.x - (x * tileSize)) / resolution),
  642. gridY = Math.floor((point.y - (y * tileSize)) / resolution),
  643. max = map.options.crs.scale(map.getZoom()) / tileSize;
  644. x = (x + max) % max;
  645. y = (y + max) % max;
  646. var data = this._cache[map.getZoom() + '_' + x + '_' + y];
  647. var result = null;
  648. if (data && data.grid) {
  649. var idx = this._utfDecode(data.grid[gridY].charCodeAt(gridX)),
  650. key = data.keys[idx];
  651. if (data.data.hasOwnProperty(key)) {
  652. result = data.data[key];
  653. }
  654. }
  655. return L.extend({ latlng: e.latlng, data: result }, e);
  656. },
  657. //Load up all required json grid files
  658. //TODO: Load from center etc
  659. _update: function () {
  660. var bounds = this._map.getPixelBounds(),
  661. zoom = Math.round(this._map.getZoom()),
  662. tileSize = this.options.tileSize;
  663. if (zoom > this.options.maxZoom || zoom < this.options.minZoom) {
  664. return;
  665. }
  666. var nwTilePoint = new L.Point(
  667. Math.floor(bounds.min.x / tileSize),
  668. Math.floor(bounds.min.y / tileSize)),
  669. seTilePoint = new L.Point(
  670. Math.floor(bounds.max.x / tileSize),
  671. Math.floor(bounds.max.y / tileSize)),
  672. max = this._map.options.crs.scale(zoom) / tileSize;
  673. //Load all required ones
  674. var visible_tiles = [];
  675. for (var x = nwTilePoint.x; x <= seTilePoint.x; x++) {
  676. for (var y = nwTilePoint.y; y <= seTilePoint.y; y++) {
  677. var xw = (x + max) % max, yw = (y + max) % max;
  678. var key = zoom + '_' + xw + '_' + yw;
  679. visible_tiles.push(key);
  680. if (!this._cache.hasOwnProperty(key)) {
  681. this._cache[key] = null;
  682. if (this.options.useJsonP) {
  683. this._loadTileP(zoom, xw, yw);
  684. } else {
  685. this._loadTile(zoom, xw, yw);
  686. }
  687. }
  688. }
  689. }
  690. // If we still have requests for tiles that have now gone out of sight, attempt to abort them.
  691. for (var req_key in this._requests) {
  692. if (visible_tiles.indexOf(req_key) < 0) {
  693. this._abort_request(req_key);
  694. }
  695. }
  696. },
  697. _loadTileP: function (zoom, x, y) {
  698. var head = document.getElementsByTagName('head')[0],
  699. key = zoom + '_' + x + '_' + y,
  700. functionName = 'lu_' + key,
  701. wk = this._windowKey,
  702. self = this;
  703. var url = L.Util.template(this._url, L.Util.extend({
  704. s: L.TileLayer.prototype._getSubdomain.call(this, { x: x, y: y }),
  705. z: zoom,
  706. x: x,
  707. y: y,
  708. cb: wk + '.' + functionName
  709. }, this.options));
  710. var script = document.createElement('script');
  711. script.setAttribute("type", "text/javascript");
  712. script.setAttribute("src", url);
  713. window[wk][functionName] = function (data) {
  714. try {
  715. self._cache[key] = data;
  716. delete window[wk][functionName];
  717. head.removeChild(script);
  718. self._finish_request(key);
  719. }
  720. catch (e) {
  721. }
  722. };
  723. this._queue_request(key, url, function () {
  724. head.appendChild(script);
  725. return {
  726. abort: function () {
  727. head.removeChild(script);
  728. }
  729. };
  730. });
  731. },
  732. _loadTile: function (zoom, x, y) {
  733. var url = L.Util.template(this._url, L.Util.extend({
  734. s: L.TileLayer.prototype._getSubdomain.call(this, { x: x, y: y }),
  735. z: zoom,
  736. x: x,
  737. y: y
  738. }, this.options));
  739. var key = zoom + '_' + x + '_' + y;
  740. this._queue_request(key, url, this._ajaxRequestFactory(key, url));
  741. },
  742. _ajaxRequestFactory: function (key, url) {
  743. var successCallback = this._successCallbackFactory(key);
  744. var errorCallback = this._errorCallbackFactory(url);
  745. return function () {
  746. var request = L.Util.utfgridAjax(url, successCallback, errorCallback);
  747. request.timeout = this.options.requestTimeout;
  748. return request;
  749. }.bind(this);
  750. },
  751. _successCallbackFactory: function (key) {
  752. return function (data) {
  753. this._cache[key] = data;
  754. this._finish_request(key);
  755. }.bind(this);
  756. },
  757. _errorCallbackFactory: function (tileurl) {
  758. return function (statuscode) {
  759. this.fire('tileerror', {
  760. url: tileurl,
  761. code: statuscode
  762. });
  763. }.bind(this);
  764. },
  765. _queue_request: function (key, url, callback) {
  766. this._requests[key] = {
  767. callback: callback,
  768. timeout: null,
  769. handler: null,
  770. url: url
  771. };
  772. this._request_queue.push(key);
  773. this._process_queued_requests();
  774. },
  775. _finish_request: function (key) {
  776. // Remove from requests in process
  777. var pos = this._requests_in_process.indexOf(key);
  778. if (pos >= 0) {
  779. this._requests_in_process.splice(pos, 1);
  780. }
  781. // Remove from request queue
  782. pos = this._request_queue.indexOf(key);
  783. if (pos >= 0) {
  784. this._request_queue.splice(pos, 1);
  785. }
  786. // Remove the request entry
  787. if (this._requests[key]) {
  788. if (this._requests[key].timeout) {
  789. window.clearTimeout(this._requests[key].timeout);
  790. }
  791. delete this._requests[key];
  792. }
  793. // Recurse
  794. this._process_queued_requests();
  795. // Fire 'load' event if all tiles have been loaded
  796. if (this._requests_in_process.length === 0) {
  797. this.fire('load');
  798. }
  799. },
  800. _abort_request: function (key) {
  801. // Abort the request if possible
  802. if (this._requests[key] && this._requests[key].handler) {
  803. if (typeof this._requests[key].handler.abort === 'function') {
  804. this._requests[key].handler.abort();
  805. }
  806. }
  807. // Ensure we don't keep a false copy of the data in the cache
  808. if (this._cache[key] === null) {
  809. delete this._cache[key];
  810. }
  811. // And remove the request
  812. this._finish_request(key);
  813. },
  814. _process_queued_requests: function () {
  815. while (this._request_queue.length > 0 && (this.options.maxRequests === 0 ||
  816. this._requests_in_process.length < this.options.maxRequests)) {
  817. this._process_request(this._request_queue.pop());
  818. }
  819. },
  820. _process_request: function (key) {
  821. this._requests_in_process.push(key);
  822. // The callback might call _finish_request, so don't assume _requests[key] still exists.
  823. var handler = this._requests[key].callback();
  824. if (this._requests[key]) {
  825. this._requests[key].handler = handler;
  826. if (handler.timeout === undefined) {
  827. var timeoutCallback = this._timeoutCallbackFactory(key);
  828. this._requests[key].timeout = window.setTimeout(timeoutCallback, this.options.requestTimeout);
  829. }
  830. }
  831. },
  832. _timeoutCallbackFactory: function (key) {
  833. var tileurl = this._requests[key].url;
  834. return function () {
  835. this.fire('tileerror', { url: tileurl, code: 'timeout' });
  836. this._abort_request(key);
  837. }.bind(this);
  838. },
  839. _utfDecode: function (c) {
  840. if (c >= 93) {
  841. c--;
  842. }
  843. if (c >= 35) {
  844. c--;
  845. }
  846. return c - 32;
  847. }
  848. });
  849. L.utfGrid = function (url, options) {
  850. return new L.UtfGrid(url, options);
  851. };
  852. }(window));
  853. /*
  854. Leaflet.label, a plugin that adds labels to markers and vectors for Leaflet powered maps.
  855. (c) 2012-2013, Jacob Toye, Smartrak
  856. https://github.com/Leaflet/Leaflet.label
  857. http://leafletjs.com
  858. https://github.com/jacobtoye
  859. */
  860. (function () {
  861. //var L = window.L;
  862. /*
  863. * Leaflet.label assumes that you have already included the Leaflet library.
  864. */
  865. //L.labelVersion = '0.2.2-dev';
  866. L.Label = (L.Layer ? L.Layer : L.Class).extend({
  867. includes: L.Mixin.Events,
  868. options: {
  869. className: '',
  870. clickable: false,
  871. direction: 'auto',
  872. noHide: false,
  873. offset: [13, -16], // 6 (width of the label triangle) + 6 (padding)
  874. opacity: 1,
  875. zoomAnimation: true
  876. },
  877. initialize: function (options, source) {
  878. L.setOptions(this, options);
  879. this._source = source;
  880. this._animated = L.Browser.any3d && this.options.zoomAnimation;
  881. this._isOpen = false;
  882. },
  883. onAdd: function (map) {
  884. this._map = map;
  885. this._pane = this.options.pane ? map._panes[this.options.pane] :
  886. this._source instanceof L.Marker ? map._panes.markerPane : map._panes.popupPane;
  887. if (!this._container) {
  888. this._initLayout();
  889. }
  890. this._pane.appendChild(this._container);
  891. this._initInteraction();
  892. this._update();
  893. this.setOpacity(this.options.opacity);
  894. map
  895. .on('moveend', this._onMoveEnd, this)
  896. .on('viewreset', this._onViewReset, this);
  897. if (this._animated) {
  898. map.on('zoomanim', this._zoomAnimation, this);
  899. }
  900. if (L.Browser.touch && !this.options.noHide) {
  901. L.DomEvent.on(this._container, 'click', this.close, this);
  902. map.on('click', this.close, this);
  903. }
  904. },
  905. onRemove: function (map) {
  906. this._pane.removeChild(this._container);
  907. map.off({
  908. zoomanim: this._zoomAnimation,
  909. moveend: this._onMoveEnd,
  910. viewreset: this._onViewReset
  911. }, this);
  912. this._removeInteraction();
  913. this._map = null;
  914. },
  915. setLatLng: function (latlng) {
  916. this._latlng = L.latLng(latlng);
  917. if (this._map) {
  918. this._updatePosition();
  919. }
  920. return this;
  921. },
  922. setContent: function (content) {
  923. // Backup previous content and store new content
  924. this._previousContent = this._content;
  925. this._content = content;
  926. this._updateContent();
  927. return this;
  928. },
  929. close: function () {
  930. var map = this._map;
  931. if (map) {
  932. if (L.Browser.touch && !this.options.noHide) {
  933. L.DomEvent.off(this._container, 'click', this.close);
  934. map.off('click', this.close, this);
  935. }
  936. map.removeLayer(this);
  937. }
  938. },
  939. updateZIndex: function (zIndex) {
  940. this._zIndex = zIndex;
  941. if (this._container && this._zIndex) {
  942. this._container.style.zIndex = zIndex;
  943. }
  944. },
  945. setOpacity: function (opacity) {
  946. this.options.opacity = opacity;
  947. if (this._container) {
  948. L.DomUtil.setOpacity(this._container, opacity);
  949. }
  950. },
  951. _initLayout: function () {
  952. this._container = L.DomUtil.create('div', 'leaflet-label ' + this.options.className + ' leaflet-zoom-animated');
  953. this.updateZIndex(this._zIndex);
  954. },
  955. _update: function () {
  956. if (!this._map) { return; }
  957. this._container.style.visibility = 'hidden';
  958. this._updateContent();
  959. this._updatePosition();
  960. this._container.style.visibility = '';
  961. },
  962. _updateContent: function () {
  963. if (!this._content || !this._map || this._prevContent === this._content) {
  964. return;
  965. }
  966. if (typeof this._content === 'string') {
  967. this._container.innerHTML = this._content;
  968. this._prevContent = this._content;
  969. this._labelWidth = this._container.offsetWidth;
  970. }else {
  971. this._container.appendChild(this._content);
  972. this._prevContent = this._content;
  973. this._labelWidth = this._container.offsetWidth;
  974. }
  975. //==S== 修改标记
  976. L.DomUtil.create('div','leaflet-label-tips',this._container);
  977. //==E== 修改标记
  978. },
  979. _updatePosition: function () {
  980. var pos = this._map.latLngToLayerPoint(this._latlng);
  981. this._setPosition(pos);
  982. },
  983. _setPosition: function (pos) {
  984. var map = this._map,
  985. container = this._container,
  986. centerPoint = map.latLngToContainerPoint(map.getCenter()),
  987. labelPoint = map.layerPointToContainerPoint(pos),
  988. direction = this.options.direction,
  989. labelWidth = this._labelWidth,
  990. offset = L.point(this.options.offset);
  991. // position to the right (right or auto & needs to)
  992. if (direction === 'right' || direction === 'auto' && labelPoint.x < centerPoint.x) {
  993. L.DomUtil.addClass(container, 'leaflet-label-right');
  994. L.DomUtil.removeClass(container, 'leaflet-label-left');
  995. pos = pos.add(offset);
  996. } else { // position to the left
  997. L.DomUtil.addClass(container, 'leaflet-label-left');
  998. L.DomUtil.removeClass(container, 'leaflet-label-right');
  999. pos = pos.add(L.point(-offset.x - labelWidth, offset.y));
  1000. }
  1001. L.DomUtil.setPosition(container, pos);
  1002. },
  1003. _zoomAnimation: function (opt) {
  1004. var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round();
  1005. this._setPosition(pos);
  1006. },
  1007. _onMoveEnd: function () {
  1008. if (!this._animated || this.options.direction === 'auto') {
  1009. this._updatePosition();
  1010. }
  1011. },
  1012. _onViewReset: function (e) {
  1013. /* if map resets hard, we must update the label */
  1014. if (e && e.hard) {
  1015. this._update();
  1016. }
  1017. },
  1018. _initInteraction: function () {
  1019. if (!this.options.clickable) { return; }
  1020. var container = this._container,
  1021. events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu'];
  1022. L.DomUtil.addClass(container, 'leaflet-clickable');
  1023. L.DomEvent.on(container, 'click', this._onMouseClick, this);
  1024. for (var i = 0; i < events.length; i++) {
  1025. L.DomEvent.on(container, events[i], this._fireMouseEvent, this);
  1026. }
  1027. },
  1028. _removeInteraction: function () {
  1029. if (!this.options.clickable) { return; }
  1030. var container = this._container,
  1031. events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu'];
  1032. L.DomUtil.removeClass(container, 'leaflet-clickable');
  1033. L.DomEvent.off(container, 'click', this._onMouseClick, this);
  1034. for (var i = 0; i < events.length; i++) {
  1035. L.DomEvent.off(container, events[i], this._fireMouseEvent, this);
  1036. }
  1037. },
  1038. _onMouseClick: function (e) {
  1039. if (this.hasEventListeners(e.type)) {
  1040. L.DomEvent.stopPropagation(e);
  1041. }
  1042. this.fire(e.type, {
  1043. originalEvent: e
  1044. });
  1045. },
  1046. _fireMouseEvent: function (e) {
  1047. this.fire(e.type, {
  1048. originalEvent: e
  1049. });
  1050. // TODO proper custom event propagation
  1051. // this line will always be called if marker is in a FeatureGroup
  1052. if (e.type === 'contextmenu' && this.hasEventListeners(e.type)) {
  1053. L.DomEvent.preventDefault(e);
  1054. }
  1055. if (e.type !== 'mousedown') {
  1056. L.DomEvent.stopPropagation(e);
  1057. } else {
  1058. L.DomEvent.preventDefault(e);
  1059. }
  1060. }
  1061. });
  1062. // This object is a mixin for L.Marker and L.CircleMarker. We declare it here as both need to include the contents.
  1063. L.BaseMarkerMethods = {
  1064. showLabel: function () {
  1065. if (this.label && this._map) {
  1066. this.label.setLatLng(this._latlng);
  1067. this._map.showLabel(this.label);
  1068. }
  1069. return this;
  1070. },
  1071. hideLabel: function () {
  1072. if (this.label) {
  1073. this.label.close();
  1074. }
  1075. return this;
  1076. },
  1077. setLabelNoHide: function (noHide) {
  1078. if (this._labelNoHide === noHide) {
  1079. return;
  1080. }
  1081. this._labelNoHide = noHide;
  1082. if (noHide) {
  1083. this._removeLabelRevealHandlers();
  1084. this.showLabel();
  1085. } else {
  1086. this._addLabelRevealHandlers();
  1087. this.hideLabel();
  1088. }
  1089. },
  1090. bindLabel: function (content, options) {
  1091. if(this.label){
  1092. return false;
  1093. }
  1094. var labelAnchor = this.options.icon ? this.options.icon.options.labelAnchor : this.options.labelAnchor,
  1095. anchor = L.point(labelAnchor) || L.point(0, 0);
  1096. anchor = anchor.add(L.Label.prototype.options.offset);
  1097. if (options && options.offset) {
  1098. anchor = anchor.add(options.offset);
  1099. }
  1100. options = L.Util.extend({offset: anchor}, options);
  1101. this._labelNoHide = options.noHide;
  1102. if (!this.label) {
  1103. if (!this._labelNoHide) {
  1104. this._addLabelRevealHandlers();
  1105. }
  1106. this
  1107. .on('remove', this.hideLabel, this)
  1108. .on('move', this._moveLabel, this)
  1109. .on('add', this._onMarkerAdd, this);
  1110. this._hasLabelHandlers = true;
  1111. }
  1112. this.label = new L.Label(options, this)
  1113. .setContent(content);
  1114. return this;
  1115. },
  1116. unbindLabel: function () {
  1117. if (this.label) {
  1118. this.hideLabel();
  1119. this.label = null;
  1120. if (this._hasLabelHandlers) {
  1121. if (!this._labelNoHide) {
  1122. this._removeLabelRevealHandlers();
  1123. }
  1124. this
  1125. .off('remove', this.hideLabel, this)
  1126. .off('move', this._moveLabel, this)
  1127. .off('add', this._onMarkerAdd, this);
  1128. }
  1129. this._hasLabelHandlers = false;
  1130. }
  1131. return this;
  1132. },
  1133. updateLabelContent: function (content) {
  1134. if (this.label) {
  1135. this.label.setContent(content);
  1136. }
  1137. },
  1138. getLabel: function () {
  1139. return this.label;
  1140. },
  1141. _onMarkerAdd: function () {
  1142. if (this._labelNoHide) {
  1143. this.showLabel();
  1144. }
  1145. },
  1146. _addLabelRevealHandlers: function () {
  1147. this
  1148. .on('mouseover', this.showLabel, this)
  1149. .on('mouseout', this.hideLabel, this);
  1150. if (L.Browser.touch) {
  1151. this.on('click', this.showLabel, this);
  1152. }
  1153. },
  1154. _removeLabelRevealHandlers: function () {
  1155. this
  1156. .off('mouseover', this.showLabel, this)
  1157. .off('mouseout', this.hideLabel, this);
  1158. if (L.Browser.touch) {
  1159. this.off('click', this.showLabel, this);
  1160. }
  1161. },
  1162. _moveLabel: function (e) {
  1163. this.label.setLatLng(e.latlng);
  1164. }
  1165. };
  1166. // Add in an option to icon that is used to set where the label anchor is
  1167. L.Icon.Default.mergeOptions({
  1168. labelAnchor: new L.Point(4, -15)
  1169. });
  1170. // Have to do this since Leaflet is loaded before this plugin and initializes
  1171. // L.Marker.options.icon therefore missing our mixin above.
  1172. L.Marker.mergeOptions({
  1173. icon: new L.Icon.Default()
  1174. });
  1175. L.Marker.include(L.BaseMarkerMethods);
  1176. L.Marker.include({
  1177. _originalUpdateZIndex: L.Marker.prototype._updateZIndex,
  1178. _updateZIndex: function (offset) {
  1179. var zIndex = this._zIndex + offset;
  1180. this._originalUpdateZIndex(offset);
  1181. if (this.label) {
  1182. this.label.updateZIndex(zIndex);
  1183. }
  1184. },
  1185. _originalSetOpacity: L.Marker.prototype.setOpacity,
  1186. setOpacity: function (opacity, labelHasSemiTransparency) {
  1187. this.options.labelHasSemiTransparency = labelHasSemiTransparency;
  1188. this._originalSetOpacity(opacity);
  1189. },
  1190. _originalUpdateOpacity: L.Marker.prototype._updateOpacity,
  1191. _updateOpacity: function () {
  1192. var absoluteOpacity = this.options.opacity === 0 ? 0 : 1;
  1193. this._originalUpdateOpacity();
  1194. if (this.label) {
  1195. this.label.setOpacity(this.options.labelHasSemiTransparency ? this.options.opacity : absoluteOpacity);
  1196. }
  1197. },
  1198. _originalSetLatLng: L.Marker.prototype.setLatLng,
  1199. setLatLng: function (latlng) {
  1200. if (this.label && !this._labelNoHide) {
  1201. this.hideLabel();
  1202. }
  1203. return this._originalSetLatLng(latlng);
  1204. }
  1205. });
  1206. // Add in an option to icon that is used to set where the label anchor is
  1207. L.CircleMarker.mergeOptions({
  1208. labelAnchor: new L.Point(-5, 5)
  1209. });
  1210. L.CircleMarker.include(L.BaseMarkerMethods);
  1211. L.Path.include({
  1212. bindLabel: function (content, options) {
  1213. if (!this.label || this.label.options !== options) {
  1214. this.label = new L.Label(options, this);
  1215. }
  1216. this.label.setContent(content);
  1217. if (!this._showLabelAdded) {
  1218. this
  1219. .on('mouseover', this._showLabel, this)
  1220. .on('mousemove', this._moveLabel, this)
  1221. .on('mouseout remove', this._hideLabel, this);
  1222. if (L.Browser.touch) {
  1223. this.on('click', this._showLabel, this);
  1224. }
  1225. this._showLabelAdded = true;
  1226. }
  1227. return this;
  1228. },
  1229. unbindLabel: function () {
  1230. if (this.label) {
  1231. this._hideLabel();
  1232. this.label = null;
  1233. this._showLabelAdded = false;
  1234. this
  1235. .off('mouseover', this._showLabel, this)
  1236. .off('mousemove', this._moveLabel, this)
  1237. .off('mouseout remove', this._hideLabel, this);
  1238. }
  1239. return this;
  1240. },
  1241. updateLabelContent: function (content) {
  1242. if (this.label) {
  1243. this.label.setContent(content);
  1244. }
  1245. },
  1246. _showLabel: function (e) {
  1247. this.label.setLatLng(e.latlng);
  1248. this._map.showLabel(this.label);
  1249. },
  1250. _moveLabel: function (e) {
  1251. this.label.setLatLng(e.latlng);
  1252. },
  1253. _hideLabel: function () {
  1254. this.label.close();
  1255. }
  1256. });
  1257. L.Map.include({
  1258. showLabel: function (label) {
  1259. return this.addLayer(label);
  1260. }
  1261. });
  1262. L.FeatureGroup.include({
  1263. // TODO: remove this when AOP is supported in Leaflet, need this as we cannot put code in removeLayer()
  1264. clearLayers: function () {
  1265. this.unbindLabel();
  1266. this.eachLayer(this.removeLayer, this);
  1267. return this;
  1268. },
  1269. bindLabel: function (content, options) {
  1270. return this.invoke('bindLabel', content, options);
  1271. },
  1272. unbindLabel: function () {
  1273. return this.invoke('unbindLabel');
  1274. },
  1275. updateLabelContent: function (content) {
  1276. this.invoke('updateLabelContent', content);
  1277. }
  1278. });
  1279. }(window, document));
  1280. /*
  1281. Leaflet.plabel, a plugin that adds plabels to markers and vectors for Leaflet powered maps.
  1282. (c) 2012-2013, Jacob Toye, Smartrak
  1283. https://github.com/Leaflet/Leaflet.plabel
  1284. http://leafletjs.com
  1285. https://github.com/jacobtoye
  1286. */
  1287. (function () {
  1288. //var L = window.L;
  1289. /*
  1290. * Leaflet.plabel assumes that you have already included the Leaflet library.
  1291. */
  1292. //L.plabelVersion = '0.2.2-dev';
  1293. L.Plabel = (L.Layer ? L.Layer : L.Class).extend({
  1294. includes: L.Mixin.Events,
  1295. options: {
  1296. className: '',
  1297. clickable: true,
  1298. direction: 'right',
  1299. noHide: false,
  1300. offset: [0, 0], // 6 (width of the plabel triangle) + 6 (padding)
  1301. opacity: 1,
  1302. color:'#000000',
  1303. bold:false,
  1304. background:'',
  1305. zoomAnimation: true,
  1306. lineWidth:42.4,
  1307. },
  1308. initialize: function (options, source) {
  1309. L.setOptions(this, options);
  1310. this._source = source;
  1311. this._animated = L.Browser.any3d && this.options.zoomAnimation;
  1312. this._isOpen = false;
  1313. },
  1314. onAdd: function (map) {
  1315. this._map = map;
  1316. this._isOpen = true;
  1317. this._pane = this.options.pane ? map._panes[this.options.pane] :
  1318. this._source instanceof L.Marker ? map._panes.markerPane : map._panes.popupPane;
  1319. if (!this._container) {
  1320. this._initLayout();
  1321. }
  1322. this._pane.appendChild(this._container);
  1323. this._initInteraction();
  1324. this._update();
  1325. this.setOpacity(this.options.opacity);
  1326. map
  1327. .on('moveend', this._onMoveEnd, this)
  1328. .on('move',this._onMoveEnd,this)
  1329. .on('viewreset', this._onViewReset, this);
  1330. if (this._animated) {
  1331. map.on('zoomanim', this._zoomAnimation, this);
  1332. }
  1333. // if (L.Browser.touch && !this.options.noHide) {
  1334. // L.DomEvent.on(this._container, 'click', this.close, this);
  1335. // map.on('click', this.close, this);
  1336. // }
  1337. },
  1338. onRemove: function (map) {
  1339. this._pane.removeChild(this._container);
  1340. this._isOpen = false;
  1341. map.off({
  1342. zoomanim: this._zoomAnimation,
  1343. move:this._onMoveEnd,
  1344. moveend: this._onMoveEnd,
  1345. viewreset: this._onViewReset
  1346. }, this);
  1347. this._removeInteraction();
  1348. this._map = null;
  1349. },
  1350. setLatLng: function (latlng) {
  1351. this._latlng = L.latLng(latlng);
  1352. if (this._map) {
  1353. this._updatePosition();
  1354. }
  1355. return this;
  1356. },
  1357. setContent: function (content) {
  1358. // Backup previous content and store new content
  1359. this._previousContent = this._content;
  1360. this._content = content;
  1361. this._updateContent();
  1362. return this;
  1363. },
  1364. setColor:function(color){
  1365. this.options.color = color;
  1366. if (this._container) {
  1367. this._containerLine.style.borderBottomColor = color;
  1368. this._containerText.style.color = color;
  1369. }
  1370. return this;
  1371. },
  1372. setBold:function(flag){
  1373. this.options.bold = flag;
  1374. if (this._container) {
  1375. if(flag){
  1376. this._containerLine.style.borderBottomWidth = '2px';
  1377. this._containerText.style.fontWeight = 800;
  1378. }else{
  1379. this._containerLine.style.borderBottomWidth = '1px';
  1380. this._containerText.style.fontWeight = 400;
  1381. }
  1382. }
  1383. return this;
  1384. },
  1385. setBackground:function(color){
  1386. this.options.background = color;
  1387. if (this._container) {
  1388. if(color){
  1389. this._containerText.style.backgroundColor = color;
  1390. }else{
  1391. this._containerText.style.backgroundColor = '';
  1392. }
  1393. }
  1394. return this;
  1395. },
  1396. close: function () {
  1397. var map = this._map;
  1398. this._isOpen = false;
  1399. if (map) {
  1400. // if (L.Browser.touch && !this.options.noHide) {
  1401. // L.DomEvent.off(this._container, 'click', this.close);
  1402. // map.off('click', this.close, this);
  1403. // }
  1404. map.removeLayer(this);
  1405. }
  1406. },
  1407. updateZIndex: function (zIndex) {
  1408. this._zIndex = zIndex;
  1409. if (this._container && this._zIndex) {
  1410. this._container.style.zIndex = zIndex;
  1411. }
  1412. },
  1413. setOpacity: function (opacity) {
  1414. this.options.opacity = opacity;
  1415. if (this._container) {
  1416. L.DomUtil.setOpacity(this._container, opacity);
  1417. }
  1418. },
  1419. _initLayout: function () {
  1420. this._container = L.DomUtil.create('div', 'leaflet-plabel ' + this.options.className + ' leaflet-zoom-animated');
  1421. this._containerLine = L.DomUtil.create('div','leaflet-plabel-line',this._container);
  1422. this._containerText = L.DomUtil.create('div','leaflet-plabel-text',this._container);
  1423. $(this._containerText).dragmove();
  1424. var lleft = Math.pow(Math.pow(this.options.lineWidth,2)/2,0.5)+'px';
  1425. var ltop = -Math.pow(Math.pow(this.options.lineWidth,2)/2,0.5)+'px';
  1426. this._containerText.style.left = lleft;
  1427. this._containerText.style.top = ltop;
  1428. this._containerLine.style.width = this.options.lineWidth+'px';
  1429. this._containerText.style.backgroundColor = this.options.background;
  1430. L.DomEvent.on(this._containerText,'mousedown',function(e){
  1431. this._map.dragging.disable();
  1432. },this)
  1433. L.DomEvent.on(this._containerText,'mousemove',function(e){
  1434. var left = parseInt(this._containerText.style.left||30);
  1435. var top = parseInt(this._containerText.style.top||-30);
  1436. var angle = this._angle({x:0,y:0},{x:left,y:top})
  1437. this._containerLine.style.transform = 'rotate('+angle+'deg)';
  1438. this._containerLine.style.msTransform = 'rotate('+angle+'deg)';
  1439. var lineWidth = Math.pow((Math.abs(left) * Math.abs(left) + Math.abs(top) * Math.abs(top)), 0.5)
  1440. this._containerLine.style.width = lineWidth+'px';
  1441. },this)
  1442. L.DomEvent.on(this._containerText,'mouseup',function(e){
  1443. this._map.dragging.enable();
  1444. },this)
  1445. this.updateZIndex(this._zIndex);
  1446. },
  1447. _angle:function(start,end){
  1448. var diff_x = end.x - start.x,
  1449. diff_y = end.y - start.y;
  1450. //返回角度,不是弧度
  1451. var angle = 360*Math.atan(diff_y/diff_x)/(2*Math.PI);
  1452. if(end.x<start.x){
  1453. angle += 180
  1454. }
  1455. return angle;
  1456. },
  1457. _update: function () {
  1458. if (!this._map) { return; }
  1459. this._container.style.visibility = 'hidden';
  1460. this._updateContent();
  1461. this._updatePosition();
  1462. this._container.style.visibility = '';
  1463. this._containerText.style.backgroundColor = this.options.background;
  1464. if(this.options.bold){
  1465. this._containerLine.style.borderBottomWidth = '2px';
  1466. this._containerText.style.fontWeight = 800;
  1467. }else{
  1468. this._containerLine.style.borderBottomWidth = '1px';
  1469. this._containerText.style.fontWeight = 400;
  1470. }
  1471. this._containerLine.style.borderBottomColor = this.options.color;
  1472. this._containerText.style.color = this.options.color;
  1473. },
  1474. _updateContent: function () {
  1475. if (!this._content || !this._map || this._prevContent === this._content) {
  1476. return;
  1477. }
  1478. if (typeof this._content === 'string') {
  1479. this._containerText.innerHTML = this._content;
  1480. this._prevContent = this._content;
  1481. this._plabelWidth = this._containerText.offsetWidth;
  1482. }else {
  1483. this._containerText.appendChild(this._content);
  1484. this._prevContent = this._content;
  1485. this._plabelWidth = this._containerText.offsetWidth;
  1486. }
  1487. },
  1488. _updatePosition: function () {
  1489. var pos = this._map.latLngToLayerPoint(this._latlng);
  1490. this._setPosition(pos);
  1491. },
  1492. _setPosition: function (pos) {
  1493. var map = this._map,
  1494. container = this._container,
  1495. centerPoint = map.latLngToContainerPoint(map.getCenter()),
  1496. plabelPoint = map.layerPointToContainerPoint(pos),
  1497. direction = this.options.direction,
  1498. plabelWidth = this._plabelWidth,
  1499. offset = L.point(this.options.offset);
  1500. // position to the right (right or auto & needs to)
  1501. if (direction === 'right' || direction === 'auto' && plabelPoint.x < centerPoint.x) {
  1502. L.DomUtil.addClass(container, 'leaflet-plabel-right');
  1503. L.DomUtil.removeClass(container, 'leaflet-plabel-left');
  1504. pos = pos.add(offset);
  1505. } else { // position to the left
  1506. L.DomUtil.addClass(container, 'leaflet-plabel-left');
  1507. L.DomUtil.removeClass(container, 'leaflet-plabel-right');
  1508. pos = pos.add(L.point(-offset.x - plabelWidth, offset.y));
  1509. }
  1510. L.DomUtil.setPosition(container, pos);
  1511. },
  1512. _zoomAnimation: function (opt) {
  1513. var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round();
  1514. this._setPosition(pos);
  1515. },
  1516. _onMoveEnd: function () {
  1517. //if (!this._animated || this.options.direction === 'auto') {
  1518. this._updatePosition();
  1519. //}
  1520. },
  1521. _onViewReset: function (e) {
  1522. /* if map resets hard, we must update the plabel */
  1523. if (e && e.hard) {
  1524. this._update();
  1525. }
  1526. },
  1527. _initInteraction: function () {
  1528. if (!this.options.clickable) { return; }
  1529. var container = this._container,
  1530. events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu'];
  1531. L.DomUtil.addClass(container, 'leaflet-clickable');
  1532. L.DomEvent.on(container, 'click', this._onMouseClick, this);
  1533. for (var i = 0; i < events.length; i++) {
  1534. L.DomEvent.on(container, events[i], this._fireMouseEvent, this);
  1535. }
  1536. },
  1537. _removeInteraction: function () {
  1538. if (!this.options.clickable) { return; }
  1539. var container = this._container,
  1540. events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu'];
  1541. L.DomUtil.removeClass(container, 'leaflet-clickable');
  1542. L.DomEvent.off(container, 'click', this._onMouseClick, this);
  1543. for (var i = 0; i < events.length; i++) {
  1544. L.DomEvent.off(container, events[i], this._fireMouseEvent, this);
  1545. }
  1546. },
  1547. _onMouseClick: function (e) {
  1548. if (this.hasEventListeners(e.type)) {
  1549. L.DomEvent.stopPropagation(e);
  1550. }
  1551. this.fire(e.type, {
  1552. originalEvent: e
  1553. });
  1554. },
  1555. _fireMouseEvent: function (e) {
  1556. this.fire(e.type, {
  1557. originalEvent: e
  1558. });
  1559. // TODO proper custom event propagation
  1560. // this line will always be called if marker is in a FeatureGroup
  1561. if (e.type === 'contextmenu' && this.hasEventListeners(e.type)) {
  1562. L.DomEvent.preventDefault(e);
  1563. }
  1564. if (e.type !== 'mousedown') {
  1565. L.DomEvent.stopPropagation(e);
  1566. } else {
  1567. L.DomEvent.preventDefault(e);
  1568. }
  1569. }
  1570. });
  1571. // This object is a mixin for L.Marker and L.CircleMarker. We declare it here as both need to include the contents.
  1572. L.BasePMarkerMethods = {
  1573. showPlabel: function () {
  1574. if (this.plabel && this._map) {
  1575. this.plabel.setLatLng(this._latlng);
  1576. if(!this.plabel._isOpen){
  1577. this._map.showPlabel(this.plabel);
  1578. }
  1579. }
  1580. return this;
  1581. },
  1582. hidePlabel: function () {
  1583. if (this.plabel) {
  1584. this.plabel.close();
  1585. }
  1586. return this;
  1587. },
  1588. setPlabelNoHide: function (noHide) {
  1589. if (this._plabelNoHide === noHide) {
  1590. return;
  1591. }
  1592. this._plabelNoHide = noHide;
  1593. this.options.noHide = noHide;
  1594. if (noHide) {
  1595. this._removePlabelRevealHandlers();
  1596. this.showPlabel();
  1597. } else {
  1598. this._addPlabelRevealHandlers();
  1599. this.hidePlabel();
  1600. }
  1601. },
  1602. bindPlabel: function (content, options) {
  1603. if(this.plabel){
  1604. return false;
  1605. }
  1606. var plabelAnchor = this.options.icon ? this.options.icon.options.plabelAnchor : this.options.plabelAnchor,
  1607. anchor = L.point(plabelAnchor) || L.point(0, 0);
  1608. anchor = anchor.add(L.Plabel.prototype.options.offset);
  1609. if (options && options.offset) {
  1610. anchor = anchor.add(options.offset);
  1611. }
  1612. options = L.Util.extend({offset: anchor}, options);
  1613. this._plabelNoHide = options.noHide;
  1614. if (!this.plabel) {
  1615. if (!this._plabelNoHide) {
  1616. this._addPlabelRevealHandlers();
  1617. }
  1618. this
  1619. .on('remove', this.hidePlabel, this)
  1620. .on('move', this._movePlabel, this)
  1621. .on('add', this._onPMarkerAdd, this);
  1622. this._hasPlabelHandlers = true;
  1623. }
  1624. this.plabel = new L.Plabel(options, this)
  1625. .setContent(content);
  1626. return this;
  1627. },
  1628. unbindPlabel: function () {
  1629. if (this.plabel) {
  1630. this.hidePlabel();
  1631. this.plabel = null;
  1632. if (this._hasPlabelHandlers) {
  1633. if (!this._plabelNoHide) {
  1634. this._removePlabelRevealHandlers();
  1635. }
  1636. this
  1637. .off('remove', this.hidePlabel, this)
  1638. .off('move', this._movePlabel, this)
  1639. .off('add', this._onPMarkerAdd, this);
  1640. }
  1641. this._hasPlabelHandlers = false;
  1642. }
  1643. return this;
  1644. },
  1645. updatePlabelContent: function (content) {
  1646. if (this.plabel) {
  1647. this.plabel.setContent(content);
  1648. }
  1649. },
  1650. getPlabel: function () {
  1651. return this.plabel;
  1652. },
  1653. _onPMarkerAdd: function () {
  1654. if (this._plabelNoHide) {
  1655. this.showPlabel();
  1656. }
  1657. },
  1658. _addPlabelRevealHandlers: function () {
  1659. this
  1660. .on('mouseover', this.showPlabel, this)
  1661. .on('mouseout', this.hidePlabel, this);
  1662. if (L.Browser.touch) {
  1663. this.on('click', this.showPlabel, this);
  1664. }
  1665. },
  1666. _removePlabelRevealHandlers: function () {
  1667. this
  1668. .off('mouseover', this.showPlabel, this)
  1669. .off('mouseout', this.hidePlabel, this);
  1670. if (L.Browser.touch) {
  1671. this.off('click', this.showPlabel, this);
  1672. }
  1673. },
  1674. _movePlabel: function (e) {
  1675. this.plabel.setLatLng(e.latlng);
  1676. }
  1677. };
  1678. // Add in an option to icon that is used to set where the plabel anchor is
  1679. L.Icon.Default.mergeOptions({
  1680. plabelAnchor: new L.Point(4, -15)
  1681. });
  1682. // Have to do this since Leaflet is loaded before this plugin and initializes
  1683. // L.Marker.options.icon therefore missing our mixin above.
  1684. // L.Marker.mergeOptions({
  1685. // icon: new L.Icon.Default()
  1686. // });
  1687. L.Marker.include(L.BasePMarkerMethods);
  1688. L.Marker.include({
  1689. _originalUpdatePZIndex: L.Marker.prototype._updateZIndex,
  1690. _updateZIndex: function (offset) {
  1691. var zIndex = this._zIndex + offset;
  1692. this._originalUpdatePZIndex(offset);
  1693. if (this.plabel) {
  1694. this.plabel.updateZIndex(zIndex);
  1695. }
  1696. },
  1697. _originalSetPOpacity: L.Marker.prototype.setOpacity,
  1698. setOpacity: function (opacity, plabelHasSemiTransparency) {
  1699. this.options.plabelHasSemiTransparency = plabelHasSemiTransparency;
  1700. this._originalSetPOpacity(opacity);
  1701. },
  1702. _originalUpdatePOpacity: L.Marker.prototype._updateOpacity,
  1703. _updateOpacity: function () {
  1704. var absoluteOpacity = this.options.opacity === 0 ? 0 : 1;
  1705. this._originalUpdatePOpacity();
  1706. if (this.plabel) {
  1707. this.plabel.setOpacity(this.options.plabelHasSemiTransparency ? this.options.opacity : absoluteOpacity);
  1708. }
  1709. },
  1710. _originalPSetLatLng: L.Marker.prototype.setLatLng,
  1711. setLatLng: function (latlng) {
  1712. if (this.plabel) {
  1713. this.plabel.setLatLng(latlng)
  1714. }
  1715. return this._originalPSetLatLng(latlng);
  1716. }
  1717. });
  1718. // Add in an option to icon that is used to set where the plabel anchor is
  1719. L.CircleMarker.mergeOptions({
  1720. plabelAnchor: new L.Point(1, 1)
  1721. });
  1722. L.CircleMarker.include(L.BasePMarkerMethods);
  1723. L.Path.include({
  1724. showPlabel: function () {
  1725. if (this.plabel && this._map) {
  1726. this.plabel.setLatLng(this._latlngs[0]);
  1727. this._map.showPlabel(this.plabel);
  1728. }
  1729. return this;
  1730. },
  1731. hidePlabel: function () {
  1732. if (this.plabel) {
  1733. this.plabel.close();
  1734. }
  1735. return this;
  1736. },
  1737. bindPlabel: function (content, options) {
  1738. if (!this.plabel || this.plabel.options !== options) {
  1739. this.plabel = new L.Plabel(options, this);
  1740. }
  1741. this.plabel.setContent(content);
  1742. //if (!this._showPlabelAdded) {
  1743. // this
  1744. // .on('mouseover', this._showPlabel, this)
  1745. // .on('mousemove', this._movePlabel, this)
  1746. // .on('mouseout remove', this._hidePlabel, this);
  1747. this.on('remove', this._hidePlabel, this);
  1748. if (L.Browser.touch) {
  1749. this.on('click', this._showPlabel, this);
  1750. }
  1751. this._showPlabelAdded = true;
  1752. //}
  1753. return this;
  1754. },
  1755. unbindPlabel: function () {
  1756. if (this.plabel) {
  1757. this._hidePlabel();
  1758. this.plabel = null;
  1759. //this._showPlabelAdded = false;
  1760. // this
  1761. // .off('mouseover', this._showPlabel, this)
  1762. // .off('mousemove', this._movePlabel, this)
  1763. // .off('mouseout remove', this._hidePlabel, this);
  1764. this.off('remove', this._hidePlabel, this);
  1765. }
  1766. return this;
  1767. },
  1768. updatePlabelContent: function (content) {
  1769. if (this.plabel) {
  1770. this.plabel.setContent(content);
  1771. }
  1772. },
  1773. _showPlabel: function (e) {
  1774. this.plabel.setLatLng(e.latlng);
  1775. //this.plabel.setLatLng(this.latlngs[0])
  1776. this._map.showPlabel(this.plabel);
  1777. },
  1778. _movePlabel: function (e) {
  1779. this.plabel.setLatLng(e.latlng);
  1780. },
  1781. _hidePlabel: function () {
  1782. this.plabel.close();
  1783. }
  1784. });
  1785. L.Polyline.include({
  1786. showPlabel: function () {
  1787. if (this.plabel && this._map) {
  1788. var pCenter = this._latlngs[parseInt(this._latlngs.length/2)];
  1789. if(this._latlngs.length == 2){
  1790. pCenter = [(this._latlngs[0].lat+this._latlngs[1].lat)/2,(this._latlngs[0].lng+this._latlngs[1].lng)/2]
  1791. }
  1792. this.plabel.setLatLng(pCenter);
  1793. this._map.showPlabel(this.plabel);
  1794. }
  1795. return this;
  1796. }
  1797. });
  1798. L.Polygon.include({
  1799. showPlabel: function () {
  1800. if (this.plabel && this._map) {
  1801. this.plabel.setLatLng(this.getBounds().getCenter());
  1802. this._map.showPlabel(this.plabel);
  1803. }
  1804. return this;
  1805. }
  1806. });
  1807. L.Circle.include({
  1808. showPlabel: function () {
  1809. if (this.plabel && this._map) {
  1810. this.plabel.setLatLng(this._latlng);
  1811. this._map.showPlabel(this.plabel);
  1812. }
  1813. return this;
  1814. }
  1815. });
  1816. L.Map.include({
  1817. showPlabel: function (plabel) {
  1818. return this.addLayer(plabel);
  1819. }
  1820. });
  1821. L.FeatureGroup.include({
  1822. // TODO: remove this when AOP is supported in Leaflet, need this as we cannot put code in removeLayer()
  1823. clearLayers: function () {
  1824. this.unbindPlabel();
  1825. this.eachLayer(this.removeLayer, this);
  1826. return this;
  1827. },
  1828. bindPlabel: function (content, options) {
  1829. return this.invoke('bindPlabel', content, options);
  1830. },
  1831. unbindPlabel: function () {
  1832. return this.invoke('unbindPlabel');
  1833. },
  1834. updatePlabelContent: function (content) {
  1835. this.invoke('updatePlabelContent', content);
  1836. }
  1837. });
  1838. }(window, document));
  1839. L.AnimatedMarker = L.Marker.extend({
  1840. options: {
  1841. // meters
  1842. distance: 200,
  1843. // ms
  1844. interval: 800,
  1845. //速度倍数
  1846. speedMultiple:0.001,
  1847. // animate on add?
  1848. autoStart: true,
  1849. // callback onend
  1850. onEnd: function(){},
  1851. clickable: false
  1852. },
  1853. initialize: function (latlngs, options) {
  1854. this.setLine(latlngs);
  1855. L.Marker.prototype.initialize.call(this, latlngs[0], options);
  1856. },
  1857. // Breaks the line up into tiny chunks (see options) ONLY if CSS3 animations
  1858. // are not supported.
  1859. _chunk: function(latlngs) {
  1860. var i,
  1861. len = latlngs.length,
  1862. chunkedLatLngs = [];
  1863. for (i=1;i<len;i++) {
  1864. var cur = latlngs[i-1],
  1865. next = latlngs[i],
  1866. dist = cur.distanceTo(next),
  1867. factor = this.options.distance / dist,
  1868. dLat = factor * (next.lat - cur.lat),
  1869. dLng = factor * (next.lng - cur.lng);
  1870. if (dist > this.options.distance) {
  1871. while (dist > this.options.distance) {
  1872. cur = new L.LatLng(cur.lat + dLat, cur.lng + dLng);
  1873. dist = cur.distanceTo(next);
  1874. chunkedLatLngs.push(cur);
  1875. }
  1876. } else {
  1877. chunkedLatLngs.push(cur);
  1878. }
  1879. }
  1880. chunkedLatLngs.push(latlngs[len-1]);
  1881. return chunkedLatLngs;
  1882. },
  1883. onAdd: function (map) {
  1884. L.Marker.prototype.onAdd.call(this, map);
  1885. // Start animating when added to the map
  1886. if (this.options.autoStart) {
  1887. this.start();
  1888. }
  1889. },
  1890. animate: function() {
  1891. map23DControl.anMarkerGon = true;
  1892. var self = this,
  1893. len = this._latlngs.length,
  1894. speed = this.options.speedMultiple;
  1895. var guid = this.guid;
  1896. $.each(map23DData.timeLineData,function(i,t){
  1897. if((guid === i) && (t._i > 0)){
  1898. self._i = t._i;
  1899. t._i = -11;
  1900. }
  1901. });
  1902. // Normalize the transition speed from vertex to vertex
  1903. if (this._i < len && this._i > 0) {
  1904. var maxlength = $("#"+guid+" .Main").width();
  1905. var curlength = Math.round((self._i/(len-1))*maxlength);
  1906. $("#"+guid+" .scroll_Thumb").css("left", curlength -32+ "px");
  1907. $("#"+guid+" .scroll_Track").css("width", curlength + "px");
  1908. $("#"+guid+" .scrollBarTxt").html(self._i + "/" + len);
  1909. 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);
  1910. turnrorate = turnrorate;
  1911. var markerData = map23DData.markers[guid];
  1912. var marker = map2DViewer.markers[guid];
  1913. if(!!markerData){
  1914. 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);" />';
  1915. var setDivIcon = L.divIcon({
  1916. className:'rorate_div',
  1917. html:icon_html,
  1918. iconAnchor:markerData.geojson.properties.iconAnchor,
  1919. iconSize:markerData.geojson.properties.iconSize,
  1920. popupAnchor:markerData.geojson.properties.popupAnchor});
  1921. marker.setIcon(setDivIcon);
  1922. //var curTime = Date.parse(map23DData.markers[guid].geojson.properties.markerTime[this._i-1]);
  1923. //var curPreTime = Date.parse(map23DData.markers[guid].geojson.properties.markerTime[this._i]);
  1924. var curTime = map23DData.markers[guid].geojson.properties.markerTime[this._i-1];
  1925. var curPreTime = map23DData.markers[guid].geojson.properties.markerTime[this._i];
  1926. //marker实时更新信息
  1927. 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));
  1928. this.curOptions = {
  1929. "curTime":curTime,
  1930. "curPreTime":curPreTime,
  1931. "curLatlng":this._latlngs[this._i],
  1932. "curPreLatlng":this._latlngs[this._i -1],
  1933. "curDiatance":curTSpeed
  1934. };
  1935. PubSub.publishSync('curMarkerOptions',guid);
  1936. if(this._i === 1){
  1937. speed = 1;
  1938. }else{
  1939. speed = (curPreTime - curTime)/this.options.speedMultiple;
  1940. }
  1941. }
  1942. }else if(this._i == len){
  1943. }
  1944. map2DViewer.map.on('zoomend',function(){
  1945. /*if (L.DomUtil.TRANSITION) {
  1946. if (this._icon) { this._icon.style[L.DomUtil.TRANSITION] = ('all ' + 1 + 'ms linear'); }
  1947. if (this._shadow) { this._shadow.style[L.DomUtil.TRANSITION] = 'all ' + 1 + 'ms linear'; }
  1948. }
  1949. this.setLatLng(this._latlngs[this._i]);*/
  1950. map23DControl.Speed = true;
  1951. if(!map23DControl.anMarkerGon){
  1952. $.each(map2DViewer.routeBackGroup,function(i,t){
  1953. var animate_data = map2DViewer.routeBackGroup[i].marker;
  1954. if(map23DData.markers[animate_data].visible2D){
  1955. var _this = map2DViewer.markers[animate_data];
  1956. if (L.DomUtil.TRANSITION) {
  1957. if (_this._icon) { _this._icon.style[L.DomUtil.TRANSITION] = ('all ' + 0 + 'ms linear'); }
  1958. if (_this._shadow) { _this._shadow.style[L.DomUtil.TRANSITION] = 'all ' + 0 + 'ms linear'; }
  1959. }
  1960. if(_this._i < _this._latlngs.length){
  1961. _this.setLatLng(_this._latlngs[_this._i]);
  1962. _this['_i'] = _this._i;
  1963. }
  1964. }
  1965. })
  1966. }
  1967. })
  1968. // Only if CSS3 transitions are supported
  1969. if (L.DomUtil.TRANSITION) {
  1970. if(map23DControl.Speed){
  1971. if (this._icon) { this._icon.style[L.DomUtil.TRANSITION] = ('all ' + 0 + 'ms linear'); }
  1972. if (this._shadow) { this._shadow.style[L.DomUtil.TRANSITION] = 'all ' + 0 + 'ms linear'; }
  1973. map23DControl.Speed = false;
  1974. }else{
  1975. if (this._icon) { this._icon.style[L.DomUtil.TRANSITION] = ('all ' + speed + 'ms linear'); }
  1976. if (this._shadow) { this._shadow.style[L.DomUtil.TRANSITION] = 'all ' + speed + 'ms linear'; }
  1977. }
  1978. }
  1979. // Move to the next vertex
  1980. this.setLatLng(this._latlngs[this._i]);
  1981. this._i++;
  1982. map23DControl.anMarkerGon = false;
  1983. // Queue up the animation to the next next vertex
  1984. this._tid = setTimeout(function(){
  1985. if (self._i === len) {
  1986. $.each(map2DViewer.routeBackGroup,function(i,t){
  1987. if(map2DViewer.routeBackGroup[i].marker === guid){
  1988. map2DViewer.routeBackGroup[i].isEnd = true;
  1989. PubSub.publishSync('payBackEnd',i);
  1990. };
  1991. })
  1992. self.options.onEnd.apply(self, Array.prototype.slice.call(arguments));
  1993. } else {
  1994. self.animate();
  1995. }
  1996. }, speed);
  1997. },
  1998. // Start the animation
  1999. start: function() {
  2000. this.animate();
  2001. window.marker_Animate = true;
  2002. $.each(map2DViewer.routeBackGroup,function(i,t){
  2003. map2DViewer.routeBackGroup[i].marker === this.guid;
  2004. map2DViewer.routeBackGroup[i].isEnd = false;
  2005. })
  2006. },
  2007. restart:function(){
  2008. this.stop();
  2009. this['_i'] = 0;
  2010. this.start();
  2011. },
  2012. // Stop the animation in place
  2013. stop: function() {
  2014. if (this._tid) {
  2015. clearTimeout(this._tid);
  2016. window.marker_Animate = false;
  2017. //this.animate();
  2018. }
  2019. },
  2020. setLine: function(latlngs){
  2021. if (L.DomUtil.TRANSITION) {
  2022. // No need to to check up the line if we can animate using CSS3
  2023. this._latlngs = latlngs;
  2024. } else {
  2025. // Chunk up the lines into options.distance bits
  2026. this._latlngs = this._chunk(latlngs);
  2027. this.options.distance = 10;
  2028. this.options.interval = 3;
  2029. }
  2030. this._i = 0;
  2031. }
  2032. });
  2033. L.animatedMarker = function (latlngs, options) {
  2034. return new L.AnimatedMarker(latlngs, options);
  2035. };
  2036. /*
  2037. Leaflet.markercluster, Provides Beautiful Animated Marker Clustering functionality for Leaflet, a JS library for interactive maps.
  2038. https://github.com/Leaflet/Leaflet.markercluster
  2039. (c) 2012-2013, Dave Leaver, smartrak
  2040. */
  2041. (function (window, document, undefined) {/*
  2042. * L.MarkerClusterGroup extends L.FeatureGroup by clustering the markers contained within
  2043. */
  2044. L.MarkerClusterGroup = L.FeatureGroup.extend({
  2045. options: {
  2046. maxClusterRadius: 120, //A cluster will cover at most this many pixels from its center
  2047. iconCreateFunction: null,
  2048. spiderfyOnMaxZoom: false,
  2049. showCoverageOnHover: false,
  2050. zoomToBoundsOnClick: true,
  2051. singleMarkerMode: false,
  2052. disableClusteringAtZoom: null,
  2053. // Setting this to false prevents the removal of any clusters outside of the viewpoint, which
  2054. // is the default behaviour for performance reasons.
  2055. removeOutsideVisibleBounds: true,
  2056. // Set to false to disable all animations (zoom and spiderfy).
  2057. // If false, option animateAddingMarkers below has no effect.
  2058. // If L.DomUtil.TRANSITION is falsy, this option has no effect.
  2059. animate: true,
  2060. //Whether to animate adding markers after adding the MarkerClusterGroup to the map
  2061. // If you are adding individual markers set to true, if adding bulk markers leave false for massive performance gains.
  2062. animateAddingMarkers: false,
  2063. //Increase to increase the distance away that spiderfied markers appear from the center
  2064. spiderfyDistanceMultiplier: 1,
  2065. // Make it possible to specify a polyline options on a spider leg
  2066. spiderLegPolylineOptions: { weight: 1, color: '#222', opacity: 0.5 },
  2067. // 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
  2068. chunkedLoading: false,
  2069. chunkInterval: 200, // process markers for a maximum of ~ n milliseconds (then trigger the chunkProgress callback)
  2070. chunkDelay: 50, // at the end of each interval, give n milliseconds back to system/browser
  2071. chunkProgress: null, // progress callback: function(processed, total, elapsed) (e.g. for a progress indicator)
  2072. //Options to pass to the L.Polygon constructor
  2073. polygonOptions: {weight: 1, opacity: 0.5}
  2074. },
  2075. initialize: function (options) {
  2076. L.Util.setOptions(this, options);
  2077. if (!this.options.iconCreateFunction) {
  2078. this.options.iconCreateFunction = this._defaultIconCreateFunction;
  2079. }
  2080. this._featureGroup = L.featureGroup();
  2081. this._featureGroup.addEventParent(this);
  2082. this._nonPointGroup = L.featureGroup();
  2083. this._nonPointGroup.addEventParent(this);
  2084. this._inZoomAnimation = 0;
  2085. this._needsClustering = [];
  2086. this._needsRemoving = []; //Markers removed while we aren't on the map need to be kept track of
  2087. //The bounds of the currently shown area (from _getExpandedVisibleBounds) Updated on zoom/move
  2088. this._currentShownBounds = null;
  2089. this._queue = [];
  2090. // Hook the appropriate animation methods.
  2091. var animate = L.DomUtil.TRANSITION && this.options.animate;
  2092. L.extend(this, animate ? this._withAnimation : this._noAnimation);
  2093. // Remember which MarkerCluster class to instantiate (animated or not).
  2094. this._markerCluster = animate ? L.MarkerCluster : L.MarkerClusterNonAnimated;
  2095. },
  2096. addLayer: function (layer) {
  2097. if (layer instanceof L.LayerGroup) {
  2098. return this.addLayers([layer]);
  2099. }
  2100. //Don't cluster non point data
  2101. if (!layer.getLatLng) {
  2102. this._nonPointGroup.addLayer(layer);
  2103. return this;
  2104. }
  2105. if (!this._map) {
  2106. this._needsClustering.push(layer);
  2107. return this;
  2108. }
  2109. if (this.hasLayer(layer)) {
  2110. return this;
  2111. }
  2112. //If we have already clustered we'll need to add this one to a cluster
  2113. if (this._unspiderfy) {
  2114. this._unspiderfy();
  2115. }
  2116. this._addLayer(layer, this._maxZoom);
  2117. // Refresh bounds and weighted positions.
  2118. this._topClusterLevel._recalculateBounds();
  2119. this._refreshClustersIcons();
  2120. //Work out what is visible
  2121. var visibleLayer = layer,
  2122. currentZoom = this._zoom;
  2123. if (layer.__parent) {
  2124. while (visibleLayer.__parent._zoom >= currentZoom) {
  2125. visibleLayer = visibleLayer.__parent;
  2126. }
  2127. }
  2128. if (this._currentShownBounds.contains(visibleLayer.getLatLng())) {
  2129. if (this.options.animateAddingMarkers) {
  2130. this._animationAddLayer(layer, visibleLayer);
  2131. } else {
  2132. this._animationAddLayerNonAnimated(layer, visibleLayer);
  2133. }
  2134. }
  2135. return this;
  2136. },
  2137. removeLayer: function (layer) {
  2138. if (layer instanceof L.LayerGroup) {
  2139. return this.removeLayers([layer]);
  2140. }
  2141. //Non point layers
  2142. if (!layer.getLatLng) {
  2143. this._nonPointGroup.removeLayer(layer);
  2144. return this;
  2145. }
  2146. if (!this._map) {
  2147. if (!this._arraySplice(this._needsClustering, layer) && this.hasLayer(layer)) {
  2148. this._needsRemoving.push(layer);
  2149. }
  2150. return this;
  2151. }
  2152. if (!layer.__parent) {
  2153. return this;
  2154. }
  2155. if (this._unspiderfy) {
  2156. this._unspiderfy();
  2157. this._unspiderfyLayer(layer);
  2158. }
  2159. //Remove the marker from clusters
  2160. this._removeLayer(layer, true);
  2161. // Refresh bounds and weighted positions.
  2162. this._topClusterLevel._recalculateBounds();
  2163. this._refreshClustersIcons();
  2164. layer.off('move', this._childMarkerMoved, this);
  2165. if (this._featureGroup.hasLayer(layer)) {
  2166. this._featureGroup.removeLayer(layer);
  2167. if (layer.clusterShow) {
  2168. layer.clusterShow();
  2169. }
  2170. }
  2171. return this;
  2172. },
  2173. //Takes an array of markers and adds them in bulk
  2174. addLayers: function (layersArray) {
  2175. if (!L.Util.isArray(layersArray)) {
  2176. return this.addLayer(layersArray);
  2177. }
  2178. var fg = this._featureGroup,
  2179. npg = this._nonPointGroup,
  2180. chunked = this.options.chunkedLoading,
  2181. chunkInterval = this.options.chunkInterval,
  2182. chunkProgress = this.options.chunkProgress,
  2183. l = layersArray.length,
  2184. offset = 0,
  2185. originalArray = true,
  2186. m;
  2187. if (this._map) {
  2188. var started = (new Date()).getTime();
  2189. var process = L.bind(function () {
  2190. var start = (new Date()).getTime();
  2191. for (; offset < l; offset++) {
  2192. if (chunked && offset % 200 === 0) {
  2193. // every couple hundred markers, instrument the time elapsed since processing started:
  2194. var elapsed = (new Date()).getTime() - start;
  2195. if (elapsed > chunkInterval) {
  2196. break; // been working too hard, time to take a break :-)
  2197. }
  2198. }
  2199. m = layersArray[offset];
  2200. // Group of layers, append children to layersArray and skip.
  2201. // Side effects:
  2202. // - Total increases, so chunkProgress ratio jumps backward.
  2203. // - Groups are not included in this group, only their non-group child layers (hasLayer).
  2204. // Changing array length while looping does not affect performance in current browsers:
  2205. // http://jsperf.com/for-loop-changing-length/6
  2206. if (m instanceof L.LayerGroup) {
  2207. if (originalArray) {
  2208. layersArray = layersArray.slice();
  2209. originalArray = false;
  2210. }
  2211. this._extractNonGroupLayers(m, layersArray);
  2212. l = layersArray.length;
  2213. continue;
  2214. }
  2215. //Not point data, can't be clustered
  2216. if (!m.getLatLng) {
  2217. npg.addLayer(m);
  2218. continue;
  2219. }
  2220. if (this.hasLayer(m)) {
  2221. continue;
  2222. }
  2223. this._addLayer(m, this._maxZoom);
  2224. //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
  2225. if (m.__parent) {
  2226. if (m.__parent.getChildCount() === 2) {
  2227. var markers = m.__parent.getAllChildMarkers(),
  2228. otherMarker = markers[0] === m ? markers[1] : markers[0];
  2229. fg.removeLayer(otherMarker);
  2230. }
  2231. }
  2232. }
  2233. if (chunkProgress) {
  2234. // report progress and time elapsed:
  2235. chunkProgress(offset, l, (new Date()).getTime() - started);
  2236. }
  2237. // Completed processing all markers.
  2238. if (offset === l) {
  2239. // Refresh bounds and weighted positions.
  2240. this._topClusterLevel._recalculateBounds();
  2241. this._refreshClustersIcons();
  2242. this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds);
  2243. } else {
  2244. setTimeout(process, this.options.chunkDelay);
  2245. }
  2246. }, this);
  2247. process();
  2248. } else {
  2249. var needsClustering = this._needsClustering;
  2250. for (; offset < l; offset++) {
  2251. m = layersArray[offset];
  2252. // Group of layers, append children to layersArray and skip.
  2253. if (m instanceof L.LayerGroup) {
  2254. if (originalArray) {
  2255. layersArray = layersArray.slice();
  2256. originalArray = false;
  2257. }
  2258. this._extractNonGroupLayers(m, layersArray);
  2259. l = layersArray.length;
  2260. continue;
  2261. }
  2262. //Not point data, can't be clustered
  2263. if (!m.getLatLng) {
  2264. npg.addLayer(m);
  2265. continue;
  2266. }
  2267. if (this.hasLayer(m)) {
  2268. continue;
  2269. }
  2270. needsClustering.push(m);
  2271. }
  2272. }
  2273. return this;
  2274. },
  2275. //Takes an array of markers and removes them in bulk
  2276. removeLayers: function (layersArray) {
  2277. var i, m,
  2278. l = layersArray.length,
  2279. fg = this._featureGroup,
  2280. npg = this._nonPointGroup,
  2281. originalArray = true;
  2282. if (!this._map) {
  2283. for (i = 0; i < l; i++) {
  2284. m = layersArray[i];
  2285. // Group of layers, append children to layersArray and skip.
  2286. if (m instanceof L.LayerGroup) {
  2287. if (originalArray) {
  2288. layersArray = layersArray.slice();
  2289. originalArray = false;
  2290. }
  2291. this._extractNonGroupLayers(m, layersArray);
  2292. l = layersArray.length;
  2293. continue;
  2294. }
  2295. this._arraySplice(this._needsClustering, m);
  2296. npg.removeLayer(m);
  2297. if (this.hasLayer(m)) {
  2298. this._needsRemoving.push(m);
  2299. }
  2300. }
  2301. return this;
  2302. }
  2303. if (this._unspiderfy) {
  2304. this._unspiderfy();
  2305. // Work on a copy of the array, so that next loop is not affected.
  2306. var layersArray2 = layersArray.slice(),
  2307. l2 = l;
  2308. for (i = 0; i < l2; i++) {
  2309. m = layersArray2[i];
  2310. // Group of layers, append children to layersArray and skip.
  2311. if (m instanceof L.LayerGroup) {
  2312. this._extractNonGroupLayers(m, layersArray2);
  2313. l2 = layersArray2.length;
  2314. continue;
  2315. }
  2316. this._unspiderfyLayer(m);
  2317. }
  2318. }
  2319. for (i = 0; i < l; i++) {
  2320. m = layersArray[i];
  2321. // Group of layers, append children to layersArray and skip.
  2322. if (m instanceof L.LayerGroup) {
  2323. if (originalArray) {
  2324. layersArray = layersArray.slice();
  2325. originalArray = false;
  2326. }
  2327. this._extractNonGroupLayers(m, layersArray);
  2328. l = layersArray.length;
  2329. continue;
  2330. }
  2331. if (!m.__parent) {
  2332. npg.removeLayer(m);
  2333. continue;
  2334. }
  2335. this._removeLayer(m, true, true);
  2336. if (fg.hasLayer(m)) {
  2337. fg.removeLayer(m);
  2338. if (m.clusterShow) {
  2339. m.clusterShow();
  2340. }
  2341. }
  2342. }
  2343. // Refresh bounds and weighted positions.
  2344. this._topClusterLevel._recalculateBounds();
  2345. this._refreshClustersIcons();
  2346. //Fix up the clusters and markers on the map
  2347. this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds);
  2348. return this;
  2349. },
  2350. //Removes all layers from the MarkerClusterGroup
  2351. clearLayers: function () {
  2352. //Need our own special implementation as the LayerGroup one doesn't work for us
  2353. //If we aren't on the map (yet), blow away the markers we know of
  2354. if (!this._map) {
  2355. this._needsClustering = [];
  2356. delete this._gridClusters;
  2357. delete this._gridUnclustered;
  2358. }
  2359. if (this._noanimationUnspiderfy) {
  2360. this._noanimationUnspiderfy();
  2361. }
  2362. //Remove all the visible layers
  2363. this._featureGroup.clearLayers();
  2364. this._nonPointGroup.clearLayers();
  2365. this.eachLayer(function (marker) {
  2366. marker.off('move', this._childMarkerMoved, this);
  2367. delete marker.__parent;
  2368. });
  2369. if (this._map) {
  2370. //Reset _topClusterLevel and the DistanceGrids
  2371. this._generateInitialClusters();
  2372. }
  2373. return this;
  2374. },
  2375. //Override FeatureGroup.getBounds as it doesn't work
  2376. getBounds: function () {
  2377. var bounds = new L.LatLngBounds();
  2378. if (this._topClusterLevel) {
  2379. bounds.extend(this._topClusterLevel._bounds);
  2380. }
  2381. for (var i = this._needsClustering.length - 1; i >= 0; i--) {
  2382. bounds.extend(this._needsClustering[i].getLatLng());
  2383. }
  2384. bounds.extend(this._nonPointGroup.getBounds());
  2385. return bounds;
  2386. },
  2387. //Overrides LayerGroup.eachLayer
  2388. eachLayer: function (method, context) {
  2389. var markers = this._needsClustering.slice(),
  2390. needsRemoving = this._needsRemoving,
  2391. i;
  2392. if (this._topClusterLevel) {
  2393. this._topClusterLevel.getAllChildMarkers(markers);
  2394. }
  2395. for (i = markers.length - 1; i >= 0; i--) {
  2396. if (needsRemoving.indexOf(markers[i]) === -1) {
  2397. method.call(context, markers[i]);
  2398. }
  2399. }
  2400. this._nonPointGroup.eachLayer(method, context);
  2401. },
  2402. //Overrides LayerGroup.getLayers
  2403. getLayers: function () {
  2404. var layers = [];
  2405. this.eachLayer(function (l) {
  2406. layers.push(l);
  2407. });
  2408. return layers;
  2409. },
  2410. //Overrides LayerGroup.getLayer, WARNING: Really bad performance
  2411. getLayer: function (id) {
  2412. var result = null;
  2413. id = parseInt(id, 10);
  2414. this.eachLayer(function (l) {
  2415. if (L.stamp(l) === id) {
  2416. result = l;
  2417. }
  2418. });
  2419. return result;
  2420. },
  2421. //Returns true if the given layer is in this MarkerClusterGroup
  2422. hasLayer: function (layer) {
  2423. if (!layer) {
  2424. return false;
  2425. }
  2426. var i, anArray = this._needsClustering;
  2427. for (i = anArray.length - 1; i >= 0; i--) {
  2428. if (anArray[i] === layer) {
  2429. return true;
  2430. }
  2431. }
  2432. anArray = this._needsRemoving;
  2433. for (i = anArray.length - 1; i >= 0; i--) {
  2434. if (anArray[i] === layer) {
  2435. return false;
  2436. }
  2437. }
  2438. return !!(layer.__parent && layer.__parent._group === this) || this._nonPointGroup.hasLayer(layer);
  2439. },
  2440. //Zoom down to show the given layer (spiderfying if necessary) then calls the callback
  2441. zoomToShowLayer: function (layer, callback) {
  2442. if (typeof callback !== 'function') {
  2443. callback = function () {};
  2444. }
  2445. var showMarker = function () {
  2446. if ((layer._icon || layer.__parent._icon) && !this._inZoomAnimation) {
  2447. this._map.off('moveend', showMarker, this);
  2448. this.off('animationend', showMarker, this);
  2449. if (layer._icon) {
  2450. callback();
  2451. } else if (layer.__parent._icon) {
  2452. this.once('spiderfied', callback, this);
  2453. layer.__parent.spiderfy();
  2454. }
  2455. }
  2456. };
  2457. if (layer._icon && this._map.getBounds().contains(layer.getLatLng())) {
  2458. //Layer is visible ond on screen, immediate return
  2459. callback();
  2460. } else if (layer.__parent._zoom < Math.round(this._map._zoom)) {
  2461. //Layer should be visible at this zoom level. It must not be on screen so just pan over to it
  2462. this._map.on('moveend', showMarker, this);
  2463. this._map.panTo(layer.getLatLng());
  2464. } else {
  2465. var moveStart = function () {
  2466. this._map.off('movestart', moveStart, this);
  2467. moveStart = null;
  2468. };
  2469. this._map.on('movestart', moveStart, this);
  2470. this._map.on('moveend', showMarker, this);
  2471. this.on('animationend', showMarker, this);
  2472. layer.__parent.zoomToBounds();
  2473. if (moveStart) {
  2474. //Never started moving, must already be there, probably need clustering however
  2475. showMarker.call(this);
  2476. }
  2477. }
  2478. },
  2479. //Overrides FeatureGroup.onAdd
  2480. onAdd: function (map) {
  2481. this._map = map;
  2482. var i, l, layer;
  2483. if (!isFinite(this._map.getMaxZoom())) {
  2484. throw "Map has no maxZoom specified";
  2485. }
  2486. this._featureGroup.addTo(map);
  2487. this._nonPointGroup.addTo(map);
  2488. if (!this._gridClusters) {
  2489. this._generateInitialClusters();
  2490. }
  2491. this._maxLat = map.options.crs.projection.MAX_LATITUDE;
  2492. for (i = 0, l = this._needsRemoving.length; i < l; i++) {
  2493. layer = this._needsRemoving[i];
  2494. this._removeLayer(layer, true);
  2495. }
  2496. this._needsRemoving = [];
  2497. //Remember the current zoom level and bounds
  2498. this._zoom = Math.round(this._map._zoom);
  2499. this._currentShownBounds = this._getExpandedVisibleBounds();
  2500. this._map.on('zoomend', this._zoomEnd, this);
  2501. this._map.on('moveend', this._moveEnd, this);
  2502. if (this._spiderfierOnAdd) { //TODO FIXME: Not sure how to have spiderfier add something on here nicely
  2503. this._spiderfierOnAdd();
  2504. }
  2505. this._bindEvents();
  2506. //Actually add our markers to the map:
  2507. l = this._needsClustering;
  2508. this._needsClustering = [];
  2509. this.addLayers(l);
  2510. },
  2511. //Overrides FeatureGroup.onRemove
  2512. onRemove: function (map) {
  2513. map.off('zoomend', this._zoomEnd, this);
  2514. map.off('moveend', this._moveEnd, this);
  2515. this._unbindEvents();
  2516. //In case we are in a cluster animation
  2517. this._map._mapPane.className = this._map._mapPane.className.replace(' leaflet-cluster-anim', '');
  2518. if (this._spiderfierOnRemove) { //TODO FIXME: Not sure how to have spiderfier add something on here nicely
  2519. this._spiderfierOnRemove();
  2520. }
  2521. delete this._maxLat;
  2522. //Clean up all the layers we added to the map
  2523. this._hideCoverage();
  2524. this._featureGroup.remove();
  2525. this._nonPointGroup.remove();
  2526. this._featureGroup.clearLayers();
  2527. this._map = null;
  2528. },
  2529. getVisibleParent: function (marker) {
  2530. var vMarker = marker;
  2531. while (vMarker && !vMarker._icon) {
  2532. vMarker = vMarker.__parent;
  2533. }
  2534. return vMarker || null;
  2535. },
  2536. //Remove the given object from the given array
  2537. _arraySplice: function (anArray, obj) {
  2538. for (var i = anArray.length - 1; i >= 0; i--) {
  2539. if (anArray[i] === obj) {
  2540. anArray.splice(i, 1);
  2541. return true;
  2542. }
  2543. }
  2544. },
  2545. /**
  2546. * Removes a marker from all _gridUnclustered zoom levels, starting at the supplied zoom.
  2547. * @param marker to be removed from _gridUnclustered.
  2548. * @param z integer bottom start zoom level (included)
  2549. * @private
  2550. */
  2551. _removeFromGridUnclustered: function (marker, z) {
  2552. var map = this._map,
  2553. gridUnclustered = this._gridUnclustered;
  2554. for (; z >= 0; z--) {
  2555. if (!gridUnclustered[z].removeObject(marker, map.project(marker.getLatLng(), z))) {
  2556. break;
  2557. }
  2558. }
  2559. },
  2560. _childMarkerMoved: function (e) {
  2561. if (!this._ignoreMove) {
  2562. e.target._latlng = e.oldLatLng;
  2563. this.removeLayer(e.target);
  2564. e.target._latlng = e.latlng;
  2565. this.addLayer(e.target);
  2566. }
  2567. },
  2568. //Internal function for removing a marker from everything.
  2569. //dontUpdateMap: set to true if you will handle updating the map manually (for bulk functions)
  2570. _removeLayer: function (marker, removeFromDistanceGrid, dontUpdateMap) {
  2571. var gridClusters = this._gridClusters,
  2572. gridUnclustered = this._gridUnclustered,
  2573. fg = this._featureGroup,
  2574. map = this._map;
  2575. //Remove the marker from distance clusters it might be in
  2576. if (removeFromDistanceGrid) {
  2577. this._removeFromGridUnclustered(marker, this._maxZoom);
  2578. }
  2579. //Work our way up the clusters removing them as we go if required
  2580. var cluster = marker.__parent,
  2581. markers = cluster._markers,
  2582. otherMarker;
  2583. //Remove the marker from the immediate parents marker list
  2584. this._arraySplice(markers, marker);
  2585. while (cluster) {
  2586. cluster._childCount--;
  2587. cluster._boundsNeedUpdate = true;
  2588. if (cluster._zoom < 0) {
  2589. //Top level, do nothing
  2590. break;
  2591. } else if (removeFromDistanceGrid && cluster._childCount <= 1) { //Cluster no longer required
  2592. //We need to push the other marker up to the parent
  2593. otherMarker = cluster._markers[0] === marker ? cluster._markers[1] : cluster._markers[0];
  2594. //Update distance grid
  2595. gridClusters[cluster._zoom].removeObject(cluster, map.project(cluster._cLatLng, cluster._zoom));
  2596. gridUnclustered[cluster._zoom].addObject(otherMarker, map.project(otherMarker.getLatLng(), cluster._zoom));
  2597. //Move otherMarker up to parent
  2598. this._arraySplice(cluster.__parent._childClusters, cluster);
  2599. cluster.__parent._markers.push(otherMarker);
  2600. otherMarker.__parent = cluster.__parent;
  2601. if (cluster._icon) {
  2602. //Cluster is currently on the map, need to put the marker on the map instead
  2603. fg.removeLayer(cluster);
  2604. if (!dontUpdateMap) {
  2605. fg.addLayer(otherMarker);
  2606. }
  2607. }
  2608. } else {
  2609. cluster._iconNeedsUpdate = true;
  2610. }
  2611. cluster = cluster.__parent;
  2612. }
  2613. delete marker.__parent;
  2614. },
  2615. _isOrIsParent: function (el, oel) {
  2616. while (oel) {
  2617. if (el === oel) {
  2618. return true;
  2619. }
  2620. oel = oel.parentNode;
  2621. }
  2622. return false;
  2623. },
  2624. //Override L.Evented.fire
  2625. fire: function (type, data, propagate) {
  2626. if (data && data.layer instanceof L.MarkerCluster) {
  2627. //Prevent multiple clustermouseover/off events if the icon is made up of stacked divs (Doesn't work in ie <= 8, no relatedTarget)
  2628. if (data.originalEvent && this._isOrIsParent(data.layer._icon, data.originalEvent.relatedTarget)) {
  2629. return;
  2630. }
  2631. type = 'cluster' + type;
  2632. }
  2633. L.FeatureGroup.prototype.fire.call(this, type, data, propagate);
  2634. },
  2635. //Override L.Evented.listens
  2636. listens: function (type, propagate) {
  2637. return L.FeatureGroup.prototype.listens.call(this, type, propagate) || L.FeatureGroup.prototype.listens.call(this, 'cluster' + type, propagate);
  2638. },
  2639. //Default functionality
  2640. _defaultIconCreateFunction: function (cluster) {
  2641. var childCount = cluster.getChildCount();
  2642. var c = ' marker-cluster-';
  2643. if (childCount < 10) {
  2644. c += 'small';
  2645. } else if (childCount < 100) {
  2646. c += 'medium';
  2647. } else {
  2648. c += 'large';
  2649. }
  2650. return new L.DivIcon({ html: '<div><span>' + childCount + '</span></div>', className: 'marker-cluster' + c, iconSize: new L.Point(40, 40) });
  2651. },
  2652. _bindEvents: function () {
  2653. var map = this._map,
  2654. spiderfyOnMaxZoom = this.options.spiderfyOnMaxZoom,
  2655. showCoverageOnHover = this.options.showCoverageOnHover,
  2656. zoomToBoundsOnClick = this.options.zoomToBoundsOnClick;
  2657. //Zoom on cluster click or spiderfy if we are at the lowest level
  2658. if (spiderfyOnMaxZoom || zoomToBoundsOnClick) {
  2659. this.on('clusterclick', this._zoomOrSpiderfy, this);
  2660. }
  2661. //Show convex hull (boundary) polygon on mouse over
  2662. if (showCoverageOnHover) {
  2663. this.on('clustermouseover', this._showCoverage, this);
  2664. this.on('clustermouseout', this._hideCoverage, this);
  2665. map.on('zoomend', this._hideCoverage, this);
  2666. }
  2667. },
  2668. _zoomOrSpiderfy: function (e) {
  2669. var cluster = e.layer,
  2670. bottomCluster = cluster;
  2671. while (bottomCluster._childClusters.length === 1) {
  2672. bottomCluster = bottomCluster._childClusters[0];
  2673. }
  2674. if (bottomCluster._zoom === this._maxZoom &&
  2675. bottomCluster._childCount === cluster._childCount &&
  2676. this.options.spiderfyOnMaxZoom) {
  2677. // All child markers are contained in a single cluster from this._maxZoom to this cluster.
  2678. cluster.spiderfy();
  2679. } else if (this.options.zoomToBoundsOnClick) {
  2680. cluster.zoomToBounds();
  2681. }
  2682. // Focus the map again for keyboard users.
  2683. if (e.originalEvent && e.originalEvent.keyCode === 13) {
  2684. this._map._container.focus();
  2685. }
  2686. },
  2687. _showCoverage: function (e) {
  2688. var map = this._map;
  2689. if (this._inZoomAnimation) {
  2690. return;
  2691. }
  2692. if (this._shownPolygon) {
  2693. map.removeLayer(this._shownPolygon);
  2694. }
  2695. if (e.layer.getChildCount() > 2 && e.layer !== this._spiderfied) {
  2696. this._shownPolygon = new L.Polygon(e.layer.getConvexHull(), this.options.polygonOptions);
  2697. map.addLayer(this._shownPolygon);
  2698. }
  2699. },
  2700. _hideCoverage: function () {
  2701. if (this._shownPolygon) {
  2702. this._map.removeLayer(this._shownPolygon);
  2703. this._shownPolygon = null;
  2704. }
  2705. },
  2706. _unbindEvents: function () {
  2707. var spiderfyOnMaxZoom = this.options.spiderfyOnMaxZoom,
  2708. showCoverageOnHover = this.options.showCoverageOnHover,
  2709. zoomToBoundsOnClick = this.options.zoomToBoundsOnClick,
  2710. map = this._map;
  2711. if (spiderfyOnMaxZoom || zoomToBoundsOnClick) {
  2712. this.off('clusterclick', this._zoomOrSpiderfy, this);
  2713. }
  2714. if (showCoverageOnHover) {
  2715. this.off('clustermouseover', this._showCoverage, this);
  2716. this.off('clustermouseout', this._hideCoverage, this);
  2717. map.off('zoomend', this._hideCoverage, this);
  2718. }
  2719. },
  2720. _zoomEnd: function () {
  2721. if (!this._map) { //May have been removed from the map by a zoomEnd handler
  2722. return;
  2723. }
  2724. this._mergeSplitClusters();
  2725. this._zoom = Math.round(this._map._zoom);
  2726. this._currentShownBounds = this._getExpandedVisibleBounds();
  2727. },
  2728. _moveEnd: function () {
  2729. if (this._inZoomAnimation) {
  2730. return;
  2731. }
  2732. var newBounds = this._getExpandedVisibleBounds();
  2733. this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, this._zoom, newBounds);
  2734. this._topClusterLevel._recursivelyAddChildrenToMap(null, Math.round(this._map._zoom), newBounds);
  2735. this._currentShownBounds = newBounds;
  2736. return;
  2737. },
  2738. _generateInitialClusters: function () {
  2739. var maxZoom = this._map.getMaxZoom(),
  2740. radius = this.options.maxClusterRadius,
  2741. radiusFn = radius;
  2742. //If we just set maxClusterRadius to a single number, we need to create
  2743. //a simple function to return that number. Otherwise, we just have to
  2744. //use the function we've passed in.
  2745. if (typeof radius !== "function") {
  2746. radiusFn = function () { return radius; };
  2747. }
  2748. if (this.options.disableClusteringAtZoom) {
  2749. maxZoom = this.options.disableClusteringAtZoom - 1;
  2750. }
  2751. this._maxZoom = maxZoom;
  2752. this._gridClusters = {};
  2753. this._gridUnclustered = {};
  2754. //Set up DistanceGrids for each zoom
  2755. for (var zoom = maxZoom; zoom >= 0; zoom--) {
  2756. this._gridClusters[zoom] = new L.DistanceGrid(radiusFn(zoom));
  2757. this._gridUnclustered[zoom] = new L.DistanceGrid(radiusFn(zoom));
  2758. }
  2759. // Instantiate the appropriate L.MarkerCluster class (animated or not).
  2760. this._topClusterLevel = new this._markerCluster(this, -1);
  2761. },
  2762. //Zoom: Zoom to start adding at (Pass this._maxZoom to start at the bottom)
  2763. _addLayer: function (layer, zoom) {
  2764. var gridClusters = this._gridClusters,
  2765. gridUnclustered = this._gridUnclustered,
  2766. markerPoint, z;
  2767. if (this.options.singleMarkerMode) {
  2768. this._overrideMarkerIcon(layer);
  2769. }
  2770. layer.on('move', this._childMarkerMoved, this);
  2771. //Find the lowest zoom level to slot this one in
  2772. for (; zoom >= 0; zoom--) {
  2773. markerPoint = this._map.project(layer.getLatLng(), zoom); // calculate pixel position
  2774. //Try find a cluster close by
  2775. var closest = gridClusters[zoom].getNearObject(markerPoint);
  2776. if (closest) {
  2777. closest._addChild(layer);
  2778. layer.__parent = closest;
  2779. return;
  2780. }
  2781. //Try find a marker close by to form a new cluster with
  2782. closest = gridUnclustered[zoom].getNearObject(markerPoint);
  2783. if (closest) {
  2784. var parent = closest.__parent;
  2785. if (parent) {
  2786. this._removeLayer(closest, false);
  2787. }
  2788. //Create new cluster with these 2 in it
  2789. var newCluster = new this._markerCluster(this, zoom, closest, layer);
  2790. gridClusters[zoom].addObject(newCluster, this._map.project(newCluster._cLatLng, zoom));
  2791. closest.__parent = newCluster;
  2792. layer.__parent = newCluster;
  2793. //First create any new intermediate parent clusters that don't exist
  2794. var lastParent = newCluster;
  2795. for (z = zoom - 1; z > parent._zoom; z--) {
  2796. lastParent = new this._markerCluster(this, z, lastParent);
  2797. gridClusters[z].addObject(lastParent, this._map.project(closest.getLatLng(), z));
  2798. }
  2799. parent._addChild(lastParent);
  2800. //Remove closest from this zoom level and any above that it is in, replace with newCluster
  2801. this._removeFromGridUnclustered(closest, zoom);
  2802. return;
  2803. }
  2804. //Didn't manage to cluster in at this zoom, record us as a marker here and continue upwards
  2805. gridUnclustered[zoom].addObject(layer, markerPoint);
  2806. }
  2807. //Didn't get in anything, add us to the top
  2808. this._topClusterLevel._addChild(layer);
  2809. layer.__parent = this._topClusterLevel;
  2810. return;
  2811. },
  2812. /**
  2813. * Refreshes the icon of all "dirty" visible clusters.
  2814. * Non-visible "dirty" clusters will be updated when they are added to the map.
  2815. * @private
  2816. */
  2817. _refreshClustersIcons: function () {
  2818. this._featureGroup.eachLayer(function (c) {
  2819. if (c instanceof L.MarkerCluster && c._iconNeedsUpdate) {
  2820. c._updateIcon();
  2821. }
  2822. });
  2823. },
  2824. //Enqueue code to fire after the marker expand/contract has happened
  2825. _enqueue: function (fn) {
  2826. this._queue.push(fn);
  2827. if (!this._queueTimeout) {
  2828. this._queueTimeout = setTimeout(L.bind(this._processQueue, this), 300);
  2829. }
  2830. },
  2831. _processQueue: function () {
  2832. for (var i = 0; i < this._queue.length; i++) {
  2833. this._queue[i].call(this);
  2834. }
  2835. this._queue.length = 0;
  2836. clearTimeout(this._queueTimeout);
  2837. this._queueTimeout = null;
  2838. },
  2839. //Merge and split any existing clusters that are too big or small
  2840. _mergeSplitClusters: function () {
  2841. var mapZoom = Math.round(this._map._zoom);
  2842. //In case we are starting to split before the animation finished
  2843. this._processQueue();
  2844. if (this._zoom < mapZoom && this._currentShownBounds.intersects(this._getExpandedVisibleBounds())) { //Zoom in, split
  2845. this._animationStart();
  2846. //Remove clusters now off screen
  2847. this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, this._zoom, this._getExpandedVisibleBounds());
  2848. this._animationZoomIn(this._zoom, mapZoom);
  2849. } else if (this._zoom > mapZoom) { //Zoom out, merge
  2850. this._animationStart();
  2851. this._animationZoomOut(this._zoom, mapZoom);
  2852. } else {
  2853. this._moveEnd();
  2854. }
  2855. },
  2856. //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)
  2857. _getExpandedVisibleBounds: function () {
  2858. if (!this.options.removeOutsideVisibleBounds) {
  2859. return this._mapBoundsInfinite;
  2860. } else if (L.Browser.mobile) {
  2861. return this._checkBoundsMaxLat(this._map.getBounds());
  2862. }
  2863. return this._checkBoundsMaxLat(this._map.getBounds().pad(1)); // Padding expands the bounds by its own dimensions but scaled with the given factor.
  2864. },
  2865. /**
  2866. * Expands the latitude to Infinity (or -Infinity) if the input bounds reach the map projection maximum defined latitude
  2867. * (in the case of Web/Spherical Mercator, it is 85.0511287798 / see https://en.wikipedia.org/wiki/Web_Mercator#Formulas).
  2868. * Otherwise, the removeOutsideVisibleBounds option will remove markers beyond that limit, whereas the same markers without
  2869. * this option (or outside MCG) will have their position floored (ceiled) by the projection and rendered at that limit,
  2870. * making the user think that MCG "eats" them and never displays them again.
  2871. * @param bounds L.LatLngBounds
  2872. * @returns {L.LatLngBounds}
  2873. * @private
  2874. */
  2875. _checkBoundsMaxLat: function (bounds) {
  2876. var maxLat = this._maxLat;
  2877. if (maxLat !== undefined) {
  2878. if (bounds.getNorth() >= maxLat) {
  2879. bounds._northEast.lat = Infinity;
  2880. }
  2881. if (bounds.getSouth() <= -maxLat) {
  2882. bounds._southWest.lat = -Infinity;
  2883. }
  2884. }
  2885. return bounds;
  2886. },
  2887. //Shared animation code
  2888. _animationAddLayerNonAnimated: function (layer, newCluster) {
  2889. if (newCluster === layer) {
  2890. this._featureGroup.addLayer(layer);
  2891. } else if (newCluster._childCount === 2) {
  2892. newCluster._addToMap();
  2893. var markers = newCluster.getAllChildMarkers();
  2894. this._featureGroup.removeLayer(markers[0]);
  2895. this._featureGroup.removeLayer(markers[1]);
  2896. } else {
  2897. newCluster._updateIcon();
  2898. }
  2899. },
  2900. /**
  2901. * Extracts individual (i.e. non-group) layers from a Layer Group.
  2902. * @param group to extract layers from.
  2903. * @param output {Array} in which to store the extracted layers.
  2904. * @returns {*|Array}
  2905. * @private
  2906. */
  2907. _extractNonGroupLayers: function (group, output) {
  2908. var layers = group.getLayers(),
  2909. i = 0,
  2910. layer;
  2911. output = output || [];
  2912. for (; i < layers.length; i++) {
  2913. layer = layers[i];
  2914. if (layer instanceof L.LayerGroup) {
  2915. this._extractNonGroupLayers(layer, output);
  2916. continue;
  2917. }
  2918. output.push(layer);
  2919. }
  2920. return output;
  2921. },
  2922. /**
  2923. * Implements the singleMarkerMode option.
  2924. * @param layer Marker to re-style using the Clusters iconCreateFunction.
  2925. * @returns {L.Icon} The newly created icon.
  2926. * @private
  2927. */
  2928. _overrideMarkerIcon: function (layer) {
  2929. var icon = layer.options.icon = this.options.iconCreateFunction({
  2930. getChildCount: function () {
  2931. return 1;
  2932. },
  2933. getAllChildMarkers: function () {
  2934. return [layer];
  2935. }
  2936. });
  2937. return icon;
  2938. }
  2939. });
  2940. // Constant bounds used in case option "removeOutsideVisibleBounds" is set to false.
  2941. L.MarkerClusterGroup.include({
  2942. _mapBoundsInfinite: new L.LatLngBounds(new L.LatLng(-Infinity, -Infinity), new L.LatLng(Infinity, Infinity))
  2943. });
  2944. L.MarkerClusterGroup.include({
  2945. _noAnimation: {
  2946. //Non Animated versions of everything
  2947. _animationStart: function () {
  2948. //Do nothing...
  2949. },
  2950. _animationZoomIn: function (previousZoomLevel, newZoomLevel) {
  2951. this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, previousZoomLevel);
  2952. this._topClusterLevel._recursivelyAddChildrenToMap(null, newZoomLevel, this._getExpandedVisibleBounds());
  2953. //We didn't actually animate, but we use this event to mean "clustering animations have finished"
  2954. this.fire('animationend');
  2955. },
  2956. _animationZoomOut: function (previousZoomLevel, newZoomLevel) {
  2957. this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, previousZoomLevel);
  2958. this._topClusterLevel._recursivelyAddChildrenToMap(null, newZoomLevel, this._getExpandedVisibleBounds());
  2959. //We didn't actually animate, but we use this event to mean "clustering animations have finished"
  2960. this.fire('animationend');
  2961. },
  2962. _animationAddLayer: function (layer, newCluster) {
  2963. this._animationAddLayerNonAnimated(layer, newCluster);
  2964. }
  2965. },
  2966. _withAnimation: {
  2967. //Animated versions here
  2968. _animationStart: function () {
  2969. this._map._mapPane.className += ' leaflet-cluster-anim';
  2970. this._inZoomAnimation++;
  2971. },
  2972. _animationZoomIn: function (previousZoomLevel, newZoomLevel) {
  2973. var bounds = this._getExpandedVisibleBounds(),
  2974. fg = this._featureGroup,
  2975. i;
  2976. this._ignoreMove = true;
  2977. //Add all children of current clusters to map and remove those clusters from map
  2978. this._topClusterLevel._recursively(bounds, previousZoomLevel, 0, function (c) {
  2979. var startPos = c._latlng,
  2980. markers = c._markers,
  2981. m;
  2982. if (!bounds.contains(startPos)) {
  2983. startPos = null;
  2984. }
  2985. if (c._isSingleParent() && previousZoomLevel + 1 === newZoomLevel) { //Immediately add the new child and remove us
  2986. fg.removeLayer(c);
  2987. c._recursivelyAddChildrenToMap(null, newZoomLevel, bounds);
  2988. } else {
  2989. //Fade out old cluster
  2990. c.clusterHide();
  2991. c._recursivelyAddChildrenToMap(startPos, newZoomLevel, bounds);
  2992. }
  2993. //Remove all markers that aren't visible any more
  2994. //TODO: Do we actually need to do this on the higher levels too?
  2995. for (i = markers.length - 1; i >= 0; i--) {
  2996. m = markers[i];
  2997. if (!bounds.contains(m._latlng)) {
  2998. fg.removeLayer(m);
  2999. }
  3000. }
  3001. });
  3002. this._forceLayout();
  3003. //Update opacities
  3004. this._topClusterLevel._recursivelyBecomeVisible(bounds, newZoomLevel);
  3005. //TODO Maybe? Update markers in _recursivelyBecomeVisible
  3006. fg.eachLayer(function (n) {
  3007. if (!(n instanceof L.MarkerCluster) && n._icon) {
  3008. n.clusterShow();
  3009. }
  3010. });
  3011. //update the positions of the just added clusters/markers
  3012. this._topClusterLevel._recursively(bounds, previousZoomLevel, newZoomLevel, function (c) {
  3013. c._recursivelyRestoreChildPositions(newZoomLevel);
  3014. });
  3015. this._ignoreMove = false;
  3016. //Remove the old clusters and close the zoom animation
  3017. this._enqueue(function () {
  3018. //update the positions of the just added clusters/markers
  3019. this._topClusterLevel._recursively(bounds, previousZoomLevel, 0, function (c) {
  3020. fg.removeLayer(c);
  3021. c.clusterShow();
  3022. });
  3023. this._animationEnd();
  3024. });
  3025. },
  3026. _animationZoomOut: function (previousZoomLevel, newZoomLevel) {
  3027. this._animationZoomOutSingle(this._topClusterLevel, previousZoomLevel - 1, newZoomLevel);
  3028. //Need to add markers for those that weren't on the map before but are now
  3029. this._topClusterLevel._recursivelyAddChildrenToMap(null, newZoomLevel, this._getExpandedVisibleBounds());
  3030. //Remove markers that were on the map before but won't be now
  3031. this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, previousZoomLevel, this._getExpandedVisibleBounds());
  3032. },
  3033. _animationAddLayer: function (layer, newCluster) {
  3034. var me = this,
  3035. fg = this._featureGroup;
  3036. fg.addLayer(layer);
  3037. if (newCluster !== layer) {
  3038. if (newCluster._childCount > 2) { //Was already a cluster
  3039. newCluster._updateIcon();
  3040. this._forceLayout();
  3041. this._animationStart();
  3042. layer._setPos(this._map.latLngToLayerPoint(newCluster.getLatLng()));
  3043. layer.clusterHide();
  3044. this._enqueue(function () {
  3045. fg.removeLayer(layer);
  3046. layer.clusterShow();
  3047. me._animationEnd();
  3048. });
  3049. } else { //Just became a cluster
  3050. this._forceLayout();
  3051. me._animationStart();
  3052. me._animationZoomOutSingle(newCluster, this._map.getMaxZoom(), this._zoom);
  3053. }
  3054. }
  3055. }
  3056. },
  3057. // Private methods for animated versions.
  3058. _animationZoomOutSingle: function (cluster, previousZoomLevel, newZoomLevel) {
  3059. var bounds = this._getExpandedVisibleBounds();
  3060. //Animate all of the markers in the clusters to move to their cluster center point
  3061. cluster._recursivelyAnimateChildrenInAndAddSelfToMap(bounds, previousZoomLevel + 1, newZoomLevel);
  3062. var me = this;
  3063. //Update the opacity (If we immediately set it they won't animate)
  3064. this._forceLayout();
  3065. cluster._recursivelyBecomeVisible(bounds, newZoomLevel);
  3066. //TODO: Maybe use the transition timing stuff to make this more reliable
  3067. //When the animations are done, tidy up
  3068. this._enqueue(function () {
  3069. //This cluster stopped being a cluster before the timeout fired
  3070. if (cluster._childCount === 1) {
  3071. var m = cluster._markers[0];
  3072. //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
  3073. this._ignoreMove = true;
  3074. m.setLatLng(m.getLatLng());
  3075. this._ignoreMove = false;
  3076. if (m.clusterShow) {
  3077. m.clusterShow();
  3078. }
  3079. } else {
  3080. cluster._recursively(bounds, newZoomLevel, 0, function (c) {
  3081. c._recursivelyRemoveChildrenFromMap(bounds, previousZoomLevel + 1);
  3082. });
  3083. }
  3084. me._animationEnd();
  3085. });
  3086. },
  3087. _animationEnd: function () {
  3088. if (this._map) {
  3089. this._map._mapPane.className = this._map._mapPane.className.replace(' leaflet-cluster-anim', '');
  3090. }
  3091. this._inZoomAnimation--;
  3092. this.fire('animationend');
  3093. },
  3094. //Force a browser layout of stuff in the map
  3095. // Should apply the current opacity and location to all elements so we can update them again for an animation
  3096. _forceLayout: function () {
  3097. //In my testing this works, infact offsetWidth of any element seems to work.
  3098. //Could loop all this._layers and do this for each _icon if it stops working
  3099. L.Util.falseFn(document.body.offsetWidth);
  3100. }
  3101. });
  3102. L.markerClusterGroup = function (options) {
  3103. return new L.MarkerClusterGroup(options);
  3104. };
  3105. L.MarkerCluster = L.Marker.extend({
  3106. initialize: function (group, zoom, a, b) {
  3107. L.Marker.prototype.initialize.call(this, a ? (a._cLatLng || a.getLatLng()) : new L.LatLng(0, 0), { icon: this });
  3108. this._group = group;
  3109. this._zoom = zoom;
  3110. this._markers = [];
  3111. this._childClusters = [];
  3112. this._childCount = 0;
  3113. this._iconNeedsUpdate = true;
  3114. this._boundsNeedUpdate = true;
  3115. this._bounds = new L.LatLngBounds();
  3116. if (a) {
  3117. this._addChild(a);
  3118. }
  3119. if (b) {
  3120. this._addChild(b);
  3121. }
  3122. },
  3123. //Recursively retrieve all child markers of this cluster
  3124. getAllChildMarkers: function (storageArray) {
  3125. storageArray = storageArray || [];
  3126. for (var i = this._childClusters.length - 1; i >= 0; i--) {
  3127. this._childClusters[i].getAllChildMarkers(storageArray);
  3128. }
  3129. for (var j = this._markers.length - 1; j >= 0; j--) {
  3130. storageArray.push(this._markers[j]);
  3131. }
  3132. return storageArray;
  3133. },
  3134. //Returns the count of how many child markers we have
  3135. getChildCount: function () {
  3136. return this._childCount;
  3137. },
  3138. //Zoom to the minimum of showing all of the child markers, or the extents of this cluster
  3139. zoomToBounds: function () {
  3140. var childClusters = this._childClusters.slice(),
  3141. map = this._group._map,
  3142. boundsZoom = map.getBoundsZoom(this._bounds),
  3143. zoom = this._zoom + 1,
  3144. mapZoom = map.getZoom(),
  3145. i;
  3146. //calculate how far we need to zoom down to see all of the markers
  3147. while (childClusters.length > 0 && boundsZoom > zoom) {
  3148. zoom++;
  3149. var newClusters = [];
  3150. for (i = 0; i < childClusters.length; i++) {
  3151. newClusters = newClusters.concat(childClusters[i]._childClusters);
  3152. }
  3153. childClusters = newClusters;
  3154. }
  3155. if (boundsZoom > zoom) {
  3156. this._group._map.setView(this._latlng, zoom);
  3157. } else if (boundsZoom <= mapZoom) { //If fitBounds wouldn't zoom us down, zoom us down instead
  3158. this._group._map.setView(this._latlng, mapZoom + 1);
  3159. } else {
  3160. this._group._map.fitBounds(this._bounds);
  3161. }
  3162. },
  3163. getBounds: function () {
  3164. var bounds = new L.LatLngBounds();
  3165. bounds.extend(this._bounds);
  3166. return bounds;
  3167. },
  3168. _updateIcon: function () {
  3169. this._iconNeedsUpdate = true;
  3170. if (this._icon) {
  3171. this.setIcon(this);
  3172. }
  3173. },
  3174. //Cludge for Icon, we pretend to be an icon for performance
  3175. createIcon: function () {
  3176. if (this._iconNeedsUpdate) {
  3177. this._iconObj = this._group.options.iconCreateFunction(this);
  3178. this._iconNeedsUpdate = false;
  3179. }
  3180. return this._iconObj.createIcon();
  3181. },
  3182. createShadow: function () {
  3183. return this._iconObj.createShadow();
  3184. },
  3185. _addChild: function (new1, isNotificationFromChild) {
  3186. this._iconNeedsUpdate = true;
  3187. this._boundsNeedUpdate = true;
  3188. this._setClusterCenter(new1);
  3189. if (new1 instanceof L.MarkerCluster) {
  3190. if (!isNotificationFromChild) {
  3191. this._childClusters.push(new1);
  3192. new1.__parent = this;
  3193. }
  3194. this._childCount += new1._childCount;
  3195. } else {
  3196. if (!isNotificationFromChild) {
  3197. this._markers.push(new1);
  3198. }
  3199. this._childCount++;
  3200. }
  3201. if (this.__parent) {
  3202. this.__parent._addChild(new1, true);
  3203. }
  3204. },
  3205. /**
  3206. * Makes sure the cluster center is set. If not, uses the child center if it is a cluster, or the marker position.
  3207. * @param child L.MarkerCluster|L.Marker that will be used as cluster center if not defined yet.
  3208. * @private
  3209. */
  3210. _setClusterCenter: function (child) {
  3211. if (!this._cLatLng) {
  3212. // when clustering, take position of the first point as the cluster center
  3213. this._cLatLng = child._cLatLng || child._latlng;
  3214. }
  3215. },
  3216. /**
  3217. * Assigns impossible bounding values so that the next extend entirely determines the new bounds.
  3218. * This method avoids having to trash the previous L.LatLngBounds object and to create a new one, which is much slower for this class.
  3219. * As long as the bounds are not extended, most other methods would probably fail, as they would with bounds initialized but not extended.
  3220. * @private
  3221. */
  3222. _resetBounds: function () {
  3223. var bounds = this._bounds;
  3224. if (bounds._southWest) {
  3225. bounds._southWest.lat = Infinity;
  3226. bounds._southWest.lng = Infinity;
  3227. }
  3228. if (bounds._northEast) {
  3229. bounds._northEast.lat = -Infinity;
  3230. bounds._northEast.lng = -Infinity;
  3231. }
  3232. },
  3233. _recalculateBounds: function () {
  3234. var markers = this._markers,
  3235. childClusters = this._childClusters,
  3236. latSum = 0,
  3237. lngSum = 0,
  3238. totalCount = this._childCount,
  3239. i, child, childLatLng, childCount;
  3240. // Case where all markers are removed from the map and we are left with just an empty _topClusterLevel.
  3241. if (totalCount === 0) {
  3242. return;
  3243. }
  3244. // Reset rather than creating a new object, for performance.
  3245. this._resetBounds();
  3246. // Child markers.
  3247. for (i = 0; i < markers.length; i++) {
  3248. childLatLng = markers[i]._latlng;
  3249. this._bounds.extend(childLatLng);
  3250. latSum += childLatLng.lat;
  3251. lngSum += childLatLng.lng;
  3252. }
  3253. // Child clusters.
  3254. for (i = 0; i < childClusters.length; i++) {
  3255. child = childClusters[i];
  3256. // Re-compute child bounds and weighted position first if necessary.
  3257. if (child._boundsNeedUpdate) {
  3258. child._recalculateBounds();
  3259. }
  3260. this._bounds.extend(child._bounds);
  3261. childLatLng = child._wLatLng;
  3262. childCount = child._childCount;
  3263. latSum += childLatLng.lat * childCount;
  3264. lngSum += childLatLng.lng * childCount;
  3265. }
  3266. this._latlng = this._wLatLng = new L.LatLng(latSum / totalCount, lngSum / totalCount);
  3267. // Reset dirty flag.
  3268. this._boundsNeedUpdate = false;
  3269. },
  3270. //Set our markers position as given and add it to the map
  3271. _addToMap: function (startPos) {
  3272. if (startPos) {
  3273. this._backupLatlng = this._latlng;
  3274. this.setLatLng(startPos);
  3275. }
  3276. this._group._featureGroup.addLayer(this);
  3277. if(this.plabel){
  3278. if(this.plabel._isOpen){
  3279. this.showPlabel();
  3280. }
  3281. }
  3282. },
  3283. _recursivelyAnimateChildrenIn: function (bounds, center, maxZoom) {
  3284. this._recursively(bounds, 0, maxZoom - 1,
  3285. function (c) {
  3286. var markers = c._markers,
  3287. i, m;
  3288. for (i = markers.length - 1; i >= 0; i--) {
  3289. m = markers[i];
  3290. //Only do it if the icon is still on the map
  3291. if (m._icon) {
  3292. m._setPos(center);
  3293. m.clusterHide();
  3294. }
  3295. }
  3296. },
  3297. function (c) {
  3298. var childClusters = c._childClusters,
  3299. j, cm;
  3300. for (j = childClusters.length - 1; j >= 0; j--) {
  3301. cm = childClusters[j];
  3302. if (cm._icon) {
  3303. cm._setPos(center);
  3304. cm.clusterHide();
  3305. }
  3306. }
  3307. }
  3308. );
  3309. },
  3310. _recursivelyAnimateChildrenInAndAddSelfToMap: function (bounds, previousZoomLevel, newZoomLevel) {
  3311. this._recursively(bounds, newZoomLevel, 0,
  3312. function (c) {
  3313. c._recursivelyAnimateChildrenIn(bounds, c._group._map.latLngToLayerPoint(c.getLatLng()).round(), previousZoomLevel);
  3314. //TODO: depthToAnimateIn affects _isSingleParent, if there is a multizoom we may/may not be.
  3315. //As a hack we only do a animation free zoom on a single level zoom, if someone does multiple levels then we always animate
  3316. if (c._isSingleParent() && previousZoomLevel - 1 === newZoomLevel) {
  3317. c.clusterShow();
  3318. c._recursivelyRemoveChildrenFromMap(bounds, previousZoomLevel); //Immediately remove our children as we are replacing them. TODO previousBounds not bounds
  3319. } else {
  3320. c.clusterHide();
  3321. }
  3322. c._addToMap();
  3323. }
  3324. );
  3325. },
  3326. _recursivelyBecomeVisible: function (bounds, zoomLevel) {
  3327. this._recursively(bounds, 0, zoomLevel, null, function (c) {
  3328. c.clusterShow();
  3329. });
  3330. },
  3331. _recursivelyAddChildrenToMap: function (startPos, zoomLevel, bounds) {
  3332. this._recursively(bounds, -1, zoomLevel,
  3333. function (c) {
  3334. if (zoomLevel === c._zoom) {
  3335. return;
  3336. }
  3337. //Add our child markers at startPos (so they can be animated out)
  3338. for (var i = c._markers.length - 1; i >= 0; i--) {
  3339. var nm = c._markers[i];
  3340. if (!bounds.contains(nm._latlng)) {
  3341. continue;
  3342. }
  3343. if (startPos) {
  3344. nm._backupLatlng = nm.getLatLng();
  3345. nm.setLatLng(startPos);
  3346. if (nm.clusterHide) {
  3347. nm.clusterHide();
  3348. }
  3349. }
  3350. c._group._featureGroup.addLayer(nm);
  3351. }
  3352. },
  3353. function (c) {
  3354. c._addToMap(startPos);
  3355. }
  3356. );
  3357. },
  3358. _recursivelyRestoreChildPositions: function (zoomLevel) {
  3359. //Fix positions of child markers
  3360. for (var i = this._markers.length - 1; i >= 0; i--) {
  3361. var nm = this._markers[i];
  3362. if (nm._backupLatlng) {
  3363. nm.setLatLng(nm._backupLatlng);
  3364. delete nm._backupLatlng;
  3365. }
  3366. }
  3367. if (zoomLevel - 1 === this._zoom) {
  3368. //Reposition child clusters
  3369. for (var j = this._childClusters.length - 1; j >= 0; j--) {
  3370. this._childClusters[j]._restorePosition();
  3371. }
  3372. } else {
  3373. for (var k = this._childClusters.length - 1; k >= 0; k--) {
  3374. this._childClusters[k]._recursivelyRestoreChildPositions(zoomLevel);
  3375. }
  3376. }
  3377. },
  3378. _restorePosition: function () {
  3379. if (this._backupLatlng) {
  3380. this.setLatLng(this._backupLatlng);
  3381. delete this._backupLatlng;
  3382. }
  3383. },
  3384. //exceptBounds: If set, don't remove any markers/clusters in it
  3385. _recursivelyRemoveChildrenFromMap: function (previousBounds, zoomLevel, exceptBounds) {
  3386. var m, i;
  3387. this._recursively(previousBounds, -1, zoomLevel - 1,
  3388. function (c) {
  3389. //Remove markers at every level
  3390. for (i = c._markers.length - 1; i >= 0; i--) {
  3391. m = c._markers[i];
  3392. if (!exceptBounds || !exceptBounds.contains(m._latlng)) {
  3393. c._group._featureGroup.removeLayer(m);
  3394. if (m.clusterShow) {
  3395. m.clusterShow();
  3396. }
  3397. }
  3398. }
  3399. },
  3400. function (c) {
  3401. //Remove child clusters at just the bottom level
  3402. for (i = c._childClusters.length - 1; i >= 0; i--) {
  3403. m = c._childClusters[i];
  3404. if (!exceptBounds || !exceptBounds.contains(m._latlng)) {
  3405. c._group._featureGroup.removeLayer(m);
  3406. if (m.clusterShow) {
  3407. m.clusterShow();
  3408. }
  3409. }
  3410. }
  3411. }
  3412. );
  3413. },
  3414. //Run the given functions recursively to this and child clusters
  3415. // boundsToApplyTo: a L.LatLngBounds representing the bounds of what clusters to recurse in to
  3416. // zoomLevelToStart: zoom level to start running functions (inclusive)
  3417. // zoomLevelToStop: zoom level to stop running functions (inclusive)
  3418. // runAtEveryLevel: function that takes an L.MarkerCluster as an argument that should be applied on every level
  3419. // runAtBottomLevel: function that takes an L.MarkerCluster as an argument that should be applied at only the bottom level
  3420. _recursively: function (boundsToApplyTo, zoomLevelToStart, zoomLevelToStop, runAtEveryLevel, runAtBottomLevel) {
  3421. var childClusters = this._childClusters,
  3422. zoom = this._zoom,
  3423. i, c;
  3424. if (zoomLevelToStart <= zoom) {
  3425. if (runAtEveryLevel) {
  3426. runAtEveryLevel(this);
  3427. }
  3428. if (runAtBottomLevel && zoom === zoomLevelToStop) {
  3429. runAtBottomLevel(this);
  3430. }
  3431. }
  3432. if (zoom < zoomLevelToStart || zoom < zoomLevelToStop) {
  3433. for (i = childClusters.length - 1; i >= 0; i--) {
  3434. c = childClusters[i];
  3435. if (boundsToApplyTo.intersects(c._bounds)) {
  3436. c._recursively(boundsToApplyTo, zoomLevelToStart, zoomLevelToStop, runAtEveryLevel, runAtBottomLevel);
  3437. }
  3438. }
  3439. }
  3440. },
  3441. //Returns true if we are the parent of only one cluster and that cluster is the same as us
  3442. _isSingleParent: function () {
  3443. //Don't need to check this._markers as the rest won't work if there are any
  3444. return this._childClusters.length > 0 && this._childClusters[0]._childCount === this._childCount;
  3445. }
  3446. });
  3447. /*
  3448. * Extends L.Marker to include two extra methods: clusterHide and clusterShow.
  3449. *
  3450. * They work as setOpacity(0) and setOpacity(1) respectively, but
  3451. * they will remember the marker's opacity when hiding and showing it again.
  3452. *
  3453. */
  3454. L.Marker.include({
  3455. clusterHide: function () {
  3456. this.options.opacityWhenUnclustered = this.options.opacity || 1;
  3457. return this.setOpacity(0);
  3458. },
  3459. clusterShow: function () {
  3460. var ret = this.setOpacity(this.options.opacity || this.options.opacityWhenUnclustered);
  3461. delete this.options.opacityWhenUnclustered;
  3462. return ret;
  3463. }
  3464. });
  3465. L.DistanceGrid = function (cellSize) {
  3466. this._cellSize = cellSize;
  3467. this._sqCellSize = cellSize * cellSize;
  3468. this._grid = {};
  3469. this._objectPoint = { };
  3470. };
  3471. L.DistanceGrid.prototype = {
  3472. addObject: function (obj, point) {
  3473. var x = this._getCoord(point.x),
  3474. y = this._getCoord(point.y),
  3475. grid = this._grid,
  3476. row = grid[y] = grid[y] || {},
  3477. cell = row[x] = row[x] || [],
  3478. stamp = L.Util.stamp(obj);
  3479. this._objectPoint[stamp] = point;
  3480. cell.push(obj);
  3481. },
  3482. updateObject: function (obj, point) {
  3483. this.removeObject(obj);
  3484. this.addObject(obj, point);
  3485. },
  3486. //Returns true if the object was found
  3487. removeObject: function (obj, point) {
  3488. var x = this._getCoord(point.x),
  3489. y = this._getCoord(point.y),
  3490. grid = this._grid,
  3491. row = grid[y] = grid[y] || {},
  3492. cell = row[x] = row[x] || [],
  3493. i, len;
  3494. delete this._objectPoint[L.Util.stamp(obj)];
  3495. for (i = 0, len = cell.length; i < len; i++) {
  3496. if (cell[i] === obj) {
  3497. cell.splice(i, 1);
  3498. if (len === 1) {
  3499. delete row[x];
  3500. }
  3501. return true;
  3502. }
  3503. }
  3504. },
  3505. eachObject: function (fn, context) {
  3506. var i, j, k, len, row, cell, removed,
  3507. grid = this._grid;
  3508. for (i in grid) {
  3509. row = grid[i];
  3510. for (j in row) {
  3511. cell = row[j];
  3512. for (k = 0, len = cell.length; k < len; k++) {
  3513. removed = fn.call(context, cell[k]);
  3514. if (removed) {
  3515. k--;
  3516. len--;
  3517. }
  3518. }
  3519. }
  3520. }
  3521. },
  3522. getNearObject: function (point) {
  3523. var x = this._getCoord(point.x),
  3524. y = this._getCoord(point.y),
  3525. i, j, k, row, cell, len, obj, dist,
  3526. objectPoint = this._objectPoint,
  3527. closestDistSq = this._sqCellSize,
  3528. closest = null;
  3529. for (i = y - 1; i <= y + 1; i++) {
  3530. row = this._grid[i];
  3531. if (row) {
  3532. for (j = x - 1; j <= x + 1; j++) {
  3533. cell = row[j];
  3534. if (cell) {
  3535. for (k = 0, len = cell.length; k < len; k++) {
  3536. obj = cell[k];
  3537. dist = this._sqDist(objectPoint[L.Util.stamp(obj)], point);
  3538. if (dist < closestDistSq) {
  3539. closestDistSq = dist;
  3540. closest = obj;
  3541. }
  3542. }
  3543. }
  3544. }
  3545. }
  3546. }
  3547. return closest;
  3548. },
  3549. _getCoord: function (x) {
  3550. return Math.floor(x / this._cellSize);
  3551. },
  3552. _sqDist: function (p, p2) {
  3553. var dx = p2.x - p.x,
  3554. dy = p2.y - p.y;
  3555. return dx * dx + dy * dy;
  3556. }
  3557. };
  3558. /* Copyright (c) 2012 the authors listed at the following URL, and/or
  3559. the authors of referenced articles or incorporated external code:
  3560. http://en.literateprograms.org/Quickhull_(Javascript)?action=history&offset=20120410175256
  3561. Permission is hereby granted, free of charge, to any person obtaining
  3562. a copy of this software and associated documentation files (the
  3563. "Software"), to deal in the Software without restriction, including
  3564. without limitation the rights to use, copy, modify, merge, publish,
  3565. distribute, sublicense, and/or sell copies of the Software, and to
  3566. permit persons to whom the Software is furnished to do so, subject to
  3567. the following conditions:
  3568. The above copyright notice and this permission notice shall be
  3569. included in all copies or substantial portions of the Software.
  3570. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  3571. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  3572. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  3573. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  3574. CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  3575. TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  3576. SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  3577. Retrieved from: http://en.literateprograms.org/Quickhull_(Javascript)?oldid=18434
  3578. */
  3579. (function () {
  3580. L.QuickHull = {
  3581. /*
  3582. * @param {Object} cpt a point to be measured from the baseline
  3583. * @param {Array} bl the baseline, as represented by a two-element
  3584. * array of latlng objects.
  3585. * @returns {Number} an approximate distance measure
  3586. */
  3587. getDistant: function (cpt, bl) {
  3588. var vY = bl[1].lat - bl[0].lat,
  3589. vX = bl[0].lng - bl[1].lng;
  3590. return (vX * (cpt.lat - bl[0].lat) + vY * (cpt.lng - bl[0].lng));
  3591. },
  3592. /*
  3593. * @param {Array} baseLine a two-element array of latlng objects
  3594. * representing the baseline to project from
  3595. * @param {Array} latLngs an array of latlng objects
  3596. * @returns {Object} the maximum point and all new points to stay
  3597. * in consideration for the hull.
  3598. */
  3599. findMostDistantPointFromBaseLine: function (baseLine, latLngs) {
  3600. var maxD = 0,
  3601. maxPt = null,
  3602. newPoints = [],
  3603. i, pt, d;
  3604. for (i = latLngs.length - 1; i >= 0; i--) {
  3605. pt = latLngs[i];
  3606. d = this.getDistant(pt, baseLine);
  3607. if (d > 0) {
  3608. newPoints.push(pt);
  3609. } else {
  3610. continue;
  3611. }
  3612. if (d > maxD) {
  3613. maxD = d;
  3614. maxPt = pt;
  3615. }
  3616. }
  3617. return { maxPoint: maxPt, newPoints: newPoints };
  3618. },
  3619. /*
  3620. * Given a baseline, compute the convex hull of latLngs as an array
  3621. * of latLngs.
  3622. *
  3623. * @param {Array} latLngs
  3624. * @returns {Array}
  3625. */
  3626. buildConvexHull: function (baseLine, latLngs) {
  3627. var convexHullBaseLines = [],
  3628. t = this.findMostDistantPointFromBaseLine(baseLine, latLngs);
  3629. if (t.maxPoint) { // if there is still a point "outside" the base line
  3630. convexHullBaseLines =
  3631. convexHullBaseLines.concat(
  3632. this.buildConvexHull([baseLine[0], t.maxPoint], t.newPoints)
  3633. );
  3634. convexHullBaseLines =
  3635. convexHullBaseLines.concat(
  3636. this.buildConvexHull([t.maxPoint, baseLine[1]], t.newPoints)
  3637. );
  3638. return convexHullBaseLines;
  3639. } else { // if there is no more point "outside" the base line, the current base line is part of the convex hull
  3640. return [baseLine[0]];
  3641. }
  3642. },
  3643. /*
  3644. * Given an array of latlngs, compute a convex hull as an array
  3645. * of latlngs
  3646. *
  3647. * @param {Array} latLngs
  3648. * @returns {Array}
  3649. */
  3650. getConvexHull: function (latLngs) {
  3651. // find first baseline
  3652. var maxLat = false, minLat = false,
  3653. maxLng = false, minLng = false,
  3654. maxLatPt = null, minLatPt = null,
  3655. maxLngPt = null, minLngPt = null,
  3656. maxPt = null, minPt = null,
  3657. i;
  3658. for (i = latLngs.length - 1; i >= 0; i--) {
  3659. var pt = latLngs[i];
  3660. if (maxLat === false || pt.lat > maxLat) {
  3661. maxLatPt = pt;
  3662. maxLat = pt.lat;
  3663. }
  3664. if (minLat === false || pt.lat < minLat) {
  3665. minLatPt = pt;
  3666. minLat = pt.lat;
  3667. }
  3668. if (maxLng === false || pt.lng > maxLng) {
  3669. maxLngPt = pt;
  3670. maxLng = pt.lng;
  3671. }
  3672. if (minLng === false || pt.lng < minLng) {
  3673. minLngPt = pt;
  3674. minLng = pt.lng;
  3675. }
  3676. }
  3677. if (minLat !== maxLat) {
  3678. minPt = minLatPt;
  3679. maxPt = maxLatPt;
  3680. } else {
  3681. minPt = minLngPt;
  3682. maxPt = maxLngPt;
  3683. }
  3684. var ch = [].concat(this.buildConvexHull([minPt, maxPt], latLngs),
  3685. this.buildConvexHull([maxPt, minPt], latLngs));
  3686. return ch;
  3687. }
  3688. };
  3689. }());
  3690. L.MarkerCluster.include({
  3691. getConvexHull: function () {
  3692. var childMarkers = this.getAllChildMarkers(),
  3693. points = [],
  3694. p, i;
  3695. for (i = childMarkers.length - 1; i >= 0; i--) {
  3696. p = childMarkers[i].getLatLng();
  3697. points.push(p);
  3698. }
  3699. return L.QuickHull.getConvexHull(points);
  3700. }
  3701. });
  3702. //This code is 100% based on https://github.com/jawj/OverlappingMarkerSpiderfier-Leaflet
  3703. //Huge thanks to jawj for implementing it first to make my job easy :-)
  3704. L.MarkerCluster.include({
  3705. _2PI: Math.PI * 2,
  3706. _circleFootSeparation: 25, //related to circumference of circle
  3707. _circleStartAngle: Math.PI / 6,
  3708. _spiralFootSeparation: 28, //related to size of spiral (experiment!)
  3709. _spiralLengthStart: 11,
  3710. _spiralLengthFactor: 5,
  3711. _circleSpiralSwitchover: 9, //show spiral instead of circle from this marker count upwards.
  3712. // 0 -> always spiral; Infinity -> always circle
  3713. spiderfy: function () {
  3714. if (this._group._spiderfied === this || this._group._inZoomAnimation) {
  3715. return;
  3716. }
  3717. var childMarkers = this.getAllChildMarkers(),
  3718. group = this._group,
  3719. map = group._map,
  3720. center = map.latLngToLayerPoint(this._latlng),
  3721. positions;
  3722. this._group._unspiderfy();
  3723. this._group._spiderfied = this;
  3724. //TODO Maybe: childMarkers order by distance to center
  3725. if (childMarkers.length >= this._circleSpiralSwitchover) {
  3726. positions = this._generatePointsSpiral(childMarkers.length, center);
  3727. } else {
  3728. center.y += 10; // Otherwise circles look wrong => hack for standard blue icon, renders differently for other icons.
  3729. positions = this._generatePointsCircle(childMarkers.length, center);
  3730. }
  3731. this._animationSpiderfy(childMarkers, positions);
  3732. },
  3733. unspiderfy: function (zoomDetails) {
  3734. /// <param Name="zoomDetails">Argument from zoomanim if being called in a zoom animation or null otherwise</param>
  3735. if (this._group._inZoomAnimation) {
  3736. return;
  3737. }
  3738. this._animationUnspiderfy(zoomDetails);
  3739. this._group._spiderfied = null;
  3740. },
  3741. _generatePointsCircle: function (count, centerPt) {
  3742. var circumference = this._group.options.spiderfyDistanceMultiplier * this._circleFootSeparation * (2 + count),
  3743. legLength = circumference / this._2PI, //radius from circumference
  3744. angleStep = this._2PI / count,
  3745. res = [],
  3746. i, angle;
  3747. res.length = count;
  3748. for (i = count - 1; i >= 0; i--) {
  3749. angle = this._circleStartAngle + i * angleStep;
  3750. res[i] = new L.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle))._round();
  3751. }
  3752. return res;
  3753. },
  3754. _generatePointsSpiral: function (count, centerPt) {
  3755. var spiderfyDistanceMultiplier = this._group.options.spiderfyDistanceMultiplier,
  3756. legLength = spiderfyDistanceMultiplier * this._spiralLengthStart,
  3757. separation = spiderfyDistanceMultiplier * this._spiralFootSeparation,
  3758. lengthFactor = spiderfyDistanceMultiplier * this._spiralLengthFactor * this._2PI,
  3759. angle = 0,
  3760. res = [],
  3761. i;
  3762. res.length = count;
  3763. // Higher index, closer position to cluster center.
  3764. for (i = count - 1; i >= 0; i--) {
  3765. angle += separation / legLength + i * 0.0005;
  3766. res[i] = new L.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle))._round();
  3767. legLength += lengthFactor / angle;
  3768. }
  3769. return res;
  3770. },
  3771. _noanimationUnspiderfy: function () {
  3772. var group = this._group,
  3773. map = group._map,
  3774. fg = group._featureGroup,
  3775. childMarkers = this.getAllChildMarkers(),
  3776. m, i;
  3777. group._ignoreMove = true;
  3778. this.setOpacity(1);
  3779. for (i = childMarkers.length - 1; i >= 0; i--) {
  3780. m = childMarkers[i];
  3781. fg.removeLayer(m);
  3782. if (m._preSpiderfyLatlng) {
  3783. m.setLatLng(m._preSpiderfyLatlng);
  3784. delete m._preSpiderfyLatlng;
  3785. }
  3786. if (m.setZIndexOffset) {
  3787. m.setZIndexOffset(0);
  3788. }
  3789. if (m._spiderLeg) {
  3790. map.removeLayer(m._spiderLeg);
  3791. delete m._spiderLeg;
  3792. }
  3793. }
  3794. group.fire('unspiderfied', {
  3795. cluster: this,
  3796. markers: childMarkers
  3797. });
  3798. group._ignoreMove = false;
  3799. group._spiderfied = null;
  3800. }
  3801. });
  3802. //Non Animated versions of everything
  3803. L.MarkerClusterNonAnimated = L.MarkerCluster.extend({
  3804. _animationSpiderfy: function (childMarkers, positions) {
  3805. var group = this._group,
  3806. map = group._map,
  3807. fg = group._featureGroup,
  3808. legOptions = this._group.options.spiderLegPolylineOptions,
  3809. i, m, leg, newPos;
  3810. group._ignoreMove = true;
  3811. // Traverse in ascending order to make sure that inner circleMarkers are on top of further legs. Normal markers are re-ordered by newPosition.
  3812. // The reverse order trick no longer improves performance on modern browsers.
  3813. for (i = 0; i < childMarkers.length; i++) {
  3814. newPos = map.layerPointToLatLng(positions[i]);
  3815. m = childMarkers[i];
  3816. // Add the leg before the marker, so that in case the latter is a circleMarker, the leg is behind it.
  3817. leg = new L.Polyline([this._latlng, newPos], legOptions);
  3818. map.addLayer(leg);
  3819. m._spiderLeg = leg;
  3820. // Now add the marker.
  3821. m._preSpiderfyLatlng = m._latlng;
  3822. m.setLatLng(newPos);
  3823. if (m.setZIndexOffset) {
  3824. m.setZIndexOffset(1000000); //Make these appear on top of EVERYTHING
  3825. }
  3826. fg.addLayer(m);
  3827. }
  3828. this.setOpacity(0.3);
  3829. group._ignoreMove = false;
  3830. group.fire('spiderfied', {
  3831. cluster: this,
  3832. markers: childMarkers
  3833. });
  3834. },
  3835. _animationUnspiderfy: function () {
  3836. this._noanimationUnspiderfy();
  3837. }
  3838. });
  3839. //Animated versions here
  3840. L.MarkerCluster.include({
  3841. _animationSpiderfy: function (childMarkers, positions) {
  3842. var me = this,
  3843. group = this._group,
  3844. map = group._map,
  3845. fg = group._featureGroup,
  3846. thisLayerLatLng = this._latlng,
  3847. thisLayerPos = map.latLngToLayerPoint(thisLayerLatLng),
  3848. svg = L.Path.SVG,
  3849. legOptions = L.extend({}, this._group.options.spiderLegPolylineOptions), // Copy the options so that we can modify them for animation.
  3850. finalLegOpacity = legOptions.opacity,
  3851. i, m, leg, legPath, legLength, newPos;
  3852. if (finalLegOpacity === undefined) {
  3853. finalLegOpacity = L.MarkerClusterGroup.prototype.options.spiderLegPolylineOptions.opacity;
  3854. }
  3855. if (svg) {
  3856. // If the initial opacity of the spider leg is not 0 then it appears before the animation starts.
  3857. legOptions.opacity = 0;
  3858. // Add the class for CSS transitions.
  3859. legOptions.className = (legOptions.className || '') + ' leaflet-cluster-spider-leg';
  3860. } else {
  3861. // Make sure we have a defined opacity.
  3862. legOptions.opacity = finalLegOpacity;
  3863. }
  3864. group._ignoreMove = true;
  3865. // Add markers and spider legs to map, hidden at our center point.
  3866. // Traverse in ascending order to make sure that inner circleMarkers are on top of further legs. Normal markers are re-ordered by newPosition.
  3867. // The reverse order trick no longer improves performance on modern browsers.
  3868. for (i = 0; i < childMarkers.length; i++) {
  3869. m = childMarkers[i];
  3870. newPos = map.layerPointToLatLng(positions[i]);
  3871. // Add the leg before the marker, so that in case the latter is a circleMarker, the leg is behind it.
  3872. leg = new L.Polyline([thisLayerLatLng, newPos], legOptions);
  3873. map.addLayer(leg);
  3874. m._spiderLeg = leg;
  3875. // Explanations: https://jakearchibald.com/2013/animated-line-drawing-svg/
  3876. // In our case the transition property is declared in the CSS file.
  3877. if (svg) {
  3878. legPath = leg._path;
  3879. legLength = legPath.getTotalLength() + 0.1; // Need a small extra length to avoid remaining dot in Firefox.
  3880. legPath.style.strokeDasharray = legLength; // Just 1 length is enough, it will be duplicated.
  3881. legPath.style.strokeDashoffset = legLength;
  3882. }
  3883. // If it is a marker, add it now and we'll animate it out
  3884. if (m.setZIndexOffset) {
  3885. m.setZIndexOffset(1000000); // Make normal markers appear on top of EVERYTHING
  3886. }
  3887. if (m.clusterHide) {
  3888. m.clusterHide();
  3889. }
  3890. // Vectors just get immediately added
  3891. fg.addLayer(m);
  3892. if (m._setPos) {
  3893. m._setPos(thisLayerPos);
  3894. }
  3895. }
  3896. group._forceLayout();
  3897. group._animationStart();
  3898. // Reveal markers and spider legs.
  3899. for (i = childMarkers.length - 1; i >= 0; i--) {
  3900. newPos = map.layerPointToLatLng(positions[i]);
  3901. m = childMarkers[i];
  3902. //Move marker to new position
  3903. m._preSpiderfyLatlng = m._latlng;
  3904. m.setLatLng(newPos);
  3905. if (m.clusterShow) {
  3906. m.clusterShow();
  3907. }
  3908. // Animate leg (animation is actually delegated to CSS transition).
  3909. if (svg) {
  3910. leg = m._spiderLeg;
  3911. legPath = leg._path;
  3912. legPath.style.strokeDashoffset = 0;
  3913. //legPath.style.strokeOpacity = finalLegOpacity;
  3914. leg.setStyle({opacity: finalLegOpacity});
  3915. }
  3916. }
  3917. this.setOpacity(0.3);
  3918. group._ignoreMove = false;
  3919. setTimeout(function () {
  3920. group._animationEnd();
  3921. group.fire('spiderfied', {
  3922. cluster: me,
  3923. markers: childMarkers
  3924. });
  3925. }, 200);
  3926. },
  3927. _animationUnspiderfy: function (zoomDetails) {
  3928. var me = this,
  3929. group = this._group,
  3930. map = group._map,
  3931. fg = group._featureGroup,
  3932. thisLayerPos = zoomDetails ? map._latLngToNewLayerPoint(this._latlng, zoomDetails.zoom, zoomDetails.center) : map.latLngToLayerPoint(this._latlng),
  3933. childMarkers = this.getAllChildMarkers(),
  3934. svg = L.Path.SVG,
  3935. m, i, leg, legPath, legLength, nonAnimatable;
  3936. group._ignoreMove = true;
  3937. group._animationStart();
  3938. //Make us visible and bring the child markers back in
  3939. this.setOpacity(1);
  3940. for (i = childMarkers.length - 1; i >= 0; i--) {
  3941. m = childMarkers[i];
  3942. //Marker was added to us after we were spiderfied
  3943. if (!m._preSpiderfyLatlng) {
  3944. continue;
  3945. }
  3946. //Fix up the location to the real one
  3947. m.setLatLng(m._preSpiderfyLatlng);
  3948. delete m._preSpiderfyLatlng;
  3949. //Hack override the location to be our center
  3950. nonAnimatable = true;
  3951. if (m._setPos) {
  3952. m._setPos(thisLayerPos);
  3953. nonAnimatable = false;
  3954. }
  3955. if (m.clusterHide) {
  3956. m.clusterHide();
  3957. nonAnimatable = false;
  3958. }
  3959. if (nonAnimatable) {
  3960. fg.removeLayer(m);
  3961. }
  3962. // Animate the spider leg back in (animation is actually delegated to CSS transition).
  3963. if (svg) {
  3964. leg = m._spiderLeg;
  3965. legPath = leg._path;
  3966. legLength = legPath.getTotalLength() + 0.1;
  3967. legPath.style.strokeDashoffset = legLength;
  3968. leg.setStyle({opacity: 0});
  3969. }
  3970. }
  3971. group._ignoreMove = false;
  3972. setTimeout(function () {
  3973. //If we have only <= one child left then that marker will be shown on the map so don't remove it!
  3974. var stillThereChildCount = 0;
  3975. for (i = childMarkers.length - 1; i >= 0; i--) {
  3976. m = childMarkers[i];
  3977. if (m._spiderLeg) {
  3978. stillThereChildCount++;
  3979. }
  3980. }
  3981. for (i = childMarkers.length - 1; i >= 0; i--) {
  3982. m = childMarkers[i];
  3983. if (!m._spiderLeg) { //Has already been unspiderfied
  3984. continue;
  3985. }
  3986. if (m.clusterShow) {
  3987. m.clusterShow();
  3988. }
  3989. if (m.setZIndexOffset) {
  3990. m.setZIndexOffset(0);
  3991. }
  3992. if (stillThereChildCount > 1) {
  3993. fg.removeLayer(m);
  3994. }
  3995. map.removeLayer(m._spiderLeg);
  3996. delete m._spiderLeg;
  3997. }
  3998. group._animationEnd();
  3999. group.fire('unspiderfied', {
  4000. cluster: me,
  4001. markers: childMarkers
  4002. });
  4003. }, 200);
  4004. }
  4005. });
  4006. L.MarkerClusterGroup.include({
  4007. //The MarkerCluster currently spiderfied (if any)
  4008. _spiderfied: null,
  4009. unspiderfy: function () {
  4010. this._unspiderfy.apply(this, arguments);
  4011. },
  4012. _spiderfierOnAdd: function () {
  4013. this._map.on('click', this._unspiderfyWrapper, this);
  4014. if (this._map.options.zoomAnimation) {
  4015. this._map.on('zoomstart', this._unspiderfyZoomStart, this);
  4016. }
  4017. //Browsers without zoomAnimation or a big zoom don't fire zoomstart
  4018. this._map.on('zoomend', this._noanimationUnspiderfy, this);
  4019. if (!L.Browser.touch) {
  4020. this._map.getRenderer(this);
  4021. //Needs to happen in the pageload, not after, or animations don't work in webkit
  4022. // http://stackoverflow.com/questions/8455200/svg-animate-with-dynamically-added-elements
  4023. //Disable on touch browsers as the animation messes up on a touch zoom and isn't very noticable
  4024. }
  4025. },
  4026. _spiderfierOnRemove: function () {
  4027. this._map.off('click', this._unspiderfyWrapper, this);
  4028. this._map.off('zoomstart', this._unspiderfyZoomStart, this);
  4029. this._map.off('zoomanim', this._unspiderfyZoomAnim, this);
  4030. this._map.off('zoomend', this._noanimationUnspiderfy, this);
  4031. //Ensure that markers are back where they should be
  4032. // Use no animation to avoid a sticky leaflet-cluster-anim class on mapPane
  4033. this._noanimationUnspiderfy();
  4034. },
  4035. //On zoom start we add a zoomanim handler so that we are guaranteed to be last (after markers are animated)
  4036. //This means we can define the animation they do rather than Markers doing an animation to their actual location
  4037. _unspiderfyZoomStart: function () {
  4038. if (!this._map) { //May have been removed from the map by a zoomEnd handler
  4039. return;
  4040. }
  4041. this._map.on('zoomanim', this._unspiderfyZoomAnim, this);
  4042. },
  4043. _unspiderfyZoomAnim: function (zoomDetails) {
  4044. //Wait until the first zoomanim after the user has finished touch-zooming before running the animation
  4045. if (L.DomUtil.hasClass(this._map._mapPane, 'leaflet-touching')) {
  4046. return;
  4047. }
  4048. this._map.off('zoomanim', this._unspiderfyZoomAnim, this);
  4049. this._unspiderfy(zoomDetails);
  4050. },
  4051. _unspiderfyWrapper: function () {
  4052. /// <summary>_unspiderfy but passes no arguments</summary>
  4053. this._unspiderfy();
  4054. },
  4055. _unspiderfy: function (zoomDetails) {
  4056. if (this._spiderfied) {
  4057. this._spiderfied.unspiderfy(zoomDetails);
  4058. }
  4059. },
  4060. _noanimationUnspiderfy: function () {
  4061. if (this._spiderfied) {
  4062. this._spiderfied._noanimationUnspiderfy();
  4063. }
  4064. },
  4065. //If the given layer is currently being spiderfied then we unspiderfy it so it isn't on the map anymore etc
  4066. _unspiderfyLayer: function (layer) {
  4067. if (layer._spiderLeg) {
  4068. this._featureGroup.removeLayer(layer);
  4069. if (layer.clusterShow) {
  4070. layer.clusterShow();
  4071. }
  4072. //Position will be fixed up immediately in _animationUnspiderfy
  4073. if (layer.setZIndexOffset) {
  4074. layer.setZIndexOffset(0);
  4075. }
  4076. this._map.removeLayer(layer._spiderLeg);
  4077. delete layer._spiderLeg;
  4078. }
  4079. }
  4080. });
  4081. /**
  4082. * Adds 1 public method to MCG and 1 to L.Marker to facilitate changing
  4083. * markers' icon options and refreshing their icon and their parent clusters
  4084. * accordingly (case where their iconCreateFunction uses data of childMarkers
  4085. * to make up the cluster icon).
  4086. */
  4087. L.MarkerClusterGroup.include({
  4088. /**
  4089. * Updates the icon of all clusters which are parents of the given marker(s).
  4090. * In singleMarkerMode, also updates the given marker(s) icon.
  4091. * @param layers L.MarkerClusterGroup|L.LayerGroup|Array(L.Marker)|Map(L.Marker)|
  4092. * L.MarkerCluster|L.Marker (optional) list of markers (or single marker) whose parent
  4093. * clusters need to be updated. If not provided, retrieves all child markers of this.
  4094. * @returns {L.MarkerClusterGroup}
  4095. */
  4096. refreshClusters: function (layers) {
  4097. if (!layers) {
  4098. layers = this._topClusterLevel.getAllChildMarkers();
  4099. } else if (layers instanceof L.MarkerClusterGroup) {
  4100. layers = layers._topClusterLevel.getAllChildMarkers();
  4101. } else if (layers instanceof L.LayerGroup) {
  4102. layers = layers._layers;
  4103. } else if (layers instanceof L.MarkerCluster) {
  4104. layers = layers.getAllChildMarkers();
  4105. } else if (layers instanceof L.Marker) {
  4106. layers = [layers];
  4107. } // else: must be an Array(L.Marker)|Map(L.Marker)
  4108. this._flagParentsIconsNeedUpdate(layers);
  4109. this._refreshClustersIcons();
  4110. // In case of singleMarkerMode, also re-draw the markers.
  4111. if (this.options.singleMarkerMode) {
  4112. this._refreshSingleMarkerModeMarkers(layers);
  4113. }
  4114. return this;
  4115. },
  4116. /**
  4117. * Simply flags all parent clusters of the given markers as having a "dirty" icon.
  4118. * @param layers Array(L.Marker)|Map(L.Marker) list of markers.
  4119. * @private
  4120. */
  4121. _flagParentsIconsNeedUpdate: function (layers) {
  4122. var id, parent;
  4123. // Assumes layers is an Array or an Object whose prototype is non-enumerable.
  4124. for (id in layers) {
  4125. // Flag parent clusters' icon as "dirty", all the way up.
  4126. // Dumb process that flags multiple times upper parents, but still
  4127. // much more efficient than trying to be smart and make short lists,
  4128. // at least in the case of a hierarchy following a power law:
  4129. // http://jsperf.com/flag-nodes-in-power-hierarchy/2
  4130. parent = layers[id].__parent;
  4131. while (parent) {
  4132. parent._iconNeedsUpdate = true;
  4133. parent = parent.__parent;
  4134. }
  4135. }
  4136. },
  4137. /**
  4138. * Re-draws the icon of the supplied markers.
  4139. * To be used in singleMarkerMode only.
  4140. * @param layers Array(L.Marker)|Map(L.Marker) list of markers.
  4141. * @private
  4142. */
  4143. _refreshSingleMarkerModeMarkers: function (layers) {
  4144. var id, layer;
  4145. for (id in layers) {
  4146. layer = layers[id];
  4147. // Make sure we do not override markers that do not belong to THIS group.
  4148. if (this.hasLayer(layer)) {
  4149. // Need to re-create the icon first, then re-draw the marker.
  4150. layer.setIcon(this._overrideMarkerIcon(layer));
  4151. }
  4152. }
  4153. }
  4154. });
  4155. L.Marker.include({
  4156. /**
  4157. * Updates the given options in the marker's icon and refreshes the marker.
  4158. * @param options map object of icon options.
  4159. * @param directlyRefreshClusters boolean (optional) true to trigger
  4160. * MCG.refreshClustersOf() right away with this single marker.
  4161. * @returns {L.Marker}
  4162. */
  4163. refreshIconOptions: function (options, directlyRefreshClusters) {
  4164. var icon = this.options.icon;
  4165. L.setOptions(icon, options);
  4166. this.setIcon(icon);
  4167. // Shortcut to refresh the associated MCG clusters right away.
  4168. // To be used when refreshing a single marker.
  4169. // Otherwise, better use MCG.refreshClusters() once at the end with
  4170. // the list of modified markers.
  4171. if (directlyRefreshClusters && this.__parent) {
  4172. this.__parent._group.refreshClusters(this);
  4173. }
  4174. return this;
  4175. }
  4176. });
  4177. }(window, document));
  4178. 'use strict';
  4179. (function (factory, window) {
  4180. /*globals define, module, require*/
  4181. // define an AMD module that relies on 'leaflet'
  4182. if (typeof define === 'function' && define.amd) {
  4183. define(['leaflet'], factory);
  4184. // define a Common JS module that relies on 'leaflet'
  4185. } else if (typeof exports === 'object') {
  4186. module.exports = factory(require('leaflet'));
  4187. }
  4188. // attach your plugin to the global 'L' variable
  4189. if(typeof window !== 'undefined' && window.L){
  4190. factory(window.L);
  4191. }
  4192. }(function (L) {
  4193. // 🍂miniclass CancelableEvent (Event objects)
  4194. // 🍂method cancel()
  4195. // Cancel any subsequent action.
  4196. // 🍂miniclass VertexEvent (Event objects)
  4197. // 🍂property vertex: VertexMarker
  4198. // The vertex that fires the event.
  4199. // 🍂miniclass ShapeEvent (Event objects)
  4200. // 🍂property shape: Array
  4201. // The shape (LatLngs array) subject of the action.
  4202. // 🍂miniclass CancelableVertexEvent (Event objects)
  4203. // 🍂inherits VertexEvent
  4204. // 🍂inherits CancelableEvent
  4205. // 🍂miniclass CancelableShapeEvent (Event objects)
  4206. // 🍂inherits ShapeEvent
  4207. // 🍂inherits CancelableEvent
  4208. // 🍂miniclass LayerEvent (Event objects)
  4209. // 🍂property layer: object
  4210. // The Layer (Marker, Polyline…) subject of the action.
  4211. // 🍂namespace Editable; 🍂class Editable; 🍂aka L.Editable
  4212. // Main edition handler. By default, it is attached to the map
  4213. // as `map.editTools` property.
  4214. // Leaflet.Editable is made to be fully extendable. You have three ways to customize
  4215. // the behaviour: using options, listening to events, or extending.
  4216. L.Editable = L.Evented.extend({
  4217. statics: {
  4218. FORWARD: 1,
  4219. BACKWARD: -1
  4220. },
  4221. options: {
  4222. // You can pass them when creating a map using the `editOptions` key.
  4223. // 🍂option zIndex: int = 1000
  4224. // The default zIndex of the editing tools.
  4225. zIndex: 1000,
  4226. // 🍂option polygonClass: class = L.Polygon
  4227. // Class to be used when creating a new Polygon.
  4228. polygonClass: L.Polygon,
  4229. // 🍂option polylineClass: class = L.Polyline
  4230. // Class to be used when creating a new Polyline.
  4231. polylineClass: L.Polyline,
  4232. // 🍂option markerClass: class = L.Marker
  4233. // Class to be used when creating a new Marker.
  4234. markerClass: L.Marker,
  4235. // 🍂option rectangleClass: class = L.Rectangle
  4236. // Class to be used when creating a new Rectangle.
  4237. rectangleClass: L.Rectangle,
  4238. // 🍂option circleClass: class = L.Circle
  4239. // Class to be used when creating a new Circle.
  4240. circleClass: L.Circle,
  4241. // 🍂option drawingCSSClass: string = 'leaflet-editable-drawing'
  4242. // CSS class to be added to the map container while drawing.
  4243. drawingCSSClass: 'leaflet-editable-drawing',
  4244. // 🍂option drawingCursor: const = 'crosshair'
  4245. // Cursor mode set to the map while drawing.
  4246. drawingCursor: 'crosshair',
  4247. // 🍂option editLayer: Layer = new L.LayerGroup()
  4248. // Layer used to store edit tools (vertex, line guide…).
  4249. editLayer: undefined,
  4250. // 🍂option featuresLayer: Layer = new L.LayerGroup()
  4251. // Default layer used to store drawn features (Marker, Polyline…).
  4252. featuresLayer: undefined,
  4253. // 🍂option polylineEditorClass: class = PolylineEditor
  4254. // Class to be used as Polyline editor.
  4255. polylineEditorClass: undefined,
  4256. // 🍂option polygonEditorClass: class = PolygonEditor
  4257. // Class to be used as Polygon editor.
  4258. polygonEditorClass: undefined,
  4259. // 🍂option markerEditorClass: class = MarkerEditor
  4260. // Class to be used as Marker editor.
  4261. markerEditorClass: undefined,
  4262. // 🍂option rectangleEditorClass: class = RectangleEditor
  4263. // Class to be used as Rectangle editor.
  4264. rectangleEditorClass: undefined,
  4265. // 🍂option circleEditorClass: class = CircleEditor
  4266. // Class to be used as Circle editor.
  4267. circleEditorClass: undefined,
  4268. // 🍂option lineGuideOptions: hash = {}
  4269. // Options to be passed to the line guides.
  4270. lineGuideOptions: {},
  4271. // 🍂option skipMiddleMarkers: boolean = false
  4272. // Set this to true if you don't want middle markers.
  4273. skipMiddleMarkers: false
  4274. },
  4275. initialize: function (map, options) {
  4276. L.setOptions(this, options);
  4277. this._lastZIndex = this.options.zIndex;
  4278. this.map = map;
  4279. this.editLayer = this.createEditLayer();
  4280. this.featuresLayer = this.createFeaturesLayer();
  4281. this.forwardLineGuide = this.createLineGuide();
  4282. this.backwardLineGuide = this.createLineGuide();
  4283. },
  4284. fireAndForward: function (type, e) {
  4285. e = e || {};
  4286. e.editTools = this;
  4287. this.fire(type, e);
  4288. this.map.fire(type, e);
  4289. },
  4290. createLineGuide: function () {
  4291. var options = L.extend({dashArray: '5,10', weight: 1, interactive: false}, this.options.lineGuideOptions);
  4292. return L.polyline([], options);
  4293. },
  4294. createVertexIcon: function (options) {
  4295. return L.Browser.touch ? new L.Editable.TouchVertexIcon(options) : new L.Editable.VertexIcon(options);
  4296. },
  4297. createEditLayer: function () {
  4298. return this.options.editLayer || new L.LayerGroup().addTo(this.map);
  4299. },
  4300. createFeaturesLayer: function () {
  4301. return this.options.featuresLayer || new L.LayerGroup().addTo(this.map);
  4302. },
  4303. moveForwardLineGuide: function (latlng) {
  4304. if (this.forwardLineGuide._latlngs.length) {
  4305. this.forwardLineGuide._latlngs[1] = latlng;
  4306. this.forwardLineGuide._bounds.extend(latlng);
  4307. this.forwardLineGuide.redraw();
  4308. }
  4309. },
  4310. moveBackwardLineGuide: function (latlng) {
  4311. if (this.backwardLineGuide._latlngs.length) {
  4312. this.backwardLineGuide._latlngs[1] = latlng;
  4313. this.backwardLineGuide._bounds.extend(latlng);
  4314. this.backwardLineGuide.redraw();
  4315. }
  4316. },
  4317. anchorForwardLineGuide: function (latlng) {
  4318. this.forwardLineGuide._latlngs[0] = latlng;
  4319. this.forwardLineGuide._bounds.extend(latlng);
  4320. this.forwardLineGuide.redraw();
  4321. },
  4322. anchorBackwardLineGuide: function (latlng) {
  4323. this.backwardLineGuide._latlngs[0] = latlng;
  4324. this.backwardLineGuide._bounds.extend(latlng);
  4325. this.backwardLineGuide.redraw();
  4326. },
  4327. attachForwardLineGuide: function () {
  4328. this.editLayer.addLayer(this.forwardLineGuide);
  4329. },
  4330. attachBackwardLineGuide: function () {
  4331. this.editLayer.addLayer(this.backwardLineGuide);
  4332. },
  4333. detachForwardLineGuide: function () {
  4334. this.forwardLineGuide.setLatLngs([]);
  4335. this.editLayer.removeLayer(this.forwardLineGuide);
  4336. },
  4337. detachBackwardLineGuide: function () {
  4338. this.backwardLineGuide.setLatLngs([]);
  4339. this.editLayer.removeLayer(this.backwardLineGuide);
  4340. },
  4341. blockEvents: function () {
  4342. // Hack: force map not to listen to other layers events while drawing.
  4343. if (!this._oldTargets) {
  4344. this._oldTargets = this.map._targets;
  4345. this.map._targets = {};
  4346. }
  4347. },
  4348. unblockEvents: function () {
  4349. if (this._oldTargets) {
  4350. // Reset, but keep targets created while drawing.
  4351. this.map._targets = L.extend(this.map._targets, this._oldTargets);
  4352. delete this._oldTargets;
  4353. }
  4354. },
  4355. registerForDrawing: function (editor) {
  4356. if (this._drawingEditor) this.unregisterForDrawing(this._drawingEditor);
  4357. this.blockEvents();
  4358. editor.reset(); // Make sure editor tools still receive events.
  4359. this._drawingEditor = editor;
  4360. this.map.on('mousemove touchmove', editor.onDrawingMouseMove, editor);
  4361. this.map.on('mousedown', this.onMousedown, this);
  4362. this.map.on('mouseup', this.onMouseup, this);
  4363. L.DomUtil.addClass(this.map._container, this.options.drawingCSSClass);
  4364. this.defaultMapCursor = this.map._container.style.cursor;
  4365. this.map._container.style.cursor = this.options.drawingCursor;
  4366. },
  4367. unregisterForDrawing: function (editor) {
  4368. this.unblockEvents();
  4369. L.DomUtil.removeClass(this.map._container, this.options.drawingCSSClass);
  4370. this.map._container.style.cursor = this.defaultMapCursor;
  4371. editor = editor || this._drawingEditor;
  4372. if (!editor) return;
  4373. this.map.off('mousemove touchmove', editor.onDrawingMouseMove, editor);
  4374. this.map.off('mousedown', this.onMousedown, this);
  4375. this.map.off('mouseup', this.onMouseup, this);
  4376. if (editor !== this._drawingEditor) return;
  4377. delete this._drawingEditor;
  4378. if (editor._drawing) editor.cancelDrawing();
  4379. },
  4380. onMousedown: function (e) {
  4381. this._mouseDown = e;
  4382. this._drawingEditor.onDrawingMouseDown(e);
  4383. },
  4384. onMouseup: function (e) {
  4385. if (this._mouseDown) {
  4386. var editor = this._drawingEditor,
  4387. mouseDown = this._mouseDown;
  4388. this._mouseDown = null;
  4389. editor.onDrawingMouseUp(e);
  4390. if (this._drawingEditor !== editor) return; // onDrawingMouseUp may call unregisterFromDrawing.
  4391. var origin = L.point(mouseDown.originalEvent.clientX, mouseDown.originalEvent.clientY);
  4392. var distance = L.point(e.originalEvent.clientX, e.originalEvent.clientY).distanceTo(origin);
  4393. if (Math.abs(distance) < 9 * (window.devicePixelRatio || 1)) this._drawingEditor.onDrawingClick(e);
  4394. }
  4395. },
  4396. // 🍂section Public methods
  4397. // You will generally access them by the `map.editTools`
  4398. // instance:
  4399. //
  4400. // `map.editTools.startPolyline();`
  4401. // 🍂method drawing(): boolean
  4402. // Return true if any drawing action is ongoing.
  4403. drawing: function () {
  4404. return this._drawingEditor && this._drawingEditor.drawing();
  4405. },
  4406. // 🍂method stopDrawing()
  4407. // When you need to stop any ongoing drawing, without needing to know which editor is active.
  4408. stopDrawing: function () {
  4409. this.unregisterForDrawing();
  4410. },
  4411. // 🍂method commitDrawing()
  4412. // When you need to commit any ongoing drawing, without needing to know which editor is active.
  4413. commitDrawing: function (e) {
  4414. if (!this._drawingEditor) return;
  4415. this._drawingEditor.commitDrawing(e);
  4416. },
  4417. connectCreatedToMap: function (layer) {
  4418. return this.featuresLayer.addLayer(layer);
  4419. },
  4420. // 🍂method startPolyline(latlng: L.LatLng, options: hash): L.Polyline
  4421. // Start drawing a Polyline. If `latlng` is given, a first point will be added. In any case, continuing on user click.
  4422. // If `options` is given, it will be passed to the Polyline class constructor.
  4423. startPolyline: function (latlng, options) {
  4424. var line = this.createPolyline([], options);
  4425. line.enableEdit(this.map).newShape(latlng);
  4426. return line;
  4427. },
  4428. // 🍂method startPolygon(latlng: L.LatLng, options: hash): L.Polygon
  4429. // Start drawing a Polygon. If `latlng` is given, a first point will be added. In any case, continuing on user click.
  4430. // If `options` is given, it will be passed to the Polygon class constructor.
  4431. startPolygon: function (latlng, options) {
  4432. var polygon = this.createPolygon([], options);
  4433. polygon.enableEdit(this.map).newShape(latlng);
  4434. return polygon;
  4435. },
  4436. // 🍂method startMarker(latlng: L.LatLng, options: hash): L.Marker
  4437. // Start adding a Marker. If `latlng` is given, the Marker will be shown first at this point.
  4438. // In any case, it will follow the user mouse, and will have a final `latlng` on next click (or touch).
  4439. // If `options` is given, it will be passed to the Marker class constructor.
  4440. startMarker: function (latlng, options) {
  4441. latlng = latlng || this.map.getCenter().clone();
  4442. var marker = this.createMarker(latlng, options);
  4443. marker.enableEdit(this.map).startDrawing();
  4444. return marker;
  4445. },
  4446. // 🍂method startRectangle(latlng: L.LatLng, options: hash): L.Rectangle
  4447. // Start drawing a Rectangle. If `latlng` is given, the Rectangle anchor will be added. In any case, continuing on user drag.
  4448. // If `options` is given, it will be passed to the Rectangle class constructor.
  4449. startRectangle: function(latlng, options) {
  4450. var corner = latlng || L.latLng([0, 0]);
  4451. var bounds = new L.LatLngBounds(corner, corner);
  4452. var rectangle = this.createRectangle(bounds, options);
  4453. rectangle.enableEdit(this.map).startDrawing();
  4454. return rectangle;
  4455. },
  4456. // 🍂method startCircle(latlng: L.LatLng, options: hash): L.Circle
  4457. // Start drawing a Circle. If `latlng` is given, the Circle anchor will be added. In any case, continuing on user drag.
  4458. // If `options` is given, it will be passed to the Circle class constructor.
  4459. startCircle: function (latlng, options) {
  4460. latlng = latlng || this.map.getCenter().clone();
  4461. var circle = this.createCircle(latlng, options);
  4462. circle.enableEdit(this.map).startDrawing();
  4463. return circle;
  4464. },
  4465. startHole: function (editor, latlng) {
  4466. editor.newHole(latlng);
  4467. },
  4468. createLayer: function (klass, latlngs, options) {
  4469. options = L.Util.extend({editOptions: {editTools: this}}, options);
  4470. var layer = new klass(latlngs, options);
  4471. // 🍂namespace Editable
  4472. // 🍂event editable:created: LayerEvent
  4473. // Fired when a new feature (Marker, Polyline…) is created.
  4474. this.fireAndForward('editable:created', {layer: layer});
  4475. return layer;
  4476. },
  4477. createPolyline: function (latlngs, options) {
  4478. return this.createLayer(options && options.polylineClass || this.options.polylineClass, latlngs, options);
  4479. },
  4480. createPolygon: function (latlngs, options) {
  4481. return this.createLayer(options && options.polygonClass || this.options.polygonClass, latlngs, options);
  4482. },
  4483. createMarker: function (latlng, options) {
  4484. return this.createLayer(options && options.markerClass || this.options.markerClass, latlng, options);
  4485. },
  4486. createRectangle: function (bounds, options) {
  4487. return this.createLayer(options && options.rectangleClass || this.options.rectangleClass, bounds, options);
  4488. },
  4489. createCircle: function (latlng, options) {
  4490. return this.createLayer(options && options.circleClass || this.options.circleClass, latlng, options);
  4491. }
  4492. });
  4493. L.extend(L.Editable, {
  4494. makeCancellable: function (e) {
  4495. e.cancel = function () {
  4496. e._cancelled = true;
  4497. };
  4498. }
  4499. });
  4500. // 🍂namespace Map; 🍂class Map
  4501. // Leaflet.Editable add options and events to the `L.Map` object.
  4502. // See `Editable` events for the list of events fired on the Map.
  4503. // 🍂example
  4504. //
  4505. // ```js
  4506. // var map = L.map('map', {
  4507. // editable: true,
  4508. // editOptions: {
  4509. // …
  4510. // }
  4511. // });
  4512. // ```
  4513. // 🍂section Editable Map Options
  4514. L.Map.mergeOptions({
  4515. // 🍂namespace Map
  4516. // 🍂section Map Options
  4517. // 🍂option editToolsClass: class = L.Editable
  4518. // Class to be used as vertex, for path editing.
  4519. editToolsClass: L.Editable,
  4520. // 🍂option editable: boolean = false
  4521. // Whether to create a L.Editable instance at map init.
  4522. editable: false,
  4523. // 🍂option editOptions: hash = {}
  4524. // Options to pass to L.Editable when instanciating.
  4525. editOptions: {}
  4526. });
  4527. L.Map.addInitHook(function () {
  4528. this.whenReady(function () {
  4529. if (this.options.editable) {
  4530. this.editTools = new this.options.editToolsClass(this, this.options.editOptions);
  4531. }
  4532. });
  4533. });
  4534. L.Editable.VertexIcon = L.DivIcon.extend({
  4535. options: {
  4536. iconSize: new L.Point(8, 8)
  4537. }
  4538. });
  4539. L.Editable.TouchVertexIcon = L.Editable.VertexIcon.extend({
  4540. options: {
  4541. iconSize: new L.Point(20, 20)
  4542. }
  4543. });
  4544. // 🍂namespace Editable; 🍂class VertexMarker; Handler for dragging path vertices.
  4545. L.Editable.VertexMarker = L.Marker.extend({
  4546. options: {
  4547. draggable: true,
  4548. className: 'leaflet-div-icon leaflet-vertex-icon'
  4549. },
  4550. // 🍂section Public methods
  4551. // The marker used to handle path vertex. You will usually interact with a `VertexMarker`
  4552. // instance when listening for events like `editable:vertex:ctrlclick`.
  4553. initialize: function (latlng, latlngs, editor, options) {
  4554. // We don't use this._latlng, because on drag Leaflet replace it while
  4555. // we want to keep reference.
  4556. this.latlng = latlng;
  4557. this.latlngs = latlngs;
  4558. this.editor = editor;
  4559. L.Marker.prototype.initialize.call(this, latlng, options);
  4560. this.options.icon = this.editor.tools.createVertexIcon({className: this.options.className});
  4561. this.latlng.__vertex = this;
  4562. this.editor.editLayer.addLayer(this);
  4563. this.setZIndexOffset(editor.tools._lastZIndex + 1);
  4564. },
  4565. onAdd: function (map) {
  4566. L.Marker.prototype.onAdd.call(this, map);
  4567. this.on('drag', this.onDrag);
  4568. this.on('dragstart', this.onDragStart);
  4569. this.on('dragend', this.onDragEnd);
  4570. this.on('mouseup', this.onMouseup);
  4571. this.on('click', this.onClick);
  4572. this.on('contextmenu', this.onContextMenu);
  4573. this.on('mousedown touchstart', this.onMouseDown);
  4574. this.addMiddleMarkers();
  4575. },
  4576. onRemove: function (map) {
  4577. if (this.middleMarker) this.middleMarker.delete();
  4578. delete this.latlng.__vertex;
  4579. this.off('drag', this.onDrag);
  4580. this.off('dragstart', this.onDragStart);
  4581. this.off('dragend', this.onDragEnd);
  4582. this.off('mouseup', this.onMouseup);
  4583. this.off('click', this.onClick);
  4584. this.off('contextmenu', this.onContextMenu);
  4585. this.off('mousedown touchstart', this.onMouseDown);
  4586. L.Marker.prototype.onRemove.call(this, map);
  4587. },
  4588. onDrag: function (e) {
  4589. e.vertex = this;
  4590. this.editor.onVertexMarkerDrag(e);
  4591. var iconPos = L.DomUtil.getPosition(this._icon),
  4592. latlng = this._map.layerPointToLatLng(iconPos);
  4593. this.latlng.update(latlng);
  4594. this._latlng = this.latlng; // Push back to Leaflet our reference.
  4595. this.editor.refresh();
  4596. if (this.middleMarker) this.middleMarker.updateLatLng();
  4597. var next = this.getNext();
  4598. if (next && next.middleMarker) next.middleMarker.updateLatLng();
  4599. },
  4600. onDragStart: function (e) {
  4601. e.vertex = this;
  4602. this.editor.onVertexMarkerDragStart(e);
  4603. },
  4604. onDragEnd: function (e) {
  4605. e.vertex = this;
  4606. this.editor.onVertexMarkerDragEnd(e);
  4607. },
  4608. onClick: function (e) {
  4609. e.vertex = this;
  4610. this.editor.onVertexMarkerClick(e);
  4611. },
  4612. onMouseup: function (e) {
  4613. L.DomEvent.stop(e);
  4614. e.vertex = this;
  4615. this.editor.map.fire('mouseup', e);
  4616. },
  4617. onContextMenu: function (e) {
  4618. e.vertex = this;
  4619. this.editor.onVertexMarkerContextMenu(e);
  4620. },
  4621. onMouseDown: function (e) {
  4622. e.vertex = this;
  4623. this.editor.onVertexMarkerMouseDown(e);
  4624. },
  4625. // 🍂method delete()
  4626. // Delete a vertex and the related LatLng.
  4627. delete: function () {
  4628. var next = this.getNext(); // Compute before changing latlng
  4629. this.latlngs.splice(this.getIndex(), 1);
  4630. this.editor.editLayer.removeLayer(this);
  4631. this.editor.onVertexDeleted({latlng: this.latlng, vertex: this});
  4632. if (!this.latlngs.length) this.editor.deleteShape(this.latlngs);
  4633. if (next) next.resetMiddleMarker();
  4634. this.editor.refresh();
  4635. },
  4636. // 🍂method getIndex(): int
  4637. // Get the index of the current vertex among others of the same LatLngs group.
  4638. getIndex: function () {
  4639. return this.latlngs.indexOf(this.latlng);
  4640. },
  4641. // 🍂method getLastIndex(): int
  4642. // Get last vertex index of the LatLngs group of the current vertex.
  4643. getLastIndex: function () {
  4644. return this.latlngs.length - 1;
  4645. },
  4646. // 🍂method getPrevious(): VertexMarker
  4647. // Get the previous VertexMarker in the same LatLngs group.
  4648. getPrevious: function () {
  4649. if (this.latlngs.length < 2) return;
  4650. var index = this.getIndex(),
  4651. previousIndex = index - 1;
  4652. if (index === 0 && this.editor.CLOSED) previousIndex = this.getLastIndex();
  4653. var previous = this.latlngs[previousIndex];
  4654. if (previous) return previous.__vertex;
  4655. },
  4656. // 🍂method getNext(): VertexMarker
  4657. // Get the next VertexMarker in the same LatLngs group.
  4658. getNext: function () {
  4659. if (this.latlngs.length < 2) return;
  4660. var index = this.getIndex(),
  4661. nextIndex = index + 1;
  4662. if (index === this.getLastIndex() && this.editor.CLOSED) nextIndex = 0;
  4663. var next = this.latlngs[nextIndex];
  4664. if (next) return next.__vertex;
  4665. },
  4666. addMiddleMarker: function (previous) {
  4667. if (!this.editor.hasMiddleMarkers()) return;
  4668. previous = previous || this.getPrevious();
  4669. if (previous && !this.middleMarker) this.middleMarker = this.editor.addMiddleMarker(previous, this, this.latlngs, this.editor);
  4670. },
  4671. addMiddleMarkers: function () {
  4672. if (!this.editor.hasMiddleMarkers()) return;
  4673. var previous = this.getPrevious();
  4674. if (previous) this.addMiddleMarker(previous);
  4675. var next = this.getNext();
  4676. if (next) next.resetMiddleMarker();
  4677. },
  4678. resetMiddleMarker: function () {
  4679. if (this.middleMarker) this.middleMarker.delete();
  4680. this.addMiddleMarker();
  4681. },
  4682. // 🍂method split()
  4683. // Split the vertex LatLngs group at its index, if possible.
  4684. split: function () {
  4685. if (!this.editor.splitShape) return; // Only for PolylineEditor
  4686. this.editor.splitShape(this.latlngs, this.getIndex());
  4687. },
  4688. // 🍂method continue()
  4689. // Continue the vertex LatLngs from this vertex. Only active for first and last vertices of a Polyline.
  4690. continue: function () {
  4691. if (!this.editor.continueBackward) return; // Only for PolylineEditor
  4692. var index = this.getIndex();
  4693. if (index === 0) this.editor.continueBackward(this.latlngs);
  4694. else if (index === this.getLastIndex()) this.editor.continueForward(this.latlngs);
  4695. }
  4696. });
  4697. L.Editable.mergeOptions({
  4698. // 🍂namespace Editable
  4699. // 🍂option vertexMarkerClass: class = VertexMarker
  4700. // Class to be used as vertex, for path editing.
  4701. vertexMarkerClass: L.Editable.VertexMarker
  4702. });
  4703. L.Editable.MiddleMarker = L.Marker.extend({
  4704. options: {
  4705. opacity: 0.5,
  4706. className: 'leaflet-div-icon leaflet-middle-icon',
  4707. draggable: true
  4708. },
  4709. initialize: function (left, right, latlngs, editor, options) {
  4710. this.left = left;
  4711. this.right = right;
  4712. this.editor = editor;
  4713. this.latlngs = latlngs;
  4714. L.Marker.prototype.initialize.call(this, this.computeLatLng(), options);
  4715. this._opacity = this.options.opacity;
  4716. this.options.icon = this.editor.tools.createVertexIcon({className: this.options.className});
  4717. this.editor.editLayer.addLayer(this);
  4718. this.setVisibility();
  4719. },
  4720. setVisibility: function () {
  4721. var leftPoint = this._map.latLngToContainerPoint(this.left.latlng),
  4722. rightPoint = this._map.latLngToContainerPoint(this.right.latlng),
  4723. size = L.point(this.options.icon.options.iconSize);
  4724. if (leftPoint.distanceTo(rightPoint) < size.x * 3) this.hide();
  4725. else this.show();
  4726. },
  4727. show: function () {
  4728. this.setOpacity(this._opacity);
  4729. },
  4730. hide: function () {
  4731. this.setOpacity(0);
  4732. },
  4733. updateLatLng: function () {
  4734. this.setLatLng(this.computeLatLng());
  4735. this.setVisibility();
  4736. },
  4737. computeLatLng: function () {
  4738. var leftPoint = this.editor.map.latLngToContainerPoint(this.left.latlng),
  4739. rightPoint = this.editor.map.latLngToContainerPoint(this.right.latlng),
  4740. y = (leftPoint.y + rightPoint.y) / 2,
  4741. x = (leftPoint.x + rightPoint.x) / 2;
  4742. return this.editor.map.containerPointToLatLng([x, y]);
  4743. },
  4744. onAdd: function (map) {
  4745. L.Marker.prototype.onAdd.call(this, map);
  4746. L.DomEvent.on(this._icon, 'mousedown touchstart', this.onMouseDown, this);
  4747. map.on('zoomend', this.setVisibility, this);
  4748. },
  4749. onRemove: function (map) {
  4750. delete this.right.middleMarker;
  4751. L.DomEvent.off(this._icon, 'mousedown touchstart', this.onMouseDown, this);
  4752. map.off('zoomend', this.setVisibility, this);
  4753. L.Marker.prototype.onRemove.call(this, map);
  4754. },
  4755. onMouseDown: function (e) {
  4756. var iconPos = L.DomUtil.getPosition(this._icon),
  4757. latlng = this.editor.map.layerPointToLatLng(iconPos);
  4758. e = {
  4759. originalEvent: e,
  4760. latlng: latlng
  4761. };
  4762. if (this.options.opacity === 0) return;
  4763. L.Editable.makeCancellable(e);
  4764. this.editor.onMiddleMarkerMouseDown(e);
  4765. if (e._cancelled) return;
  4766. this.latlngs.splice(this.index(), 0, e.latlng);
  4767. this.editor.refresh();
  4768. var icon = this._icon;
  4769. var marker = this.editor.addVertexMarker(e.latlng, this.latlngs);
  4770. /* Hack to workaround browser not firing touchend when element is no more on DOM */
  4771. var parent = marker._icon.parentNode;
  4772. parent.removeChild(marker._icon);
  4773. marker._icon = icon;
  4774. parent.appendChild(marker._icon);
  4775. marker._initIcon();
  4776. marker._initInteraction();
  4777. marker.setOpacity(1);
  4778. /* End hack */
  4779. // Transfer ongoing dragging to real marker
  4780. L.Draggable._dragging = false;
  4781. marker.dragging._draggable._onDown(e.originalEvent);
  4782. this.delete();
  4783. },
  4784. delete: function () {
  4785. this.editor.editLayer.removeLayer(this);
  4786. },
  4787. index: function () {
  4788. return this.latlngs.indexOf(this.right.latlng);
  4789. }
  4790. });
  4791. L.Editable.mergeOptions({
  4792. // 🍂namespace Editable
  4793. // 🍂option middleMarkerClass: class = VertexMarker
  4794. // Class to be used as middle vertex, pulled by the user to create a new point in the middle of a path.
  4795. middleMarkerClass: L.Editable.MiddleMarker
  4796. });
  4797. // 🍂namespace Editable; 🍂class BaseEditor; 🍂aka L.Editable.BaseEditor
  4798. // When editing a feature (Marker, Polyline…), an editor is attached to it. This
  4799. // editor basically knows how to handle the edition.
  4800. L.Editable.BaseEditor = L.Handler.extend({
  4801. initialize: function (map, feature, options) {
  4802. L.setOptions(this, options);
  4803. this.map = map;
  4804. this.feature = feature;
  4805. this.feature.editor = this;
  4806. this.editLayer = new L.LayerGroup();
  4807. this.tools = this.options.editTools || map.editTools;
  4808. },
  4809. // 🍂method enable(): this
  4810. // Set up the drawing tools for the feature to be editable.
  4811. addHooks: function () {
  4812. if (this.isConnected()) this.onFeatureAdd();
  4813. else this.feature.once('add', this.onFeatureAdd, this);
  4814. this.onEnable();
  4815. this.feature.on(this._getEvents(), this);
  4816. return;
  4817. },
  4818. // 🍂method disable(): this
  4819. // Remove the drawing tools for the feature.
  4820. removeHooks: function () {
  4821. this.feature.off(this._getEvents(), this);
  4822. if (this.feature.dragging) this.feature.dragging.disable();
  4823. this.editLayer.clearLayers();
  4824. this.tools.editLayer.removeLayer(this.editLayer);
  4825. this.onDisable();
  4826. if (this._drawing) this.cancelDrawing();
  4827. return;
  4828. },
  4829. // 🍂method drawing(): boolean
  4830. // Return true if any drawing action is ongoing with this editor.
  4831. drawing: function () {
  4832. return !!this._drawing;
  4833. },
  4834. reset: function () {},
  4835. onFeatureAdd: function () {
  4836. this.tools.editLayer.addLayer(this.editLayer);
  4837. if (this.feature.dragging) this.feature.dragging.enable();
  4838. },
  4839. hasMiddleMarkers: function () {
  4840. return !this.options.skipMiddleMarkers && !this.tools.options.skipMiddleMarkers;
  4841. },
  4842. fireAndForward: function (type, e) {
  4843. if(this.feature.linetype === "circleline" || this.feature.linetype === "circlepolygon"){
  4844. }else{
  4845. e = e || {};
  4846. e.layer = this.feature;
  4847. this.feature.fire(type, e);
  4848. this.tools.fireAndForward(type, e);
  4849. }
  4850. },
  4851. onEnable: function () {
  4852. // 🍂namespace Editable
  4853. // 🍂event editable:enable: Event
  4854. // Fired when an existing feature is ready to be edited.
  4855. this.fireAndForward('editable:enable');
  4856. },
  4857. onDisable: function () {
  4858. // 🍂namespace Editable
  4859. // 🍂event editable:disable: Event
  4860. // Fired when an existing feature is not ready anymore to be edited.
  4861. this.fireAndForward('editable:disable');
  4862. },
  4863. onEditing: function () {
  4864. // 🍂namespace Editable
  4865. // 🍂event editable:editing: Event
  4866. // Fired as soon as any change is made to the feature geometry.
  4867. this.fireAndForward('editable:editing');
  4868. },
  4869. onStartDrawing: function () {
  4870. // 🍂namespace Editable
  4871. // 🍂section Drawing events
  4872. // 🍂event editable:drawing:start: Event
  4873. // Fired when a feature is to be drawn.
  4874. this.fireAndForward('editable:drawing:start');
  4875. },
  4876. onEndDrawing: function () {
  4877. // 🍂namespace Editable
  4878. // 🍂section Drawing events
  4879. // 🍂event editable:drawing:end: Event
  4880. // Fired when a feature is not drawn anymore.
  4881. this.fireAndForward('editable:drawing:end');
  4882. },
  4883. onCancelDrawing: function () {
  4884. // 🍂namespace Editable
  4885. // 🍂section Drawing events
  4886. // 🍂event editable:drawing:cancel: Event
  4887. // Fired when user cancel drawing while a feature is being drawn.
  4888. this.fireAndForward('editable:drawing:cancel');
  4889. },
  4890. onCommitDrawing: function (e) {
  4891. // 🍂namespace Editable
  4892. // 🍂section Drawing events
  4893. // 🍂event editable:drawing:commit: Event
  4894. // Fired when user finish drawing a feature.
  4895. this.fireAndForward('editable:drawing:commit', e);
  4896. },
  4897. onDrawingMouseDown: function (e) {
  4898. // 🍂namespace Editable
  4899. // 🍂section Drawing events
  4900. // 🍂event editable:drawing:mousedown: Event
  4901. // Fired when user `mousedown` while drawing.
  4902. this.fireAndForward('editable:drawing:mousedown', e);
  4903. },
  4904. onDrawingMouseUp: function (e) {
  4905. // 🍂namespace Editable
  4906. // 🍂section Drawing events
  4907. // 🍂event editable:drawing:mouseup: Event
  4908. // Fired when user `mouseup` while drawing.
  4909. this.fireAndForward('editable:drawing:mouseup', e);
  4910. },
  4911. startDrawing: function () {
  4912. if (!this._drawing) this._drawing = L.Editable.FORWARD;
  4913. this.tools.registerForDrawing(this);
  4914. this.onStartDrawing();
  4915. },
  4916. commitDrawing: function (e) {
  4917. this.onCommitDrawing(e);
  4918. this.endDrawing();
  4919. },
  4920. cancelDrawing: function () {
  4921. // If called during a vertex drag, the vertex will be removed before
  4922. // the mouseup fires on it. This is a workaround. Maybe better fix is
  4923. // To have L.Draggable reset it's status on disable (Leaflet side).
  4924. L.Draggable._dragging = false;
  4925. this.onCancelDrawing();
  4926. this.endDrawing();
  4927. },
  4928. endDrawing: function () {
  4929. this._drawing = false;
  4930. this.tools.unregisterForDrawing(this);
  4931. this.onEndDrawing();
  4932. },
  4933. onDrawingClick: function (e) {
  4934. if (!this.drawing()) return;
  4935. L.Editable.makeCancellable(e);
  4936. // 🍂namespace Editable
  4937. // 🍂section Drawing events
  4938. // 🍂event editable:drawing:click: CancelableEvent
  4939. // Fired when user `click` while drawing, before any internal action is being processed.
  4940. this.fireAndForward('editable:drawing:click', e);
  4941. if (e._cancelled) return;
  4942. if (!this.isConnected()) this.connect(e);
  4943. this.processDrawingClick(e);
  4944. },
  4945. isConnected: function () {
  4946. return this.map.hasLayer(this.feature);
  4947. },
  4948. connect: function (e) {
  4949. this.tools.connectCreatedToMap(this.feature);
  4950. this.tools.editLayer.addLayer(this.editLayer);
  4951. },
  4952. onMove: function (e) {
  4953. // 🍂namespace Editable
  4954. // 🍂section Drawing events
  4955. // 🍂event editable:drawing:move: Event
  4956. // Fired when `move` mouse while drawing, while dragging a marker, and while dragging a vertex.
  4957. this.fireAndForward('editable:drawing:move', e);
  4958. },
  4959. onDrawingMouseMove: function (e) {
  4960. this.onMove(e);
  4961. },
  4962. _getEvents: function () {
  4963. return {
  4964. dragstart: this.onDragStart,
  4965. drag: this.onDrag,
  4966. dragend: this.onDragEnd,
  4967. remove: this.disable
  4968. };
  4969. },
  4970. onDragStart: function (e) {
  4971. this.onEditing();
  4972. // 🍂namespace Editable
  4973. // 🍂event editable:dragstart: Event
  4974. // Fired before a path feature is dragged.
  4975. this.fireAndForward('editable:dragstart', e);
  4976. },
  4977. onDrag: function (e) {
  4978. this.onMove(e);
  4979. // 🍂namespace Editable
  4980. // 🍂event editable:drag: Event
  4981. // Fired when a path feature is being dragged.
  4982. this.fireAndForward('editable:drag', e);
  4983. },
  4984. onDragEnd: function (e) {
  4985. // 🍂namespace Editable
  4986. // 🍂event editable:dragend: Event
  4987. // Fired after a path feature has been dragged.
  4988. this.fireAndForward('editable:dragend', e);
  4989. }
  4990. });
  4991. // 🍂namespace Editable; 🍂class MarkerEditor; 🍂aka L.Editable.MarkerEditor
  4992. // 🍂inherits BaseEditor
  4993. // Editor for Marker.
  4994. L.Editable.MarkerEditor = L.Editable.BaseEditor.extend({
  4995. onDrawingMouseMove: function (e) {
  4996. L.Editable.BaseEditor.prototype.onDrawingMouseMove.call(this, e);
  4997. if (this._drawing) this.feature.setLatLng(e.latlng);
  4998. },
  4999. processDrawingClick: function (e) {
  5000. // 🍂namespace Editable
  5001. // 🍂section Drawing events
  5002. // 🍂event editable:drawing:clicked: Event
  5003. // Fired when user `click` while drawing, after all internal actions.
  5004. this.fireAndForward('editable:drawing:clicked', e);
  5005. this.commitDrawing(e);
  5006. },
  5007. connect: function (e) {
  5008. // On touch, the latlng has not been updated because there is
  5009. // no mousemove.
  5010. if (e) this.feature._latlng = e.latlng;
  5011. L.Editable.BaseEditor.prototype.connect.call(this, e);
  5012. }
  5013. });
  5014. // 🍂namespace Editable; 🍂class PathEditor; 🍂aka L.Editable.PathEditor
  5015. // 🍂inherits BaseEditor
  5016. // Base class for all path editors.
  5017. L.Editable.PathEditor = L.Editable.BaseEditor.extend({
  5018. CLOSED: false,
  5019. MIN_VERTEX: 2,
  5020. addHooks: function () {
  5021. L.Editable.BaseEditor.prototype.addHooks.call(this);
  5022. if (this.feature) this.initVertexMarkers();
  5023. return this;
  5024. },
  5025. initVertexMarkers: function (latlngs) {
  5026. if (!this.enabled()) return;
  5027. latlngs = latlngs || this.getLatLngs();
  5028. if (L.Polyline._flat(latlngs)) this.addVertexMarkers(latlngs);
  5029. else for (var i = 0; i < latlngs.length; i++) this.initVertexMarkers(latlngs[i]);
  5030. },
  5031. getLatLngs: function () {
  5032. return this.feature.getLatLngs();
  5033. },
  5034. // 🍂method reset()
  5035. // Rebuild edit elements (Vertex, MiddleMarker, etc.).
  5036. reset: function () {
  5037. this.editLayer.clearLayers();
  5038. this.initVertexMarkers();
  5039. },
  5040. addVertexMarker: function (latlng, latlngs) {
  5041. return new this.tools.options.vertexMarkerClass(latlng, latlngs, this);
  5042. },
  5043. addVertexMarkers: function (latlngs) {
  5044. for (var i = 0; i < latlngs.length; i++) {
  5045. this.addVertexMarker(latlngs[i], latlngs);
  5046. }
  5047. },
  5048. refreshVertexMarkers: function (latlngs) {
  5049. latlngs = latlngs || this.getDefaultLatLngs();
  5050. for (var i = 0; i < latlngs.length; i++) {
  5051. latlngs[i].__vertex.update();
  5052. }
  5053. },
  5054. addMiddleMarker: function (left, right, latlngs) {
  5055. return new this.tools.options.middleMarkerClass(left, right, latlngs, this);
  5056. },
  5057. onVertexMarkerClick: function (e) {
  5058. L.Editable.makeCancellable(e);
  5059. // 🍂namespace Editable
  5060. // 🍂section Vertex events
  5061. // 🍂event editable:vertex:click: CancelableVertexEvent
  5062. // Fired when a `click` is issued on a vertex, before any internal action is being processed.
  5063. this.fireAndForward('editable:vertex:click', e);
  5064. if (e._cancelled) return;
  5065. if (this.tools.drawing() && this.tools._drawingEditor !== this) return;
  5066. var index = e.vertex.getIndex(), commit;
  5067. if (e.originalEvent.ctrlKey) {
  5068. this.onVertexMarkerCtrlClick(e);
  5069. } else if (e.originalEvent.altKey) {
  5070. this.onVertexMarkerAltClick(e);
  5071. } else if (e.originalEvent.shiftKey) {
  5072. this.onVertexMarkerShiftClick(e);
  5073. } else if (e.originalEvent.metaKey) {
  5074. this.onVertexMarkerMetaKeyClick(e);
  5075. } else if (index === e.vertex.getLastIndex() && this._drawing === L.Editable.FORWARD) {
  5076. if (index >= this.MIN_VERTEX - 1) commit = true;
  5077. } else if (index === 0 && this._drawing === L.Editable.BACKWARD && this._drawnLatLngs.length >= this.MIN_VERTEX) {
  5078. commit = true;
  5079. } else if (index === 0 && this._drawing === L.Editable.FORWARD && this._drawnLatLngs.length >= this.MIN_VERTEX && this.CLOSED) {
  5080. commit = true; // Allow to close on first point also for polygons
  5081. } else {
  5082. this.onVertexRawMarkerClick(e);
  5083. }
  5084. // 🍂namespace Editable
  5085. // 🍂section Vertex events
  5086. // 🍂event editable:vertex:clicked: VertexEvent
  5087. // Fired when a `click` is issued on a vertex, after all internal actions.
  5088. this.fireAndForward('editable:vertex:clicked', e);
  5089. if (commit) this.commitDrawing(e);
  5090. },
  5091. onVertexRawMarkerClick: function (e) {
  5092. // 🍂namespace Editable
  5093. // 🍂section Vertex events
  5094. // 🍂event editable:vertex:rawclick: CancelableVertexEvent
  5095. // Fired when a `click` is issued on a vertex without any special key and without being in drawing mode.
  5096. this.fireAndForward('editable:vertex:rawclick', e);
  5097. if (e._cancelled) return;
  5098. if (!this.vertexCanBeDeleted(e.vertex)) return;
  5099. e.vertex.delete();
  5100. },
  5101. vertexCanBeDeleted: function (vertex) {
  5102. return vertex.latlngs.length > this.MIN_VERTEX;
  5103. },
  5104. onVertexDeleted: function (e) {
  5105. // 🍂namespace Editable
  5106. // 🍂section Vertex events
  5107. // 🍂event editable:vertex:deleted: VertexEvent
  5108. // Fired after a vertex has been deleted by user.
  5109. this.fireAndForward('editable:vertex:deleted', e);
  5110. },
  5111. onVertexMarkerCtrlClick: function (e) {
  5112. // 🍂namespace Editable
  5113. // 🍂section Vertex events
  5114. // 🍂event editable:vertex:ctrlclick: VertexEvent
  5115. // Fired when a `click` with `ctrlKey` is issued on a vertex.
  5116. this.fireAndForward('editable:vertex:ctrlclick', e);
  5117. },
  5118. onVertexMarkerShiftClick: function (e) {
  5119. // 🍂namespace Editable
  5120. // 🍂section Vertex events
  5121. // 🍂event editable:vertex:shiftclick: VertexEvent
  5122. // Fired when a `click` with `shiftKey` is issued on a vertex.
  5123. this.fireAndForward('editable:vertex:shiftclick', e);
  5124. },
  5125. onVertexMarkerMetaKeyClick: function (e) {
  5126. // 🍂namespace Editable
  5127. // 🍂section Vertex events
  5128. // 🍂event editable:vertex:metakeyclick: VertexEvent
  5129. // Fired when a `click` with `metaKey` is issued on a vertex.
  5130. this.fireAndForward('editable:vertex:metakeyclick', e);
  5131. },
  5132. onVertexMarkerAltClick: function (e) {
  5133. // 🍂namespace Editable
  5134. // 🍂section Vertex events
  5135. // 🍂event editable:vertex:altclick: VertexEvent
  5136. // Fired when a `click` with `altKey` is issued on a vertex.
  5137. this.fireAndForward('editable:vertex:altclick', e);
  5138. },
  5139. onVertexMarkerContextMenu: function (e) {
  5140. // 🍂namespace Editable
  5141. // 🍂section Vertex events
  5142. // 🍂event editable:vertex:contextmenu: VertexEvent
  5143. // Fired when a `contextmenu` is issued on a vertex.
  5144. this.fireAndForward('editable:vertex:contextmenu', e);
  5145. },
  5146. onVertexMarkerMouseDown: function (e) {
  5147. // 🍂namespace Editable
  5148. // 🍂section Vertex events
  5149. // 🍂event editable:vertex:mousedown: VertexEvent
  5150. // Fired when user `mousedown` a vertex.
  5151. this.fireAndForward('editable:vertex:mousedown', e);
  5152. },
  5153. onMiddleMarkerMouseDown: function (e) {
  5154. // 🍂namespace Editable
  5155. // 🍂section MiddleMarker events
  5156. // 🍂event editable:middlemarker:mousedown: VertexEvent
  5157. // Fired when user `mousedown` a middle marker.
  5158. this.fireAndForward('editable:middlemarker:mousedown', e);
  5159. },
  5160. onVertexMarkerDrag: function (e) {
  5161. this.onMove(e);
  5162. if (this.feature._bounds) this.extendBounds(e);
  5163. // 🍂namespace Editable
  5164. // 🍂section Vertex events
  5165. // 🍂event editable:vertex:drag: VertexEvent
  5166. // Fired when a vertex is dragged by user.
  5167. this.fireAndForward('editable:vertex:drag', e);
  5168. },
  5169. onVertexMarkerDragStart: function (e) {
  5170. // 🍂namespace Editable
  5171. // 🍂section Vertex events
  5172. // 🍂event editable:vertex:dragstart: VertexEvent
  5173. // Fired before a vertex is dragged by user.
  5174. this.fireAndForward('editable:vertex:dragstart', e);
  5175. },
  5176. onVertexMarkerDragEnd: function (e) {
  5177. // 🍂namespace Editable
  5178. // 🍂section Vertex events
  5179. // 🍂event editable:vertex:dragend: VertexEvent
  5180. // Fired after a vertex is dragged by user.
  5181. this.fireAndForward('editable:vertex:dragend', e);
  5182. },
  5183. setDrawnLatLngs: function (latlngs) {
  5184. this._drawnLatLngs = latlngs || this.getDefaultLatLngs();
  5185. },
  5186. startDrawing: function () {
  5187. if (!this._drawnLatLngs) this.setDrawnLatLngs();
  5188. L.Editable.BaseEditor.prototype.startDrawing.call(this);
  5189. },
  5190. startDrawingForward: function () {
  5191. this.startDrawing();
  5192. },
  5193. endDrawing: function () {
  5194. this.tools.detachForwardLineGuide();
  5195. this.tools.detachBackwardLineGuide();
  5196. if (this._drawnLatLngs && this._drawnLatLngs.length < this.MIN_VERTEX) this.deleteShape(this._drawnLatLngs);
  5197. L.Editable.BaseEditor.prototype.endDrawing.call(this);
  5198. delete this._drawnLatLngs;
  5199. },
  5200. addLatLng: function (latlng) {
  5201. if (this._drawing === L.Editable.FORWARD) this._drawnLatLngs.push(latlng);
  5202. else this._drawnLatLngs.unshift(latlng);
  5203. this.feature._bounds.extend(latlng);
  5204. this.addVertexMarker(latlng, this._drawnLatLngs);
  5205. this.refresh();
  5206. },
  5207. newPointForward: function (latlng) {
  5208. this.addLatLng(latlng);
  5209. this.tools.attachForwardLineGuide();
  5210. this.tools.anchorForwardLineGuide(latlng);
  5211. },
  5212. newPointBackward: function (latlng) {
  5213. this.addLatLng(latlng);
  5214. this.tools.anchorBackwardLineGuide(latlng);
  5215. },
  5216. // 🍂namespace PathEditor
  5217. // 🍂method push()
  5218. // Programmatically add a point while drawing.
  5219. push: function (latlng) {
  5220. if (!latlng) return console.error('L.Editable.PathEditor.push expect a vaild latlng as parameter');
  5221. if (this._drawing === L.Editable.FORWARD) this.newPointForward(latlng);
  5222. else this.newPointBackward(latlng);
  5223. },
  5224. removeLatLng: function (latlng) {
  5225. latlng.__vertex.delete();
  5226. this.refresh();
  5227. },
  5228. // 🍂method pop(): L.LatLng or null
  5229. // Programmatically remove last point (if any) while drawing.
  5230. pop: function () {
  5231. if (this._drawnLatLngs.length <= 1) return;
  5232. var latlng;
  5233. if (this._drawing === L.Editable.FORWARD) latlng = this._drawnLatLngs[this._drawnLatLngs.length - 1];
  5234. else latlng = this._drawnLatLngs[0];
  5235. this.removeLatLng(latlng);
  5236. if (this._drawing === L.Editable.FORWARD) this.tools.anchorForwardLineGuide(this._drawnLatLngs[this._drawnLatLngs.length - 1]);
  5237. else this.tools.anchorForwardLineGuide(this._drawnLatLngs[0]);
  5238. return latlng;
  5239. },
  5240. processDrawingClick: function (e) {
  5241. if (e.vertex && e.vertex.editor === this) return;
  5242. if (this._drawing === L.Editable.FORWARD) this.newPointForward(e.latlng);
  5243. else this.newPointBackward(e.latlng);
  5244. this.fireAndForward('editable:drawing:clicked', e);
  5245. },
  5246. onDrawingMouseMove: function (e) {
  5247. L.Editable.BaseEditor.prototype.onDrawingMouseMove.call(this, e);
  5248. if (this._drawing) {
  5249. this.tools.moveForwardLineGuide(e.latlng);
  5250. this.tools.moveBackwardLineGuide(e.latlng);
  5251. }
  5252. },
  5253. refresh: function () {
  5254. this.feature.redraw();
  5255. this.onEditing();
  5256. },
  5257. // 🍂namespace PathEditor
  5258. // 🍂method newShape(latlng?: L.LatLng)
  5259. // Add a new shape (Polyline, Polygon) in a multi, and setup up drawing tools to draw it;
  5260. // if optional `latlng` is given, start a path at this point.
  5261. newShape: function (latlng) {
  5262. var shape = this.addNewEmptyShape();
  5263. if (!shape) return;
  5264. this.setDrawnLatLngs(shape[0] || shape); // Polygon or polyline
  5265. this.startDrawingForward();
  5266. // 🍂namespace Editable
  5267. // 🍂section Shape events
  5268. // 🍂event editable:shape:new: ShapeEvent
  5269. // Fired when a new shape is created in a multi (Polygon or Polyline).
  5270. this.fireAndForward('editable:shape:new', {shape: shape});
  5271. if (latlng) this.newPointForward(latlng);
  5272. },
  5273. deleteShape: function (shape, latlngs) {
  5274. var e = {shape: shape};
  5275. L.Editable.makeCancellable(e);
  5276. // 🍂namespace Editable
  5277. // 🍂section Shape events
  5278. // 🍂event editable:shape:delete: CancelableShapeEvent
  5279. // Fired before a new shape is deleted in a multi (Polygon or Polyline).
  5280. this.fireAndForward('editable:shape:delete', e);
  5281. if (e._cancelled) return;
  5282. shape = this._deleteShape(shape, latlngs);
  5283. if (this.ensureNotFlat) this.ensureNotFlat(); // Polygon.
  5284. this.feature.setLatLngs(this.getLatLngs()); // Force bounds reset.
  5285. this.refresh();
  5286. this.reset();
  5287. // 🍂namespace Editable
  5288. // 🍂section Shape events
  5289. // 🍂event editable:shape:deleted: ShapeEvent
  5290. // Fired after a new shape is deleted in a multi (Polygon or Polyline).
  5291. this.fireAndForward('editable:shape:deleted', {shape: shape});
  5292. return shape;
  5293. },
  5294. _deleteShape: function (shape, latlngs) {
  5295. latlngs = latlngs || this.getLatLngs();
  5296. if (!latlngs.length) return;
  5297. var self = this,
  5298. inplaceDelete = function (latlngs, shape) {
  5299. // Called when deleting a flat latlngs
  5300. shape = latlngs.splice(0, Number.MAX_VALUE);
  5301. return shape;
  5302. },
  5303. spliceDelete = function (latlngs, shape) {
  5304. // Called when removing a latlngs inside an array
  5305. latlngs.splice(latlngs.indexOf(shape), 1);
  5306. if (!latlngs.length) self._deleteShape(latlngs);
  5307. return shape;
  5308. };
  5309. if (latlngs === shape) return inplaceDelete(latlngs, shape);
  5310. for (var i = 0; i < latlngs.length; i++) {
  5311. if (latlngs[i] === shape) return spliceDelete(latlngs, shape);
  5312. else if (latlngs[i].indexOf(shape) !== -1) return spliceDelete(latlngs[i], shape);
  5313. }
  5314. },
  5315. // 🍂namespace PathEditor
  5316. // 🍂method deleteShapeAt(latlng: L.LatLng): Array
  5317. // Remove a path shape at the given `latlng`.
  5318. deleteShapeAt: function (latlng) {
  5319. var shape = this.feature.shapeAt(latlng);
  5320. if (shape) return this.deleteShape(shape);
  5321. },
  5322. // 🍂method appendShape(shape: Array)
  5323. // Append a new shape to the Polygon or Polyline.
  5324. appendShape: function (shape) {
  5325. this.insertShape(shape);
  5326. },
  5327. // 🍂method prependShape(shape: Array)
  5328. // Prepend a new shape to the Polygon or Polyline.
  5329. prependShape: function (shape) {
  5330. this.insertShape(shape, 0);
  5331. },
  5332. // 🍂method insertShape(shape: Array, index: int)
  5333. // Insert a new shape to the Polygon or Polyline at given index (default is to append).
  5334. insertShape: function (shape, index) {
  5335. this.ensureMulti();
  5336. shape = this.formatShape(shape);
  5337. if (typeof index === 'undefined') index = this.feature._latlngs.length;
  5338. this.feature._latlngs.splice(index, 0, shape);
  5339. this.feature.redraw();
  5340. if (this._enabled) this.reset();
  5341. },
  5342. extendBounds: function (e) {
  5343. this.feature._bounds.extend(e.vertex.latlng);
  5344. },
  5345. onDragStart: function (e) {
  5346. this.editLayer.clearLayers();
  5347. L.Editable.BaseEditor.prototype.onDragStart.call(this, e);
  5348. },
  5349. onDragEnd: function (e) {
  5350. this.initVertexMarkers();
  5351. L.Editable.BaseEditor.prototype.onDragEnd.call(this, e);
  5352. }
  5353. });
  5354. // 🍂namespace Editable; 🍂class PolylineEditor; 🍂aka L.Editable.PolylineEditor
  5355. // 🍂inherits PathEditor
  5356. L.Editable.PolylineEditor = L.Editable.PathEditor.extend({
  5357. startDrawingBackward: function () {
  5358. this._drawing = L.Editable.BACKWARD;
  5359. this.startDrawing();
  5360. },
  5361. // 🍂method continueBackward(latlngs?: Array)
  5362. // Set up drawing tools to continue the line backward.
  5363. continueBackward: function (latlngs) {
  5364. if (this.drawing()) return;
  5365. latlngs = latlngs || this.getDefaultLatLngs();
  5366. this.setDrawnLatLngs(latlngs);
  5367. if (latlngs.length > 0) {
  5368. this.tools.attachBackwardLineGuide();
  5369. this.tools.anchorBackwardLineGuide(latlngs[0]);
  5370. }
  5371. this.startDrawingBackward();
  5372. },
  5373. // 🍂method continueForward(latlngs?: Array)
  5374. // Set up drawing tools to continue the line forward.
  5375. continueForward: function (latlngs) {
  5376. if (this.drawing()) return;
  5377. latlngs = latlngs || this.getDefaultLatLngs();
  5378. this.setDrawnLatLngs(latlngs);
  5379. if (latlngs.length > 0) {
  5380. this.tools.attachForwardLineGuide();
  5381. this.tools.anchorForwardLineGuide(latlngs[latlngs.length - 1]);
  5382. }
  5383. this.startDrawingForward();
  5384. },
  5385. getDefaultLatLngs: function (latlngs) {
  5386. latlngs = latlngs || this.feature._latlngs;
  5387. if (!latlngs.length || latlngs[0] instanceof L.LatLng) return latlngs;
  5388. else return this.getDefaultLatLngs(latlngs[0]);
  5389. },
  5390. ensureMulti: function () {
  5391. if (this.feature._latlngs.length && L.Polyline._flat(this.feature._latlngs)) {
  5392. this.feature._latlngs = [this.feature._latlngs];
  5393. }
  5394. },
  5395. addNewEmptyShape: function () {
  5396. if (this.feature._latlngs.length) {
  5397. var shape = [];
  5398. this.appendShape(shape);
  5399. return shape;
  5400. } else {
  5401. return this.feature._latlngs;
  5402. }
  5403. },
  5404. formatShape: function (shape) {
  5405. if (L.Polyline._flat(shape)) return shape;
  5406. else if (shape[0]) return this.formatShape(shape[0]);
  5407. },
  5408. // 🍂method splitShape(latlngs?: Array, index: int)
  5409. // Split the given `latlngs` shape at index `index` and integrate new shape in instance `latlngs`.
  5410. splitShape: function (shape, index) {
  5411. if (!index || index >= shape.length - 1) return;
  5412. this.ensureMulti();
  5413. var shapeIndex = this.feature._latlngs.indexOf(shape);
  5414. if (shapeIndex === -1) return;
  5415. var first = shape.slice(0, index + 1),
  5416. second = shape.slice(index);
  5417. // We deal with reference, we don't want twice the same latlng around.
  5418. second[0] = L.latLng(second[0].lat, second[0].lng, second[0].alt);
  5419. this.feature._latlngs.splice(shapeIndex, 1, first, second);
  5420. this.refresh();
  5421. this.reset();
  5422. }
  5423. });
  5424. // 🍂namespace Editable; 🍂class PolygonEditor; 🍂aka L.Editable.PolygonEditor
  5425. // 🍂inherits PathEditor
  5426. L.Editable.PolygonEditor = L.Editable.PathEditor.extend({
  5427. CLOSED: true,
  5428. MIN_VERTEX: 3,
  5429. newPointForward: function (latlng) {
  5430. L.Editable.PathEditor.prototype.newPointForward.call(this, latlng);
  5431. if (!this.tools.backwardLineGuide._latlngs.length) this.tools.anchorBackwardLineGuide(latlng);
  5432. if (this._drawnLatLngs.length === 2) this.tools.attachBackwardLineGuide();
  5433. },
  5434. addNewEmptyHole: function (latlng) {
  5435. this.ensureNotFlat();
  5436. var latlngs = this.feature.shapeAt(latlng);
  5437. if (!latlngs) return;
  5438. var holes = [];
  5439. latlngs.push(holes);
  5440. return holes;
  5441. },
  5442. // 🍂method newHole(latlng?: L.LatLng, index: int)
  5443. // Set up drawing tools for creating a new hole on the Polygon. If the `latlng` param is given, a first point is created.
  5444. newHole: function (latlng) {
  5445. var holes = this.addNewEmptyHole(latlng);
  5446. if (!holes) return;
  5447. this.setDrawnLatLngs(holes);
  5448. this.startDrawingForward();
  5449. if (latlng) this.newPointForward(latlng);
  5450. },
  5451. addNewEmptyShape: function () {
  5452. if (this.feature._latlngs.length && this.feature._latlngs[0].length) {
  5453. var shape = [];
  5454. this.appendShape(shape);
  5455. return shape;
  5456. } else {
  5457. return this.feature._latlngs;
  5458. }
  5459. },
  5460. ensureMulti: function () {
  5461. if (this.feature._latlngs.length && L.Polyline._flat(this.feature._latlngs[0])) {
  5462. this.feature._latlngs = [this.feature._latlngs];
  5463. }
  5464. },
  5465. ensureNotFlat: function () {
  5466. if (!this.feature._latlngs.length || L.Polyline._flat(this.feature._latlngs)) this.feature._latlngs = [this.feature._latlngs];
  5467. },
  5468. vertexCanBeDeleted: function (vertex) {
  5469. var parent = this.feature.parentShape(vertex.latlngs),
  5470. idx = L.Util.indexOf(parent, vertex.latlngs);
  5471. if (idx > 0) return true; // Holes can be totally deleted without removing the layer itself.
  5472. return L.Editable.PathEditor.prototype.vertexCanBeDeleted.call(this, vertex);
  5473. },
  5474. getDefaultLatLngs: function () {
  5475. if (!this.feature._latlngs.length) this.feature._latlngs.push([]);
  5476. return this.feature._latlngs[0];
  5477. },
  5478. formatShape: function (shape) {
  5479. // [[1, 2], [3, 4]] => must be nested
  5480. // [] => must be nested
  5481. // [[]] => is already nested
  5482. if (L.Polyline._flat(shape) && (!shape[0] || shape[0].length !== 0)) return [shape];
  5483. else return shape;
  5484. }
  5485. });
  5486. // 🍂namespace Editable; 🍂class RectangleEditor; 🍂aka L.Editable.RectangleEditor
  5487. // 🍂inherits PathEditor
  5488. L.Editable.RectangleEditor = L.Editable.PathEditor.extend({
  5489. CLOSED: true,
  5490. MIN_VERTEX: 4,
  5491. options: {
  5492. skipMiddleMarkers: true
  5493. },
  5494. extendBounds: function (e) {
  5495. var index = e.vertex.getIndex(),
  5496. next = e.vertex.getNext(),
  5497. previous = e.vertex.getPrevious(),
  5498. oppositeIndex = (index + 2) % 4,
  5499. opposite = e.vertex.latlngs[oppositeIndex],
  5500. bounds = new L.LatLngBounds(e.latlng, opposite);
  5501. // Update latlngs by hand to preserve order.
  5502. previous.latlng.update([e.latlng.lat, opposite.lng]);
  5503. next.latlng.update([opposite.lat, e.latlng.lng]);
  5504. this.updateBounds(bounds);
  5505. this.refreshVertexMarkers();
  5506. },
  5507. onDrawingMouseDown: function (e) {
  5508. L.Editable.PathEditor.prototype.onDrawingMouseDown.call(this, e);
  5509. this.connect();
  5510. var latlngs = this.getDefaultLatLngs();
  5511. // L.Polygon._convertLatLngs removes last latlng if it equals first point,
  5512. // which is the case here as all latlngs are [0, 0]
  5513. if (latlngs.length === 3) latlngs.push(e.latlng);
  5514. var bounds = new L.LatLngBounds(e.latlng, e.latlng);
  5515. this.updateBounds(bounds);
  5516. this.updateLatLngs(bounds);
  5517. this.refresh();
  5518. this.reset();
  5519. // Stop dragging map.
  5520. // L.Draggable has two workflows:
  5521. // - mousedown => mousemove => mouseup
  5522. // - touchstart => touchmove => touchend
  5523. // Problem: L.Map.Tap does not allow us to listen to touchstart, so we only
  5524. // can deal with mousedown, but then when in a touch device, we are dealing with
  5525. // simulated events (actually simulated by L.Map.Tap), which are no more taken
  5526. // into account by L.Draggable.
  5527. // Ref.: https://github.com/Leaflet/Leaflet.Editable/issues/103
  5528. e.originalEvent._simulated = false;
  5529. this.map.dragging._draggable._onUp(e.originalEvent);
  5530. // Now transfer ongoing drag action to the bottom right corner.
  5531. // Should we refine which corne will handle the drag according to
  5532. // drag direction?
  5533. latlngs[3].__vertex.dragging._draggable._onDown(e.originalEvent);
  5534. },
  5535. onDrawingMouseUp: function (e) {
  5536. this.commitDrawing(e);
  5537. e.originalEvent._simulated = false;
  5538. L.Editable.PathEditor.prototype.onDrawingMouseUp.call(this, e);
  5539. },
  5540. onDrawingMouseMove: function (e) {
  5541. e.originalEvent._simulated = false;
  5542. L.Editable.PathEditor.prototype.onDrawingMouseMove.call(this, e);
  5543. },
  5544. getDefaultLatLngs: function (latlngs) {
  5545. return latlngs || this.feature._latlngs[0];
  5546. },
  5547. updateBounds: function (bounds) {
  5548. this.feature._bounds = bounds;
  5549. },
  5550. updateLatLngs: function (bounds) {
  5551. var latlngs = this.getDefaultLatLngs(),
  5552. newLatlngs = this.feature._boundsToLatLngs(bounds);
  5553. // Keep references.
  5554. for (var i = 0; i < latlngs.length; i++) {
  5555. latlngs[i].update(newLatlngs[i]);
  5556. };
  5557. }
  5558. });
  5559. // 🍂namespace Editable; 🍂class CircleEditor; 🍂aka L.Editable.CircleEditor
  5560. // 🍂inherits PathEditor
  5561. L.Editable.CircleEditor = L.Editable.PathEditor.extend({
  5562. MIN_VERTEX: 2,
  5563. options: {
  5564. skipMiddleMarkers: true
  5565. },
  5566. initialize: function (map, feature, options) {
  5567. L.Editable.PathEditor.prototype.initialize.call(this, map, feature, options);
  5568. this._resizeLatLng = this.computeResizeLatLng();
  5569. },
  5570. computeResizeLatLng: function () {
  5571. // While circle is not added to the map, _radius is not set.
  5572. var delta = (this.feature._radius || this.feature._mRadius) * Math.cos(Math.PI / 4),
  5573. point = this.map.project(this.feature._latlng);
  5574. return this.map.unproject([point.x + delta, point.y - delta]);
  5575. },
  5576. updateResizeLatLng: function () {
  5577. this._resizeLatLng.update(this.computeResizeLatLng());
  5578. this._resizeLatLng.__vertex.update();
  5579. },
  5580. getLatLngs: function () {
  5581. return [this.feature._latlng, this._resizeLatLng];
  5582. },
  5583. getDefaultLatLngs: function () {
  5584. return this.getLatLngs();
  5585. },
  5586. onVertexMarkerDrag: function (e) {
  5587. if (e.vertex.getIndex() === 1) this.resize(e);
  5588. else this.updateResizeLatLng(e);
  5589. L.Editable.PathEditor.prototype.onVertexMarkerDrag.call(this, e);
  5590. },
  5591. resize: function (e) {
  5592. var radius = this.feature._latlng.distanceTo(e.latlng)
  5593. this.feature.setRadius(radius);
  5594. },
  5595. onDrawingMouseDown: function (e) {
  5596. L.Editable.PathEditor.prototype.onDrawingMouseDown.call(this, e);
  5597. this._resizeLatLng.update(e.latlng);
  5598. this.feature._latlng.update(e.latlng);
  5599. this.connect();
  5600. // Stop dragging map.
  5601. e.originalEvent._simulated = false;
  5602. this.map.dragging._draggable._onUp(e.originalEvent);
  5603. // Now transfer ongoing drag action to the radius handler.
  5604. this._resizeLatLng.__vertex.dragging._draggable._onDown(e.originalEvent);
  5605. },
  5606. onDrawingMouseUp: function (e) {
  5607. this.commitDrawing(e);
  5608. e.originalEvent._simulated = false;
  5609. L.Editable.PathEditor.prototype.onDrawingMouseUp.call(this, e);
  5610. },
  5611. onDrawingMouseMove: function (e) {
  5612. e.originalEvent._simulated = false;
  5613. L.Editable.PathEditor.prototype.onDrawingMouseMove.call(this, e);
  5614. },
  5615. onDrag: function (e) {
  5616. L.Editable.PathEditor.prototype.onDrag.call(this, e);
  5617. this.feature.dragging.updateLatLng(this._resizeLatLng);
  5618. }
  5619. });
  5620. // 🍂namespace Editable; 🍂class EditableMixin
  5621. // `EditableMixin` is included to `L.Polyline`, `L.Polygon`, `L.Rectangle`, `L.Circle`
  5622. // and `L.Marker`. It adds some methods to them.
  5623. // *When editing is enabled, the editor is accessible on the instance with the
  5624. // `editor` property.*
  5625. var EditableMixin = {
  5626. createEditor: function (map) {
  5627. map = map || this._map;
  5628. var tools = (this.options.editOptions || {}).editTools || map.editTools;
  5629. if (!tools) throw Error('Unable to detect Editable instance.')
  5630. var Klass = this.options.editorClass || this.getEditorClass(tools);
  5631. return new Klass(map, this, this.options.editOptions);
  5632. },
  5633. // 🍂method enableEdit(map?: L.Map): this.editor
  5634. // Enable editing, by creating an editor if not existing, and then calling `enable` on it.
  5635. enableEdit: function (map) {
  5636. if (!this.editor) this.createEditor(map);
  5637. this.editor.enable();
  5638. return this.editor;
  5639. },
  5640. // 🍂method editEnabled(): boolean
  5641. // Return true if current instance has an editor attached, and this editor is enabled.
  5642. editEnabled: function () {
  5643. return this.editor && this.editor.enabled();
  5644. },
  5645. // 🍂method disableEdit()
  5646. // Disable editing, also remove the editor property reference.
  5647. disableEdit: function () {
  5648. if (this.editor) {
  5649. this.editor.disable();
  5650. delete this.editor;
  5651. }
  5652. },
  5653. // 🍂method toggleEdit()
  5654. // Enable or disable editing, according to current status.
  5655. toggleEdit: function () {
  5656. if (this.editEnabled()) this.disableEdit();
  5657. else this.enableEdit();
  5658. },
  5659. _onEditableAdd: function () {
  5660. if (this.editor) this.enableEdit();
  5661. }
  5662. };
  5663. var PolylineMixin = {
  5664. getEditorClass: function (tools) {
  5665. return (tools && tools.options.polylineEditorClass) ? tools.options.polylineEditorClass : L.Editable.PolylineEditor;
  5666. },
  5667. shapeAt: function (latlng, latlngs) {
  5668. // We can have those cases:
  5669. // - latlngs are just a flat array of latlngs, use this
  5670. // - latlngs is an array of arrays of latlngs, loop over
  5671. var shape = null;
  5672. latlngs = latlngs || this._latlngs;
  5673. if (!latlngs.length) return shape;
  5674. else if (L.Polyline._flat(latlngs) && this.isInLatLngs(latlng, latlngs)) shape = latlngs;
  5675. else for (var i = 0; i < latlngs.length; i++) if (this.isInLatLngs(latlng, latlngs[i])) return latlngs[i];
  5676. return shape;
  5677. },
  5678. isInLatLngs: function (l, latlngs) {
  5679. if (!latlngs) return false;
  5680. var i, k, len, part = [], p,
  5681. w = this._clickTolerance();
  5682. this._projectLatlngs(latlngs, part, this._pxBounds);
  5683. part = part[0];
  5684. p = this._map.latLngToLayerPoint(l);
  5685. if (!this._pxBounds.contains(p)) { return false; }
  5686. for (i = 1, len = part.length, k = 0; i < len; k = i++) {
  5687. if (L.LineUtil.pointToSegmentDistance(p, part[k], part[i]) <= w) {
  5688. return true;
  5689. }
  5690. }
  5691. return false;
  5692. }
  5693. };
  5694. var PolygonMixin = {
  5695. getEditorClass: function (tools) {
  5696. return (tools && tools.options.polygonEditorClass) ? tools.options.polygonEditorClass : L.Editable.PolygonEditor;
  5697. },
  5698. shapeAt: function (latlng, latlngs) {
  5699. // We can have those cases:
  5700. // - latlngs are just a flat array of latlngs, use this
  5701. // - latlngs is an array of arrays of latlngs, this is a simple polygon (maybe with holes), use the first
  5702. // - latlngs is an array of arrays of arrays, this is a multi, loop over
  5703. var shape = null;
  5704. latlngs = latlngs || this._latlngs;
  5705. if (!latlngs.length) return shape;
  5706. else if (L.Polyline._flat(latlngs) && this.isInLatLngs(latlng, latlngs)) shape = latlngs;
  5707. else if (L.Polyline._flat(latlngs[0]) && this.isInLatLngs(latlng, latlngs[0])) shape = latlngs;
  5708. else for (var i = 0; i < latlngs.length; i++) if (this.isInLatLngs(latlng, latlngs[i][0])) return latlngs[i];
  5709. return shape;
  5710. },
  5711. isInLatLngs: function (l, latlngs) {
  5712. var inside = false, l1, l2, j, k, len2;
  5713. for (j = 0, len2 = latlngs.length, k = len2 - 1; j < len2; k = j++) {
  5714. l1 = latlngs[j];
  5715. l2 = latlngs[k];
  5716. if (((l1.lat > l.lat) !== (l2.lat > l.lat)) &&
  5717. (l.lng < (l2.lng - l1.lng) * (l.lat - l1.lat) / (l2.lat - l1.lat) + l1.lng)) {
  5718. inside = !inside;
  5719. }
  5720. }
  5721. return inside;
  5722. },
  5723. parentShape: function (shape, latlngs) {
  5724. latlngs = latlngs || this._latlngs;
  5725. if (!latlngs) return;
  5726. var idx = L.Util.indexOf(latlngs, shape);
  5727. if (idx !== -1) return latlngs;
  5728. for (var i = 0; i < latlngs.length; i++) {
  5729. idx = L.Util.indexOf(latlngs[i], shape);
  5730. if (idx !== -1) return latlngs[i];
  5731. }
  5732. }
  5733. };
  5734. var MarkerMixin = {
  5735. getEditorClass: function (tools) {
  5736. return (tools && tools.options.markerEditorClass) ? tools.options.markerEditorClass : L.Editable.MarkerEditor;
  5737. }
  5738. };
  5739. var RectangleMixin = {
  5740. getEditorClass: function (tools) {
  5741. return (tools && tools.options.rectangleEditorClass) ? tools.options.rectangleEditorClass : L.Editable.RectangleEditor;
  5742. }
  5743. };
  5744. var CircleMixin = {
  5745. getEditorClass: function (tools) {
  5746. return (tools && tools.options.circleEditorClass) ? tools.options.circleEditorClass : L.Editable.CircleEditor;
  5747. }
  5748. };
  5749. var keepEditable = function () {
  5750. // Make sure you can remove/readd an editable layer.
  5751. this.on('add', this._onEditableAdd);
  5752. };
  5753. if (L.Polyline) {
  5754. L.Polyline.include(EditableMixin);
  5755. L.Polyline.include(PolylineMixin);
  5756. L.Polyline.addInitHook(keepEditable);
  5757. }
  5758. if (L.Polygon) {
  5759. L.Polygon.include(EditableMixin);
  5760. L.Polygon.include(PolygonMixin);
  5761. }
  5762. if (L.Marker) {
  5763. L.Marker.include(EditableMixin);
  5764. L.Marker.include(MarkerMixin);
  5765. L.Marker.addInitHook(keepEditable);
  5766. }
  5767. if (L.Rectangle) {
  5768. L.Rectangle.include(EditableMixin);
  5769. L.Rectangle.include(RectangleMixin);
  5770. }
  5771. if (L.Circle) {
  5772. L.Circle.include(EditableMixin);
  5773. L.Circle.include(CircleMixin);
  5774. }
  5775. L.LatLng.prototype.update = function (latlng) {
  5776. latlng = L.latLng(latlng);
  5777. this.lat = latlng.lat;
  5778. this.lng = latlng.lng;
  5779. }
  5780. }, window));
  5781. /*
  5782. Leaflet.contextmenu, a context menu for Leaflet.
  5783. (c) 2015, Adam Ratcliffe, GeoSmart Maps Limited
  5784. @preserve
  5785. */
  5786. (function(factory) {
  5787. // Packaging/modules magic dance
  5788. var L;
  5789. if (typeof define === 'function' && define.amd) {
  5790. // AMD
  5791. define(['leaflet'], factory);
  5792. } else if (typeof module !== 'undefined') {
  5793. // Node/CommonJS
  5794. L = require('leaflet');
  5795. module.exports = factory(L);
  5796. } else {
  5797. // Browser globals
  5798. if (typeof window.L === 'undefined') {
  5799. throw new Error('Leaflet must be loaded first');
  5800. }
  5801. factory(window.L);
  5802. }
  5803. })(function(L) {
  5804. L.Map.mergeOptions({
  5805. contextmenuItems: []
  5806. });
  5807. L.Map.ContextMenu = L.Handler.extend({
  5808. _touchstart: L.Browser.msPointer ? 'MSPointerDown' : L.Browser.pointer ? 'pointerdown' : 'touchstart',
  5809. statics: {
  5810. BASE_CLS: 'leaflet-contextmenu'
  5811. },
  5812. runCallFunc:[],
  5813. initialize: function (map) {
  5814. L.Handler.prototype.initialize.call(this, map);
  5815. this._items = [];
  5816. this._visible = false;
  5817. var container = this._container = L.DomUtil.create('div', L.Map.ContextMenu.BASE_CLS, map._container);
  5818. container.style.zIndex = 10000;
  5819. container.style.position = 'absolute';
  5820. if (map.options.contextmenuWidth) {
  5821. container.style.width = map.options.contextmenuWidth + 'px';
  5822. }
  5823. this._createItems();
  5824. L.DomEvent
  5825. .on(container, 'click', L.DomEvent.stop)
  5826. .on(container, 'mousedown', L.DomEvent.stop)
  5827. .on(container, 'dblclick', L.DomEvent.stop)
  5828. .on(container, 'contextmenu', L.DomEvent.stop);
  5829. },
  5830. addHooks: function () {
  5831. var container = this._map.getContainer();
  5832. L.DomEvent
  5833. .on(container, 'mouseleave', this._hide, this)
  5834. .on(document, 'keydown', this._onKeyDown, this);
  5835. if (L.Browser.touch) {
  5836. L.DomEvent.on(document, this._touchstart, this._hide, this);
  5837. }
  5838. this._map.on({
  5839. contextmenu: this._show,
  5840. mousedown: this._hide,
  5841. movestart: this._hide,
  5842. zoomstart: this._hide
  5843. }, this);
  5844. },
  5845. removeHooks: function () {
  5846. var container = this._map.getContainer();
  5847. L.DomEvent
  5848. .off(container, 'mouseleave', this._hide, this)
  5849. .off(document, 'keydown', this._onKeyDown, this);
  5850. if (L.Browser.touch) {
  5851. L.DomEvent.off(document, this._touchstart, this._hide, this);
  5852. }
  5853. this._map.off({
  5854. contextmenu: this._show,
  5855. mousedown: this._hide,
  5856. movestart: this._hide,
  5857. zoomstart: this._hide
  5858. }, this);
  5859. },
  5860. showAt: function (point, data) {
  5861. if (point instanceof L.LatLng) {
  5862. point = this._map.latLngToContainerPoint(point);
  5863. }
  5864. this._showAtPoint(point, data);
  5865. },
  5866. hide: function () {
  5867. this._hide();
  5868. },
  5869. addItem: function (options) {
  5870. return this.insertItem(options);
  5871. },
  5872. insertItem: function (options, index) {
  5873. index = index !== undefined ? index: this._items.length;
  5874. var item = this._createItem(this._container, options, index);
  5875. this._items.push(item);
  5876. this._sizeChanged = true;
  5877. this._map.fire('contextmenu.additem', {
  5878. contextmenu: this,
  5879. el: item.el,
  5880. index: index
  5881. });
  5882. return item.el;
  5883. },
  5884. removeItem: function (item) {
  5885. var container = this._container;
  5886. if (!isNaN(item)) {
  5887. item = container.children[item];
  5888. }
  5889. if (item) {
  5890. this._removeItem(L.Util.stamp(item));
  5891. this._sizeChanged = true;
  5892. this._map.fire('contextmenu.removeitem', {
  5893. contextmenu: this,
  5894. el: item
  5895. });
  5896. }
  5897. },
  5898. removeAllItems: function () {
  5899. var item;
  5900. while (this._container.children.length) {
  5901. item = this._container.children[0];
  5902. this._removeItem(L.Util.stamp(item));
  5903. }
  5904. },
  5905. hideAllItems: function () {
  5906. var item, i, l;
  5907. for (i = 0, l = this._items.length; i < l; i++) {
  5908. item = this._items[i];
  5909. item.el.style.display = 'none';
  5910. }
  5911. },
  5912. showAllItems: function () {
  5913. var item, i, l;
  5914. for (i = 0, l = this._items.length; i < l; i++) {
  5915. item = this._items[i];
  5916. item.el.style.display = '';
  5917. }
  5918. },
  5919. setDisabled: function (item, disabled) {
  5920. var container = this._container,
  5921. itemCls = L.Map.ContextMenu.BASE_CLS + '-item';
  5922. if (!isNaN(item)) {
  5923. item = container.children[item];
  5924. }
  5925. if (item && L.DomUtil.hasClass(item, itemCls)) {
  5926. if (disabled) {
  5927. L.DomUtil.addClass(item, itemCls + '-disabled');
  5928. this._map.fire('contextmenu.disableitem', {
  5929. contextmenu: this,
  5930. el: item
  5931. });
  5932. } else {
  5933. L.DomUtil.removeClass(item, itemCls + '-disabled');
  5934. this._map.fire('contextmenu.enableitem', {
  5935. contextmenu: this,
  5936. el: item
  5937. });
  5938. }
  5939. }
  5940. },
  5941. isVisible: function () {
  5942. return this._visible;
  5943. },
  5944. _createItems: function () {
  5945. var itemOptions = this._map.options.contextmenuItems,
  5946. item,
  5947. i, l;
  5948. for (i = 0, l = itemOptions.length; i < l; i++) {
  5949. this._items.push(this._createItem(this._container, itemOptions[i]));
  5950. }
  5951. },
  5952. _createItem: function (container, options, index) {
  5953. if (options.separator || options === '-') {
  5954. return this._createSeparator(container, index);
  5955. }
  5956. var itemCls = L.Map.ContextMenu.BASE_CLS + '-item',
  5957. cls = options.disabled ? (itemCls + ' ' + itemCls + '-disabled') : itemCls;
  5958. if(options.hasOwnProperty('className')){
  5959. cls = cls + ' ' + options.className;
  5960. }
  5961. var el = this._insertElementAt('a', cls, container, index),
  5962. callback = this._createEventHandler(el, options.callback, options.context, options.hideOnSelect),
  5963. html = '';
  5964. if(options.hasOwnProperty('runCall')){
  5965. this.runCallFunc.push(options.runCall);
  5966. }
  5967. if (options.icon) {
  5968. html = '<img class="' + L.Map.ContextMenu.BASE_CLS + '-icon" src="' + options.icon + '"/>';
  5969. } else if (options.iconCls) {
  5970. html = '<span class="' + L.Map.ContextMenu.BASE_CLS + '-icon ' + options.iconCls + '"></span>';
  5971. }
  5972. if(typeof options.text === 'object'){
  5973. el.innerHTML = html;
  5974. el.appendChild(options.text);
  5975. }else {
  5976. el.innerHTML = html + options.text;
  5977. }
  5978. el.href = '#';
  5979. L.DomEvent
  5980. .on(el, 'mouseover', this._onItemMouseOver, this)
  5981. .on(el, 'mouseout', this._onItemMouseOut, this)
  5982. .on(el, 'mousedown', L.DomEvent.stopPropagation)
  5983. .on(el, 'click', callback);
  5984. if (L.Browser.touch) {
  5985. L.DomEvent.on(el, this._touchstart, L.DomEvent.stopPropagation);
  5986. }
  5987. return {
  5988. id: L.Util.stamp(el),
  5989. el: el,
  5990. callback: callback
  5991. };
  5992. },
  5993. _removeItem: function (id) {
  5994. var item,
  5995. el,
  5996. i, l, callback;
  5997. for (i = 0, l = this._items.length; i < l; i++) {
  5998. item = this._items[i];
  5999. if (item.id === id) {
  6000. el = item.el;
  6001. callback = item.callback;
  6002. if (callback) {
  6003. L.DomEvent
  6004. .off(el, 'mouseover', this._onItemMouseOver, this)
  6005. .off(el, 'mouseover', this._onItemMouseOut, this)
  6006. .off(el, 'mousedown', L.DomEvent.stopPropagation)
  6007. .off(el, 'click', callback);
  6008. if (L.Browser.touch) {
  6009. L.DomEvent.off(el, this._touchstart, L.DomEvent.stopPropagation);
  6010. }
  6011. }
  6012. this._container.removeChild(el);
  6013. this._items.splice(i, 1);
  6014. return item;
  6015. }
  6016. }
  6017. return null;
  6018. },
  6019. _createSeparator: function (container, index) {
  6020. var el = this._insertElementAt('div', L.Map.ContextMenu.BASE_CLS + '-separator', container, index);
  6021. return {
  6022. id: L.Util.stamp(el),
  6023. el: el
  6024. };
  6025. },
  6026. _createEventHandler: function (el, func, context, hideOnSelect) {
  6027. var me = this,
  6028. map = this._map,
  6029. disabledCls = L.Map.ContextMenu.BASE_CLS + '-item-disabled',
  6030. hideOnSelect = (hideOnSelect !== undefined) ? hideOnSelect : true;
  6031. return function (e) {
  6032. if (L.DomUtil.hasClass(el, disabledCls)) {
  6033. return;
  6034. }
  6035. if (hideOnSelect) {
  6036. me._hide();
  6037. }
  6038. if (func) {
  6039. func.call(context || map, me._showLocation);
  6040. }
  6041. me._map.fire('contextmenu:select', {
  6042. contextmenu: me,
  6043. el: el
  6044. });
  6045. };
  6046. },
  6047. _insertElementAt: function (tagName, className, container, index) {
  6048. var refEl,
  6049. el = document.createElement(tagName);
  6050. el.className = className;
  6051. if (index !== undefined) {
  6052. refEl = container.children[index];
  6053. }
  6054. if (refEl) {
  6055. container.insertBefore(el, refEl);
  6056. } else {
  6057. container.appendChild(el);
  6058. }
  6059. return el;
  6060. },
  6061. _show: function (e) {
  6062. var _this = this;
  6063. //this._showAtPoint(e.containerPoint, e);
  6064. for(var i = 0, l=this.runCallFunc.length; i<l; i++){
  6065. this.runCallFunc[i](e);
  6066. }
  6067. _this.tempE = e;
  6068. setTimeout(function(){
  6069. _this._showAtPoint(_this.tempE.containerPoint);
  6070. },100);
  6071. if(_this.circleMarker){
  6072. _this._map.removeLayer(_this.circleMarker);
  6073. }
  6074. _this.circleMarker = L.circleMarker(e.latlng, { fillColor: "#cb0000",fillOpacity:1,weight:1, color:"#fff", radius: 3, opacity:1 }).addTo(this._map);
  6075. },
  6076. _showAtPoint: function (pt, data) {
  6077. if (this._items.length) {
  6078. var map = this._map,
  6079. layerPoint = map.containerPointToLayerPoint(pt),
  6080. latlng = map.layerPointToLatLng(layerPoint),
  6081. event = L.extend(data || {}, {contextmenu: this});
  6082. this._showLocation = {
  6083. latlng: latlng,
  6084. layerPoint: layerPoint,
  6085. containerPoint: pt
  6086. };
  6087. if(data && data.relatedTarget){
  6088. this._showLocation.relatedTarget = data.relatedTarget;
  6089. }
  6090. this._setPosition(pt);
  6091. if (!this._visible) {
  6092. this._container.style.display = 'block';
  6093. this._visible = true;
  6094. } else {
  6095. this._setPosition(pt);
  6096. }
  6097. this._map.fire('contextmenu.show', event);
  6098. }
  6099. },
  6100. _hide: function () {
  6101. if (this._visible) {
  6102. this._visible = false;
  6103. this._container.style.display = 'none';
  6104. this._map.fire('contextmenu.hide', {contextmenu: this});
  6105. this._map.removeLayer(this.circleMarker);
  6106. }
  6107. },
  6108. _setPosition: function (pt) {
  6109. var mapSize = this._map.getSize(),
  6110. container = this._container,
  6111. containerSize = this._getElementSize(container),
  6112. anchor;
  6113. if (this._map.options.contextmenuAnchor) {
  6114. anchor = L.point(this._map.options.contextmenuAnchor);
  6115. pt = pt.add(anchor);
  6116. }
  6117. container._leaflet_pos = pt;
  6118. if (pt.x + containerSize.x > mapSize.x) {
  6119. container.style.left = 'auto';
  6120. container.style.right = Math.max(mapSize.x - pt.x, 0) + 'px';
  6121. } else {
  6122. container.style.left = Math.max(pt.x, 0) + 'px';
  6123. container.style.right = 'auto';
  6124. }
  6125. if (pt.y + containerSize.y > mapSize.y) {
  6126. container.style.top = 'auto';
  6127. container.style.bottom = Math.max(mapSize.y - pt.y, 0) + 'px';
  6128. } else {
  6129. container.style.top = Math.max(pt.y, 0) + 'px';
  6130. container.style.bottom = 'auto';
  6131. }
  6132. },
  6133. _getElementSize: function (el) {
  6134. var size = this._size,
  6135. initialDisplay = el.style.display;
  6136. if (!size || this._sizeChanged) {
  6137. size = {};
  6138. el.style.left = '-999999px';
  6139. el.style.right = 'auto';
  6140. el.style.display = 'block';
  6141. size.x = el.offsetWidth;
  6142. size.y = el.offsetHeight;
  6143. el.style.left = 'auto';
  6144. el.style.display = initialDisplay;
  6145. this._sizeChanged = false;
  6146. }
  6147. return size;
  6148. },
  6149. _onKeyDown: function (e) {
  6150. var key = e.keyCode;
  6151. // If ESC pressed and context menu is visible hide it
  6152. if (key === 27) {
  6153. this._hide();
  6154. }
  6155. },
  6156. _onItemMouseOver: function (e) {
  6157. L.DomUtil.addClass(e.target || e.srcElement, 'over');
  6158. },
  6159. _onItemMouseOut: function (e) {
  6160. L.DomUtil.removeClass(e.target || e.srcElement, 'over');
  6161. }
  6162. });
  6163. L.Map.addInitHook('addHandler', 'contextmenu', L.Map.ContextMenu);
  6164. L.Mixin.ContextMenu = {
  6165. bindContextMenu: function (options) {
  6166. L.setOptions(this, options);
  6167. this._initContextMenu();
  6168. return this;
  6169. },
  6170. unbindContextMenu: function (){
  6171. this.off('contextmenu', this._showContextMenu, this);
  6172. return this;
  6173. },
  6174. addContextMenuItem: function (item) {
  6175. this.options.contextmenuItems.push(item);
  6176. },
  6177. removeContextMenuItemWithIndex: function (index) {
  6178. var items = [];
  6179. for (var i = 0; i < this.options.contextmenuItems.length; i++) {
  6180. if(this.options.contextmenuItems[i].index == index){
  6181. items.push(i);
  6182. }
  6183. }
  6184. var elem = items.pop();
  6185. while (elem !== undefined) {
  6186. this.options.contextmenuItems.splice(elem,1);
  6187. elem = items.pop();
  6188. }
  6189. },
  6190. replaceConextMenuItem: function (item) {
  6191. this.removeContextMenuItemWithIndex(item.index);
  6192. this.addContextMenuItem(item);
  6193. },
  6194. _initContextMenu: function () {
  6195. this._items = [];
  6196. this.on('contextmenu', this._showContextMenu, this);
  6197. },
  6198. _showContextMenu: function (e) {
  6199. var itemOptions,
  6200. data, pt, i, l;
  6201. if (this._map.contextmenu) {
  6202. data = L.extend({relatedTarget: this}, e)
  6203. pt = this._map.mouseEventToContainerPoint(e.originalEvent);
  6204. if (!this.options.contextmenuInheritItems) {
  6205. this._map.contextmenu.hideAllItems();
  6206. }
  6207. for (i = 0, l = this.options.contextmenuItems.length; i < l; i++) {
  6208. itemOptions = this.options.contextmenuItems[i];
  6209. this._items.push(this._map.contextmenu.insertItem(itemOptions, itemOptions.index));
  6210. }
  6211. this._map.once('contextmenu.hide', this._hideContextMenu, this);
  6212. this._map.contextmenu.showAt(pt, data);
  6213. }
  6214. },
  6215. _hideContextMenu: function () {
  6216. var i, l;
  6217. for (i = 0, l = this._items.length; i < l; i++) {
  6218. this._map.contextmenu.removeItem(this._items[i]);
  6219. }
  6220. this._items.length = 0;
  6221. if (!this.options.contextmenuInheritItems) {
  6222. this._map.contextmenu.showAllItems();
  6223. }
  6224. }
  6225. };
  6226. var classes = [L.Marker, L.Path],
  6227. defaultOptions = {
  6228. contextmenu: false,
  6229. contextmenuItems: [],
  6230. contextmenuInheritItems: true
  6231. },
  6232. cls, i, l;
  6233. for (i = 0, l = classes.length; i < l; i++) {
  6234. cls = classes[i];
  6235. // L.Class should probably provide an empty options hash, as it does not test
  6236. // for it here and add if needed
  6237. if (!cls.prototype.options) {
  6238. cls.prototype.options = defaultOptions;
  6239. } else {
  6240. cls.mergeOptions(defaultOptions);
  6241. }
  6242. cls.addInitHook(function () {
  6243. if (this.options.contextmenu) {
  6244. this._initContextMenu();
  6245. }
  6246. });
  6247. cls.include(L.Mixin.ContextMenu);
  6248. }
  6249. return L.Map.ContextMenu;
  6250. });
  6251. /**
  6252. * Semicircle extension for L.Circle.
  6253. * Jan Pieter Waagmeester <jieter@jieter.nl>
  6254. *
  6255. * This version is tested with leaflet 1.0.2
  6256. */
  6257. (function (factory) {
  6258. if (typeof define === 'function' && define.amd) {
  6259. // AMD
  6260. define(['leaflet'], factory);
  6261. } else if (typeof module !== 'undefined') {
  6262. // Node/CommonJS
  6263. module.exports = factory(require('leaflet'));
  6264. } else {
  6265. // Browser globals
  6266. if (typeof window.L === 'undefined') {
  6267. throw 'Leaflet must be loaded first';
  6268. }
  6269. factory(window.L);
  6270. }
  6271. })(function (L) {
  6272. var DEG_TO_RAD = Math.PI / 180;
  6273. // make sure 0 degrees is up (North) and convert to radians.
  6274. function fixAngle (angle) {
  6275. return (angle - 90) * DEG_TO_RAD;
  6276. }
  6277. // rotate point [x + r, y+r] around [x, y] by `angle` radians.
  6278. function rotated (p, angle, r) {
  6279. return p.add(
  6280. L.point(Math.cos(angle), Math.sin(angle)).multiplyBy(r)
  6281. );
  6282. }
  6283. L.Point.prototype.rotated = function (angle, r) {
  6284. return rotated(this, angle, r);
  6285. };
  6286. L.Circle = L.Circle.extend({
  6287. options: {
  6288. startAngle: 0,
  6289. stopAngle: 359.9999999999999999999999
  6290. },
  6291. startAngle: function () {
  6292. if (this.options.startAngle < this.options.stopAngle) {
  6293. return fixAngle(this.options.startAngle);
  6294. } else {
  6295. return fixAngle(this.options.stopAngle);
  6296. }
  6297. },
  6298. stopAngle: function () {
  6299. if (this.options.startAngle < this.options.stopAngle) {
  6300. return fixAngle(this.options.stopAngle);
  6301. } else {
  6302. return fixAngle(this.options.startAngle);
  6303. }
  6304. },
  6305. setStartAngle: function (angle) {
  6306. this.options.startAngle = angle;
  6307. return this.redraw();
  6308. },
  6309. setStopAngle: function (angle) {
  6310. this.options.stopAngle = angle;
  6311. return this.redraw();
  6312. },
  6313. setDirection: function (direction, degrees) {
  6314. if (degrees === undefined) {
  6315. degrees = 10;
  6316. }
  6317. this.options.startAngle = direction - (degrees / 2);
  6318. this.options.stopAngle = direction + (degrees / 2);
  6319. return this.redraw();
  6320. },
  6321. getDirection: function () {
  6322. return this.stopAngle() - (this.stopAngle() - this.startAngle()) / 2;
  6323. },
  6324. isSemicircle: function () {
  6325. var startAngle = this.options.startAngle,
  6326. stopAngle = this.options.stopAngle;
  6327. return (
  6328. !(startAngle === 0 && stopAngle > 359) &&
  6329. !(startAngle == stopAngle)
  6330. );
  6331. },
  6332. _containsPoint: function (p) {
  6333. function normalize (angle) {
  6334. while (angle <= -Math.PI) {
  6335. angle += 2.0 * Math.PI;
  6336. }
  6337. while (angle > Math.PI) {
  6338. angle -= 2.0 * Math.PI;
  6339. }
  6340. return angle;
  6341. }
  6342. var angle = Math.atan2(p.y - this._point.y, p.x - this._point.x);
  6343. var nStart = normalize(this.startAngle());
  6344. var nStop = normalize(this.stopAngle());
  6345. if (nStop <= nStart) {
  6346. nStop += 2.0 * Math.PI;
  6347. }
  6348. if (angle <= nStart) {
  6349. angle += 2.0 * Math.PI;
  6350. }
  6351. return (
  6352. nStart < angle && angle <= nStop &&
  6353. p.distanceTo(this._point) <= this._radius + this._clickTolerance()
  6354. );
  6355. }
  6356. });
  6357. var _updateCircleSVG = L.SVG.prototype._updateCircle;
  6358. var _updateCircleCanvas = L.Canvas.prototype._updateCircle;
  6359. L.SVG.include({
  6360. _updateCircle: function (layer) {
  6361. // If we want a circle, we use the original function
  6362. if (!layer.isSemicircle()) {
  6363. return _updateCircleSVG.call(this, layer);
  6364. }
  6365. if (layer._empty()) {
  6366. return this._setPath(layer, 'M0 0');
  6367. }
  6368. var p = layer._point,
  6369. r = layer._radius,
  6370. r2 = Math.round(layer._radiusY || r),
  6371. start = p.rotated(layer.startAngle(), r),
  6372. end = p.rotated(layer.stopAngle(), r);
  6373. var largeArc = (layer.options.stopAngle - layer.options.startAngle >= 180) ? '1' : '0';
  6374. var d = 'M' + p.x + ',' + p.y +
  6375. // line to first start point
  6376. 'L' + start.x + ',' + start.y +
  6377. 'A ' + r + ',' + r2 + ',0,' + largeArc + ',1,' + end.x + ',' + end.y +
  6378. ' z';
  6379. this._setPath(layer, d);
  6380. }
  6381. });
  6382. L.Canvas.include({
  6383. _updateCircle: function (layer) {
  6384. // If we want a circle, we use the original function
  6385. if (!layer.isSemicircle()) {
  6386. return _updateCircleCanvas.call(this, layer);
  6387. }
  6388. var p = layer._point,
  6389. ctx = this._ctx,
  6390. r = layer._radius,
  6391. s = (layer._radiusY || r) / r,
  6392. start = p.rotated(layer.startAngle(), r);
  6393. this._drawnLayers[layer._leaflet_id] = layer;
  6394. if (s !== 1) {
  6395. ctx.save();
  6396. ctx.scale(1, s);
  6397. }
  6398. ctx.beginPath();
  6399. ctx.moveTo(p.x, p.y);
  6400. ctx.lineTo(start.x, start.y);
  6401. ctx.arc(p.x, p.y, r, layer.startAngle(), layer.stopAngle());
  6402. ctx.lineTo(p.x, p.y);
  6403. if (s !== 1) {
  6404. ctx.restore();
  6405. }
  6406. this._fillStroke(ctx, layer);
  6407. }
  6408. });
  6409. // L.CircleMarker inherits from L.Circle before the Semicircle stuff is
  6410. // added. The renderers test if the layer is a semicircle with a function
  6411. // isSemicircle, so add that to L.CircleMarker to make sure we can still
  6412. // make L.CircleMarkers.
  6413. L.CircleMarker = L.CircleMarker.extend({
  6414. isSemicircle: function () { return false; }
  6415. });
  6416. });
  6417. ;
  6418. (function(window, document, undefined) {
  6419. //获取三维视图任一点象素位置的经纬度坐标
  6420. function get3DPixToLnglat(option) {
  6421. var point = locaSpaceMap.CreatePoint2D();
  6422. if (option == 'topleft') {
  6423. var S2dx = 0; //3D视图容器宽度的二分之一
  6424. var S2dy = 0; //3D视图容器高度的二分之一
  6425. } else if (option == 'bottomright') {
  6426. var S2dx = $('#map3DWrap').width(); //3D视图容器宽度的二分之一
  6427. var S2dy = $('#map3DWrap').height(); //3D视图容器高度的二分之一
  6428. } else if (option == 'center') {
  6429. var S2dx = $('#map3DWrap').width() / 2; //3D视图容器宽度的二分之一
  6430. var S2dy = $('#map3DWrap').height() / 2; //3D视图容器高度的二分之一
  6431. }
  6432. point.x = parseInt(S2dx);
  6433. point.y = parseInt(S2dy);
  6434. var result = locaSpaceMap.Globe.ScreenToScene(point);
  6435. return {
  6436. lng: result.x,
  6437. lat: result.y
  6438. };
  6439. }
  6440. /**
  6441. * 聚集区显示
  6442. * 根据两个点或三个点计算出聚集区坐标
  6443. */
  6444. function getGeoGatheringPlace(start, middle, stop) {
  6445. var originP = new SuperMap.Geometry.Point(start[0], start[1]);
  6446. var lastP = new SuperMap.Geometry.Point(stop[0], stop[1]);
  6447. var gather = new SuperMap.Geometry.GeoGatheringPlace;
  6448. var points = [];
  6449. // 向量originP_lastP
  6450. var vectorOL = new SuperMap.Geometry.Point(lastP.x - originP.x, lastP.y - originP.y);
  6451. // 向量originP_lastP的模
  6452. var dOL = Math.sqrt(vectorOL.x * vectorOL.x + vectorOL.y * vectorOL.y);
  6453. //计算第一个插值控制点
  6454. //向量originP_P1以originP为起点,与向量originP_lastP的夹角设为30,模为√3/12*dOL,
  6455. var v_O_P1_lr = gather.calculateVector(vectorOL, Math.PI / 3, Math.sqrt(3) / 12 * dOL);
  6456. //取左边的向量作为向量originP_P1
  6457. var originP_P1 = v_O_P1_lr[0];
  6458. var p1 = new SuperMap.Geometry.Point(originP_P1.x + originP.x, originP_P1.y + originP.y);
  6459. //计算第二个插值控制点,取第一控制点和第二控制点的中点为第二个插值控制点
  6460. var p2 = new SuperMap.Geometry.Point((originP.x + lastP.x) / 2, (originP.y + lastP.y) / 2);
  6461. //计算第三个插值控制点
  6462. //向量originP_P3以lastP为起点,与向量originP_lastP的夹角设为150°,模为√3/12*dOL,
  6463. var v_L_P3_lr = gather.calculateVector(vectorOL, Math.PI * 2 / 3, Math.sqrt(3) / 12 * dOL);
  6464. //取左边的向量作为向量originP_P1
  6465. var lastP_P3 = v_L_P3_lr[0];
  6466. var p3 = new SuperMap.Geometry.Point(lastP_P3.x + lastP.x, lastP_P3.y + lastP.y);
  6467. //计算第四个插值控制点
  6468. if (middle) {
  6469. var p5 = new SuperMap.Geometry.Point(middle[0], middle[1]);
  6470. } else {
  6471. //向量originP_P4以向量originP_lastP中点为起点,与向量originP_lastP的夹角设为90°,模为1/2*dOL,
  6472. var v_O_P5_lr = gather.calculateVector(vectorOL, Math.PI / 2, 1 / 2 * dOL);
  6473. //取左边的向量作为向量originP_P1
  6474. var v_O_P5 = v_O_P5_lr[1];
  6475. var p5 = new SuperMap.Geometry.Point(v_O_P5.x + p2.x, v_O_P5.y + p2.y);
  6476. }
  6477. var P0 = originP.clone();
  6478. var P4 = lastP.clone();
  6479. points.push(P0, p1, p2, p3, P4, p5);
  6480. var cardinalPoints = SuperMap.Geometry.LineString.createCloseCardinal(points);
  6481. var gatherGeo = SuperMap.Geometry.LineString.createBezier3(cardinalPoints, 100);
  6482. gatherGeo = gatherGeo.components;
  6483. var newGatherGeo = [];
  6484. for (var i = 0; i < gatherGeo.length; i++) {
  6485. newGatherGeo.push([gatherGeo[i].x, gatherGeo[i].y])
  6486. }
  6487. return newGatherGeo;
  6488. }
  6489. /**
  6490. * 添加卫星单元
  6491. * 根据卫星六根数和时间得出卫星所在时间的经纬高、速度、方向
  6492. */
  6493. function getCurSatelliteData(options) {
  6494. var coordinesAll = [];
  6495. var heightAll = [];
  6496. if (options.type === 'sixNum') {
  6497. //卫星长半轴转平均转数
  6498. var mu = 3.986004419 * Math.pow(10, 14),
  6499. pe = 86400,
  6500. rad; //转数
  6501. rad = pe / (2 * Math.PI * Math.sqrt((Math.pow(options.a, 3) / mu)));
  6502. var inclination = options.inclination; //轨道倾角
  6503. var rightAscension = options.rightAscension; //升交点赤经
  6504. var eccentricity = options.eccentricity; //偏心率
  6505. //eccentricity = eccentricity.toString();
  6506. //eccentricity = JSON.parse(eccentricity.split('.')[1]);
  6507. var argumentPerigee = options.argumentPerigee; //近地点中心角
  6508. var meanAnomaly = options.meanAnomaly; //平近点角
  6509. //由卫星六根数得出卫星位置及速度
  6510. var tleLine1 = '1 25544U 98067A 13149.87225694 .00009369 00000-0 16828-3 0 9031',
  6511. tleLine2 = '2 25544 ' + inclination + ' ' + rightAscension + ' ' + eccentricity + ' ' + argumentPerigee + ' ' + meanAnomaly + ' ' + rad;
  6512. } else {
  6513. var tleLine1 = options.tleLine1,
  6514. tleLine2 = options.tleLine2;
  6515. var rad = options.rad;
  6516. }
  6517. //卫星初始化
  6518. var satrec = satellite.twoline2satrec(tleLine1, tleLine2);
  6519. //ECI(J2000)坐标和速度 单位KM或KM/S
  6520. var curTime = options.time;
  6521. for (var i = 0; i < 2; i++) {
  6522. if (i != 0) {
  6523. curTime.setMinutes(curTime.getMinutes() + 1);
  6524. }
  6525. var positionAndVelocity = satellite.propagate(satrec, curTime);
  6526. var positionEci = positionAndVelocity.position,
  6527. velocityEci = positionAndVelocity.velocity;
  6528. if (!positionEci || !velocityEci || !velocityEci.x || !positionEci.x) {
  6529. return false;
  6530. }
  6531. //添加一个观察者点
  6532. var observerGd = {
  6533. longitude: (130 * Math.PI) / 180,
  6534. latitude: (15 * Math.PI) / 180,
  6535. height: 0.1
  6536. };
  6537. //将ECI转ECF
  6538. var gmst = satellite.gstimeFromDate(new Date());
  6539. var positionEcf = satellite.eciToEcf(positionEci, gmst),
  6540. observerEcf = satellite.geodeticToEcf(observerGd),
  6541. positionGd = satellite.eciToGeodetic(positionEci, gmst),
  6542. lookAngles = satellite.ecfToLookAngles(observerGd, positionEcf);
  6543. //ECF,大地测量,角度,和多普勒因子
  6544. var satelliteX = positionEci.x,
  6545. satelliteY = positionEci.y,
  6546. satelliteZ = positionEci.z;
  6547. var azimuth = lookAngles.azimuth,
  6548. elevation = lookAngles.elevation,
  6549. rangeSat = lookAngles.rangeSat;
  6550. //获取经纬高
  6551. var longitude = positionGd.longitude,
  6552. latitude = positionGd.latitude,
  6553. height = positionGd.height * 1000;
  6554. //经纬高标准化
  6555. var longitudeStr = satellite.degreesLong(longitude),
  6556. latitudeStr = satellite.degreesLat(latitude);
  6557. coordinesAll.push([longitudeStr, latitudeStr]);
  6558. heightAll.push(height)
  6559. }
  6560. //计算卫星角度
  6561. var angle = L.Util.getAngleByLatLng(coordinesAll[0][0], coordinesAll[0][1], coordinesAll[1][0], coordinesAll[1][1]);
  6562. return {
  6563. height: heightAll[0],
  6564. coordinates: coordinesAll[0],
  6565. angle: angle
  6566. }
  6567. }
  6568. /**
  6569. * 卫星轨道参数
  6570. */
  6571. function satelliteData(options) {
  6572. var coordinesAll = [];
  6573. var heightAll = [];
  6574. if (options.type === 'sixNum') {
  6575. //卫星长半轴转平均转数
  6576. var mu = 3.986004419 * Math.pow(10, 14),
  6577. pe = 86400,
  6578. rad; //转数
  6579. rad = pe / (2 * Math.PI * Math.sqrt((Math.pow(options.a, 3) / mu)));
  6580. var inclination = options.inclination; //轨道倾角
  6581. var rightAscension = options.rightAscension; //升交点赤经
  6582. var eccentricity = options.eccentricity; //偏心率
  6583. //eccentricity = eccentricity.toString();
  6584. //eccentricity = JSON.parse(eccentricity.split('.')[1]);
  6585. var argumentPerigee = options.argumentPerigee; //近地点中心角
  6586. var meanAnomaly = options.meanAnomaly; //平近点角
  6587. //由卫星六根数得出卫星位置及速度
  6588. var tleLine1 = '1 25544U 98067A 13149.87225694 .00009369 00000-0 16828-3 0 9031',
  6589. tleLine2 = '2 25544 ' + inclination + ' ' + rightAscension + ' ' + eccentricity + ' ' + argumentPerigee + ' ' + meanAnomaly + ' ' + rad;
  6590. } else {
  6591. var tleLine1 = options.tleLine1,
  6592. tleLine2 = options.tleLine2;
  6593. var rad = options.rad;
  6594. }
  6595. //卫星初始化
  6596. var satrec = satellite.twoline2satrec(tleLine1, tleLine2);
  6597. //ECI(J2000)坐标和速度 单位KM或KM/S
  6598. var curTime = options.time;
  6599. //轨道点的个数
  6600. if (rad >= 1 && rad < 8) {
  6601. var length = 24 / rad * 6 + 1;
  6602. } else if (rad < 1) {
  6603. var length = 24 / rad * 60 + 1;
  6604. } else {
  6605. var length = 24 / rad * 2 + 1;
  6606. }
  6607. for (var i = 0; i < length; i++) {
  6608. if(i!=0){
  6609. if (rad >= 1 && rad < 8) {
  6610. curTime.setMinutes(curTime.getMinutes() + 10);
  6611. } else if (rad < 1) {
  6612. curTime.setMinutes(curTime.getMinutes() + 1);
  6613. } else {
  6614. curTime.setMinutes(curTime.getMinutes() + 30);
  6615. }
  6616. }
  6617. var positionAndVelocity = satellite.propagate(satrec, curTime);
  6618. var positionEci = positionAndVelocity.position,
  6619. velocityEci = positionAndVelocity.velocity;
  6620. if (!positionEci || !velocityEci || !velocityEci.x || !positionEci.x) {
  6621. return false;
  6622. }
  6623. //添加一个观察者点
  6624. var observerGd = {
  6625. longitude: (130 * Math.PI) / 180,
  6626. latitude: (15 * Math.PI) / 180,
  6627. height: 0.1
  6628. };
  6629. //将ECI转ECF
  6630. var gmst = satellite.gstimeFromDate(new Date());
  6631. var positionEcf = satellite.eciToEcf(positionEci, gmst),
  6632. observerEcf = satellite.geodeticToEcf(observerGd),
  6633. positionGd = satellite.eciToGeodetic(positionEci, gmst),
  6634. lookAngles = satellite.ecfToLookAngles(observerGd, positionEcf);
  6635. //ECF,大地测量,角度,和多普勒因子
  6636. var satelliteX = positionEci.x,
  6637. satelliteY = positionEci.y,
  6638. satelliteZ = positionEci.z;
  6639. var azimuth = lookAngles.azimuth,
  6640. elevation = lookAngles.elevation,
  6641. rangeSat = lookAngles.rangeSat;
  6642. //获取经纬高
  6643. var longitude = positionGd.longitude,
  6644. latitude = positionGd.latitude,
  6645. height = positionGd.height * 1000;
  6646. //经纬高标准化
  6647. var longitudeStr = satellite.degreesLong(longitude),
  6648. latitudeStr = satellite.degreesLat(latitude);
  6649. coordinesAll.push([longitudeStr, latitudeStr]);
  6650. heightAll.push(height)
  6651. }
  6652. return {
  6653. height: heightAll,
  6654. coordinates: coordinesAll
  6655. }
  6656. };
  6657. /**
  6658. * 转换3世界坐标 用于在leaflet中实现跨逆子午线,线走最近距离 坐标不能超过一圈
  6659. * 遍历坐标数组,取经度,
  6660. * 如果(N+1).lng-N.lng 绝对值超过180表示需要进行换算,取最近路线:负数为逆时针,正数为顺时针
  6661. *
  6662. * @param {[type]} lnglats [description]
  6663. * @return {[type]} [description]
  6664. */
  6665. function lnglatsToDateLineLnglats(lnglats, circleLng) {
  6666. for (var i = 1; i < lnglats.length; i++) {
  6667. var dY = lnglats[i][0] - lnglats[i - 1][0];
  6668. if (dY > 180) {
  6669. if (dY > 540) {
  6670. lnglats[i][0] -= 720;
  6671. } else {
  6672. lnglats[i][0] -= 360;
  6673. }
  6674. }
  6675. if (dY < -180) {
  6676. if (dY < -540) {
  6677. lnglats[i][0] += 720;
  6678. } else {
  6679. lnglats[i][0] += 360;
  6680. }
  6681. }
  6682. }
  6683. //如果第一个点和圆心的差值小于-180 则圆平移360度
  6684. if (circleLng) {
  6685. if ((lnglats[0][0] - circleLng) < -180) {
  6686. for (var i = 0; i < lnglats.length; i++) {
  6687. lnglats[i][0] += 360
  6688. }
  6689. }
  6690. }
  6691. return lnglats;
  6692. }
  6693. /**
  6694. * 3世界坐标 转换 -180 180 纬度坐标
  6695. * @param {[type]} lnglats [description]
  6696. * @return {[type]} [description]
  6697. */
  6698. function dateLineLnglatsToLnglats(lnglats) {
  6699. for (var i = 1; i < lnglats.length; i++) {
  6700. var dY = lnglats[i][0] + lnglats[i - 1][0];
  6701. if (dY > 180) {
  6702. lnglats[i][0] -= 360;
  6703. }
  6704. if (dY < -180) {
  6705. lnglats[i][0] += 360;
  6706. }
  6707. }
  6708. return lnglats;
  6709. }
  6710. /**
  6711. *
  6712. * 2D坐标转3D视角中心点
  6713. */
  6714. function latlngsTo3DViewCenter(mapState) {
  6715. var RoraTilt = ((map23DData.view.tilt) / 180) * Math.PI;
  6716. var gausscenter = coordn_to_gauss([mapState.center.lng, mapState.center.lat], mapState.zoom);
  6717. var h = map23DData.view.distance;
  6718. var heading3D = -map23DData.view.heading;
  6719. if (heading3D > 180) {
  6720. heading3D = heading3D % 180 - 180;
  6721. } else if (heading3D < -180) {
  6722. heading3D = 180 + heading3D % 180;
  6723. }
  6724. if (-90 < heading3D && heading3D <= 0) {
  6725. var RoraHead = Math.abs(map23DData.view.heading / 180 * Math.PI);
  6726. gausscenter[1] = gausscenter[1] - h * Math.sin(RoraTilt) * Math.cos(RoraHead);
  6727. gausscenter[0] = gausscenter[0] + h * Math.sin(RoraTilt) * Math.sin(RoraHead);
  6728. var mapsetlatlng = gaussToGeo(gausscenter[0], gausscenter[1], mapState.center.lng, mapState.zoom);
  6729. } else if (-180 <= heading3D && heading3D <= -90) {
  6730. var RoraHead = Math.abs((map23DData.view.heading + 180) / 180 * Math.PI);
  6731. gausscenter[1] = gausscenter[1] + h * Math.sin(RoraTilt) * Math.cos(RoraHead);
  6732. gausscenter[0] = gausscenter[0] - h * Math.sin(RoraTilt) * Math.sin(RoraHead);
  6733. var mapsetlatlng = gaussToGeo(gausscenter[0], gausscenter[1], mapState.center.lng, mapState.zoom);
  6734. } else if (0 < heading3D && heading3D <= 90) {
  6735. var RoraHead = Math.abs(map23DData.view.heading / 180 * Math.PI);
  6736. gausscenter[1] = gausscenter[1] - h * Math.sin(RoraTilt) * Math.cos(RoraHead);
  6737. gausscenter[0] = gausscenter[0] - h * Math.sin(RoraTilt) * Math.sin(RoraHead);
  6738. var mapsetlatlng = gaussToGeo(gausscenter[0], gausscenter[1], mapState.center.lng, mapState.zoom);
  6739. } else if (90 < heading3D && heading3D <= 180) {
  6740. var RoraHead = Math.abs((180 - map23DData.view.heading) / 180 * Math.PI);
  6741. gausscenter[1] = gausscenter[1] + h * Math.sin(RoraTilt) * Math.cos(RoraHead);
  6742. gausscenter[0] = gausscenter[0] + h * Math.sin(RoraTilt) * Math.sin(RoraHead);
  6743. var mapsetlatlng = gaussToGeo(gausscenter[0], gausscenter[1], mapState.center.lng, mapState.zoom);
  6744. }
  6745. return {
  6746. View3Dlat: mapsetlatlng.latitude,
  6747. View3Dlng: mapsetlatlng.longitude
  6748. }
  6749. }
  6750. /**
  6751. * 北半球高纬度雷达转换
  6752. */
  6753. function northHeightLatLD(coordinates) {
  6754. var positive;
  6755. var isPositive = false;
  6756. for (var i = 0; i < coordinates.length - 2; i++) {
  6757. if (coordinates[i][0] - coordinates[i + 1][0] > 0) {
  6758. if (!isPositive) {
  6759. positive = i;
  6760. isPositive = true;
  6761. }
  6762. coordinates[i + 1][0] = coordinates[positive][0] * 2 - coordinates[i + 1][0];
  6763. }
  6764. }
  6765. return coordinates;
  6766. }
  6767. /**
  6768. * 南半球高纬度雷达经纬度转换
  6769. */
  6770. function southHeightLatLD(coordinates) {
  6771. var negative;
  6772. var isNegative = false;
  6773. for (var i = 0; i < coordinates.length - 2; i++) {
  6774. if (coordinates[i][0] - coordinates[i + 1][0] < 0) {
  6775. if (!isNegative) {
  6776. negative = i;
  6777. isNegative = true;
  6778. }
  6779. coordinates[i + 1][0] = coordinates[negative][0] * 2 - coordinates[i + 1][0];
  6780. }
  6781. }
  6782. return coordinates;
  6783. }
  6784. /**
  6785. * 计算雷达半球最低拉伸高度
  6786. */
  6787. function getLDCircleExtrude(radius) {
  6788. var earthRadius = 6371000; //地球半径
  6789. var tangle = (360 * radius) / (4 * Math.PI * earthRadius);
  6790. tangle = tangle * Math.PI / 180;
  6791. var minExtrude = 2 * earthRadius * Math.sin(tangle) * Math.sin(tangle);
  6792. return minExtrude;
  6793. };
  6794. /**
  6795. * 经纬度转高斯坐标
  6796. */
  6797. function coordn_to_gauss(mapCenter_data, zoom,userProjNo) {
  6798. var mapxy = mapCenter_data;
  6799. var longitude = mapCenter_data[0];
  6800. var latitude = mapCenter_data[1];
  6801. var f = 1.0 / 298.257222101;
  6802. var a = 6378137;
  6803. var ipi = Math.PI / 180;
  6804. var X0 = 500000;
  6805. var Y0 = 0;
  6806. longitude = parseFloat(longitude);
  6807. latitude = parseFloat(latitude);
  6808. if(userProjNo){
  6809. if(userProjNo == 3){
  6810. ProjNo = Math.round((longitude) / 3);
  6811. longitude0 = ProjNo * 3;
  6812. }else{
  6813. ProjNo = parseInt((longitude) / 6)+1;
  6814. longitude0 = ProjNo * 6 -3;
  6815. }
  6816. }else{
  6817. if (zoom >= 16) {
  6818. ProjNo = Math.round((longitude) / 3);
  6819. longitude0 = ProjNo * 3;
  6820. } else {
  6821. ProjNo = parseInt((longitude) / 6)+1;
  6822. longitude0 = ProjNo * 6 - 3;
  6823. }
  6824. }
  6825. new_longitude0 = longitude0 * ipi;
  6826. latitude0 = 0;
  6827. longitude1 = longitude * ipi;
  6828. latitude1 = latitude * ipi;
  6829. e2 = 2 * f - f * f;
  6830. ee = e2 * (1.0 - e2);
  6831. NN = a / Math.sqrt(1.0 - e2 * Math.sin(latitude1) * Math.sin(latitude1));
  6832. T = Math.tan(latitude1) * Math.tan(latitude1);
  6833. C = ee * Math.cos(latitude1) * Math.cos(latitude1);
  6834. A = (longitude1 - new_longitude0) * Math.cos(latitude1);
  6835. M = a * ((1 - e2 / 4 - 3 * e2 * e2 / 64 - 5 * e2 * e2 * e2 / 256) * latitude1 -
  6836. (3 * e2 / 8 + 3 * e2 * e2 / 32 + 45 * e2 * e2 * e2 / 1024) * Math.sin(2 * latitude1) +
  6837. (15 * e2 * e2 / 256 + 45 * e2 * e2 * e2 / 1024) * Math.sin(4 * latitude1) -
  6838. (35 * e2 * e2 * e2 / 3072) * Math.sin(6 * latitude1));
  6839. 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);
  6840. yval = M + NN * Math.tan(latitude1) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24 +
  6841. (61 - 58 * T + T * T + 600 * C - 330 * ee) * A * A * A * A * A * A / 720);
  6842. xval = xval + X0;
  6843. yval = yval + Y0;
  6844. X = xval;
  6845. X = parseInt((X - 500000) * 0.9996 + 500000);
  6846. Y = yval;
  6847. Y = parseInt(Y * 0.9996);
  6848. return [X, Y,longitude0,ProjNo];
  6849. }
  6850. /**
  6851. * 高斯坐标转经纬度
  6852. */
  6853. function gaussToGeo(X, Y, lng, zoom) {
  6854. var f = 1.0 / 298.257222101;
  6855. var X0 = 500000;
  6856. var Y0 = 0;
  6857. var iPI = Math.PI / 180;
  6858. var a = 6378137;
  6859. if (zoom >= 16) {
  6860. var ZoneWide = 3;
  6861. var ProjNo = parseInt((lng) / ZoneWide);
  6862. var longitude0 = ProjNo * ZoneWide;
  6863. } else {
  6864. var ZoneWide = 6;
  6865. var ProjNo = parseInt((lng) / ZoneWide);
  6866. var longitude0 = ProjNo * ZoneWide + ZoneWide / 2
  6867. }
  6868. longitude0 = longitude0 * iPI
  6869. X = (X - 500000) / 0.9996 + 500000;
  6870. Y = Y / 0.9996;
  6871. var xval = X - X0;
  6872. var yval = Y - Y0;
  6873. var e2 = 2 * f - f * f;
  6874. var e1 = (1.0 - Math.sqrt(1 - e2)) / (1.0 + Math.sqrt(1 - e2));
  6875. var ee = e2 / (1 - e2);
  6876. var M = yval;
  6877. var u = M / (a * (1 - e2 / 4 - 3 * e2 * e2 / 64 - 5 * e2 * e2 * e2 / 256));
  6878. var fai = u + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.sin(2 * u) +
  6879. (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) * Math.sin(4 * u) +
  6880. (151 * e1 * e1 * e1 / 96) * Math.sin(6 * u) + (1097 * e1 * e1 * e1 * e1 / 512) *
  6881. Math.sin(8 * u);
  6882. var C = ee * Math.cos(fai) * Math.cos(fai);
  6883. var T = Math.tan(fai) * Math.tan(fai);
  6884. var NN = a / Math.sqrt(1.0 - e2 * Math.sin(fai) * Math.sin(fai));
  6885. var R = a * (1 - e2) / Math.sqrt((1 - e2 * Math.sin(fai) * Math.sin(fai)) *
  6886. (1 - e2 * Math.sin(fai) * Math.sin(fai)) *
  6887. (1 - e2 * Math.sin(fai) * Math.sin(fai)));
  6888. var D = xval / NN;
  6889. longitude1 = longitude0 + (D - (1 + 2 * T + C) * D * D * D / 6 +
  6890. (5 - 2 * C + 28 * T - 3 * C * C + 8 * ee + 24 * T * T) * D * D * D * D * D / 120) / Math.cos(fai);
  6891. latitude1 = fai - (NN * Math.tan(fai) / R) * (D * D / 2 -
  6892. (5 + 3 * T + 10 * C - 4 * C * C - 9 * ee) * D * D * D * D / 24 +
  6893. (61 + 90 * T + 298 * C + 45 * T * T - 256 * ee - 3 * C * C) * D * D * D * D * D * D / 720);
  6894. longitude = longitude1 / iPI;
  6895. latitude = latitude1 / iPI;
  6896. return {
  6897. longitude: longitude,
  6898. latitude: latitude
  6899. }
  6900. }
  6901. /**
  6902. * 坐标反转
  6903. * @param {[type]} latlngsAry [description]
  6904. * @return {[type]} [description]
  6905. */
  6906. function latLngsToReverse(latlngsAry) {
  6907. var tempLatlngsAry = JSON.parse(JSON.stringify(latlngsAry));
  6908. if (!_.isArray(tempLatlngsAry[0])) {
  6909. return tempLatlngsAry.reverse();
  6910. } else {
  6911. for (var i = 0, l = tempLatlngsAry.length; i < l; i++) {
  6912. tempLatlngsAry[i] = latLngsToReverse(tempLatlngsAry[i]);
  6913. }
  6914. }
  6915. return tempLatlngsAry;
  6916. }
  6917. function getCentroid(arr) {
  6918. var twoTimesSignedArea = 0;
  6919. var cxTimes6SignedArea = 0;
  6920. var cyTimes6SignedArea = 0;
  6921. var length = arr.length;
  6922. var x = function(i) {
  6923. return arr[i % length][0]
  6924. };
  6925. var y = function(i) {
  6926. return arr[i % length][1]
  6927. };
  6928. for (var i = 0; i < arr.length; i++) {
  6929. var twoSA = x(i) * y(i + 1) - x(i + 1) * y(i);
  6930. twoTimesSignedArea += twoSA;
  6931. cxTimes6SignedArea += (x(i) + x(i + 1)) * twoSA;
  6932. cyTimes6SignedArea += (y(i) + y(i + 1)) * twoSA;
  6933. }
  6934. var sixSignedArea = 3 * twoTimesSignedArea;
  6935. return [cxTimes6SignedArea / sixSignedArea, cyTimes6SignedArea / sixSignedArea];
  6936. }
  6937. window.map23DUtil = {
  6938. latLngsToReverse: latLngsToReverse,
  6939. getCentroid: getCentroid,
  6940. latlngsTo3DViewCenter: latlngsTo3DViewCenter,
  6941. gaussToGeo: gaussToGeo,
  6942. coordn_to_gauss: coordn_to_gauss,
  6943. getLDCircleExtrude: getLDCircleExtrude,
  6944. dateLineLnglatsToLnglats: dateLineLnglatsToLnglats,
  6945. lnglatsToDateLineLnglats: lnglatsToDateLineLnglats,
  6946. satelliteData: satelliteData,
  6947. getCurSatelliteData: getCurSatelliteData,
  6948. northHeightLatLD: northHeightLatLD,
  6949. southHeightLatLD: southHeightLatLD,
  6950. getGeoGatheringPlace: getGeoGatheringPlace,
  6951. get3DPixToLnglat: get3DPixToLnglat
  6952. };
  6953. if (typeof module === 'object' && typeof module.exports === 'object') {
  6954. module.exports = map23DUtil;
  6955. } else if (typeof define === 'function' && define.amd) {
  6956. define(map23DUtil);
  6957. }
  6958. }(window, document));
  6959. ;(function (window, document, undefined) {
  6960. window.map23DDefaultData = {
  6961. imageOverlay:{
  6962. from:'23D',
  6963. type:'imageOverlay',
  6964. guid:null,//图层ID tileLayer23D/tileLayer2D/tileLayer3D
  6965. add2D:false,//2D是否已添加
  6966. add3D:false,//3D是否已添加
  6967. visible2D:false,
  6968. visible3D:false,
  6969. layers:{
  6970. opacity:1,//2D透明度
  6971. layerBounds:[[80,-180],[-80,180]],//左上角 右下角
  6972. imageUrl2D:null,//2D图片地址
  6973. imageUrl3D:null//3D图片服务地址
  6974. }
  6975. },
  6976. layer:{
  6977. from:'23D',
  6978. type:'tileLayer',
  6979. guid:null,//图层ID tileLayer23D/tileLayer2D/tileLayer3D
  6980. add2D:false,//2D是否已添加
  6981. add3D:false,//3D是否已添加
  6982. visible2D:false,
  6983. visible3D:false,
  6984. layer:{
  6985. url2D:null,//2D瓦片服务地址
  6986. url3D:null,//3D瓦片服务地址
  6987. minZoom:map23DConfig.map2DMinZoom || 1, //23D最大缩放等级
  6988. maxZoom:map23DConfig.map2DMaxZoom || 21,//23D最小缩放等级
  6989. maxNativeZoom:map23DConfig.map2DMaxZoom || 21,//2D最大渲染等级
  6990. attribution:null,//2D瓦片附属信息
  6991. opacity:1,//2D瓦片透明度
  6992. imageType:'jpeg'//3D瓦片图片类型
  6993. }
  6994. },
  6995. group:{
  6996. from:'23D',
  6997. type:'group',
  6998. guid:null,//图层组ID group23D/group2D/group3D
  6999. add2D:false,//2D是否已添加
  7000. add3D:false,//3D是否已添加
  7001. visible2D:false,
  7002. visible3D:false,
  7003. clustering:false,//2D是否聚合
  7004. clusterOptions:{
  7005. maxClusterRadius:120,//多少像素距离的点会聚合 默认小于120像素内的点会聚合
  7006. polygonOptions: {weight: 1, opacity: 0.5}, //聚合范围面样式
  7007. showCoverageOnHover: true, //是否显示聚合范围
  7008. disableClusteringAtZoom: null, //设置到达指定缩放等级后禁用聚合
  7009. }//2D聚合参数
  7010. },
  7011. marker:{
  7012. from:'23D',
  7013. type:'marker',
  7014. guid:null,//标记ID marker23D/marker2D/marker3D
  7015. add2D:false,
  7016. add3D:false,
  7017. visible2D:false,
  7018. visible3D:false,
  7019. groupId:null,
  7020. animate:false,
  7021. vectorMarker:false,
  7022. geojson:{
  7023. "type": "Feature",
  7024. "properties": {
  7025. title:null,
  7026. titleColor:'#FFFFFF',
  7027. titleFontSize :12,
  7028. baseSize:null,//矢量图片基础大小 控制地图缩放时显示
  7029. baseZoom:null,//矢量图片基础缩放级别
  7030. iconUrl:null,
  7031. icon3DUrl:null,
  7032. iconSize: [25, 41],
  7033. iconAnchor: [12, 41],
  7034. popupAnchor: [1, -34],
  7035. popupContent:null,
  7036. altitude:0,
  7037. altitudeMode:0,
  7038. iconRorate:0,
  7039. iconScale:1,
  7040. fontIcon:null,
  7041. fontSize:null,
  7042. fontColor:null,
  7043. fontWeight:null
  7044. },
  7045. "geometry": {
  7046. "type": "Point",
  7047. "coordinates": [0,0]
  7048. }
  7049. }
  7050. },
  7051. polyline:{
  7052. from:'23D',
  7053. type:'polyline',
  7054. guid:null,
  7055. add2D:false,
  7056. add3D:false,
  7057. visible2D:false,
  7058. visible3D:false,
  7059. groupId:null,
  7060. linetype:'line',
  7061. geojson:{
  7062. "type": "Feature",
  7063. "properties": {
  7064. title:null,
  7065. color:'#0033ff',
  7066. weight:1,
  7067. opacity:1,
  7068. popupContent:null,
  7069. dashArray: null,
  7070. lineType:0, //3D用 Solid:0/Dash:1/Dot:2/DashDot:3/DashDotDot:4
  7071. extrude:0,//拉伸高度
  7072. altitude:0,//海拔高度
  7073. altitudeMode:1
  7074. },
  7075. "geometry": {
  7076. "type": "LineString",
  7077. "coordinates": [[0,0]]
  7078. }
  7079. }
  7080. },
  7081. polygon:{
  7082. from:'23D',
  7083. type:'polygon',
  7084. guid:null,
  7085. add2D:false,
  7086. add3D:false,
  7087. visible2D:false,
  7088. visible3D:false,
  7089. groupId:null,
  7090. polygontype:'polygon',
  7091. geojson:{
  7092. "type": "Feature",
  7093. "properties": {
  7094. title:null,
  7095. color:'#ff0000',
  7096. weight:1,
  7097. fillColor:'#ff6600',
  7098. opacity:1,
  7099. fillOpacity:1,
  7100. popupContent:null,
  7101. extrude:0,
  7102. altitude:0,
  7103. altitudeMode:1
  7104. },
  7105. "geometry": {
  7106. "type": "Polygon",
  7107. "coordinates": [[0,0]]
  7108. }
  7109. }
  7110. },
  7111. circle:{
  7112. from:'23D',
  7113. type:'circle',
  7114. guid:null,
  7115. add2D:false,
  7116. add3D:false,
  7117. visible2D:false,
  7118. visible3D:false,
  7119. groupId:null,
  7120. geojson:{
  7121. "type": "Feature",
  7122. "properties": {
  7123. title:null,
  7124. radius:0,//半径 米
  7125. color:'#ff0000',
  7126. weight:1,
  7127. fillColor:'#ff6600',
  7128. opacity:1,
  7129. fillOpacity:1,
  7130. popupContent:null,
  7131. extrude:0,
  7132. altitude:0,
  7133. altitudeMode:1
  7134. },
  7135. "geometry": {
  7136. "type": "Circle",
  7137. "coordinates": [0,0]
  7138. }
  7139. }
  7140. },
  7141. circleMarker:{
  7142. from:'23D',
  7143. type:'circleMarker',
  7144. guid:null,
  7145. add2D:false,
  7146. add3D:false,
  7147. visible2D:false,
  7148. visible3D:false,
  7149. groupId:null,
  7150. geojson:{
  7151. "type": "Feature",
  7152. "properties": {
  7153. title:null,
  7154. radius:0,//半径 米
  7155. color:'#ff0000',
  7156. weight:1,
  7157. fillColor:'#ff6600',
  7158. opacity:1,
  7159. fillOpacity:1,
  7160. popupContent:null,
  7161. stroke: false,
  7162. extrude:0,
  7163. altitude:0,
  7164. altitudeMode:1
  7165. },
  7166. "geometry": {
  7167. "type": "CircleMarker",
  7168. "coordinates": [0,0]
  7169. }
  7170. }
  7171. },
  7172. model:{
  7173. from:'23D',
  7174. type:'model',
  7175. guid:null,
  7176. add2D:false,
  7177. add3D:false,
  7178. visible2D:false,
  7179. visible3D:false,
  7180. groupId:null,
  7181. geojson:{
  7182. "type": "Feature",
  7183. "properties": {
  7184. title:null,
  7185. url:null,
  7186. popupContent:null,
  7187. altitude:0,
  7188. altitudeMode:0,
  7189. scale:0,
  7190. rotate:[0,0,0],
  7191. visible:true
  7192. },
  7193. "geometry": {
  7194. "type": "Model",
  7195. "coordinates": [0,0]
  7196. }
  7197. }
  7198. }
  7199. }
  7200. window.map23DData = {
  7201. mouseIn:'2D',//2D or 3D
  7202. display:{
  7203. map2D:false,
  7204. map3D:false
  7205. },
  7206. view:{
  7207. center:{
  7208. lat:39,
  7209. lng:116
  7210. },
  7211. zoom:12,
  7212. heading:0,//摄像机平面角度 正北为0
  7213. tilt:0,//摄像机倾斜角
  7214. distance:0//摄像机距地面高度
  7215. },
  7216. layers:{},
  7217. imageOverlays:{},
  7218. groups:{},
  7219. markers:{},
  7220. polylines:{},
  7221. circles:{},
  7222. circleMarkers:{},
  7223. polygons:{},
  7224. models:{},
  7225. timeLineData:{}
  7226. };
  7227. if (typeof module === 'object' && typeof module.exports === 'object') {
  7228. module.exports = map23DData;
  7229. } else if (typeof define === 'function' && define.amd) {
  7230. define(map23DData);
  7231. }
  7232. }(window, document));
  7233. ;
  7234. (function(window, document, undefined) {
  7235. window.map23DControl = {};
  7236. if (typeof module === 'object' && typeof module.exports === 'object') {
  7237. module.exports = map23DControl;
  7238. } else if (typeof define === 'function' && define.amd) {
  7239. define(map23DControl);
  7240. }
  7241. map23DControl.init = function(options) {
  7242. var _this = this;
  7243. _.merge(map23DData, options);
  7244. this.mapWrap = document.getElementById(map23DData.mapWrapId);
  7245. this.map2DWrap = document.createElement('div');
  7246. this.map2DWrap.id = 'map2DWrap';
  7247. this.mapWrap.appendChild(this.map2DWrap);
  7248. this.map3DWrap = document.createElement('div');
  7249. this.map3DWrap.id = 'map3DWrap';
  7250. this.mapWrap.appendChild(this.map3DWrap);
  7251. if (map23DData.display.map2D == true && map23DData.display.map3D == false) {
  7252. this.mapWrap.className = 'show2DOnly';
  7253. map2DViewer.init();
  7254. } else if (map23DData.display.map3D == true && map23DData.display.map2D == false) {
  7255. this.mapWrap.className = 'show3DOnly';
  7256. map3DViewer.init();
  7257. } else {
  7258. map2DViewer.init();
  7259. map3DViewer.init();
  7260. }
  7261. _this.map2DWrap.onmouseover = function(e) {
  7262. map23DData.mouseIn = '2D';
  7263. _this.map2DWrap.focus();
  7264. }
  7265. _this.map3DWrap.onmouseover = function(e) {
  7266. map23DData.mouseIn = '3D';
  7267. if (map3DViewer.inited) {
  7268. _this.map3DWrap.focus();
  7269. }
  7270. }
  7271. }
  7272. map23DControl.show2D = function() {
  7273. this.mapWrap = document.getElementById(map23DData.mapWrapId);
  7274. this.mapWrap.className = 'show2DOnly';
  7275. _.merge(map23DData, {
  7276. display: {
  7277. map2D: true,
  7278. map3D: false
  7279. }
  7280. });
  7281. PubSub.publish('map23D.show2D', {
  7282. from: '23D'
  7283. });
  7284. }
  7285. map23DControl.show3D = function() {
  7286. this.mapWrap = document.getElementById(map23DData.mapWrapId);
  7287. this.mapWrap.className = 'show3DOnly';
  7288. _.merge(map23DData, {
  7289. display: {
  7290. map2D: false,
  7291. map3D: true
  7292. }
  7293. });
  7294. PubSub.publish('map23D.show3D', {
  7295. from: '23D'
  7296. });
  7297. }
  7298. map23DControl.show23D = function() {
  7299. this.mapWrap = document.getElementById(map23DData.mapWrapId);
  7300. this.mapWrap.className = '';
  7301. _.merge(map23DData, {
  7302. display: {
  7303. map2D: true,
  7304. map3D: true
  7305. }
  7306. });
  7307. PubSub.publish('map23D.show23D', {
  7308. from: '23D'
  7309. })
  7310. }
  7311. /**
  7312. * 生成随机GUID
  7313. * @param {[type]} options [description]
  7314. * @return {[type]} [description]
  7315. */
  7316. map23DControl.buildGuid = function(options) {
  7317. var text = "";
  7318. var mar = options || 'default';
  7319. var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  7320. for (var i = 0; i < 18; i++) text += possible.charAt(Math.floor(Math.random() * possible.length));
  7321. return mar + '_' + (new Date()).getTime().toString() + text;
  7322. }
  7323. map23DControl.setView = function(options) {
  7324. _.merge(map23DData.view, options);
  7325. PubSub.publish('map23D.setView', {
  7326. from: '23D'
  7327. })
  7328. }
  7329. //卫星增删改
  7330. map23DControl.satelliteModel = function(options) {
  7331. switch (options.action) {
  7332. case 'add':
  7333. return addSatelliteModel(options.satellite);
  7334. break;
  7335. case 'update':
  7336. return updateSatelliteModel(options);
  7337. break;
  7338. case 'remove':
  7339. return removeSatelliteModel(options);
  7340. break;
  7341. }
  7342. }
  7343. /**
  7344. * 删除卫星单元
  7345. * 卫星单元GUID
  7346. */
  7347. removeSatelliteModel = function(options) {
  7348. //删除卫星轨道
  7349. map23DControl.polyline({
  7350. action: 'remove',
  7351. guid: options.satelliteId.GDId
  7352. })
  7353. //删除卫星模型
  7354. map3DViewer.model({
  7355. action: 'remove',
  7356. guid: options.satelliteId.modelId
  7357. })
  7358. map23DControl.polygon({
  7359. action: 'remove',
  7360. guid: options.satelliteId.polygonId
  7361. })
  7362. //删除2D卫星点
  7363. map2DViewer.marker({
  7364. action: 'remove',
  7365. guid: options.satelliteId.markerId
  7366. })
  7367. //删除卫星扫描四根线
  7368. for (var i = 0; i < options.satelliteId.polylineId.length; i++) {
  7369. map23DControl.polyline({
  7370. action: 'remove',
  7371. guid: options.satelliteId.polylineId[i]
  7372. })
  7373. }
  7374. }
  7375. /**
  7376. * 更新卫星单元
  7377. */
  7378. updateSatelliteModel = function(options) {
  7379. var cahlatlng = options.satellite.breadth / 111000 / 2;
  7380. var lng = options.satellite.lng;
  7381. var lat = options.satellite.lat;
  7382. var altitule = options.satellite.altitude;
  7383. var angle = options.satellite.angle - 90;
  7384. var weixingC = [lng, lat];
  7385. //更新2D卫星点
  7386. var oldmarkerData = map23DData.markers[options.satelliteId.markerId];
  7387. var judgewx = weixingC[0] - oldmarkerData.geojson.geometry.coordinates[0];
  7388. if (judgewx < 0) {
  7389. var curweixingC = [weixingC[0] + 360, weixingC[1]];
  7390. } else {
  7391. var curweixingC = weixingC;
  7392. }
  7393. map2DViewer.marker({
  7394. action: 'update',
  7395. guid: options.satelliteId.markerId,
  7396. geojson: {
  7397. "properties": {
  7398. title: options.satellite.properties.WXtitle,
  7399. iconUrl: options.satellite.model2DUrl, //当有fontIcon的时候 iconUrl无效
  7400. iconSize: options.satellite.properties.iconSize,
  7401. iconAnchor: options.satellite.properties.iconAnchor,
  7402. popupAnchor: options.satellite.properties.popupAnchor,
  7403. popupContent: options.satellite.properties.popupContent,
  7404. iconRorate: angle + 180,
  7405. },
  7406. "geometry": {
  7407. "coordinates": curweixingC
  7408. }
  7409. }
  7410. })
  7411. //更新卫星轨道
  7412. if (options.satellite.updata2DOrbit) {
  7413. map23DControl.polyline({
  7414. action: 'update',
  7415. guid: options.satelliteId.GDId,
  7416. geojson: {
  7417. "properties": {
  7418. title: options.satellite.properties.GDtitle,
  7419. color: options.satellite.properties.GDColor,
  7420. weight: options.satellite.properties.GDWeight,
  7421. opacity: options.satellite.properties.GDopacity,
  7422. extrude: 0, //拉伸高度
  7423. altitude: options.satellite.satelliteTraData.height, //点海拔高度
  7424. altitudeMode: 1 //海拔模式
  7425. },
  7426. "geometry": {
  7427. "coordinates": map23DUtil.lnglatsToDateLineLnglats(options.satellite.satelliteTraData.coordinates)
  7428. }
  7429. }
  7430. })
  7431. } else {
  7432. map3DViewer.polyline({
  7433. action: 'update',
  7434. guid: options.satelliteId.GDId,
  7435. geojson: {
  7436. "properties": {
  7437. title: options.satellite.properties.GDtitle,
  7438. color: options.satellite.properties.GDColor,
  7439. weight: options.satellite.properties.GDWeight,
  7440. opacity: options.satellite.properties.GDopacity,
  7441. extrude: 0, //拉伸高度
  7442. altitude: options.satellite.satelliteTraData.height, //点海拔高度
  7443. altitudeMode: 1 //海拔模式
  7444. },
  7445. "geometry": {
  7446. "coordinates": map23DUtil.lnglatsToDateLineLnglats(options.satellite.satelliteTraData.coordinates)
  7447. }
  7448. }
  7449. })
  7450. }
  7451. //更新卫星模型
  7452. map3DViewer.model({
  7453. action: 'update',
  7454. guid: options.satelliteId.modelId,
  7455. geojson: {
  7456. "properties": {
  7457. title: options.satellite.properties.WXtitle,
  7458. url: options.satellite.modelUrl,
  7459. altitude: altitule, //高度
  7460. altitudeMode: 1, //高度模式
  7461. scale: options.satellite.properties.scale, //放大倍数
  7462. rotate: [0, 0, angle], //前倾角度,左右摆角,平面转角
  7463. visible: true
  7464. },
  7465. "geometry": {
  7466. "coordinates": weixingC //纬度,经度
  7467. }
  7468. }
  7469. })
  7470. //更新卫星扫描面
  7471. var polygonCoors = map2DViewer.PointToPolygon([lng + cahlatlng, lat + cahlatlng], [lng - cahlatlng, lat - cahlatlng]);
  7472. var curcoordinates = [];
  7473. if (judgewx < 0) {
  7474. for (var i = 0; i < polygonCoors.coordinates.length; i++) {
  7475. curcoordinates.push([polygonCoors.coordinates[i][0] + 360, polygonCoors.coordinates[i][1]]);
  7476. }
  7477. } else {
  7478. curcoordinates = polygonCoors.coordinates;
  7479. }
  7480. if (map23DData.display.map2D) {
  7481. map2DViewer.polygon({
  7482. action: 'update',
  7483. guid: options.satelliteId.polygonId,
  7484. geojson: {
  7485. "properties": {
  7486. title: options.satellite.properties.breadthPloygonTitle,
  7487. color: options.satellite.properties.breadthColor,
  7488. weight: options.satellite.properties.breadthWeight,
  7489. fillColor: options.satellite.properties.breadthFillColor,
  7490. opacity: options.satellite.properties.breadthOpacity,
  7491. fillOpacity: options.satellite.properties.breadthFillOpacity,
  7492. extrude: 0, //拉伸高度
  7493. altitude: [16000, 11000, 8000, 4000, 5000, 9000, 16000], //点海拔高度
  7494. altitudeMode: 0 //海拔模式
  7495. },
  7496. "geometry": {
  7497. "type": "Polygon",
  7498. "coordinates": [
  7499. curcoordinates
  7500. ]
  7501. }
  7502. }
  7503. })
  7504. } else if (map23DData.display.map3D) {
  7505. map3DViewer.polygon({
  7506. action: 'update',
  7507. guid: options.satelliteId.polygonId,
  7508. geojson: {
  7509. "properties": {
  7510. title: options.satellite.properties.breadthPloygonTitle,
  7511. color: options.satellite.properties.breadthColor,
  7512. weight: options.satellite.properties.breadthWeight,
  7513. fillColor: options.satellite.properties.breadthFillColor,
  7514. opacity: options.satellite.properties.breadthOpacity,
  7515. fillOpacity: options.satellite.properties.breadthFillOpacity,
  7516. extrude: 0, //拉伸高度
  7517. altitude: [16000, 11000, 8000, 4000, 5000, 9000, 16000], //点海拔高度
  7518. altitudeMode: 0 //海拔模式
  7519. },
  7520. "geometry": {
  7521. "type": "Polygon",
  7522. "coordinates": [
  7523. polygonCoors.coordinates
  7524. ]
  7525. }
  7526. }
  7527. })
  7528. }
  7529. //更新卫星扫描四根线
  7530. for (var i = 0; i < polygonCoors.coordinates.length; i++) {
  7531. if (map23DData.display.map2D) {
  7532. map2DViewer.polyline({
  7533. action: 'update',
  7534. guid: options.satelliteId.polylineId[i],
  7535. geojson: {
  7536. "properties": {
  7537. title: options.satellite.properties.lineTitle,
  7538. color: options.satellite.properties.lineColor,
  7539. weight: options.satellite.properties.lineWeigth,
  7540. opacity: options.satellite.properties.lineOpacity,
  7541. altitude: [altitule, 0], //点海拔高度
  7542. altitudeMode: 1 //海拔模式
  7543. },
  7544. "geometry": {
  7545. "coordinates": [
  7546. curweixingC,
  7547. curcoordinates[i]
  7548. ]
  7549. }
  7550. }
  7551. })
  7552. } else if (map23DData.display.map3D) {
  7553. map3DViewer.polyline({
  7554. action: 'update',
  7555. guid: options.satelliteId.polylineId[i],
  7556. geojson: {
  7557. "properties": {
  7558. title: options.satellite.properties.lineTitle,
  7559. color: options.satellite.properties.lineColor,
  7560. weight: options.satellite.properties.lineWeigth,
  7561. opacity: options.satellite.properties.lineOpacity,
  7562. altitude: [altitule, 0], //点海拔高度
  7563. altitudeMode: 1 //海拔模式
  7564. },
  7565. "geometry": {
  7566. "coordinates": [
  7567. curweixingC,
  7568. polygonCoors.coordinates[i]
  7569. ]
  7570. }
  7571. }
  7572. })
  7573. }
  7574. }
  7575. }
  7576. /**
  7577. * 添加卫星单元
  7578. * 经纬度、高度、角度
  7579. */
  7580. addSatelliteModel = function(options, atelliteTraData) {
  7581. var satelliteId = {
  7582. polygonId: null,
  7583. modelId: null,
  7584. polylineId: [],
  7585. GDId: null,
  7586. markerId: null
  7587. };
  7588. var cahlatlng = options.breadth / 111000 / 2;
  7589. var lng = options.lng;
  7590. var lat = options.lat;
  7591. var altitule = options.altitude;
  7592. var angle = options.angle - 90;
  7593. var weixingC = [lng, lat];
  7594. //添加卫星2D点
  7595. var markerId = map2DViewer.marker({
  7596. action: 'add',
  7597. geojson: {
  7598. "properties": {
  7599. title: options.properties.WXtitle,
  7600. iconUrl: options.model2DUrl, //当有fontIcon的时候 iconUrl无效
  7601. iconSize: options.properties.iconSize,
  7602. iconAnchor: options.properties.iconAnchor,
  7603. popupAnchor: options.properties.popupAnchor,
  7604. popupContent: options.properties.popupContent,
  7605. iconRorate: angle + 180,
  7606. },
  7607. "geometry": {
  7608. "coordinates": weixingC
  7609. }
  7610. }
  7611. })
  7612. satelliteId.markerId = markerId;
  7613. //添加卫星轨道
  7614. //添加23D线
  7615. var GDguid = map23DControl.polyline({
  7616. action: 'add',
  7617. geojson: {
  7618. "properties": {
  7619. title: options.properties.GDtitle,
  7620. color: options.properties.GDColor,
  7621. weight: options.properties.GDWeight,
  7622. opacity: options.properties.GDopacity,
  7623. extrude: 0, //拉伸高度
  7624. altitude: options.satelliteTraData.height, //点海拔高度
  7625. altitudeMode: 1 //海拔模式
  7626. },
  7627. "geometry": {
  7628. "coordinates": map23DUtil.lnglatsToDateLineLnglats(options.satelliteTraData.coordinates)
  7629. }
  7630. }
  7631. })
  7632. satelliteId.GDId = GDguid;
  7633. var model = map3DViewer.model({
  7634. action: 'add',
  7635. geojson: {
  7636. "properties": {
  7637. title: options.properties.WXtitle,
  7638. url: options.modelUrl,
  7639. altitude: altitule, //高度
  7640. altitudeMode: 1, //高度模式
  7641. scale: options.properties.scale, //放大倍数
  7642. rotate: [0, 0, angle], //前倾角度,左右摆角,平面转角
  7643. visible: true
  7644. },
  7645. "geometry": {
  7646. "coordinates": weixingC //纬度,经度
  7647. }
  7648. }
  7649. })
  7650. satelliteId.modelId = model;
  7651. //画面
  7652. var polygonCoors = map2DViewer.PointToPolygon([lng + cahlatlng, lat + cahlatlng], [lng - cahlatlng, lat - cahlatlng]);
  7653. var modelpolygonguid = map23DControl.polygon({
  7654. action: 'add',
  7655. geojson: {
  7656. "properties": {
  7657. title: options.properties.breadthPloygonTitle,
  7658. color: options.properties.breadthColor,
  7659. weight: options.properties.breadthWeight,
  7660. fillColor: options.properties.breadthFillColor,
  7661. opacity: options.properties.breadthOpacity,
  7662. fillOpacity: options.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. polygonCoors.coordinates
  7671. ]
  7672. }
  7673. }
  7674. })
  7675. satelliteId.polygonId = modelpolygonguid;
  7676. for (var i = 0; i < polygonCoors.coordinates.length; i++) {
  7677. var guid = map23DControl.polyline({
  7678. action: 'add',
  7679. geojson: {
  7680. "properties": {
  7681. title: options.properties.lineTitle,
  7682. color: options.properties.lineColor,
  7683. weight: options.properties.lineWeigth,
  7684. opacity: options.properties.lineOpacity,
  7685. altitude: [altitule, 0], //点海拔高度
  7686. altitudeMode: 1 //海拔模式
  7687. },
  7688. "geometry": {
  7689. "coordinates": [
  7690. weixingC,
  7691. polygonCoors.coordinates[i]
  7692. ]
  7693. }
  7694. }
  7695. })
  7696. satelliteId.polylineId.push(guid);
  7697. }
  7698. return satelliteId;
  7699. }
  7700. }(window, document));
  7701. ;
  7702. (function(window, document, undefined) {
  7703. window.map2DViewer = {
  7704. inited: false,
  7705. markers: {},
  7706. layers: {},
  7707. polylines: {},
  7708. polygons: {},
  7709. circles: {},
  7710. circleMarkers: {},
  7711. models:{},
  7712. groups: {},
  7713. hide2D:false,
  7714. syncTimeer:null,
  7715. imageOverlays:{}
  7716. };
  7717. if (typeof module === 'object' && typeof module.exports === 'object') {
  7718. module.exports = map2DViewer;
  7719. } else if (typeof define === 'function' && define.amd) {
  7720. define(map2DViewer);
  7721. }
  7722. PubSub.subscribe('map23D.show2D', function(msg, options) {
  7723. if (options.from == '23D' && map23DData.display.map2D) {
  7724. if (map2DViewer.inited) {
  7725. map2DViewer.map.invalidateSize();
  7726. map2DViewer.map.setView([map23DData.view.center.lat, map23DData.view.center.lng], map23DData.view.zoom);
  7727. } else {
  7728. map2DViewer.init();
  7729. //如果从隐藏到显示,添加所有因show3D隐藏的地图元素,添加同步
  7730. }
  7731. map2DViewer.hide2D = false;
  7732. }
  7733. });
  7734. PubSub.subscribe('map23D.show23D', function(msg, options) {
  7735. if (options.from == '23D' && map23DData.display.map2D) {
  7736. if (map2DViewer.inited) {
  7737. map2DViewer.map.invalidateSize();
  7738. } else {
  7739. map2DViewer.init();
  7740. }
  7741. map2DViewer.hide2D = false;
  7742. }
  7743. });
  7744. PubSub.subscribe('map23D.show3D', function(msg, options) {
  7745. if (options.from == '23D') {
  7746. if (map2DViewer.inited) {
  7747. //移除所有显示的地图元素,并断开同步
  7748. map2DViewer.hide2D = true;
  7749. }
  7750. }
  7751. });
  7752. map2DViewer.init = function(options) {
  7753. var _this = map2DViewer;
  7754. if (this.inited) {
  7755. return;
  7756. } else {
  7757. this.inited = true;
  7758. }
  7759. this.map = L.map('map2DWrap', {
  7760. editable: true,
  7761. attributionControl: false,
  7762. inertia: false,
  7763. // fadeAnimation: false,
  7764. // zoomAnimation: true,
  7765. contextmenu: true,
  7766. minZoom:map23DConfig.map2DMinZoom||1,
  7767. maxZoom:map23DConfig.map2DMaxZoom || 21,
  7768. preferCanvas:true
  7769. }).setView([map23DData.view.center.lat, map23DData.view.center.lng], map23DData.view.zoom);
  7770. this.polygonCanvasRenderer = L.canvas();
  7771. this.polylineCanvasRenderer = L.canvas();
  7772. this.rectangleCanvasRenderer = L.canvas();
  7773. this.circleleCanvasRenderer = L.canvas();
  7774. this.circleMarkerCanvasRenderer = L.canvas();
  7775. this.map.on('zoomend',function(){
  7776. PubSub.publish('map2DViewerZoomend',{
  7777. from:'2D'
  7778. })
  7779. })
  7780. this.map.on('zoomend move', function(e) {
  7781. if (map23DData.mouseIn != '2D') {
  7782. return;
  7783. }
  7784. if(map2DViewer.syncTimeer){
  7785. return false;
  7786. }
  7787. map2DViewer.syncTimeer = setTimeout(function(){
  7788. var mapState = {
  7789. view: {
  7790. center: {
  7791. lat: e.target.getCenter().lat,
  7792. lng: e.target.getCenter().lng
  7793. },
  7794. zoom: _this.map.getZoom()
  7795. }
  7796. }
  7797. _.merge(map23DData, mapState);
  7798. PubSub.publish('map2D.setView', {
  7799. from: '2D'
  7800. })
  7801. clearTimeout(map2DViewer.syncTimeer);
  7802. map2DViewer.syncTimeer = null;
  7803. },300)
  7804. });
  7805. PubSub.subscribe('map3D.setView', function(msg, options) {
  7806. if (options.from == '3D' && map23DData.mouseIn == '3D' && !map2DViewer.hide2D) {
  7807. _this.map.setView(
  7808. [map23DData.view.center.lat, map23DData.view.center.lng],
  7809. map23DData.view.zoom
  7810. );
  7811. }
  7812. });
  7813. PubSub.subscribe('map23D.setView', function(msg, options) {
  7814. if (options.from == '23D' && !map2DViewer.hide2D) {
  7815. _this.map.setView(
  7816. [map23DData.view.center.lat, map23DData.view.center.lng],
  7817. map23DData.view.zoom
  7818. );
  7819. }
  7820. });
  7821. }
  7822. map2DViewer.setView = function(options){
  7823. _.merge(map23DData.view, options);
  7824. map2DViewer.map.setView(
  7825. [map23DData.view.center.lat, map23DData.view.center.lng],
  7826. map23DData.view.zoom
  7827. );
  7828. map23DData.mouseIn = '2D';
  7829. PubSub.publish('map2D.setView', {
  7830. from: '2D'
  7831. })
  7832. }
  7833. map2DViewer.flyTo = function(options){
  7834. _.merge(map23DData.view, options);
  7835. map2DViewer.map.flyTo(
  7836. [map23DData.view.center.lat, map23DData.view.center.lng],
  7837. map23DData.view.zoom
  7838. );
  7839. map23DData.mouseIn = '2D';
  7840. PubSub.publish('map2D.setView', {
  7841. from: '2D'
  7842. })
  7843. }
  7844. /**
  7845. * 设置系统自带图层
  7846. * @param {[type]} options [description]
  7847. */
  7848. map2DViewer.setDefaultTileLayer = function(options) {
  7849. PubSub.publish('map2D.defaultTileLayer.change', {
  7850. mapName: options
  7851. })
  7852. }
  7853. /**
  7854. * 根据两点坐标返回矩形坐标
  7855. * IN 进入坐标[lng,lat]
  7856. * OUT 离开坐标[lng,lat]
  7857. * 扫描宽度在1200KM内效果较好
  7858. */
  7859. map2DViewer.PointToPolygon = function(IN,OUT,inverse){
  7860. var polygonCoors = [];
  7861. var zoom = map23DData.view.zoom;
  7862. //两点之间距离
  7863. //var distanceIO = new L.LatLng(IN[0],IN[1]).distanceTo(new L.LatLng(OUT[0],OUT[1]));
  7864. var distanceIO = Math.sqrt(Math.pow((IN[0]-OUT[0]),2) + Math.pow((IN[1]-OUT[1]),2))
  7865. //经纬度转换成高斯坐标
  7866. //var goosIN = window.map23DUtil.coordn_to_gauss(IN,zoom);
  7867. //var goosOUT = window.map23DUtil.coordn_to_gauss(OUT,zoom);
  7868. var goosIN = IN;
  7869. var goosOUT = OUT;
  7870. //中心点坐标
  7871. var centerLngLatGoos = [(goosIN[0]+goosOUT[0])/2,(goosIN[1]+goosOUT[1])/2];
  7872. var centerLngLat = [(IN[0]+OUT[0])/2,(IN[1]+OUT[1])/2];
  7873. if(goosIN[1] >= centerLngLatGoos[1]){
  7874. if(goosIN[0]> centerLngLatGoos[0]){
  7875. var tangle = L.Util.getAngleByLatLng(centerLngLat[0],centerLngLat[1],IN[0],IN[1]);
  7876. }else{
  7877. var tangle = 360 - L.Util.getAngleByLatLng(centerLngLat[0],centerLngLat[1],IN[0],IN[1]);
  7878. }
  7879. }else{
  7880. if(goosIN[0]> centerLngLatGoos[0]){
  7881. var tangle = 360 - L.Util.getAngleByLatLng(IN[0],IN[1],centerLngLat[0],centerLngLat[1]);
  7882. }else{
  7883. var tangle = L.Util.getAngleByLatLng(IN[0],IN[1],centerLngLat[0],centerLngLat[1]);
  7884. }
  7885. }
  7886. var curTangle = tangle;
  7887. tangle= tangle/180*Math.PI;
  7888. if(curTangle === 0){
  7889. var chaX = distanceIO/2;
  7890. var chaY = distanceIO/2;
  7891. var inverseGoos1 = [centerLngLatGoos[0]-chaX,centerLngLatGoos[1]+chaY];
  7892. var inverseGoos2 = [centerLngLatGoos[0]-chaX,centerLngLatGoos[1]-chaY];
  7893. var inverseGoos3 = [centerLngLatGoos[0]+chaX,centerLngLatGoos[1]-chaY];
  7894. var inverseGoos4 = [centerLngLatGoos[0]+chaX,centerLngLatGoos[1]+chaY];
  7895. }else if(curTangle === 90){
  7896. var chaX = distanceIO/2;
  7897. var chaY = distanceIO/2;
  7898. var inverseGoos1 = [centerLngLatGoos[0]-chaX,centerLngLatGoos[1]+chaY];
  7899. var inverseGoos2 = [centerLngLatGoos[0]-chaX,centerLngLatGoos[1]-chaY];
  7900. var inverseGoos3 = [centerLngLatGoos[0]+chaX,centerLngLatGoos[1]-chaY];
  7901. var inverseGoos4 = [centerLngLatGoos[0]+chaX,centerLngLatGoos[1]+chaY];
  7902. }else{
  7903. var chaX = distanceIO * Math.cos(tangle);
  7904. var chaY = distanceIO * Math.sin(tangle);
  7905. if(!inverse){
  7906. chaY = chaY;
  7907. chaX = chaX;
  7908. }else{
  7909. chaY = -chaY;
  7910. chaX = -chaX;
  7911. }
  7912. var inverseGoos1 = goosIN;
  7913. var inverseGoos2 = [goosIN[0]+chaX,goosIN[1]-chaY];
  7914. var inverseGoos3 = [goosOUT[0]+chaX,goosOUT[1]-chaY];
  7915. var inverseGoos4 = goosOUT;
  7916. }
  7917. var inverse1 = window.map23DUtil.gaussToGeo(inverseGoos1[0],inverseGoos1[1],IN[0],zoom);
  7918. var inverse2 = window.map23DUtil.gaussToGeo(inverseGoos2[0],inverseGoos2[1],centerLngLat[0],zoom);
  7919. var inverse3 = window.map23DUtil.gaussToGeo(inverseGoos3[0],inverseGoos3[1],centerLngLat[0],zoom);
  7920. var inverse4 = window.map23DUtil.gaussToGeo(inverseGoos4[0],inverseGoos4[1],OUT[0],zoom);
  7921. //polygonCoors.push([inverse1.longitude,inverse1.latitude]);
  7922. //polygonCoors.push([inverse2.longitude,inverse2.latitude]);
  7923. //polygonCoors.push([inverse3.longitude,inverse3.latitude]);
  7924. //polygonCoors.push([inverse4.longitude,inverse4.latitude]);
  7925. polygonCoors.push(inverseGoos1);
  7926. polygonCoors.push(inverseGoos2);
  7927. polygonCoors.push(inverseGoos3);
  7928. polygonCoors.push(inverseGoos4);
  7929. return ({
  7930. "coordinates":polygonCoors
  7931. })
  7932. };
  7933. //2D图层组
  7934. map2DViewer.group = function(options) {
  7935. switch (options.action) {
  7936. case 'add':
  7937. return addGroup2D(options);
  7938. break;
  7939. case 'show':
  7940. return showGroup2D(options);
  7941. break;
  7942. case 'hide':
  7943. return hideGroup2D(options);
  7944. break;
  7945. case 'remove':
  7946. return removeGroup2D(options);
  7947. break;
  7948. case 'cleanAll':
  7949. return cleanGroupAllFeatures2D(options);
  7950. break;
  7951. }
  7952. }
  7953. function addGroup2D(options) {
  7954. var guid = options.guid || map23DControl.buildGuid('group2D');
  7955. if(options.guid){
  7956. guid = 'group2D_'+guid;
  7957. }
  7958. var defaultData = _.cloneDeep(map23DDefaultData.group)
  7959. defaultData.guid = guid;
  7960. defaultData.from = '2D';
  7961. _.merge(defaultData, options);
  7962. map23DData.groups[guid] = defaultData;
  7963. PubSub.publishSync('map2D.group.add', guid);
  7964. return guid;
  7965. }
  7966. function showGroup2D(options){
  7967. if (map2DViewer.groups[options.guid]) {
  7968. PubSub.publishSync('map2D.group.show', options.guid);
  7969. return options.guid;
  7970. } else {
  7971. return false;
  7972. }
  7973. }
  7974. function hideGroup2D(options){
  7975. if (map2DViewer.groups[options.guid]) {
  7976. PubSub.publishSync('map2D.group.hide', options.guid);
  7977. return options.guid;
  7978. } else {
  7979. return false;
  7980. }
  7981. }
  7982. function removeGroup2D(options) {
  7983. if (map23DData.groups[options.guid]) {
  7984. cleanGroupAllFeatures2D(options);
  7985. PubSub.publishSync('map2D.group.remove', options.guid);
  7986. if(map23DData.groups[options.guid].add3D == false){
  7987. delete map23DData.groups[options.guid];
  7988. }
  7989. return options.guid;
  7990. } else {
  7991. return false;
  7992. }
  7993. }
  7994. function cleanGroupAllFeatures2D(options) {
  7995. if (map23DData.groups[options.guid]) {
  7996. //移除点
  7997. _(map23DData.markers).forEach(function(item, key) {
  7998. if (item.groupId == options.guid) {
  7999. map2DViewer.marker({
  8000. action: 'remove',
  8001. guid: key
  8002. })
  8003. }
  8004. });
  8005. //移除线
  8006. _(map23DData.polylines).forEach(function(item, key) {
  8007. if (item.groupId == options.guid) {
  8008. map2DViewer.polyline({
  8009. action: 'remove',
  8010. guid: key
  8011. })
  8012. }
  8013. });
  8014. //移除面
  8015. _(map23DData.polygons).forEach(function(item, key) {
  8016. if (item.groupId == options.guid) {
  8017. map2DViewer.polygon({
  8018. action: 'remove',
  8019. guid: key
  8020. })
  8021. }
  8022. });
  8023. //移除圆
  8024. _(map23DData.circles).forEach(function(item, key) {
  8025. if (item.groupId == options.guid) {
  8026. map2DViewer.circle({
  8027. action: 'remove',
  8028. guid: key
  8029. })
  8030. }
  8031. });
  8032. //移除圆标记
  8033. _(map23DData.circleMarkers).forEach(function(item, key) {
  8034. if (item.groupId == options.guid) {
  8035. map2DViewer.circleMarker({
  8036. action: 'remove',
  8037. guid: key
  8038. })
  8039. }
  8040. });
  8041. return options.guid;
  8042. } else {
  8043. return false
  8044. }
  8045. }
  8046. //2D 点
  8047. map2DViewer.marker = function(options) {
  8048. switch (options.action) {
  8049. case 'add':
  8050. return addMarker2D(options);
  8051. break;
  8052. case 'remove':
  8053. return removeMarker2D(options);
  8054. break;
  8055. case 'update':
  8056. return updateMarker2D(options);
  8057. break;
  8058. case 'hide':
  8059. return hideMarker2D(options);
  8060. break;
  8061. case 'show':
  8062. return showMarker2D(options);
  8063. break;
  8064. }
  8065. }
  8066. function addMarker2D(options) {
  8067. var guid = options.guid || map23DControl.buildGuid('marker2D');
  8068. if(options.guid){
  8069. guid = 'marker2D_'+guid;
  8070. }
  8071. if (!options.RBkey) {
  8072. var markerTime = null;
  8073. } else {
  8074. var markerTime = map23DData.polylines[map2DViewer.routeBackGroup[options.RBkey].polyline].geojson.properties.times;
  8075. }
  8076. if(options.vectorMarker){
  8077. var dataSize = options.geojson.properties.baseSize;
  8078. var curZoom = map23DData.view.zoom;
  8079. if(curZoom>=options.geojson.properties.baseZoom){
  8080. var scaleX = dataSize[0]+ dataSize[0]*(curZoom-options.geojson.properties.baseZoom);
  8081. var scaleY = dataSize[1]+ dataSize[1]*(curZoom-options.geojson.properties.baseZoom);
  8082. }else{
  8083. var scaleX = dataSize[0]*Math.pow(options.geojson.properties.baseZoom-curZoom+1,-1);
  8084. var scaleY = dataSize[1]*Math.pow(options.geojson.properties.baseZoom-curZoom+1,-1);
  8085. }
  8086. options.geojson.properties.iconSize = [scaleX,scaleY];
  8087. options.geojson.properties.iconAnchor = [scaleX/2,scaleY/2];
  8088. options.geojson.properties.popupAnchor = [0,-scaleY];
  8089. }
  8090. var defaultData = _.cloneDeep(map23DDefaultData.marker)
  8091. defaultData.guid = guid;
  8092. defaultData.from = '2D';
  8093. defaultData.geojson.geometry.markerTime = markerTime;
  8094. _.merge(defaultData, options);
  8095. map23DData.markers[guid] = defaultData;
  8096. PubSub.publishSync('map2D.marker.add', guid);
  8097. return guid;
  8098. }
  8099. function showMarker2D(options){
  8100. if (map2DViewer.markers[options.guid]) {
  8101. PubSub.publishSync('map2D.marker.show', options.guid);
  8102. return options.guid;
  8103. } else {
  8104. return false;
  8105. }
  8106. }
  8107. function hideMarker2D(options){
  8108. if (map2DViewer.markers[options.guid]) {
  8109. PubSub.publishSync('map2D.marker.hide', options.guid);
  8110. return options.guid;
  8111. } else {
  8112. return false;
  8113. }
  8114. }
  8115. function removeMarker2D(options) {
  8116. if (map23DData.markers[options.guid]) {
  8117. PubSub.publishSync('map2D.marker.remove', options.guid);
  8118. if(map23DData.markers[options.guid].add3D == false){
  8119. delete map23DData.markers[options.guid];
  8120. }
  8121. return options.guid;
  8122. } else {
  8123. return false;
  8124. }
  8125. }
  8126. function updateMarker2D(options){
  8127. if (map23DData.markers[options.guid]) {
  8128. _.merge(map23DData.markers[options.guid], options);
  8129. PubSub.publishSync('map2D.marker.update', options.guid);
  8130. return options.guid;
  8131. } else {
  8132. return false;
  8133. }
  8134. }
  8135. //2D 线
  8136. map2DViewer.polyline = function(options) {
  8137. switch (options.action) {
  8138. case 'add':
  8139. return addPolyline2D(options);
  8140. break;
  8141. case 'show':
  8142. return showPolyline2D(options);
  8143. break;
  8144. case 'hide':
  8145. return hidePolyline2D(options);
  8146. break;
  8147. case 'remove':
  8148. return removePolyline2D(options);
  8149. break;
  8150. case 'update':
  8151. return updatePolyline2D(options);
  8152. break;
  8153. }
  8154. }
  8155. function addPolyline2D(options) {
  8156. var guid = options.guid || map23DControl.buildGuid('polyline2D');
  8157. if(options.guid){
  8158. guid = 'polyline2D_'+guid;
  8159. }
  8160. var defaultData = _.cloneDeep(map23DDefaultData.polyline)
  8161. defaultData.guid = guid;
  8162. defaultData.from = '2D';
  8163. _.merge(defaultData, options);
  8164. map23DData.polylines[guid] = defaultData;
  8165. PubSub.publishSync('map2D.polyline.add', guid);
  8166. return guid;
  8167. }
  8168. function showPolyline2D(options){
  8169. if (map2DViewer.polylines[options.guid]) {
  8170. PubSub.publishSync('map2D.polyline.show', options.guid);
  8171. return options.guid;
  8172. } else {
  8173. return false;
  8174. }
  8175. }
  8176. function hidePolyline2D(options){
  8177. if (map2DViewer.polylines[options.guid]) {
  8178. PubSub.publishSync('map2D.polyline.hide', options.guid);
  8179. return options.guid;
  8180. } else {
  8181. return false;
  8182. }
  8183. }
  8184. function removePolyline2D(options) {
  8185. if (map23DData.polylines[options.guid]) {
  8186. PubSub.publishSync('map2D.polyline.remove', options.guid);
  8187. if(map23DData.polylines[options.guid].add3D == false){
  8188. delete map23DData.polylines[options.guid];
  8189. }
  8190. return options.guid;
  8191. } else {
  8192. return false;
  8193. }
  8194. }
  8195. function updatePolyline2D(options){
  8196. if (map23DData.polylines[options.guid]) {
  8197. _.merge(map23DData.polylines[options.guid], options);
  8198. PubSub.publishSync('map2D.polyline.update', options.guid);
  8199. return options.guid;
  8200. } else {
  8201. return false;
  8202. }
  8203. }
  8204. //2D 面
  8205. map2DViewer.polygon = function(options) {
  8206. switch (options.action) {
  8207. case 'add':
  8208. return addPolygon2D(options);
  8209. break;
  8210. case 'show':
  8211. return showPolygon2D(options);
  8212. break;
  8213. case 'hide':
  8214. return hidePolygon2D(options);
  8215. break;
  8216. case 'remove':
  8217. return removePolygon2D(options);
  8218. break;
  8219. case 'update':
  8220. return updatePolygon2D(options);
  8221. break;
  8222. }
  8223. }
  8224. function addPolygon2D(options) {
  8225. var guid = options.guid || map23DControl.buildGuid('polygon2D');
  8226. if(options.guid){
  8227. guid = 'polygon2D_'+guid;
  8228. }
  8229. var defaultData = _.cloneDeep(map23DDefaultData.polyline)
  8230. defaultData.guid = guid;
  8231. defaultData.from = '2D';
  8232. _.merge(defaultData, options);
  8233. map23DData.polygons[guid] = defaultData;
  8234. PubSub.publishSync('map2D.polygon.add', guid);
  8235. return guid;
  8236. }
  8237. function showPolygon2D(options){
  8238. if (map2DViewer.polygons[options.guid]) {
  8239. PubSub.publishSync('map2D.polygon.show', options.guid);
  8240. return options.guid;
  8241. } else {
  8242. return false;
  8243. }
  8244. }
  8245. function hidePolygon2D(options){
  8246. if (map2DViewer.polygons[options.guid]) {
  8247. PubSub.publishSync('map2D.polygon.hide', options.guid);
  8248. return options.guid;
  8249. } else {
  8250. return false;
  8251. }
  8252. }
  8253. function removePolygon2D(options) {
  8254. if (map23DData.polygons[options.guid]) {
  8255. PubSub.publishSync('map2D.polygon.remove', options.guid);
  8256. if(map23DData.polygons[options.guid].add3D == false){
  8257. delete map23DData.polygons[options.guid];
  8258. }
  8259. return options.guid;
  8260. } else {
  8261. return false;
  8262. }
  8263. }
  8264. function updatePolygon2D(options){
  8265. if (map23DData.polygons[options.guid]) {
  8266. _.merge(map23DData.polygons[options.guid], options);
  8267. PubSub.publishSync('map2D.polygon.update', options.guid);
  8268. return options.guid;
  8269. } else {
  8270. return false;
  8271. }
  8272. }
  8273. //2D 圆
  8274. map2DViewer.circle = function(options) {
  8275. switch (options.action) {
  8276. case 'add':
  8277. return addCircle2D(options);
  8278. break;
  8279. case 'show':
  8280. return showCircle2D(options);
  8281. break;
  8282. case 'hide':
  8283. return hideCircle2D(options);
  8284. break;
  8285. case 'remove':
  8286. return removeCircle2D(options);
  8287. break;
  8288. case 'update':
  8289. return updateCircle2D(options);
  8290. break;
  8291. }
  8292. }
  8293. function addCircle2D(options) {
  8294. var guid = options.guid || map23DControl.buildGuid('circle2D');
  8295. if(options.guid){
  8296. guid = 'circle2D_'+guid;
  8297. }
  8298. var defaultData = _.cloneDeep(map23DDefaultData.circle)
  8299. defaultData.guid = guid;
  8300. defaultData.from = '2D';
  8301. _.merge(defaultData, options);
  8302. map23DData.circles[guid] = defaultData;
  8303. PubSub.publishSync('map2D.circle.add', guid);
  8304. return guid;
  8305. }
  8306. function showCircle2D(options){
  8307. if (map2DViewer.circles[options.guid]) {
  8308. PubSub.publishSync('map2D.circle.show', options.guid);
  8309. return options.guid;
  8310. } else {
  8311. return false;
  8312. }
  8313. }
  8314. function hideCircle2D(options){
  8315. if (map2DViewer.circles[options.guid]) {
  8316. PubSub.publishSync('map2D.circle.hide', options.guid);
  8317. return options.guid;
  8318. } else {
  8319. return false;
  8320. }
  8321. }
  8322. function removeCircle2D(options) {
  8323. if (map23DData.circles[options.guid]) {
  8324. PubSub.publishSync('map2D.circle.remove', options.guid);
  8325. if(map23DData.circles[options.guid].add3D == false){
  8326. delete map23DData.circles[options.guid];
  8327. }
  8328. return options.guid;
  8329. } else {
  8330. return false;
  8331. }
  8332. }
  8333. function updateCircle2D(options){
  8334. if (map23DData.circles[options.guid]) {
  8335. _.merge(map23DData.circles[options.guid], options);
  8336. PubSub.publishSync('map2D.circle.update', options.guid);
  8337. return options.guid;
  8338. } else {
  8339. return false;
  8340. }
  8341. }
  8342. //2D 圆标记
  8343. map2DViewer.circleMarker = function(options) {
  8344. switch (options.action) {
  8345. case 'add':
  8346. return addCircleMarker2D(options);
  8347. break;
  8348. case 'show':
  8349. return showCircleMarker2D(options);
  8350. break;
  8351. case 'hide':
  8352. return hideCircleMarker2D(options);
  8353. break;
  8354. case 'remove':
  8355. return removeCircleMarker2D(options);
  8356. break;
  8357. case 'update':
  8358. return updateCircleMarker2D(options);
  8359. break;
  8360. }
  8361. }
  8362. function addCircleMarker2D(options) {
  8363. var guid = options.guid || map23DControl.buildGuid('circleMarker2D');
  8364. if(options.guid){
  8365. guid = 'circleMarker2D_'+guid;
  8366. }
  8367. var defaultData = _.cloneDeep(map23DDefaultData.circleMarker)
  8368. defaultData.guid = guid;
  8369. defaultData.from = '2D';
  8370. _.merge(defaultData, options);
  8371. map23DData.circleMarkers[guid] = defaultData;
  8372. PubSub.publishSync('map2D.circleMarker.add', guid);
  8373. return guid;
  8374. }
  8375. function showCircleMarker2D(options){
  8376. if (map2DViewer.circleMarkers[options.guid]) {
  8377. PubSub.publishSync('map2D.circleMarker.show', options.guid);
  8378. return options.guid;
  8379. } else {
  8380. return false;
  8381. }
  8382. }
  8383. function hideCircleMarker2D(options){
  8384. if (map2DViewer.circleMarkers[options.guid]) {
  8385. PubSub.publishSync('map2D.circleMarker.hide', options.guid);
  8386. return options.guid;
  8387. } else {
  8388. return false;
  8389. }
  8390. }
  8391. function removeCircleMarker2D(options) {
  8392. if (map23DData.circleMarkers[options.guid]) {
  8393. PubSub.publishSync('map2D.circleMarker.remove', options.guid);
  8394. if(map23DData.circleMarkers[options.guid].add3D == false){
  8395. delete map23DData.circleMarkers[options.guid];
  8396. }
  8397. return options.guid;
  8398. } else {
  8399. return false;
  8400. }
  8401. }
  8402. function updateCircleMarker2D(options){
  8403. if (map23DData.circleMarkers[options.guid]) {
  8404. _.merge(map23DData.circleMarkers[options.guid], options);
  8405. PubSub.publishSync('map2D.circleMarker.update', options.guid);
  8406. return options.guid;
  8407. } else {
  8408. return false;
  8409. }
  8410. }
  8411. map2DViewer.imageOverlay = function(options) {
  8412. switch (options.action) {
  8413. case 'add':
  8414. return addImageOverlay(options);
  8415. break;
  8416. case 'remove':
  8417. return removeImageOverlay(options);
  8418. break;
  8419. case 'update':
  8420. return updateImageOverlay(options);
  8421. break;
  8422. case 'hide':
  8423. return hideImageOverlay(options);
  8424. break;
  8425. case 'show':
  8426. return showImageOverlay(options);
  8427. break;
  8428. }
  8429. }
  8430. function hideImageOverlay(options){
  8431. if (map23DData.imageOverlays[options.guid]) {
  8432. _.merge(map23DData.imageOverlays[options.guid], options);
  8433. PubSub.publishSync('map2D.imageOverlay.hide', options.guid);
  8434. return options.guid;
  8435. } else {
  8436. return false;
  8437. }
  8438. }
  8439. function showImageOverlay(options){
  8440. if (map23DData.imageOverlays[options.guid]) {
  8441. _.merge(map23DData.imageOverlays[options.guid], options);
  8442. PubSub.publishSync('map2D.imageOverlay.show', options.guid);
  8443. return options.guid;
  8444. } else {
  8445. return false;
  8446. }
  8447. }
  8448. function addImageOverlay(options) {
  8449. var guid = options.guid || map23DControl.buildGuid('imageOverlay23D');
  8450. if(options.guid){
  8451. guid = 'imageOverlay2D_'+guid;
  8452. }
  8453. var defaultData = _.cloneDeep(map23DDefaultData.imageOverlay)
  8454. defaultData.guid = guid;
  8455. _.merge(defaultData, options);
  8456. map23DData.imageOverlays[guid] = defaultData;
  8457. PubSub.publishSync('map2D.imageOverlay.add', guid);
  8458. return guid;
  8459. }
  8460. /**
  8461. * 移除图层组,移除前先清除图层组中的元素
  8462. * @param {[type]} options [description]
  8463. * @return {[type]} [description]
  8464. */
  8465. function removeImageOverlay(options) {
  8466. if (map23DData.imageOverlays[options.guid]) {
  8467. PubSub.publishSync('map2D.imageOverlay.remove', options.guid);
  8468. delete map23DData.imageOverlays[options.guid];
  8469. return options.guid;
  8470. } else {
  8471. return false;
  8472. }
  8473. }
  8474. function updateImageOverlay(options) {
  8475. if (map23DData.imageOverlays[options.guid]) {
  8476. _.merge(map23DData.imageOverlays[options.guid], options);
  8477. PubSub.publishSync('map2D.imageOverlay.update', options.guid);
  8478. return options.guid;
  8479. } else {
  8480. return false;
  8481. }
  8482. }
  8483. /**
  8484. * 2D图层控制
  8485. */
  8486. map2DViewer.tileLayer = function(options) {
  8487. switch (options.action) {
  8488. case 'add':
  8489. return addTileLayer2D(options);
  8490. break;
  8491. case 'show':
  8492. return showTileLayer2D(options);
  8493. break;
  8494. case 'hide':
  8495. return hideTileLayer2D(options);
  8496. break;
  8497. case 'remove':
  8498. return removeTileLayer2D(options);
  8499. break;
  8500. case 'update':
  8501. return updateTileLayer2D(options);
  8502. }
  8503. }
  8504. function addTileLayer2D(options) {
  8505. var guid = options.guid || map23DControl.buildGuid('tileLayer2D');
  8506. if(options.guid){
  8507. guid = 'tileLayer2D_'+guid;
  8508. }
  8509. var defaultData = _.cloneDeep(map23DDefaultData.layer)
  8510. defaultData.guid = guid;
  8511. defaultData.from = '2D';
  8512. _.merge(defaultData, options);
  8513. map23DData.layers[guid] = defaultData;
  8514. PubSub.publishSync('map2D.tileLayer.add', guid);
  8515. return guid;
  8516. }
  8517. function showTileLayer2D(options){
  8518. if (map2DViewer.layers[options.guid]) {
  8519. PubSub.publishSync('map2D.tileLayer.show', options.guid);
  8520. return options.guid;
  8521. } else {
  8522. return false;
  8523. }
  8524. }
  8525. function hideTileLayer2D(options){
  8526. if (map2DViewer.layers[options.guid]) {
  8527. PubSub.publishSync('map2D.tileLayer.hide', options.guid);
  8528. return options.guid;
  8529. } else {
  8530. return false;
  8531. }
  8532. }
  8533. function updateTileLayer2D(options) {
  8534. if (map23DData.layers[options.guid]) {
  8535. _.merge(map23DData.layers[options.guid], options);
  8536. PubSub.publishSync('map2D.tileLayer.update', options.guid);
  8537. return options.guid;
  8538. } else {
  8539. return false;
  8540. }
  8541. }
  8542. function removeTileLayer2D(options) {
  8543. if (map23DData.layers[options.guid]) {
  8544. PubSub.publishSync('map2D.tileLayer.remove', options.guid);
  8545. if(map23DData.layers[options.guid].add3D == false){
  8546. delete map23DData.layers[options.guid];
  8547. }
  8548. return options.guid;
  8549. } else {
  8550. return false;
  8551. }
  8552. }
  8553. /**
  8554. * 2DCartodb控制
  8555. */
  8556. map2DViewer.cartodbLayer = function(options) {
  8557. switch (options.action) {
  8558. case 'add':
  8559. return addCartodbLayer2D(options);
  8560. break;
  8561. case 'remove':
  8562. return removeCartodbLayer2D(options);
  8563. break;
  8564. }
  8565. }
  8566. function addCartodbLayer2D(options) {
  8567. var guid = options.guid || map23DControl.buildGuid('cartodbLayer2D');
  8568. if(options.guid){
  8569. guid = 'cartodbLayer2D_'+guid;
  8570. }
  8571. var defaultData = _.cloneDeep(map23DDefaultData.layer)
  8572. defaultData.guid = guid;
  8573. defaultData.from = '2D';
  8574. _.merge(defaultData, options);
  8575. map23DData.layers[guid] = defaultData;
  8576. PubSub.publishSync('map2D.cartodbLayer.add', guid);
  8577. return guid;
  8578. }
  8579. function removeCartodbLayer2D(options) {
  8580. if (map23DData.layers[options.guid]) {
  8581. PubSub.publishSync('map2D.cartodbLayer.remove', options.guid);
  8582. delete map23DData.layers[options.guid];
  8583. return options.guid;
  8584. } else {
  8585. return false;
  8586. }
  8587. }
  8588. }(window, document));
  8589. ;
  8590. (function(window, document, undefined) {
  8591. window.map3DViewer = {
  8592. inited: false,
  8593. markers: {},
  8594. layers: {},
  8595. polylines: {},
  8596. polygons: {},
  8597. circles: {},
  8598. groups: {},
  8599. models: {},
  8600. hide3D:false,
  8601. 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],
  8602. syncTimeer:null,
  8603. imageOverlays:{}
  8604. };
  8605. if (typeof module === 'object' && typeof module.exports === 'object') {
  8606. module.exports = map3DViewer;
  8607. } else if (typeof define === 'function' && define.amd) {
  8608. define(map3DViewer);
  8609. }
  8610. PubSub.subscribe('map23D.show3D', function(msg, options) {
  8611. if (options.from == '23D' && map23DData.display.map3D) {
  8612. if (map3DViewer.inited) {
  8613. var newlatlng = window.map23DUtil.latlngsTo3DViewCenter(map23DData.view);
  8614. var map3DHeading = -map23DData.view.heading;
  8615. locaSpace.JumpTo(
  8616. newlatlng.View3Dlng,
  8617. newlatlng.View3Dlat,
  8618. map3DViewer.getZoomFrom2DZoom(map23DData.view.zoom),
  8619. map3DHeading,
  8620. 0
  8621. );
  8622. locaSpaceMap.Refresh();
  8623. map23DData.mouseIn = '3D';
  8624. } else {
  8625. map3DViewer.init();
  8626. //如果从隐藏到显示,添加所有因show2D隐藏的地图元素,添加同步
  8627. }
  8628. map3DViewer.hide3D = false;
  8629. }
  8630. });
  8631. PubSub.subscribe('map23D.show23D', function(msg, options) {
  8632. if (options.from == '23D' && map23DData.display.map3D) {
  8633. if (map3DViewer.inited) {} else {
  8634. map3DViewer.init();
  8635. }
  8636. map3DViewer.hide3D = false;
  8637. }
  8638. });
  8639. PubSub.subscribe('map23D.show2D', function(msg, options) {
  8640. if (options.from == '23D') {
  8641. if (map3DViewer.inited) {
  8642. //移除所有显示的地图元素,并断开同步
  8643. map3DViewer.hide3D = true;
  8644. }
  8645. }
  8646. });
  8647. map3DViewer.init = function() {
  8648. var _this = this;
  8649. if (this.inited) {
  8650. return;
  8651. } else {
  8652. this.inited = true;
  8653. }
  8654. var initResult = locaSpace.InitGlobal('map3DWrap');
  8655. if(!initResult){
  8656. this.inited = false;
  8657. return false;
  8658. }
  8659. locaSpace.ConnectServer(map23DConfig.threeDimensionalServerUrl, 1500);
  8660. this.map = locaSpaceMap;
  8661. locaSpaceMap.Globe.ClearNetCache();
  8662. locaSpaceMap.Globe.Layers.RemoveAll();
  8663. //设置经纬网隐藏
  8664. locaSpaceMap.Globe.LatLonGridVisible = false;
  8665. //显示太阳
  8666. locaSpaceMap.Globe.SunVisible = false;
  8667. locaSpaceMap.Globe.OverviewControl.Visible = false;
  8668. locaSpaceMap.FeatureMouseOverEnable = true;
  8669. locaSpaceMap.Refresh();
  8670. //设置三维球最大可见高度和摄像机透视距离
  8671. locaSpaceMap.Globe.UserProFarDist = 6378137*100;
  8672. locaSpaceMap.Globe.MaxCarmeraDist = 6378137*100;
  8673. //初始位置
  8674. var map3DHeading = -map23DData.view.heading;
  8675. locaSpace.JumpTo(
  8676. map23DData.view.center.lng,
  8677. map23DData.view.center.lat,
  8678. map3DViewer.getZoomFrom2DZoom(map23DData.view.zoom),
  8679. map3DHeading, 0);
  8680. locaSpaceMap.attachEvent("FireBeforeSceneRender", function(e) {
  8681. if (map23DData.mouseIn != '3D') {
  8682. return;
  8683. }
  8684. if(map3DViewer.syncTimeer){
  8685. return;
  8686. }
  8687. var _cameraState = locaSpaceMap.Globe.CameraState;
  8688. if(_cameraState.Distance > 501243630){
  8689. _cameraState.Distance = 50124363;
  8690. locaSpaceMap.Globe.JumpToCameraState(_cameraState);
  8691. return;
  8692. }
  8693. map3DViewer.syncTimeer = setTimeout(function(){
  8694. var cameraState = locaSpaceMap.Globe.CameraState;
  8695. var map23DDataHeading = -cameraState.Heading;
  8696. var mapState = {
  8697. view: {
  8698. center: {
  8699. lat: cameraState.Latitude,
  8700. lng: cameraState.Longitude
  8701. },
  8702. zoom: map3DViewer.getZoomFrom3DZoom(cameraState.Distance),
  8703. heading: map23DDataHeading,
  8704. tilt: cameraState.Tilt,
  8705. distance: cameraState.Distance
  8706. }
  8707. }
  8708. _.merge(map23DData, mapState);
  8709. PubSub.publish('map3D.setView', {
  8710. from: '3D'
  8711. })
  8712. clearTimeout(map3DViewer.syncTimeer);
  8713. map3DViewer.syncTimeer = null;
  8714. },300)
  8715. });
  8716. //鼠标点击元素
  8717. locaSpaceMap.attachEvent("FireFeatureMouseClick", function(feature, e) {
  8718. PubSub.publish('map3D.featureClick', {
  8719. from: '3D',
  8720. evt: e,
  8721. feature:feature
  8722. })
  8723. });
  8724. //鼠标滑过元素
  8725. locaSpaceMap.attachEvent("FireFeatureMouseHover",function(feature, e){
  8726. PubSub.publish('map3D.featureMouseHover', {
  8727. from: '3D',
  8728. evt: e,
  8729. feature:feature
  8730. })
  8731. });
  8732. //鼠标进入元素
  8733. locaSpaceMap.attachEvent("FireFeatureMouseInto",function(feature, e){
  8734. PubSub.publish('map3D.featureMouseInto', {
  8735. from: '3D',
  8736. evt: e,
  8737. feature:feature
  8738. })
  8739. });
  8740. //鼠标移出元素
  8741. locaSpaceMap.attachEvent("FireFeatureMouseOut",function(feature, e){
  8742. PubSub.publish('map3D.featureMouseOut', {
  8743. from: '3D',
  8744. evt: e,
  8745. feature:feature
  8746. })
  8747. });
  8748. //鼠标在元素上滑动
  8749. locaSpaceMap.attachEvent("FireFeatureMouseOver",function(feature, e){
  8750. PubSub.publish('map3D.featureMouseOver', {
  8751. from: '3D',
  8752. evt: e,
  8753. feature:feature
  8754. })
  8755. });
  8756. //摄像机移动停止
  8757. locaSpaceMap.attachEvent("FireCameraBeginStop",function(e){
  8758. PubSub.publish('map3D.cameraBeginStop', {
  8759. from: '3D',
  8760. evt: e
  8761. })
  8762. });
  8763. //摄像机开始移动
  8764. locaSpaceMap.attachEvent("FireCameraBeginMove",function(e){
  8765. PubSub.publish('map3D.cameraBeginMove', {
  8766. from: '3D',
  8767. evt: e
  8768. })
  8769. });
  8770. //停止飞行
  8771. locaSpaceMap.attachEvent("FireStopFly",function(flyId,flyType){
  8772. PubSub.publish('map3D.stopFly', {
  8773. from: '3D',
  8774. flyId:flyId,
  8775. flyType:flyType
  8776. })
  8777. });
  8778. //暂停飞行
  8779. locaSpaceMap.attachEvent("FirePauseFly",function(flyId,flyType){
  8780. PubSub.publish('map3D.pauseFly', {
  8781. from: '3D',
  8782. flyId:flyId,
  8783. flyType:flyType
  8784. })
  8785. });
  8786. //鼠标移动
  8787. locaSpaceMap.attachEvent("MouseMove",function(button,shift,x,y){
  8788. PubSub.publish('map3D.mouseMove', {
  8789. from: '3D',
  8790. button: button,
  8791. shift:shift,
  8792. x:x,
  8793. y:y
  8794. })
  8795. });
  8796. //鼠标按下
  8797. locaSpaceMap.attachEvent("MouseDown",function(button,shift,x,y){
  8798. PubSub.publish('map3D.mouseDown', {
  8799. from: '3D',
  8800. button: button,
  8801. shift:shift,
  8802. x:x,
  8803. y:y
  8804. })
  8805. });
  8806. //鼠标弹起
  8807. locaSpaceMap.attachEvent("MouseUp",function(button,shift,x,y){
  8808. PubSub.publish('map3D.mouseUp', {
  8809. from: '3D',
  8810. button: button,
  8811. shift:shift,
  8812. x:x,
  8813. y:y
  8814. })
  8815. });
  8816. //鼠标单击
  8817. locaSpaceMap.attachEvent("Click",function(){
  8818. PubSub.publish('map3D.click', {
  8819. from: '3D'
  8820. })
  8821. });
  8822. //鼠标双击
  8823. locaSpaceMap.attachEvent("DblClick",function(){
  8824. PubSub.publish('map3D.dblClick', {
  8825. from: '3D'
  8826. })
  8827. });
  8828. PubSub.subscribe('map2D.setView', function(msg, options) {
  8829. if (options.from == '2D' && map23DData.mouseIn == '2D' && !map3DViewer.hide3D) {
  8830. var newlatlng = window.map23DUtil.latlngsTo3DViewCenter(map23DData.view);
  8831. var map3DHeading = -map23DData.view.heading;
  8832. if(map23DData.view.zoom < 6){
  8833. map23DData.view.tilt = 0;
  8834. }
  8835. locaSpace.JumpTo(
  8836. newlatlng.View3Dlng,
  8837. newlatlng.View3Dlat,
  8838. map3DViewer.getZoomFrom2DZoom(map23DData.view.zoom),
  8839. map3DHeading,
  8840. map23DData.view.tilt
  8841. );
  8842. var cameraState = locaSpaceMap.Globe.CameraState;
  8843. // var mapState = {
  8844. // view: {
  8845. // center: {
  8846. // lat: cameraState.Latitude,
  8847. // lng: cameraState.Longitude
  8848. // },
  8849. // zoom: map3DViewer.getZoomFrom3DZoom(cameraState.Distance),
  8850. // heading: cameraState.Heading,
  8851. // tilt: map23DData.view.tilt,
  8852. // distance: cameraState.Distance
  8853. // }
  8854. // };
  8855. map23DData.view.distance = cameraState.Distance;
  8856. locaSpaceMap.Refresh();
  8857. }
  8858. });
  8859. PubSub.subscribe('map23D.setView', function(msg, options) {
  8860. if (options.from == '23D' && !map3DViewer.hide3D) {
  8861. var newlatlng = window.map23DUtil.latlngsTo3DViewCenter(map23DData.view);
  8862. var map3DHeading = -map23DData.view.heading;
  8863. locaSpace.JumpTo(
  8864. newlatlng.View3Dlng,
  8865. newlatlng.View3Dlat,
  8866. map3DViewer.getZoomFrom2DZoom(map23DData.view.zoom),
  8867. map3DHeading,
  8868. map23DData.view.tilt
  8869. );
  8870. locaSpaceMap.Refresh();
  8871. }
  8872. });
  8873. }
  8874. //显示支持文本的冒泡窗
  8875. map3DViewer.showTextTips = function(options){
  8876. var featureTooltip = locaSpaceMap.CreateBalloon();
  8877. featureTooltip.Create(locaSpaceMap.Handle);
  8878. featureTooltip.SetShadow(0,0,0,false,0,0);
  8879. featureTooltip.CloseButtonVisible = options.closeButtonVisible || false;
  8880. featureTooltip.MaxWidth = options.maxWidth || 100;
  8881. featureTooltip.ShowBalloon1(options.x,options.y,options.content);
  8882. locaSpaceMap.Refresh();
  8883. }
  8884. //显示支持html的冒泡窗
  8885. map3DViewer.showPopup = function(options){
  8886. var featureTooltip = locaSpaceMap.CreateBalloonEx();
  8887. featureTooltip.Create(locaSpaceMap.Handle);
  8888. featureTooltip.SetShadow(0,0,0,false,0,0);
  8889. featureTooltip.CloseButtonVisible = options.closeButtonVisible || true;
  8890. featureTooltip.SetSize(4,(options.width || 200));
  8891. featureTooltip.SetSize(5,(options.height || 100));
  8892. featureTooltip.SetSize(10,0);
  8893. // alert('ROUNDED_CX:'+featureTooltip.GetSize(0))
  8894. // alert('ROUNDED_CY:'+featureTooltip.GetSize(1))
  8895. // alert('MARGIN_CX:'+featureTooltip.GetSize(2))
  8896. // alert('MARGIN_CY:'+featureTooltip.GetSize(3))
  8897. // alert('CONTENT_CX:'+featureTooltip.GetSize(4))
  8898. // alert('CONTENT_CY:'+featureTooltip.GetSize(5))
  8899. // alert('ANCHOR_WIDTH:'+featureTooltip.GetSize(6))
  8900. // alert('ANCHOR_HEIGHT:'+featureTooltip.GetSize(7))
  8901. // alert('ANCHOR_MARGIN:'+featureTooltip.GetSize(8))
  8902. // alert('CLOSEBUTTON_OFFSET:'+featureTooltip.GetSize(9))
  8903. // alert('WINDOWED_OFFSET:'+featureTooltip.GetSize(10))
  8904. options.content = '<style type="text/css">html,body{margin:0px;padding:0px;word-wrap: break-word; word-break: normal;font-size:12px; font-family:"Microsoft Yahei"} *{padding:0px;margin:0px;}</style>'+options.content;
  8905. featureTooltip.ShowBalloon1(options.x,options.y,options.content);
  8906. locaSpaceMap.Refresh();
  8907. }
  8908. map3DViewer.getZoomFrom2DZoom = function(zoom) {
  8909. zoom = zoom || map23DData.view.zoom;
  8910. var RoraTilt = ((map23DData.view.tilt)/180)*Math.PI;
  8911. return this.zoomAry[zoom] * 1000*Math.cos(RoraTilt);
  8912. }
  8913. map3DViewer.getZoomFrom3DZoom = function(distance) {
  8914. distance = distance / 1000;
  8915. for (var i = 0, len = this.zoomAry.length; i < len; i++) {
  8916. var max = (this.zoomAry[i] + this.zoomAry[i - 1]) / 2;
  8917. var min = (this.zoomAry[i] + this.zoomAry[i + 1]) / 2;
  8918. if (distance < max && distance > min) {
  8919. return i;
  8920. }
  8921. }
  8922. }
  8923. map3DViewer.imageOverlay = function(options) {
  8924. switch (options.action) {
  8925. case 'add':
  8926. return addImageOverlay(options);
  8927. break;
  8928. case 'remove':
  8929. return removeImageOverlay(options);
  8930. break;
  8931. case 'update':
  8932. return updateImageOverlay(options);
  8933. break;
  8934. case 'hide':
  8935. return hideImageOverlay(options);
  8936. break;
  8937. case 'show':
  8938. return showImageOverlay(options);
  8939. break;
  8940. }
  8941. }
  8942. function hideImageOverlay(options){
  8943. if (map23DData.imageOverlays[options.guid]) {
  8944. _.merge(map23DData.imageOverlays[options.guid], options);
  8945. PubSub.publishSync('map3D.imageOverlay.hide', options.guid);
  8946. return options.guid;
  8947. } else {
  8948. return false;
  8949. }
  8950. }
  8951. function showImageOverlay(options){
  8952. if (map23DData.imageOverlays[options.guid]) {
  8953. _.merge(map23DData.imageOverlays[options.guid], options);
  8954. PubSub.publishSync('map3D.imageOverlay.show', options.guid);
  8955. return options.guid;
  8956. } else {
  8957. return false;
  8958. }
  8959. }
  8960. function addImageOverlay(options) {
  8961. var guid = options.guid || map23DControl.buildGuid('imageOverlay23D');
  8962. if(options.guid){
  8963. guid = 'imageOverlay3D_'+guid;
  8964. }
  8965. var defaultData = _.cloneDeep(map23DDefaultData.imageOverlay)
  8966. defaultData.guid = guid;
  8967. _.merge(defaultData, options);
  8968. map23DData.imageOverlays[guid] = defaultData;
  8969. PubSub.publishSync('map3D.imageOverlay.add', guid);
  8970. return guid;
  8971. }
  8972. /**
  8973. * 移除图层组,移除前先清除图层组中的元素
  8974. * @param {[type]} options [description]
  8975. * @return {[type]} [description]
  8976. */
  8977. function removeImageOverlay(options) {
  8978. if (map23DData.imageOverlays[options.guid]) {
  8979. PubSub.publishSync('map3D.imageOverlay.remove', options.guid);
  8980. delete map23DData.imageOverlays[options.guid];
  8981. return options.guid;
  8982. } else {
  8983. return false;
  8984. }
  8985. }
  8986. function updateImageOverlay(options) {
  8987. if (map23DData.imageOverlays[options.guid]) {
  8988. _.merge(map23DData.imageOverlays[options.guid], options);
  8989. PubSub.publishSync('map3D.imageOverlay.update', options.guid);
  8990. return options.guid;
  8991. } else {
  8992. return false;
  8993. }
  8994. }
  8995. /**
  8996. * 获取3D视角中心点
  8997. */
  8998. map3DViewer.get3DViewCenter = function(){
  8999. var point = locaSpaceMap.CreatePoint2D();
  9000. var S2dx = $('#map3DWrap').width()/2;//3D视图容器宽度的二分之一
  9001. var S2dy = $('#map3DWrap').height()/2;//3D视图容器高度的二分之一
  9002. point.x = parseInt(S2dx);
  9003. point.y = parseInt(S2dy);
  9004. var result = locaSpaceMap.Globe.ScreenToScene(point);
  9005. return {lng:result.x,
  9006. lat:result.y
  9007. };
  9008. }
  9009. //是否显示经纬网
  9010. map3DViewer.setLatLonGridVisible = function(flag){
  9011. locaSpaceMap.Globe.LatLonGridVisible = flag;
  9012. locaSpaceMap.Refresh();
  9013. }
  9014. //是否显示天空
  9015. map3DViewer.setSkyVisible = function(flag){
  9016. locaSpaceMap.Globe.SkyVisible = flag;
  9017. locaSpaceMap.Refresh();
  9018. }
  9019. //是否显示大气层
  9020. map3DViewer.setAtmosphereVisible = function(flag){
  9021. locaSpaceMap.Globe.Atmosphere.Visible = flag;
  9022. locaSpaceMap.Refresh();
  9023. }
  9024. //是否显示光影效果
  9025. map3DViewer.setShaderAtmosphereUsing = function(flag){
  9026. locaSpaceMap.Globe.Atmosphere.ShaderUsing = flag;
  9027. locaSpaceMap.Refresh();
  9028. }
  9029. //是否显示控制栏
  9030. map3DViewer.setControlPanelVisible = function(flag){
  9031. locaSpaceMap.Globe.ControlPanelVisible = flag;
  9032. locaSpaceMap.Refresh();
  9033. }
  9034. //是否显示状态栏
  9035. map3DViewer.setStatusBarVisible = function(flag){
  9036. locaSpaceMap.Globe.StatusBarVisible = flag;
  9037. locaSpaceMap.Refresh();
  9038. }
  9039. //是否显示海洋
  9040. map3DViewer.setOceanVisible = function(flag){
  9041. locaSpaceMap.Globe.OceanVisible = flag;
  9042. locaSpaceMap.Refresh();
  9043. }
  9044. //是否显示太阳
  9045. map3DViewer.setSunVisible = function(flag){
  9046. locaSpaceMap.Globe.SunVisible = flag;
  9047. locaSpaceMap.Refresh();
  9048. }
  9049. //是否开启下雪效果
  9050. map3DViewer.setSnowVisible = function(flag){
  9051. locaSpaceMap.Globe.SnowVisible = flag;
  9052. locaSpaceMap.Refresh();
  9053. }
  9054. //是否开启下雨效果
  9055. map3DViewer.setRainVisible = function(flag){
  9056. locaSpaceMap.Globe.RainVisible = flag;
  9057. locaSpaceMap.Refresh();
  9058. }
  9059. //是否显示云层
  9060. map3DViewer.setCloudsVisible = function(flag){
  9061. locaSpaceMap.Globe.CloudsVisible = flag;
  9062. locaSpaceMap.Refresh();
  9063. }
  9064. //是否显示预览小地图
  9065. map3DViewer.setOverviewControl = function(flag){
  9066. locaSpaceMap.Globe.OverviewControl.Visible = flag;
  9067. locaSpaceMap.Refresh();
  9068. }
  9069. //跳转到指定位置
  9070. map3DViewer.setView = function(options) {
  9071. _.merge(map23DData.view, options);
  9072. var newlatlng = window.map23DUtil.latlngsTo3DViewCenter(map23DData.view);
  9073. var map3DHeading = -map23DData.view.heading;
  9074. locaSpace.JumpTo(
  9075. newlatlng.View3Dlng,
  9076. newlatlng.View3Dlat,
  9077. map23DData.view.distance,
  9078. map3DHeading,
  9079. map23DData.view.tilt
  9080. );
  9081. locaSpaceMap.Refresh();
  9082. map23DData.mouseIn = '3D';
  9083. PubSub.publish('map3D.setView', {
  9084. from: '3D'
  9085. })
  9086. }
  9087. //飞行到指定位置
  9088. map3DViewer.flyTo = function(options) {
  9089. _.merge(map23DData.view, options);
  9090. var newlatlng = window.map23DUtil.latlngsTo3DViewCenter(map23DData.view);
  9091. var map3DHeading = -map23DData.view.heading;
  9092. //longitude, latitude, altitude, dHeading, dTilt, dDistance, altMode
  9093. locaSpace.FlyTo(
  9094. newlatlng.View3Dlng,
  9095. newlatlng.View3Dlat,
  9096. map3DViewer.getZoomFrom2DZoom(map23DData.view.zoom),
  9097. map3DHeading,
  9098. map23DData.view.tilt,
  9099. 0,
  9100. 1
  9101. );
  9102. locaSpaceMap.Refresh();
  9103. map23DData.mouseIn = '3D';
  9104. PubSub.publish('map3D.setView', {
  9105. from: '3D'
  9106. })
  9107. }
  9108. //围绕元素旋转
  9109. map3DViewer.flyAroundFeature = function(feature){
  9110. locaSpaceMap.Globe.FlyAroundFeature(feature);
  9111. }
  9112. //DEM
  9113. map3DViewer.DEMTileLayer = function(options) {
  9114. switch (options.action) {
  9115. case 'add':
  9116. var guid = options.guid || map23DControl.buildGuid('tileLayer3DDEM');
  9117. var defaultData = {
  9118. from: '3D',
  9119. type: 'tileLayer',
  9120. guid: guid,
  9121. layer: {
  9122. url3D: map23DConfig.tileServerUrl + '/dem?z=%d&x=%d&y=%d',
  9123. }
  9124. }
  9125. tileLayerData = _.merge(defaultData, options);
  9126. map23DData.layers[guid] = tileLayerData;
  9127. PubSub.publish('map3D.DEMTileLayer.add', guid);
  9128. return guid;
  9129. break;
  9130. case 'remove':
  9131. var guid = options.guid;
  9132. PubSub.publish('map3D.DEMTileLayer.remove', guid);
  9133. return guid;
  9134. break;
  9135. }
  9136. }
  9137. //三维模型
  9138. map3DViewer.model = function(options) {
  9139. switch (options.action) {
  9140. case 'add':
  9141. var guid = options.guid || map23DControl.buildGuid('model3D');
  9142. if(options.guid){
  9143. guid = 'model3D_'+guid;
  9144. }
  9145. var defaultData = _.cloneDeep(map23DDefaultData.model)
  9146. defaultData.guid = guid;
  9147. defaultData.from = '3D';
  9148. modelData = _.merge(defaultData, options);
  9149. map23DData.models[guid] = modelData;
  9150. PubSub.publish('map3D.model.add', guid);
  9151. return guid;
  9152. break;
  9153. case 'update':
  9154. var guid = options.guid;
  9155. _.merge(map23DData.models[guid], options);
  9156. PubSub.publish('map3D.model.update', guid);
  9157. return guid;
  9158. break;
  9159. case 'remove':
  9160. var guid = options.guid;
  9161. PubSub.publish('map3D.model.remove', guid);
  9162. return guid;
  9163. break;
  9164. }
  9165. }
  9166. //3D 组
  9167. map3DViewer.group = function(options) {
  9168. switch (options.action) {
  9169. case 'add':
  9170. return addGroup3D(options);
  9171. break;
  9172. case 'remove':
  9173. return removeGroup3D(options);
  9174. break;
  9175. case 'hide':
  9176. return hideGroup3D(options);
  9177. break;
  9178. case 'show':
  9179. return showGroup3D(options);
  9180. break;
  9181. case 'cleanAll':
  9182. return cleanGroupAllFeatures3D(options);
  9183. break;
  9184. }
  9185. }
  9186. function hideGroup3D(options){
  9187. if (map23DData.groups[options.guid]) {
  9188. PubSub.publishSync('map3D.group.hide', options.guid);
  9189. return options.guid;
  9190. } else {
  9191. return false;
  9192. }
  9193. }
  9194. function showGroup3D(options){
  9195. if (map23DData.groups[options.guid]) {
  9196. PubSub.publishSync('map3D.group.show', options.guid);
  9197. return options.guid;
  9198. } else {
  9199. return false;
  9200. }
  9201. }
  9202. function addGroup3D(options) {
  9203. var guid = options.guid || map23DControl.buildGuid('group3D');
  9204. if(options.guid){
  9205. guid = 'group3D_'+guid;
  9206. }
  9207. var defaultData = _.cloneDeep(map23DDefaultData.group)
  9208. defaultData.guid = guid;
  9209. defaultData.from = '3D';
  9210. _.merge(defaultData, options);
  9211. map23DData.groups[guid] = defaultData;
  9212. PubSub.publishSync('map3D.group.add', guid);
  9213. return guid;
  9214. }
  9215. function removeGroup3D(options){
  9216. if (map23DData.groups[options.guid]) {
  9217. cleanGroupAllFeatures3D(options);
  9218. PubSub.publishSync('map3D.group.remove', options.guid);
  9219. if(map23DData.groups[options.guid].add2D == false){
  9220. delete map23DData.groups[options.guid];
  9221. }
  9222. return options.guid;
  9223. } else {
  9224. return false;
  9225. }
  9226. }
  9227. function cleanGroupAllFeatures3D(options) {
  9228. if (map23DData.groups[options.guid]) {
  9229. //移除点
  9230. _(map23DData.markers).forEach(function(item, key) {
  9231. if (item.groupId == options.guid) {
  9232. map3DViewer.marker({
  9233. action: 'remove',
  9234. guid: key
  9235. })
  9236. }
  9237. });
  9238. //移除线
  9239. _(map23DData.polylines).forEach(function(item, key) {
  9240. if (item.groupId == options.guid) {
  9241. map3DViewer.polyline({
  9242. action: 'remove',
  9243. guid: key
  9244. })
  9245. }
  9246. });
  9247. //移除面
  9248. _(map23DData.polygons).forEach(function(item, key) {
  9249. if (item.groupId == options.guid) {
  9250. map3DViewer.polygon({
  9251. action: 'remove',
  9252. guid: key
  9253. })
  9254. }
  9255. });
  9256. //移除圆
  9257. _(map23DData.circles).forEach(function(item, key) {
  9258. if (item.groupId == options.guid) {
  9259. map3DViewer.circle({
  9260. action: 'remove',
  9261. guid: key
  9262. })
  9263. }
  9264. });
  9265. //移除模型
  9266. _(map23DData.models).forEach(function(item, key) {
  9267. if (item.groupId == options.guid) {
  9268. map3DViewer.model({
  9269. action: 'remove',
  9270. guid: key
  9271. })
  9272. }
  9273. });
  9274. return options.guid;
  9275. } else {
  9276. return false
  9277. }
  9278. }
  9279. //3D 点
  9280. map3DViewer.marker = function(options) {
  9281. switch (options.action) {
  9282. case 'add':
  9283. return addMarker3D(options);
  9284. break;
  9285. case 'remove':
  9286. return removeMarker3D(options);
  9287. break;
  9288. case 'update':
  9289. return updateMarker3D(options);
  9290. break;
  9291. }
  9292. }
  9293. function addMarker3D(options) {
  9294. var guid = options.guid || map23DControl.buildGuid('marker3D');
  9295. if(options.guid){
  9296. guid = 'marker3D_'+guid;
  9297. }
  9298. var defaultData = _.cloneDeep(map23DDefaultData.marker)
  9299. defaultData.guid = guid;
  9300. defaultData.from = '3D';
  9301. _.merge(defaultData, options);
  9302. map23DData.markers[guid] = defaultData;
  9303. PubSub.publishSync('map3D.marker.add', guid);
  9304. return guid;
  9305. }
  9306. function removeMarker3D(options) {
  9307. if (map23DData.markers[options.guid]) {
  9308. PubSub.publishSync('map3D.marker.remove', options.guid);
  9309. if(map23DData.markers[options.guid].add2D == false){
  9310. delete map23DData.markers[options.guid];
  9311. }
  9312. return options.guid;
  9313. } else {
  9314. return false;
  9315. }
  9316. }
  9317. function updateMarker3D(options){
  9318. if (map23DData.markers[options.guid]) {
  9319. _.merge(map23DData.markers[options.guid], options);
  9320. PubSub.publishSync('map3D.marker.update', options.guid);
  9321. return options.guid;
  9322. } else {
  9323. return false;
  9324. }
  9325. }
  9326. //3D瓦片图层
  9327. //
  9328. map3DViewer.tileLayer = function(options) {
  9329. switch (options.action) {
  9330. case 'add':
  9331. return addTileLayer3D(options);
  9332. break;
  9333. case 'remove':
  9334. return removeTileLayer3D(options);
  9335. break;
  9336. case 'hide':
  9337. return hideTileLayer3D(options);
  9338. break;
  9339. case 'show':
  9340. return showTileLayer3D(options);
  9341. break;
  9342. case 'update':
  9343. return updateTileLayer3D(options);
  9344. break;
  9345. }
  9346. }
  9347. function updateTileLayer3D(options){
  9348. if (map3DViewer.layers[options.guid]) {
  9349. PubSub.publishSync('map3D.tileLayer.update', options.guid);
  9350. return options.guid;
  9351. } else {
  9352. return false;
  9353. }
  9354. }
  9355. function hideTileLayer3D(options){
  9356. if (map3DViewer.layers[options.guid]) {
  9357. PubSub.publishSync('map3D.tileLayer.hide', options.guid);
  9358. return options.guid;
  9359. } else {
  9360. return false;
  9361. }
  9362. }
  9363. function showTileLayer3D(options){
  9364. if (map3DViewer.layers[options.guid]) {
  9365. PubSub.publishSync('map3D.tileLayer.show', options.guid);
  9366. return options.guid;
  9367. } else {
  9368. return false;
  9369. }
  9370. }
  9371. function addTileLayer3D(options) {
  9372. var guid = options.guid || map23DControl.buildGuid('tileLayer3D');
  9373. if(options.guid){
  9374. guid = 'tileLayer3D_'+guid;
  9375. }
  9376. var defaultData = _.cloneDeep(map23DDefaultData.layer)
  9377. defaultData.guid = guid;
  9378. defaultData.from = '3D';
  9379. _.merge(defaultData, options);
  9380. map23DData.layers[guid] = defaultData;
  9381. PubSub.publishSync('map3D.tileLayer.add', guid);
  9382. return guid;
  9383. }
  9384. /**
  9385. * 移除图层组,移除前先清除图层组中的元素
  9386. * @param {[type]} options [description]
  9387. * @return {[type]} [description]
  9388. */
  9389. function removeTileLayer3D(options) {
  9390. if (map23DData.layers[options.guid]) {
  9391. PubSub.publishSync('map3D.tileLayer.remove', options.guid);
  9392. if(map23DData.layers[options.guid].add2D == false){
  9393. delete map23DData.layers[options.guid];
  9394. }
  9395. return options.guid;
  9396. } else {
  9397. return false;
  9398. }
  9399. }
  9400. //3D绑定Label
  9401. map3DViewer.label = function(options){
  9402. switch (options.action) {
  9403. case 'add':
  9404. return PubSub.publishSync('map3D.label.add', options);
  9405. break;
  9406. case 'remove':
  9407. return PubSub.publishSync('map3D.label.remove', options);
  9408. break;
  9409. case 'update':
  9410. return PubSub.publishSync('map3D.label.update', options);
  9411. break;
  9412. }
  9413. }
  9414. //3D 线
  9415. map3DViewer.polyline = function(options) {
  9416. switch (options.action) {
  9417. case 'add':
  9418. return addPolyline3D(options);
  9419. break;
  9420. case 'remove':
  9421. return removePolyline3D(options);
  9422. break;
  9423. case 'update':
  9424. return updatePolyline3D(options);
  9425. break;
  9426. }
  9427. }
  9428. function addPolyline3D(options) {
  9429. var guid = options.guid || map23DControl.buildGuid('polyline3D');
  9430. if(options.guid){
  9431. guid = 'polyline3D_'+guid;
  9432. }
  9433. var defaultData = _.cloneDeep(map23DDefaultData.polyline)
  9434. defaultData.guid = guid;
  9435. defaultData.from = '3D';
  9436. _.merge(defaultData, options);
  9437. map23DData.polylines[guid] = defaultData;
  9438. PubSub.publishSync('map3D.polyline.add', guid);
  9439. return guid;
  9440. }
  9441. function removePolyline3D(options) {
  9442. if (map23DData.polylines[options.guid]) {
  9443. PubSub.publishSync('map3D.polyline.remove', options.guid);
  9444. if(map23DData.polylines[options.guid].add2D == false){
  9445. delete map23DData.polylines[options.guid];
  9446. }
  9447. return options.guid;
  9448. } else {
  9449. return false;
  9450. }
  9451. }
  9452. function updatePolyline3D(options){
  9453. if (map23DData.polylines[options.guid]) {
  9454. _.merge(map23DData.polylines[options.guid], options);
  9455. PubSub.publishSync('map3D.polyline.update', options.guid);
  9456. return options.guid;
  9457. } else {
  9458. return false;
  9459. }
  9460. }
  9461. //3D 面
  9462. map3DViewer.polygon = function(options) {
  9463. switch (options.action) {
  9464. case 'add':
  9465. return addPolygon3D(options);
  9466. break;
  9467. case 'remove':
  9468. return removePolygon3D(options);
  9469. break;
  9470. case 'update':
  9471. return updatePolygon3D(options);
  9472. break;
  9473. }
  9474. }
  9475. function addPolygon3D(options) {
  9476. var guid = options.guid || map23DControl.buildGuid('polygon3D');
  9477. if(options.guid){
  9478. guid = 'polygon3D_'+guid;
  9479. }
  9480. var defaultData = _.cloneDeep(map23DDefaultData.polyline)
  9481. defaultData.guid = guid;
  9482. defaultData.from = '3D';
  9483. _.merge(defaultData, options);
  9484. map23DData.polygons[guid] = defaultData;
  9485. PubSub.publishSync('map3D.polygon.add', guid);
  9486. return guid;
  9487. }
  9488. function removePolygon3D(options) {
  9489. if (map23DData.polygons[options.guid]) {
  9490. PubSub.publishSync('map3D.polygon.remove', options.guid);
  9491. if(map23DData.polygons[options.guid].add2D == false){
  9492. delete map23DData.polygons[options.guid];
  9493. }
  9494. return options.guid;
  9495. } else {
  9496. return false;
  9497. }
  9498. }
  9499. function updatePolygon3D(options){
  9500. if (map23DData.polygons[options.guid]) {
  9501. _.merge(map23DData.polygons[options.guid], options);
  9502. PubSub.publishSync('map3D.polygon.update', options.guid);
  9503. return options.guid;
  9504. } else {
  9505. return false;
  9506. }
  9507. }
  9508. //3D 圆
  9509. map3DViewer.circle = function(options) {
  9510. switch (options.action) {
  9511. case 'add':
  9512. return addCircle3D(options);
  9513. break;
  9514. case 'remove':
  9515. return removeCircle3D(options);
  9516. break;
  9517. case 'update':
  9518. return updateCircle3D(options);
  9519. break;
  9520. }
  9521. }
  9522. function addCircle3D(options) {
  9523. var guid = options.guid || map23DControl.buildGuid('circle3D');
  9524. if(options.guid){
  9525. guid = 'circle3D_'+guid;
  9526. }
  9527. var defaultData = _.cloneDeep(map23DDefaultData.circle)
  9528. defaultData.guid = guid;
  9529. defaultData.from = '3D';
  9530. _.merge(defaultData, options);
  9531. map23DData.circles[guid] = defaultData;
  9532. PubSub.publishSync('map3D.circle.add', guid);
  9533. return guid;
  9534. }
  9535. function removeCircle3D(options) {
  9536. if (map23DData.circles[options.guid]) {
  9537. PubSub.publishSync('map3D.circle.remove', options.guid);
  9538. if(map23DData.circles[options.guid].add2D == false){
  9539. delete map23DData.circles[options.guid];
  9540. }
  9541. return options.guid;
  9542. } else {
  9543. return false;
  9544. }
  9545. }
  9546. function updateCircle3D(options){
  9547. if (map23DData.circles[options.guid]) {
  9548. _.merge(map23DData.circles[options.guid], options);
  9549. PubSub.publishSync('map3D.circle.update', options.guid);
  9550. return options.guid;
  9551. } else {
  9552. return false;
  9553. }
  9554. }
  9555. }(window, document));
  9556. ;
  9557. (function(window, document, undefined) {
  9558. var group = map23DControl.group;
  9559. if (typeof module === 'object' && typeof module.exports === 'object') {
  9560. module.exports = group;
  9561. } else if (typeof define === 'function' && define.amd) {
  9562. define(group);
  9563. }
  9564. map23DControl.group = function(options) {
  9565. switch (options.action) {
  9566. case 'add':
  9567. return addgroup(options);
  9568. break;
  9569. case 'hide':
  9570. return hidegroup(options);
  9571. break;
  9572. case 'show':
  9573. return showgroup(options);
  9574. break;
  9575. case 'remove':
  9576. return removegroup(options);
  9577. break;
  9578. case 'cleanAll':
  9579. return cleanAllFeatures(options);
  9580. break;
  9581. }
  9582. }
  9583. function hidegroup(options){
  9584. if (map23DData.groups[options.guid]) {
  9585. PubSub.publishSync('map23D.group.hide', options.guid);
  9586. return options.guid;
  9587. } else {
  9588. return false;
  9589. }
  9590. }
  9591. function showgroup(options){
  9592. if (map23DData.groups[options.guid]) {
  9593. PubSub.publishSync('map23D.group.show', options.guid);
  9594. return options.guid;
  9595. } else {
  9596. return false;
  9597. }
  9598. }
  9599. function addgroup(options) {
  9600. var guid = options.guid || map23DControl.buildGuid('group23D');
  9601. if(options.guid){
  9602. guid = 'group23D_'+guid;
  9603. }
  9604. var defaultData = _.cloneDeep(map23DDefaultData.group)
  9605. defaultData.guid = guid;
  9606. _.merge(defaultData, options);
  9607. map23DData.groups[guid] = defaultData;
  9608. PubSub.publishSync('map23D.group.add', guid);
  9609. return guid;
  9610. }
  9611. /**
  9612. * 移除图层组,移除前先清除图层组中的元素
  9613. * @param {[type]} options [description]
  9614. * @return {[type]} [description]
  9615. */
  9616. function removegroup(options) {
  9617. if (map23DData.groups[options.guid]) {
  9618. cleanAllFeatures(options);
  9619. PubSub.publishSync('map23D.group.remove', options.guid);
  9620. delete map23DData.groups[options.guid];
  9621. return options.guid;
  9622. } else {
  9623. return false;
  9624. }
  9625. }
  9626. /**
  9627. * 清除图层组元素
  9628. * @param {[type]} options [description]
  9629. * @return {[type]} [description]
  9630. */
  9631. function cleanAllFeatures(options) {
  9632. if (map23DData.groups[options.guid]) {
  9633. //移除点
  9634. _(map23DData.markers).forEach(function(item, key) {
  9635. if (item.groupId == options.guid) {
  9636. map23DControl.marker({
  9637. action: 'remove',
  9638. guid: key
  9639. })
  9640. }
  9641. });
  9642. //移除线
  9643. _(map23DData.polylines).forEach(function(item, key) {
  9644. if (item.groupId == options.guid) {
  9645. map23DControl.polyline({
  9646. action: 'remove',
  9647. guid: key
  9648. })
  9649. }
  9650. });
  9651. //移除面
  9652. _(map23DData.polygons).forEach(function(item, key) {
  9653. if (item.groupId == options.guid) {
  9654. map23DControl.polygon({
  9655. action: 'remove',
  9656. guid: key
  9657. })
  9658. }
  9659. });
  9660. //移除圆
  9661. _(map23DData.circles).forEach(function(item, key) {
  9662. if (item.groupId == options.guid) {
  9663. map23DControl.circle({
  9664. action: 'remove',
  9665. guid: key
  9666. })
  9667. }
  9668. });
  9669. return options.guid;
  9670. } else {
  9671. return false
  9672. }
  9673. }
  9674. }(window, document));
  9675. ;
  9676. (function(window, document, undefined) {
  9677. var imageOverlay = map23DControl.imageOverlay;
  9678. if (typeof module === 'object' && typeof module.exports === 'object') {
  9679. module.exports = imageOverlay;
  9680. } else if (typeof define === 'function' && define.amd) {
  9681. define(imageOverlay);
  9682. }
  9683. map23DControl.imageOverlay = function(options) {
  9684. switch (options.action) {
  9685. case 'add':
  9686. return addImageOverlay(options);
  9687. break;
  9688. case 'remove':
  9689. return removeImageOverlay(options);
  9690. break;
  9691. case 'update':
  9692. return updateImageOverlay(options);
  9693. break;
  9694. case 'hide':
  9695. return hideImageOverlay(options);
  9696. break;
  9697. case 'show':
  9698. return showImageOverlay(options);
  9699. break;
  9700. }
  9701. }
  9702. function hideImageOverlay(options){
  9703. if (map23DData.imageOverlays[options.guid]) {
  9704. _.merge(map23DData.imageOverlays[options.guid], options);
  9705. PubSub.publishSync('map23D.imageOverlay.hide', options.guid);
  9706. return options.guid;
  9707. } else {
  9708. return false;
  9709. }
  9710. }
  9711. function showImageOverlay(options){
  9712. if (map23DData.imageOverlays[options.guid]) {
  9713. _.merge(map23DData.imageOverlays[options.guid], options);
  9714. PubSub.publishSync('map23D.imageOverlay.show', options.guid);
  9715. return options.guid;
  9716. } else {
  9717. return false;
  9718. }
  9719. }
  9720. function addImageOverlay(options) {
  9721. var guid = options.guid || map23DControl.buildGuid('imageOverlay23D');
  9722. if(options.guid){
  9723. guid = 'imageOverlay23D_'+guid;
  9724. }
  9725. var defaultData = _.cloneDeep(map23DDefaultData.imageOverlay)
  9726. defaultData.guid = guid;
  9727. _.merge(defaultData, options);
  9728. map23DData.imageOverlays[guid] = defaultData;
  9729. PubSub.publishSync('map23D.imageOverlay.add', guid);
  9730. return guid;
  9731. }
  9732. /**
  9733. * 移除图层组,移除前先清除图层组中的元素
  9734. * @param {[type]} options [description]
  9735. * @return {[type]} [description]
  9736. */
  9737. function removeImageOverlay(options) {
  9738. if (map23DData.imageOverlays[options.guid]) {
  9739. PubSub.publishSync('map23D.imageOverlay.remove', options.guid);
  9740. delete map23DData.imageOverlays[options.guid];
  9741. return options.guid;
  9742. } else {
  9743. return false;
  9744. }
  9745. }
  9746. function updateImageOverlay(options) {
  9747. if (map23DData.imageOverlays[options.guid]) {
  9748. _.merge(map23DData.imageOverlays[options.guid], options);
  9749. PubSub.publishSync('map23D.imageOverlay.update', options.guid);
  9750. return options.guid;
  9751. } else {
  9752. return false;
  9753. }
  9754. }
  9755. }(window, document));
  9756. ;
  9757. (function(window, document, undefined) {
  9758. PubSub.subscribe('map23D.imageOverlay.add', add2DimageOverlay);
  9759. PubSub.subscribe('map23D.imageOverlay.remove', remove2DimageOverlay);
  9760. PubSub.subscribe('map23D.imageOverlay.update', update2DimageOverlay);
  9761. PubSub.subscribe('map23D.imageOverlay.show', show2DimageOverlay);
  9762. PubSub.subscribe('map23D.imageOverlay.hide', hide2DimageOverlay);
  9763. PubSub.subscribe('map2D.imageOverlay.add', add2DimageOverlay);
  9764. PubSub.subscribe('map2D.imageOverlay.show', show2DimageOverlay);
  9765. PubSub.subscribe('map2D.imageOverlay.hide', hide2DimageOverlay);
  9766. PubSub.subscribe('map2D.imageOverlay.remove', remove2DimageOverlay);
  9767. PubSub.subscribe('map2D.imageOverlay.update', update2DimageOverlay);
  9768. /**
  9769. * 根据GUID添加图层
  9770. * @param {[type]} msg [description]
  9771. * @param {[type]} guid [description]
  9772. */
  9773. function add2DimageOverlay(msg, guid) {
  9774. if (!map2DViewer.inited) {
  9775. return false;
  9776. }
  9777. var imageOverlayData = map23DData.imageOverlays[guid];
  9778. if (imageOverlayData.from === '3D') {
  9779. return false;
  9780. }
  9781. var corner1 = L.latLng(imageOverlayData.layers.layerBounds[0][1],imageOverlayData.layers.layerBounds[0][0]);
  9782. var corner2 = L.latLng(imageOverlayData.layers.layerBounds[1][1],imageOverlayData.layers.layerBounds[1][0]);
  9783. layerBounds = L.latLngBounds(corner1, corner2);
  9784. var imageOverlay = L.imageOverlay(imageOverlayData.layers.imageUrl2D,layerBounds,{
  9785. opacity: imageOverlayData.layers.opacity
  9786. });
  9787. imageOverlay.guid = guid;
  9788. imageOverlay.addTo(map2DViewer.map);
  9789. map2DViewer.imageOverlays[guid] = imageOverlay;
  9790. imageOverlayData.add2D = true;
  9791. imageOverlayData.visible2D = true;
  9792. }
  9793. function show2DimageOverlay(msg, guid) {
  9794. if (!map2DViewer.inited) {
  9795. return false;
  9796. }
  9797. var imageOverlayData = map23DData.imageOverlays[guid];
  9798. if (imageOverlayData.from === '3D') {
  9799. return false;
  9800. }
  9801. if(imageOverlayData.visible2D){
  9802. return false;
  9803. }
  9804. map2DViewer.imageOverlays[guid].addTo(map2DViewer.map);
  9805. imageOverlayData.visible2D = true;
  9806. }
  9807. function hide2DimageOverlay(msg, guid) {
  9808. if (!map2DViewer.inited) {
  9809. return false;
  9810. }
  9811. var imageOverlayData = map23DData.imageOverlays[guid];
  9812. if (imageOverlayData.from === '3D') {
  9813. return false;
  9814. }
  9815. if(!imageOverlayData.visible2D){
  9816. return false;
  9817. }
  9818. map2DViewer.map.removeLayer(map2DViewer.imageOverlays[guid]);
  9819. imageOverlayData.visible2D = false;
  9820. }
  9821. /**
  9822. * 移除指定GUID的图层
  9823. * @param {[type]} msg [description]
  9824. * @param {[type]} guid [description]
  9825. * @return {[type]} [description]
  9826. */
  9827. function remove2DimageOverlay(msg, guid) {
  9828. if (!map2DViewer.inited) {
  9829. return false;
  9830. }
  9831. var imageOverlayData = map23DData.imageOverlays[guid];
  9832. if (imageOverlayData.from === '3D') {
  9833. return false;
  9834. }
  9835. map2DViewer.map.removeLayer(map2DViewer.imageOverlays[guid]);
  9836. delete map2DViewer.imageOverlays[guid];
  9837. imageOverlayData.add2D = false;
  9838. }
  9839. /**
  9840. * 更新指定GUID的图层
  9841. * @param {[type]} msg [description]
  9842. * @param {[type]} guid [description]
  9843. * @return {[type]} [description]
  9844. */
  9845. function update2DimageOverlay(msg, guid) {
  9846. if (!map2DViewer.inited) {
  9847. return false;
  9848. }
  9849. var imageOverlayData = map23DData.imageOverlays[guid];
  9850. if (imageOverlayData.from === '3D') {
  9851. return false;
  9852. }
  9853. var imageOverlay = map2DViewer.imageOverlays[guid];
  9854. if (imageOverlay.options.opacity != imageOverlayData.layers.opacity) {
  9855. imageOverlay.setOpacity(imageOverlayData.layers.opacity);
  9856. }
  9857. //if (imageOverlay.options._bounds != imageOverlayData.layers.layerBounds) {
  9858. var corner1 = L.latLng(imageOverlayData.layers.layerBounds[0][1],imageOverlayData.layers.layerBounds[0][0]);
  9859. var corner2 = L.latLng(imageOverlayData.layers.layerBounds[1][1],imageOverlayData.layers.layerBounds[1][0]);
  9860. layerBounds = L.latLngBounds(corner1, corner2);
  9861. imageOverlay.setBounds(layerBounds);
  9862. //}
  9863. if (imageOverlay._url != imageOverlayData.layers.imageUrl2D) {
  9864. imageOverlay.setUrl(imageOverlayData.layers.imageUrl2D);
  9865. }
  9866. }
  9867. }(window, document));
  9868. ;
  9869. (function(window, document, undefined) {
  9870. PubSub.subscribe('map23D.imageOverlay.add', add3DimageOverlay);
  9871. PubSub.subscribe('map23D.imageOverlay.remove', remove3DimageOverlay);
  9872. PubSub.subscribe('map23D.imageOverlay.hide', hide3DimageOverlay);
  9873. PubSub.subscribe('map23D.imageOverlay.show', show3DimageOverlay);
  9874. PubSub.subscribe('map23D.imageOverlay.update', update3DimageOverlay);
  9875. PubSub.subscribe('map3D.imageOverlay.add', add3DimageOverlay);
  9876. PubSub.subscribe('map3D.imageOverlay.remove', remove3DimageOverlay);
  9877. PubSub.subscribe('map3D.imageOverlay.hide', hide3DimageOverlay);
  9878. PubSub.subscribe('map3D.imageOverlay.show', show3DimageOverlay);
  9879. PubSub.subscribe('map3D.imageOverlay.update', update3DimageOverlay);
  9880. function hide3DimageOverlay(msg, guid) {
  9881. if (!map3DViewer.inited) {
  9882. return false;
  9883. }
  9884. var imageOverlayData = map23DData.imageOverlays[guid];
  9885. if (imageOverlayData.from === '2D') {
  9886. return false;
  9887. }
  9888. map3DViewer.imageOverlays[guid].Visible = false;
  9889. imageOverlayData.add3D = false;
  9890. locaSpaceMap.Refresh();
  9891. }
  9892. function show3DimageOverlay(msg, guid) {
  9893. if (!map3DViewer.inited) {
  9894. return false;
  9895. }
  9896. var imageOverlayData = map23DData.imageOverlays[guid];
  9897. if (imageOverlayData.from === '2D') {
  9898. return false;
  9899. }
  9900. map3DViewer.imageOverlays[guid].Visible = true;
  9901. imageOverlayData.add3D = true;
  9902. locaSpaceMap.Refresh();
  9903. }
  9904. function update3DimageOverlay(msg, guid){
  9905. if (!map3DViewer.inited) {
  9906. return false;
  9907. }
  9908. var imageOverlayData = map23DData.imageOverlays[guid];
  9909. if (imageOverlayData.from === '2D') {
  9910. return false;
  9911. }
  9912. var geoPolygon = locaSpaceMap.CreateGeoPolygon3D();
  9913. var pnts = locaSpaceMap.CreatePoint3ds();
  9914. pnts.Add(imageOverlayData.layers.layerBounds[0][0], imageOverlayData.layers.layerBounds[1][1], 10000);
  9915. pnts.Add(imageOverlayData.layers.layerBounds[1][0], imageOverlayData.layers.layerBounds[1][1], 10000);
  9916. pnts.Add(imageOverlayData.layers.layerBounds[1][0], imageOverlayData.layers.layerBounds[0][1], 10000);
  9917. pnts.Add(imageOverlayData.layers.layerBounds[0][0], imageOverlayData.layers.layerBounds[0][1], 10000);
  9918. geoPolygon.AddPart(pnts);
  9919. geoPolygon.AltitudeMode = 0;
  9920. //线样式设置
  9921. var newPolygonStyle = locaSpaceMap.CreateSimplePolygonStyle3D();
  9922. var textureParam = locaSpaceMap.CreateTextureParam();
  9923. textureParam.TexturePath = imageOverlayData.layers.imageUrl3D;
  9924. textureParam.MipMapUsed = true;
  9925. newPolygonStyle.OutlineVisible = false;
  9926. newPolygonStyle.TextureParam = textureParam;
  9927. geoPolygon.Style = newPolygonStyle;
  9928. map3DViewer.imageOverlays[guid].Geometry = geoPolygon;
  9929. locaSpaceMap.Refresh();
  9930. };
  9931. function add3DimageOverlay(msg, guid) {
  9932. if (!map3DViewer.inited) {
  9933. return false;
  9934. }
  9935. var imageOverlayData = map23DData.imageOverlays[guid];
  9936. if (imageOverlayData.from === '2D') {
  9937. return false;
  9938. }
  9939. var geoPolygon = locaSpaceMap.CreateGeoPolygon3D();
  9940. var pnts = locaSpaceMap.CreatePoint3ds();
  9941. pnts.Add(imageOverlayData.layers.layerBounds[0][0], imageOverlayData.layers.layerBounds[1][1], 10000);
  9942. pnts.Add(imageOverlayData.layers.layerBounds[1][0], imageOverlayData.layers.layerBounds[1][1], 10000);
  9943. pnts.Add(imageOverlayData.layers.layerBounds[1][0], imageOverlayData.layers.layerBounds[0][1], 10000);
  9944. pnts.Add(imageOverlayData.layers.layerBounds[0][0], imageOverlayData.layers.layerBounds[0][1], 10000);
  9945. geoPolygon.AddPart(pnts);
  9946. geoPolygon.AltitudeMode = 0;
  9947. //线样式设置
  9948. var newPolygonStyle = locaSpaceMap.CreateSimplePolygonStyle3D();
  9949. var textureParam = locaSpaceMap.CreateTextureParam();
  9950. textureParam.TexturePath = imageOverlayData.layers.imageUrl3D;
  9951. textureParam.MipMapUsed = true;
  9952. newPolygonStyle.OutlineVisible = false;
  9953. newPolygonStyle.TextureParam = textureParam;
  9954. geoPolygon.Style = newPolygonStyle;
  9955. var feature = locaSpaceMap.CreateFeature();
  9956. feature.Geometry = geoPolygon;
  9957. feature.name = guid;
  9958. var imageOverlay = locaSpaceMap.Globe.MemoryLayer.AddFeature(feature);
  9959. map3DViewer.imageOverlays[guid] = imageOverlay;
  9960. imageOverlayData.add3D = true;
  9961. locaSpaceMap.Refresh();
  9962. };
  9963. function remove3DimageOverlay(msg, guid) {
  9964. if (!map3DViewer.inited) {
  9965. return false;
  9966. }
  9967. var imageOverlayData = map23DData.imageOverlays[guid];
  9968. if (imageOverlayData.from === '2D') {
  9969. return false;
  9970. }
  9971. if (map3DViewer.imageOverlays[guid] != null) {
  9972. locaSpace.RemoveFeatureByName(guid);
  9973. }
  9974. delete map3DViewer.imageOverlays[guid];
  9975. imageOverlayData.add3D = false;
  9976. locaSpaceMap.Refresh();
  9977. };
  9978. }(window, document));
  9979. ;
  9980. (function(window, document, undefined) {
  9981. var circle = map23DControl.circle;
  9982. if (typeof module === 'object' && typeof module.exports === 'object') {
  9983. module.exports = circle;
  9984. } else if (typeof define === 'function' && define.amd) {
  9985. define(circle);
  9986. }
  9987. map23DControl.circle = function(options) {
  9988. switch (options.action) {
  9989. case 'add':
  9990. return addCircle(options);
  9991. break;
  9992. case 'remove':
  9993. return removeCircle(options);
  9994. break;
  9995. case 'update':
  9996. return updateCircle(options);
  9997. break;
  9998. }
  9999. }
  10000. function addCircle(options) {
  10001. var guid = options.guid || map23DControl.buildGuid('circle23D');
  10002. if(options.guid){
  10003. guid = 'circle23D_'+guid;
  10004. }
  10005. var defaultData = _.cloneDeep(map23DDefaultData.circle)
  10006. defaultData.guid = guid;
  10007. _.merge(defaultData, options);
  10008. map23DData.circles[guid] = defaultData;
  10009. PubSub.publishSync('map23D.circle.add', guid);
  10010. return guid;
  10011. }
  10012. function removeCircle(options) {
  10013. if (map23DData.circles[options.guid]) {
  10014. PubSub.publishSync('map23D.circle.remove', options.guid);
  10015. delete map23DData.circles[options.guid];
  10016. return options.guid;
  10017. } else {
  10018. return false;
  10019. }
  10020. }
  10021. function updateCircle(options) {
  10022. if (map23DData.circles[options.guid]) {
  10023. _.merge(map23DData.circles[options.guid], options);
  10024. PubSub.publishSync('map23D.circle.update', options.guid);
  10025. return options.guid;
  10026. } else {
  10027. return false
  10028. }
  10029. }
  10030. }(window, document));
  10031. ;
  10032. (function(window, document, undefined) {
  10033. var marker = map23DControl.marker;
  10034. if (typeof module === 'object' && typeof module.exports === 'object') {
  10035. module.exports = marker;
  10036. } else if (typeof define === 'function' && define.amd) {
  10037. define(marker);
  10038. }
  10039. map23DControl.marker = function(options) {
  10040. switch (options.action) {
  10041. case 'add':
  10042. return addMarker(options);
  10043. break;
  10044. case 'remove':
  10045. return removeMarker(options);
  10046. break;
  10047. case 'update':
  10048. return updateMarker(options);
  10049. break;
  10050. case 'show':
  10051. return showMarker(options);
  10052. break;
  10053. case 'hide':
  10054. return hideMarker(options);
  10055. break;
  10056. }
  10057. }
  10058. function showMarker(options){
  10059. var guid = options.guid;
  10060. PubSub.publishSync('map2D.marker.show', guid);
  10061. };
  10062. function hideMarker(options){
  10063. var guid = options.guid;
  10064. PubSub.publishSync('map2D.marker.hide', guid);
  10065. };
  10066. function addMarker(options) {
  10067. var guid = options.guid || map23DControl.buildGuid('marker23D');
  10068. if(options.guid){
  10069. guid = 'marker23D_'+guid;
  10070. }
  10071. if (!options.RBkey) {
  10072. var markerTime = null;
  10073. } else {
  10074. var markerTime = map23DData.polylines[map2DViewer.routeBackGroup[options.RBkey].polyline].geojson.properties.times;
  10075. }
  10076. if(options.vectorMarker){
  10077. var dataSize = options.geojson.properties.baseSize;
  10078. var curZoom = map23DData.view.zoom;
  10079. var scale = Math.pow(2,curZoom-options.geojson.properties.baseZoom);
  10080. options.geojson.properties.iconSize = [dataSize[0]*scale,dataSize[1]*scale];
  10081. options.geojson.properties.iconAnchor = [dataSize[0]*scale/2,dataSize[1]*scale/2];
  10082. options.geojson.properties.popupAnchor = [0,-dataSize[1]*scale];
  10083. }
  10084. var defaultData = _.cloneDeep(map23DDefaultData.marker)
  10085. defaultData.guid = guid;
  10086. defaultData.geojson.properties.markerTime = markerTime;
  10087. _.merge(defaultData, options);
  10088. map23DData.markers[guid] = defaultData;
  10089. PubSub.publishSync('map23D.marker.add', guid);
  10090. return guid;
  10091. }
  10092. function removeMarker(options) {
  10093. if (map23DData.markers[options.guid]) {
  10094. PubSub.publishSync('map23D.marker.remove', options.guid);
  10095. delete map23DData.markers[options.guid];
  10096. return options.guid;
  10097. } else {
  10098. return false;
  10099. }
  10100. }
  10101. function updateMarker(options) {
  10102. if (map23DData.markers[options.guid]) {
  10103. _.merge(map23DData.markers[options.guid], options);
  10104. PubSub.publishSync('map23D.marker.update', options.guid);
  10105. return options.guid;
  10106. } else {
  10107. return false
  10108. }
  10109. }
  10110. }(window, document));
  10111. ;
  10112. (function(window, document, undefined) {
  10113. var polyline = map23DControl.polyline;
  10114. if (typeof module === 'object' && typeof module.exports === 'object') {
  10115. module.exports = polyline;
  10116. } else if (typeof define === 'function' && define.amd) {
  10117. define(polyline);
  10118. }
  10119. map23DControl.polyline = function(options) {
  10120. switch (options.action) {
  10121. case 'add':
  10122. return addPolyline(options);
  10123. break;
  10124. case 'remove':
  10125. return removePolyline(options);
  10126. break;
  10127. case 'update':
  10128. return updatePolyline(options);
  10129. break;
  10130. }
  10131. }
  10132. function addPolyline(options) {
  10133. var guid = options.guid || map23DControl.buildGuid('polyline23D');
  10134. if(options.guid){
  10135. guid = 'polyline23D_'+guid;
  10136. }
  10137. var defaultData = _.cloneDeep(map23DDefaultData.polyline)
  10138. defaultData.guid = guid;
  10139. _.merge(defaultData, options);
  10140. map23DData.polylines[guid] = defaultData;
  10141. PubSub.publishSync('map23D.polyline.add', guid);
  10142. return guid;
  10143. }
  10144. function removePolyline(options) {
  10145. if (map23DData.polylines[options.guid]) {
  10146. PubSub.publishSync('map23D.polyline.remove', options.guid);
  10147. delete map23DData.polylines[options.guid];
  10148. return options.guid;
  10149. } else {
  10150. return false;
  10151. }
  10152. }
  10153. function updatePolyline(options) {
  10154. if (map23DData.polylines[options.guid]) {
  10155. _.merge(map23DData.polylines[options.guid], options);
  10156. PubSub.publishSync('map23D.polyline.update', options.guid);
  10157. return options.guid;
  10158. } else {
  10159. return false
  10160. }
  10161. }
  10162. }(window, document));
  10163. ;
  10164. (function(window, document, undefined) {
  10165. var polygon = map23DControl.polygon;
  10166. if (typeof module === 'object' && typeof module.exports === 'object') {
  10167. module.exports = polygon;
  10168. } else if (typeof define === 'function' && define.amd) {
  10169. define(polygon);
  10170. }
  10171. map23DControl.polygon = function(options) {
  10172. switch (options.action) {
  10173. case 'add':
  10174. return addPolygon(options);
  10175. break;
  10176. case 'remove':
  10177. return removePolygon(options);
  10178. break;
  10179. case 'update':
  10180. return updatePolygon(options);
  10181. break;
  10182. }
  10183. }
  10184. function addPolygon(options) {
  10185. var guid = options.guid || map23DControl.buildGuid('polygon23D');
  10186. if(options.guid){
  10187. guid = 'polygon23D_'+guid;
  10188. }
  10189. var defaultData = _.cloneDeep(map23DDefaultData.polygon)
  10190. defaultData.guid = guid;
  10191. _.merge(defaultData, options);
  10192. map23DData.polygons[guid] = defaultData;
  10193. PubSub.publishSync('map23D.polygon.add', guid);
  10194. return guid;
  10195. }
  10196. function removePolygon(options) {
  10197. if (map23DData.polygons[options.guid]) {
  10198. PubSub.publishSync('map23D.polygon.remove', options.guid);
  10199. delete map23DData.polygons[options.guid];
  10200. return options.guid;
  10201. } else {
  10202. return false;
  10203. }
  10204. }
  10205. function updatePolygon(options) {
  10206. if (map23DData.polygons[options.guid]) {
  10207. _.merge(map23DData.polygons[options.guid], options);
  10208. PubSub.publishSync('map23D.polygon.update', options.guid);
  10209. return options.guid;
  10210. } else {
  10211. return false
  10212. }
  10213. }
  10214. }(window, document));
  10215. ;
  10216. (function(window, document, undefined) {
  10217. var tileLayer = map23DControl.tileLayer;
  10218. if (typeof module === 'object' && typeof module.exports === 'object') {
  10219. module.exports = tileLayer;
  10220. } else if (typeof define === 'function' && define.amd) {
  10221. define(tileLayer);
  10222. }
  10223. map23DControl.tileLayer = function(options) {
  10224. switch (options.action) {
  10225. case 'add':
  10226. return addTileLayer(options);
  10227. break;
  10228. case 'remove':
  10229. return removeTileLayer(options);
  10230. break;
  10231. case 'update':
  10232. return updateTileLayer(options);
  10233. break;
  10234. case 'hide':
  10235. return hideTileLayer(options);
  10236. break;
  10237. case 'show':
  10238. return showTileLayer(options);
  10239. break;
  10240. }
  10241. }
  10242. function hideTileLayer(options){
  10243. if (map23DData.layers[options.guid]) {
  10244. _.merge(map23DData.layers[options.guid], options);
  10245. PubSub.publishSync('map23D.tileLayer.hide', options.guid);
  10246. return options.guid;
  10247. } else {
  10248. return false;
  10249. }
  10250. }
  10251. function showTileLayer(options){
  10252. if (map23DData.layers[options.guid]) {
  10253. _.merge(map23DData.layers[options.guid], options);
  10254. PubSub.publishSync('map23D.tileLayer.show', options.guid);
  10255. return options.guid;
  10256. } else {
  10257. return false;
  10258. }
  10259. }
  10260. function addTileLayer(options) {
  10261. var guid = options.guid || map23DControl.buildGuid('tileLayer23D');
  10262. if(options.guid){
  10263. guid = 'tileLayer23D_'+guid;
  10264. }
  10265. var defaultData = _.cloneDeep(map23DDefaultData.layer)
  10266. defaultData.guid = guid;
  10267. _.merge(defaultData, options);
  10268. map23DData.layers[guid] = defaultData;
  10269. PubSub.publishSync('map23D.tileLayer.add', guid);
  10270. return guid;
  10271. }
  10272. /**
  10273. * 移除图层组,移除前先清除图层组中的元素
  10274. * @param {[type]} options [description]
  10275. * @return {[type]} [description]
  10276. */
  10277. function removeTileLayer(options) {
  10278. if (map23DData.layers[options.guid]) {
  10279. PubSub.publishSync('map23D.tileLayer.remove', options.guid);
  10280. delete map23DData.layers[options.guid];
  10281. return options.guid;
  10282. } else {
  10283. return false;
  10284. }
  10285. }
  10286. function updateTileLayer(options) {
  10287. if (map23DData.layers[options.guid]) {
  10288. _.merge(map23DData.layers[options.guid], options);
  10289. PubSub.publishSync('map23D.tileLayer.update', options.guid);
  10290. return options.guid;
  10291. } else {
  10292. return false;
  10293. }
  10294. }
  10295. }(window, document));
  10296. ;
  10297. (function(window, document, undefined) {
  10298. PubSub.subscribe('map23D.group.add', add2Dgroup);
  10299. PubSub.subscribe('map23D.group.remove', remove2Dgroup);
  10300. PubSub.subscribe('map23D.group.show', show2Dgroup);
  10301. PubSub.subscribe('map23D.group.hide', hide2Dgroup);
  10302. PubSub.subscribe('map2D.group.add', add2Dgroup);
  10303. PubSub.subscribe('map2D.group.show', show2Dgroup);
  10304. PubSub.subscribe('map2D.group.hide', hide2Dgroup);
  10305. PubSub.subscribe('map2D.group.remove', remove2Dgroup);
  10306. function add2Dgroup(msg, guid) {
  10307. if (!map2DViewer.inited) {
  10308. return false;
  10309. }
  10310. var groupData = map23DData.groups[guid];
  10311. if (groupData.from === '3D') {
  10312. return false;
  10313. }
  10314. if (groupData.clustering) {
  10315. var group = L.markerClusterGroup(groupData.clusterOptions);
  10316. } else {
  10317. var group = L.featureGroup();
  10318. }
  10319. group.guid = guid;
  10320. group.addTo(map2DViewer.map);
  10321. map2DViewer.groups[guid] = group;
  10322. groupData.add2D = true;
  10323. groupData.visible2D = true;
  10324. }
  10325. function show2Dgroup(msg, guid) {
  10326. if (!map2DViewer.inited) {
  10327. return false;
  10328. }
  10329. var groupData = map23DData.groups[guid];
  10330. if (groupData.from === '3D') {
  10331. return false;
  10332. }
  10333. if (groupData.visible2D) {
  10334. return false;
  10335. }
  10336. map2DViewer.groups[guid].addTo(map2DViewer.map);
  10337. groupData.visible2D = true;
  10338. }
  10339. function hide2Dgroup(msg, guid) {
  10340. if (!map2DViewer.inited) {
  10341. return false;
  10342. }
  10343. var groupData = map23DData.groups[guid];
  10344. if (groupData.from === '3D') {
  10345. return false;
  10346. }
  10347. if (!groupData.visible2D) {
  10348. return false;
  10349. }
  10350. map2DViewer.map.removeLayer(map2DViewer.groups[guid]);
  10351. groupData.visible2D = false;
  10352. }
  10353. function remove2Dgroup(msg, guid) {
  10354. if (!map2DViewer.inited) {
  10355. return false;
  10356. }
  10357. var groupData = map23DData.groups[guid];
  10358. if (groupData.from === '3D') {
  10359. return false;
  10360. }
  10361. map2DViewer.map.removeLayer(map2DViewer.groups[guid]);
  10362. delete map2DViewer.groups[guid];
  10363. groupData.add2D = false;
  10364. }
  10365. }(window, document));
  10366. ;
  10367. (function(window, document, undefined) {
  10368. PubSub.subscribe('map23D.group.add', add3Dgroup);
  10369. PubSub.subscribe('map23D.group.remove', remove3Dgroup);
  10370. PubSub.subscribe('map23D.group.show', show3Dgroup);
  10371. PubSub.subscribe('map23D.group.hide', hide3Dgroup);
  10372. PubSub.subscribe('map3D.group.hide', hide3Dgroup);
  10373. PubSub.subscribe('map3D.group.show', show3Dgroup);
  10374. PubSub.subscribe('map3D.group.add', add3Dgroup);
  10375. PubSub.subscribe('map3D.group.remove', remove3Dgroup);
  10376. function hide3Dgroup(msg, guid){
  10377. if (!map3DViewer.inited) {
  10378. return false;
  10379. }
  10380. var groupData = map23DData.groups[guid];
  10381. if (groupData.from === '2D') {
  10382. return false;
  10383. }
  10384. map3DViewer.groups[guid].Visible = false;
  10385. locaSpaceMap.Refresh();
  10386. };
  10387. function show3Dgroup(msg, guid){
  10388. if (!map3DViewer.inited) {
  10389. return false;
  10390. }
  10391. var groupData = map23DData.groups[guid];
  10392. if (groupData.from === '2D') {
  10393. return false;
  10394. }
  10395. map3DViewer.groups[guid].Visible = true;
  10396. locaSpaceMap.Refresh();
  10397. };
  10398. function add3Dgroup(msg, guid) {
  10399. if (!map3DViewer.inited) {
  10400. return false;
  10401. }
  10402. var groupData = map23DData.groups[guid];
  10403. if (groupData.from === '2D') {
  10404. return false;
  10405. }
  10406. var group = locaSpaceMap.Globe.Layers.Add1(guid + ".lgd");
  10407. map3DViewer.groups[guid] = group;
  10408. groupData.add3D = true;
  10409. locaSpaceMap.Refresh();
  10410. };
  10411. function remove3Dgroup(msg, guid) {
  10412. if (!map3DViewer.inited) {
  10413. return false;
  10414. }
  10415. var groupData = map23DData.groups[guid];
  10416. if (groupData.from === '2D') {
  10417. return false;
  10418. }
  10419. if (map3DViewer.groups[guid] != null) {
  10420. locaSpaceMap.Globe.Layers.RemoveLayerByID(map3DViewer.groups[guid].ID);
  10421. }
  10422. delete map3DViewer.groups[guid];
  10423. groupData.add3D = false;
  10424. locaSpaceMap.Refresh();
  10425. };
  10426. }(window, document));
  10427. ;
  10428. (function(window, document, undefined) {
  10429. PubSub.subscribe('map23D.marker.add', add2Dmarker);
  10430. PubSub.subscribe('map23D.marker.remove', remove2Dmarker);
  10431. PubSub.subscribe('map23D.marker.update', update2Dmarker);
  10432. PubSub.subscribe('map2D.marker.add', add2Dmarker);
  10433. PubSub.subscribe('map2D.marker.show', show2Dmarker);
  10434. PubSub.subscribe('map2D.marker.hide', hide2Dmarker);
  10435. PubSub.subscribe('map2D.marker.remove', remove2Dmarker);
  10436. PubSub.subscribe('map2D.marker.update', update2Dmarker);
  10437. function marker_icon(markerData) {
  10438. if (markerData.geojson.properties.fontIcon) {
  10439. var icon_html = '<div width="' + markerData.geojson.properties.iconSize[0] + '" \
  10440. height="' + markerData.geojson.properties.iconSize[1] + '" \
  10441. style="color:' + markerData.geojson.properties.fontColor + ';\
  10442. line-height:1;\
  10443. font-weight:' + markerData.geojson.properties.fontWeight + '; \
  10444. font-size:' + markerData.geojson.properties.fontSize + 'px; \
  10445. -webkit-transform: rotate(' + markerData.geojson.properties.iconRorate + 'deg); \
  10446. transform-origin:' + markerData.geojson.properties.iconAnchor[0] + 'px ' + markerData.geojson.properties.iconAnchor[1] + 'px;\
  10447. -ms-transform-origin:' + markerData.geojson.properties.iconAnchor[0] + 'px ' + markerData.geojson.properties.iconAnchor[1] + 'px;\
  10448. -moz-transform:rotate(' + markerData.geojson.properties.iconRorate + 'deg);\
  10449. -ms-transform:rotate(' + markerData.geojson.properties.iconRorate + 'deg);">' + markerData.geojson.properties.fontIcon +
  10450. '</div>';
  10451. } else {
  10452. var icon_html = '<img width="' + markerData.geojson.properties.iconSize[0] + '" \
  10453. height="' + markerData.geojson.properties.iconSize[1] + '" \
  10454. src="' + markerData.geojson.properties.iconUrl + '" \
  10455. style=" -webkit-transform: rotate(' + markerData.geojson.properties.iconRorate + 'deg); \
  10456. transform-origin:' + markerData.geojson.properties.iconAnchor[0] + 'px ' + markerData.geojson.properties.iconAnchor[1] + 'px;\
  10457. -ms-transform-origin:' + markerData.geojson.properties.iconAnchor[0] + 'px ' + markerData.geojson.properties.iconAnchor[1] + 'px;\
  10458. -moz-transform:rotate(' + markerData.geojson.properties.iconRorate + 'deg);\
  10459. -ms-transform:rotate(' + markerData.geojson.properties.iconRorate + 'deg);" />';
  10460. }
  10461. return icon_html;
  10462. }
  10463. function add2Dmarker(msg, guid) {
  10464. if (!map2DViewer.inited) {
  10465. return false;
  10466. }
  10467. var markerData = map23DData.markers[guid];
  10468. if (markerData.from === '3D') {
  10469. return false;
  10470. }
  10471. if (markerData['animate']) {
  10472. var icon_html = marker_icon(markerData);
  10473. var setDivIcon = L.divIcon({
  10474. className: 'rorate_div',
  10475. html: icon_html,
  10476. iconAnchor: markerData.geojson.properties.iconAnchor,
  10477. iconSize: markerData.geojson.properties.iconSize,
  10478. popupAnchor: markerData.geojson.properties.popupAnchor
  10479. });
  10480. var marker = L.animatedMarker(map2DViewer.polylines[map2DViewer.routeBackGroup[markerData.RBkey].polyline].getLatLngs(), {
  10481. icon: setDivIcon,
  10482. autoStart: markerData.geojson.properties.autoStart,
  10483. interval: markerData.geojson.properties.interval,
  10484. distance: markerData.geojson.properties.distance,
  10485. onEnd: function() {
  10486. marker.stop();
  10487. }
  10488. });
  10489. } else {
  10490. var icon_html = marker_icon(markerData);
  10491. var setDivIcon = L.divIcon({
  10492. className: 'rorate_div',
  10493. html: icon_html,
  10494. iconAnchor: markerData.geojson.properties.iconAnchor,
  10495. iconSize: markerData.geojson.properties.iconSize,
  10496. popupAnchor: markerData.geojson.properties.popupAnchor
  10497. });
  10498. var marker = L.marker(
  10499. map23DUtil.latLngsToReverse(markerData.geojson.geometry.coordinates), {
  10500. icon: setDivIcon,
  10501. title: markerData.geojson.properties.title
  10502. }
  10503. )
  10504. PubSub.subscribe('map2DViewerZoomend',function(){
  10505. if(markerData.vectorMarker){
  10506. setTimeout(function(){
  10507. var dataSize = markerData.geojson.properties.baseSize;
  10508. var curZoom = map2DViewer.map.getZoom();
  10509. if(curZoom>=markerData.geojson.properties.baseZoom){
  10510. var scaleX = dataSize[0]+ dataSize[0]*(curZoom-markerData.geojson.properties.baseZoom);
  10511. var scaleY = dataSize[1]+ dataSize[1]*(curZoom-markerData.geojson.properties.baseZoom);
  10512. }else{
  10513. var scaleX = dataSize[0]*Math.pow(markerData.geojson.properties.baseZoom-curZoom+1,-1);
  10514. var scaleY = dataSize[1]*Math.pow(markerData.geojson.properties.baseZoom-curZoom+1,-1);
  10515. }
  10516. markerData.geojson.properties.iconSize = [scaleX,scaleY];
  10517. markerData.geojson.properties.iconAnchor = [scaleX/2,scaleY/2];
  10518. markerData.geojson.properties.popupAnchor = [0,-scaleY];
  10519. var icon_html = marker_icon(markerData);
  10520. var setDivIcon = L.divIcon({
  10521. className: 'rorate_div',
  10522. html: icon_html,
  10523. iconAnchor: markerData.geojson.properties.iconAnchor,
  10524. iconSize: markerData.geojson.properties.iconSize,
  10525. popupAnchor: markerData.geojson.properties.popupAnchor
  10526. });
  10527. marker.setIcon(setDivIcon);
  10528. },3)
  10529. }
  10530. })
  10531. }
  10532. marker.guid = guid;
  10533. if (markerData.geojson.properties.popupContent) {
  10534. marker.bindPopup(markerData.geojson.properties.popupContent)
  10535. }
  10536. if (markerData.groupId) {
  10537. marker.addTo(map2DViewer.groups[markerData.groupId]);
  10538. } else {
  10539. marker.addTo(map2DViewer.map);
  10540. }
  10541. map2DViewer.markers[guid] = marker;
  10542. markerData.add2D = true;
  10543. markerData.visible2D = true;
  10544. };
  10545. function show2Dmarker(msg, guid) {
  10546. if (!map2DViewer.inited) {
  10547. return false;
  10548. }
  10549. var markerData = map23DData.markers[guid];
  10550. if (markerData.from === '3D') {
  10551. return false;
  10552. }
  10553. if(markerData.visible2D){
  10554. return false;
  10555. }
  10556. if (markerData.groupId) {
  10557. map2DViewer.markers[guid].addTo(map2DViewer.groups[markerData.groupId]);
  10558. } else {
  10559. map2DViewer.markers[guid].addTo(map2DViewer.map);
  10560. }
  10561. markerData.visible2D = true;
  10562. }
  10563. function hide2Dmarker(msg, guid) {
  10564. if (!map2DViewer.inited) {
  10565. return false;
  10566. }
  10567. var markerData = map23DData.markers[guid];
  10568. if (markerData.from === '3D') {
  10569. return false;
  10570. }
  10571. if(!markerData.visible2D){
  10572. return false;
  10573. }
  10574. if (markerData.groupId) {
  10575. map2DViewer.groups[markerData.groupId].removeLayer(map2DViewer.markers[guid]);
  10576. } else {
  10577. map2DViewer.map.removeLayer(map2DViewer.markers[guid]);
  10578. }
  10579. markerData.visible2D = false;
  10580. }
  10581. function remove2Dmarker(msg, guid) {
  10582. if (!map2DViewer.inited) {
  10583. return false;
  10584. }
  10585. var markerData = map23DData.markers[guid];
  10586. if (markerData.from === '3D') {
  10587. return false;
  10588. }
  10589. if (markerData.groupId) {
  10590. map2DViewer.groups[markerData.groupId].removeLayer(map2DViewer.markers[guid]);
  10591. } else {
  10592. map2DViewer.map.removeLayer(map2DViewer.markers[guid]);
  10593. }
  10594. delete map2DViewer.markers[guid];
  10595. markerData.add2D = false;
  10596. };
  10597. function update2Dmarker(msg, guid) {
  10598. if (!map2DViewer.inited) {
  10599. return false;
  10600. }
  10601. if (map23DData.markers[guid]) {
  10602. var markerData = map23DData.markers[guid];
  10603. if (markerData.from === '3D') {
  10604. return false;
  10605. }
  10606. var marker = map2DViewer.markers[guid];
  10607. marker.setLatLng(map23DUtil.latLngsToReverse(markerData.geojson.geometry.coordinates));
  10608. var icon_html = marker_icon(markerData);
  10609. var setDivIcon = L.divIcon({
  10610. className: 'rorate_div',
  10611. html: icon_html,
  10612. iconAnchor: markerData.geojson.properties.iconAnchor,
  10613. iconSize: markerData.geojson.properties.iconSize,
  10614. popupAnchor: markerData.geojson.properties.popupAnchor
  10615. });
  10616. marker.setIcon(setDivIcon);
  10617. if (markerData.geojson.properties.popupContent) {
  10618. marker.bindPopup(markerData.geojson.properties.popupContent)
  10619. }
  10620. }
  10621. };
  10622. }(window, document));
  10623. ;
  10624. (function(window, document, undefined) {
  10625. PubSub.subscribe('map23D.marker.add', add3Dmarker);
  10626. PubSub.subscribe('map23D.marker.remove', remove3Dmarker);
  10627. PubSub.subscribe('map23D.marker.update', update3Dmarker);
  10628. PubSub.subscribe('map3D.marker.add', add3Dmarker);
  10629. PubSub.subscribe('map3D.marker.remove', remove3Dmarker);
  10630. PubSub.subscribe('map3D.marker.update', update3Dmarker);
  10631. function add3Dmarker(msg, guid) {
  10632. if (!map3DViewer.inited) {
  10633. return false;
  10634. }
  10635. var markerData = map23DData.markers[guid];
  10636. if (markerData.from === '2D') {
  10637. return false;
  10638. }
  10639. var marker = getMarkerStyle(markerData);
  10640. var markerFeature = locaSpaceMap.CreateFeature();
  10641. markerFeature.Geometry = marker;
  10642. markerFeature.Name = guid;
  10643. markerFeature.Visible = true;
  10644. if (markerData.groupId) {
  10645. var groupLayer = locaSpaceMap.Globe.Layers.GetLayerByCaption(markerData.groupId);
  10646. groupLayer.AddFeature(markerFeature);
  10647. } else {
  10648. locaSpaceMap.Globe.MemoryLayer.AddFeature(markerFeature);
  10649. }
  10650. map3DViewer.markers[guid] = markerFeature;
  10651. markerData.add3D = true;
  10652. locaSpaceMap.Refresh();
  10653. };
  10654. function getMarkerStyle(markerData){
  10655. var marker = locaSpaceMap.CreateGeoMarker();
  10656. //图标设置
  10657. var markerStyle = locaSpaceMap.CreateMarkerStyle3D();
  10658. markerStyle.IconPath = markerData.geojson.properties.icon3DUrl || markerData.geojson.properties.iconUrl;
  10659. markerStyle.IconPath = markerStyle.IconPath.replace('https://','http://');
  10660. markerStyle.IconScale = markerData.geojson.properties.iconScale;
  10661. markerStyle.IconAvoidance = true;
  10662. //文字设置
  10663. var newTextStyle = locaSpaceMap.CreateTextStyle();
  10664. newTextStyle.FontSize = markerData.geojson.properties.titleFontSize; //字体大小
  10665. newTextStyle.FontWeight = 22;
  10666. var newColor = locaSpaceMap.CreateColorRGBA();
  10667. var newColorRGB = new Color(markerData.geojson.properties.titleColor, 1);
  10668. var newColorRGBAry = newColorRGB.rgbData();
  10669. newColor.SetValue(newColorRGBAry[0], newColorRGBAry[1], newColorRGBAry[2], 250);
  10670. newTextStyle.ForeColor = newColor; //把设置的颜色赋值给字体颜色
  10671. var outlineColor = locaSpaceMap.CreateColorRGBA();
  10672. outlineColor.SetValue(0, 0, 0, 250);
  10673. newTextStyle.OutlineColor = outlineColor;
  10674. newTextStyle.FontName = 'Microsoft Yahei';
  10675. markerStyle.TextStyle = newTextStyle;
  10676. markerStyle.TextVisible = true;
  10677. marker.Text = markerData.geojson.properties.title || '';
  10678. //newTextStyle.Alignment = 1;
  10679. //属性设置
  10680. marker.Style = markerStyle;
  10681. marker.X = markerData.geojson.geometry.coordinates[0];
  10682. marker.Y = markerData.geojson.geometry.coordinates[1];
  10683. marker.Z = markerData.geojson.properties.altitude;
  10684. marker.AltitudeMode = markerData.geojson.properties.altitudeMode;
  10685. return marker;
  10686. }
  10687. function remove3Dmarker(msg, guid) {
  10688. if (!map3DViewer.inited) {
  10689. return false;
  10690. }
  10691. var markerData = map23DData.markers[guid];
  10692. if (markerData.from === '2D') {
  10693. return false;
  10694. }
  10695. if (markerData.groupId) {
  10696. locaSpace.RemoveFeatureByName(guid, markerData.groupId);
  10697. } else {
  10698. locaSpace.RemoveFeatureByName(guid);
  10699. }
  10700. delete map3DViewer.markers[guid];
  10701. markerData.add3D = false;
  10702. locaSpaceMap.Refresh();
  10703. };
  10704. function update3Dmarker(msg, guid) {
  10705. if (!map3DViewer.inited) {
  10706. return false;
  10707. }
  10708. if (map23DData.markers[guid]) {
  10709. var markerData = map23DData.markers[guid];
  10710. if (markerData.from === '2D') {
  10711. return false;
  10712. }
  10713. var markerStyle = getMarkerStyle(markerData);
  10714. var marker = map3DViewer.markers[guid];
  10715. marker.Geometry = markerStyle;
  10716. //marker.Label.Visible = true;
  10717. locaSpaceMap.Refresh();
  10718. }
  10719. };
  10720. }(window, document));
  10721. ;
  10722. (function(window, document, undefined) {
  10723. PubSub.subscribe('map23D.polyline.add', add2Dpolyline);
  10724. PubSub.subscribe('map23D.polyline.remove', remove2Dplyline);
  10725. PubSub.subscribe('map23D.polyline.update', update2Dpolyline);
  10726. PubSub.subscribe('map2D.polyline.add', add2Dpolyline);
  10727. PubSub.subscribe('map2D.polyline.show', show2Dpolyline);
  10728. PubSub.subscribe('map2D.polyline.hide', hide2Dpolyline);
  10729. PubSub.subscribe('map2D.polyline.remove', remove2Dplyline);
  10730. PubSub.subscribe('map2D.polyline.update', update2Dpolyline);
  10731. function add2Dpolyline(msg, guid) {
  10732. if (!map2DViewer.inited) {
  10733. return false;
  10734. }
  10735. var polylineData = map23DData.polylines[guid];
  10736. if (polylineData.from === '3D') {
  10737. return false;
  10738. }
  10739. /*for(var i=0;i<polylineData.geojson.geometry.coordinates.length;i++){
  10740. if(polylineData.geojson.geometry.coordinates[i][0]<=0){
  10741. polylineData.geojson.geometry.coordinates[i][0] = 360+polylineData.geojson.geometry.coordinates[i][0];
  10742. }
  10743. }*/
  10744. var polyline = L.polyline(
  10745. map23DUtil.latLngsToReverse(polylineData.geojson.geometry.coordinates), {
  10746. color: polylineData.geojson.properties.color,
  10747. weight: polylineData.geojson.properties.weight,
  10748. opacity: polylineData.geojson.properties.opacity,
  10749. title: polylineData.geojson.properties.title,
  10750. dashArray: polylineData.geojson.properties.dashArray,
  10751. lineJoin: polylineData.geojson.properties.lineJoin,
  10752. lineCap: polylineData.geojson.properties.lineCap
  10753. }
  10754. )
  10755. if(polylineData.linetype === "circleline"){
  10756. L.Util.circleDrawLatlng(polyline);
  10757. }
  10758. polyline.guid = guid;
  10759. polyline.linetype = polylineData.linetype;
  10760. if (polylineData.geojson.properties.popupContent) {
  10761. polyline.bindPopup(polylineData.geojson.properties.popupContent)
  10762. }
  10763. if (polylineData.groupId) {
  10764. polyline.addTo(map2DViewer.groups[polylineData.groupId]);
  10765. } else {
  10766. polyline.addTo(map2DViewer.map);
  10767. }
  10768. map2DViewer.polylines[guid] = polyline;
  10769. polylineData.add2D = true;
  10770. polylineData.visible2D = true;
  10771. };
  10772. function show2Dpolyline(msg, guid) {
  10773. if (!map2DViewer.inited) {
  10774. return false;
  10775. }
  10776. var polylineData = map23DData.polylines[guid];
  10777. if (polylineData.from === '3D') {
  10778. return false;
  10779. }
  10780. if(polylineData.visible2D){
  10781. return false;
  10782. }
  10783. if (polylineData.groupId) {
  10784. map2DViewer.polylines[guid].addTo(map2DViewer.groups[polylineData.groupId]);
  10785. } else {
  10786. map2DViewer.polylines[guid].addTo(map2DViewer.map);
  10787. }
  10788. polylineData.visible2D = true;
  10789. }
  10790. function hide2Dpolyline(msg, guid) {
  10791. if (!map2DViewer.inited) {
  10792. return false;
  10793. }
  10794. var polylineData = map23DData.polylines[guid];
  10795. if (polylineData.from === '3D') {
  10796. return false;
  10797. }
  10798. if(!polylineData.visible2D){
  10799. return false;
  10800. }
  10801. if (polylineData.groupId) {
  10802. map2DViewer.groups[polylineData.groupId].removeLayer(map2DViewer.polylines[guid]);
  10803. } else {
  10804. map2DViewer.map.removeLayer(map2DViewer.polylines[guid]);
  10805. }
  10806. polylineData.visible2D = false;
  10807. }
  10808. function remove2Dplyline(msg, guid) {
  10809. if (!map2DViewer.inited) {
  10810. return false;
  10811. }
  10812. var polylineData = map23DData.polylines[guid];
  10813. if (polylineData.from === '3D') {
  10814. return false;
  10815. }
  10816. if (polylineData.groupId) {
  10817. map2DViewer.groups[polylineData.groupId].removeLayer(map2DViewer.polylines[guid]);
  10818. } else {
  10819. map2DViewer.map.removeLayer(map2DViewer.polylines[guid]);
  10820. }
  10821. delete map2DViewer.polylines[guid];
  10822. polylineData.add2D = false;
  10823. };
  10824. function update2Dpolyline(msg, guid) {
  10825. if (!map2DViewer.inited) {
  10826. return false;
  10827. }
  10828. var polylineData = map23DData.polylines[guid];
  10829. if (polylineData.from === '3D') {
  10830. return false;
  10831. }
  10832. map2DViewer.polylines[guid].setStyle(
  10833. polylineData.geojson.properties
  10834. );
  10835. if(polylineData.geojson.hasOwnProperty('geometry')){
  10836. if(polylineData.geojson.geometry.coordinates.length > 1){
  10837. map2DViewer.polylines[guid].setLatLngs(map23DUtil.latLngsToReverse(polylineData.geojson.geometry.coordinates));
  10838. }
  10839. }
  10840. if (polylineData.geojson.properties.popupContent) {
  10841. polyline.bindPopup(polylineData.geojson.properties.popupContent)
  10842. }
  10843. };
  10844. }(window, document));
  10845. ;
  10846. (function(window, document, undefined) {
  10847. PubSub.subscribe('map23D.polyline.add', add3Dpolyline);
  10848. PubSub.subscribe('map23D.polyline.remove', remove3Dpolyline);
  10849. PubSub.subscribe('map23D.polyline.update', update3Dpolyline);
  10850. PubSub.subscribe('map3D.polyline.add', add3Dpolyline);
  10851. PubSub.subscribe('map3D.polyline.remove', remove3Dpolyline);
  10852. PubSub.subscribe('map3D.polyline.update', update3Dpolyline);
  10853. function add3Dpolyline(msg, guid) {
  10854. if (!map3DViewer.inited) {
  10855. return false;
  10856. }
  10857. var polylineData = map23DData.polylines[guid];
  10858. if (polylineData.from === '2D') {
  10859. return false;
  10860. }
  10861. var geoNewLine = getPolylineStyle(polylineData);
  10862. var polyline = locaSpaceMap.CreateFeature();
  10863. polyline.Geometry = geoNewLine;
  10864. polyline.Name = guid;
  10865. if (polylineData.groupId) {
  10866. var groupLayer = locaSpaceMap.Globe.Layers.GetLayerByCaption(polylineData.groupId);
  10867. groupLayer.AddFeature(polyline);
  10868. } else {
  10869. locaSpaceMap.Globe.MemoryLayer.AddFeature(polyline);
  10870. }
  10871. map3DViewer.polylines[guid] = polyline;
  10872. polylineData.add3D = true;
  10873. locaSpaceMap.Refresh();
  10874. };
  10875. function getPolylineStyle(polylineData){
  10876. var geoNewLine = locaSpaceMap.CreateGeoPolyline3D();
  10877. var pnts = locaSpaceMap.CreatePoint3ds();
  10878. for (var i = 0, l = polylineData.geojson.geometry.coordinates.length; i < l; i++) {
  10879. pnts.Add(polylineData.geojson.geometry.coordinates[i][0], polylineData.geojson.geometry.coordinates[i][1], polylineData.geojson.properties.altitude[i]);
  10880. }
  10881. geoNewLine.AddPart(pnts);
  10882. geoNewLine.AltitudeMode = polylineData.geojson.properties.altitudeMode; //0紧贴地表 1海拔高度 2相对地表
  10883. //线样式设置
  10884. if(polylineData.geojson.properties.pipe){//管道
  10885. var newLineStyle = locaSpaceMap.CreatePipeLineStyle3D();
  10886. newLineStyle.Radius = polylineData.geojson.properties.radius;
  10887. }else {//非管道
  10888. var newLineStyle = locaSpaceMap.CreateSimpleLineStyle3D();
  10889. }
  10890. var newColor = locaSpaceMap.CreateColorRGBA();
  10891. var newColorRGB = new Color(polylineData.geojson.properties.color, polylineData.geojson.properties.opacity);
  10892. var newColorRGBAry = newColorRGB.rgbData();
  10893. newColor.SetValue(newColorRGBAry[0], newColorRGBAry[1], newColorRGBAry[2], polylineData.geojson.properties.opacity * 250);
  10894. newLineStyle.LineColor = newColor;
  10895. if(!polylineData.geojson.properties.pipe){
  10896. // 线宽设置
  10897. newLineStyle.LineWidth = polylineData.geojson.properties.weight;
  10898. //线样式设置
  10899. newLineStyle.LineType = polylineData.geojson.properties.lineType;
  10900. }
  10901. geoNewLine.Style = newLineStyle;
  10902. if(!polylineData.geojson.properties.pipe){
  10903. //拉伸
  10904. var extrudeStyle = locaSpaceMap.CreateExtrudeStyle();
  10905. var extrudePolygonStyle = locaSpaceMap.CreateSimplePolygonStyle3D();
  10906. var fillColor = locaSpaceMap.CreateColorRGBA();
  10907. var newFillColorRGB = new Color(polylineData.geojson.properties.color, polylineData.geojson.properties.opacity);
  10908. var newFillColorRGBAry = newFillColorRGB.rgbData();
  10909. fillColor.SetValue(newFillColorRGBAry[0], newFillColorRGBAry[1], newFillColorRGBAry[2], polylineData.geojson.properties.opacity * 250);
  10910. // 拉伸颜色填充设置
  10911. extrudePolygonStyle.FillColor = fillColor;
  10912. extrudePolygonStyle.Fill = true;
  10913. extrudeStyle.ExtrudeValue = polylineData.geojson.properties.extrude;
  10914. extrudeStyle.BodyStyle = extrudePolygonStyle;
  10915. geoNewLine.ExtrudeStyle = extrudeStyle;
  10916. }
  10917. return geoNewLine;
  10918. }
  10919. function remove3Dpolyline(msg, guid) {
  10920. if (!map3DViewer.inited) {
  10921. return false;
  10922. }
  10923. var polylineData = map23DData.polylines[guid];
  10924. if (polylineData.from === '2D') {
  10925. return false;
  10926. }
  10927. if (polylineData.groupId) {
  10928. locaSpace.RemoveFeatureByName(guid, polylineData.groupId);
  10929. } else {
  10930. locaSpace.RemoveFeatureByName(guid);
  10931. }
  10932. delete map3DViewer.polylines[guid];
  10933. polylineData.add3D = false;
  10934. locaSpaceMap.Refresh();
  10935. };
  10936. function update3Dpolyline(msg, guid) {
  10937. if (!map3DViewer.inited) {
  10938. return false;
  10939. }
  10940. var polylineData = map23DData.polylines[guid];
  10941. if (polylineData.from === '2D') {
  10942. return false;
  10943. }
  10944. var geoNewLine = getPolylineStyle(polylineData);
  10945. var polyline = map3DViewer.polylines[guid];
  10946. polyline.Geometry = geoNewLine;
  10947. locaSpaceMap.Refresh();
  10948. };
  10949. }(window, document));
  10950. ;
  10951. (function(window, document, undefined) {
  10952. PubSub.subscribe('map23D.polygon.add', add2Dpolygon);
  10953. PubSub.subscribe('map23D.polygon.remove', remove2Dpolygon);
  10954. PubSub.subscribe('map23D.polygon.update', update2Dpolygon);
  10955. PubSub.subscribe('map2D.polygon.add', add2Dpolygon);
  10956. PubSub.subscribe('map2D.polygon.show', show2Dpolygon);
  10957. PubSub.subscribe('map2D.polygon.hide', hide2Dpolygon);
  10958. PubSub.subscribe('map2D.polygon.remove', remove2Dpolygon);
  10959. PubSub.subscribe('map2D.polygon.update', update2Dpolygon);
  10960. function add2Dpolygon(msg, guid) {
  10961. if (!map2DViewer.inited) {
  10962. return false;
  10963. }
  10964. var polygonData = map23DData.polygons[guid];
  10965. if (polygonData.from === '3D') {
  10966. return false;
  10967. }
  10968. var polygon = L.polygon(
  10969. map23DUtil.latLngsToReverse(polygonData.geojson.geometry.coordinates[0]), {
  10970. color: polygonData.geojson.properties.color,
  10971. weight: polygonData.geojson.properties.weight,
  10972. fillColor: polygonData.geojson.properties.fillColor,
  10973. opacity: polygonData.geojson.properties.opacity,
  10974. fillOpacity: polygonData.geojson.properties.fillOpacity,
  10975. title: polygonData.geojson.properties.title
  10976. }
  10977. )
  10978. if(polygonData.polygontype === "circlepolygon"){
  10979. L.Util.circleDrawLatlng(polygon);
  10980. }
  10981. polygon.guid = guid;
  10982. polygon.polygontype = polygonData.polygontype;
  10983. if (polygonData.geojson.properties.popupContent) {
  10984. polygon.bindPopup(polygonData.geojson.properties.popupContent)
  10985. }
  10986. if (polygonData.groupId) {
  10987. polygon.addTo(map2DViewer.groups[polygonData.groupId]);
  10988. } else {
  10989. polygon.addTo(map2DViewer.map);
  10990. }
  10991. map2DViewer.polygons[guid] = polygon;
  10992. polygonData.add2D = true;
  10993. polygonData.visible2D = true;
  10994. };
  10995. function show2Dpolygon(msg, guid) {
  10996. if (!map2DViewer.inited) {
  10997. return false;
  10998. }
  10999. var polygonData = map23DData.polygons[guid];
  11000. if (polygonData.from === '3D') {
  11001. return false;
  11002. }
  11003. if(polygonData.visible2D){
  11004. return false;
  11005. }
  11006. if (polygonData.groupId) {
  11007. map2DViewer.polygons[guid].addTo(map2DViewer.groups[polygonData.groupId]);
  11008. } else {
  11009. map2DViewer.polygons[guid].addTo(map2DViewer.map);
  11010. }
  11011. polygonData.visible2D = true;
  11012. }
  11013. function hide2Dpolygon(msg, guid) {
  11014. if (!map2DViewer.inited) {
  11015. return false;
  11016. }
  11017. var polygonData = map23DData.polygons[guid];
  11018. if (polygonData.from === '3D') {
  11019. return false;
  11020. }
  11021. if(!polygonData.visible2D){
  11022. return false;
  11023. }
  11024. if (polygonData.groupId) {
  11025. map2DViewer.groups[polygonData.groupId].removeLayer(map2DViewer.polygons[guid]);
  11026. } else {
  11027. map2DViewer.map.removeLayer(map2DViewer.polygons[guid]);
  11028. }
  11029. polygonData.visible2D = false;
  11030. }
  11031. function remove2Dpolygon(msg, guid) {
  11032. if (!map2DViewer.inited) {
  11033. return false;
  11034. }
  11035. var polygonData = map23DData.polygons[guid];
  11036. if (polygonData.from === '3D') {
  11037. return false;
  11038. }
  11039. if (polygonData.groupId) {
  11040. map2DViewer.groups[polygonData.groupId].removeLayer(map2DViewer.polygons[guid]);
  11041. } else {
  11042. map2DViewer.map.removeLayer(map2DViewer.polygons[guid]);
  11043. }
  11044. delete map2DViewer.polygons[guid];
  11045. polygonData.add2D = false;
  11046. };
  11047. function update2Dpolygon(msg, guid) {
  11048. if (!map2DViewer.inited) {
  11049. return false;
  11050. }
  11051. var polygonData = map23DData.polygons[guid];
  11052. if (polygonData.from === '3D') {
  11053. return false;
  11054. }
  11055. map2DViewer.polygons[guid].setStyle(
  11056. polygonData.geojson.properties
  11057. );
  11058. if(polygonData.geojson.hasOwnProperty('geometry')){
  11059. if(polygonData.geojson.geometry.coordinates[0].length > 1){
  11060. map2DViewer.polygons[guid].setLatLngs(map23DUtil.latLngsToReverse(polygonData.geojson.geometry.coordinates[0]));
  11061. }
  11062. }
  11063. if (polygonData.geojson.properties.popupContent) {
  11064. polygon.bindPopup(polygonData.geojson.properties.popupContent)
  11065. }
  11066. };
  11067. }(window, document));
  11068. ;
  11069. (function(window, document, undefined) {
  11070. PubSub.subscribe('map23D.polygon.add', add3Dpolygon);
  11071. PubSub.subscribe('map23D.polygon.remove', remove3Dpolygon);
  11072. PubSub.subscribe('map23D.polygon.update', update3Dpolygon);
  11073. PubSub.subscribe('map3D.polygon.add', add3Dpolygon);
  11074. PubSub.subscribe('map3D.polygon.remove', remove3Dpolygon);
  11075. PubSub.subscribe('map3D.polygon.update', update3Dpolygon);
  11076. function add3Dpolygon(msg, guid) {
  11077. if (!map3DViewer.inited) {
  11078. return false;
  11079. }
  11080. var polygonData = map23DData.polygons[guid];
  11081. if (polygonData.from === '2D') {
  11082. return false;
  11083. }
  11084. var geoNewPolygon = getPolygonStyle(polygonData);
  11085. var polygon = locaSpaceMap.CreateFeature();
  11086. polygon.Geometry = geoNewPolygon;
  11087. polygon.Name = guid;
  11088. if (polygonData.groupId) {
  11089. var groupLayer = locaSpaceMap.Globe.Layers.GetLayerByCaption(polygonData.groupId);
  11090. groupLayer.AddFeature(polygon);
  11091. } else {
  11092. locaSpaceMap.Globe.MemoryLayer.AddFeature(polygon);
  11093. }
  11094. map3DViewer.polygons[guid] = polygon;
  11095. polygonData.add3D = true;
  11096. locaSpaceMap.Refresh();
  11097. };
  11098. function getPolygonStyle(polygonData){
  11099. var geoNewPolygon = locaSpaceMap.CreateGeoPolygon3D();
  11100. var pnts = locaSpaceMap.CreatePoint3ds();
  11101. for (var i = 0, l = polygonData.geojson.geometry.coordinates[0].length; i < l; i++) {
  11102. pnts.Add(polygonData.geojson.geometry.coordinates[0][i][0], polygonData.geojson.geometry.coordinates[0][i][1], polygonData.geojson.properties.altitude[i]);
  11103. }
  11104. geoNewPolygon.AddPart(pnts);
  11105. geoNewPolygon.AltitudeMode = polygonData.geojson.properties.altitudeMode; //0紧贴地表 1海拔高度 2相对地表
  11106. //填充色设置
  11107. var newPolygonStyle = locaSpaceMap.CreateSimplePolygonStyle3D();
  11108. var fillColor = locaSpaceMap.CreateColorRGBA();
  11109. var newFillColorRGB = new Color(polygonData.geojson.properties.fillColor, polygonData.geojson.properties.fillOpacity);
  11110. var newFillColorRGBAry = newFillColorRGB.rgbData();
  11111. fillColor.SetValue(newFillColorRGBAry[0], newFillColorRGBAry[1], newFillColorRGBAry[2], polygonData.geojson.properties.fillOpacity * 250);
  11112. // 颜色填充设置
  11113. newPolygonStyle.FillColor = fillColor;
  11114. newPolygonStyle.Fill = true;
  11115. // 线宽,颜色设置
  11116. var newLineStyle = locaSpaceMap.CreateSimpleLineStyle3D();
  11117. var newColor = locaSpaceMap.CreateColorRGBA();
  11118. var newColorRGB = new Color(polygonData.geojson.properties.color, polygonData.geojson.properties.opacity);
  11119. var newColorRGBAry = newColorRGB.rgbData();
  11120. newColor.SetValue(newColorRGBAry[0], newColorRGBAry[1], newColorRGBAry[2], polygonData.geojson.properties.opacity * 250);
  11121. // 线颜色设置
  11122. newLineStyle.LineColor = newColor;
  11123. // 线宽设置
  11124. newLineStyle.LineWidth = polygonData.geojson.properties.weight;
  11125. newPolygonStyle.OutlineStyle = newLineStyle;
  11126. geoNewPolygon.Style = newPolygonStyle;
  11127. //拉伸
  11128. var extrudeStyle = locaSpaceMap.CreateExtrudeStyle();
  11129. var extrudePolygonStyle = locaSpaceMap.CreateSimplePolygonStyle3D();
  11130. var fillColor = locaSpaceMap.CreateColorRGBA();
  11131. var newFillColorRGB = new Color(polygonData.geojson.properties.color, polygonData.geojson.properties.fillOpacity);
  11132. var newFillColorRGBAry = newFillColorRGB.rgbData();
  11133. fillColor.SetValue(newFillColorRGBAry[0], newFillColorRGBAry[1], newFillColorRGBAry[2], polygonData.geojson.properties.fillOpacity * 250);
  11134. // 拉伸颜色填充设置
  11135. extrudePolygonStyle.FillColor = fillColor;
  11136. extrudePolygonStyle.Fill = true;
  11137. extrudeStyle.ExtrudeValue = polygonData.geojson.properties.extrude;
  11138. extrudeStyle.BodyStyle = extrudePolygonStyle;
  11139. extrudeStyle.TailStyle = newPolygonStyle;
  11140. geoNewPolygon.ExtrudeStyle = extrudeStyle;
  11141. return geoNewPolygon;
  11142. }
  11143. function remove3Dpolygon(msg, guid) {
  11144. if (!map3DViewer.inited) {
  11145. return false;
  11146. }
  11147. var polygonData = map23DData.polygons[guid];
  11148. if (polygonData.from === '2D') {
  11149. return false;
  11150. }
  11151. if (polygonData.groupId) {
  11152. locaSpace.RemoveFeatureByName(guid, polygonData.groupId);
  11153. } else {
  11154. locaSpace.RemoveFeatureByName(guid);
  11155. }
  11156. delete map3DViewer.polygons[guid];
  11157. polygonData.add3D = false;
  11158. locaSpaceMap.Refresh();
  11159. };
  11160. function update3Dpolygon(msg, guid) {
  11161. if (!map3DViewer.inited) {
  11162. return false;
  11163. }
  11164. var polygonData = map23DData.polygons[guid];
  11165. if (polygonData.from === '2D') {
  11166. return false;
  11167. }
  11168. var geoNewPolygon = getPolygonStyle(polygonData);
  11169. var polygon = map3DViewer.polygons[guid];
  11170. polygon.Geometry = geoNewPolygon;
  11171. locaSpaceMap.Refresh();
  11172. };
  11173. }(window, document));
  11174. ;
  11175. (function(window, document, undefined) {
  11176. PubSub.subscribe('map23D.tileLayer.add', add2Dlayer);
  11177. PubSub.subscribe('map23D.tileLayer.remove', remove2Dlayer);
  11178. PubSub.subscribe('map23D.tileLayer.update', update2Dlayer);
  11179. PubSub.subscribe('map23D.tileLayer.show', show2Dlayer);
  11180. PubSub.subscribe('map23D.tileLayer.hide', hide2Dlayer);
  11181. PubSub.subscribe('map2D.tileLayer.add', add2Dlayer);
  11182. PubSub.subscribe('map2D.tileLayer.show', show2Dlayer);
  11183. PubSub.subscribe('map2D.tileLayer.hide', hide2Dlayer);
  11184. PubSub.subscribe('map2D.tileLayer.remove', remove2Dlayer);
  11185. PubSub.subscribe('map2D.tileLayer.update', update2Dlayer);
  11186. PubSub.subscribe('map2D.defaultTileLayer.change', default2DtileLayer);
  11187. function default2DtileLayer(msg, options) {
  11188. var guid = 'tileLayer2DDefault';
  11189. if (options.mapName.length == 0) {
  11190. if (map2DViewer.layers[guid]) {
  11191. map2DViewer.map.removeLayer(map2DViewer.layers[guid]);
  11192. delete map23DData.layers[guid];
  11193. }
  11194. return guid;
  11195. }
  11196. if (map2DViewer.layers[guid]) {
  11197. map2DViewer.map.removeLayer(map2DViewer.layers[guid]);
  11198. }
  11199. var tileLayerData = {
  11200. from: '2D',
  11201. type: 'tileLayer',
  11202. guid: guid,
  11203. layer: {
  11204. url2D: map23DConfig.tileServerUrl + '/' + options.mapName + '?l={z}&x={x}&y={y}',
  11205. minZoom: map23DConfig.map2DMinZoom || 1,
  11206. maxZoom: map23DConfig.map2DMaxZoom || 21,
  11207. maxNativeZoom: map23DConfig.map2DMaxZoom || 21,
  11208. attribution: '',
  11209. opacity: 1
  11210. }
  11211. }
  11212. map23DData.layers[guid] = tileLayerData;
  11213. var tileLayer = L.tileLayer(tileLayerData.layer.url2D, {
  11214. minZoom: tileLayerData.layer.minZoom,
  11215. maxZoom: tileLayerData.layer.maxZoom,
  11216. opacity: tileLayerData.layer.opacity,
  11217. maxNativeZoom: tileLayerData.layer.maxNativeZoom,
  11218. attribution: tileLayerData.layer.attribution,
  11219. subdomains: map23DConfig.tileSubdomains||'',
  11220. noWrap: false
  11221. });
  11222. tileLayer.guid = guid;
  11223. tileLayer.addTo(map2DViewer.map);
  11224. tileLayer.bringToBack();
  11225. map2DViewer.layers[guid] = tileLayer;
  11226. return guid;
  11227. }
  11228. /**
  11229. * 根据GUID添加图层
  11230. * @param {[type]} msg [description]
  11231. * @param {[type]} guid [description]
  11232. */
  11233. function add2Dlayer(msg, guid) {
  11234. if (!map2DViewer.inited) {
  11235. return false;
  11236. }
  11237. var tileLayerData = map23DData.layers[guid];
  11238. if (tileLayerData.from === '3D') {
  11239. return false;
  11240. }
  11241. var tileLayer = L.tileLayer(tileLayerData.layer.url2D, {
  11242. minZoom: tileLayerData.layer.minZoom,
  11243. maxZoom: tileLayerData.layer.maxZoom,
  11244. opacity: tileLayerData.layer.opacity,
  11245. attribution: tileLayerData.layer.attribution,
  11246. subdomains: map23DConfig.tileSubdomains||'',
  11247. noWrap: false
  11248. });
  11249. tileLayer.guid = guid;
  11250. tileLayer.addTo(map2DViewer.map);
  11251. map2DViewer.layers[guid] = tileLayer;
  11252. tileLayerData.add2D = true;
  11253. tileLayerData.visible2D = true;
  11254. }
  11255. function show2Dlayer(msg, guid) {
  11256. if (!map2DViewer.inited) {
  11257. return false;
  11258. }
  11259. var tileLayerData = map23DData.layers[guid];
  11260. if (tileLayerData.from === '3D') {
  11261. return false;
  11262. }
  11263. if(tileLayerData.visible2D){
  11264. return false;
  11265. }
  11266. map2DViewer.layers[guid].addTo(map2DViewer.map);
  11267. tileLayerData.visible2D = true;
  11268. }
  11269. function hide2Dlayer(msg, guid) {
  11270. if (!map2DViewer.inited) {
  11271. return false;
  11272. }
  11273. var tileLayerData = map23DData.layers[guid];
  11274. if (tileLayerData.from === '3D') {
  11275. return false;
  11276. }
  11277. if(!tileLayerData.visible2D){
  11278. return false;
  11279. }
  11280. map2DViewer.map.removeLayer(map2DViewer.layers[guid]);
  11281. tileLayerData.visible2D = false;
  11282. }
  11283. /**
  11284. * 移除指定GUID的图层
  11285. * @param {[type]} msg [description]
  11286. * @param {[type]} guid [description]
  11287. * @return {[type]} [description]
  11288. */
  11289. function remove2Dlayer(msg, guid) {
  11290. if (!map2DViewer.inited) {
  11291. return false;
  11292. }
  11293. var tileLayerData = map23DData.layers[guid];
  11294. if (tileLayerData.from === '3D') {
  11295. return false;
  11296. }
  11297. map2DViewer.map.removeLayer(map2DViewer.layers[guid]);
  11298. delete map2DViewer.layers[guid];
  11299. tileLayerData.add2D = false;
  11300. }
  11301. /**
  11302. * 更新指定GUID的图层
  11303. * @param {[type]} msg [description]
  11304. * @param {[type]} guid [description]
  11305. * @return {[type]} [description]
  11306. */
  11307. function update2Dlayer(msg, guid) {
  11308. if (!map2DViewer.inited) {
  11309. return false;
  11310. }
  11311. var tileLayerData = map23DData.layers[guid];
  11312. if (tileLayerData.from === '3D') {
  11313. return false;
  11314. }
  11315. var tileLayer = map2DViewer.layers[guid];
  11316. if (tileLayer.options.opacity != tileLayerData.layer.opacity) {
  11317. tileLayer.setOpacity(tileLayerData.layer.opacity);
  11318. }
  11319. if (tileLayer._url != tileLayerData.layer.url2D) {
  11320. tileLayer.setUrl(tileLayerData.layer.url2D);
  11321. }
  11322. }
  11323. }(window, document));
  11324. ;
  11325. (function(window, document, undefined) {
  11326. PubSub.subscribe('map23D.tileLayer.add', add3DtileLayer);
  11327. PubSub.subscribe('map23D.tileLayer.remove', remove3DtileLayer);
  11328. PubSub.subscribe('map23D.tileLayer.hide', hide3DtileLayer);
  11329. PubSub.subscribe('map23D.tileLayer.show', show3DtileLayer);
  11330. PubSub.subscribe('map23D.tileLayer.update', update3DtileLayer);
  11331. PubSub.subscribe('map3D.tileLayer.add', add3DtileLayer);
  11332. PubSub.subscribe('map3D.tileLayer.remove', remove3DtileLayer);
  11333. PubSub.subscribe('map3D.tileLayer.hide', hide3DtileLayer);
  11334. PubSub.subscribe('map3D.tileLayer.show', show3DtileLayer);
  11335. PubSub.subscribe('map3D.tileLayer.update', update3DtileLayer);
  11336. function update3DtileLayer(msg, guid){
  11337. if (!map3DViewer.inited) {
  11338. return false;
  11339. }
  11340. var tileLayerData = map23DData.layers[guid];
  11341. if (tileLayerData.from === '2D') {
  11342. return false;
  11343. }
  11344. if(map3DViewer.layers[guid].Opaque != tileLayerData.layer.opacity*100)
  11345. map3DViewer.layers[guid].Opaque = tileLayerData.layer.opacity*100;
  11346. locaSpaceMap.Refresh();
  11347. }
  11348. function hide3DtileLayer(msg, guid){
  11349. if (!map3DViewer.inited) {
  11350. return false;
  11351. }
  11352. var tileLayerData = map23DData.layers[guid];
  11353. if (tileLayerData.from === '2D') {
  11354. return false;
  11355. }
  11356. map3DViewer.layers[guid].Visible = false;
  11357. tileLayerData.add3D = false;
  11358. locaSpaceMap.Refresh();
  11359. }
  11360. function show3DtileLayer(msg, guid){
  11361. if (!map3DViewer.inited) {
  11362. return false;
  11363. }
  11364. var tileLayerData = map23DData.layers[guid];
  11365. if (tileLayerData.from === '2D') {
  11366. return false;
  11367. }
  11368. map3DViewer.layers[guid].Visible = true;
  11369. tileLayerData.add3D = true;
  11370. locaSpaceMap.Refresh();
  11371. }
  11372. function add3DtileLayer(msg, guid) {
  11373. if (!map3DViewer.inited) {
  11374. return false;
  11375. }
  11376. var tileLayerData = map23DData.layers[guid];
  11377. if (tileLayerData.from === '2D') {
  11378. return false;
  11379. }
  11380. var tileLayer = locaSpaceMap.Globe.Layers.AddTileLayer(
  11381. 3, 256,
  11382. tileLayerData.layer.minZoom,
  11383. tileLayerData.layer.maxZoom,
  11384. -180, 180, -90, 90,
  11385. tileLayerData.layer.imageType,
  11386. (tileLayerData.layer.url3D.replace('https://','http://')),
  11387. guid, "urlformat");
  11388. map3DViewer.layers[guid] = tileLayer;
  11389. tileLayerData.add3D = true;
  11390. locaSpaceMap.Refresh();
  11391. };
  11392. function remove3DtileLayer(msg, guid) {
  11393. if (!map3DViewer.inited) {
  11394. return false;
  11395. }
  11396. var tileLayerData = map23DData.layers[guid];
  11397. if (tileLayerData.from === '2D') {
  11398. return false;
  11399. }
  11400. if (map3DViewer.layers[guid] != null) {
  11401. locaSpaceMap.Globe.Layers.RemoveLayerByID(map3DViewer.layers[guid].ID);
  11402. }
  11403. delete map3DViewer.layers[guid];
  11404. tileLayerData.add3D = false;
  11405. locaSpaceMap.Refresh();
  11406. };
  11407. }(window, document));
  11408. ;
  11409. (function(window, document, undefined) {
  11410. PubSub.subscribe('map23D.circle.add', add2Dcircle);
  11411. PubSub.subscribe('map23D.circle.remove', remove2Dcircle);
  11412. PubSub.subscribe('map23D.circle.update', update2Dcircle);
  11413. PubSub.subscribe('map2D.circle.add', add2Dcircle);
  11414. PubSub.subscribe('map2D.circle.remove', remove2Dcircle);
  11415. PubSub.subscribe('map2D.circle.update', update2Dcircle);
  11416. PubSub.subscribe('map2D.circle.show', show2Dcircle);
  11417. PubSub.subscribe('map2D.circle.hide', hide2Dcircle);
  11418. function add2Dcircle(msg, guid) {
  11419. if (!map2DViewer.inited) {
  11420. return false;
  11421. }
  11422. var circleData = map23DData.circles[guid];
  11423. if (circleData.from === '3D') {
  11424. return false;
  11425. }
  11426. var circle = L.circle(
  11427. map23DUtil.latLngsToReverse(circleData.geojson.geometry.coordinates),
  11428. circleData.geojson.properties.radius,{
  11429. color: circleData.geojson.properties.color,
  11430. weight: circleData.geojson.properties.weight,
  11431. fillColor: circleData.geojson.properties.fillColor,
  11432. opacity: circleData.geojson.properties.opacity,
  11433. fillOpacity: circleData.geojson.properties.fillOpacity,
  11434. title: circleData.geojson.properties.title
  11435. }
  11436. )
  11437. circle.guid = guid;
  11438. if (circleData.geojson.properties.popupContent) {
  11439. circle.bindPopup(circleData.geojson.properties.popupContent)
  11440. }
  11441. if (circleData.groupId) {
  11442. circle.addTo(map2DViewer.groups[circleData.groupId]);
  11443. } else {
  11444. circle.addTo(map2DViewer.map);
  11445. }
  11446. map2DViewer.circles[guid] = circle;
  11447. circleData.add2D = true;
  11448. circleData.visible2D = true;
  11449. };
  11450. function show2Dcircle(msg, guid) {
  11451. if (!map2DViewer.inited) {
  11452. return false;
  11453. }
  11454. var circleData = map23DData.circles[guid];
  11455. if (circleData.from === '3D') {
  11456. return false;
  11457. }
  11458. if(circleData.visible2D){
  11459. return false;
  11460. }
  11461. if (circleData.groupId) {
  11462. map2DViewer.circles[guid].addTo(map2DViewer.groups[circleData.groupId]);
  11463. } else {
  11464. map2DViewer.circles[guid].addTo(map2DViewer.map);
  11465. }
  11466. circleData.visible2D = true;
  11467. };
  11468. function hide2Dcircle(msg, guid) {
  11469. if (!map2DViewer.inited) {
  11470. return false;
  11471. }
  11472. var circleData = map23DData.circles[guid];
  11473. if (circleData.from === '3D') {
  11474. return false;
  11475. }
  11476. if(!circleData.visible2D){
  11477. return false;
  11478. }
  11479. if (circleData.groupId) {
  11480. map2DViewer.groups[circleData.groupId].removeLayer(map2DViewer.circles[guid]);
  11481. } else {
  11482. map2DViewer.map.removeLayer(map2DViewer.circles[guid]);
  11483. }
  11484. circleData.visible2D = false;
  11485. };
  11486. function remove2Dcircle(msg, guid) {
  11487. if (!map2DViewer.inited) {
  11488. return false;
  11489. }
  11490. var circleData = map23DData.circles[guid];
  11491. if (circleData.from === '3D') {
  11492. return false;
  11493. }
  11494. if (circleData.groupId) {
  11495. map2DViewer.groups[circleData.groupId].removeLayer(map2DViewer.circles[guid]);
  11496. } else {
  11497. map2DViewer.map.removeLayer(map2DViewer.circles[guid]);
  11498. }
  11499. delete map2DViewer.circles[guid];
  11500. circleData.add2D = false;
  11501. };
  11502. function update2Dcircle(msg, guid) {
  11503. if (!map2DViewer.inited) {
  11504. return false;
  11505. }
  11506. var circleData = map23DData.circles[guid];
  11507. if (circleData.from === '3D') {
  11508. return false;
  11509. }
  11510. map2DViewer.circles[guid].setStyle(
  11511. circleData.geojson.properties
  11512. );
  11513. if (circleData.geojson.properties.popupContent) {
  11514. circle.bindPopup(circleData.geojson.properties.popupContent)
  11515. }
  11516. if(circleData.geojson.hasOwnProperty('geometry')){
  11517. map2DViewer.circles[guid].setLatLng(map23DUtil.latLngsToReverse(circleData.geojson.geometry.coordinates));
  11518. map2DViewer.circles[guid].setRadius(circleData.geojson.properties.radius);
  11519. }
  11520. };
  11521. }(window, document));
  11522. ;
  11523. (function(window, document, undefined) {
  11524. PubSub.subscribe('map2D.circleMarker.add', add2DcircleMarker);
  11525. PubSub.subscribe('map2D.circleMarker.remove', remove2DcircleMarker);
  11526. PubSub.subscribe('map2D.circleMarker.update', update2DcircleMarker);
  11527. PubSub.subscribe('map2D.circleMarker.show', show2DcircleMarker);
  11528. PubSub.subscribe('map2D.circleMarker.hide', hide2DcircleMarker);
  11529. function add2DcircleMarker(msg, guid) {
  11530. if (!map2DViewer.inited) {
  11531. return false;
  11532. }
  11533. var circleMarkerData = map23DData.circleMarkers[guid];
  11534. if (circleMarkerData.from === '3D') {
  11535. return false;
  11536. }
  11537. var circleMarker = L.circleMarker(
  11538. map23DUtil.latLngsToReverse(circleMarkerData.geojson.geometry.coordinates),{
  11539. radius: circleMarkerData.geojson.properties.radius,
  11540. color: circleMarkerData.geojson.properties.color,
  11541. weight: circleMarkerData.geojson.properties.weight,
  11542. fillColor: circleMarkerData.geojson.properties.fillColor,
  11543. opacity: circleMarkerData.geojson.properties.opacity,
  11544. fillOpacity: circleMarkerData.geojson.properties.fillOpacity,
  11545. title: circleMarkerData.geojson.properties.title
  11546. }
  11547. )
  11548. circleMarker.guid = guid;
  11549. if (circleMarkerData.geojson.properties.popupContent) {
  11550. circleMarker.bindPopup(circleMarkerData.geojson.properties.popupContent)
  11551. }
  11552. if (circleMarkerData.groupId) {
  11553. circleMarker.addTo(map2DViewer.groups[circleMarkerData.groupId]);
  11554. } else {
  11555. circleMarker.addTo(map2DViewer.map);
  11556. }
  11557. map2DViewer.circleMarkers[guid] = circleMarker;
  11558. circleMarkerData.add2D = true;
  11559. circleMarkerData.visible2D = true;
  11560. };
  11561. function show2DcircleMarker(msg, guid) {
  11562. if (!map2DViewer.inited) {
  11563. return false;
  11564. }
  11565. var circleMarkerData = map23DData.circleMarkers[guid];
  11566. if (circleMarkerData.from === '3D') {
  11567. return false;
  11568. }
  11569. if(circleMarkerData.visible2D){
  11570. return false;
  11571. }
  11572. if (circleMarkerData.groupId) {
  11573. map2DViewer.circleMarkers[guid].addTo(map2DViewer.groups[circleMarkerData.groupId]);
  11574. } else {
  11575. map2DViewer.circleMarkers[guid].addTo(map2DViewer.map);
  11576. }
  11577. circleMarkerData.visible2D = true;
  11578. };
  11579. function hide2DcircleMarker(msg, guid) {
  11580. if (!map2DViewer.inited) {
  11581. return false;
  11582. }
  11583. var circleMarkerData = map23DData.circleMarkers[guid];
  11584. if (circleMarkerData.from === '3D') {
  11585. return false;
  11586. }
  11587. if(!circleMarkerData.visible2D){
  11588. return false;
  11589. }
  11590. if (circleMarkerData.groupId) {
  11591. map2DViewer.groups[circleMarkerData.groupId].removeLayer(map2DViewer.circleMarkers[guid]);
  11592. } else {
  11593. map2DViewer.map.removeLayer(map2DViewer.circleMarkers[guid]);
  11594. }
  11595. circleMarkerData.visible2D = false;
  11596. };
  11597. function remove2DcircleMarker(msg, guid) {
  11598. if (!map2DViewer.inited) {
  11599. return false;
  11600. }
  11601. var circleMarkerData = map23DData.circleMarkers[guid];
  11602. if (circleMarkerData.from === '3D') {
  11603. return false;
  11604. }
  11605. if (circleMarkerData.groupId) {
  11606. map2DViewer.groups[circleMarkerData.groupId].removeLayer(map2DViewer.circleMarkers[guid]);
  11607. } else {
  11608. map2DViewer.map.removeLayer(map2DViewer.circleMarkers[guid]);
  11609. }
  11610. delete map2DViewer.circleMarkers[guid];
  11611. circleMarkerData.add2D = false;
  11612. };
  11613. function update2DcircleMarker(msg, guid) {
  11614. if (!map2DViewer.inited) {
  11615. return false;
  11616. }
  11617. var circleMarkerData = map23DData.circleMarkers[guid];
  11618. if (circleMarkerData.from === '3D') {
  11619. return false;
  11620. }
  11621. map2DViewer.circleMarkers[guid].setStyle(
  11622. circleMarkerData.geojson.properties
  11623. );
  11624. if (circleMarkerData.geojson.properties.popupContent) {
  11625. circleMarker.bindPopup(circleMarkerData.geojson.properties.popupContent)
  11626. }
  11627. if(circleMarkerData.geojson.hasOwnProperty('geometry')){
  11628. map2DViewer.circleMarkers[guid].setLatLng(map23DUtil.latLngsToReverse(circleMarkerData.geojson.geometry.coordinates));
  11629. map2DViewer.circleMarkers[guid].setRadius(circleMarkerData.geojson.properties.radius);
  11630. }
  11631. };
  11632. }(window, document));
  11633. ;
  11634. (function(window, document, undefined) {
  11635. PubSub.subscribe('map23D.circle.add', add3DCircle);
  11636. PubSub.subscribe('map23D.circle.update', update3DCircle);
  11637. PubSub.subscribe('map23D.circle.remove', remove3DCircle);
  11638. PubSub.subscribe('map3D.circle.add', add3DCircle);
  11639. PubSub.subscribe('map3D.circle.update', update3DCircle);
  11640. PubSub.subscribe('map3D.circle.remove', remove3DCircle);
  11641. function add3DCircle(msg, guid) {
  11642. if (!map3DViewer.inited) {
  11643. return false;
  11644. }
  11645. var circleData = map23DData.circles[guid];
  11646. if (circleData.from === '2D') {
  11647. return false;
  11648. }
  11649. var feature = locaSpaceMap.CreateFeature();
  11650. feature.Name = guid;
  11651. var circleStyle = getCircleStyle(circleData);
  11652. feature.Geometry = circleStyle;
  11653. feature.Description = circleData.geojson.properties.title;
  11654. if (circleData.groupId) {
  11655. var groupLayer = locaSpaceMap.Globe.Layers.GetLayerByCaption(circleData.groupId);
  11656. groupLayer.AddFeature(feature);
  11657. } else {
  11658. locaSpaceMap.Globe.MemoryLayer.AddFeature(feature);
  11659. }
  11660. map3DViewer.circles[guid] = feature;
  11661. circleData.add3D = true;
  11662. locaSpaceMap.Refresh();
  11663. };
  11664. function getCircleStyle(circleData){
  11665. var point = locaSpaceMap.CreatePoint3d();
  11666. point.X = circleData.geojson.geometry.coordinates[0];
  11667. point.Y = circleData.geojson.geometry.coordinates[1];
  11668. //point.Z = circleData.geojson.properties.altitude;
  11669. var lineLength = circleData.geojson.properties.radius;
  11670. var line = locaSpaceMap.CreateGeoPolyline3D();
  11671. var part = locaSpaceMap.CreatePoint3ds();
  11672. part.Add2(point);
  11673. point.X +=0.000000001;
  11674. part.Add2(point);
  11675. line.AddPart(part);
  11676. var polygon = line.CreateBuffer(lineLength*2,true,5,true,false);
  11677. //填充色设置
  11678. var newPolygonStyle = locaSpaceMap.CreateSimplePolygonStyle3D();
  11679. var fillColor = locaSpaceMap.CreateColorRGBA();
  11680. var newFillColorRGB = new Color(circleData.geojson.properties.fillColor, circleData.geojson.properties.fillOpacity);
  11681. var newFillColorRGBAry = newFillColorRGB.rgbData();
  11682. fillColor.SetValue(newFillColorRGBAry[0], newFillColorRGBAry[1], newFillColorRGBAry[2], circleData.geojson.properties.fillOpacity * 250);
  11683. // 颜色填充设置
  11684. newPolygonStyle.FillColor = fillColor;
  11685. newPolygonStyle.Fill = true;
  11686. // 线宽,颜色设置
  11687. var newLineStyle = locaSpaceMap.CreateSimpleLineStyle3D();
  11688. var newColor = locaSpaceMap.CreateColorRGBA();
  11689. var newColorRGB = new Color(circleData.geojson.properties.color, circleData.geojson.properties.opacity);
  11690. var newColorRGBAry = newColorRGB.rgbData();
  11691. newColor.SetValue(newColorRGBAry[0], newColorRGBAry[1], newColorRGBAry[2], circleData.geojson.properties.opacity * 250);
  11692. // 线颜色设置
  11693. newLineStyle.LineColor = newColor;
  11694. // 线宽设置
  11695. newLineStyle.LineWidth = circleData.geojson.properties.weight;
  11696. newPolygonStyle.OutlineStyle = newLineStyle;
  11697. polygon.Style = newPolygonStyle;
  11698. //拉伸
  11699. var extrudeStyle = locaSpaceMap.CreateExtrudeStyle();
  11700. var extrudePolygonStyle = locaSpaceMap.CreateSimplePolygonStyle3D();
  11701. var fillColor = locaSpaceMap.CreateColorRGBA();
  11702. var newFillColorRGB = new Color(circleData.geojson.properties.color, circleData.geojson.properties.fillOpacity);
  11703. var newFillColorRGBAry = newFillColorRGB.rgbData();
  11704. fillColor.SetValue(newFillColorRGBAry[0], newFillColorRGBAry[1], newFillColorRGBAry[2], circleData.geojson.properties.fillOpacity * 250);
  11705. // 拉伸颜色填充设置
  11706. extrudePolygonStyle.FillColor = fillColor;
  11707. extrudePolygonStyle.Fill = true;
  11708. extrudeStyle.ExtrudeValue = circleData.geojson.properties.extrude;
  11709. extrudeStyle.BodyStyle = extrudePolygonStyle;
  11710. extrudeStyle.TailStyle = newPolygonStyle;
  11711. polygon.ExtrudeStyle = extrudeStyle;
  11712. polygon.SetAltitude(circleData.geojson.properties.altitude);
  11713. polygon.AltitudeMode = circleData.geojson.properties.altitudeMode;
  11714. return polygon;
  11715. }
  11716. function update3DCircle(msg,guid){
  11717. if (!map3DViewer.inited) {
  11718. return false;
  11719. }
  11720. var circleData = map23DData.circles[guid];
  11721. if (circleData.from === '2D') {
  11722. return false;
  11723. }
  11724. if (map3DViewer.circles[guid] == null) {
  11725. return false;
  11726. }
  11727. var feature = map3DViewer.circles[guid];
  11728. var circleStyle = getCircleStyle(circleData);
  11729. feature.Geometry = circleStyle;
  11730. feature.Description = circleData.geojson.properties.title;
  11731. locaSpaceMap.Refresh();
  11732. }
  11733. function remove3DCircle(msg, guid) {
  11734. if (!map3DViewer.inited) {
  11735. return false;
  11736. }
  11737. var circleData = map23DData.circles[guid];
  11738. if (circleData.from === '2D') {
  11739. return false;
  11740. }
  11741. if (map3DViewer.circles[guid] != null) {
  11742. locaSpaceMap.Globe.MemoryLayer.RemoveFeatureByID(map3DViewer.circles[guid].ID);
  11743. }
  11744. delete map3DViewer.circles[guid];
  11745. circleData.add3D = false;
  11746. locaSpaceMap.Refresh();
  11747. };
  11748. }(window, document));
  11749. ;
  11750. (function(window, document, undefined) {
  11751. PubSub.subscribe('map3D.DEMTileLayer.add', add3DDEMTileLayer);
  11752. PubSub.subscribe('map3D.DEMTileLayer.remove', remove3DDEMTileLayer);
  11753. function add3DDEMTileLayer(msg, guid) {
  11754. if (!map3DViewer.inited) {
  11755. return false;
  11756. }
  11757. var tileLayerData = map23DData.layers[guid];
  11758. var tileUrl = tileLayerData.layer.url3D;
  11759. tileUrl = tileUrl.replace('https://','http://');
  11760. var tileLayer = locaSpaceMap.Globe.Terrains.AddTileTerrain(
  11761. 3, 129, 1, 0, 19, -180, 180, -90, 90, "dtpt",
  11762. tileUrl,
  11763. guid, "urlformat");
  11764. map3DViewer.layers[guid] = tileLayer;
  11765. locaSpaceMap.Refresh();
  11766. };
  11767. function remove3DDEMTileLayer(msg, guid) {
  11768. if (!map3DViewer.inited) {
  11769. return false;
  11770. }
  11771. if (map3DViewer.layers[guid] != null) {
  11772. locaSpaceMap.Globe.Terrains.RemoveTerrainByID(map3DViewer.layers[guid].ID);
  11773. }
  11774. delete map3DViewer.layers[guid];
  11775. locaSpaceMap.Refresh();
  11776. };
  11777. }(window, document));
  11778. ;
  11779. (function(window, document, undefined) {
  11780. PubSub.subscribe('map3D.model.add', add3DModel);
  11781. PubSub.subscribe('map3D.model.update', update3DModel);
  11782. PubSub.subscribe('map3D.model.remove', remove3DModel);
  11783. function add3DModel(msg, guid) {
  11784. if (!map3DViewer.inited) {
  11785. return false;
  11786. }
  11787. var modelData = map23DData.models[guid];
  11788. if (modelData.from === '2D') {
  11789. return false;
  11790. }
  11791. var feature = locaSpaceMap.CreateFeature();
  11792. feature.Name = guid;
  11793. var modelStyle = getModelStyle(modelData);
  11794. feature.Geometry = modelStyle;
  11795. feature.Visible = modelData.geojson.properties.visible;
  11796. feature.Description = modelData.geojson.properties.title;
  11797. if (modelData.groupId) {
  11798. var groupLayer = locaSpaceMap.Globe.Layers.GetLayerByCaption(modelData.groupId);
  11799. groupLayer.AddFeature(feature);
  11800. } else {
  11801. locaSpaceMap.Globe.MemoryLayer.AddFeature(feature);
  11802. }
  11803. map3DViewer.models[guid] = feature;
  11804. modelData.add3D = true;
  11805. locaSpaceMap.Refresh();
  11806. };
  11807. function getModelStyle(modelData) {
  11808. var model = locaSpaceMap.CreateGeoModel();
  11809. model.FilePath = modelData.geojson.properties.url.replace('https://', 'http://');;
  11810. model.PositonX = modelData.geojson.geometry.coordinates[0];
  11811. model.PositonY = modelData.geojson.geometry.coordinates[1];
  11812. model.PositonZ = modelData.geojson.properties.altitude;
  11813. model.RotateX = modelData.geojson.properties.rotate[0];
  11814. model.RotateY = modelData.geojson.properties.rotate[1];
  11815. model.RotateZ = modelData.geojson.properties.rotate[2];
  11816. model.AltitudeMode = modelData.geojson.properties.altitudeMode;
  11817. model.SetScale(modelData.geojson.properties.scale);
  11818. return model;
  11819. }
  11820. function update3DModel(msg, guid) {
  11821. if (!map3DViewer.inited) {
  11822. return false;
  11823. }
  11824. var modelData = map23DData.models[guid];
  11825. if (modelData.from === '2D') {
  11826. return false;
  11827. }
  11828. if (map3DViewer.models[guid] == null) {
  11829. return false;
  11830. }
  11831. modelData.modelUlr = map3DViewer.models[guid].Geometry.FilePath;
  11832. var feature = map3DViewer.models[guid];
  11833. // var modelStyle = getModelStyle(modelData);
  11834. // feature.Geometry = modelStyle;
  11835. feature.Geometry.PositonX = modelData.geojson.geometry.coordinates[0];
  11836. feature.Geometry.PositonY = modelData.geojson.geometry.coordinates[1];
  11837. feature.Geometry.PositonZ = modelData.geojson.properties.altitude;
  11838. feature.Geometry.RotateX = modelData.geojson.properties.rotate[0];
  11839. feature.Geometry.RotateY = modelData.geojson.properties.rotate[1];
  11840. feature.Geometry.RotateZ = modelData.geojson.properties.rotate[2];
  11841. feature.Geometry.AltitudeMode = modelData.geojson.properties.altitudeMode;
  11842. feature.Geometry.SetScale(modelData.geojson.properties.scale);
  11843. feature.Visible = modelData.geojson.properties.visible;
  11844. feature.Description = modelData.geojson.properties.title;
  11845. locaSpaceMap.Refresh();
  11846. }
  11847. function remove3DModel(msg, guid) {
  11848. if (!map3DViewer.inited) {
  11849. return false;
  11850. }
  11851. var modelData = map23DData.models[guid];
  11852. if (modelData.from === '2D') {
  11853. return false;
  11854. }
  11855. if (map3DViewer.models[guid] != null) {
  11856. locaSpaceMap.Globe.MemoryLayer.RemoveFeatureByID(map3DViewer.models[guid].ID);
  11857. }
  11858. delete map3DViewer.models[guid];
  11859. modelData.add3D = false;
  11860. locaSpaceMap.Refresh();
  11861. };
  11862. }(window, document));
  11863. ;
  11864. (function(window, document, undefined) {
  11865. PubSub.subscribe('map3D.label.add', add3Dlabel);
  11866. PubSub.subscribe('map3D.label.remove', remove3Dlabel);
  11867. PubSub.subscribe('map3D.label.update', update3Dlabel);
  11868. function add3Dlabel(msg, options) {
  11869. if (!map3DViewer.inited) {
  11870. return false;
  11871. }
  11872. switch(options.featureType){
  11873. case 'marker':
  11874. var featuerData = map23DData.markers[options.guid];
  11875. var feature = map3DViewer.markers[options.guid];
  11876. break;
  11877. case 'polyline':
  11878. var featuerData = map23DData.polylines[options.guid];
  11879. var feature = map3DViewer.polylines[options.guid];
  11880. break;
  11881. case 'polygon':
  11882. var featuerData = map23DData.polygons[options.guid];
  11883. var feature = map3DViewer.polygons[options.guid];
  11884. break;
  11885. case 'circle':
  11886. var featuerData = map23DData.circles[options.guid];
  11887. var feature = map3DViewer.circles[options.guid];
  11888. break;
  11889. case 'model':
  11890. var featuerData = map23DData.models[options.guid];
  11891. var feature = map3DViewer.models[options.guid];
  11892. break;
  11893. }
  11894. if(!featuerData || !feature){
  11895. return false;
  11896. }
  11897. if (featuerData.from === '2D') {
  11898. return false;
  11899. }
  11900. //label设置
  11901. feature.Label = getLabelStyle(options.label);
  11902. locaSpaceMap.Refresh();
  11903. };
  11904. function getLabelStyle(labelData){
  11905. var labelStyle = locaSpaceMap.CreateLabel();
  11906. labelStyle.Text = labelData.text;
  11907. labelStyle.Style = locaSpaceMap.CreateLabelStyle();
  11908. labelStyle.Style.TracktionLineType = 0;
  11909. labelStyle.Style.TracktionLineWidth = 1;
  11910. //偏移量
  11911. var tractionPos = locaSpaceMap.CreatePoint2d();
  11912. tractionPos.X = labelData.lineLeft ||40;
  11913. tractionPos.Y = labelData.lineTop || 30;
  11914. labelStyle.Style.TractionLineEndPos = tractionPos;
  11915. //文字设置
  11916. var newTextStyle = locaSpaceMap.CreateTextStyle();
  11917. newTextStyle.FontSize = labelData.fontSize || 10; //字体大小
  11918. newTextStyle.FontWeight = 22;
  11919. var newColor = locaSpaceMap.CreateColorRGBA();
  11920. var newColorRGB = new Color((labelData.textColor||'#000000'), 1);
  11921. var newColorRGBAry = newColorRGB.rgbData();
  11922. newColor.SetValue(newColorRGBAry[0], newColorRGBAry[1], newColorRGBAry[2], 250);
  11923. newTextStyle.ForeColor = newColor; //把设置的颜色赋值给字体颜色
  11924. newTextStyle.FontName = 'Microsoft Yahei';
  11925. newTextStyle.Alignment = 6;
  11926. labelStyle.Style.TextStyle = newTextStyle;
  11927. //线条颜色
  11928. var new2Color = locaSpaceMap.CreateColorRGBA();
  11929. var new2ColorRGB = new Color((labelData.lineColor||'#000000'), 1);
  11930. var new2ColorRGBAry = new2ColorRGB.rgbData();
  11931. new2Color.SetValue(new2ColorRGBAry[0], new2ColorRGBAry[1], new2ColorRGBAry[2], 250);
  11932. labelStyle.Style.TractionLineColor = new2Color;
  11933. labelStyle.Style.OutlineColor = new2Color;
  11934. //背景颜色
  11935. var new3Color = locaSpaceMap.CreateColorRGBA();
  11936. var new3ColorRGB = new Color((labelData.background||'#ffffff'), 1);
  11937. var new3ColorRGBAry = new3ColorRGB.rgbData();
  11938. new3Color.SetValue(new3ColorRGBAry[0], new3ColorRGBAry[1], new3ColorRGBAry[2], 250);
  11939. labelStyle.Style.BackBeginColor = new3Color;
  11940. labelStyle.Style.BackMidColor = new3Color;
  11941. labelStyle.Style.BackEndColor = new3Color;
  11942. labelStyle.Style.TextMarginX = 2;
  11943. labelStyle.Style.TextMarginY = 0;
  11944. return labelStyle;
  11945. }
  11946. function remove3Dlabel(msg, options) {
  11947. if (!map3DViewer.inited) {
  11948. return false;
  11949. }
  11950. switch(options.featureType){
  11951. case 'marker':
  11952. var featuerData = map23DData.markers[options.guid];
  11953. var feature = map3DViewer.markers[options.guid];
  11954. break;
  11955. case 'polyline':
  11956. var featuerData = map23DData.polylines[options.guid];
  11957. var feature = map3DViewer.polylines[options.guid];
  11958. break;
  11959. case 'polygon':
  11960. var featuerData = map23DData.polygons[options.guid];
  11961. var feature = map3DViewer.polygons[options.guid];
  11962. break;
  11963. case 'circle':
  11964. var featuerData = map23DData.circles[options.guid];
  11965. var feature = map3DViewer.circles[options.guid];
  11966. break;
  11967. case 'model':
  11968. var featuerData = map23DData.models[options.guid];
  11969. var feature = map3DViewer.models[options.guid];
  11970. break;
  11971. }
  11972. if(!featuerData || !feature){
  11973. return false;
  11974. }
  11975. if (featuerData.from === '2D') {
  11976. return false;
  11977. }
  11978. //label设置
  11979. feature.Label.Visible = false;
  11980. locaSpaceMap.Refresh();
  11981. };
  11982. function update3Dlabel(msg, options) {
  11983. if (!map3DViewer.inited) {
  11984. return false;
  11985. }
  11986. switch(options.featureType){
  11987. case 'marker':
  11988. var featuerData = map23DData.markers[options.guid];
  11989. var feature = map3DViewer.markers[options.guid];
  11990. break;
  11991. case 'polyline':
  11992. var featuerData = map23DData.polylines[options.guid];
  11993. var feature = map3DViewer.polylines[options.guid];
  11994. break;
  11995. case 'polygon':
  11996. var featuerData = map23DData.polygons[options.guid];
  11997. var feature = map3DViewer.polygons[options.guid];
  11998. break;
  11999. case 'circle':
  12000. var featuerData = map23DData.circles[options.guid];
  12001. var feature = map3DViewer.circles[options.guid];
  12002. break;
  12003. case 'model':
  12004. var featuerData = map23DData.models[options.guid];
  12005. var feature = map3DViewer.models[options.guid];
  12006. break;
  12007. }
  12008. if(!featuerData || !feature){
  12009. return false;
  12010. }
  12011. //label设置
  12012. feature.Label = getLabelStyle(options.label);
  12013. locaSpaceMap.Refresh();
  12014. };
  12015. }(window, document));
  12016. ;
  12017. (function(window, document, undefined) {
  12018. // PubSub.subscribe('map2D.cartodbLayer.add', add2DcartodbLayer);
  12019. // PubSub.subscribe('map2D.cartodbLayer.remove', remove2DcartodbLayer);
  12020. // function add2DcartodbLayer(msg, guid){
  12021. // if (!map2DViewer.inited) {
  12022. // return false;
  12023. // }
  12024. // var cartodbData = map23DData.layers[guid];
  12025. // cartodbData.map = cartodbData.map || map2DViewer.map;
  12026. // cartodb.createLayer(cartodbData.map, cartodbData.layer.url2D)
  12027. // .addTo(cartodbData.map)
  12028. // .on('done', function(layer) {
  12029. // layer.guid = guid;
  12030. // map2DViewer.layers[guid] = layer;
  12031. // cartodbData.add2D = true;
  12032. // })
  12033. // .on('error', function(err) {
  12034. // alert("some error occurred: " + err);
  12035. // });
  12036. // }
  12037. // function remove2DcartodbLayer(msg, guid){
  12038. // if (!map2DViewer.inited) {
  12039. // return false;
  12040. // }
  12041. // var cartodbData = map23DData.layers[guid];
  12042. // map2DViewer.map.removeLayer(map2DViewer.layers[guid]);
  12043. // delete map2DViewer.layers[guid];
  12044. // cartodbData.add2D = false;
  12045. // }
  12046. }(window, document));
  12047. ;(function (window, document, undefined) {
  12048. window.locaSpaceMap = null;
  12049. window.locaSpace = {};
  12050. if (typeof module === 'object' && typeof module.exports === 'object') {
  12051. module.exports = locaSpace;
  12052. } else if (typeof define === 'function' && define.amd) {
  12053. define(locaSpace);
  12054. }
  12055. //加载WEB三维控件
  12056. function DetectActiveX() {
  12057. try {
  12058. var comActiveX = new ActiveXObject("LocaSpacePlugin.LocaSpacePluginCtrl.1");
  12059. } catch (e) {
  12060. return false;
  12061. }
  12062. return true;
  12063. }
  12064. locaSpace.DetectActiveX = DetectActiveX;
  12065. //初始化地球
  12066. function InitGlobal(globeDiv) {
  12067. var result = false;
  12068. if (locaSpace.DetectActiveX() == false) {
  12069. var earthDiv = document.getElementById("map3DWrap");
  12070. earthDiv.innerHTML =
  12071. "<div id='LocaSpacePluginNote'>3D地球支持32位的IE10/IE11浏览器访问,并且需要安装 <a href='/soft/LocaSpacePlugin.msi' target='_blank'>LocaSpacePlugin</a> 插件。<br/>安装后请关闭所有浏览器并重新打开!</div>";
  12072. } else {
  12073. try {
  12074. var earthDiv = document.getElementById(globeDiv);
  12075. earthDiv.innerHTML = "<OBJECT ID=\"MyGlobe\" CLASSID=\"CLSID:0E7A33FF-6238-41A6-A38D-AC3F755F92B6\" WIDTH=\"100%\" HEIGHT=\"100%\" style=\"position:Relative;left:0px;top:0px;\"></OBJECT>";
  12076. locaSpaceMap = document.getElementById("MyGlobe");
  12077. result = true;
  12078. } catch (e) {
  12079. alert(e.description);
  12080. }
  12081. }
  12082. return result;
  12083. }
  12084. locaSpace.InitGlobal = InitGlobal;
  12085. function ConnectServer(strIP, nPort) {
  12086. try {
  12087. if (locaSpaceMap != null) {
  12088. locaSpaceMap.Globe.ConnectServer(strIP, nPort, "", "");
  12089. }
  12090. } catch (e) {
  12091. alert(e.description);
  12092. }
  12093. }
  12094. locaSpace.ConnectServer = ConnectServer;
  12095. //打开工作空间
  12096. function OpenWorkSpace(strFilePath) {
  12097. try {
  12098. if (locaSpaceMap != null) {
  12099. locaSpaceMap.Globe.OpenWorkSpace(strFilePath);
  12100. }
  12101. } catch (e) {
  12102. alert(e.description);
  12103. }
  12104. }
  12105. locaSpace.OpenWorkSpace = OpenWorkSpace;
  12106. function FlyTo1(longitude, latitude, altitude, dDistance, altMode) {
  12107. FlyTo(longitude, latitude, altitude, altMode, 0, 0, dDistance);
  12108. }
  12109. locaSpace.FlyTo1 = FlyTo1;
  12110. function FlyTo(longitude, latitude, altitude, dHeading, dTilt, dDistance, altMode) {
  12111. try {
  12112. if (locaSpaceMap != null) {
  12113. var pnt3d = locaSpaceMap.CreatePoint3d();
  12114. pnt3d.SetValue(longitude, latitude, altitude);
  12115. locaSpaceMap.Globe.FlyToPosition1(pnt3d, altMode, dHeading, dTilt, dDistance);
  12116. }
  12117. } catch (e) {
  12118. alert(e.description);
  12119. }
  12120. }
  12121. locaSpace.FlyTo = FlyTo;
  12122. function JumpTo1(longitude, latitude, altitude, dDistance, altMode) {
  12123. JumpTo(longitude, latitude, altitude, altMode, 0, 0, dDistance);
  12124. }
  12125. locaSpace.JumpTo1 = JumpTo1;
  12126. function JumpTo(longitude, latitude, altitude, heading, tilt) {
  12127. try {
  12128. if (locaSpaceMap != null) {
  12129. var cameraState = locaSpaceMap.CreateCameraState();
  12130. cameraState.Latitude = latitude;
  12131. cameraState.Longitude = longitude;
  12132. cameraState.Altitude = altitude;
  12133. cameraState.Heading = heading;
  12134. cameraState.AltitudeMode = 1;
  12135. cameraState.Tilt = tilt;
  12136. locaSpaceMap.Globe.JumpToCameraState(cameraState);
  12137. }
  12138. } catch (e) {
  12139. alert(e.description);
  12140. }
  12141. }
  12142. locaSpace.JumpTo = JumpTo;
  12143. //定点飞行
  12144. function FlyToPlace(longitude, latitude, altitude, heading, tilt) {
  12145. try {
  12146. if (locaSpaceMap != null) {
  12147. var cameraState = locaSpaceMap.CreateCameraState();
  12148. cameraState.Latitude = latitude;
  12149. cameraState.Longitude = longitude;
  12150. cameraState.Altitude = altitude;
  12151. cameraState.Heading = heading;
  12152. cameraState.AltitudeMode = 1;
  12153. cameraState.Tilt = tilt;
  12154. locaSpaceMap.Globe.FlyToCameraState(cameraState);
  12155. }
  12156. } catch (e) {
  12157. alert(e.description);
  12158. }
  12159. }
  12160. locaSpace.FlyToPlace = FlyToPlace;
  12161. function FindFeaturesInPolygon(layerCaption, geoPolygon3D, bCompletelyContained) {
  12162. var layer = locaSpaceMap.Globe.Layers.GetLayerByCaption(layerCaption);
  12163. if (layer != null) {
  12164. var features = layer.FindFeaturesInPolygon(geoPolygon3D, bCompletelyContained);
  12165. return features;
  12166. }
  12167. return null;
  12168. }
  12169. locaSpace.FindFeaturesInPolygon = FindFeaturesInPolygon;
  12170. function RemoveFeatureByName(strName,layerName) {
  12171. if(layerName){
  12172. var groupLayer = locaSpaceMap.Globe.Layers.GetLayerByCaption(layerName);
  12173. var features = groupLayer.GetFeatureByName(strName, true);
  12174. }else {
  12175. var features = locaSpaceMap.Globe.MemoryLayer.GetFeatureByName(strName, true);
  12176. }
  12177. if (features != null && features.Count > 0) {
  12178. var feature = features(0);
  12179. if (feature != null) {
  12180. if(layerName){
  12181. groupLayer.RemoveFeatureByID(feature.ID);
  12182. }else {
  12183. locaSpaceMap.Globe.MemoryLayer.RemoveFeatureByID(feature.ID);
  12184. }
  12185. }
  12186. }
  12187. }
  12188. locaSpace.RemoveFeatureByName = RemoveFeatureByName;
  12189. }(window, document));