12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127301283012930130301313013230133301343013530136301373013830139301403014130142301433014430145301463014730148301493015030151301523015330154301553015630157301583015930160301613016230163301643016530166301673016830169301703017130172301733017430175301763017730178301793018030181301823018330184301853018630187301883018930190301913019230193301943019530196301973019830199302003020130202302033020430205302063020730208302093021030211302123021330214302153021630217302183021930220302213022230223302243022530226302273022830229302303023130232302333023430235302363023730238302393024030241302423024330244302453024630247302483024930250302513025230253302543025530256302573025830259302603026130262302633026430265302663026730268302693027030271302723027330274302753027630277302783027930280302813028230283302843028530286302873028830289302903029130292302933029430295302963029730298302993030030301303023030330304303053030630307303083030930310303113031230313303143031530316303173031830319303203032130322303233032430325303263032730328303293033030331303323033330334303353033630337303383033930340303413034230343303443034530346303473034830349303503035130352303533035430355303563035730358303593036030361303623036330364303653036630367303683036930370303713037230373303743037530376303773037830379303803038130382303833038430385303863038730388303893039030391303923039330394303953039630397303983039930400304013040230403304043040530406304073040830409304103041130412304133041430415304163041730418304193042030421304223042330424304253042630427304283042930430304313043230433304343043530436304373043830439304403044130442304433044430445304463044730448304493045030451304523045330454304553045630457304583045930460304613046230463304643046530466304673046830469304703047130472304733047430475304763047730478304793048030481304823048330484304853048630487304883048930490304913049230493304943049530496304973049830499305003050130502305033050430505305063050730508305093051030511305123051330514305153051630517305183051930520305213052230523305243052530526305273052830529305303053130532305333053430535305363053730538305393054030541305423054330544305453054630547305483054930550305513055230553305543055530556305573055830559305603056130562305633056430565305663056730568305693057030571305723057330574305753057630577305783057930580305813058230583305843058530586305873058830589305903059130592305933059430595305963059730598305993060030601306023060330604306053060630607306083060930610306113061230613306143061530616306173061830619306203062130622306233062430625306263062730628306293063030631306323063330634306353063630637306383063930640306413064230643306443064530646306473064830649306503065130652306533065430655306563065730658306593066030661306623066330664306653066630667306683066930670306713067230673306743067530676306773067830679306803068130682306833068430685306863068730688306893069030691306923069330694306953069630697306983069930700307013070230703307043070530706307073070830709307103071130712307133071430715307163071730718307193072030721307223072330724307253072630727307283072930730307313073230733307343073530736307373073830739307403074130742307433074430745307463074730748307493075030751307523075330754307553075630757307583075930760307613076230763307643076530766307673076830769307703077130772307733077430775307763077730778307793078030781307823078330784307853078630787307883078930790307913079230793307943079530796307973079830799308003080130802308033080430805308063080730808308093081030811308123081330814308153081630817308183081930820308213082230823308243082530826308273082830829308303083130832308333083430835308363083730838308393084030841308423084330844308453084630847308483084930850308513085230853308543085530856308573085830859308603086130862308633086430865308663086730868308693087030871308723087330874308753087630877308783087930880308813088230883308843088530886308873088830889308903089130892308933089430895308963089730898308993090030901309023090330904309053090630907309083090930910309113091230913309143091530916309173091830919309203092130922309233092430925309263092730928309293093030931309323093330934309353093630937309383093930940309413094230943309443094530946309473094830949309503095130952309533095430955309563095730958309593096030961309623096330964309653096630967309683096930970309713097230973309743097530976309773097830979309803098130982309833098430985309863098730988309893099030991309923099330994309953099630997309983099931000310013100231003310043100531006310073100831009310103101131012310133101431015310163101731018310193102031021310223102331024310253102631027310283102931030310313103231033310343103531036310373103831039310403104131042310433104431045310463104731048310493105031051310523105331054310553105631057310583105931060310613106231063310643106531066310673106831069310703107131072310733107431075310763107731078310793108031081310823108331084310853108631087310883108931090310913109231093310943109531096310973109831099311003110131102311033110431105311063110731108311093111031111311123111331114311153111631117311183111931120311213112231123311243112531126311273112831129311303113131132311333113431135311363113731138311393114031141311423114331144311453114631147311483114931150311513115231153311543115531156311573115831159311603116131162311633116431165311663116731168311693117031171311723117331174311753117631177311783117931180311813118231183311843118531186311873118831189311903119131192311933119431195311963119731198311993120031201312023120331204312053120631207312083120931210312113121231213312143121531216312173121831219312203122131222312233122431225312263122731228312293123031231312323123331234312353123631237312383123931240312413124231243312443124531246312473124831249312503125131252312533125431255312563125731258312593126031261312623126331264312653126631267312683126931270312713127231273312743127531276312773127831279312803128131282312833128431285312863128731288312893129031291312923129331294312953129631297312983129931300313013130231303313043130531306313073130831309313103131131312313133131431315313163131731318313193132031321313223132331324313253132631327313283132931330313313133231333313343133531336313373133831339313403134131342313433134431345313463134731348313493135031351313523135331354313553135631357313583135931360313613136231363313643136531366313673136831369313703137131372313733137431375313763137731378313793138031381313823138331384313853138631387313883138931390313913139231393313943139531396313973139831399314003140131402314033140431405314063140731408314093141031411314123141331414314153141631417314183141931420314213142231423314243142531426314273142831429314303143131432314333143431435314363143731438314393144031441314423144331444314453144631447314483144931450314513145231453314543145531456314573145831459314603146131462314633146431465314663146731468314693147031471314723147331474314753147631477314783147931480314813148231483314843148531486314873148831489314903149131492314933149431495314963149731498314993150031501315023150331504315053150631507315083150931510315113151231513315143151531516315173151831519315203152131522315233152431525315263152731528315293153031531315323153331534315353153631537315383153931540315413154231543315443154531546315473154831549315503155131552315533155431555315563155731558315593156031561315623156331564315653156631567315683156931570315713157231573315743157531576315773157831579315803158131582315833158431585315863158731588315893159031591315923159331594315953159631597315983159931600316013160231603316043160531606316073160831609316103161131612316133161431615316163161731618316193162031621316223162331624316253162631627316283162931630316313163231633316343163531636316373163831639316403164131642316433164431645316463164731648316493165031651316523165331654316553165631657316583165931660316613166231663316643166531666316673166831669316703167131672316733167431675316763167731678316793168031681316823168331684316853168631687316883168931690316913169231693316943169531696316973169831699317003170131702317033170431705317063170731708317093171031711317123171331714317153171631717317183171931720317213172231723317243172531726317273172831729317303173131732317333173431735317363173731738317393174031741317423174331744317453174631747317483174931750317513175231753317543175531756317573175831759317603176131762317633176431765317663176731768317693177031771317723177331774317753177631777317783177931780317813178231783317843178531786317873178831789317903179131792317933179431795317963179731798317993180031801318023180331804318053180631807318083180931810318113181231813318143181531816318173181831819318203182131822318233182431825318263182731828318293183031831318323183331834318353183631837318383183931840318413184231843318443184531846318473184831849318503185131852318533185431855318563185731858318593186031861318623186331864318653186631867318683186931870318713187231873318743187531876318773187831879318803188131882318833188431885318863188731888318893189031891318923189331894318953189631897318983189931900319013190231903319043190531906319073190831909319103191131912319133191431915319163191731918319193192031921319223192331924319253192631927319283192931930319313193231933319343193531936319373193831939319403194131942319433194431945319463194731948319493195031951319523195331954319553195631957319583195931960319613196231963319643196531966319673196831969319703197131972319733197431975319763197731978319793198031981319823198331984319853198631987319883198931990319913199231993319943199531996319973199831999320003200132002320033200432005320063200732008320093201032011320123201332014320153201632017320183201932020320213202232023320243202532026320273202832029320303203132032320333203432035320363203732038320393204032041320423204332044320453204632047320483204932050320513205232053320543205532056320573205832059320603206132062320633206432065320663206732068320693207032071320723207332074320753207632077320783207932080320813208232083320843208532086320873208832089320903209132092320933209432095320963209732098320993210032101321023210332104321053210632107321083210932110321113211232113321143211532116321173211832119321203212132122321233212432125321263212732128321293213032131321323213332134321353213632137321383213932140321413214232143321443214532146321473214832149321503215132152321533215432155321563215732158321593216032161321623216332164321653216632167321683216932170321713217232173321743217532176321773217832179321803218132182321833218432185321863218732188321893219032191321923219332194321953219632197321983219932200322013220232203322043220532206322073220832209322103221132212322133221432215322163221732218322193222032221322223222332224322253222632227322283222932230322313223232233322343223532236322373223832239322403224132242322433224432245322463224732248322493225032251322523225332254322553225632257322583225932260322613226232263322643226532266322673226832269322703227132272322733227432275322763227732278322793228032281322823228332284322853228632287322883228932290322913229232293322943229532296322973229832299323003230132302323033230432305323063230732308323093231032311323123231332314323153231632317323183231932320323213232232323323243232532326323273232832329323303233132332323333233432335323363233732338323393234032341323423234332344323453234632347323483234932350323513235232353323543235532356323573235832359323603236132362323633236432365323663236732368323693237032371323723237332374323753237632377323783237932380323813238232383323843238532386323873238832389323903239132392323933239432395323963239732398323993240032401324023240332404324053240632407324083240932410324113241232413324143241532416324173241832419324203242132422324233242432425324263242732428324293243032431324323243332434324353243632437324383243932440324413244232443324443244532446324473244832449324503245132452324533245432455324563245732458324593246032461324623246332464324653246632467324683246932470324713247232473324743247532476324773247832479324803248132482324833248432485324863248732488324893249032491324923249332494324953249632497324983249932500325013250232503325043250532506325073250832509325103251132512325133251432515325163251732518325193252032521325223252332524325253252632527325283252932530325313253232533325343253532536325373253832539325403254132542325433254432545325463254732548325493255032551325523255332554325553255632557325583255932560325613256232563325643256532566325673256832569325703257132572325733257432575325763257732578325793258032581325823258332584325853258632587325883258932590325913259232593325943259532596325973259832599326003260132602326033260432605326063260732608326093261032611326123261332614326153261632617326183261932620326213262232623326243262532626326273262832629326303263132632326333263432635326363263732638326393264032641326423264332644326453264632647326483264932650326513265232653326543265532656326573265832659326603266132662326633266432665326663266732668326693267032671326723267332674326753267632677326783267932680326813268232683326843268532686326873268832689326903269132692326933269432695326963269732698326993270032701327023270332704327053270632707327083270932710327113271232713327143271532716327173271832719327203272132722327233272432725327263272732728327293273032731327323273332734327353273632737327383273932740327413274232743327443274532746327473274832749327503275132752327533275432755327563275732758327593276032761327623276332764327653276632767327683276932770327713277232773327743277532776327773277832779327803278132782327833278432785327863278732788327893279032791327923279332794327953279632797327983279932800328013280232803328043280532806328073280832809328103281132812328133281432815328163281732818328193282032821328223282332824328253282632827328283282932830328313283232833328343283532836328373283832839328403284132842328433284432845328463284732848328493285032851328523285332854328553285632857328583285932860328613286232863328643286532866328673286832869328703287132872328733287432875328763287732878328793288032881328823288332884328853288632887328883288932890328913289232893328943289532896328973289832899329003290132902329033290432905329063290732908329093291032911329123291332914329153291632917329183291932920329213292232923329243292532926329273292832929329303293132932329333293432935329363293732938329393294032941329423294332944329453294632947329483294932950329513295232953329543295532956329573295832959329603296132962329633296432965329663296732968329693297032971329723297332974329753297632977329783297932980329813298232983329843298532986329873298832989329903299132992329933299432995329963299732998329993300033001330023300333004330053300633007330083300933010330113301233013330143301533016330173301833019330203302133022330233302433025330263302733028330293303033031330323303333034330353303633037330383303933040330413304233043330443304533046330473304833049330503305133052330533305433055330563305733058330593306033061330623306333064330653306633067330683306933070330713307233073330743307533076330773307833079330803308133082330833308433085330863308733088330893309033091330923309333094330953309633097330983309933100331013310233103331043310533106331073310833109331103311133112331133311433115331163311733118331193312033121331223312333124331253312633127331283312933130331313313233133331343313533136331373313833139331403314133142331433314433145331463314733148331493315033151331523315333154331553315633157331583315933160331613316233163331643316533166331673316833169331703317133172331733317433175331763317733178331793318033181331823318333184331853318633187331883318933190331913319233193331943319533196331973319833199332003320133202332033320433205332063320733208332093321033211332123321333214332153321633217332183321933220332213322233223332243322533226332273322833229332303323133232332333323433235332363323733238332393324033241332423324333244332453324633247332483324933250332513325233253332543325533256332573325833259332603326133262332633326433265332663326733268332693327033271332723327333274332753327633277332783327933280332813328233283332843328533286332873328833289332903329133292332933329433295332963329733298332993330033301333023330333304333053330633307333083330933310333113331233313333143331533316333173331833319333203332133322333233332433325333263332733328333293333033331333323333333334333353333633337333383333933340333413334233343333443334533346333473334833349333503335133352333533335433355333563335733358333593336033361333623336333364333653336633367333683336933370333713337233373333743337533376333773337833379333803338133382333833338433385333863338733388333893339033391333923339333394333953339633397333983339933400334013340233403334043340533406334073340833409334103341133412334133341433415334163341733418334193342033421334223342333424334253342633427334283342933430334313343233433334343343533436334373343833439334403344133442334433344433445334463344733448334493345033451334523345333454334553345633457334583345933460334613346233463334643346533466334673346833469334703347133472334733347433475334763347733478334793348033481334823348333484334853348633487334883348933490334913349233493334943349533496334973349833499335003350133502335033350433505335063350733508335093351033511335123351333514335153351633517335183351933520335213352233523335243352533526335273352833529335303353133532335333353433535335363353733538335393354033541335423354333544335453354633547335483354933550335513355233553335543355533556335573355833559335603356133562335633356433565335663356733568335693357033571335723357333574335753357633577335783357933580335813358233583335843358533586335873358833589335903359133592335933359433595335963359733598335993360033601336023360333604336053360633607336083360933610336113361233613336143361533616336173361833619336203362133622336233362433625336263362733628336293363033631336323363333634336353363633637336383363933640336413364233643336443364533646336473364833649336503365133652336533365433655336563365733658336593366033661336623366333664336653366633667336683366933670336713367233673336743367533676336773367833679336803368133682336833368433685336863368733688336893369033691336923369333694336953369633697336983369933700337013370233703337043370533706337073370833709337103371133712337133371433715337163371733718337193372033721337223372333724337253372633727337283372933730337313373233733337343373533736337373373833739337403374133742337433374433745337463374733748337493375033751337523375333754337553375633757337583375933760337613376233763337643376533766337673376833769337703377133772337733377433775337763377733778337793378033781337823378333784337853378633787337883378933790337913379233793337943379533796337973379833799338003380133802338033380433805338063380733808338093381033811338123381333814338153381633817338183381933820338213382233823338243382533826338273382833829338303383133832338333383433835338363383733838338393384033841338423384333844338453384633847338483384933850338513385233853338543385533856338573385833859338603386133862338633386433865338663386733868338693387033871338723387333874338753387633877338783387933880338813388233883338843388533886338873388833889338903389133892338933389433895338963389733898338993390033901339023390333904339053390633907339083390933910339113391233913339143391533916339173391833919339203392133922339233392433925339263392733928339293393033931339323393333934339353393633937339383393933940339413394233943339443394533946339473394833949339503395133952339533395433955339563395733958339593396033961339623396333964339653396633967339683396933970339713397233973339743397533976339773397833979339803398133982339833398433985339863398733988339893399033991339923399333994339953399633997339983399934000340013400234003340043400534006340073400834009340103401134012340133401434015340163401734018340193402034021340223402334024340253402634027340283402934030340313403234033340343403534036340373403834039340403404134042340433404434045340463404734048340493405034051340523405334054340553405634057340583405934060340613406234063340643406534066340673406834069340703407134072340733407434075340763407734078340793408034081340823408334084340853408634087340883408934090340913409234093340943409534096340973409834099341003410134102341033410434105341063410734108341093411034111341123411334114341153411634117341183411934120341213412234123341243412534126341273412834129341303413134132341333413434135341363413734138341393414034141341423414334144341453414634147341483414934150341513415234153341543415534156341573415834159341603416134162341633416434165341663416734168341693417034171341723417334174341753417634177341783417934180341813418234183341843418534186341873418834189341903419134192341933419434195341963419734198341993420034201342023420334204342053420634207342083420934210342113421234213342143421534216342173421834219342203422134222342233422434225342263422734228342293423034231342323423334234342353423634237342383423934240342413424234243342443424534246342473424834249342503425134252342533425434255342563425734258342593426034261342623426334264342653426634267342683426934270342713427234273342743427534276342773427834279342803428134282342833428434285342863428734288342893429034291342923429334294342953429634297342983429934300343013430234303343043430534306343073430834309343103431134312343133431434315343163431734318343193432034321343223432334324343253432634327343283432934330343313433234333343343433534336343373433834339343403434134342343433434434345343463434734348343493435034351343523435334354343553435634357343583435934360343613436234363343643436534366343673436834369343703437134372343733437434375343763437734378343793438034381343823438334384343853438634387343883438934390343913439234393343943439534396343973439834399344003440134402344033440434405344063440734408344093441034411344123441334414344153441634417344183441934420344213442234423344243442534426344273442834429344303443134432344333443434435344363443734438344393444034441344423444334444344453444634447344483444934450344513445234453344543445534456344573445834459344603446134462344633446434465344663446734468344693447034471344723447334474344753447634477344783447934480344813448234483344843448534486344873448834489344903449134492344933449434495344963449734498344993450034501345023450334504345053450634507345083450934510345113451234513345143451534516345173451834519345203452134522345233452434525345263452734528345293453034531345323453334534345353453634537345383453934540345413454234543345443454534546345473454834549345503455134552345533455434555345563455734558345593456034561345623456334564345653456634567345683456934570345713457234573345743457534576345773457834579345803458134582345833458434585345863458734588345893459034591345923459334594345953459634597345983459934600346013460234603346043460534606346073460834609346103461134612346133461434615346163461734618346193462034621346223462334624346253462634627346283462934630346313463234633346343463534636346373463834639346403464134642346433464434645346463464734648346493465034651346523465334654346553465634657346583465934660346613466234663346643466534666346673466834669346703467134672346733467434675346763467734678346793468034681346823468334684346853468634687346883468934690346913469234693346943469534696346973469834699347003470134702347033470434705347063470734708347093471034711347123471334714347153471634717347183471934720347213472234723347243472534726347273472834729347303473134732347333473434735347363473734738347393474034741347423474334744347453474634747347483474934750347513475234753347543475534756347573475834759347603476134762347633476434765347663476734768347693477034771347723477334774347753477634777347783477934780347813478234783347843478534786347873478834789347903479134792347933479434795347963479734798347993480034801348023480334804348053480634807348083480934810348113481234813348143481534816348173481834819348203482134822348233482434825348263482734828348293483034831348323483334834348353483634837348383483934840348413484234843348443484534846348473484834849348503485134852348533485434855348563485734858348593486034861348623486334864348653486634867348683486934870348713487234873348743487534876348773487834879348803488134882348833488434885348863488734888348893489034891348923489334894348953489634897348983489934900349013490234903349043490534906349073490834909349103491134912349133491434915349163491734918349193492034921349223492334924349253492634927349283492934930349313493234933349343493534936349373493834939349403494134942349433494434945349463494734948349493495034951349523495334954349553495634957349583495934960349613496234963349643496534966349673496834969349703497134972349733497434975349763497734978349793498034981349823498334984349853498634987349883498934990349913499234993349943499534996349973499834999350003500135002350033500435005350063500735008350093501035011350123501335014350153501635017350183501935020350213502235023350243502535026350273502835029350303503135032350333503435035350363503735038350393504035041350423504335044350453504635047350483504935050350513505235053350543505535056350573505835059350603506135062350633506435065350663506735068350693507035071350723507335074350753507635077350783507935080350813508235083350843508535086350873508835089350903509135092350933509435095350963509735098350993510035101351023510335104351053510635107351083510935110351113511235113351143511535116351173511835119351203512135122351233512435125351263512735128351293513035131351323513335134351353513635137351383513935140351413514235143351443514535146351473514835149351503515135152351533515435155351563515735158351593516035161351623516335164351653516635167351683516935170351713517235173351743517535176351773517835179351803518135182351833518435185351863518735188351893519035191351923519335194351953519635197351983519935200352013520235203352043520535206352073520835209352103521135212352133521435215352163521735218352193522035221352223522335224352253522635227352283522935230352313523235233352343523535236352373523835239352403524135242352433524435245352463524735248352493525035251352523525335254352553525635257352583525935260352613526235263352643526535266352673526835269352703527135272352733527435275352763527735278352793528035281352823528335284352853528635287352883528935290352913529235293352943529535296352973529835299353003530135302353033530435305353063530735308353093531035311353123531335314353153531635317353183531935320353213532235323353243532535326353273532835329353303533135332353333533435335353363533735338353393534035341353423534335344353453534635347353483534935350353513535235353353543535535356353573535835359353603536135362353633536435365353663536735368353693537035371353723537335374353753537635377353783537935380353813538235383353843538535386353873538835389353903539135392353933539435395353963539735398353993540035401354023540335404354053540635407354083540935410354113541235413354143541535416354173541835419354203542135422354233542435425354263542735428354293543035431354323543335434354353543635437354383543935440354413544235443354443544535446354473544835449354503545135452354533545435455354563545735458354593546035461354623546335464354653546635467354683546935470354713547235473354743547535476354773547835479354803548135482354833548435485354863548735488354893549035491354923549335494354953549635497354983549935500355013550235503355043550535506355073550835509355103551135512355133551435515355163551735518355193552035521355223552335524355253552635527355283552935530355313553235533355343553535536355373553835539355403554135542355433554435545355463554735548355493555035551355523555335554355553555635557355583555935560355613556235563355643556535566355673556835569355703557135572355733557435575355763557735578355793558035581355823558335584355853558635587355883558935590355913559235593355943559535596355973559835599356003560135602356033560435605356063560735608356093561035611356123561335614356153561635617356183561935620356213562235623356243562535626356273562835629356303563135632356333563435635356363563735638356393564035641356423564335644356453564635647356483564935650356513565235653356543565535656356573565835659356603566135662356633566435665356663566735668356693567035671356723567335674356753567635677356783567935680356813568235683356843568535686356873568835689356903569135692356933569435695356963569735698356993570035701357023570335704357053570635707357083570935710357113571235713357143571535716357173571835719357203572135722357233572435725357263572735728357293573035731357323573335734357353573635737357383573935740357413574235743357443574535746357473574835749357503575135752357533575435755357563575735758357593576035761357623576335764357653576635767357683576935770357713577235773357743577535776357773577835779357803578135782357833578435785357863578735788357893579035791357923579335794357953579635797357983579935800358013580235803358043580535806358073580835809358103581135812358133581435815358163581735818358193582035821358223582335824358253582635827358283582935830358313583235833358343583535836358373583835839358403584135842358433584435845358463584735848358493585035851358523585335854358553585635857358583585935860358613586235863358643586535866358673586835869358703587135872358733587435875358763587735878358793588035881358823588335884358853588635887358883588935890358913589235893358943589535896358973589835899359003590135902359033590435905359063590735908359093591035911359123591335914359153591635917359183591935920359213592235923359243592535926359273592835929359303593135932359333593435935359363593735938359393594035941359423594335944359453594635947359483594935950359513595235953359543595535956359573595835959359603596135962359633596435965359663596735968359693597035971359723597335974359753597635977359783597935980359813598235983359843598535986359873598835989359903599135992359933599435995359963599735998359993600036001360023600336004360053600636007360083600936010360113601236013360143601536016360173601836019360203602136022360233602436025360263602736028360293603036031360323603336034360353603636037360383603936040360413604236043360443604536046360473604836049360503605136052360533605436055360563605736058360593606036061360623606336064360653606636067360683606936070360713607236073360743607536076360773607836079360803608136082360833608436085360863608736088360893609036091360923609336094360953609636097360983609936100361013610236103361043610536106361073610836109361103611136112361133611436115361163611736118361193612036121361223612336124361253612636127361283612936130361313613236133361343613536136361373613836139361403614136142361433614436145361463614736148361493615036151361523615336154361553615636157361583615936160361613616236163361643616536166361673616836169361703617136172361733617436175361763617736178361793618036181361823618336184361853618636187361883618936190361913619236193361943619536196361973619836199362003620136202362033620436205362063620736208362093621036211362123621336214362153621636217362183621936220362213622236223362243622536226362273622836229362303623136232362333623436235362363623736238362393624036241362423624336244362453624636247362483624936250362513625236253362543625536256362573625836259362603626136262362633626436265362663626736268362693627036271362723627336274362753627636277362783627936280362813628236283362843628536286362873628836289362903629136292362933629436295362963629736298362993630036301363023630336304363053630636307363083630936310363113631236313363143631536316363173631836319363203632136322363233632436325363263632736328363293633036331363323633336334363353633636337363383633936340363413634236343363443634536346363473634836349363503635136352363533635436355363563635736358363593636036361363623636336364363653636636367363683636936370363713637236373363743637536376363773637836379363803638136382363833638436385363863638736388363893639036391363923639336394363953639636397363983639936400364013640236403364043640536406364073640836409364103641136412364133641436415364163641736418364193642036421364223642336424364253642636427364283642936430364313643236433364343643536436364373643836439364403644136442364433644436445364463644736448364493645036451364523645336454364553645636457364583645936460364613646236463364643646536466364673646836469364703647136472364733647436475364763647736478364793648036481364823648336484364853648636487364883648936490364913649236493364943649536496364973649836499365003650136502365033650436505365063650736508365093651036511365123651336514365153651636517365183651936520365213652236523365243652536526365273652836529365303653136532365333653436535365363653736538365393654036541365423654336544365453654636547365483654936550365513655236553365543655536556365573655836559365603656136562365633656436565365663656736568365693657036571365723657336574365753657636577365783657936580365813658236583365843658536586365873658836589365903659136592365933659436595365963659736598365993660036601366023660336604366053660636607366083660936610366113661236613366143661536616366173661836619366203662136622366233662436625366263662736628366293663036631366323663336634366353663636637366383663936640366413664236643366443664536646366473664836649366503665136652366533665436655366563665736658366593666036661366623666336664366653666636667366683666936670366713667236673366743667536676366773667836679366803668136682366833668436685366863668736688366893669036691366923669336694366953669636697366983669936700367013670236703367043670536706367073670836709367103671136712367133671436715367163671736718367193672036721367223672336724367253672636727367283672936730367313673236733367343673536736367373673836739367403674136742367433674436745367463674736748367493675036751367523675336754367553675636757367583675936760367613676236763367643676536766367673676836769367703677136772367733677436775367763677736778367793678036781367823678336784367853678636787367883678936790367913679236793367943679536796367973679836799368003680136802368033680436805368063680736808368093681036811368123681336814368153681636817368183681936820368213682236823368243682536826368273682836829368303683136832368333683436835368363683736838368393684036841368423684336844368453684636847368483684936850368513685236853368543685536856368573685836859368603686136862368633686436865368663686736868368693687036871368723687336874368753687636877368783687936880368813688236883368843688536886368873688836889368903689136892368933689436895368963689736898368993690036901369023690336904369053690636907369083690936910369113691236913369143691536916369173691836919369203692136922369233692436925369263692736928369293693036931369323693336934369353693636937369383693936940369413694236943369443694536946369473694836949369503695136952369533695436955369563695736958369593696036961369623696336964369653696636967369683696936970369713697236973369743697536976369773697836979369803698136982369833698436985369863698736988369893699036991369923699336994369953699636997369983699937000370013700237003370043700537006370073700837009370103701137012370133701437015370163701737018370193702037021370223702337024370253702637027370283702937030370313703237033370343703537036370373703837039370403704137042370433704437045370463704737048370493705037051370523705337054370553705637057370583705937060370613706237063370643706537066370673706837069370703707137072370733707437075370763707737078370793708037081370823708337084370853708637087370883708937090370913709237093370943709537096370973709837099371003710137102371033710437105371063710737108371093711037111371123711337114371153711637117371183711937120371213712237123371243712537126371273712837129371303713137132371333713437135371363713737138371393714037141371423714337144371453714637147371483714937150371513715237153371543715537156371573715837159371603716137162371633716437165371663716737168371693717037171371723717337174371753717637177371783717937180371813718237183371843718537186371873718837189371903719137192371933719437195371963719737198371993720037201372023720337204372053720637207372083720937210372113721237213372143721537216372173721837219372203722137222372233722437225372263722737228372293723037231372323723337234372353723637237372383723937240372413724237243372443724537246372473724837249372503725137252372533725437255372563725737258372593726037261372623726337264372653726637267372683726937270372713727237273372743727537276372773727837279372803728137282372833728437285372863728737288372893729037291372923729337294372953729637297372983729937300373013730237303373043730537306373073730837309373103731137312373133731437315373163731737318373193732037321373223732337324373253732637327373283732937330373313733237333373343733537336373373733837339373403734137342373433734437345373463734737348373493735037351373523735337354373553735637357373583735937360373613736237363373643736537366373673736837369373703737137372373733737437375373763737737378373793738037381373823738337384373853738637387373883738937390373913739237393373943739537396373973739837399374003740137402374033740437405374063740737408374093741037411374123741337414374153741637417374183741937420374213742237423374243742537426374273742837429374303743137432374333743437435374363743737438374393744037441374423744337444374453744637447374483744937450374513745237453374543745537456374573745837459374603746137462374633746437465374663746737468374693747037471374723747337474374753747637477374783747937480374813748237483374843748537486374873748837489374903749137492374933749437495374963749737498374993750037501375023750337504375053750637507375083750937510375113751237513375143751537516375173751837519375203752137522375233752437525375263752737528375293753037531375323753337534375353753637537375383753937540375413754237543375443754537546375473754837549375503755137552375533755437555375563755737558375593756037561375623756337564375653756637567375683756937570375713757237573375743757537576375773757837579375803758137582375833758437585375863758737588375893759037591375923759337594375953759637597375983759937600376013760237603376043760537606376073760837609376103761137612376133761437615376163761737618376193762037621376223762337624376253762637627376283762937630376313763237633376343763537636376373763837639376403764137642376433764437645376463764737648376493765037651376523765337654376553765637657376583765937660376613766237663376643766537666376673766837669376703767137672376733767437675376763767737678376793768037681376823768337684376853768637687376883768937690376913769237693376943769537696376973769837699377003770137702377033770437705377063770737708377093771037711377123771337714377153771637717377183771937720377213772237723377243772537726377273772837729377303773137732377333773437735377363773737738377393774037741377423774337744377453774637747377483774937750377513775237753377543775537756377573775837759377603776137762377633776437765377663776737768377693777037771377723777337774377753777637777377783777937780377813778237783377843778537786377873778837789377903779137792377933779437795377963779737798377993780037801378023780337804378053780637807378083780937810378113781237813378143781537816378173781837819378203782137822378233782437825378263782737828378293783037831378323783337834378353783637837378383783937840378413784237843378443784537846378473784837849378503785137852378533785437855378563785737858378593786037861378623786337864378653786637867378683786937870378713787237873378743787537876378773787837879378803788137882378833788437885378863788737888378893789037891378923789337894378953789637897378983789937900379013790237903379043790537906379073790837909379103791137912379133791437915379163791737918379193792037921379223792337924379253792637927379283792937930379313793237933379343793537936379373793837939379403794137942379433794437945379463794737948379493795037951379523795337954379553795637957379583795937960379613796237963379643796537966379673796837969379703797137972379733797437975379763797737978379793798037981379823798337984379853798637987379883798937990379913799237993379943799537996379973799837999380003800138002380033800438005380063800738008380093801038011380123801338014380153801638017380183801938020380213802238023380243802538026380273802838029380303803138032380333803438035380363803738038380393804038041380423804338044380453804638047380483804938050380513805238053380543805538056380573805838059380603806138062380633806438065380663806738068380693807038071380723807338074380753807638077380783807938080380813808238083380843808538086380873808838089380903809138092380933809438095380963809738098380993810038101381023810338104381053810638107381083810938110381113811238113381143811538116381173811838119381203812138122381233812438125381263812738128381293813038131381323813338134381353813638137381383813938140381413814238143381443814538146381473814838149381503815138152381533815438155381563815738158381593816038161381623816338164381653816638167381683816938170381713817238173381743817538176381773817838179381803818138182381833818438185381863818738188381893819038191381923819338194381953819638197381983819938200382013820238203382043820538206382073820838209382103821138212382133821438215382163821738218382193822038221382223822338224382253822638227382283822938230382313823238233382343823538236382373823838239382403824138242382433824438245382463824738248382493825038251382523825338254382553825638257382583825938260382613826238263382643826538266382673826838269382703827138272382733827438275382763827738278382793828038281382823828338284382853828638287382883828938290382913829238293382943829538296382973829838299383003830138302383033830438305383063830738308383093831038311383123831338314383153831638317383183831938320383213832238323383243832538326383273832838329383303833138332383333833438335383363833738338383393834038341383423834338344383453834638347383483834938350383513835238353383543835538356383573835838359383603836138362383633836438365383663836738368383693837038371383723837338374383753837638377383783837938380383813838238383383843838538386383873838838389383903839138392383933839438395383963839738398383993840038401384023840338404384053840638407384083840938410384113841238413384143841538416384173841838419384203842138422384233842438425384263842738428384293843038431384323843338434384353843638437384383843938440384413844238443384443844538446384473844838449384503845138452384533845438455384563845738458384593846038461384623846338464384653846638467384683846938470384713847238473384743847538476384773847838479384803848138482384833848438485384863848738488384893849038491384923849338494384953849638497384983849938500385013850238503385043850538506385073850838509385103851138512385133851438515385163851738518385193852038521385223852338524385253852638527385283852938530385313853238533385343853538536385373853838539385403854138542385433854438545385463854738548385493855038551385523855338554385553855638557385583855938560385613856238563385643856538566385673856838569385703857138572385733857438575385763857738578385793858038581385823858338584385853858638587385883858938590385913859238593385943859538596385973859838599386003860138602386033860438605386063860738608386093861038611386123861338614386153861638617386183861938620386213862238623386243862538626386273862838629386303863138632386333863438635386363863738638386393864038641386423864338644386453864638647386483864938650386513865238653386543865538656386573865838659386603866138662386633866438665386663866738668386693867038671386723867338674386753867638677386783867938680386813868238683386843868538686386873868838689386903869138692386933869438695386963869738698386993870038701387023870338704387053870638707387083870938710387113871238713387143871538716387173871838719387203872138722387233872438725387263872738728387293873038731387323873338734387353873638737387383873938740387413874238743387443874538746387473874838749387503875138752387533875438755387563875738758387593876038761387623876338764387653876638767387683876938770387713877238773387743877538776387773877838779387803878138782387833878438785387863878738788387893879038791387923879338794387953879638797387983879938800388013880238803388043880538806388073880838809388103881138812388133881438815388163881738818388193882038821388223882338824388253882638827388283882938830388313883238833388343883538836388373883838839388403884138842388433884438845388463884738848388493885038851388523885338854388553885638857388583885938860388613886238863388643886538866388673886838869388703887138872388733887438875388763887738878388793888038881388823888338884388853888638887388883888938890388913889238893388943889538896388973889838899389003890138902389033890438905389063890738908389093891038911389123891338914389153891638917389183891938920389213892238923389243892538926389273892838929389303893138932389333893438935389363893738938389393894038941389423894338944389453894638947389483894938950389513895238953389543895538956389573895838959389603896138962389633896438965389663896738968389693897038971389723897338974389753897638977389783897938980389813898238983389843898538986389873898838989389903899138992389933899438995389963899738998389993900039001390023900339004390053900639007390083900939010390113901239013390143901539016390173901839019390203902139022390233902439025390263902739028390293903039031390323903339034390353903639037390383903939040390413904239043390443904539046390473904839049390503905139052390533905439055390563905739058390593906039061390623906339064390653906639067390683906939070390713907239073390743907539076390773907839079390803908139082390833908439085390863908739088390893909039091390923909339094390953909639097390983909939100391013910239103391043910539106391073910839109391103911139112391133911439115391163911739118391193912039121391223912339124391253912639127391283912939130391313913239133391343913539136391373913839139391403914139142391433914439145391463914739148391493915039151391523915339154391553915639157391583915939160391613916239163391643916539166391673916839169391703917139172391733917439175391763917739178391793918039181391823918339184391853918639187391883918939190391913919239193391943919539196391973919839199392003920139202392033920439205392063920739208392093921039211392123921339214392153921639217392183921939220392213922239223392243922539226392273922839229392303923139232392333923439235392363923739238392393924039241392423924339244392453924639247392483924939250392513925239253392543925539256392573925839259392603926139262392633926439265392663926739268392693927039271392723927339274392753927639277392783927939280392813928239283392843928539286392873928839289392903929139292392933929439295392963929739298392993930039301393023930339304393053930639307393083930939310393113931239313393143931539316393173931839319393203932139322393233932439325393263932739328393293933039331393323933339334393353933639337393383933939340393413934239343393443934539346393473934839349393503935139352393533935439355393563935739358393593936039361393623936339364393653936639367393683936939370393713937239373393743937539376393773937839379393803938139382393833938439385393863938739388393893939039391393923939339394393953939639397393983939939400394013940239403394043940539406394073940839409394103941139412394133941439415394163941739418394193942039421394223942339424394253942639427394283942939430394313943239433394343943539436394373943839439394403944139442394433944439445394463944739448394493945039451394523945339454394553945639457394583945939460394613946239463394643946539466394673946839469394703947139472394733947439475394763947739478394793948039481394823948339484394853948639487394883948939490394913949239493394943949539496394973949839499395003950139502395033950439505395063950739508395093951039511395123951339514395153951639517395183951939520395213952239523395243952539526395273952839529395303953139532395333953439535395363953739538395393954039541395423954339544395453954639547395483954939550395513955239553395543955539556395573955839559395603956139562395633956439565395663956739568395693957039571395723957339574395753957639577395783957939580395813958239583395843958539586395873958839589395903959139592395933959439595395963959739598395993960039601396023960339604396053960639607396083960939610396113961239613396143961539616396173961839619396203962139622396233962439625396263962739628396293963039631396323963339634396353963639637396383963939640396413964239643396443964539646396473964839649396503965139652396533965439655396563965739658396593966039661396623966339664396653966639667396683966939670396713967239673396743967539676396773967839679396803968139682396833968439685396863968739688396893969039691396923969339694396953969639697396983969939700397013970239703397043970539706397073970839709397103971139712397133971439715397163971739718397193972039721397223972339724397253972639727397283972939730397313973239733397343973539736397373973839739397403974139742397433974439745397463974739748397493975039751397523975339754397553975639757397583975939760397613976239763397643976539766397673976839769397703977139772397733977439775397763977739778397793978039781397823978339784397853978639787397883978939790397913979239793397943979539796397973979839799398003980139802398033980439805398063980739808398093981039811398123981339814398153981639817398183981939820398213982239823398243982539826398273982839829398303983139832398333983439835398363983739838398393984039841398423984339844398453984639847398483984939850398513985239853398543985539856398573985839859398603986139862398633986439865398663986739868398693987039871398723987339874398753987639877398783987939880398813988239883398843988539886398873988839889398903989139892398933989439895398963989739898398993990039901399023990339904399053990639907399083990939910399113991239913399143991539916399173991839919399203992139922399233992439925399263992739928399293993039931399323993339934399353993639937399383993939940399413994239943399443994539946399473994839949399503995139952399533995439955399563995739958399593996039961399623996339964399653996639967399683996939970399713997239973399743997539976399773997839979399803998139982399833998439985399863998739988399893999039991399923999339994399953999639997399983999940000400014000240003400044000540006400074000840009400104001140012400134001440015400164001740018400194002040021400224002340024400254002640027400284002940030400314003240033400344003540036400374003840039400404004140042400434004440045400464004740048400494005040051400524005340054400554005640057400584005940060400614006240063400644006540066400674006840069400704007140072400734007440075400764007740078400794008040081400824008340084400854008640087400884008940090400914009240093400944009540096400974009840099401004010140102401034010440105401064010740108401094011040111401124011340114401154011640117401184011940120401214012240123401244012540126401274012840129401304013140132401334013440135401364013740138401394014040141401424014340144401454014640147401484014940150401514015240153401544015540156401574015840159401604016140162401634016440165401664016740168401694017040171401724017340174401754017640177401784017940180401814018240183401844018540186401874018840189401904019140192401934019440195401964019740198401994020040201402024020340204402054020640207402084020940210402114021240213402144021540216402174021840219402204022140222402234022440225402264022740228402294023040231402324023340234402354023640237402384023940240402414024240243402444024540246402474024840249402504025140252402534025440255402564025740258402594026040261402624026340264402654026640267402684026940270402714027240273402744027540276402774027840279402804028140282402834028440285402864028740288402894029040291402924029340294402954029640297402984029940300403014030240303403044030540306403074030840309403104031140312403134031440315403164031740318403194032040321403224032340324403254032640327403284032940330403314033240333403344033540336403374033840339403404034140342403434034440345403464034740348403494035040351403524035340354403554035640357403584035940360403614036240363403644036540366403674036840369403704037140372403734037440375403764037740378403794038040381403824038340384403854038640387403884038940390403914039240393403944039540396403974039840399404004040140402404034040440405404064040740408404094041040411404124041340414404154041640417404184041940420404214042240423404244042540426404274042840429404304043140432404334043440435404364043740438404394044040441404424044340444404454044640447404484044940450404514045240453404544045540456404574045840459404604046140462404634046440465404664046740468404694047040471404724047340474404754047640477404784047940480404814048240483404844048540486404874048840489404904049140492404934049440495404964049740498404994050040501405024050340504405054050640507405084050940510405114051240513405144051540516405174051840519405204052140522405234052440525405264052740528405294053040531405324053340534405354053640537405384053940540405414054240543405444054540546405474054840549405504055140552405534055440555405564055740558405594056040561405624056340564405654056640567405684056940570405714057240573405744057540576405774057840579405804058140582405834058440585405864058740588405894059040591405924059340594405954059640597405984059940600406014060240603406044060540606406074060840609406104061140612406134061440615406164061740618406194062040621406224062340624406254062640627406284062940630406314063240633406344063540636406374063840639406404064140642406434064440645406464064740648406494065040651406524065340654406554065640657406584065940660406614066240663406644066540666406674066840669406704067140672406734067440675406764067740678406794068040681406824068340684406854068640687406884068940690406914069240693406944069540696406974069840699407004070140702407034070440705407064070740708407094071040711407124071340714407154071640717407184071940720407214072240723407244072540726407274072840729407304073140732407334073440735407364073740738407394074040741407424074340744407454074640747407484074940750407514075240753407544075540756407574075840759407604076140762407634076440765407664076740768407694077040771407724077340774407754077640777407784077940780407814078240783407844078540786407874078840789407904079140792407934079440795407964079740798407994080040801408024080340804408054080640807408084080940810408114081240813408144081540816408174081840819408204082140822408234082440825408264082740828408294083040831408324083340834408354083640837408384083940840408414084240843408444084540846408474084840849408504085140852408534085440855408564085740858408594086040861408624086340864408654086640867408684086940870408714087240873408744087540876408774087840879408804088140882408834088440885408864088740888408894089040891408924089340894408954089640897408984089940900409014090240903409044090540906409074090840909409104091140912409134091440915409164091740918409194092040921409224092340924409254092640927409284092940930409314093240933409344093540936409374093840939409404094140942409434094440945409464094740948409494095040951409524095340954409554095640957409584095940960409614096240963409644096540966409674096840969409704097140972409734097440975409764097740978409794098040981409824098340984409854098640987409884098940990409914099240993409944099540996409974099840999410004100141002410034100441005410064100741008410094101041011410124101341014410154101641017410184101941020410214102241023410244102541026410274102841029410304103141032410334103441035410364103741038410394104041041410424104341044410454104641047410484104941050410514105241053410544105541056410574105841059410604106141062410634106441065410664106741068410694107041071410724107341074410754107641077410784107941080410814108241083410844108541086410874108841089410904109141092410934109441095410964109741098410994110041101411024110341104411054110641107411084110941110411114111241113411144111541116411174111841119411204112141122411234112441125411264112741128411294113041131411324113341134411354113641137411384113941140411414114241143411444114541146411474114841149411504115141152411534115441155411564115741158411594116041161411624116341164411654116641167411684116941170411714117241173411744117541176411774117841179411804118141182411834118441185411864118741188411894119041191411924119341194411954119641197411984119941200412014120241203412044120541206412074120841209412104121141212412134121441215412164121741218412194122041221412224122341224412254122641227412284122941230412314123241233412344123541236412374123841239412404124141242412434124441245412464124741248412494125041251412524125341254412554125641257412584125941260412614126241263412644126541266412674126841269412704127141272412734127441275412764127741278412794128041281412824128341284412854128641287412884128941290412914129241293412944129541296412974129841299413004130141302413034130441305413064130741308413094131041311413124131341314413154131641317413184131941320413214132241323413244132541326413274132841329413304133141332413334133441335413364133741338413394134041341413424134341344413454134641347413484134941350413514135241353413544135541356413574135841359413604136141362413634136441365413664136741368413694137041371413724137341374413754137641377413784137941380413814138241383413844138541386413874138841389413904139141392413934139441395413964139741398413994140041401414024140341404414054140641407414084140941410414114141241413414144141541416414174141841419414204142141422414234142441425414264142741428414294143041431414324143341434414354143641437414384143941440414414144241443414444144541446414474144841449414504145141452414534145441455414564145741458414594146041461414624146341464414654146641467414684146941470414714147241473414744147541476414774147841479414804148141482414834148441485414864148741488414894149041491414924149341494414954149641497414984149941500415014150241503415044150541506415074150841509415104151141512415134151441515415164151741518415194152041521415224152341524415254152641527415284152941530415314153241533415344153541536415374153841539415404154141542415434154441545415464154741548415494155041551415524155341554415554155641557415584155941560415614156241563415644156541566415674156841569415704157141572415734157441575415764157741578415794158041581415824158341584415854158641587415884158941590415914159241593415944159541596415974159841599416004160141602416034160441605416064160741608416094161041611416124161341614416154161641617416184161941620416214162241623416244162541626416274162841629416304163141632416334163441635416364163741638416394164041641416424164341644416454164641647416484164941650416514165241653416544165541656416574165841659416604166141662416634166441665416664166741668416694167041671416724167341674416754167641677416784167941680416814168241683416844168541686416874168841689416904169141692416934169441695416964169741698416994170041701417024170341704417054170641707417084170941710417114171241713417144171541716417174171841719417204172141722417234172441725417264172741728417294173041731417324173341734417354173641737417384173941740417414174241743417444174541746417474174841749417504175141752417534175441755417564175741758417594176041761417624176341764417654176641767417684176941770417714177241773417744177541776417774177841779417804178141782417834178441785417864178741788417894179041791417924179341794417954179641797417984179941800418014180241803418044180541806418074180841809418104181141812418134181441815418164181741818418194182041821418224182341824418254182641827418284182941830418314183241833418344183541836418374183841839418404184141842418434184441845418464184741848418494185041851418524185341854418554185641857418584185941860418614186241863418644186541866418674186841869418704187141872418734187441875418764187741878418794188041881418824188341884418854188641887418884188941890418914189241893418944189541896418974189841899419004190141902419034190441905419064190741908419094191041911419124191341914419154191641917419184191941920419214192241923419244192541926419274192841929419304193141932419334193441935419364193741938419394194041941419424194341944419454194641947419484194941950419514195241953419544195541956419574195841959419604196141962419634196441965419664196741968419694197041971419724197341974419754197641977419784197941980419814198241983419844198541986419874198841989419904199141992419934199441995419964199741998419994200042001420024200342004420054200642007420084200942010420114201242013420144201542016420174201842019420204202142022420234202442025420264202742028420294203042031420324203342034420354203642037420384203942040420414204242043420444204542046420474204842049420504205142052420534205442055420564205742058420594206042061420624206342064420654206642067420684206942070420714207242073420744207542076420774207842079420804208142082420834208442085420864208742088420894209042091420924209342094420954209642097420984209942100421014210242103421044210542106421074210842109421104211142112421134211442115421164211742118421194212042121421224212342124421254212642127421284212942130421314213242133421344213542136421374213842139421404214142142421434214442145421464214742148421494215042151421524215342154421554215642157421584215942160421614216242163421644216542166421674216842169421704217142172421734217442175421764217742178421794218042181421824218342184421854218642187421884218942190421914219242193421944219542196421974219842199422004220142202422034220442205422064220742208422094221042211422124221342214422154221642217422184221942220422214222242223422244222542226422274222842229422304223142232422334223442235422364223742238422394224042241422424224342244422454224642247422484224942250422514225242253422544225542256422574225842259422604226142262422634226442265422664226742268422694227042271422724227342274422754227642277422784227942280422814228242283422844228542286422874228842289422904229142292422934229442295422964229742298422994230042301423024230342304423054230642307423084230942310423114231242313423144231542316423174231842319423204232142322423234232442325423264232742328423294233042331423324233342334423354233642337423384233942340423414234242343423444234542346423474234842349423504235142352423534235442355423564235742358423594236042361423624236342364423654236642367423684236942370423714237242373423744237542376423774237842379423804238142382423834238442385423864238742388423894239042391423924239342394423954239642397423984239942400424014240242403424044240542406424074240842409424104241142412424134241442415424164241742418424194242042421424224242342424424254242642427424284242942430424314243242433424344243542436424374243842439424404244142442424434244442445424464244742448424494245042451424524245342454424554245642457424584245942460424614246242463424644246542466424674246842469424704247142472424734247442475424764247742478424794248042481424824248342484424854248642487424884248942490424914249242493424944249542496424974249842499425004250142502425034250442505425064250742508425094251042511425124251342514425154251642517425184251942520425214252242523425244252542526425274252842529425304253142532425334253442535425364253742538425394254042541425424254342544425454254642547425484254942550425514255242553425544255542556425574255842559425604256142562425634256442565425664256742568425694257042571425724257342574425754257642577425784257942580425814258242583425844258542586425874258842589425904259142592425934259442595425964259742598425994260042601426024260342604426054260642607426084260942610426114261242613426144261542616426174261842619426204262142622426234262442625426264262742628426294263042631426324263342634426354263642637426384263942640426414264242643426444264542646426474264842649426504265142652426534265442655426564265742658426594266042661426624266342664426654266642667426684266942670426714267242673426744267542676426774267842679426804268142682426834268442685426864268742688426894269042691426924269342694426954269642697426984269942700427014270242703427044270542706427074270842709427104271142712427134271442715427164271742718427194272042721427224272342724427254272642727427284272942730427314273242733427344273542736427374273842739427404274142742427434274442745427464274742748427494275042751427524275342754427554275642757427584275942760427614276242763427644276542766427674276842769427704277142772427734277442775427764277742778427794278042781427824278342784427854278642787427884278942790427914279242793427944279542796427974279842799428004280142802428034280442805428064280742808428094281042811428124281342814428154281642817428184281942820428214282242823428244282542826428274282842829428304283142832428334283442835428364283742838428394284042841428424284342844428454284642847428484284942850428514285242853428544285542856428574285842859428604286142862428634286442865428664286742868428694287042871428724287342874428754287642877428784287942880428814288242883428844288542886428874288842889428904289142892428934289442895428964289742898428994290042901429024290342904429054290642907429084290942910429114291242913429144291542916429174291842919429204292142922429234292442925429264292742928429294293042931429324293342934429354293642937429384293942940429414294242943429444294542946429474294842949429504295142952429534295442955429564295742958429594296042961429624296342964429654296642967429684296942970429714297242973429744297542976429774297842979429804298142982429834298442985429864298742988429894299042991429924299342994429954299642997429984299943000430014300243003430044300543006430074300843009430104301143012430134301443015430164301743018430194302043021430224302343024430254302643027430284302943030430314303243033430344303543036430374303843039430404304143042430434304443045430464304743048430494305043051430524305343054430554305643057430584305943060430614306243063430644306543066430674306843069430704307143072430734307443075430764307743078430794308043081430824308343084430854308643087430884308943090430914309243093430944309543096430974309843099431004310143102431034310443105431064310743108431094311043111431124311343114431154311643117431184311943120431214312243123431244312543126431274312843129431304313143132431334313443135431364313743138431394314043141431424314343144431454314643147431484314943150431514315243153431544315543156431574315843159431604316143162431634316443165431664316743168431694317043171431724317343174431754317643177431784317943180431814318243183431844318543186431874318843189431904319143192431934319443195431964319743198431994320043201432024320343204432054320643207432084320943210432114321243213432144321543216432174321843219432204322143222432234322443225432264322743228432294323043231432324323343234432354323643237432384323943240432414324243243432444324543246432474324843249432504325143252432534325443255432564325743258432594326043261432624326343264432654326643267432684326943270432714327243273432744327543276432774327843279432804328143282432834328443285432864328743288432894329043291432924329343294432954329643297432984329943300433014330243303433044330543306433074330843309433104331143312433134331443315433164331743318433194332043321433224332343324433254332643327433284332943330433314333243333433344333543336433374333843339433404334143342433434334443345433464334743348433494335043351433524335343354433554335643357433584335943360433614336243363433644336543366433674336843369433704337143372433734337443375433764337743378433794338043381433824338343384433854338643387433884338943390433914339243393433944339543396433974339843399434004340143402434034340443405434064340743408434094341043411434124341343414434154341643417434184341943420434214342243423434244342543426434274342843429434304343143432434334343443435434364343743438434394344043441434424344343444434454344643447434484344943450434514345243453434544345543456434574345843459434604346143462434634346443465434664346743468434694347043471434724347343474434754347643477434784347943480434814348243483434844348543486434874348843489434904349143492434934349443495434964349743498434994350043501435024350343504435054350643507435084350943510435114351243513435144351543516435174351843519435204352143522435234352443525435264352743528435294353043531435324353343534435354353643537435384353943540435414354243543435444354543546435474354843549435504355143552435534355443555435564355743558435594356043561435624356343564435654356643567435684356943570435714357243573435744357543576435774357843579435804358143582435834358443585435864358743588435894359043591435924359343594435954359643597435984359943600436014360243603436044360543606436074360843609436104361143612436134361443615436164361743618436194362043621436224362343624436254362643627436284362943630436314363243633436344363543636436374363843639436404364143642436434364443645436464364743648436494365043651436524365343654436554365643657436584365943660436614366243663436644366543666436674366843669436704367143672436734367443675436764367743678436794368043681436824368343684436854368643687436884368943690436914369243693436944369543696436974369843699437004370143702437034370443705437064370743708437094371043711437124371343714437154371643717437184371943720437214372243723437244372543726437274372843729437304373143732437334373443735437364373743738437394374043741437424374343744437454374643747437484374943750437514375243753437544375543756437574375843759437604376143762437634376443765437664376743768437694377043771437724377343774437754377643777437784377943780437814378243783437844378543786437874378843789437904379143792437934379443795437964379743798437994380043801438024380343804438054380643807438084380943810438114381243813438144381543816438174381843819438204382143822438234382443825438264382743828438294383043831438324383343834438354383643837438384383943840438414384243843438444384543846438474384843849438504385143852438534385443855438564385743858438594386043861438624386343864438654386643867438684386943870438714387243873438744387543876438774387843879438804388143882438834388443885438864388743888438894389043891438924389343894438954389643897438984389943900439014390243903439044390543906439074390843909439104391143912439134391443915439164391743918439194392043921439224392343924439254392643927439284392943930439314393243933439344393543936439374393843939439404394143942439434394443945439464394743948439494395043951439524395343954439554395643957439584395943960439614396243963439644396543966439674396843969439704397143972439734397443975439764397743978439794398043981439824398343984439854398643987439884398943990439914399243993439944399543996439974399843999440004400144002440034400444005440064400744008440094401044011440124401344014440154401644017440184401944020440214402244023440244402544026440274402844029440304403144032440334403444035440364403744038440394404044041440424404344044440454404644047440484404944050440514405244053440544405544056440574405844059440604406144062440634406444065440664406744068440694407044071440724407344074440754407644077440784407944080440814408244083440844408544086440874408844089440904409144092440934409444095440964409744098440994410044101441024410344104441054410644107441084410944110441114411244113441144411544116441174411844119441204412144122441234412444125441264412744128441294413044131441324413344134441354413644137441384413944140441414414244143441444414544146441474414844149441504415144152441534415444155441564415744158441594416044161441624416344164441654416644167441684416944170441714417244173441744417544176441774417844179441804418144182441834418444185441864418744188441894419044191441924419344194441954419644197441984419944200442014420244203442044420544206442074420844209442104421144212442134421444215442164421744218442194422044221442224422344224442254422644227442284422944230442314423244233442344423544236442374423844239442404424144242442434424444245442464424744248442494425044251442524425344254442554425644257442584425944260442614426244263442644426544266442674426844269442704427144272442734427444275442764427744278442794428044281442824428344284442854428644287442884428944290442914429244293442944429544296442974429844299443004430144302443034430444305443064430744308443094431044311443124431344314443154431644317443184431944320443214432244323443244432544326443274432844329443304433144332443334433444335443364433744338443394434044341443424434344344443454434644347443484434944350443514435244353443544435544356443574435844359443604436144362443634436444365443664436744368443694437044371443724437344374443754437644377443784437944380443814438244383443844438544386443874438844389443904439144392443934439444395443964439744398443994440044401444024440344404444054440644407444084440944410444114441244413444144441544416444174441844419444204442144422444234442444425444264442744428444294443044431444324443344434444354443644437444384443944440444414444244443444444444544446444474444844449444504445144452444534445444455444564445744458444594446044461444624446344464444654446644467444684446944470444714447244473444744447544476444774447844479444804448144482444834448444485444864448744488444894449044491444924449344494444954449644497444984449944500445014450244503445044450544506445074450844509445104451144512445134451444515445164451744518445194452044521445224452344524445254452644527445284452944530445314453244533445344453544536445374453844539445404454144542445434454444545445464454744548445494455044551445524455344554445554455644557445584455944560445614456244563445644456544566445674456844569445704457144572445734457444575445764457744578445794458044581445824458344584445854458644587445884458944590445914459244593445944459544596445974459844599446004460144602446034460444605446064460744608446094461044611446124461344614446154461644617446184461944620446214462244623446244462544626446274462844629446304463144632446334463444635446364463744638446394464044641446424464344644446454464644647446484464944650446514465244653446544465544656446574465844659446604466144662446634466444665446664466744668446694467044671446724467344674446754467644677446784467944680446814468244683446844468544686446874468844689446904469144692446934469444695446964469744698446994470044701447024470344704447054470644707447084470944710447114471244713447144471544716447174471844719447204472144722447234472444725447264472744728447294473044731447324473344734447354473644737447384473944740447414474244743447444474544746447474474844749447504475144752447534475444755447564475744758447594476044761447624476344764447654476644767447684476944770447714477244773447744477544776447774477844779447804478144782447834478444785447864478744788447894479044791447924479344794447954479644797447984479944800448014480244803448044480544806448074480844809448104481144812448134481444815448164481744818448194482044821448224482344824448254482644827448284482944830448314483244833448344483544836448374483844839448404484144842448434484444845448464484744848448494485044851448524485344854448554485644857448584485944860448614486244863448644486544866448674486844869448704487144872448734487444875448764487744878448794488044881448824488344884448854488644887448884488944890448914489244893448944489544896448974489844899449004490144902449034490444905449064490744908449094491044911449124491344914449154491644917449184491944920449214492244923449244492544926449274492844929449304493144932449334493444935449364493744938449394494044941449424494344944449454494644947449484494944950449514495244953449544495544956449574495844959449604496144962449634496444965449664496744968449694497044971449724497344974449754497644977449784497944980449814498244983449844498544986449874498844989449904499144992449934499444995449964499744998449994500045001450024500345004450054500645007450084500945010450114501245013450144501545016450174501845019450204502145022450234502445025450264502745028450294503045031450324503345034450354503645037450384503945040450414504245043450444504545046450474504845049450504505145052450534505445055450564505745058450594506045061450624506345064450654506645067450684506945070450714507245073450744507545076450774507845079450804508145082450834508445085450864508745088450894509045091450924509345094450954509645097450984509945100451014510245103451044510545106451074510845109451104511145112451134511445115451164511745118451194512045121451224512345124451254512645127451284512945130451314513245133451344513545136451374513845139451404514145142451434514445145451464514745148451494515045151451524515345154451554515645157451584515945160451614516245163451644516545166451674516845169451704517145172451734517445175451764517745178451794518045181451824518345184451854518645187451884518945190451914519245193451944519545196451974519845199452004520145202452034520445205452064520745208452094521045211452124521345214452154521645217452184521945220452214522245223452244522545226452274522845229452304523145232452334523445235452364523745238452394524045241452424524345244452454524645247452484524945250452514525245253452544525545256452574525845259452604526145262452634526445265452664526745268452694527045271452724527345274452754527645277452784527945280452814528245283452844528545286452874528845289452904529145292452934529445295452964529745298452994530045301453024530345304453054530645307453084530945310453114531245313453144531545316453174531845319453204532145322453234532445325453264532745328453294533045331453324533345334453354533645337453384533945340453414534245343453444534545346453474534845349453504535145352453534535445355453564535745358453594536045361453624536345364453654536645367453684536945370453714537245373453744537545376453774537845379453804538145382453834538445385453864538745388453894539045391453924539345394453954539645397453984539945400454014540245403454044540545406454074540845409454104541145412454134541445415454164541745418454194542045421454224542345424454254542645427454284542945430454314543245433454344543545436454374543845439454404544145442454434544445445454464544745448454494545045451454524545345454454554545645457454584545945460454614546245463454644546545466454674546845469454704547145472454734547445475454764547745478454794548045481454824548345484454854548645487454884548945490454914549245493454944549545496454974549845499455004550145502455034550445505455064550745508455094551045511455124551345514455154551645517455184551945520455214552245523455244552545526455274552845529455304553145532455334553445535455364553745538455394554045541455424554345544455454554645547455484554945550455514555245553455544555545556455574555845559455604556145562455634556445565455664556745568455694557045571455724557345574455754557645577455784557945580455814558245583455844558545586455874558845589455904559145592455934559445595455964559745598455994560045601456024560345604456054560645607456084560945610456114561245613456144561545616456174561845619456204562145622456234562445625456264562745628456294563045631456324563345634456354563645637456384563945640456414564245643456444564545646456474564845649456504565145652456534565445655456564565745658456594566045661456624566345664456654566645667456684566945670456714567245673456744567545676456774567845679456804568145682456834568445685456864568745688456894569045691456924569345694456954569645697456984569945700457014570245703457044570545706457074570845709457104571145712457134571445715457164571745718457194572045721457224572345724457254572645727457284572945730457314573245733457344573545736457374573845739457404574145742457434574445745457464574745748457494575045751457524575345754457554575645757457584575945760457614576245763457644576545766457674576845769457704577145772457734577445775457764577745778457794578045781457824578345784457854578645787457884578945790457914579245793457944579545796457974579845799458004580145802458034580445805458064580745808458094581045811458124581345814458154581645817458184581945820458214582245823458244582545826458274582845829458304583145832458334583445835458364583745838458394584045841458424584345844458454584645847458484584945850458514585245853458544585545856458574585845859458604586145862458634586445865458664586745868458694587045871458724587345874458754587645877458784587945880458814588245883458844588545886458874588845889458904589145892458934589445895458964589745898458994590045901459024590345904459054590645907459084590945910459114591245913459144591545916459174591845919459204592145922459234592445925459264592745928459294593045931459324593345934459354593645937459384593945940459414594245943459444594545946459474594845949459504595145952459534595445955459564595745958459594596045961459624596345964459654596645967459684596945970459714597245973459744597545976459774597845979459804598145982459834598445985459864598745988459894599045991459924599345994459954599645997459984599946000460014600246003460044600546006460074600846009460104601146012460134601446015460164601746018460194602046021460224602346024460254602646027460284602946030460314603246033460344603546036460374603846039460404604146042460434604446045460464604746048460494605046051460524605346054460554605646057460584605946060460614606246063460644606546066460674606846069460704607146072460734607446075460764607746078460794608046081460824608346084460854608646087460884608946090460914609246093460944609546096460974609846099461004610146102461034610446105461064610746108461094611046111461124611346114461154611646117461184611946120461214612246123461244612546126461274612846129461304613146132461334613446135461364613746138461394614046141461424614346144461454614646147461484614946150461514615246153461544615546156461574615846159461604616146162461634616446165461664616746168461694617046171461724617346174461754617646177461784617946180461814618246183461844618546186461874618846189461904619146192461934619446195461964619746198461994620046201462024620346204462054620646207462084620946210462114621246213462144621546216462174621846219462204622146222462234622446225462264622746228462294623046231462324623346234462354623646237462384623946240462414624246243462444624546246462474624846249462504625146252462534625446255462564625746258462594626046261462624626346264462654626646267462684626946270462714627246273462744627546276462774627846279462804628146282462834628446285462864628746288462894629046291462924629346294462954629646297462984629946300463014630246303463044630546306463074630846309463104631146312463134631446315463164631746318463194632046321463224632346324463254632646327463284632946330463314633246333463344633546336463374633846339463404634146342463434634446345463464634746348463494635046351463524635346354463554635646357463584635946360463614636246363463644636546366463674636846369463704637146372463734637446375463764637746378463794638046381463824638346384463854638646387463884638946390463914639246393463944639546396463974639846399464004640146402464034640446405464064640746408464094641046411464124641346414464154641646417464184641946420464214642246423464244642546426464274642846429464304643146432464334643446435464364643746438464394644046441464424644346444464454644646447464484644946450464514645246453464544645546456464574645846459464604646146462464634646446465464664646746468464694647046471464724647346474464754647646477464784647946480464814648246483464844648546486464874648846489464904649146492464934649446495464964649746498464994650046501465024650346504465054650646507465084650946510465114651246513465144651546516465174651846519465204652146522465234652446525465264652746528465294653046531465324653346534465354653646537465384653946540465414654246543465444654546546465474654846549465504655146552465534655446555465564655746558465594656046561465624656346564465654656646567465684656946570465714657246573465744657546576465774657846579465804658146582465834658446585465864658746588465894659046591465924659346594465954659646597465984659946600466014660246603466044660546606466074660846609466104661146612466134661446615466164661746618466194662046621466224662346624466254662646627466284662946630466314663246633466344663546636466374663846639466404664146642466434664446645466464664746648466494665046651466524665346654466554665646657466584665946660466614666246663466644666546666466674666846669466704667146672466734667446675466764667746678466794668046681466824668346684466854668646687466884668946690466914669246693466944669546696466974669846699467004670146702467034670446705467064670746708467094671046711467124671346714467154671646717467184671946720467214672246723467244672546726467274672846729467304673146732467334673446735467364673746738467394674046741467424674346744467454674646747467484674946750467514675246753467544675546756467574675846759467604676146762467634676446765467664676746768467694677046771467724677346774467754677646777467784677946780467814678246783467844678546786467874678846789467904679146792467934679446795467964679746798467994680046801468024680346804468054680646807468084680946810468114681246813468144681546816468174681846819468204682146822468234682446825468264682746828468294683046831468324683346834468354683646837468384683946840468414684246843468444684546846468474684846849468504685146852468534685446855468564685746858468594686046861468624686346864468654686646867468684686946870468714687246873468744687546876468774687846879468804688146882468834688446885468864688746888468894689046891468924689346894468954689646897468984689946900469014690246903469044690546906469074690846909469104691146912469134691446915469164691746918469194692046921469224692346924469254692646927469284692946930469314693246933469344693546936469374693846939469404694146942469434694446945469464694746948469494695046951469524695346954469554695646957469584695946960469614696246963469644696546966469674696846969469704697146972469734697446975469764697746978469794698046981469824698346984469854698646987469884698946990469914699246993469944699546996469974699846999470004700147002470034700447005470064700747008470094701047011470124701347014470154701647017470184701947020470214702247023470244702547026470274702847029470304703147032470334703447035470364703747038470394704047041470424704347044470454704647047470484704947050470514705247053470544705547056470574705847059470604706147062470634706447065470664706747068470694707047071470724707347074470754707647077470784707947080470814708247083470844708547086470874708847089470904709147092470934709447095470964709747098470994710047101471024710347104471054710647107471084710947110471114711247113471144711547116471174711847119471204712147122471234712447125471264712747128471294713047131471324713347134471354713647137471384713947140471414714247143471444714547146471474714847149471504715147152471534715447155471564715747158471594716047161471624716347164471654716647167471684716947170471714717247173471744717547176471774717847179471804718147182471834718447185471864718747188471894719047191471924719347194471954719647197471984719947200472014720247203472044720547206472074720847209472104721147212472134721447215472164721747218472194722047221472224722347224472254722647227472284722947230472314723247233472344723547236472374723847239472404724147242472434724447245472464724747248472494725047251472524725347254472554725647257472584725947260472614726247263472644726547266472674726847269472704727147272472734727447275472764727747278472794728047281472824728347284472854728647287472884728947290472914729247293472944729547296472974729847299473004730147302473034730447305473064730747308473094731047311473124731347314473154731647317473184731947320473214732247323473244732547326473274732847329473304733147332473334733447335473364733747338473394734047341473424734347344473454734647347473484734947350473514735247353473544735547356473574735847359473604736147362473634736447365473664736747368473694737047371473724737347374473754737647377473784737947380473814738247383473844738547386473874738847389473904739147392473934739447395473964739747398473994740047401474024740347404474054740647407474084740947410474114741247413474144741547416474174741847419474204742147422474234742447425474264742747428474294743047431474324743347434474354743647437474384743947440474414744247443474444744547446474474744847449474504745147452474534745447455474564745747458474594746047461474624746347464474654746647467474684746947470474714747247473474744747547476474774747847479474804748147482474834748447485474864748747488474894749047491474924749347494474954749647497474984749947500475014750247503475044750547506475074750847509475104751147512475134751447515475164751747518475194752047521475224752347524475254752647527475284752947530475314753247533475344753547536475374753847539475404754147542475434754447545475464754747548475494755047551475524755347554475554755647557475584755947560475614756247563475644756547566475674756847569475704757147572475734757447575475764757747578475794758047581475824758347584475854758647587475884758947590475914759247593475944759547596475974759847599476004760147602476034760447605476064760747608476094761047611476124761347614476154761647617476184761947620476214762247623476244762547626476274762847629476304763147632476334763447635476364763747638476394764047641476424764347644476454764647647476484764947650476514765247653476544765547656476574765847659476604766147662476634766447665476664766747668476694767047671476724767347674476754767647677476784767947680476814768247683476844768547686476874768847689476904769147692476934769447695476964769747698476994770047701477024770347704477054770647707477084770947710477114771247713477144771547716477174771847719477204772147722477234772447725477264772747728477294773047731477324773347734477354773647737477384773947740477414774247743477444774547746477474774847749477504775147752477534775447755477564775747758477594776047761477624776347764477654776647767477684776947770477714777247773477744777547776477774777847779477804778147782477834778447785477864778747788477894779047791477924779347794477954779647797477984779947800478014780247803478044780547806478074780847809478104781147812478134781447815478164781747818478194782047821478224782347824478254782647827478284782947830478314783247833478344783547836478374783847839478404784147842478434784447845478464784747848478494785047851478524785347854478554785647857478584785947860478614786247863478644786547866478674786847869478704787147872478734787447875478764787747878478794788047881478824788347884478854788647887478884788947890478914789247893478944789547896478974789847899479004790147902479034790447905479064790747908479094791047911479124791347914479154791647917479184791947920479214792247923479244792547926479274792847929479304793147932479334793447935479364793747938479394794047941479424794347944479454794647947479484794947950479514795247953479544795547956479574795847959479604796147962479634796447965479664796747968479694797047971479724797347974479754797647977479784797947980479814798247983479844798547986479874798847989479904799147992479934799447995479964799747998479994800048001480024800348004480054800648007480084800948010480114801248013480144801548016480174801848019480204802148022480234802448025480264802748028480294803048031480324803348034480354803648037480384803948040480414804248043480444804548046480474804848049480504805148052480534805448055480564805748058480594806048061480624806348064480654806648067480684806948070480714807248073480744807548076480774807848079480804808148082480834808448085480864808748088480894809048091480924809348094480954809648097480984809948100481014810248103481044810548106481074810848109481104811148112481134811448115481164811748118481194812048121481224812348124481254812648127481284812948130481314813248133481344813548136481374813848139481404814148142481434814448145481464814748148481494815048151481524815348154481554815648157481584815948160481614816248163481644816548166481674816848169481704817148172481734817448175481764817748178481794818048181481824818348184481854818648187481884818948190481914819248193481944819548196481974819848199482004820148202482034820448205482064820748208482094821048211482124821348214482154821648217482184821948220482214822248223482244822548226482274822848229482304823148232482334823448235482364823748238482394824048241482424824348244482454824648247482484824948250482514825248253482544825548256482574825848259482604826148262482634826448265482664826748268482694827048271482724827348274482754827648277482784827948280482814828248283482844828548286482874828848289482904829148292482934829448295482964829748298482994830048301483024830348304483054830648307483084830948310483114831248313483144831548316483174831848319483204832148322483234832448325483264832748328483294833048331483324833348334483354833648337483384833948340483414834248343483444834548346483474834848349483504835148352483534835448355483564835748358483594836048361483624836348364483654836648367483684836948370483714837248373483744837548376483774837848379483804838148382483834838448385483864838748388483894839048391483924839348394483954839648397483984839948400484014840248403484044840548406484074840848409484104841148412484134841448415484164841748418484194842048421484224842348424484254842648427484284842948430484314843248433484344843548436484374843848439484404844148442484434844448445484464844748448484494845048451484524845348454484554845648457484584845948460484614846248463484644846548466484674846848469484704847148472484734847448475484764847748478484794848048481484824848348484484854848648487484884848948490484914849248493484944849548496484974849848499485004850148502485034850448505485064850748508485094851048511485124851348514485154851648517485184851948520485214852248523485244852548526485274852848529485304853148532485334853448535485364853748538485394854048541485424854348544485454854648547485484854948550485514855248553485544855548556485574855848559485604856148562485634856448565485664856748568485694857048571485724857348574485754857648577485784857948580485814858248583485844858548586485874858848589485904859148592485934859448595485964859748598485994860048601486024860348604486054860648607486084860948610486114861248613486144861548616486174861848619486204862148622486234862448625486264862748628486294863048631486324863348634486354863648637486384863948640486414864248643486444864548646486474864848649486504865148652486534865448655486564865748658486594866048661486624866348664486654866648667486684866948670486714867248673486744867548676486774867848679486804868148682486834868448685486864868748688486894869048691486924869348694486954869648697486984869948700487014870248703487044870548706487074870848709487104871148712487134871448715487164871748718487194872048721487224872348724487254872648727487284872948730487314873248733487344873548736487374873848739487404874148742487434874448745487464874748748487494875048751487524875348754487554875648757487584875948760487614876248763487644876548766487674876848769487704877148772487734877448775487764877748778487794878048781487824878348784487854878648787487884878948790487914879248793487944879548796487974879848799488004880148802488034880448805488064880748808488094881048811488124881348814488154881648817488184881948820488214882248823488244882548826488274882848829488304883148832488334883448835488364883748838488394884048841488424884348844488454884648847488484884948850488514885248853488544885548856488574885848859488604886148862488634886448865488664886748868488694887048871488724887348874488754887648877488784887948880488814888248883488844888548886488874888848889488904889148892488934889448895488964889748898488994890048901489024890348904489054890648907489084890948910489114891248913489144891548916489174891848919489204892148922489234892448925489264892748928489294893048931489324893348934489354893648937489384893948940489414894248943489444894548946489474894848949489504895148952489534895448955489564895748958489594896048961489624896348964489654896648967489684896948970489714897248973489744897548976489774897848979489804898148982489834898448985489864898748988489894899048991489924899348994489954899648997489984899949000490014900249003490044900549006490074900849009490104901149012490134901449015490164901749018490194902049021490224902349024490254902649027490284902949030490314903249033490344903549036490374903849039490404904149042490434904449045490464904749048490494905049051490524905349054490554905649057490584905949060490614906249063490644906549066490674906849069490704907149072490734907449075490764907749078490794908049081490824908349084490854908649087490884908949090490914909249093490944909549096490974909849099491004910149102491034910449105491064910749108491094911049111491124911349114491154911649117491184911949120491214912249123491244912549126491274912849129491304913149132491334913449135491364913749138491394914049141491424914349144491454914649147491484914949150491514915249153491544915549156491574915849159491604916149162491634916449165491664916749168491694917049171491724917349174491754917649177491784917949180491814918249183491844918549186491874918849189491904919149192491934919449195491964919749198491994920049201492024920349204492054920649207492084920949210492114921249213492144921549216492174921849219492204922149222492234922449225492264922749228492294923049231492324923349234492354923649237492384923949240492414924249243492444924549246492474924849249492504925149252492534925449255492564925749258492594926049261492624926349264492654926649267492684926949270492714927249273492744927549276492774927849279492804928149282492834928449285492864928749288492894929049291492924929349294492954929649297492984929949300493014930249303493044930549306493074930849309493104931149312493134931449315493164931749318493194932049321493224932349324493254932649327493284932949330493314933249333493344933549336493374933849339493404934149342493434934449345493464934749348493494935049351493524935349354493554935649357493584935949360493614936249363493644936549366493674936849369493704937149372493734937449375493764937749378493794938049381493824938349384493854938649387493884938949390493914939249393493944939549396493974939849399494004940149402494034940449405494064940749408494094941049411494124941349414494154941649417494184941949420494214942249423494244942549426494274942849429494304943149432494334943449435494364943749438494394944049441494424944349444494454944649447494484944949450494514945249453494544945549456494574945849459494604946149462494634946449465494664946749468494694947049471494724947349474494754947649477494784947949480494814948249483494844948549486494874948849489494904949149492494934949449495494964949749498494994950049501495024950349504495054950649507495084950949510495114951249513495144951549516495174951849519495204952149522495234952449525495264952749528495294953049531495324953349534495354953649537495384953949540495414954249543495444954549546495474954849549495504955149552495534955449555495564955749558495594956049561495624956349564495654956649567495684956949570495714957249573495744957549576495774957849579495804958149582495834958449585495864958749588495894959049591495924959349594495954959649597495984959949600496014960249603496044960549606496074960849609496104961149612496134961449615496164961749618496194962049621496224962349624496254962649627496284962949630496314963249633496344963549636496374963849639496404964149642496434964449645496464964749648496494965049651496524965349654496554965649657496584965949660496614966249663496644966549666496674966849669496704967149672496734967449675496764967749678496794968049681496824968349684496854968649687496884968949690496914969249693496944969549696496974969849699497004970149702497034970449705497064970749708497094971049711497124971349714497154971649717497184971949720497214972249723497244972549726497274972849729497304973149732497334973449735497364973749738497394974049741497424974349744497454974649747497484974949750497514975249753497544975549756497574975849759497604976149762497634976449765497664976749768497694977049771497724977349774497754977649777497784977949780497814978249783497844978549786497874978849789497904979149792497934979449795497964979749798497994980049801498024980349804498054980649807498084980949810498114981249813498144981549816498174981849819498204982149822498234982449825498264982749828498294983049831498324983349834498354983649837498384983949840498414984249843498444984549846498474984849849498504985149852498534985449855498564985749858498594986049861498624986349864498654986649867498684986949870498714987249873498744987549876498774987849879498804988149882498834988449885498864988749888498894989049891498924989349894498954989649897498984989949900499014990249903499044990549906499074990849909499104991149912499134991449915499164991749918499194992049921499224992349924499254992649927499284992949930499314993249933499344993549936499374993849939499404994149942499434994449945499464994749948499494995049951499524995349954499554995649957499584995949960499614996249963499644996549966499674996849969499704997149972499734997449975499764997749978499794998049981499824998349984499854998649987499884998949990499914999249993499944999549996499974999849999500005000150002500035000450005500065000750008500095001050011500125001350014500155001650017500185001950020500215002250023500245002550026500275002850029500305003150032500335003450035500365003750038500395004050041500425004350044500455004650047500485004950050500515005250053500545005550056500575005850059500605006150062500635006450065500665006750068500695007050071500725007350074500755007650077500785007950080500815008250083500845008550086500875008850089500905009150092500935009450095500965009750098500995010050101501025010350104501055010650107501085010950110501115011250113501145011550116501175011850119501205012150122501235012450125501265012750128501295013050131501325013350134501355013650137501385013950140501415014250143501445014550146501475014850149501505015150152501535015450155501565015750158501595016050161501625016350164501655016650167501685016950170501715017250173501745017550176501775017850179501805018150182501835018450185501865018750188501895019050191501925019350194501955019650197501985019950200502015020250203502045020550206502075020850209502105021150212502135021450215502165021750218502195022050221502225022350224502255022650227502285022950230502315023250233502345023550236502375023850239502405024150242502435024450245502465024750248502495025050251502525025350254502555025650257502585025950260502615026250263502645026550266502675026850269502705027150272502735027450275502765027750278502795028050281502825028350284502855028650287502885028950290502915029250293502945029550296502975029850299503005030150302503035030450305503065030750308503095031050311503125031350314503155031650317503185031950320503215032250323503245032550326503275032850329503305033150332503335033450335503365033750338503395034050341503425034350344503455034650347503485034950350503515035250353503545035550356503575035850359503605036150362503635036450365503665036750368503695037050371503725037350374503755037650377503785037950380503815038250383503845038550386503875038850389503905039150392503935039450395503965039750398503995040050401504025040350404504055040650407504085040950410504115041250413504145041550416504175041850419504205042150422504235042450425504265042750428504295043050431504325043350434504355043650437504385043950440504415044250443504445044550446504475044850449504505045150452504535045450455504565045750458504595046050461504625046350464504655046650467504685046950470504715047250473504745047550476504775047850479504805048150482504835048450485504865048750488504895049050491504925049350494504955049650497504985049950500505015050250503505045050550506505075050850509505105051150512505135051450515505165051750518505195052050521505225052350524505255052650527505285052950530505315053250533505345053550536505375053850539505405054150542505435054450545505465054750548505495055050551505525055350554505555055650557505585055950560505615056250563505645056550566505675056850569505705057150572505735057450575505765057750578505795058050581505825058350584505855058650587505885058950590505915059250593505945059550596505975059850599506005060150602506035060450605506065060750608506095061050611506125061350614506155061650617506185061950620506215062250623506245062550626506275062850629506305063150632506335063450635506365063750638506395064050641506425064350644506455064650647506485064950650506515065250653506545065550656506575065850659506605066150662506635066450665506665066750668506695067050671506725067350674506755067650677506785067950680506815068250683506845068550686506875068850689506905069150692506935069450695506965069750698506995070050701507025070350704507055070650707507085070950710507115071250713507145071550716507175071850719507205072150722507235072450725507265072750728507295073050731507325073350734507355073650737507385073950740507415074250743507445074550746507475074850749507505075150752507535075450755507565075750758507595076050761507625076350764507655076650767507685076950770507715077250773507745077550776507775077850779507805078150782507835078450785507865078750788507895079050791507925079350794507955079650797507985079950800508015080250803508045080550806508075080850809508105081150812508135081450815508165081750818508195082050821508225082350824508255082650827508285082950830508315083250833508345083550836508375083850839508405084150842508435084450845508465084750848508495085050851508525085350854508555085650857508585085950860508615086250863508645086550866508675086850869508705087150872508735087450875508765087750878508795088050881508825088350884508855088650887508885088950890508915089250893508945089550896508975089850899509005090150902509035090450905509065090750908509095091050911509125091350914509155091650917509185091950920509215092250923509245092550926509275092850929509305093150932509335093450935509365093750938509395094050941509425094350944509455094650947509485094950950509515095250953509545095550956509575095850959509605096150962509635096450965509665096750968509695097050971509725097350974509755097650977509785097950980509815098250983509845098550986509875098850989509905099150992509935099450995509965099750998509995100051001510025100351004510055100651007510085100951010510115101251013510145101551016510175101851019510205102151022510235102451025510265102751028510295103051031510325103351034510355103651037510385103951040510415104251043510445104551046510475104851049510505105151052510535105451055510565105751058510595106051061510625106351064510655106651067510685106951070510715107251073510745107551076510775107851079510805108151082510835108451085510865108751088510895109051091510925109351094510955109651097510985109951100511015110251103511045110551106511075110851109511105111151112511135111451115511165111751118511195112051121511225112351124511255112651127511285112951130511315113251133511345113551136511375113851139511405114151142511435114451145511465114751148511495115051151511525115351154511555115651157511585115951160511615116251163511645116551166511675116851169511705117151172511735117451175511765117751178511795118051181511825118351184511855118651187511885118951190511915119251193511945119551196511975119851199512005120151202512035120451205512065120751208512095121051211512125121351214512155121651217512185121951220512215122251223512245122551226512275122851229512305123151232512335123451235512365123751238512395124051241512425124351244512455124651247512485124951250512515125251253512545125551256512575125851259512605126151262512635126451265512665126751268512695127051271512725127351274512755127651277512785127951280512815128251283512845128551286512875128851289512905129151292512935129451295512965129751298512995130051301513025130351304513055130651307513085130951310513115131251313513145131551316513175131851319513205132151322513235132451325513265132751328513295133051331513325133351334513355133651337513385133951340513415134251343513445134551346513475134851349513505135151352513535135451355513565135751358513595136051361513625136351364513655136651367513685136951370513715137251373513745137551376513775137851379513805138151382513835138451385513865138751388513895139051391513925139351394513955139651397513985139951400514015140251403514045140551406514075140851409514105141151412514135141451415514165141751418514195142051421514225142351424514255142651427514285142951430514315143251433514345143551436514375143851439514405144151442514435144451445514465144751448514495145051451514525145351454514555145651457514585145951460514615146251463514645146551466514675146851469514705147151472514735147451475514765147751478514795148051481514825148351484514855148651487514885148951490514915149251493514945149551496514975149851499515005150151502515035150451505515065150751508515095151051511515125151351514515155151651517515185151951520515215152251523515245152551526515275152851529515305153151532515335153451535515365153751538515395154051541515425154351544515455154651547515485154951550515515155251553515545155551556515575155851559515605156151562515635156451565515665156751568515695157051571515725157351574515755157651577515785157951580515815158251583515845158551586515875158851589515905159151592515935159451595515965159751598515995160051601516025160351604516055160651607516085160951610516115161251613516145161551616516175161851619516205162151622516235162451625516265162751628516295163051631516325163351634516355163651637516385163951640516415164251643516445164551646516475164851649516505165151652516535165451655516565165751658516595166051661516625166351664516655166651667516685166951670516715167251673516745167551676516775167851679516805168151682516835168451685516865168751688516895169051691516925169351694516955169651697516985169951700517015170251703517045170551706517075170851709517105171151712517135171451715517165171751718517195172051721517225172351724517255172651727517285172951730517315173251733517345173551736517375173851739517405174151742517435174451745517465174751748517495175051751517525175351754517555175651757517585175951760517615176251763517645176551766517675176851769517705177151772517735177451775517765177751778517795178051781517825178351784517855178651787517885178951790517915179251793517945179551796517975179851799518005180151802518035180451805518065180751808518095181051811518125181351814518155181651817518185181951820518215182251823518245182551826518275182851829518305183151832518335183451835518365183751838518395184051841518425184351844518455184651847518485184951850518515185251853518545185551856518575185851859518605186151862518635186451865518665186751868518695187051871518725187351874518755187651877518785187951880518815188251883518845188551886518875188851889518905189151892518935189451895518965189751898518995190051901519025190351904519055190651907519085190951910519115191251913519145191551916519175191851919519205192151922519235192451925519265192751928519295193051931519325193351934519355193651937519385193951940519415194251943519445194551946519475194851949519505195151952519535195451955519565195751958519595196051961519625196351964519655196651967519685196951970519715197251973519745197551976519775197851979519805198151982519835198451985519865198751988519895199051991519925199351994519955199651997519985199952000520015200252003520045200552006520075200852009520105201152012520135201452015520165201752018520195202052021520225202352024520255202652027520285202952030520315203252033520345203552036520375203852039520405204152042520435204452045520465204752048520495205052051520525205352054520555205652057520585205952060520615206252063520645206552066520675206852069520705207152072520735207452075520765207752078520795208052081520825208352084520855208652087520885208952090520915209252093520945209552096520975209852099521005210152102521035210452105521065210752108521095211052111521125211352114521155211652117521185211952120521215212252123521245212552126521275212852129521305213152132521335213452135521365213752138521395214052141521425214352144521455214652147521485214952150521515215252153521545215552156521575215852159521605216152162521635216452165521665216752168521695217052171521725217352174521755217652177521785217952180521815218252183521845218552186521875218852189521905219152192521935219452195521965219752198521995220052201522025220352204522055220652207522085220952210522115221252213522145221552216522175221852219522205222152222522235222452225522265222752228522295223052231522325223352234522355223652237522385223952240522415224252243522445224552246522475224852249522505225152252522535225452255522565225752258522595226052261522625226352264522655226652267522685226952270522715227252273522745227552276522775227852279522805228152282522835228452285522865228752288522895229052291522925229352294522955229652297522985229952300523015230252303523045230552306523075230852309523105231152312523135231452315523165231752318523195232052321523225232352324523255232652327523285232952330523315233252333523345233552336523375233852339523405234152342523435234452345523465234752348523495235052351523525235352354523555235652357523585235952360523615236252363523645236552366523675236852369523705237152372523735237452375523765237752378523795238052381523825238352384523855238652387523885238952390523915239252393523945239552396523975239852399524005240152402524035240452405524065240752408524095241052411524125241352414524155241652417524185241952420524215242252423524245242552426524275242852429524305243152432524335243452435524365243752438524395244052441524425244352444524455244652447524485244952450524515245252453524545245552456524575245852459524605246152462524635246452465524665246752468524695247052471524725247352474524755247652477524785247952480524815248252483524845248552486524875248852489524905249152492524935249452495524965249752498524995250052501525025250352504525055250652507525085250952510525115251252513525145251552516525175251852519525205252152522525235252452525525265252752528525295253052531525325253352534525355253652537525385253952540525415254252543525445254552546525475254852549525505255152552525535255452555525565255752558525595256052561525625256352564525655256652567525685256952570525715257252573525745257552576525775257852579525805258152582525835258452585525865258752588525895259052591525925259352594525955259652597525985259952600526015260252603526045260552606526075260852609526105261152612526135261452615526165261752618526195262052621526225262352624526255262652627526285262952630526315263252633526345263552636526375263852639526405264152642526435264452645526465264752648526495265052651526525265352654526555265652657526585265952660526615266252663526645266552666526675266852669526705267152672526735267452675526765267752678526795268052681526825268352684526855268652687526885268952690526915269252693526945269552696526975269852699527005270152702527035270452705527065270752708527095271052711527125271352714527155271652717527185271952720527215272252723527245272552726527275272852729527305273152732527335273452735527365273752738527395274052741527425274352744527455274652747527485274952750527515275252753527545275552756527575275852759527605276152762527635276452765527665276752768527695277052771527725277352774527755277652777527785277952780527815278252783527845278552786527875278852789527905279152792527935279452795527965279752798527995280052801528025280352804528055280652807528085280952810528115281252813528145281552816528175281852819528205282152822528235282452825528265282752828528295283052831528325283352834528355283652837528385283952840528415284252843528445284552846528475284852849528505285152852528535285452855528565285752858528595286052861528625286352864528655286652867528685286952870528715287252873528745287552876528775287852879528805288152882528835288452885528865288752888528895289052891528925289352894528955289652897528985289952900529015290252903529045290552906529075290852909529105291152912529135291452915529165291752918529195292052921529225292352924529255292652927529285292952930529315293252933529345293552936529375293852939529405294152942529435294452945529465294752948529495295052951529525295352954529555295652957529585295952960529615296252963529645296552966529675296852969529705297152972529735297452975529765297752978529795298052981529825298352984529855298652987529885298952990529915299252993529945299552996529975299852999530005300153002530035300453005530065300753008530095301053011530125301353014530155301653017530185301953020530215302253023530245302553026530275302853029530305303153032530335303453035530365303753038530395304053041530425304353044530455304653047530485304953050530515305253053530545305553056530575305853059530605306153062530635306453065530665306753068530695307053071530725307353074530755307653077530785307953080530815308253083530845308553086530875308853089530905309153092530935309453095530965309753098530995310053101531025310353104531055310653107531085310953110531115311253113531145311553116531175311853119531205312153122531235312453125531265312753128531295313053131531325313353134531355313653137531385313953140531415314253143531445314553146531475314853149531505315153152531535315453155531565315753158531595316053161531625316353164531655316653167531685316953170531715317253173531745317553176531775317853179531805318153182531835318453185531865318753188531895319053191531925319353194531955319653197531985319953200532015320253203532045320553206532075320853209532105321153212532135321453215532165321753218532195322053221532225322353224532255322653227532285322953230532315323253233532345323553236532375323853239532405324153242532435324453245532465324753248532495325053251532525325353254532555325653257532585325953260532615326253263532645326553266532675326853269532705327153272532735327453275532765327753278532795328053281532825328353284532855328653287532885328953290532915329253293532945329553296532975329853299533005330153302533035330453305533065330753308533095331053311533125331353314533155331653317533185331953320533215332253323533245332553326533275332853329533305333153332533335333453335533365333753338533395334053341533425334353344533455334653347533485334953350533515335253353533545335553356533575335853359533605336153362533635336453365533665336753368533695337053371533725337353374533755337653377533785337953380533815338253383533845338553386533875338853389533905339153392533935339453395533965339753398533995340053401534025340353404534055340653407534085340953410534115341253413534145341553416534175341853419534205342153422534235342453425534265342753428534295343053431534325343353434534355343653437534385343953440534415344253443534445344553446534475344853449534505345153452534535345453455534565345753458534595346053461534625346353464534655346653467534685346953470534715347253473534745347553476534775347853479534805348153482534835348453485534865348753488534895349053491534925349353494534955349653497534985349953500535015350253503535045350553506535075350853509535105351153512535135351453515535165351753518535195352053521535225352353524535255352653527535285352953530535315353253533535345353553536535375353853539535405354153542535435354453545535465354753548535495355053551535525355353554535555355653557535585355953560535615356253563535645356553566535675356853569535705357153572535735357453575535765357753578535795358053581535825358353584535855358653587535885358953590535915359253593535945359553596535975359853599536005360153602536035360453605536065360753608536095361053611536125361353614536155361653617536185361953620536215362253623536245362553626536275362853629536305363153632536335363453635536365363753638536395364053641536425364353644536455364653647536485364953650536515365253653536545365553656536575365853659536605366153662536635366453665536665366753668536695367053671536725367353674536755367653677536785367953680536815368253683536845368553686536875368853689536905369153692536935369453695536965369753698536995370053701537025370353704537055370653707537085370953710537115371253713537145371553716537175371853719537205372153722537235372453725537265372753728537295373053731537325373353734537355373653737537385373953740537415374253743537445374553746537475374853749537505375153752537535375453755537565375753758537595376053761537625376353764537655376653767537685376953770537715377253773537745377553776537775377853779537805378153782537835378453785537865378753788537895379053791537925379353794537955379653797537985379953800538015380253803538045380553806538075380853809538105381153812538135381453815538165381753818538195382053821538225382353824538255382653827538285382953830538315383253833538345383553836538375383853839538405384153842538435384453845538465384753848538495385053851538525385353854538555385653857538585385953860538615386253863538645386553866538675386853869538705387153872538735387453875538765387753878538795388053881538825388353884538855388653887538885388953890538915389253893538945389553896538975389853899539005390153902539035390453905539065390753908539095391053911539125391353914539155391653917539185391953920539215392253923539245392553926539275392853929539305393153932539335393453935539365393753938539395394053941539425394353944539455394653947539485394953950539515395253953539545395553956539575395853959539605396153962539635396453965539665396753968539695397053971539725397353974539755397653977539785397953980539815398253983539845398553986539875398853989539905399153992539935399453995539965399753998539995400054001540025400354004540055400654007540085400954010540115401254013540145401554016540175401854019540205402154022540235402454025540265402754028540295403054031540325403354034540355403654037540385403954040540415404254043540445404554046540475404854049540505405154052540535405454055540565405754058540595406054061540625406354064540655406654067540685406954070540715407254073540745407554076540775407854079540805408154082540835408454085540865408754088540895409054091540925409354094540955409654097540985409954100541015410254103541045410554106541075410854109541105411154112541135411454115541165411754118541195412054121541225412354124541255412654127541285412954130541315413254133541345413554136541375413854139541405414154142541435414454145541465414754148541495415054151541525415354154541555415654157541585415954160541615416254163541645416554166541675416854169541705417154172541735417454175541765417754178541795418054181541825418354184541855418654187541885418954190541915419254193541945419554196541975419854199542005420154202542035420454205542065420754208542095421054211542125421354214542155421654217542185421954220542215422254223542245422554226542275422854229542305423154232542335423454235542365423754238542395424054241542425424354244542455424654247542485424954250542515425254253542545425554256542575425854259542605426154262542635426454265542665426754268542695427054271542725427354274542755427654277542785427954280542815428254283542845428554286542875428854289542905429154292542935429454295542965429754298542995430054301543025430354304543055430654307543085430954310543115431254313543145431554316543175431854319543205432154322543235432454325543265432754328543295433054331543325433354334543355433654337543385433954340543415434254343543445434554346543475434854349543505435154352543535435454355543565435754358543595436054361543625436354364543655436654367543685436954370543715437254373543745437554376543775437854379543805438154382543835438454385543865438754388543895439054391543925439354394543955439654397543985439954400544015440254403544045440554406544075440854409544105441154412544135441454415544165441754418544195442054421544225442354424544255442654427544285442954430544315443254433544345443554436544375443854439544405444154442544435444454445544465444754448544495445054451544525445354454544555445654457544585445954460544615446254463544645446554466544675446854469544705447154472544735447454475544765447754478544795448054481544825448354484544855448654487544885448954490544915449254493544945449554496544975449854499545005450154502545035450454505545065450754508545095451054511545125451354514545155451654517545185451954520545215452254523545245452554526545275452854529545305453154532545335453454535545365453754538545395454054541545425454354544545455454654547545485454954550545515455254553545545455554556545575455854559545605456154562545635456454565545665456754568545695457054571545725457354574545755457654577545785457954580545815458254583545845458554586545875458854589545905459154592545935459454595545965459754598545995460054601546025460354604546055460654607546085460954610546115461254613546145461554616546175461854619546205462154622546235462454625546265462754628546295463054631546325463354634546355463654637546385463954640546415464254643546445464554646546475464854649546505465154652546535465454655546565465754658546595466054661546625466354664546655466654667546685466954670546715467254673546745467554676546775467854679546805468154682546835468454685546865468754688546895469054691546925469354694546955469654697546985469954700547015470254703547045470554706547075470854709547105471154712547135471454715547165471754718547195472054721547225472354724547255472654727547285472954730547315473254733547345473554736547375473854739547405474154742547435474454745547465474754748547495475054751547525475354754547555475654757547585475954760547615476254763547645476554766547675476854769547705477154772547735477454775547765477754778547795478054781547825478354784547855478654787547885478954790547915479254793547945479554796547975479854799548005480154802548035480454805548065480754808548095481054811548125481354814548155481654817548185481954820548215482254823548245482554826548275482854829548305483154832548335483454835548365483754838548395484054841548425484354844548455484654847548485484954850548515485254853548545485554856548575485854859548605486154862548635486454865548665486754868548695487054871548725487354874548755487654877548785487954880548815488254883548845488554886548875488854889548905489154892548935489454895548965489754898548995490054901549025490354904549055490654907549085490954910549115491254913549145491554916549175491854919549205492154922549235492454925549265492754928549295493054931549325493354934549355493654937549385493954940549415494254943549445494554946549475494854949549505495154952549535495454955549565495754958549595496054961549625496354964549655496654967549685496954970549715497254973549745497554976549775497854979549805498154982549835498454985549865498754988549895499054991549925499354994549955499654997549985499955000550015500255003550045500555006550075500855009550105501155012550135501455015550165501755018550195502055021550225502355024550255502655027550285502955030550315503255033550345503555036550375503855039550405504155042550435504455045550465504755048550495505055051550525505355054550555505655057550585505955060550615506255063550645506555066550675506855069550705507155072550735507455075550765507755078550795508055081550825508355084550855508655087550885508955090550915509255093550945509555096550975509855099551005510155102551035510455105551065510755108551095511055111551125511355114551155511655117551185511955120551215512255123551245512555126551275512855129551305513155132551335513455135551365513755138551395514055141551425514355144551455514655147551485514955150551515515255153551545515555156551575515855159551605516155162551635516455165551665516755168551695517055171551725517355174551755517655177551785517955180551815518255183551845518555186551875518855189551905519155192551935519455195551965519755198551995520055201552025520355204552055520655207552085520955210552115521255213552145521555216552175521855219552205522155222552235522455225552265522755228552295523055231552325523355234552355523655237552385523955240552415524255243552445524555246552475524855249552505525155252552535525455255552565525755258552595526055261552625526355264552655526655267552685526955270552715527255273552745527555276552775527855279552805528155282552835528455285552865528755288552895529055291552925529355294552955529655297552985529955300553015530255303553045530555306553075530855309553105531155312553135531455315553165531755318553195532055321553225532355324553255532655327553285532955330553315533255333553345533555336553375533855339553405534155342553435534455345553465534755348553495535055351553525535355354553555535655357553585535955360553615536255363553645536555366553675536855369553705537155372553735537455375553765537755378553795538055381553825538355384553855538655387553885538955390553915539255393553945539555396553975539855399554005540155402554035540455405554065540755408554095541055411554125541355414554155541655417554185541955420554215542255423554245542555426554275542855429554305543155432554335543455435554365543755438554395544055441554425544355444554455544655447554485544955450554515545255453554545545555456554575545855459554605546155462554635546455465554665546755468554695547055471554725547355474554755547655477554785547955480554815548255483554845548555486554875548855489554905549155492554935549455495554965549755498554995550055501555025550355504555055550655507555085550955510555115551255513555145551555516555175551855519555205552155522555235552455525555265552755528555295553055531555325553355534555355553655537555385553955540555415554255543555445554555546555475554855549555505555155552555535555455555555565555755558555595556055561555625556355564555655556655567555685556955570555715557255573555745557555576555775557855579555805558155582555835558455585555865558755588555895559055591555925559355594555955559655597555985559955600556015560255603556045560555606556075560855609556105561155612556135561455615556165561755618556195562055621556225562355624556255562655627556285562955630556315563255633556345563555636556375563855639556405564155642556435564455645556465564755648556495565055651556525565355654556555565655657556585565955660556615566255663556645566555666556675566855669556705567155672556735567455675556765567755678556795568055681556825568355684556855568655687556885568955690556915569255693556945569555696556975569855699557005570155702557035570455705557065570755708557095571055711557125571355714557155571655717557185571955720557215572255723557245572555726557275572855729557305573155732557335573455735557365573755738557395574055741557425574355744557455574655747557485574955750557515575255753557545575555756557575575855759557605576155762557635576455765557665576755768557695577055771557725577355774557755577655777557785577955780557815578255783557845578555786557875578855789557905579155792557935579455795557965579755798557995580055801558025580355804558055580655807558085580955810558115581255813558145581555816558175581855819558205582155822558235582455825558265582755828558295583055831558325583355834558355583655837558385583955840558415584255843558445584555846558475584855849558505585155852558535585455855558565585755858558595586055861558625586355864558655586655867558685586955870558715587255873558745587555876558775587855879558805588155882558835588455885558865588755888558895589055891558925589355894558955589655897558985589955900559015590255903559045590555906559075590855909559105591155912559135591455915559165591755918559195592055921559225592355924559255592655927559285592955930559315593255933559345593555936559375593855939559405594155942559435594455945559465594755948559495595055951559525595355954559555595655957559585595955960559615596255963559645596555966559675596855969559705597155972559735597455975559765597755978559795598055981559825598355984559855598655987559885598955990559915599255993559945599555996559975599855999560005600156002560035600456005560065600756008560095601056011560125601356014560155601656017560185601956020560215602256023560245602556026560275602856029560305603156032560335603456035560365603756038560395604056041560425604356044560455604656047560485604956050560515605256053560545605556056560575605856059560605606156062560635606456065560665606756068560695607056071560725607356074560755607656077560785607956080560815608256083560845608556086560875608856089560905609156092560935609456095560965609756098560995610056101561025610356104561055610656107561085610956110561115611256113561145611556116561175611856119561205612156122561235612456125561265612756128561295613056131561325613356134561355613656137561385613956140561415614256143561445614556146561475614856149561505615156152561535615456155561565615756158561595616056161561625616356164561655616656167561685616956170561715617256173561745617556176561775617856179561805618156182561835618456185561865618756188561895619056191561925619356194561955619656197561985619956200562015620256203562045620556206562075620856209562105621156212562135621456215562165621756218562195622056221562225622356224562255622656227562285622956230562315623256233562345623556236562375623856239562405624156242562435624456245562465624756248562495625056251562525625356254562555625656257562585625956260562615626256263562645626556266562675626856269562705627156272562735627456275562765627756278562795628056281562825628356284562855628656287562885628956290562915629256293562945629556296562975629856299563005630156302563035630456305563065630756308563095631056311563125631356314563155631656317563185631956320563215632256323563245632556326563275632856329563305633156332563335633456335563365633756338563395634056341563425634356344563455634656347563485634956350563515635256353563545635556356563575635856359563605636156362563635636456365563665636756368563695637056371563725637356374563755637656377563785637956380563815638256383563845638556386563875638856389563905639156392563935639456395563965639756398563995640056401564025640356404564055640656407564085640956410564115641256413564145641556416564175641856419564205642156422564235642456425564265642756428564295643056431564325643356434564355643656437564385643956440564415644256443564445644556446564475644856449564505645156452564535645456455564565645756458564595646056461564625646356464564655646656467564685646956470564715647256473564745647556476564775647856479564805648156482564835648456485564865648756488564895649056491564925649356494564955649656497564985649956500565015650256503565045650556506565075650856509565105651156512565135651456515565165651756518565195652056521565225652356524565255652656527565285652956530565315653256533565345653556536565375653856539565405654156542565435654456545565465654756548565495655056551565525655356554565555655656557565585655956560565615656256563565645656556566565675656856569565705657156572565735657456575565765657756578565795658056581565825658356584565855658656587565885658956590565915659256593565945659556596565975659856599566005660156602566035660456605566065660756608566095661056611566125661356614566155661656617566185661956620566215662256623566245662556626566275662856629566305663156632566335663456635566365663756638566395664056641566425664356644566455664656647566485664956650566515665256653566545665556656566575665856659566605666156662566635666456665566665666756668566695667056671566725667356674566755667656677566785667956680566815668256683566845668556686566875668856689566905669156692566935669456695566965669756698566995670056701567025670356704567055670656707567085670956710567115671256713567145671556716567175671856719567205672156722567235672456725567265672756728567295673056731567325673356734567355673656737567385673956740567415674256743567445674556746567475674856749567505675156752567535675456755567565675756758567595676056761567625676356764567655676656767567685676956770567715677256773567745677556776567775677856779567805678156782567835678456785567865678756788567895679056791567925679356794567955679656797567985679956800568015680256803568045680556806568075680856809568105681156812568135681456815568165681756818568195682056821568225682356824568255682656827568285682956830568315683256833568345683556836568375683856839568405684156842568435684456845568465684756848568495685056851568525685356854568555685656857568585685956860568615686256863568645686556866568675686856869568705687156872568735687456875568765687756878568795688056881568825688356884568855688656887568885688956890568915689256893568945689556896568975689856899569005690156902569035690456905569065690756908569095691056911569125691356914569155691656917569185691956920569215692256923569245692556926569275692856929569305693156932569335693456935569365693756938569395694056941569425694356944569455694656947569485694956950569515695256953569545695556956569575695856959569605696156962569635696456965569665696756968569695697056971569725697356974569755697656977569785697956980569815698256983569845698556986569875698856989569905699156992569935699456995569965699756998569995700057001570025700357004570055700657007570085700957010570115701257013570145701557016570175701857019570205702157022570235702457025570265702757028570295703057031570325703357034570355703657037570385703957040570415704257043570445704557046570475704857049570505705157052570535705457055570565705757058570595706057061570625706357064570655706657067570685706957070570715707257073570745707557076570775707857079570805708157082570835708457085570865708757088570895709057091570925709357094570955709657097570985709957100571015710257103571045710557106571075710857109571105711157112571135711457115571165711757118571195712057121571225712357124571255712657127571285712957130571315713257133571345713557136571375713857139571405714157142571435714457145571465714757148571495715057151571525715357154571555715657157571585715957160571615716257163571645716557166571675716857169571705717157172571735717457175571765717757178571795718057181571825718357184571855718657187571885718957190571915719257193571945719557196571975719857199572005720157202572035720457205572065720757208572095721057211572125721357214572155721657217572185721957220572215722257223572245722557226572275722857229572305723157232572335723457235572365723757238572395724057241572425724357244572455724657247572485724957250572515725257253572545725557256572575725857259572605726157262572635726457265572665726757268572695727057271572725727357274572755727657277572785727957280572815728257283572845728557286572875728857289572905729157292572935729457295572965729757298572995730057301573025730357304573055730657307573085730957310573115731257313573145731557316573175731857319573205732157322573235732457325573265732757328573295733057331573325733357334573355733657337573385733957340573415734257343573445734557346573475734857349573505735157352573535735457355573565735757358573595736057361573625736357364573655736657367573685736957370573715737257373573745737557376573775737857379573805738157382573835738457385573865738757388573895739057391573925739357394573955739657397573985739957400574015740257403574045740557406574075740857409574105741157412574135741457415574165741757418574195742057421574225742357424574255742657427574285742957430574315743257433574345743557436574375743857439574405744157442574435744457445574465744757448574495745057451574525745357454574555745657457574585745957460574615746257463574645746557466574675746857469574705747157472574735747457475574765747757478574795748057481574825748357484574855748657487574885748957490574915749257493574945749557496574975749857499575005750157502575035750457505575065750757508575095751057511575125751357514575155751657517575185751957520575215752257523575245752557526575275752857529575305753157532575335753457535575365753757538575395754057541575425754357544575455754657547575485754957550575515755257553575545755557556575575755857559575605756157562575635756457565575665756757568575695757057571575725757357574575755757657577575785757957580575815758257583575845758557586575875758857589575905759157592575935759457595575965759757598575995760057601576025760357604576055760657607576085760957610576115761257613576145761557616576175761857619576205762157622576235762457625576265762757628576295763057631576325763357634576355763657637576385763957640576415764257643576445764557646576475764857649576505765157652576535765457655576565765757658576595766057661576625766357664576655766657667576685766957670576715767257673576745767557676576775767857679576805768157682576835768457685576865768757688576895769057691576925769357694576955769657697576985769957700577015770257703577045770557706577075770857709577105771157712577135771457715577165771757718577195772057721577225772357724577255772657727577285772957730577315773257733577345773557736577375773857739577405774157742577435774457745577465774757748577495775057751577525775357754577555775657757577585775957760577615776257763577645776557766577675776857769577705777157772577735777457775577765777757778577795778057781577825778357784577855778657787577885778957790577915779257793577945779557796577975779857799578005780157802578035780457805578065780757808578095781057811578125781357814578155781657817578185781957820578215782257823578245782557826578275782857829578305783157832578335783457835578365783757838578395784057841578425784357844578455784657847578485784957850578515785257853578545785557856578575785857859578605786157862578635786457865578665786757868578695787057871578725787357874578755787657877578785787957880578815788257883578845788557886578875788857889578905789157892578935789457895578965789757898578995790057901579025790357904579055790657907579085790957910579115791257913579145791557916579175791857919579205792157922579235792457925579265792757928579295793057931579325793357934579355793657937579385793957940579415794257943579445794557946579475794857949579505795157952579535795457955579565795757958579595796057961579625796357964579655796657967579685796957970579715797257973579745797557976579775797857979579805798157982579835798457985579865798757988579895799057991579925799357994579955799657997579985799958000580015800258003580045800558006580075800858009580105801158012580135801458015580165801758018580195802058021580225802358024580255802658027580285802958030580315803258033580345803558036580375803858039580405804158042580435804458045580465804758048580495805058051580525805358054580555805658057580585805958060580615806258063580645806558066580675806858069580705807158072580735807458075580765807758078580795808058081580825808358084580855808658087580885808958090580915809258093580945809558096580975809858099581005810158102581035810458105581065810758108581095811058111581125811358114581155811658117581185811958120581215812258123581245812558126581275812858129581305813158132581335813458135581365813758138581395814058141581425814358144581455814658147581485814958150581515815258153581545815558156581575815858159581605816158162581635816458165581665816758168581695817058171581725817358174581755817658177581785817958180581815818258183581845818558186581875818858189581905819158192581935819458195581965819758198581995820058201582025820358204582055820658207582085820958210582115821258213582145821558216582175821858219582205822158222582235822458225582265822758228582295823058231582325823358234582355823658237582385823958240582415824258243582445824558246582475824858249582505825158252582535825458255582565825758258582595826058261582625826358264582655826658267582685826958270582715827258273582745827558276582775827858279582805828158282582835828458285582865828758288582895829058291582925829358294582955829658297582985829958300583015830258303583045830558306583075830858309583105831158312583135831458315583165831758318583195832058321583225832358324583255832658327583285832958330583315833258333583345833558336583375833858339583405834158342583435834458345583465834758348583495835058351583525835358354583555835658357583585835958360583615836258363583645836558366583675836858369583705837158372583735837458375583765837758378583795838058381583825838358384583855838658387583885838958390583915839258393583945839558396583975839858399584005840158402584035840458405584065840758408584095841058411584125841358414584155841658417584185841958420584215842258423584245842558426584275842858429584305843158432584335843458435584365843758438584395844058441584425844358444584455844658447584485844958450584515845258453584545845558456584575845858459584605846158462584635846458465584665846758468584695847058471584725847358474584755847658477584785847958480584815848258483584845848558486584875848858489584905849158492584935849458495584965849758498584995850058501585025850358504585055850658507585085850958510585115851258513585145851558516585175851858519585205852158522585235852458525585265852758528585295853058531585325853358534585355853658537585385853958540585415854258543585445854558546585475854858549585505855158552585535855458555585565855758558585595856058561585625856358564585655856658567585685856958570585715857258573585745857558576585775857858579585805858158582585835858458585585865858758588585895859058591585925859358594585955859658597585985859958600586015860258603586045860558606586075860858609586105861158612586135861458615586165861758618586195862058621586225862358624586255862658627586285862958630586315863258633586345863558636586375863858639586405864158642586435864458645586465864758648586495865058651586525865358654586555865658657586585865958660586615866258663586645866558666586675866858669586705867158672586735867458675586765867758678586795868058681586825868358684586855868658687586885868958690586915869258693586945869558696586975869858699587005870158702587035870458705587065870758708587095871058711587125871358714587155871658717587185871958720587215872258723587245872558726587275872858729587305873158732587335873458735587365873758738587395874058741587425874358744587455874658747587485874958750587515875258753587545875558756587575875858759587605876158762587635876458765587665876758768587695877058771587725877358774587755877658777587785877958780587815878258783587845878558786587875878858789587905879158792587935879458795587965879758798587995880058801588025880358804588055880658807588085880958810588115881258813588145881558816588175881858819588205882158822588235882458825588265882758828588295883058831588325883358834588355883658837588385883958840588415884258843588445884558846588475884858849588505885158852588535885458855588565885758858588595886058861588625886358864588655886658867588685886958870588715887258873588745887558876588775887858879588805888158882588835888458885588865888758888588895889058891588925889358894588955889658897588985889958900589015890258903589045890558906589075890858909589105891158912589135891458915589165891758918589195892058921589225892358924589255892658927589285892958930589315893258933589345893558936589375893858939589405894158942589435894458945589465894758948589495895058951589525895358954589555895658957589585895958960589615896258963589645896558966589675896858969589705897158972589735897458975589765897758978589795898058981589825898358984589855898658987589885898958990589915899258993589945899558996589975899858999590005900159002590035900459005590065900759008590095901059011590125901359014590155901659017590185901959020590215902259023590245902559026590275902859029590305903159032590335903459035590365903759038590395904059041590425904359044590455904659047590485904959050590515905259053590545905559056590575905859059590605906159062590635906459065590665906759068590695907059071590725907359074590755907659077590785907959080590815908259083590845908559086590875908859089590905909159092590935909459095590965909759098590995910059101591025910359104591055910659107591085910959110591115911259113591145911559116591175911859119591205912159122591235912459125591265912759128591295913059131591325913359134591355913659137591385913959140591415914259143591445914559146591475914859149591505915159152591535915459155591565915759158591595916059161591625916359164591655916659167591685916959170591715917259173591745917559176591775917859179591805918159182591835918459185591865918759188591895919059191591925919359194591955919659197591985919959200592015920259203592045920559206592075920859209592105921159212592135921459215592165921759218592195922059221592225922359224592255922659227592285922959230592315923259233592345923559236592375923859239592405924159242592435924459245592465924759248592495925059251592525925359254592555925659257592585925959260592615926259263592645926559266592675926859269592705927159272592735927459275592765927759278592795928059281592825928359284592855928659287592885928959290592915929259293592945929559296592975929859299593005930159302593035930459305593065930759308593095931059311593125931359314593155931659317593185931959320593215932259323593245932559326593275932859329593305933159332593335933459335593365933759338593395934059341593425934359344593455934659347593485934959350593515935259353593545935559356593575935859359593605936159362593635936459365593665936759368593695937059371593725937359374593755937659377593785937959380593815938259383593845938559386593875938859389593905939159392593935939459395593965939759398593995940059401594025940359404594055940659407594085940959410594115941259413594145941559416594175941859419594205942159422594235942459425594265942759428594295943059431594325943359434594355943659437594385943959440594415944259443594445944559446594475944859449594505945159452594535945459455594565945759458594595946059461594625946359464594655946659467594685946959470594715947259473594745947559476594775947859479594805948159482594835948459485594865948759488594895949059491594925949359494594955949659497594985949959500595015950259503595045950559506595075950859509595105951159512595135951459515595165951759518595195952059521595225952359524595255952659527595285952959530595315953259533595345953559536595375953859539595405954159542595435954459545595465954759548595495955059551595525955359554595555955659557595585955959560595615956259563595645956559566595675956859569595705957159572595735957459575595765957759578595795958059581595825958359584595855958659587595885958959590595915959259593595945959559596595975959859599596005960159602596035960459605596065960759608596095961059611596125961359614596155961659617596185961959620596215962259623596245962559626596275962859629596305963159632596335963459635596365963759638596395964059641596425964359644596455964659647596485964959650596515965259653596545965559656596575965859659596605966159662596635966459665596665966759668596695967059671596725967359674596755967659677596785967959680596815968259683596845968559686596875968859689596905969159692596935969459695596965969759698596995970059701597025970359704597055970659707597085970959710597115971259713597145971559716597175971859719597205972159722597235972459725597265972759728597295973059731597325973359734597355973659737597385973959740597415974259743597445974559746597475974859749597505975159752597535975459755597565975759758597595976059761597625976359764597655976659767597685976959770597715977259773597745977559776597775977859779597805978159782597835978459785597865978759788597895979059791597925979359794597955979659797597985979959800598015980259803598045980559806598075980859809598105981159812598135981459815598165981759818598195982059821598225982359824598255982659827598285982959830598315983259833598345983559836598375983859839598405984159842598435984459845598465984759848598495985059851598525985359854598555985659857598585985959860598615986259863598645986559866598675986859869598705987159872598735987459875598765987759878598795988059881598825988359884598855988659887598885988959890598915989259893598945989559896598975989859899599005990159902599035990459905599065990759908599095991059911599125991359914599155991659917599185991959920599215992259923599245992559926599275992859929599305993159932599335993459935599365993759938599395994059941599425994359944599455994659947599485994959950599515995259953599545995559956599575995859959599605996159962599635996459965599665996759968599695997059971599725997359974599755997659977599785997959980599815998259983599845998559986599875998859989599905999159992599935999459995599965999759998599996000060001600026000360004600056000660007600086000960010600116001260013600146001560016600176001860019600206002160022600236002460025600266002760028600296003060031600326003360034600356003660037600386003960040600416004260043600446004560046600476004860049600506005160052600536005460055600566005760058600596006060061600626006360064600656006660067600686006960070600716007260073600746007560076600776007860079600806008160082600836008460085600866008760088600896009060091600926009360094600956009660097600986009960100601016010260103601046010560106601076010860109601106011160112601136011460115601166011760118601196012060121601226012360124601256012660127601286012960130601316013260133601346013560136601376013860139601406014160142601436014460145601466014760148601496015060151601526015360154601556015660157601586015960160601616016260163601646016560166601676016860169601706017160172601736017460175601766017760178601796018060181601826018360184601856018660187601886018960190601916019260193601946019560196601976019860199602006020160202602036020460205602066020760208602096021060211602126021360214602156021660217602186021960220602216022260223602246022560226602276022860229602306023160232602336023460235602366023760238602396024060241602426024360244602456024660247602486024960250602516025260253602546025560256602576025860259602606026160262602636026460265602666026760268602696027060271602726027360274602756027660277602786027960280602816028260283602846028560286602876028860289602906029160292602936029460295602966029760298602996030060301603026030360304603056030660307603086030960310603116031260313603146031560316603176031860319603206032160322603236032460325603266032760328603296033060331603326033360334603356033660337603386033960340603416034260343603446034560346603476034860349603506035160352603536035460355603566035760358603596036060361603626036360364603656036660367603686036960370603716037260373603746037560376603776037860379603806038160382603836038460385603866038760388603896039060391603926039360394603956039660397603986039960400604016040260403604046040560406604076040860409604106041160412604136041460415604166041760418604196042060421604226042360424604256042660427604286042960430604316043260433604346043560436604376043860439604406044160442604436044460445604466044760448604496045060451604526045360454604556045660457604586045960460604616046260463604646046560466604676046860469604706047160472604736047460475604766047760478604796048060481604826048360484604856048660487604886048960490604916049260493604946049560496604976049860499605006050160502605036050460505605066050760508605096051060511605126051360514605156051660517605186051960520605216052260523605246052560526605276052860529605306053160532605336053460535605366053760538605396054060541605426054360544605456054660547605486054960550605516055260553605546055560556605576055860559605606056160562605636056460565605666056760568605696057060571605726057360574605756057660577605786057960580605816058260583605846058560586605876058860589605906059160592605936059460595605966059760598605996060060601606026060360604606056060660607606086060960610606116061260613606146061560616606176061860619606206062160622606236062460625606266062760628606296063060631606326063360634606356063660637606386063960640606416064260643606446064560646606476064860649606506065160652606536065460655606566065760658606596066060661606626066360664606656066660667606686066960670606716067260673606746067560676606776067860679606806068160682606836068460685606866068760688606896069060691606926069360694606956069660697606986069960700607016070260703607046070560706607076070860709607106071160712607136071460715607166071760718607196072060721607226072360724607256072660727607286072960730607316073260733607346073560736607376073860739607406074160742607436074460745607466074760748607496075060751607526075360754607556075660757607586075960760607616076260763607646076560766607676076860769607706077160772607736077460775607766077760778607796078060781607826078360784607856078660787607886078960790607916079260793607946079560796607976079860799608006080160802608036080460805608066080760808608096081060811608126081360814608156081660817608186081960820608216082260823608246082560826608276082860829608306083160832608336083460835608366083760838608396084060841608426084360844608456084660847608486084960850608516085260853608546085560856608576085860859608606086160862608636086460865608666086760868608696087060871608726087360874608756087660877608786087960880608816088260883608846088560886608876088860889608906089160892608936089460895608966089760898608996090060901609026090360904609056090660907609086090960910609116091260913609146091560916609176091860919609206092160922609236092460925609266092760928609296093060931609326093360934609356093660937609386093960940609416094260943609446094560946609476094860949609506095160952609536095460955609566095760958609596096060961609626096360964609656096660967609686096960970609716097260973609746097560976609776097860979609806098160982609836098460985609866098760988609896099060991609926099360994609956099660997609986099961000610016100261003610046100561006610076100861009610106101161012610136101461015610166101761018610196102061021610226102361024610256102661027610286102961030610316103261033610346103561036610376103861039610406104161042610436104461045610466104761048610496105061051610526105361054610556105661057610586105961060610616106261063610646106561066610676106861069610706107161072610736107461075610766107761078610796108061081610826108361084610856108661087610886108961090610916109261093610946109561096610976109861099611006110161102611036110461105611066110761108611096111061111611126111361114611156111661117611186111961120611216112261123611246112561126611276112861129611306113161132611336113461135611366113761138611396114061141611426114361144611456114661147611486114961150611516115261153611546115561156611576115861159611606116161162611636116461165611666116761168611696117061171611726117361174611756117661177611786117961180611816118261183611846118561186611876118861189611906119161192611936119461195611966119761198611996120061201612026120361204612056120661207612086120961210612116121261213612146121561216612176121861219612206122161222612236122461225612266122761228612296123061231612326123361234612356123661237612386123961240612416124261243612446124561246612476124861249612506125161252612536125461255612566125761258612596126061261612626126361264612656126661267612686126961270612716127261273612746127561276612776127861279612806128161282612836128461285612866128761288612896129061291612926129361294612956129661297612986129961300613016130261303613046130561306613076130861309613106131161312613136131461315613166131761318613196132061321613226132361324613256132661327613286132961330613316133261333613346133561336613376133861339613406134161342613436134461345613466134761348613496135061351613526135361354613556135661357613586135961360613616136261363613646136561366613676136861369613706137161372613736137461375613766137761378613796138061381613826138361384613856138661387613886138961390613916139261393613946139561396613976139861399614006140161402614036140461405614066140761408614096141061411614126141361414614156141661417614186141961420614216142261423614246142561426614276142861429614306143161432614336143461435614366143761438614396144061441614426144361444614456144661447614486144961450614516145261453614546145561456614576145861459614606146161462614636146461465614666146761468614696147061471614726147361474614756147661477614786147961480614816148261483614846148561486614876148861489614906149161492614936149461495614966149761498614996150061501615026150361504615056150661507615086150961510615116151261513615146151561516615176151861519615206152161522615236152461525615266152761528615296153061531615326153361534615356153661537615386153961540615416154261543615446154561546615476154861549615506155161552615536155461555615566155761558615596156061561615626156361564615656156661567615686156961570615716157261573615746157561576615776157861579615806158161582615836158461585615866158761588615896159061591615926159361594615956159661597615986159961600616016160261603616046160561606616076160861609616106161161612616136161461615616166161761618616196162061621616226162361624616256162661627616286162961630616316163261633616346163561636616376163861639616406164161642616436164461645616466164761648616496165061651616526165361654616556165661657616586165961660616616166261663616646166561666616676166861669616706167161672616736167461675616766167761678616796168061681616826168361684616856168661687616886168961690616916169261693616946169561696616976169861699617006170161702617036170461705617066170761708617096171061711617126171361714617156171661717617186171961720617216172261723617246172561726617276172861729617306173161732617336173461735617366173761738617396174061741617426174361744617456174661747617486174961750617516175261753617546175561756617576175861759617606176161762617636176461765617666176761768617696177061771617726177361774617756177661777617786177961780617816178261783617846178561786617876178861789617906179161792617936179461795617966179761798617996180061801618026180361804618056180661807618086180961810618116181261813618146181561816618176181861819618206182161822618236182461825618266182761828618296183061831618326183361834618356183661837618386183961840618416184261843618446184561846618476184861849618506185161852618536185461855618566185761858618596186061861618626186361864618656186661867618686186961870618716187261873618746187561876618776187861879618806188161882618836188461885618866188761888618896189061891618926189361894618956189661897618986189961900619016190261903619046190561906619076190861909619106191161912619136191461915619166191761918619196192061921619226192361924619256192661927619286192961930619316193261933619346193561936619376193861939619406194161942619436194461945619466194761948619496195061951619526195361954619556195661957619586195961960619616196261963619646196561966619676196861969619706197161972619736197461975619766197761978619796198061981619826198361984619856198661987619886198961990619916199261993619946199561996619976199861999620006200162002620036200462005620066200762008620096201062011620126201362014620156201662017620186201962020620216202262023620246202562026620276202862029620306203162032620336203462035620366203762038620396204062041620426204362044620456204662047620486204962050620516205262053620546205562056620576205862059620606206162062620636206462065620666206762068620696207062071620726207362074620756207662077620786207962080620816208262083620846208562086620876208862089620906209162092620936209462095620966209762098620996210062101621026210362104621056210662107621086210962110621116211262113621146211562116621176211862119621206212162122621236212462125621266212762128621296213062131621326213362134621356213662137621386213962140621416214262143621446214562146621476214862149621506215162152621536215462155621566215762158621596216062161621626216362164621656216662167621686216962170621716217262173621746217562176621776217862179621806218162182621836218462185621866218762188621896219062191621926219362194621956219662197621986219962200622016220262203622046220562206622076220862209622106221162212622136221462215622166221762218622196222062221622226222362224622256222662227622286222962230622316223262233622346223562236622376223862239622406224162242622436224462245622466224762248622496225062251622526225362254622556225662257622586225962260622616226262263622646226562266622676226862269622706227162272622736227462275622766227762278622796228062281622826228362284622856228662287622886228962290622916229262293622946229562296622976229862299623006230162302623036230462305623066230762308623096231062311623126231362314623156231662317623186231962320623216232262323623246232562326623276232862329623306233162332623336233462335623366233762338623396234062341623426234362344623456234662347623486234962350623516235262353623546235562356623576235862359623606236162362623636236462365623666236762368623696237062371623726237362374623756237662377623786237962380623816238262383623846238562386623876238862389623906239162392623936239462395623966239762398623996240062401624026240362404624056240662407624086240962410624116241262413624146241562416624176241862419624206242162422624236242462425624266242762428624296243062431624326243362434624356243662437624386243962440624416244262443624446244562446624476244862449624506245162452624536245462455624566245762458624596246062461624626246362464624656246662467624686246962470624716247262473624746247562476624776247862479624806248162482624836248462485624866248762488624896249062491624926249362494624956249662497624986249962500625016250262503625046250562506625076250862509625106251162512625136251462515625166251762518625196252062521625226252362524625256252662527625286252962530625316253262533625346253562536625376253862539625406254162542625436254462545625466254762548625496255062551625526255362554625556255662557625586255962560625616256262563625646256562566625676256862569625706257162572625736257462575625766257762578625796258062581625826258362584625856258662587625886258962590625916259262593625946259562596625976259862599626006260162602626036260462605626066260762608626096261062611626126261362614626156261662617626186261962620626216262262623626246262562626626276262862629626306263162632626336263462635626366263762638626396264062641626426264362644626456264662647626486264962650626516265262653626546265562656626576265862659626606266162662626636266462665626666266762668626696267062671626726267362674626756267662677626786267962680626816268262683626846268562686626876268862689626906269162692626936269462695626966269762698626996270062701627026270362704627056270662707627086270962710627116271262713627146271562716627176271862719627206272162722627236272462725627266272762728627296273062731627326273362734627356273662737627386273962740627416274262743627446274562746627476274862749627506275162752627536275462755627566275762758627596276062761627626276362764627656276662767627686276962770627716277262773627746277562776627776277862779627806278162782627836278462785627866278762788627896279062791627926279362794627956279662797627986279962800628016280262803628046280562806628076280862809628106281162812628136281462815628166281762818628196282062821628226282362824628256282662827628286282962830628316283262833628346283562836628376283862839628406284162842628436284462845628466284762848628496285062851628526285362854628556285662857628586285962860628616286262863628646286562866628676286862869628706287162872628736287462875628766287762878628796288062881628826288362884628856288662887628886288962890628916289262893628946289562896628976289862899629006290162902629036290462905629066290762908629096291062911629126291362914629156291662917629186291962920629216292262923629246292562926629276292862929629306293162932629336293462935629366293762938629396294062941629426294362944629456294662947629486294962950629516295262953629546295562956629576295862959629606296162962629636296462965629666296762968629696297062971629726297362974629756297662977629786297962980629816298262983629846298562986629876298862989629906299162992629936299462995629966299762998629996300063001630026300363004630056300663007630086300963010630116301263013630146301563016630176301863019630206302163022630236302463025630266302763028630296303063031630326303363034630356303663037630386303963040630416304263043630446304563046630476304863049630506305163052630536305463055630566305763058630596306063061630626306363064630656306663067630686306963070630716307263073630746307563076630776307863079630806308163082630836308463085630866308763088630896309063091630926309363094630956309663097630986309963100631016310263103631046310563106631076310863109631106311163112631136311463115631166311763118631196312063121631226312363124631256312663127631286312963130631316313263133631346313563136631376313863139631406314163142631436314463145631466314763148631496315063151631526315363154631556315663157631586315963160631616316263163631646316563166631676316863169631706317163172631736317463175631766317763178631796318063181631826318363184631856318663187631886318963190631916319263193631946319563196631976319863199632006320163202632036320463205632066320763208632096321063211632126321363214632156321663217632186321963220632216322263223632246322563226632276322863229632306323163232632336323463235632366323763238632396324063241632426324363244632456324663247632486324963250632516325263253632546325563256632576325863259632606326163262632636326463265632666326763268632696327063271632726327363274632756327663277632786327963280632816328263283632846328563286632876328863289632906329163292632936329463295632966329763298632996330063301633026330363304633056330663307633086330963310633116331263313633146331563316633176331863319633206332163322633236332463325633266332763328633296333063331633326333363334633356333663337633386333963340633416334263343633446334563346633476334863349633506335163352633536335463355633566335763358633596336063361633626336363364633656336663367633686336963370633716337263373633746337563376633776337863379633806338163382633836338463385633866338763388633896339063391633926339363394633956339663397633986339963400634016340263403634046340563406634076340863409634106341163412634136341463415634166341763418634196342063421634226342363424634256342663427634286342963430634316343263433634346343563436634376343863439634406344163442634436344463445634466344763448634496345063451634526345363454634556345663457634586345963460634616346263463634646346563466634676346863469634706347163472634736347463475634766347763478634796348063481634826348363484634856348663487634886348963490634916349263493634946349563496634976349863499635006350163502635036350463505635066350763508635096351063511635126351363514635156351663517635186351963520635216352263523635246352563526635276352863529635306353163532635336353463535635366353763538635396354063541635426354363544635456354663547635486354963550635516355263553635546355563556635576355863559635606356163562635636356463565635666356763568635696357063571635726357363574635756357663577635786357963580635816358263583635846358563586635876358863589635906359163592635936359463595635966359763598635996360063601636026360363604636056360663607636086360963610636116361263613636146361563616636176361863619636206362163622636236362463625636266362763628636296363063631636326363363634636356363663637636386363963640636416364263643636446364563646636476364863649636506365163652636536365463655636566365763658636596366063661636626366363664636656366663667636686366963670636716367263673636746367563676636776367863679636806368163682636836368463685636866368763688636896369063691636926369363694636956369663697636986369963700637016370263703637046370563706637076370863709637106371163712637136371463715637166371763718637196372063721637226372363724637256372663727637286372963730637316373263733637346373563736637376373863739637406374163742637436374463745637466374763748637496375063751637526375363754637556375663757637586375963760637616376263763637646376563766637676376863769637706377163772637736377463775637766377763778637796378063781637826378363784637856378663787637886378963790637916379263793637946379563796637976379863799638006380163802638036380463805638066380763808638096381063811638126381363814638156381663817638186381963820638216382263823638246382563826638276382863829638306383163832638336383463835638366383763838638396384063841638426384363844638456384663847638486384963850638516385263853638546385563856638576385863859638606386163862638636386463865638666386763868638696387063871638726387363874638756387663877638786387963880638816388263883638846388563886638876388863889638906389163892638936389463895638966389763898638996390063901639026390363904639056390663907639086390963910639116391263913639146391563916639176391863919639206392163922639236392463925639266392763928639296393063931639326393363934639356393663937639386393963940639416394263943639446394563946639476394863949639506395163952639536395463955639566395763958639596396063961639626396363964639656396663967639686396963970639716397263973639746397563976639776397863979639806398163982639836398463985639866398763988639896399063991639926399363994639956399663997639986399964000640016400264003640046400564006640076400864009640106401164012640136401464015640166401764018640196402064021640226402364024640256402664027640286402964030640316403264033640346403564036640376403864039640406404164042640436404464045640466404764048640496405064051640526405364054640556405664057640586405964060640616406264063640646406564066640676406864069640706407164072640736407464075640766407764078640796408064081640826408364084640856408664087640886408964090640916409264093640946409564096640976409864099641006410164102641036410464105641066410764108641096411064111641126411364114641156411664117641186411964120641216412264123641246412564126641276412864129641306413164132641336413464135641366413764138641396414064141641426414364144641456414664147641486414964150641516415264153641546415564156641576415864159641606416164162641636416464165641666416764168641696417064171641726417364174641756417664177641786417964180641816418264183641846418564186641876418864189641906419164192641936419464195641966419764198641996420064201642026420364204642056420664207642086420964210642116421264213642146421564216642176421864219642206422164222642236422464225642266422764228642296423064231642326423364234642356423664237642386423964240642416424264243642446424564246642476424864249642506425164252642536425464255642566425764258642596426064261642626426364264642656426664267642686426964270642716427264273642746427564276642776427864279642806428164282642836428464285642866428764288642896429064291642926429364294642956429664297642986429964300643016430264303643046430564306643076430864309643106431164312643136431464315643166431764318643196432064321643226432364324643256432664327643286432964330643316433264333643346433564336643376433864339643406434164342643436434464345643466434764348643496435064351643526435364354643556435664357643586435964360643616436264363643646436564366643676436864369643706437164372643736437464375643766437764378643796438064381643826438364384643856438664387643886438964390643916439264393643946439564396643976439864399644006440164402644036440464405644066440764408644096441064411644126441364414644156441664417644186441964420644216442264423644246442564426644276442864429644306443164432644336443464435644366443764438644396444064441644426444364444644456444664447644486444964450644516445264453644546445564456644576445864459644606446164462644636446464465644666446764468644696447064471644726447364474644756447664477644786447964480644816448264483644846448564486644876448864489644906449164492644936449464495644966449764498644996450064501645026450364504645056450664507645086450964510645116451264513645146451564516645176451864519645206452164522645236452464525645266452764528645296453064531645326453364534645356453664537645386453964540645416454264543645446454564546645476454864549645506455164552645536455464555645566455764558645596456064561645626456364564645656456664567645686456964570645716457264573645746457564576645776457864579645806458164582645836458464585645866458764588645896459064591645926459364594645956459664597645986459964600646016460264603646046460564606646076460864609646106461164612646136461464615646166461764618646196462064621646226462364624646256462664627646286462964630646316463264633646346463564636646376463864639646406464164642646436464464645646466464764648646496465064651646526465364654646556465664657646586465964660646616466264663646646466564666646676466864669646706467164672646736467464675646766467764678646796468064681646826468364684646856468664687646886468964690646916469264693646946469564696646976469864699647006470164702647036470464705647066470764708647096471064711647126471364714647156471664717647186471964720647216472264723647246472564726647276472864729647306473164732647336473464735647366473764738647396474064741647426474364744647456474664747647486474964750647516475264753647546475564756647576475864759647606476164762647636476464765647666476764768647696477064771647726477364774647756477664777647786477964780647816478264783647846478564786647876478864789647906479164792647936479464795647966479764798647996480064801648026480364804648056480664807648086480964810648116481264813648146481564816648176481864819648206482164822648236482464825648266482764828648296483064831648326483364834648356483664837648386483964840648416484264843648446484564846648476484864849648506485164852648536485464855648566485764858648596486064861648626486364864648656486664867648686486964870648716487264873648746487564876648776487864879648806488164882648836488464885648866488764888648896489064891648926489364894648956489664897648986489964900649016490264903649046490564906649076490864909649106491164912649136491464915649166491764918649196492064921649226492364924649256492664927649286492964930649316493264933649346493564936649376493864939649406494164942649436494464945649466494764948649496495064951649526495364954649556495664957649586495964960649616496264963649646496564966649676496864969649706497164972649736497464975649766497764978649796498064981649826498364984649856498664987649886498964990649916499264993649946499564996649976499864999650006500165002650036500465005650066500765008650096501065011650126501365014650156501665017650186501965020650216502265023650246502565026650276502865029650306503165032650336503465035650366503765038650396504065041650426504365044650456504665047650486504965050650516505265053650546505565056650576505865059650606506165062650636506465065650666506765068650696507065071650726507365074650756507665077650786507965080650816508265083650846508565086650876508865089650906509165092650936509465095650966509765098650996510065101651026510365104651056510665107651086510965110651116511265113651146511565116651176511865119651206512165122651236512465125651266512765128651296513065131651326513365134651356513665137651386513965140651416514265143651446514565146651476514865149651506515165152651536515465155651566515765158651596516065161651626516365164651656516665167651686516965170651716517265173651746517565176651776517865179651806518165182651836518465185651866518765188651896519065191651926519365194651956519665197651986519965200652016520265203652046520565206652076520865209652106521165212652136521465215652166521765218652196522065221652226522365224652256522665227652286522965230652316523265233652346523565236652376523865239652406524165242652436524465245652466524765248652496525065251652526525365254652556525665257652586525965260652616526265263652646526565266652676526865269652706527165272652736527465275652766527765278652796528065281652826528365284652856528665287652886528965290652916529265293652946529565296652976529865299653006530165302653036530465305653066530765308653096531065311653126531365314653156531665317653186531965320653216532265323653246532565326653276532865329653306533165332653336533465335653366533765338653396534065341653426534365344653456534665347653486534965350653516535265353653546535565356653576535865359653606536165362653636536465365653666536765368653696537065371653726537365374653756537665377653786537965380653816538265383653846538565386653876538865389653906539165392653936539465395653966539765398653996540065401654026540365404654056540665407654086540965410654116541265413654146541565416654176541865419654206542165422654236542465425654266542765428654296543065431654326543365434654356543665437654386543965440654416544265443654446544565446654476544865449654506545165452654536545465455654566545765458654596546065461654626546365464654656546665467654686546965470654716547265473654746547565476654776547865479654806548165482654836548465485654866548765488654896549065491654926549365494654956549665497654986549965500655016550265503655046550565506655076550865509655106551165512655136551465515655166551765518655196552065521655226552365524655256552665527655286552965530655316553265533655346553565536655376553865539655406554165542655436554465545655466554765548655496555065551655526555365554655556555665557655586555965560655616556265563655646556565566655676556865569655706557165572655736557465575655766557765578655796558065581655826558365584655856558665587655886558965590655916559265593655946559565596655976559865599656006560165602656036560465605656066560765608656096561065611656126561365614656156561665617656186561965620656216562265623656246562565626656276562865629656306563165632656336563465635656366563765638656396564065641656426564365644656456564665647656486564965650656516565265653656546565565656656576565865659656606566165662656636566465665656666566765668656696567065671656726567365674656756567665677656786567965680656816568265683656846568565686656876568865689656906569165692656936569465695656966569765698656996570065701657026570365704657056570665707657086570965710657116571265713657146571565716657176571865719657206572165722657236572465725657266572765728657296573065731657326573365734657356573665737657386573965740657416574265743657446574565746657476574865749657506575165752657536575465755657566575765758657596576065761657626576365764657656576665767657686576965770657716577265773657746577565776657776577865779657806578165782657836578465785657866578765788657896579065791657926579365794657956579665797657986579965800658016580265803658046580565806658076580865809658106581165812658136581465815658166581765818658196582065821658226582365824658256582665827658286582965830658316583265833658346583565836658376583865839658406584165842658436584465845658466584765848658496585065851658526585365854658556585665857658586585965860658616586265863658646586565866658676586865869658706587165872658736587465875658766587765878658796588065881658826588365884658856588665887658886588965890658916589265893658946589565896658976589865899659006590165902659036590465905659066590765908659096591065911659126591365914659156591665917659186591965920659216592265923659246592565926659276592865929659306593165932659336593465935659366593765938659396594065941659426594365944659456594665947659486594965950659516595265953659546595565956659576595865959659606596165962659636596465965659666596765968659696597065971659726597365974659756597665977659786597965980659816598265983659846598565986659876598865989659906599165992659936599465995659966599765998659996600066001660026600366004660056600666007660086600966010660116601266013660146601566016660176601866019660206602166022660236602466025660266602766028660296603066031660326603366034660356603666037660386603966040660416604266043660446604566046660476604866049660506605166052660536605466055660566605766058660596606066061660626606366064660656606666067660686606966070660716607266073660746607566076660776607866079660806608166082660836608466085660866608766088660896609066091660926609366094660956609666097660986609966100661016610266103661046610566106661076610866109661106611166112661136611466115661166611766118661196612066121661226612366124661256612666127661286612966130661316613266133661346613566136661376613866139661406614166142661436614466145661466614766148661496615066151661526615366154661556615666157661586615966160661616616266163661646616566166661676616866169661706617166172661736617466175661766617766178661796618066181661826618366184661856618666187661886618966190661916619266193661946619566196661976619866199662006620166202662036620466205662066620766208662096621066211662126621366214662156621666217662186621966220662216622266223662246622566226662276622866229662306623166232662336623466235662366623766238662396624066241662426624366244662456624666247662486624966250662516625266253662546625566256662576625866259662606626166262662636626466265662666626766268662696627066271662726627366274662756627666277662786627966280662816628266283662846628566286662876628866289662906629166292662936629466295662966629766298662996630066301663026630366304663056630666307663086630966310663116631266313663146631566316663176631866319663206632166322663236632466325663266632766328663296633066331663326633366334663356633666337663386633966340663416634266343663446634566346663476634866349663506635166352663536635466355663566635766358663596636066361663626636366364663656636666367663686636966370663716637266373663746637566376663776637866379663806638166382663836638466385663866638766388663896639066391663926639366394663956639666397663986639966400664016640266403664046640566406664076640866409664106641166412664136641466415664166641766418664196642066421664226642366424664256642666427664286642966430664316643266433664346643566436664376643866439664406644166442664436644466445664466644766448664496645066451664526645366454664556645666457664586645966460664616646266463664646646566466664676646866469664706647166472664736647466475664766647766478664796648066481664826648366484664856648666487664886648966490664916649266493664946649566496664976649866499665006650166502665036650466505665066650766508665096651066511665126651366514665156651666517665186651966520665216652266523665246652566526665276652866529665306653166532665336653466535665366653766538665396654066541665426654366544665456654666547665486654966550665516655266553665546655566556665576655866559665606656166562665636656466565665666656766568665696657066571665726657366574665756657666577665786657966580665816658266583665846658566586665876658866589665906659166592665936659466595665966659766598665996660066601666026660366604666056660666607666086660966610666116661266613666146661566616666176661866619666206662166622666236662466625666266662766628666296663066631666326663366634666356663666637666386663966640666416664266643666446664566646666476664866649666506665166652666536665466655666566665766658666596666066661666626666366664666656666666667666686666966670666716667266673666746667566676666776667866679666806668166682666836668466685666866668766688666896669066691666926669366694666956669666697666986669966700667016670266703667046670566706667076670866709667106671166712667136671466715667166671766718667196672066721667226672366724667256672666727667286672966730667316673266733667346673566736667376673866739667406674166742667436674466745667466674766748667496675066751667526675366754667556675666757667586675966760667616676266763667646676566766667676676866769667706677166772667736677466775667766677766778667796678066781667826678366784667856678666787667886678966790667916679266793667946679566796667976679866799668006680166802668036680466805668066680766808668096681066811668126681366814668156681666817668186681966820668216682266823668246682566826668276682866829668306683166832668336683466835668366683766838668396684066841668426684366844668456684666847668486684966850668516685266853668546685566856668576685866859668606686166862668636686466865668666686766868668696687066871668726687366874668756687666877668786687966880668816688266883668846688566886668876688866889668906689166892668936689466895668966689766898668996690066901669026690366904669056690666907669086690966910669116691266913669146691566916669176691866919669206692166922669236692466925669266692766928669296693066931669326693366934669356693666937669386693966940669416694266943669446694566946669476694866949669506695166952669536695466955669566695766958669596696066961669626696366964669656696666967669686696966970669716697266973669746697566976669776697866979669806698166982669836698466985669866698766988669896699066991669926699366994669956699666997669986699967000670016700267003670046700567006670076700867009670106701167012670136701467015670166701767018670196702067021670226702367024670256702667027670286702967030670316703267033670346703567036670376703867039670406704167042670436704467045670466704767048670496705067051670526705367054670556705667057670586705967060670616706267063670646706567066670676706867069670706707167072670736707467075670766707767078670796708067081670826708367084670856708667087670886708967090670916709267093670946709567096670976709867099671006710167102671036710467105671066710767108671096711067111671126711367114671156711667117671186711967120671216712267123671246712567126671276712867129671306713167132671336713467135671366713767138671396714067141671426714367144671456714667147671486714967150671516715267153671546715567156671576715867159671606716167162671636716467165671666716767168671696717067171671726717367174671756717667177671786717967180671816718267183671846718567186671876718867189671906719167192671936719467195671966719767198671996720067201672026720367204672056720667207672086720967210672116721267213672146721567216672176721867219672206722167222672236722467225672266722767228672296723067231672326723367234672356723667237672386723967240672416724267243672446724567246672476724867249672506725167252672536725467255672566725767258672596726067261672626726367264672656726667267672686726967270672716727267273672746727567276672776727867279672806728167282672836728467285672866728767288672896729067291672926729367294672956729667297672986729967300673016730267303673046730567306673076730867309673106731167312673136731467315673166731767318673196732067321673226732367324673256732667327673286732967330673316733267333673346733567336673376733867339673406734167342673436734467345673466734767348673496735067351673526735367354673556735667357673586735967360673616736267363673646736567366673676736867369673706737167372673736737467375673766737767378673796738067381673826738367384673856738667387673886738967390673916739267393673946739567396673976739867399674006740167402674036740467405674066740767408674096741067411674126741367414674156741667417674186741967420674216742267423674246742567426674276742867429674306743167432674336743467435674366743767438674396744067441674426744367444674456744667447674486744967450674516745267453674546745567456674576745867459674606746167462674636746467465674666746767468674696747067471674726747367474674756747667477674786747967480674816748267483674846748567486674876748867489674906749167492674936749467495674966749767498674996750067501675026750367504675056750667507675086750967510675116751267513675146751567516675176751867519675206752167522675236752467525675266752767528675296753067531675326753367534675356753667537675386753967540675416754267543675446754567546675476754867549675506755167552675536755467555675566755767558675596756067561675626756367564675656756667567675686756967570675716757267573675746757567576675776757867579675806758167582675836758467585675866758767588675896759067591675926759367594675956759667597675986759967600676016760267603676046760567606676076760867609676106761167612676136761467615676166761767618676196762067621676226762367624676256762667627676286762967630676316763267633676346763567636676376763867639676406764167642676436764467645676466764767648676496765067651676526765367654676556765667657676586765967660676616766267663676646766567666676676766867669676706767167672676736767467675676766767767678676796768067681676826768367684676856768667687676886768967690676916769267693676946769567696676976769867699677006770167702677036770467705677066770767708677096771067711677126771367714677156771667717677186771967720677216772267723677246772567726677276772867729677306773167732677336773467735677366773767738677396774067741677426774367744677456774667747677486774967750677516775267753677546775567756677576775867759677606776167762677636776467765677666776767768677696777067771677726777367774677756777667777677786777967780677816778267783677846778567786677876778867789677906779167792677936779467795677966779767798677996780067801678026780367804678056780667807678086780967810678116781267813678146781567816678176781867819678206782167822678236782467825678266782767828678296783067831678326783367834678356783667837678386783967840678416784267843678446784567846678476784867849678506785167852678536785467855678566785767858678596786067861678626786367864678656786667867678686786967870678716787267873678746787567876678776787867879678806788167882678836788467885678866788767888678896789067891678926789367894678956789667897678986789967900679016790267903679046790567906679076790867909679106791167912679136791467915679166791767918679196792067921679226792367924679256792667927679286792967930679316793267933679346793567936679376793867939679406794167942679436794467945679466794767948679496795067951679526795367954679556795667957679586795967960679616796267963679646796567966679676796867969679706797167972679736797467975679766797767978679796798067981679826798367984679856798667987679886798967990679916799267993679946799567996679976799867999680006800168002680036800468005680066800768008680096801068011680126801368014680156801668017680186801968020680216802268023680246802568026680276802868029680306803168032680336803468035680366803768038680396804068041680426804368044680456804668047680486804968050680516805268053680546805568056680576805868059680606806168062680636806468065680666806768068680696807068071680726807368074680756807668077680786807968080680816808268083680846808568086680876808868089680906809168092680936809468095680966809768098680996810068101681026810368104681056810668107681086810968110681116811268113681146811568116681176811868119681206812168122681236812468125681266812768128681296813068131681326813368134681356813668137681386813968140681416814268143681446814568146681476814868149681506815168152681536815468155681566815768158681596816068161681626816368164681656816668167681686816968170681716817268173681746817568176681776817868179681806818168182681836818468185681866818768188681896819068191681926819368194681956819668197681986819968200682016820268203682046820568206682076820868209682106821168212682136821468215682166821768218682196822068221682226822368224682256822668227682286822968230682316823268233682346823568236682376823868239682406824168242682436824468245682466824768248682496825068251682526825368254682556825668257682586825968260682616826268263682646826568266682676826868269682706827168272682736827468275682766827768278682796828068281682826828368284682856828668287682886828968290682916829268293682946829568296682976829868299683006830168302683036830468305683066830768308683096831068311683126831368314683156831668317683186831968320683216832268323683246832568326683276832868329683306833168332683336833468335683366833768338683396834068341683426834368344683456834668347683486834968350683516835268353683546835568356683576835868359683606836168362683636836468365683666836768368683696837068371683726837368374683756837668377683786837968380683816838268383683846838568386683876838868389683906839168392683936839468395683966839768398683996840068401684026840368404684056840668407684086840968410684116841268413684146841568416684176841868419684206842168422684236842468425684266842768428684296843068431684326843368434684356843668437684386843968440684416844268443684446844568446684476844868449684506845168452684536845468455684566845768458684596846068461684626846368464684656846668467684686846968470684716847268473684746847568476684776847868479684806848168482684836848468485684866848768488684896849068491684926849368494684956849668497684986849968500685016850268503685046850568506685076850868509685106851168512685136851468515685166851768518685196852068521685226852368524685256852668527685286852968530685316853268533685346853568536685376853868539685406854168542685436854468545685466854768548685496855068551685526855368554685556855668557685586855968560685616856268563685646856568566685676856868569685706857168572685736857468575685766857768578685796858068581685826858368584685856858668587685886858968590685916859268593685946859568596685976859868599686006860168602686036860468605686066860768608686096861068611686126861368614686156861668617686186861968620686216862268623686246862568626686276862868629686306863168632686336863468635686366863768638686396864068641686426864368644686456864668647686486864968650686516865268653686546865568656686576865868659686606866168662686636866468665686666866768668686696867068671686726867368674686756867668677686786867968680686816868268683686846868568686686876868868689686906869168692686936869468695686966869768698686996870068701687026870368704687056870668707687086870968710687116871268713687146871568716687176871868719687206872168722687236872468725687266872768728687296873068731687326873368734687356873668737687386873968740687416874268743687446874568746687476874868749687506875168752687536875468755687566875768758687596876068761687626876368764687656876668767687686876968770687716877268773687746877568776687776877868779687806878168782687836878468785687866878768788687896879068791687926879368794687956879668797687986879968800688016880268803688046880568806688076880868809688106881168812688136881468815688166881768818688196882068821688226882368824688256882668827688286882968830688316883268833688346883568836688376883868839688406884168842688436884468845688466884768848688496885068851688526885368854688556885668857688586885968860688616886268863688646886568866688676886868869688706887168872688736887468875688766887768878688796888068881688826888368884688856888668887688886888968890688916889268893688946889568896688976889868899689006890168902689036890468905689066890768908689096891068911689126891368914689156891668917689186891968920689216892268923689246892568926689276892868929689306893168932689336893468935689366893768938689396894068941689426894368944689456894668947689486894968950689516895268953689546895568956689576895868959689606896168962689636896468965689666896768968689696897068971689726897368974689756897668977689786897968980689816898268983689846898568986689876898868989689906899168992689936899468995689966899768998689996900069001690026900369004690056900669007690086900969010690116901269013690146901569016690176901869019690206902169022690236902469025690266902769028690296903069031690326903369034690356903669037690386903969040690416904269043690446904569046690476904869049690506905169052690536905469055690566905769058690596906069061690626906369064690656906669067690686906969070690716907269073690746907569076690776907869079690806908169082690836908469085690866908769088690896909069091690926909369094690956909669097690986909969100691016910269103691046910569106691076910869109691106911169112691136911469115691166911769118691196912069121691226912369124691256912669127691286912969130691316913269133691346913569136691376913869139691406914169142691436914469145691466914769148691496915069151691526915369154691556915669157691586915969160691616916269163691646916569166691676916869169691706917169172691736917469175691766917769178691796918069181691826918369184691856918669187691886918969190691916919269193691946919569196691976919869199692006920169202692036920469205692066920769208692096921069211692126921369214692156921669217692186921969220692216922269223692246922569226692276922869229692306923169232692336923469235692366923769238692396924069241692426924369244692456924669247692486924969250692516925269253692546925569256692576925869259692606926169262692636926469265692666926769268692696927069271692726927369274692756927669277692786927969280692816928269283692846928569286692876928869289692906929169292692936929469295692966929769298692996930069301693026930369304693056930669307693086930969310693116931269313693146931569316693176931869319693206932169322693236932469325693266932769328693296933069331693326933369334693356933669337693386933969340693416934269343693446934569346693476934869349693506935169352693536935469355693566935769358693596936069361693626936369364693656936669367693686936969370693716937269373693746937569376693776937869379693806938169382693836938469385693866938769388693896939069391693926939369394693956939669397693986939969400694016940269403694046940569406694076940869409694106941169412694136941469415694166941769418694196942069421694226942369424694256942669427694286942969430694316943269433694346943569436694376943869439694406944169442694436944469445694466944769448694496945069451694526945369454694556945669457694586945969460694616946269463694646946569466694676946869469694706947169472694736947469475694766947769478694796948069481694826948369484694856948669487694886948969490694916949269493694946949569496694976949869499695006950169502695036950469505695066950769508695096951069511695126951369514695156951669517695186951969520695216952269523695246952569526695276952869529695306953169532695336953469535695366953769538695396954069541695426954369544695456954669547695486954969550695516955269553695546955569556695576955869559695606956169562695636956469565695666956769568695696957069571695726957369574695756957669577695786957969580695816958269583695846958569586695876958869589695906959169592695936959469595695966959769598695996960069601696026960369604696056960669607696086960969610696116961269613696146961569616696176961869619696206962169622696236962469625696266962769628696296963069631696326963369634696356963669637696386963969640696416964269643696446964569646696476964869649696506965169652696536965469655696566965769658696596966069661696626966369664696656966669667696686966969670696716967269673696746967569676696776967869679696806968169682696836968469685696866968769688696896969069691696926969369694696956969669697696986969969700697016970269703697046970569706697076970869709697106971169712697136971469715697166971769718697196972069721697226972369724697256972669727697286972969730697316973269733697346973569736697376973869739697406974169742697436974469745697466974769748697496975069751697526975369754697556975669757697586975969760697616976269763697646976569766697676976869769697706977169772697736977469775697766977769778697796978069781697826978369784697856978669787697886978969790697916979269793697946979569796697976979869799698006980169802698036980469805698066980769808698096981069811698126981369814698156981669817698186981969820698216982269823698246982569826698276982869829698306983169832698336983469835698366983769838698396984069841698426984369844698456984669847698486984969850698516985269853698546985569856698576985869859698606986169862698636986469865698666986769868698696987069871698726987369874698756987669877698786987969880698816988269883698846988569886698876988869889698906989169892698936989469895698966989769898698996990069901699026990369904699056990669907699086990969910699116991269913699146991569916699176991869919699206992169922699236992469925699266992769928699296993069931699326993369934699356993669937699386993969940699416994269943699446994569946699476994869949699506995169952699536995469955699566995769958699596996069961699626996369964699656996669967699686996969970699716997269973699746997569976699776997869979699806998169982699836998469985699866998769988699896999069991699926999369994699956999669997699986999970000700017000270003700047000570006700077000870009700107001170012700137001470015700167001770018700197002070021700227002370024700257002670027700287002970030700317003270033700347003570036700377003870039700407004170042700437004470045700467004770048700497005070051700527005370054700557005670057700587005970060700617006270063700647006570066700677006870069700707007170072700737007470075700767007770078700797008070081700827008370084700857008670087700887008970090700917009270093700947009570096700977009870099701007010170102701037010470105701067010770108701097011070111701127011370114701157011670117701187011970120701217012270123701247012570126701277012870129701307013170132701337013470135701367013770138701397014070141701427014370144701457014670147701487014970150701517015270153701547015570156701577015870159701607016170162701637016470165701667016770168701697017070171701727017370174701757017670177701787017970180701817018270183701847018570186701877018870189701907019170192701937019470195701967019770198701997020070201702027020370204702057020670207702087020970210702117021270213702147021570216702177021870219702207022170222702237022470225702267022770228702297023070231702327023370234702357023670237702387023970240702417024270243702447024570246702477024870249702507025170252702537025470255702567025770258702597026070261702627026370264702657026670267702687026970270702717027270273702747027570276702777027870279702807028170282702837028470285702867028770288702897029070291702927029370294702957029670297702987029970300703017030270303703047030570306703077030870309703107031170312703137031470315703167031770318703197032070321703227032370324703257032670327703287032970330703317033270333703347033570336703377033870339703407034170342703437034470345703467034770348703497035070351703527035370354703557035670357703587035970360703617036270363703647036570366703677036870369703707037170372703737037470375703767037770378703797038070381703827038370384703857038670387703887038970390703917039270393703947039570396703977039870399704007040170402704037040470405704067040770408704097041070411704127041370414704157041670417704187041970420704217042270423704247042570426704277042870429704307043170432704337043470435704367043770438704397044070441704427044370444704457044670447704487044970450704517045270453704547045570456704577045870459704607046170462704637046470465704667046770468704697047070471704727047370474704757047670477704787047970480704817048270483704847048570486704877048870489704907049170492704937049470495704967049770498704997050070501705027050370504705057050670507705087050970510705117051270513705147051570516705177051870519705207052170522705237052470525705267052770528705297053070531705327053370534705357053670537705387053970540705417054270543705447054570546705477054870549705507055170552705537055470555705567055770558705597056070561705627056370564705657056670567705687056970570705717057270573705747057570576705777057870579705807058170582705837058470585705867058770588705897059070591705927059370594705957059670597705987059970600706017060270603706047060570606706077060870609706107061170612706137061470615706167061770618706197062070621706227062370624706257062670627706287062970630706317063270633706347063570636706377063870639706407064170642706437064470645706467064770648706497065070651706527065370654706557065670657706587065970660706617066270663706647066570666706677066870669706707067170672706737067470675706767067770678706797068070681706827068370684706857068670687706887068970690706917069270693706947069570696706977069870699707007070170702707037070470705707067070770708707097071070711707127071370714707157071670717707187071970720707217072270723707247072570726707277072870729707307073170732707337073470735707367073770738707397074070741707427074370744707457074670747707487074970750707517075270753707547075570756707577075870759707607076170762707637076470765707667076770768707697077070771707727077370774707757077670777707787077970780707817078270783707847078570786707877078870789707907079170792707937079470795707967079770798707997080070801708027080370804708057080670807708087080970810708117081270813708147081570816708177081870819708207082170822708237082470825708267082770828708297083070831708327083370834708357083670837708387083970840708417084270843708447084570846708477084870849708507085170852708537085470855708567085770858708597086070861708627086370864708657086670867708687086970870708717087270873708747087570876708777087870879708807088170882708837088470885708867088770888708897089070891708927089370894708957089670897708987089970900709017090270903709047090570906709077090870909709107091170912709137091470915709167091770918709197092070921709227092370924709257092670927709287092970930709317093270933709347093570936709377093870939709407094170942709437094470945709467094770948709497095070951709527095370954709557095670957709587095970960709617096270963709647096570966709677096870969709707097170972709737097470975709767097770978709797098070981709827098370984709857098670987709887098970990709917099270993709947099570996709977099870999710007100171002710037100471005710067100771008710097101071011710127101371014710157101671017710187101971020710217102271023710247102571026710277102871029710307103171032710337103471035710367103771038710397104071041710427104371044710457104671047710487104971050710517105271053710547105571056710577105871059710607106171062710637106471065710667106771068710697107071071710727107371074710757107671077710787107971080710817108271083710847108571086710877108871089710907109171092710937109471095710967109771098710997110071101711027110371104711057110671107711087110971110711117111271113711147111571116711177111871119711207112171122711237112471125711267112771128711297113071131711327113371134711357113671137711387113971140711417114271143711447114571146711477114871149711507115171152711537115471155711567115771158711597116071161711627116371164711657116671167711687116971170711717117271173711747117571176711777117871179711807118171182711837118471185711867118771188711897119071191711927119371194711957119671197711987119971200712017120271203712047120571206712077120871209712107121171212712137121471215712167121771218712197122071221712227122371224712257122671227712287122971230712317123271233712347123571236712377123871239712407124171242712437124471245712467124771248712497125071251712527125371254712557125671257712587125971260712617126271263712647126571266712677126871269712707127171272712737127471275712767127771278712797128071281712827128371284712857128671287712887128971290712917129271293712947129571296712977129871299713007130171302713037130471305713067130771308713097131071311713127131371314713157131671317713187131971320713217132271323713247132571326713277132871329713307133171332713337133471335713367133771338713397134071341713427134371344713457134671347713487134971350713517135271353713547135571356713577135871359713607136171362713637136471365713667136771368713697137071371713727137371374713757137671377713787137971380713817138271383713847138571386713877138871389713907139171392713937139471395713967139771398713997140071401714027140371404714057140671407714087140971410714117141271413714147141571416714177141871419714207142171422714237142471425714267142771428714297143071431714327143371434714357143671437714387143971440714417144271443714447144571446714477144871449714507145171452714537145471455714567145771458714597146071461714627146371464714657146671467714687146971470714717147271473714747147571476714777147871479714807148171482714837148471485714867148771488714897149071491714927149371494714957149671497714987149971500715017150271503715047150571506715077150871509715107151171512715137151471515715167151771518715197152071521715227152371524715257152671527715287152971530715317153271533715347153571536715377153871539715407154171542715437154471545715467154771548715497155071551715527155371554715557155671557715587155971560715617156271563715647156571566715677156871569715707157171572715737157471575715767157771578715797158071581715827158371584715857158671587715887158971590715917159271593715947159571596715977159871599716007160171602716037160471605716067160771608716097161071611716127161371614716157161671617716187161971620716217162271623716247162571626716277162871629716307163171632716337163471635716367163771638716397164071641716427164371644716457164671647716487164971650716517165271653716547165571656716577165871659716607166171662716637166471665716667166771668716697167071671716727167371674716757167671677716787167971680716817168271683716847168571686716877168871689716907169171692716937169471695716967169771698716997170071701717027170371704717057170671707717087170971710717117171271713717147171571716717177171871719717207172171722717237172471725717267172771728717297173071731717327173371734717357173671737717387173971740717417174271743717447174571746717477174871749717507175171752717537175471755717567175771758717597176071761717627176371764717657176671767717687176971770717717177271773717747177571776717777177871779717807178171782717837178471785717867178771788717897179071791717927179371794717957179671797717987179971800718017180271803718047180571806718077180871809718107181171812718137181471815718167181771818718197182071821718227182371824718257182671827718287182971830718317183271833718347183571836718377183871839718407184171842718437184471845718467184771848718497185071851718527185371854718557185671857718587185971860718617186271863718647186571866718677186871869718707187171872718737187471875718767187771878718797188071881718827188371884718857188671887718887188971890718917189271893718947189571896718977189871899719007190171902719037190471905719067190771908719097191071911719127191371914719157191671917719187191971920719217192271923719247192571926719277192871929719307193171932719337193471935719367193771938719397194071941719427194371944719457194671947719487194971950719517195271953719547195571956719577195871959719607196171962719637196471965719667196771968719697197071971719727197371974719757197671977719787197971980719817198271983719847198571986719877198871989719907199171992719937199471995719967199771998719997200072001720027200372004720057200672007720087200972010720117201272013720147201572016720177201872019720207202172022720237202472025720267202772028720297203072031720327203372034720357203672037720387203972040720417204272043720447204572046720477204872049720507205172052720537205472055720567205772058720597206072061720627206372064720657206672067720687206972070720717207272073720747207572076720777207872079720807208172082720837208472085720867208772088720897209072091720927209372094720957209672097720987209972100721017210272103721047210572106721077210872109721107211172112721137211472115721167211772118721197212072121721227212372124721257212672127721287212972130721317213272133721347213572136721377213872139721407214172142721437214472145721467214772148721497215072151721527215372154721557215672157721587215972160721617216272163721647216572166721677216872169721707217172172721737217472175721767217772178721797218072181721827218372184721857218672187721887218972190721917219272193721947219572196721977219872199722007220172202722037220472205722067220772208722097221072211722127221372214722157221672217722187221972220722217222272223722247222572226722277222872229722307223172232722337223472235722367223772238722397224072241722427224372244722457224672247722487224972250722517225272253722547225572256722577225872259722607226172262722637226472265722667226772268722697227072271722727227372274722757227672277722787227972280722817228272283722847228572286722877228872289722907229172292722937229472295722967229772298722997230072301723027230372304723057230672307723087230972310723117231272313723147231572316723177231872319723207232172322723237232472325723267232772328723297233072331723327233372334723357233672337723387233972340723417234272343723447234572346723477234872349723507235172352723537235472355723567235772358723597236072361723627236372364723657236672367723687236972370723717237272373723747237572376723777237872379723807238172382723837238472385723867238772388723897239072391723927239372394723957239672397723987239972400724017240272403724047240572406724077240872409724107241172412724137241472415724167241772418724197242072421724227242372424724257242672427724287242972430724317243272433724347243572436724377243872439724407244172442724437244472445724467244772448724497245072451724527245372454724557245672457724587245972460724617246272463724647246572466724677246872469724707247172472724737247472475724767247772478724797248072481724827248372484724857248672487724887248972490724917249272493724947249572496724977249872499725007250172502725037250472505725067250772508725097251072511725127251372514725157251672517725187251972520725217252272523725247252572526725277252872529725307253172532725337253472535725367253772538725397254072541725427254372544725457254672547725487254972550725517255272553725547255572556725577255872559725607256172562725637256472565725667256772568725697257072571725727257372574725757257672577725787257972580725817258272583725847258572586725877258872589725907259172592725937259472595725967259772598725997260072601726027260372604726057260672607726087260972610726117261272613726147261572616726177261872619726207262172622726237262472625726267262772628726297263072631726327263372634726357263672637726387263972640726417264272643726447264572646726477264872649726507265172652726537265472655726567265772658726597266072661726627266372664726657266672667726687266972670726717267272673726747267572676726777267872679726807268172682726837268472685726867268772688726897269072691726927269372694726957269672697726987269972700727017270272703727047270572706727077270872709727107271172712727137271472715727167271772718727197272072721727227272372724727257272672727727287272972730727317273272733727347273572736727377273872739727407274172742727437274472745727467274772748727497275072751727527275372754727557275672757727587275972760727617276272763727647276572766727677276872769727707277172772727737277472775727767277772778727797278072781727827278372784727857278672787727887278972790727917279272793727947279572796727977279872799728007280172802728037280472805728067280772808728097281072811728127281372814728157281672817728187281972820728217282272823728247282572826728277282872829728307283172832728337283472835728367283772838728397284072841728427284372844728457284672847728487284972850728517285272853728547285572856728577285872859728607286172862728637286472865728667286772868728697287072871728727287372874728757287672877728787287972880728817288272883728847288572886728877288872889728907289172892728937289472895728967289772898728997290072901729027290372904729057290672907729087290972910729117291272913729147291572916729177291872919729207292172922729237292472925729267292772928729297293072931729327293372934729357293672937729387293972940729417294272943729447294572946729477294872949729507295172952729537295472955729567295772958729597296072961729627296372964729657296672967729687296972970729717297272973729747297572976729777297872979729807298172982729837298472985729867298772988729897299072991729927299372994729957299672997729987299973000730017300273003730047300573006730077300873009730107301173012730137301473015730167301773018730197302073021730227302373024730257302673027730287302973030730317303273033730347303573036730377303873039730407304173042730437304473045730467304773048730497305073051730527305373054730557305673057730587305973060730617306273063730647306573066730677306873069730707307173072730737307473075730767307773078730797308073081730827308373084730857308673087730887308973090730917309273093730947309573096730977309873099731007310173102731037310473105731067310773108731097311073111731127311373114731157311673117731187311973120731217312273123731247312573126731277312873129731307313173132731337313473135731367313773138731397314073141731427314373144731457314673147731487314973150731517315273153731547315573156731577315873159731607316173162731637316473165731667316773168731697317073171731727317373174731757317673177731787317973180731817318273183731847318573186731877318873189731907319173192731937319473195731967319773198731997320073201732027320373204732057320673207732087320973210732117321273213732147321573216732177321873219732207322173222732237322473225732267322773228732297323073231732327323373234732357323673237732387323973240732417324273243732447324573246732477324873249732507325173252732537325473255732567325773258732597326073261732627326373264732657326673267732687326973270732717327273273732747327573276732777327873279732807328173282732837328473285732867328773288732897329073291732927329373294732957329673297732987329973300733017330273303733047330573306733077330873309733107331173312733137331473315733167331773318733197332073321733227332373324733257332673327733287332973330733317333273333733347333573336733377333873339733407334173342733437334473345733467334773348733497335073351733527335373354733557335673357733587335973360733617336273363733647336573366733677336873369733707337173372733737337473375733767337773378733797338073381733827338373384733857338673387733887338973390733917339273393733947339573396733977339873399734007340173402734037340473405734067340773408734097341073411734127341373414734157341673417734187341973420734217342273423734247342573426734277342873429734307343173432734337343473435734367343773438734397344073441734427344373444734457344673447734487344973450734517345273453734547345573456734577345873459734607346173462734637346473465734667346773468734697347073471734727347373474734757347673477734787347973480734817348273483734847348573486734877348873489734907349173492734937349473495734967349773498734997350073501735027350373504735057350673507735087350973510735117351273513735147351573516735177351873519735207352173522735237352473525735267352773528735297353073531735327353373534735357353673537735387353973540735417354273543735447354573546735477354873549735507355173552735537355473555735567355773558735597356073561735627356373564735657356673567735687356973570735717357273573735747357573576735777357873579735807358173582735837358473585735867358773588735897359073591735927359373594735957359673597735987359973600736017360273603736047360573606736077360873609736107361173612736137361473615736167361773618736197362073621736227362373624736257362673627736287362973630736317363273633736347363573636736377363873639736407364173642736437364473645736467364773648736497365073651736527365373654736557365673657736587365973660736617366273663736647366573666736677366873669736707367173672736737367473675736767367773678736797368073681736827368373684736857368673687736887368973690736917369273693736947369573696736977369873699737007370173702737037370473705737067370773708737097371073711737127371373714737157371673717737187371973720737217372273723737247372573726737277372873729737307373173732737337373473735737367373773738737397374073741737427374373744737457374673747737487374973750737517375273753737547375573756737577375873759737607376173762737637376473765737667376773768737697377073771737727377373774737757377673777737787377973780737817378273783737847378573786737877378873789737907379173792737937379473795737967379773798737997380073801738027380373804738057380673807738087380973810738117381273813738147381573816738177381873819738207382173822738237382473825738267382773828738297383073831738327383373834738357383673837738387383973840738417384273843738447384573846738477384873849738507385173852738537385473855738567385773858738597386073861738627386373864738657386673867738687386973870738717387273873738747387573876738777387873879738807388173882738837388473885738867388773888738897389073891738927389373894738957389673897738987389973900739017390273903739047390573906739077390873909739107391173912739137391473915739167391773918739197392073921739227392373924739257392673927739287392973930739317393273933739347393573936739377393873939739407394173942739437394473945739467394773948739497395073951739527395373954739557395673957739587395973960739617396273963739647396573966739677396873969739707397173972739737397473975739767397773978739797398073981739827398373984739857398673987739887398973990739917399273993739947399573996739977399873999740007400174002740037400474005740067400774008740097401074011740127401374014740157401674017740187401974020740217402274023740247402574026740277402874029740307403174032740337403474035740367403774038740397404074041740427404374044740457404674047740487404974050740517405274053740547405574056740577405874059740607406174062740637406474065740667406774068740697407074071740727407374074740757407674077740787407974080740817408274083740847408574086740877408874089740907409174092740937409474095740967409774098740997410074101741027410374104741057410674107741087410974110741117411274113741147411574116741177411874119741207412174122741237412474125741267412774128741297413074131741327413374134741357413674137741387413974140741417414274143741447414574146741477414874149741507415174152741537415474155741567415774158741597416074161741627416374164741657416674167741687416974170741717417274173741747417574176741777417874179741807418174182741837418474185741867418774188741897419074191741927419374194741957419674197741987419974200742017420274203742047420574206742077420874209742107421174212742137421474215742167421774218742197422074221742227422374224742257422674227742287422974230742317423274233742347423574236742377423874239742407424174242742437424474245742467424774248742497425074251742527425374254742557425674257742587425974260742617426274263742647426574266742677426874269742707427174272742737427474275742767427774278742797428074281742827428374284742857428674287742887428974290742917429274293742947429574296742977429874299743007430174302743037430474305743067430774308743097431074311743127431374314743157431674317743187431974320743217432274323743247432574326743277432874329743307433174332743337433474335743367433774338743397434074341743427434374344743457434674347743487434974350743517435274353743547435574356743577435874359743607436174362743637436474365743667436774368743697437074371743727437374374743757437674377743787437974380743817438274383743847438574386743877438874389743907439174392743937439474395743967439774398743997440074401744027440374404744057440674407744087440974410744117441274413744147441574416744177441874419744207442174422744237442474425744267442774428744297443074431744327443374434744357443674437744387443974440744417444274443744447444574446744477444874449744507445174452744537445474455744567445774458744597446074461744627446374464744657446674467744687446974470744717447274473744747447574476744777447874479744807448174482744837448474485744867448774488744897449074491744927449374494744957449674497744987449974500745017450274503745047450574506745077450874509745107451174512745137451474515745167451774518745197452074521745227452374524745257452674527745287452974530745317453274533745347453574536745377453874539745407454174542745437454474545745467454774548745497455074551745527455374554745557455674557745587455974560745617456274563745647456574566745677456874569745707457174572745737457474575745767457774578745797458074581745827458374584745857458674587745887458974590745917459274593745947459574596745977459874599746007460174602746037460474605746067460774608746097461074611746127461374614746157461674617746187461974620746217462274623746247462574626746277462874629746307463174632746337463474635746367463774638746397464074641746427464374644746457464674647746487464974650746517465274653746547465574656746577465874659746607466174662746637466474665746667466774668746697467074671746727467374674746757467674677746787467974680746817468274683746847468574686746877468874689746907469174692746937469474695746967469774698746997470074701747027470374704747057470674707747087470974710747117471274713747147471574716747177471874719747207472174722747237472474725747267472774728747297473074731747327473374734747357473674737747387473974740747417474274743747447474574746747477474874749747507475174752747537475474755747567475774758747597476074761747627476374764747657476674767747687476974770747717477274773747747477574776747777477874779747807478174782747837478474785747867478774788747897479074791747927479374794747957479674797747987479974800748017480274803748047480574806748077480874809748107481174812748137481474815748167481774818748197482074821748227482374824748257482674827748287482974830748317483274833748347483574836748377483874839748407484174842748437484474845748467484774848748497485074851748527485374854748557485674857748587485974860748617486274863748647486574866748677486874869748707487174872748737487474875748767487774878748797488074881748827488374884748857488674887748887488974890748917489274893748947489574896748977489874899749007490174902749037490474905749067490774908749097491074911749127491374914749157491674917749187491974920749217492274923749247492574926749277492874929749307493174932749337493474935749367493774938749397494074941749427494374944749457494674947749487494974950749517495274953749547495574956749577495874959749607496174962749637496474965749667496774968749697497074971749727497374974749757497674977749787497974980749817498274983749847498574986749877498874989749907499174992749937499474995749967499774998749997500075001750027500375004750057500675007750087500975010750117501275013750147501575016750177501875019750207502175022750237502475025750267502775028750297503075031750327503375034750357503675037750387503975040750417504275043750447504575046750477504875049750507505175052750537505475055750567505775058750597506075061750627506375064750657506675067750687506975070750717507275073750747507575076750777507875079750807508175082750837508475085750867508775088750897509075091750927509375094750957509675097750987509975100751017510275103751047510575106751077510875109751107511175112751137511475115751167511775118751197512075121751227512375124751257512675127751287512975130751317513275133751347513575136751377513875139751407514175142751437514475145751467514775148751497515075151751527515375154751557515675157751587515975160751617516275163751647516575166751677516875169751707517175172751737517475175751767517775178751797518075181751827518375184751857518675187751887518975190751917519275193751947519575196751977519875199752007520175202752037520475205752067520775208752097521075211752127521375214752157521675217752187521975220752217522275223752247522575226752277522875229752307523175232752337523475235752367523775238752397524075241752427524375244752457524675247752487524975250752517525275253752547525575256752577525875259752607526175262752637526475265752667526775268752697527075271752727527375274752757527675277752787527975280752817528275283752847528575286752877528875289752907529175292752937529475295752967529775298752997530075301753027530375304753057530675307753087530975310753117531275313753147531575316753177531875319753207532175322753237532475325753267532775328753297533075331753327533375334753357533675337753387533975340753417534275343753447534575346753477534875349753507535175352753537535475355753567535775358753597536075361753627536375364753657536675367753687536975370753717537275373753747537575376753777537875379753807538175382753837538475385753867538775388753897539075391753927539375394753957539675397753987539975400754017540275403754047540575406754077540875409754107541175412754137541475415754167541775418754197542075421754227542375424754257542675427754287542975430754317543275433754347543575436754377543875439754407544175442754437544475445754467544775448754497545075451754527545375454754557545675457754587545975460754617546275463754647546575466754677546875469754707547175472754737547475475754767547775478754797548075481754827548375484754857548675487754887548975490754917549275493754947549575496754977549875499755007550175502755037550475505755067550775508755097551075511755127551375514755157551675517755187551975520755217552275523755247552575526755277552875529755307553175532755337553475535755367553775538755397554075541755427554375544755457554675547755487554975550755517555275553755547555575556755577555875559755607556175562755637556475565755667556775568755697557075571755727557375574755757557675577755787557975580755817558275583755847558575586755877558875589755907559175592755937559475595755967559775598755997560075601756027560375604756057560675607756087560975610756117561275613756147561575616756177561875619756207562175622756237562475625756267562775628756297563075631756327563375634756357563675637756387563975640756417564275643756447564575646756477564875649756507565175652756537565475655756567565775658756597566075661756627566375664756657566675667756687566975670756717567275673756747567575676756777567875679756807568175682756837568475685756867568775688756897569075691756927569375694756957569675697756987569975700757017570275703757047570575706757077570875709757107571175712757137571475715757167571775718757197572075721757227572375724757257572675727757287572975730757317573275733757347573575736757377573875739757407574175742757437574475745757467574775748757497575075751757527575375754757557575675757757587575975760757617576275763757647576575766757677576875769757707577175772757737577475775757767577775778757797578075781757827578375784757857578675787757887578975790757917579275793757947579575796757977579875799758007580175802758037580475805758067580775808758097581075811758127581375814758157581675817758187581975820758217582275823758247582575826758277582875829758307583175832758337583475835758367583775838758397584075841758427584375844758457584675847758487584975850758517585275853758547585575856758577585875859758607586175862758637586475865758667586775868758697587075871758727587375874758757587675877758787587975880758817588275883758847588575886758877588875889758907589175892758937589475895758967589775898758997590075901759027590375904759057590675907759087590975910759117591275913759147591575916759177591875919759207592175922759237592475925759267592775928759297593075931759327593375934759357593675937759387593975940759417594275943759447594575946759477594875949759507595175952759537595475955759567595775958759597596075961759627596375964759657596675967759687596975970759717597275973759747597575976759777597875979759807598175982759837598475985759867598775988759897599075991759927599375994759957599675997759987599976000760017600276003760047600576006760077600876009760107601176012760137601476015760167601776018760197602076021760227602376024760257602676027760287602976030760317603276033760347603576036760377603876039760407604176042760437604476045760467604776048760497605076051760527605376054760557605676057760587605976060760617606276063760647606576066760677606876069760707607176072760737607476075760767607776078760797608076081760827608376084760857608676087760887608976090760917609276093760947609576096760977609876099761007610176102761037610476105761067610776108761097611076111761127611376114761157611676117761187611976120761217612276123761247612576126761277612876129761307613176132761337613476135761367613776138761397614076141761427614376144761457614676147761487614976150761517615276153761547615576156761577615876159761607616176162761637616476165761667616776168761697617076171761727617376174761757617676177761787617976180761817618276183761847618576186761877618876189761907619176192761937619476195761967619776198761997620076201762027620376204762057620676207762087620976210762117621276213762147621576216762177621876219762207622176222762237622476225762267622776228762297623076231762327623376234762357623676237762387623976240762417624276243762447624576246762477624876249762507625176252762537625476255762567625776258762597626076261762627626376264762657626676267762687626976270762717627276273762747627576276762777627876279762807628176282762837628476285762867628776288762897629076291762927629376294762957629676297762987629976300763017630276303763047630576306763077630876309763107631176312763137631476315763167631776318763197632076321763227632376324763257632676327763287632976330763317633276333763347633576336763377633876339763407634176342763437634476345763467634776348763497635076351763527635376354763557635676357763587635976360763617636276363763647636576366763677636876369763707637176372763737637476375763767637776378763797638076381763827638376384763857638676387763887638976390763917639276393763947639576396763977639876399764007640176402764037640476405764067640776408764097641076411764127641376414764157641676417764187641976420764217642276423764247642576426764277642876429764307643176432764337643476435764367643776438764397644076441764427644376444764457644676447764487644976450764517645276453764547645576456764577645876459764607646176462764637646476465764667646776468764697647076471764727647376474764757647676477764787647976480764817648276483764847648576486764877648876489764907649176492764937649476495764967649776498764997650076501765027650376504765057650676507765087650976510765117651276513765147651576516765177651876519765207652176522765237652476525765267652776528765297653076531765327653376534765357653676537765387653976540765417654276543765447654576546765477654876549765507655176552765537655476555765567655776558765597656076561765627656376564765657656676567765687656976570765717657276573765747657576576765777657876579765807658176582765837658476585765867658776588765897659076591765927659376594765957659676597765987659976600766017660276603766047660576606766077660876609766107661176612766137661476615766167661776618766197662076621766227662376624766257662676627766287662976630766317663276633766347663576636766377663876639766407664176642766437664476645766467664776648766497665076651766527665376654766557665676657766587665976660766617666276663766647666576666766677666876669766707667176672766737667476675766767667776678766797668076681766827668376684766857668676687766887668976690766917669276693766947669576696766977669876699767007670176702767037670476705767067670776708767097671076711767127671376714767157671676717767187671976720767217672276723767247672576726767277672876729767307673176732767337673476735767367673776738767397674076741767427674376744767457674676747767487674976750767517675276753767547675576756767577675876759767607676176762767637676476765767667676776768767697677076771767727677376774767757677676777767787677976780767817678276783767847678576786767877678876789767907679176792767937679476795767967679776798767997680076801768027680376804768057680676807768087680976810768117681276813768147681576816768177681876819768207682176822768237682476825768267682776828768297683076831768327683376834768357683676837768387683976840768417684276843768447684576846768477684876849768507685176852768537685476855768567685776858768597686076861768627686376864768657686676867768687686976870768717687276873768747687576876768777687876879768807688176882768837688476885768867688776888768897689076891768927689376894768957689676897768987689976900769017690276903769047690576906769077690876909769107691176912769137691476915769167691776918769197692076921769227692376924769257692676927769287692976930769317693276933769347693576936769377693876939769407694176942769437694476945769467694776948769497695076951769527695376954769557695676957769587695976960769617696276963769647696576966769677696876969769707697176972769737697476975769767697776978769797698076981769827698376984769857698676987769887698976990769917699276993769947699576996769977699876999770007700177002770037700477005770067700777008770097701077011770127701377014770157701677017770187701977020770217702277023770247702577026770277702877029770307703177032770337703477035770367703777038770397704077041770427704377044770457704677047770487704977050770517705277053770547705577056770577705877059770607706177062770637706477065770667706777068770697707077071770727707377074770757707677077770787707977080770817708277083770847708577086770877708877089770907709177092770937709477095770967709777098770997710077101771027710377104771057710677107771087710977110771117711277113771147711577116771177711877119771207712177122771237712477125771267712777128771297713077131771327713377134771357713677137771387713977140771417714277143771447714577146771477714877149771507715177152771537715477155771567715777158771597716077161771627716377164771657716677167771687716977170771717717277173771747717577176771777717877179771807718177182771837718477185771867718777188771897719077191771927719377194771957719677197771987719977200772017720277203772047720577206772077720877209772107721177212772137721477215772167721777218772197722077221772227722377224772257722677227772287722977230772317723277233772347723577236772377723877239772407724177242772437724477245772467724777248772497725077251772527725377254772557725677257772587725977260772617726277263772647726577266772677726877269772707727177272772737727477275772767727777278772797728077281772827728377284772857728677287772887728977290772917729277293772947729577296772977729877299773007730177302773037730477305773067730777308773097731077311773127731377314773157731677317773187731977320773217732277323773247732577326773277732877329773307733177332773337733477335773367733777338773397734077341773427734377344773457734677347773487734977350773517735277353773547735577356773577735877359773607736177362773637736477365773667736777368773697737077371773727737377374773757737677377773787737977380773817738277383773847738577386773877738877389773907739177392773937739477395773967739777398773997740077401774027740377404774057740677407774087740977410774117741277413774147741577416774177741877419774207742177422774237742477425774267742777428774297743077431774327743377434774357743677437774387743977440774417744277443774447744577446774477744877449774507745177452774537745477455774567745777458774597746077461774627746377464774657746677467774687746977470774717747277473774747747577476774777747877479774807748177482774837748477485774867748777488774897749077491774927749377494774957749677497774987749977500775017750277503775047750577506775077750877509775107751177512775137751477515775167751777518775197752077521775227752377524775257752677527775287752977530775317753277533775347753577536775377753877539775407754177542775437754477545775467754777548775497755077551775527755377554775557755677557775587755977560775617756277563775647756577566775677756877569775707757177572775737757477575775767757777578775797758077581775827758377584775857758677587775887758977590775917759277593775947759577596775977759877599776007760177602776037760477605776067760777608776097761077611776127761377614776157761677617776187761977620776217762277623776247762577626776277762877629776307763177632776337763477635776367763777638776397764077641776427764377644776457764677647776487764977650776517765277653776547765577656776577765877659776607766177662776637766477665776667766777668776697767077671776727767377674776757767677677776787767977680776817768277683776847768577686776877768877689776907769177692776937769477695776967769777698776997770077701777027770377704777057770677707777087770977710777117771277713777147771577716777177771877719777207772177722777237772477725777267772777728777297773077731777327773377734777357773677737777387773977740777417774277743777447774577746777477774877749777507775177752777537775477755777567775777758777597776077761777627776377764777657776677767777687776977770777717777277773777747777577776777777777877779777807778177782777837778477785777867778777788777897779077791777927779377794777957779677797777987779977800778017780277803778047780577806778077780877809778107781177812778137781477815778167781777818778197782077821778227782377824778257782677827778287782977830778317783277833778347783577836778377783877839778407784177842778437784477845778467784777848778497785077851778527785377854778557785677857778587785977860778617786277863778647786577866778677786877869778707787177872778737787477875778767787777878778797788077881778827788377884778857788677887778887788977890778917789277893778947789577896778977789877899779007790177902779037790477905779067790777908779097791077911779127791377914779157791677917779187791977920779217792277923779247792577926779277792877929779307793177932779337793477935779367793777938779397794077941779427794377944779457794677947779487794977950779517795277953779547795577956779577795877959779607796177962779637796477965779667796777968779697797077971779727797377974779757797677977779787797977980779817798277983779847798577986779877798877989779907799177992779937799477995779967799777998779997800078001780027800378004780057800678007780087800978010780117801278013780147801578016780177801878019780207802178022780237802478025780267802778028780297803078031780327803378034780357803678037780387803978040780417804278043780447804578046780477804878049780507805178052780537805478055780567805778058780597806078061780627806378064780657806678067780687806978070780717807278073780747807578076780777807878079780807808178082780837808478085780867808778088780897809078091780927809378094780957809678097780987809978100781017810278103781047810578106781077810878109781107811178112781137811478115781167811778118781197812078121781227812378124781257812678127781287812978130781317813278133781347813578136781377813878139781407814178142781437814478145781467814778148781497815078151781527815378154781557815678157781587815978160781617816278163781647816578166781677816878169781707817178172781737817478175781767817778178781797818078181781827818378184781857818678187781887818978190781917819278193781947819578196781977819878199782007820178202782037820478205782067820778208782097821078211782127821378214782157821678217782187821978220782217822278223782247822578226782277822878229782307823178232782337823478235782367823778238782397824078241782427824378244782457824678247782487824978250782517825278253782547825578256782577825878259782607826178262782637826478265782667826778268782697827078271782727827378274782757827678277782787827978280782817828278283782847828578286782877828878289782907829178292782937829478295782967829778298782997830078301783027830378304783057830678307783087830978310783117831278313783147831578316783177831878319783207832178322783237832478325783267832778328783297833078331783327833378334783357833678337783387833978340783417834278343783447834578346783477834878349783507835178352783537835478355783567835778358783597836078361783627836378364783657836678367783687836978370783717837278373783747837578376783777837878379783807838178382783837838478385783867838778388783897839078391783927839378394783957839678397783987839978400784017840278403784047840578406784077840878409784107841178412784137841478415784167841778418784197842078421784227842378424784257842678427784287842978430784317843278433784347843578436784377843878439784407844178442784437844478445784467844778448784497845078451784527845378454784557845678457784587845978460784617846278463784647846578466784677846878469784707847178472784737847478475784767847778478784797848078481784827848378484784857848678487784887848978490784917849278493784947849578496784977849878499785007850178502785037850478505785067850778508785097851078511785127851378514785157851678517785187851978520785217852278523785247852578526785277852878529785307853178532785337853478535785367853778538785397854078541785427854378544785457854678547785487854978550785517855278553785547855578556785577855878559785607856178562785637856478565785667856778568785697857078571785727857378574785757857678577785787857978580785817858278583785847858578586785877858878589785907859178592785937859478595785967859778598785997860078601786027860378604786057860678607786087860978610786117861278613786147861578616786177861878619786207862178622786237862478625786267862778628786297863078631786327863378634786357863678637786387863978640786417864278643786447864578646786477864878649786507865178652786537865478655786567865778658786597866078661786627866378664786657866678667786687866978670786717867278673786747867578676786777867878679786807868178682786837868478685786867868778688786897869078691786927869378694786957869678697786987869978700787017870278703787047870578706787077870878709787107871178712787137871478715787167871778718787197872078721787227872378724787257872678727787287872978730787317873278733787347873578736787377873878739787407874178742787437874478745787467874778748787497875078751787527875378754787557875678757787587875978760787617876278763787647876578766787677876878769787707877178772787737877478775787767877778778787797878078781787827878378784787857878678787787887878978790787917879278793787947879578796787977879878799788007880178802788037880478805788067880778808788097881078811788127881378814788157881678817788187881978820788217882278823788247882578826788277882878829788307883178832788337883478835788367883778838788397884078841788427884378844788457884678847788487884978850788517885278853788547885578856788577885878859788607886178862788637886478865788667886778868788697887078871788727887378874788757887678877788787887978880788817888278883788847888578886788877888878889788907889178892788937889478895788967889778898788997890078901789027890378904789057890678907789087890978910789117891278913789147891578916789177891878919789207892178922789237892478925789267892778928789297893078931789327893378934789357893678937789387893978940789417894278943789447894578946789477894878949789507895178952789537895478955789567895778958789597896078961789627896378964789657896678967789687896978970789717897278973789747897578976789777897878979789807898178982789837898478985789867898778988789897899078991789927899378994789957899678997789987899979000790017900279003790047900579006790077900879009790107901179012790137901479015790167901779018790197902079021790227902379024790257902679027790287902979030790317903279033790347903579036790377903879039790407904179042790437904479045790467904779048790497905079051790527905379054790557905679057790587905979060790617906279063790647906579066790677906879069790707907179072790737907479075790767907779078790797908079081790827908379084790857908679087790887908979090790917909279093790947909579096790977909879099791007910179102791037910479105791067910779108791097911079111791127911379114791157911679117791187911979120791217912279123791247912579126791277912879129791307913179132791337913479135791367913779138791397914079141791427914379144791457914679147791487914979150791517915279153791547915579156791577915879159791607916179162791637916479165791667916779168791697917079171791727917379174791757917679177791787917979180791817918279183791847918579186791877918879189791907919179192791937919479195791967919779198791997920079201792027920379204792057920679207792087920979210792117921279213792147921579216792177921879219792207922179222792237922479225792267922779228792297923079231792327923379234792357923679237792387923979240792417924279243792447924579246792477924879249792507925179252792537925479255792567925779258792597926079261792627926379264792657926679267792687926979270792717927279273792747927579276792777927879279792807928179282792837928479285792867928779288792897929079291792927929379294792957929679297792987929979300793017930279303793047930579306793077930879309793107931179312793137931479315793167931779318793197932079321793227932379324793257932679327793287932979330793317933279333793347933579336793377933879339793407934179342793437934479345793467934779348793497935079351793527935379354793557935679357793587935979360793617936279363793647936579366793677936879369793707937179372793737937479375793767937779378793797938079381793827938379384793857938679387793887938979390793917939279393793947939579396793977939879399794007940179402794037940479405794067940779408794097941079411794127941379414794157941679417794187941979420794217942279423794247942579426794277942879429794307943179432794337943479435794367943779438794397944079441794427944379444794457944679447794487944979450794517945279453794547945579456794577945879459794607946179462794637946479465794667946779468794697947079471794727947379474794757947679477794787947979480794817948279483794847948579486794877948879489794907949179492794937949479495794967949779498794997950079501795027950379504795057950679507795087950979510795117951279513795147951579516795177951879519795207952179522795237952479525795267952779528795297953079531795327953379534795357953679537795387953979540795417954279543795447954579546795477954879549795507955179552795537955479555795567955779558795597956079561795627956379564795657956679567795687956979570795717957279573795747957579576795777957879579795807958179582795837958479585795867958779588795897959079591795927959379594795957959679597795987959979600796017960279603796047960579606796077960879609796107961179612796137961479615796167961779618796197962079621796227962379624796257962679627796287962979630796317963279633796347963579636796377963879639796407964179642796437964479645796467964779648796497965079651796527965379654796557965679657796587965979660796617966279663796647966579666796677966879669796707967179672796737967479675796767967779678796797968079681796827968379684796857968679687796887968979690796917969279693796947969579696796977969879699797007970179702797037970479705797067970779708797097971079711797127971379714797157971679717797187971979720797217972279723797247972579726797277972879729797307973179732797337973479735797367973779738797397974079741797427974379744797457974679747797487974979750797517975279753797547975579756797577975879759797607976179762797637976479765797667976779768797697977079771797727977379774797757977679777797787977979780797817978279783797847978579786797877978879789797907979179792797937979479795797967979779798797997980079801798027980379804798057980679807798087980979810798117981279813798147981579816798177981879819798207982179822798237982479825798267982779828798297983079831798327983379834798357983679837798387983979840798417984279843798447984579846798477984879849798507985179852798537985479855798567985779858798597986079861798627986379864798657986679867798687986979870798717987279873798747987579876798777987879879798807988179882798837988479885798867988779888798897989079891798927989379894798957989679897798987989979900799017990279903799047990579906799077990879909799107991179912799137991479915799167991779918799197992079921799227992379924799257992679927799287992979930799317993279933799347993579936799377993879939799407994179942799437994479945799467994779948799497995079951799527995379954799557995679957799587995979960799617996279963799647996579966799677996879969799707997179972799737997479975799767997779978799797998079981799827998379984799857998679987799887998979990799917999279993799947999579996799977999879999800008000180002800038000480005800068000780008800098001080011800128001380014800158001680017800188001980020800218002280023800248002580026800278002880029800308003180032800338003480035800368003780038800398004080041800428004380044800458004680047800488004980050800518005280053800548005580056800578005880059800608006180062800638006480065800668006780068800698007080071800728007380074800758007680077800788007980080800818008280083800848008580086800878008880089800908009180092800938009480095800968009780098800998010080101801028010380104801058010680107801088010980110801118011280113801148011580116801178011880119801208012180122801238012480125801268012780128801298013080131801328013380134801358013680137801388013980140801418014280143801448014580146801478014880149801508015180152801538015480155801568015780158801598016080161801628016380164801658016680167801688016980170801718017280173801748017580176801778017880179801808018180182801838018480185801868018780188801898019080191801928019380194801958019680197801988019980200802018020280203802048020580206802078020880209802108021180212802138021480215802168021780218802198022080221802228022380224802258022680227802288022980230802318023280233802348023580236802378023880239802408024180242802438024480245802468024780248802498025080251802528025380254802558025680257802588025980260802618026280263802648026580266802678026880269802708027180272802738027480275802768027780278802798028080281802828028380284802858028680287802888028980290802918029280293802948029580296802978029880299803008030180302803038030480305803068030780308803098031080311803128031380314803158031680317803188031980320803218032280323803248032580326803278032880329803308033180332803338033480335803368033780338803398034080341803428034380344803458034680347803488034980350803518035280353803548035580356803578035880359803608036180362803638036480365803668036780368803698037080371803728037380374803758037680377803788037980380803818038280383803848038580386803878038880389803908039180392803938039480395803968039780398803998040080401804028040380404804058040680407804088040980410804118041280413804148041580416804178041880419804208042180422804238042480425804268042780428804298043080431804328043380434804358043680437804388043980440804418044280443804448044580446804478044880449804508045180452804538045480455804568045780458804598046080461804628046380464804658046680467804688046980470804718047280473804748047580476804778047880479804808048180482804838048480485804868048780488804898049080491804928049380494804958049680497804988049980500805018050280503805048050580506805078050880509805108051180512805138051480515805168051780518805198052080521805228052380524805258052680527805288052980530805318053280533805348053580536805378053880539805408054180542805438054480545805468054780548805498055080551805528055380554805558055680557805588055980560805618056280563805648056580566805678056880569805708057180572805738057480575805768057780578805798058080581805828058380584805858058680587805888058980590805918059280593805948059580596805978059880599806008060180602806038060480605806068060780608806098061080611806128061380614806158061680617806188061980620806218062280623806248062580626806278062880629806308063180632806338063480635806368063780638806398064080641806428064380644806458064680647806488064980650806518065280653806548065580656806578065880659806608066180662806638066480665806668066780668806698067080671806728067380674806758067680677806788067980680806818068280683806848068580686806878068880689806908069180692806938069480695806968069780698806998070080701807028070380704807058070680707807088070980710807118071280713807148071580716807178071880719807208072180722807238072480725807268072780728807298073080731807328073380734807358073680737807388073980740807418074280743807448074580746807478074880749807508075180752807538075480755807568075780758807598076080761807628076380764807658076680767807688076980770807718077280773807748077580776807778077880779807808078180782807838078480785807868078780788807898079080791807928079380794807958079680797807988079980800808018080280803808048080580806808078080880809808108081180812808138081480815808168081780818808198082080821808228082380824808258082680827808288082980830808318083280833808348083580836808378083880839808408084180842808438084480845808468084780848808498085080851808528085380854808558085680857808588085980860808618086280863808648086580866808678086880869808708087180872808738087480875808768087780878808798088080881808828088380884808858088680887808888088980890808918089280893808948089580896808978089880899809008090180902809038090480905809068090780908809098091080911809128091380914809158091680917809188091980920809218092280923809248092580926809278092880929809308093180932809338093480935809368093780938809398094080941809428094380944809458094680947809488094980950809518095280953809548095580956809578095880959809608096180962809638096480965809668096780968809698097080971809728097380974809758097680977809788097980980809818098280983809848098580986809878098880989809908099180992809938099480995809968099780998809998100081001810028100381004810058100681007810088100981010810118101281013810148101581016810178101881019810208102181022810238102481025810268102781028810298103081031810328103381034810358103681037810388103981040810418104281043810448104581046810478104881049810508105181052810538105481055810568105781058810598106081061810628106381064810658106681067810688106981070810718107281073810748107581076810778107881079810808108181082810838108481085810868108781088810898109081091810928109381094810958109681097810988109981100811018110281103811048110581106811078110881109811108111181112811138111481115811168111781118811198112081121811228112381124811258112681127811288112981130811318113281133811348113581136811378113881139811408114181142811438114481145811468114781148811498115081151811528115381154811558115681157811588115981160811618116281163811648116581166811678116881169811708117181172811738117481175811768117781178811798118081181811828118381184811858118681187811888118981190811918119281193811948119581196811978119881199812008120181202812038120481205812068120781208812098121081211812128121381214812158121681217812188121981220812218122281223812248122581226812278122881229812308123181232812338123481235812368123781238812398124081241812428124381244812458124681247812488124981250812518125281253812548125581256812578125881259812608126181262812638126481265812668126781268812698127081271812728127381274812758127681277812788127981280812818128281283812848128581286812878128881289812908129181292812938129481295812968129781298812998130081301813028130381304813058130681307813088130981310813118131281313813148131581316813178131881319813208132181322813238132481325813268132781328813298133081331813328133381334813358133681337813388133981340813418134281343813448134581346813478134881349813508135181352813538135481355813568135781358813598136081361813628136381364813658136681367813688136981370813718137281373813748137581376813778137881379813808138181382813838138481385813868138781388813898139081391813928139381394813958139681397813988139981400814018140281403814048140581406814078140881409814108141181412814138141481415814168141781418814198142081421814228142381424814258142681427814288142981430814318143281433814348143581436814378143881439814408144181442814438144481445814468144781448814498145081451814528145381454814558145681457814588145981460814618146281463814648146581466814678146881469814708147181472814738147481475814768147781478814798148081481814828148381484814858148681487814888148981490814918149281493814948149581496814978149881499815008150181502815038150481505815068150781508815098151081511815128151381514815158151681517815188151981520815218152281523815248152581526815278152881529815308153181532815338153481535815368153781538815398154081541815428154381544815458154681547815488154981550815518155281553815548155581556815578155881559815608156181562815638156481565815668156781568815698157081571815728157381574815758157681577815788157981580815818158281583815848158581586815878158881589815908159181592815938159481595815968159781598815998160081601816028160381604816058160681607816088160981610816118161281613816148161581616816178161881619816208162181622816238162481625816268162781628816298163081631816328163381634816358163681637816388163981640816418164281643816448164581646816478164881649816508165181652816538165481655816568165781658816598166081661816628166381664816658166681667816688166981670816718167281673816748167581676816778167881679816808168181682816838168481685816868168781688816898169081691816928169381694816958169681697816988169981700817018170281703817048170581706817078170881709817108171181712817138171481715817168171781718817198172081721817228172381724817258172681727817288172981730817318173281733817348173581736817378173881739817408174181742817438174481745817468174781748817498175081751817528175381754817558175681757817588175981760817618176281763817648176581766817678176881769817708177181772817738177481775817768177781778817798178081781817828178381784817858178681787817888178981790817918179281793817948179581796817978179881799818008180181802818038180481805818068180781808818098181081811818128181381814818158181681817818188181981820818218182281823818248182581826818278182881829818308183181832818338183481835818368183781838818398184081841818428184381844818458184681847818488184981850818518185281853818548185581856818578185881859818608186181862818638186481865818668186781868818698187081871818728187381874818758187681877818788187981880818818188281883818848188581886818878188881889818908189181892818938189481895818968189781898818998190081901819028190381904819058190681907819088190981910819118191281913819148191581916819178191881919819208192181922819238192481925819268192781928819298193081931819328193381934819358193681937819388193981940819418194281943819448194581946819478194881949819508195181952819538195481955819568195781958819598196081961819628196381964819658196681967819688196981970819718197281973819748197581976819778197881979819808198181982819838198481985819868198781988819898199081991819928199381994819958199681997819988199982000820018200282003820048200582006820078200882009820108201182012820138201482015820168201782018820198202082021820228202382024820258202682027820288202982030820318203282033820348203582036820378203882039820408204182042820438204482045820468204782048820498205082051820528205382054820558205682057820588205982060820618206282063820648206582066820678206882069820708207182072820738207482075820768207782078820798208082081820828208382084820858208682087820888208982090820918209282093820948209582096820978209882099821008210182102821038210482105821068210782108821098211082111821128211382114821158211682117821188211982120821218212282123821248212582126821278212882129821308213182132821338213482135821368213782138821398214082141821428214382144821458214682147821488214982150821518215282153821548215582156821578215882159821608216182162821638216482165821668216782168821698217082171821728217382174821758217682177821788217982180821818218282183821848218582186821878218882189821908219182192821938219482195821968219782198821998220082201822028220382204822058220682207822088220982210822118221282213822148221582216822178221882219822208222182222822238222482225822268222782228822298223082231822328223382234822358223682237822388223982240822418224282243822448224582246822478224882249822508225182252822538225482255822568225782258822598226082261822628226382264822658226682267822688226982270822718227282273822748227582276822778227882279822808228182282822838228482285822868228782288822898229082291822928229382294822958229682297822988229982300823018230282303823048230582306823078230882309823108231182312823138231482315823168231782318823198232082321823228232382324823258232682327823288232982330823318233282333823348233582336823378233882339823408234182342823438234482345823468234782348823498235082351823528235382354823558235682357823588235982360823618236282363823648236582366823678236882369823708237182372823738237482375823768237782378823798238082381823828238382384823858238682387823888238982390823918239282393823948239582396823978239882399824008240182402824038240482405824068240782408824098241082411824128241382414824158241682417824188241982420824218242282423824248242582426824278242882429824308243182432824338243482435824368243782438824398244082441824428244382444824458244682447824488244982450824518245282453824548245582456824578245882459824608246182462824638246482465824668246782468824698247082471824728247382474824758247682477824788247982480824818248282483824848248582486824878248882489824908249182492824938249482495824968249782498824998250082501825028250382504825058250682507825088250982510825118251282513825148251582516825178251882519825208252182522825238252482525825268252782528825298253082531825328253382534825358253682537825388253982540825418254282543825448254582546825478254882549825508255182552825538255482555825568255782558825598256082561825628256382564825658256682567825688256982570825718257282573825748257582576825778257882579825808258182582825838258482585825868258782588825898259082591825928259382594825958259682597825988259982600826018260282603826048260582606826078260882609826108261182612826138261482615826168261782618826198262082621826228262382624826258262682627826288262982630826318263282633826348263582636826378263882639826408264182642826438264482645826468264782648826498265082651826528265382654826558265682657826588265982660826618266282663826648266582666826678266882669826708267182672826738267482675826768267782678826798268082681826828268382684826858268682687826888268982690826918269282693826948269582696826978269882699827008270182702827038270482705827068270782708827098271082711827128271382714827158271682717827188271982720827218272282723827248272582726827278272882729827308273182732827338273482735827368273782738827398274082741827428274382744827458274682747827488274982750827518275282753827548275582756827578275882759827608276182762827638276482765827668276782768827698277082771827728277382774827758277682777827788277982780827818278282783827848278582786827878278882789827908279182792827938279482795827968279782798827998280082801828028280382804828058280682807828088280982810828118281282813828148281582816828178281882819828208282182822828238282482825828268282782828828298283082831828328283382834828358283682837828388283982840828418284282843828448284582846828478284882849828508285182852828538285482855828568285782858828598286082861828628286382864828658286682867828688286982870828718287282873828748287582876828778287882879828808288182882828838288482885828868288782888828898289082891828928289382894828958289682897828988289982900829018290282903829048290582906829078290882909829108291182912829138291482915829168291782918829198292082921829228292382924829258292682927829288292982930829318293282933829348293582936829378293882939829408294182942829438294482945829468294782948829498295082951829528295382954829558295682957829588295982960829618296282963829648296582966829678296882969829708297182972829738297482975829768297782978829798298082981829828298382984829858298682987829888298982990829918299282993829948299582996829978299882999830008300183002830038300483005830068300783008830098301083011830128301383014830158301683017830188301983020830218302283023830248302583026830278302883029830308303183032830338303483035830368303783038830398304083041830428304383044830458304683047830488304983050830518305283053830548305583056830578305883059830608306183062830638306483065830668306783068830698307083071830728307383074830758307683077830788307983080830818308283083830848308583086830878308883089830908309183092830938309483095830968309783098830998310083101831028310383104831058310683107831088310983110831118311283113831148311583116831178311883119831208312183122831238312483125831268312783128831298313083131831328313383134831358313683137831388313983140831418314283143831448314583146831478314883149831508315183152831538315483155831568315783158831598316083161831628316383164831658316683167831688316983170831718317283173831748317583176831778317883179831808318183182831838318483185831868318783188831898319083191831928319383194831958319683197831988319983200832018320283203832048320583206832078320883209832108321183212832138321483215832168321783218832198322083221832228322383224832258322683227832288322983230832318323283233832348323583236832378323883239832408324183242832438324483245832468324783248832498325083251832528325383254832558325683257832588325983260832618326283263832648326583266832678326883269832708327183272832738327483275832768327783278832798328083281832828328383284832858328683287832888328983290832918329283293832948329583296832978329883299833008330183302833038330483305833068330783308833098331083311833128331383314833158331683317833188331983320833218332283323833248332583326833278332883329833308333183332833338333483335833368333783338833398334083341833428334383344833458334683347833488334983350833518335283353833548335583356833578335883359833608336183362833638336483365833668336783368833698337083371833728337383374833758337683377833788337983380833818338283383833848338583386833878338883389833908339183392833938339483395833968339783398833998340083401834028340383404834058340683407834088340983410834118341283413834148341583416834178341883419834208342183422834238342483425834268342783428834298343083431834328343383434834358343683437834388343983440834418344283443834448344583446834478344883449834508345183452834538345483455834568345783458834598346083461834628346383464834658346683467834688346983470834718347283473834748347583476834778347883479834808348183482834838348483485834868348783488834898349083491834928349383494834958349683497834988349983500835018350283503835048350583506835078350883509835108351183512835138351483515835168351783518835198352083521835228352383524835258352683527835288352983530835318353283533835348353583536835378353883539835408354183542835438354483545835468354783548835498355083551835528355383554835558355683557835588355983560835618356283563835648356583566835678356883569835708357183572835738357483575835768357783578835798358083581835828358383584835858358683587835888358983590835918359283593835948359583596835978359883599836008360183602836038360483605836068360783608836098361083611836128361383614836158361683617836188361983620836218362283623836248362583626836278362883629836308363183632836338363483635836368363783638836398364083641836428364383644836458364683647836488364983650836518365283653836548365583656836578365883659836608366183662836638366483665836668366783668836698367083671836728367383674836758367683677836788367983680836818368283683836848368583686836878368883689836908369183692836938369483695836968369783698836998370083701837028370383704837058370683707837088370983710837118371283713837148371583716837178371883719837208372183722837238372483725837268372783728837298373083731837328373383734837358373683737837388373983740837418374283743837448374583746837478374883749837508375183752837538375483755837568375783758837598376083761837628376383764837658376683767837688376983770837718377283773837748377583776837778377883779837808378183782837838378483785837868378783788837898379083791837928379383794837958379683797837988379983800838018380283803838048380583806838078380883809838108381183812838138381483815838168381783818838198382083821838228382383824838258382683827838288382983830838318383283833838348383583836838378383883839838408384183842838438384483845838468384783848838498385083851838528385383854838558385683857838588385983860838618386283863838648386583866838678386883869838708387183872838738387483875838768387783878838798388083881838828388383884838858388683887838888388983890838918389283893838948389583896838978389883899839008390183902839038390483905839068390783908839098391083911839128391383914839158391683917839188391983920839218392283923839248392583926839278392883929839308393183932839338393483935839368393783938839398394083941839428394383944839458394683947839488394983950839518395283953839548395583956839578395883959839608396183962839638396483965839668396783968839698397083971839728397383974839758397683977839788397983980839818398283983839848398583986839878398883989839908399183992839938399483995839968399783998839998400084001840028400384004840058400684007840088400984010840118401284013840148401584016840178401884019840208402184022840238402484025840268402784028840298403084031840328403384034840358403684037840388403984040840418404284043840448404584046840478404884049840508405184052840538405484055840568405784058840598406084061840628406384064840658406684067840688406984070840718407284073840748407584076840778407884079840808408184082840838408484085840868408784088840898409084091840928409384094840958409684097840988409984100841018410284103841048410584106841078410884109841108411184112841138411484115841168411784118841198412084121841228412384124841258412684127841288412984130841318413284133841348413584136841378413884139841408414184142841438414484145841468414784148841498415084151841528415384154841558415684157841588415984160841618416284163841648416584166841678416884169841708417184172841738417484175841768417784178841798418084181841828418384184841858418684187841888418984190841918419284193841948419584196841978419884199842008420184202842038420484205842068420784208842098421084211842128421384214842158421684217842188421984220842218422284223842248422584226842278422884229842308423184232842338423484235842368423784238842398424084241842428424384244842458424684247842488424984250842518425284253842548425584256842578425884259842608426184262842638426484265842668426784268842698427084271842728427384274842758427684277842788427984280842818428284283842848428584286842878428884289842908429184292842938429484295842968429784298842998430084301843028430384304843058430684307843088430984310843118431284313843148431584316843178431884319843208432184322843238432484325843268432784328843298433084331843328433384334843358433684337843388433984340843418434284343843448434584346843478434884349843508435184352843538435484355843568435784358843598436084361843628436384364843658436684367843688436984370843718437284373843748437584376843778437884379843808438184382843838438484385843868438784388843898439084391843928439384394843958439684397843988439984400844018440284403844048440584406844078440884409844108441184412844138441484415844168441784418844198442084421844228442384424844258442684427844288442984430844318443284433844348443584436844378443884439844408444184442844438444484445844468444784448844498445084451844528445384454844558445684457844588445984460844618446284463844648446584466844678446884469844708447184472844738447484475844768447784478844798448084481844828448384484844858448684487844888448984490844918449284493844948449584496844978449884499845008450184502845038450484505845068450784508845098451084511845128451384514845158451684517845188451984520845218452284523845248452584526845278452884529845308453184532845338453484535845368453784538845398454084541845428454384544845458454684547845488454984550845518455284553845548455584556845578455884559845608456184562845638456484565845668456784568845698457084571845728457384574845758457684577845788457984580845818458284583845848458584586845878458884589845908459184592845938459484595845968459784598845998460084601846028460384604846058460684607846088460984610846118461284613846148461584616846178461884619846208462184622846238462484625846268462784628846298463084631846328463384634846358463684637846388463984640846418464284643846448464584646846478464884649846508465184652846538465484655846568465784658846598466084661846628466384664846658466684667846688466984670846718467284673846748467584676846778467884679846808468184682846838468484685846868468784688846898469084691846928469384694846958469684697846988469984700847018470284703847048470584706847078470884709847108471184712847138471484715847168471784718847198472084721847228472384724847258472684727847288472984730847318473284733847348473584736847378473884739847408474184742847438474484745847468474784748847498475084751847528475384754847558475684757847588475984760847618476284763847648476584766847678476884769847708477184772847738477484775847768477784778847798478084781847828478384784847858478684787847888478984790847918479284793847948479584796847978479884799848008480184802848038480484805848068480784808848098481084811848128481384814848158481684817848188481984820848218482284823848248482584826848278482884829848308483184832848338483484835848368483784838848398484084841848428484384844848458484684847848488484984850848518485284853848548485584856848578485884859848608486184862848638486484865848668486784868848698487084871848728487384874848758487684877848788487984880848818488284883848848488584886848878488884889848908489184892848938489484895848968489784898848998490084901849028490384904849058490684907849088490984910849118491284913849148491584916849178491884919849208492184922849238492484925849268492784928849298493084931849328493384934849358493684937849388493984940849418494284943849448494584946849478494884949849508495184952849538495484955849568495784958849598496084961849628496384964849658496684967849688496984970849718497284973849748497584976849778497884979849808498184982849838498484985849868498784988849898499084991849928499384994849958499684997849988499985000850018500285003850048500585006850078500885009850108501185012850138501485015850168501785018850198502085021850228502385024850258502685027850288502985030850318503285033850348503585036850378503885039850408504185042850438504485045850468504785048850498505085051850528505385054850558505685057850588505985060850618506285063850648506585066850678506885069850708507185072850738507485075850768507785078850798508085081850828508385084850858508685087850888508985090850918509285093850948509585096850978509885099851008510185102851038510485105851068510785108851098511085111851128511385114851158511685117851188511985120851218512285123851248512585126851278512885129851308513185132851338513485135851368513785138851398514085141851428514385144851458514685147851488514985150851518515285153851548515585156851578515885159851608516185162851638516485165851668516785168851698517085171851728517385174851758517685177851788517985180851818518285183851848518585186851878518885189851908519185192851938519485195851968519785198851998520085201852028520385204852058520685207852088520985210852118521285213852148521585216852178521885219852208522185222852238522485225852268522785228852298523085231852328523385234852358523685237852388523985240852418524285243852448524585246852478524885249852508525185252852538525485255852568525785258852598526085261852628526385264852658526685267852688526985270852718527285273852748527585276852778527885279852808528185282852838528485285852868528785288852898529085291852928529385294852958529685297852988529985300853018530285303853048530585306853078530885309853108531185312853138531485315853168531785318853198532085321853228532385324853258532685327853288532985330853318533285333853348533585336853378533885339853408534185342853438534485345853468534785348853498535085351853528535385354853558535685357853588535985360853618536285363853648536585366853678536885369853708537185372853738537485375853768537785378853798538085381853828538385384853858538685387853888538985390853918539285393853948539585396853978539885399854008540185402854038540485405854068540785408854098541085411854128541385414854158541685417854188541985420854218542285423854248542585426854278542885429854308543185432854338543485435854368543785438854398544085441854428544385444854458544685447854488544985450854518545285453854548545585456854578545885459854608546185462854638546485465854668546785468854698547085471854728547385474854758547685477854788547985480854818548285483854848548585486854878548885489854908549185492854938549485495854968549785498854998550085501855028550385504855058550685507855088550985510855118551285513855148551585516855178551885519855208552185522855238552485525855268552785528855298553085531855328553385534855358553685537855388553985540855418554285543855448554585546855478554885549855508555185552855538555485555855568555785558855598556085561855628556385564855658556685567855688556985570855718557285573855748557585576855778557885579855808558185582855838558485585855868558785588855898559085591855928559385594855958559685597855988559985600856018560285603856048560585606856078560885609856108561185612856138561485615856168561785618856198562085621856228562385624856258562685627856288562985630856318563285633856348563585636856378563885639856408564185642856438564485645856468564785648856498565085651856528565385654856558565685657856588565985660856618566285663856648566585666856678566885669856708567185672856738567485675856768567785678856798568085681856828568385684856858568685687856888568985690856918569285693856948569585696856978569885699857008570185702857038570485705857068570785708857098571085711857128571385714857158571685717857188571985720857218572285723857248572585726857278572885729857308573185732857338573485735857368573785738857398574085741857428574385744857458574685747857488574985750857518575285753857548575585756857578575885759857608576185762857638576485765857668576785768857698577085771857728577385774857758577685777857788577985780857818578285783857848578585786857878578885789857908579185792857938579485795857968579785798857998580085801858028580385804858058580685807858088580985810858118581285813858148581585816858178581885819858208582185822858238582485825858268582785828858298583085831858328583385834858358583685837858388583985840858418584285843858448584585846858478584885849858508585185852858538585485855858568585785858858598586085861858628586385864858658586685867858688586985870858718587285873858748587585876858778587885879858808588185882858838588485885858868588785888858898589085891858928589385894858958589685897858988589985900859018590285903859048590585906859078590885909859108591185912859138591485915859168591785918859198592085921859228592385924859258592685927859288592985930859318593285933859348593585936859378593885939859408594185942859438594485945859468594785948859498595085951859528595385954859558595685957859588595985960859618596285963859648596585966859678596885969859708597185972859738597485975859768597785978859798598085981859828598385984859858598685987859888598985990859918599285993859948599585996859978599885999860008600186002860038600486005860068600786008860098601086011860128601386014860158601686017860188601986020860218602286023860248602586026860278602886029860308603186032860338603486035860368603786038860398604086041860428604386044860458604686047860488604986050860518605286053860548605586056860578605886059860608606186062860638606486065860668606786068860698607086071860728607386074860758607686077860788607986080860818608286083860848608586086860878608886089860908609186092860938609486095860968609786098860998610086101861028610386104861058610686107861088610986110861118611286113861148611586116861178611886119861208612186122861238612486125861268612786128861298613086131861328613386134861358613686137861388613986140861418614286143861448614586146861478614886149861508615186152861538615486155861568615786158861598616086161861628616386164861658616686167861688616986170861718617286173861748617586176861778617886179861808618186182861838618486185861868618786188861898619086191861928619386194861958619686197861988619986200862018620286203862048620586206862078620886209862108621186212862138621486215862168621786218862198622086221862228622386224862258622686227862288622986230862318623286233862348623586236862378623886239862408624186242862438624486245862468624786248862498625086251862528625386254862558625686257862588625986260862618626286263862648626586266862678626886269862708627186272862738627486275862768627786278862798628086281862828628386284862858628686287862888628986290862918629286293862948629586296862978629886299863008630186302863038630486305863068630786308863098631086311863128631386314863158631686317863188631986320863218632286323863248632586326863278632886329863308633186332863338633486335863368633786338863398634086341863428634386344863458634686347863488634986350863518635286353863548635586356863578635886359863608636186362863638636486365863668636786368863698637086371863728637386374863758637686377863788637986380863818638286383863848638586386863878638886389863908639186392863938639486395863968639786398863998640086401864028640386404864058640686407864088640986410864118641286413864148641586416864178641886419864208642186422864238642486425864268642786428864298643086431864328643386434864358643686437864388643986440864418644286443864448644586446864478644886449864508645186452864538645486455864568645786458864598646086461864628646386464864658646686467864688646986470864718647286473864748647586476864778647886479864808648186482864838648486485864868648786488864898649086491864928649386494864958649686497864988649986500865018650286503865048650586506865078650886509865108651186512865138651486515865168651786518865198652086521865228652386524865258652686527865288652986530865318653286533865348653586536865378653886539865408654186542865438654486545865468654786548865498655086551865528655386554865558655686557865588655986560865618656286563865648656586566865678656886569865708657186572865738657486575865768657786578865798658086581865828658386584865858658686587865888658986590865918659286593865948659586596865978659886599866008660186602866038660486605866068660786608866098661086611866128661386614866158661686617866188661986620866218662286623866248662586626866278662886629866308663186632866338663486635866368663786638866398664086641866428664386644866458664686647866488664986650866518665286653866548665586656866578665886659866608666186662866638666486665866668666786668866698667086671866728667386674866758667686677866788667986680866818668286683866848668586686866878668886689866908669186692866938669486695866968669786698866998670086701867028670386704867058670686707867088670986710867118671286713867148671586716867178671886719867208672186722867238672486725867268672786728867298673086731867328673386734867358673686737867388673986740867418674286743867448674586746867478674886749867508675186752867538675486755867568675786758867598676086761867628676386764867658676686767867688676986770867718677286773867748677586776867778677886779867808678186782867838678486785867868678786788867898679086791867928679386794867958679686797867988679986800868018680286803868048680586806868078680886809868108681186812868138681486815868168681786818868198682086821868228682386824868258682686827868288682986830868318683286833868348683586836868378683886839868408684186842868438684486845868468684786848868498685086851868528685386854868558685686857868588685986860868618686286863868648686586866868678686886869868708687186872868738687486875868768687786878868798688086881868828688386884868858688686887868888688986890868918689286893868948689586896868978689886899869008690186902869038690486905869068690786908869098691086911869128691386914869158691686917869188691986920869218692286923869248692586926869278692886929869308693186932869338693486935869368693786938869398694086941869428694386944869458694686947869488694986950869518695286953869548695586956869578695886959869608696186962869638696486965869668696786968869698697086971869728697386974869758697686977869788697986980869818698286983869848698586986869878698886989869908699186992869938699486995869968699786998869998700087001870028700387004870058700687007870088700987010870118701287013870148701587016870178701887019870208702187022870238702487025870268702787028870298703087031870328703387034870358703687037870388703987040870418704287043870448704587046870478704887049870508705187052870538705487055870568705787058870598706087061870628706387064870658706687067870688706987070870718707287073870748707587076870778707887079870808708187082870838708487085870868708787088870898709087091870928709387094870958709687097870988709987100871018710287103871048710587106871078710887109871108711187112871138711487115871168711787118871198712087121871228712387124871258712687127871288712987130871318713287133871348713587136871378713887139871408714187142871438714487145871468714787148871498715087151871528715387154871558715687157871588715987160871618716287163871648716587166871678716887169871708717187172871738717487175871768717787178871798718087181871828718387184871858718687187871888718987190871918719287193871948719587196871978719887199872008720187202872038720487205872068720787208872098721087211872128721387214872158721687217872188721987220872218722287223872248722587226872278722887229872308723187232872338723487235872368723787238872398724087241872428724387244872458724687247872488724987250872518725287253872548725587256872578725887259872608726187262872638726487265872668726787268872698727087271872728727387274872758727687277872788727987280872818728287283872848728587286872878728887289872908729187292872938729487295872968729787298872998730087301873028730387304873058730687307873088730987310873118731287313873148731587316873178731887319873208732187322873238732487325873268732787328873298733087331873328733387334873358733687337873388733987340873418734287343873448734587346873478734887349873508735187352873538735487355873568735787358873598736087361873628736387364873658736687367873688736987370873718737287373873748737587376873778737887379873808738187382873838738487385873868738787388873898739087391873928739387394873958739687397873988739987400874018740287403874048740587406874078740887409874108741187412874138741487415874168741787418874198742087421874228742387424874258742687427874288742987430874318743287433874348743587436874378743887439874408744187442874438744487445874468744787448874498745087451874528745387454874558745687457874588745987460874618746287463874648746587466874678746887469874708747187472874738747487475874768747787478874798748087481874828748387484874858748687487874888748987490874918749287493874948749587496874978749887499875008750187502875038750487505875068750787508875098751087511875128751387514875158751687517875188751987520875218752287523875248752587526875278752887529875308753187532875338753487535875368753787538875398754087541875428754387544875458754687547875488754987550875518755287553875548755587556875578755887559875608756187562875638756487565875668756787568875698757087571875728757387574875758757687577875788757987580875818758287583875848758587586875878758887589875908759187592875938759487595875968759787598875998760087601876028760387604876058760687607876088760987610876118761287613876148761587616876178761887619876208762187622876238762487625876268762787628876298763087631876328763387634876358763687637876388763987640876418764287643876448764587646876478764887649876508765187652876538765487655876568765787658876598766087661876628766387664876658766687667876688766987670876718767287673876748767587676876778767887679876808768187682876838768487685876868768787688876898769087691876928769387694876958769687697876988769987700877018770287703877048770587706877078770887709877108771187712877138771487715877168771787718877198772087721877228772387724877258772687727877288772987730877318773287733877348773587736877378773887739877408774187742877438774487745877468774787748877498775087751877528775387754877558775687757877588775987760877618776287763877648776587766877678776887769877708777187772877738777487775877768777787778877798778087781877828778387784877858778687787877888778987790877918779287793877948779587796877978779887799878008780187802878038780487805878068780787808878098781087811878128781387814878158781687817878188781987820878218782287823878248782587826878278782887829878308783187832878338783487835878368783787838878398784087841878428784387844878458784687847878488784987850878518785287853878548785587856878578785887859878608786187862878638786487865878668786787868878698787087871878728787387874878758787687877878788787987880878818788287883878848788587886878878788887889878908789187892878938789487895878968789787898878998790087901879028790387904879058790687907879088790987910879118791287913879148791587916879178791887919879208792187922879238792487925879268792787928879298793087931879328793387934879358793687937879388793987940879418794287943879448794587946879478794887949879508795187952879538795487955879568795787958879598796087961879628796387964879658796687967879688796987970879718797287973879748797587976879778797887979879808798187982879838798487985879868798787988879898799087991879928799387994879958799687997879988799988000880018800288003880048800588006880078800888009880108801188012880138801488015880168801788018880198802088021880228802388024880258802688027880288802988030880318803288033880348803588036880378803888039880408804188042880438804488045880468804788048880498805088051880528805388054880558805688057880588805988060880618806288063880648806588066880678806888069880708807188072880738807488075880768807788078880798808088081880828808388084880858808688087880888808988090880918809288093880948809588096880978809888099881008810188102881038810488105881068810788108881098811088111881128811388114881158811688117881188811988120881218812288123881248812588126881278812888129881308813188132881338813488135881368813788138881398814088141881428814388144881458814688147881488814988150881518815288153881548815588156881578815888159881608816188162881638816488165881668816788168881698817088171881728817388174881758817688177881788817988180881818818288183881848818588186881878818888189881908819188192881938819488195881968819788198881998820088201882028820388204882058820688207882088820988210882118821288213882148821588216882178821888219882208822188222882238822488225882268822788228882298823088231882328823388234882358823688237882388823988240882418824288243882448824588246882478824888249882508825188252882538825488255882568825788258882598826088261882628826388264882658826688267882688826988270882718827288273882748827588276882778827888279882808828188282882838828488285882868828788288882898829088291882928829388294882958829688297882988829988300883018830288303883048830588306883078830888309883108831188312883138831488315883168831788318883198832088321883228832388324883258832688327883288832988330883318833288333883348833588336883378833888339883408834188342883438834488345883468834788348883498835088351883528835388354883558835688357883588835988360883618836288363883648836588366883678836888369883708837188372883738837488375883768837788378883798838088381883828838388384883858838688387883888838988390883918839288393883948839588396883978839888399884008840188402884038840488405884068840788408884098841088411884128841388414884158841688417884188841988420884218842288423884248842588426884278842888429884308843188432884338843488435884368843788438884398844088441884428844388444884458844688447884488844988450884518845288453884548845588456884578845888459884608846188462884638846488465884668846788468884698847088471884728847388474884758847688477884788847988480884818848288483884848848588486884878848888489884908849188492884938849488495884968849788498884998850088501885028850388504885058850688507885088850988510885118851288513885148851588516885178851888519885208852188522885238852488525885268852788528885298853088531885328853388534885358853688537885388853988540885418854288543885448854588546885478854888549885508855188552885538855488555885568855788558885598856088561885628856388564885658856688567885688856988570885718857288573885748857588576885778857888579885808858188582885838858488585885868858788588885898859088591885928859388594885958859688597885988859988600886018860288603886048860588606886078860888609886108861188612886138861488615886168861788618886198862088621886228862388624886258862688627886288862988630886318863288633886348863588636886378863888639886408864188642886438864488645886468864788648886498865088651886528865388654886558865688657886588865988660886618866288663886648866588666886678866888669886708867188672886738867488675886768867788678886798868088681886828868388684886858868688687886888868988690886918869288693886948869588696886978869888699887008870188702887038870488705887068870788708887098871088711887128871388714887158871688717887188871988720887218872288723887248872588726887278872888729887308873188732887338873488735887368873788738887398874088741887428874388744887458874688747887488874988750887518875288753887548875588756887578875888759887608876188762887638876488765887668876788768887698877088771887728877388774887758877688777887788877988780887818878288783887848878588786887878878888789887908879188792887938879488795887968879788798887998880088801888028880388804888058880688807888088880988810888118881288813888148881588816888178881888819888208882188822888238882488825888268882788828888298883088831888328883388834888358883688837888388883988840888418884288843888448884588846888478884888849888508885188852888538885488855888568885788858888598886088861888628886388864888658886688867888688886988870888718887288873888748887588876888778887888879888808888188882888838888488885888868888788888888898889088891888928889388894888958889688897888988889988900889018890288903889048890588906889078890888909889108891188912889138891488915889168891788918889198892088921889228892388924889258892688927889288892988930889318893288933889348893588936889378893888939889408894188942889438894488945889468894788948889498895088951889528895388954889558895688957889588895988960889618896288963889648896588966889678896888969889708897188972889738897488975889768897788978889798898088981889828898388984889858898688987889888898988990889918899288993889948899588996889978899888999890008900189002890038900489005890068900789008890098901089011890128901389014890158901689017890188901989020890218902289023890248902589026890278902889029890308903189032890338903489035890368903789038890398904089041890428904389044890458904689047890488904989050890518905289053890548905589056890578905889059890608906189062890638906489065890668906789068890698907089071890728907389074890758907689077890788907989080890818908289083890848908589086890878908889089890908909189092890938909489095890968909789098890998910089101891028910389104891058910689107891088910989110891118911289113891148911589116891178911889119891208912189122891238912489125891268912789128891298913089131891328913389134891358913689137891388913989140891418914289143891448914589146891478914889149891508915189152891538915489155891568915789158891598916089161891628916389164891658916689167891688916989170891718917289173891748917589176891778917889179891808918189182891838918489185891868918789188891898919089191891928919389194891958919689197891988919989200892018920289203892048920589206892078920889209892108921189212892138921489215892168921789218892198922089221892228922389224892258922689227892288922989230892318923289233892348923589236892378923889239892408924189242892438924489245892468924789248892498925089251892528925389254892558925689257892588925989260892618926289263892648926589266892678926889269892708927189272892738927489275892768927789278892798928089281892828928389284892858928689287892888928989290892918929289293892948929589296892978929889299893008930189302893038930489305893068930789308893098931089311893128931389314893158931689317893188931989320893218932289323893248932589326893278932889329893308933189332893338933489335893368933789338893398934089341893428934389344893458934689347893488934989350893518935289353893548935589356893578935889359893608936189362893638936489365893668936789368893698937089371893728937389374893758937689377893788937989380893818938289383893848938589386893878938889389893908939189392893938939489395893968939789398893998940089401894028940389404894058940689407894088940989410894118941289413894148941589416894178941889419894208942189422894238942489425894268942789428894298943089431894328943389434894358943689437894388943989440894418944289443894448944589446894478944889449894508945189452894538945489455894568945789458894598946089461894628946389464894658946689467894688946989470894718947289473894748947589476894778947889479894808948189482894838948489485894868948789488894898949089491894928949389494894958949689497894988949989500895018950289503895048950589506895078950889509895108951189512895138951489515895168951789518895198952089521895228952389524895258952689527895288952989530895318953289533895348953589536895378953889539895408954189542895438954489545895468954789548895498955089551895528955389554895558955689557895588955989560895618956289563895648956589566895678956889569895708957189572895738957489575895768957789578895798958089581895828958389584895858958689587895888958989590895918959289593895948959589596895978959889599896008960189602896038960489605896068960789608896098961089611896128961389614896158961689617896188961989620896218962289623896248962589626896278962889629896308963189632896338963489635896368963789638896398964089641896428964389644896458964689647896488964989650896518965289653896548965589656896578965889659896608966189662896638966489665896668966789668896698967089671896728967389674896758967689677896788967989680896818968289683896848968589686896878968889689896908969189692896938969489695896968969789698896998970089701897028970389704897058970689707897088970989710897118971289713897148971589716897178971889719897208972189722897238972489725897268972789728897298973089731897328973389734897358973689737897388973989740897418974289743897448974589746897478974889749897508975189752897538975489755897568975789758897598976089761897628976389764897658976689767897688976989770897718977289773897748977589776897778977889779897808978189782897838978489785897868978789788897898979089791897928979389794897958979689797897988979989800898018980289803898048980589806898078980889809898108981189812898138981489815898168981789818898198982089821898228982389824898258982689827898288982989830898318983289833898348983589836898378983889839898408984189842898438984489845898468984789848898498985089851898528985389854898558985689857898588985989860898618986289863898648986589866898678986889869898708987189872898738987489875898768987789878898798988089881898828988389884898858988689887898888988989890898918989289893898948989589896898978989889899899008990189902899038990489905899068990789908899098991089911899128991389914899158991689917899188991989920899218992289923899248992589926899278992889929899308993189932899338993489935899368993789938899398994089941899428994389944899458994689947899488994989950899518995289953899548995589956899578995889959899608996189962899638996489965899668996789968899698997089971899728997389974899758997689977899788997989980899818998289983899848998589986899878998889989899908999189992899938999489995899968999789998899999000090001900029000390004900059000690007900089000990010900119001290013900149001590016900179001890019900209002190022900239002490025900269002790028900299003090031900329003390034900359003690037900389003990040900419004290043900449004590046900479004890049900509005190052900539005490055900569005790058900599006090061900629006390064900659006690067900689006990070900719007290073900749007590076900779007890079900809008190082900839008490085900869008790088900899009090091900929009390094900959009690097900989009990100901019010290103901049010590106901079010890109901109011190112901139011490115901169011790118901199012090121901229012390124901259012690127901289012990130901319013290133901349013590136901379013890139901409014190142901439014490145901469014790148901499015090151901529015390154901559015690157901589015990160901619016290163901649016590166901679016890169901709017190172901739017490175901769017790178901799018090181901829018390184901859018690187901889018990190901919019290193901949019590196901979019890199902009020190202902039020490205902069020790208902099021090211902129021390214902159021690217902189021990220902219022290223902249022590226902279022890229902309023190232902339023490235902369023790238902399024090241902429024390244902459024690247902489024990250902519025290253902549025590256902579025890259902609026190262902639026490265902669026790268902699027090271902729027390274902759027690277902789027990280902819028290283902849028590286902879028890289902909029190292902939029490295902969029790298902999030090301903029030390304903059030690307903089030990310903119031290313903149031590316903179031890319903209032190322903239032490325903269032790328903299033090331903329033390334903359033690337903389033990340903419034290343903449034590346903479034890349903509035190352903539035490355903569035790358903599036090361903629036390364903659036690367903689036990370903719037290373903749037590376903779037890379903809038190382903839038490385903869038790388903899039090391903929039390394903959039690397903989039990400904019040290403904049040590406904079040890409904109041190412904139041490415904169041790418904199042090421904229042390424904259042690427904289042990430904319043290433904349043590436904379043890439904409044190442904439044490445904469044790448904499045090451904529045390454904559045690457904589045990460904619046290463904649046590466904679046890469904709047190472904739047490475904769047790478904799048090481904829048390484904859048690487904889048990490904919049290493904949049590496904979049890499905009050190502905039050490505905069050790508905099051090511905129051390514905159051690517905189051990520905219052290523905249052590526905279052890529905309053190532905339053490535905369053790538905399054090541905429054390544905459054690547905489054990550905519055290553905549055590556905579055890559905609056190562905639056490565905669056790568905699057090571905729057390574905759057690577905789057990580905819058290583905849058590586905879058890589905909059190592905939059490595905969059790598905999060090601906029060390604906059060690607906089060990610906119061290613906149061590616906179061890619906209062190622906239062490625906269062790628906299063090631906329063390634906359063690637906389063990640906419064290643906449064590646906479064890649906509065190652906539065490655906569065790658906599066090661906629066390664906659066690667906689066990670906719067290673906749067590676906779067890679906809068190682906839068490685906869068790688906899069090691906929069390694906959069690697906989069990700907019070290703907049070590706907079070890709907109071190712907139071490715907169071790718907199072090721907229072390724907259072690727907289072990730907319073290733907349073590736907379073890739907409074190742907439074490745907469074790748907499075090751907529075390754907559075690757907589075990760907619076290763907649076590766907679076890769907709077190772907739077490775907769077790778907799078090781907829078390784907859078690787907889078990790907919079290793907949079590796907979079890799908009080190802908039080490805908069080790808908099081090811908129081390814908159081690817908189081990820908219082290823908249082590826908279082890829908309083190832908339083490835908369083790838908399084090841908429084390844908459084690847908489084990850908519085290853908549085590856908579085890859908609086190862908639086490865908669086790868908699087090871908729087390874908759087690877908789087990880908819088290883908849088590886908879088890889908909089190892908939089490895908969089790898908999090090901909029090390904909059090690907909089090990910909119091290913909149091590916909179091890919909209092190922909239092490925909269092790928909299093090931909329093390934909359093690937909389093990940909419094290943909449094590946909479094890949909509095190952909539095490955909569095790958909599096090961909629096390964909659096690967909689096990970909719097290973909749097590976909779097890979909809098190982909839098490985909869098790988909899099090991909929099390994909959099690997909989099991000910019100291003910049100591006910079100891009910109101191012910139101491015910169101791018910199102091021910229102391024910259102691027910289102991030910319103291033910349103591036910379103891039910409104191042910439104491045910469104791048910499105091051910529105391054910559105691057910589105991060910619106291063910649106591066910679106891069910709107191072910739107491075910769107791078910799108091081910829108391084910859108691087910889108991090910919109291093910949109591096910979109891099911009110191102911039110491105911069110791108911099111091111911129111391114911159111691117911189111991120911219112291123911249112591126911279112891129911309113191132911339113491135911369113791138911399114091141911429114391144911459114691147911489114991150911519115291153911549115591156911579115891159911609116191162911639116491165911669116791168911699117091171911729117391174911759117691177911789117991180911819118291183911849118591186911879118891189911909119191192911939119491195911969119791198911999120091201912029120391204912059120691207912089120991210912119121291213912149121591216912179121891219912209122191222912239122491225912269122791228912299123091231912329123391234912359123691237912389123991240912419124291243912449124591246912479124891249912509125191252912539125491255912569125791258912599126091261912629126391264912659126691267912689126991270912719127291273912749127591276912779127891279912809128191282912839128491285912869128791288912899129091291912929129391294912959129691297912989129991300913019130291303913049130591306913079130891309913109131191312913139131491315913169131791318913199132091321913229132391324913259132691327913289132991330913319133291333913349133591336913379133891339913409134191342913439134491345913469134791348913499135091351913529135391354913559135691357913589135991360913619136291363913649136591366913679136891369913709137191372913739137491375913769137791378913799138091381913829138391384913859138691387913889138991390913919139291393913949139591396913979139891399914009140191402914039140491405914069140791408914099141091411914129141391414914159141691417914189141991420914219142291423914249142591426914279142891429914309143191432914339143491435914369143791438914399144091441914429144391444914459144691447914489144991450914519145291453914549145591456914579145891459914609146191462914639146491465914669146791468914699147091471914729147391474914759147691477914789147991480914819148291483914849148591486914879148891489914909149191492914939149491495914969149791498914999150091501915029150391504915059150691507915089150991510915119151291513915149151591516915179151891519915209152191522915239152491525915269152791528915299153091531915329153391534915359153691537915389153991540915419154291543915449154591546915479154891549915509155191552915539155491555915569155791558915599156091561915629156391564915659156691567915689156991570915719157291573915749157591576915779157891579915809158191582915839158491585915869158791588915899159091591915929159391594915959159691597915989159991600916019160291603916049160591606916079160891609916109161191612916139161491615916169161791618916199162091621916229162391624916259162691627916289162991630916319163291633916349163591636916379163891639916409164191642916439164491645916469164791648916499165091651916529165391654916559165691657916589165991660916619166291663916649166591666916679166891669916709167191672916739167491675916769167791678916799168091681916829168391684916859168691687916889168991690916919169291693916949169591696916979169891699917009170191702917039170491705917069170791708917099171091711917129171391714917159171691717917189171991720917219172291723917249172591726917279172891729917309173191732917339173491735917369173791738917399174091741917429174391744917459174691747917489174991750917519175291753917549175591756917579175891759917609176191762917639176491765917669176791768917699177091771917729177391774917759177691777917789177991780917819178291783917849178591786917879178891789917909179191792917939179491795917969179791798917999180091801918029180391804918059180691807918089180991810918119181291813918149181591816918179181891819918209182191822918239182491825918269182791828918299183091831918329183391834918359183691837918389183991840918419184291843918449184591846918479184891849918509185191852918539185491855918569185791858918599186091861918629186391864918659186691867918689186991870918719187291873918749187591876918779187891879918809188191882918839188491885918869188791888918899189091891918929189391894918959189691897918989189991900919019190291903919049190591906919079190891909919109191191912919139191491915919169191791918919199192091921919229192391924919259192691927919289192991930919319193291933919349193591936919379193891939919409194191942919439194491945919469194791948919499195091951919529195391954919559195691957919589195991960919619196291963919649196591966919679196891969919709197191972919739197491975919769197791978919799198091981919829198391984919859198691987919889198991990919919199291993919949199591996919979199891999920009200192002920039200492005920069200792008920099201092011920129201392014920159201692017920189201992020920219202292023920249202592026920279202892029920309203192032920339203492035920369203792038920399204092041920429204392044920459204692047920489204992050920519205292053920549205592056920579205892059920609206192062920639206492065920669206792068920699207092071920729207392074920759207692077920789207992080920819208292083920849208592086920879208892089920909209192092920939209492095920969209792098920999210092101921029210392104921059210692107921089210992110921119211292113921149211592116921179211892119921209212192122921239212492125921269212792128921299213092131921329213392134921359213692137921389213992140921419214292143921449214592146921479214892149921509215192152921539215492155921569215792158921599216092161921629216392164921659216692167921689216992170921719217292173921749217592176921779217892179921809218192182921839218492185921869218792188921899219092191921929219392194921959219692197921989219992200922019220292203922049220592206922079220892209922109221192212922139221492215922169221792218922199222092221922229222392224922259222692227922289222992230922319223292233922349223592236922379223892239922409224192242922439224492245922469224792248922499225092251922529225392254922559225692257922589225992260922619226292263922649226592266922679226892269922709227192272922739227492275922769227792278922799228092281922829228392284922859228692287922889228992290922919229292293922949229592296922979229892299923009230192302923039230492305923069230792308923099231092311923129231392314923159231692317923189231992320923219232292323923249232592326923279232892329923309233192332923339233492335923369233792338923399234092341923429234392344923459234692347923489234992350923519235292353923549235592356923579235892359923609236192362923639236492365923669236792368923699237092371923729237392374923759237692377923789237992380923819238292383923849238592386923879238892389923909239192392923939239492395923969239792398923999240092401924029240392404924059240692407924089240992410924119241292413924149241592416924179241892419924209242192422924239242492425924269242792428924299243092431924329243392434924359243692437924389243992440924419244292443924449244592446924479244892449924509245192452924539245492455924569245792458924599246092461924629246392464924659246692467924689246992470924719247292473924749247592476924779247892479924809248192482924839248492485924869248792488924899249092491924929249392494924959249692497924989249992500925019250292503925049250592506925079250892509925109251192512925139251492515925169251792518925199252092521925229252392524925259252692527925289252992530925319253292533925349253592536925379253892539925409254192542925439254492545925469254792548925499255092551925529255392554925559255692557925589255992560925619256292563925649256592566925679256892569925709257192572925739257492575925769257792578925799258092581925829258392584925859258692587925889258992590925919259292593925949259592596925979259892599926009260192602926039260492605926069260792608926099261092611926129261392614926159261692617926189261992620926219262292623926249262592626926279262892629926309263192632926339263492635926369263792638926399264092641926429264392644926459264692647926489264992650926519265292653926549265592656926579265892659926609266192662926639266492665926669266792668926699267092671926729267392674926759267692677926789267992680926819268292683926849268592686926879268892689926909269192692926939269492695926969269792698926999270092701927029270392704927059270692707927089270992710927119271292713927149271592716927179271892719927209272192722927239272492725927269272792728927299273092731927329273392734927359273692737927389273992740927419274292743927449274592746927479274892749927509275192752927539275492755927569275792758927599276092761927629276392764927659276692767927689276992770927719277292773927749277592776927779277892779927809278192782927839278492785927869278792788927899279092791927929279392794927959279692797927989279992800928019280292803928049280592806928079280892809928109281192812928139281492815928169281792818928199282092821928229282392824928259282692827928289282992830928319283292833928349283592836928379283892839928409284192842928439284492845928469284792848928499285092851928529285392854928559285692857928589285992860928619286292863928649286592866928679286892869928709287192872928739287492875928769287792878928799288092881928829288392884928859288692887928889288992890928919289292893928949289592896928979289892899929009290192902929039290492905929069290792908929099291092911929129291392914929159291692917929189291992920929219292292923929249292592926929279292892929929309293192932929339293492935929369293792938929399294092941929429294392944929459294692947929489294992950929519295292953929549295592956929579295892959929609296192962929639296492965929669296792968929699297092971929729297392974929759297692977929789297992980929819298292983929849298592986929879298892989929909299192992929939299492995929969299792998929999300093001930029300393004930059300693007930089300993010930119301293013930149301593016930179301893019930209302193022930239302493025930269302793028930299303093031930329303393034930359303693037930389303993040930419304293043930449304593046930479304893049930509305193052930539305493055930569305793058930599306093061930629306393064930659306693067930689306993070930719307293073930749307593076930779307893079930809308193082930839308493085930869308793088930899309093091930929309393094930959309693097930989309993100931019310293103931049310593106931079310893109931109311193112931139311493115931169311793118931199312093121931229312393124931259312693127931289312993130931319313293133931349313593136931379313893139931409314193142931439314493145931469314793148931499315093151931529315393154931559315693157931589315993160931619316293163931649316593166931679316893169931709317193172931739317493175931769317793178931799318093181931829318393184931859318693187931889318993190931919319293193931949319593196931979319893199932009320193202932039320493205932069320793208932099321093211932129321393214932159321693217932189321993220932219322293223932249322593226932279322893229932309323193232932339323493235932369323793238932399324093241932429324393244932459324693247932489324993250932519325293253932549325593256932579325893259932609326193262932639326493265932669326793268932699327093271932729327393274932759327693277932789327993280932819328293283932849328593286932879328893289932909329193292932939329493295932969329793298932999330093301933029330393304933059330693307933089330993310933119331293313933149331593316933179331893319933209332193322933239332493325933269332793328933299333093331933329333393334933359333693337933389333993340933419334293343933449334593346933479334893349933509335193352933539335493355933569335793358933599336093361933629336393364933659336693367933689336993370933719337293373933749337593376933779337893379933809338193382933839338493385933869338793388933899339093391933929339393394933959339693397933989339993400934019340293403934049340593406934079340893409934109341193412934139341493415934169341793418934199342093421934229342393424934259342693427934289342993430934319343293433934349343593436934379343893439934409344193442934439344493445934469344793448934499345093451934529345393454934559345693457934589345993460934619346293463934649346593466934679346893469934709347193472934739347493475934769347793478934799348093481934829348393484934859348693487934889348993490934919349293493934949349593496934979349893499935009350193502935039350493505935069350793508935099351093511935129351393514935159351693517935189351993520935219352293523935249352593526935279352893529935309353193532935339353493535935369353793538935399354093541935429354393544935459354693547935489354993550935519355293553935549355593556935579355893559935609356193562935639356493565935669356793568935699357093571935729357393574935759357693577935789357993580935819358293583935849358593586935879358893589935909359193592935939359493595935969359793598935999360093601936029360393604936059360693607936089360993610936119361293613936149361593616936179361893619936209362193622936239362493625936269362793628936299363093631936329363393634936359363693637936389363993640936419364293643936449364593646936479364893649936509365193652936539365493655936569365793658936599366093661936629366393664936659366693667936689366993670936719367293673936749367593676936779367893679936809368193682936839368493685936869368793688936899369093691936929369393694936959369693697936989369993700937019370293703937049370593706937079370893709937109371193712937139371493715937169371793718937199372093721937229372393724937259372693727937289372993730937319373293733937349373593736937379373893739937409374193742937439374493745937469374793748937499375093751937529375393754937559375693757937589375993760937619376293763937649376593766937679376893769937709377193772937739377493775937769377793778937799378093781937829378393784937859378693787937889378993790937919379293793937949379593796937979379893799938009380193802938039380493805938069380793808938099381093811938129381393814938159381693817938189381993820938219382293823938249382593826938279382893829938309383193832938339383493835938369383793838938399384093841938429384393844938459384693847938489384993850938519385293853938549385593856938579385893859938609386193862938639386493865938669386793868938699387093871938729387393874938759387693877938789387993880938819388293883938849388593886938879388893889938909389193892938939389493895938969389793898938999390093901939029390393904939059390693907939089390993910939119391293913939149391593916939179391893919939209392193922939239392493925939269392793928939299393093931939329393393934939359393693937939389393993940939419394293943939449394593946939479394893949939509395193952939539395493955939569395793958939599396093961939629396393964939659396693967939689396993970939719397293973939749397593976939779397893979939809398193982939839398493985939869398793988939899399093991939929399393994939959399693997939989399994000940019400294003940049400594006940079400894009940109401194012940139401494015940169401794018940199402094021940229402394024940259402694027940289402994030940319403294033940349403594036940379403894039940409404194042940439404494045940469404794048940499405094051940529405394054940559405694057940589405994060940619406294063940649406594066940679406894069940709407194072940739407494075940769407794078940799408094081940829408394084940859408694087940889408994090940919409294093940949409594096940979409894099941009410194102941039410494105941069410794108941099411094111941129411394114941159411694117941189411994120941219412294123941249412594126941279412894129941309413194132941339413494135941369413794138941399414094141941429414394144941459414694147941489414994150941519415294153941549415594156941579415894159941609416194162941639416494165941669416794168941699417094171941729417394174941759417694177941789417994180941819418294183941849418594186941879418894189941909419194192941939419494195941969419794198941999420094201942029420394204942059420694207942089420994210942119421294213942149421594216942179421894219942209422194222942239422494225942269422794228942299423094231942329423394234942359423694237942389423994240942419424294243942449424594246942479424894249942509425194252942539425494255942569425794258942599426094261942629426394264942659426694267942689426994270942719427294273942749427594276942779427894279942809428194282942839428494285942869428794288942899429094291942929429394294942959429694297942989429994300943019430294303943049430594306943079430894309943109431194312943139431494315943169431794318943199432094321943229432394324943259432694327943289432994330943319433294333943349433594336943379433894339943409434194342943439434494345943469434794348943499435094351943529435394354943559435694357943589435994360943619436294363943649436594366943679436894369943709437194372943739437494375943769437794378943799438094381943829438394384943859438694387943889438994390943919439294393943949439594396943979439894399944009440194402944039440494405944069440794408944099441094411944129441394414944159441694417944189441994420944219442294423944249442594426944279442894429944309443194432944339443494435944369443794438944399444094441944429444394444944459444694447944489444994450944519445294453944549445594456944579445894459944609446194462944639446494465944669446794468944699447094471944729447394474944759447694477944789447994480944819448294483944849448594486944879448894489944909449194492944939449494495944969449794498944999450094501945029450394504945059450694507945089450994510945119451294513945149451594516945179451894519945209452194522945239452494525945269452794528945299453094531945329453394534945359453694537945389453994540945419454294543945449454594546945479454894549945509455194552945539455494555945569455794558945599456094561945629456394564945659456694567945689456994570945719457294573945749457594576945779457894579945809458194582945839458494585945869458794588945899459094591945929459394594945959459694597945989459994600946019460294603946049460594606946079460894609946109461194612946139461494615946169461794618946199462094621946229462394624946259462694627946289462994630946319463294633946349463594636946379463894639946409464194642946439464494645946469464794648946499465094651946529465394654946559465694657946589465994660946619466294663946649466594666946679466894669946709467194672946739467494675946769467794678946799468094681946829468394684946859468694687946889468994690946919469294693946949469594696946979469894699947009470194702947039470494705947069470794708947099471094711947129471394714947159471694717947189471994720947219472294723947249472594726947279472894729947309473194732947339473494735947369473794738947399474094741947429474394744947459474694747947489474994750947519475294753947549475594756947579475894759947609476194762947639476494765947669476794768947699477094771947729477394774947759477694777947789477994780947819478294783947849478594786947879478894789947909479194792947939479494795947969479794798947999480094801948029480394804948059480694807948089480994810948119481294813948149481594816948179481894819948209482194822948239482494825948269482794828948299483094831948329483394834948359483694837948389483994840948419484294843948449484594846948479484894849948509485194852948539485494855948569485794858948599486094861948629486394864948659486694867948689486994870948719487294873948749487594876948779487894879948809488194882948839488494885948869488794888948899489094891948929489394894948959489694897948989489994900949019490294903949049490594906949079490894909949109491194912949139491494915949169491794918949199492094921949229492394924949259492694927949289492994930949319493294933949349493594936949379493894939949409494194942949439494494945949469494794948949499495094951949529495394954949559495694957949589495994960949619496294963949649496594966949679496894969949709497194972949739497494975949769497794978949799498094981949829498394984949859498694987949889498994990949919499294993949949499594996949979499894999950009500195002950039500495005950069500795008950099501095011950129501395014950159501695017950189501995020950219502295023950249502595026950279502895029950309503195032950339503495035950369503795038950399504095041950429504395044950459504695047950489504995050950519505295053950549505595056950579505895059950609506195062950639506495065950669506795068950699507095071950729507395074950759507695077950789507995080950819508295083950849508595086950879508895089950909509195092950939509495095950969509795098950999510095101951029510395104951059510695107951089510995110951119511295113951149511595116951179511895119951209512195122951239512495125951269512795128951299513095131951329513395134951359513695137951389513995140951419514295143951449514595146951479514895149951509515195152951539515495155951569515795158951599516095161951629516395164951659516695167951689516995170951719517295173951749517595176951779517895179951809518195182951839518495185951869518795188951899519095191951929519395194951959519695197951989519995200952019520295203952049520595206952079520895209952109521195212952139521495215952169521795218952199522095221952229522395224952259522695227952289522995230952319523295233952349523595236952379523895239952409524195242952439524495245952469524795248952499525095251952529525395254952559525695257952589525995260952619526295263952649526595266952679526895269952709527195272952739527495275952769527795278952799528095281952829528395284952859528695287952889528995290952919529295293952949529595296952979529895299953009530195302953039530495305953069530795308953099531095311953129531395314953159531695317953189531995320953219532295323953249532595326953279532895329953309533195332953339533495335953369533795338953399534095341953429534395344953459534695347953489534995350953519535295353953549535595356953579535895359953609536195362953639536495365953669536795368953699537095371953729537395374953759537695377953789537995380953819538295383953849538595386953879538895389953909539195392953939539495395953969539795398953999540095401954029540395404954059540695407954089540995410954119541295413954149541595416954179541895419954209542195422954239542495425954269542795428954299543095431954329543395434954359543695437954389543995440954419544295443954449544595446954479544895449954509545195452954539545495455954569545795458954599546095461954629546395464954659546695467954689546995470954719547295473954749547595476954779547895479954809548195482954839548495485954869548795488954899549095491954929549395494954959549695497954989549995500955019550295503955049550595506955079550895509955109551195512955139551495515955169551795518955199552095521955229552395524955259552695527955289552995530955319553295533955349553595536955379553895539955409554195542955439554495545955469554795548955499555095551955529555395554955559555695557955589555995560955619556295563955649556595566955679556895569955709557195572955739557495575955769557795578955799558095581955829558395584955859558695587955889558995590955919559295593955949559595596955979559895599956009560195602956039560495605956069560795608956099561095611956129561395614956159561695617956189561995620956219562295623956249562595626956279562895629956309563195632956339563495635956369563795638956399564095641956429564395644956459564695647956489564995650956519565295653956549565595656956579565895659956609566195662956639566495665956669566795668956699567095671956729567395674956759567695677956789567995680956819568295683956849568595686956879568895689956909569195692956939569495695956969569795698956999570095701957029570395704957059570695707957089570995710957119571295713957149571595716957179571895719957209572195722957239572495725957269572795728957299573095731957329573395734957359573695737957389573995740957419574295743957449574595746957479574895749957509575195752957539575495755957569575795758957599576095761957629576395764957659576695767957689576995770957719577295773957749577595776957779577895779957809578195782957839578495785957869578795788957899579095791957929579395794957959579695797957989579995800958019580295803958049580595806958079580895809958109581195812958139581495815958169581795818958199582095821958229582395824958259582695827958289582995830958319583295833958349583595836958379583895839958409584195842958439584495845958469584795848958499585095851958529585395854958559585695857958589585995860958619586295863958649586595866958679586895869958709587195872958739587495875958769587795878958799588095881958829588395884958859588695887958889588995890958919589295893958949589595896958979589895899959009590195902959039590495905959069590795908959099591095911959129591395914959159591695917959189591995920959219592295923959249592595926959279592895929959309593195932959339593495935959369593795938959399594095941959429594395944959459594695947959489594995950959519595295953959549595595956959579595895959959609596195962959639596495965959669596795968959699597095971959729597395974959759597695977959789597995980959819598295983959849598595986959879598895989959909599195992959939599495995959969599795998959999600096001960029600396004960059600696007960089600996010960119601296013960149601596016960179601896019960209602196022960239602496025960269602796028960299603096031960329603396034960359603696037960389603996040960419604296043960449604596046960479604896049960509605196052 |
- // OpenLayers. See https://openlayers.org/
- // License: https://raw.githubusercontent.com/openlayers/openlayers/master/LICENSE.md
- // Version: v4.6.5
- ;(function (root, factory) {
- if (typeof exports === "object") {
- module.exports = factory();
- } else if (typeof define === "function" && define.amd) {
- define([], factory);
- } else {
- root.ol = factory();
- }
- }(this, function () {
- var OPENLAYERS = {};
- var goog = this.goog = {};
- this.CLOSURE_NO_DEPS = true;
- // Copyright 2006 The Closure Library Authors. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS-IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- /**
- * @fileoverview Bootstrap for the Google JS Library (Closure).
- *
- * In uncompiled mode base.js will attempt to load Closure's deps file, unless
- * the global <code>CLOSURE_NO_DEPS</code> is set to true. This allows projects
- * to include their own deps file(s) from different locations.
- *
- * Avoid including base.js more than once. This is strictly discouraged and not
- * supported. goog.require(...) won't work properly in that case.
- *
- * @provideGoog
- */
- /**
- * @define {boolean} Overridden to true by the compiler.
- */
- var COMPILED = false;
- /**
- * Base namespace for the Closure library. Checks to see goog is already
- * defined in the current scope before assigning to prevent clobbering if
- * base.js is loaded more than once.
- *
- * @const
- */
- var goog = goog || {};
- /**
- * Reference to the global context. In most cases this will be 'window'.
- */
- goog.global = this;
- /**
- * A hook for overriding the define values in uncompiled mode.
- *
- * In uncompiled mode, {@code CLOSURE_UNCOMPILED_DEFINES} may be defined before
- * loading base.js. If a key is defined in {@code CLOSURE_UNCOMPILED_DEFINES},
- * {@code goog.define} will use the value instead of the default value. This
- * allows flags to be overwritten without compilation (this is normally
- * accomplished with the compiler's "define" flag).
- *
- * Example:
- * <pre>
- * var CLOSURE_UNCOMPILED_DEFINES = {'goog.DEBUG': false};
- * </pre>
- *
- * @type {Object<string, (string|number|boolean)>|undefined}
- */
- goog.global.CLOSURE_UNCOMPILED_DEFINES;
- /**
- * A hook for overriding the define values in uncompiled or compiled mode,
- * like CLOSURE_UNCOMPILED_DEFINES but effective in compiled code. In
- * uncompiled code CLOSURE_UNCOMPILED_DEFINES takes precedence.
- *
- * Also unlike CLOSURE_UNCOMPILED_DEFINES the values must be number, boolean or
- * string literals or the compiler will emit an error.
- *
- * While any @define value may be set, only those set with goog.define will be
- * effective for uncompiled code.
- *
- * Example:
- * <pre>
- * var CLOSURE_DEFINES = {'goog.DEBUG': false} ;
- * </pre>
- *
- * @type {Object<string, (string|number|boolean)>|undefined}
- */
- goog.global.CLOSURE_DEFINES;
- /**
- * Returns true if the specified value is not undefined.
- *
- * @param {?} val Variable to test.
- * @return {boolean} Whether variable is defined.
- */
- goog.isDef = function(val) {
- // void 0 always evaluates to undefined and hence we do not need to depend on
- // the definition of the global variable named 'undefined'.
- return val !== void 0;
- };
- /**
- * Returns true if the specified value is a string.
- * @param {?} val Variable to test.
- * @return {boolean} Whether variable is a string.
- */
- goog.isString = function(val) {
- return typeof val == 'string';
- };
- /**
- * Returns true if the specified value is a boolean.
- * @param {?} val Variable to test.
- * @return {boolean} Whether variable is boolean.
- */
- goog.isBoolean = function(val) {
- return typeof val == 'boolean';
- };
- /**
- * Returns true if the specified value is a number.
- * @param {?} val Variable to test.
- * @return {boolean} Whether variable is a number.
- */
- goog.isNumber = function(val) {
- return typeof val == 'number';
- };
- /**
- * Builds an object structure for the provided namespace path, ensuring that
- * names that already exist are not overwritten. For example:
- * "a.b.c" -> a = {};a.b={};a.b.c={};
- * Used by goog.provide and goog.exportSymbol.
- * @param {string} name name of the object that this file defines.
- * @param {*=} opt_object the object to expose at the end of the path.
- * @param {Object=} opt_objectToExportTo The object to add the path to; default
- * is `goog.global`.
- * @private
- */
- goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) {
- var parts = name.split('.');
- var cur = opt_objectToExportTo || goog.global;
- // Internet Explorer exhibits strange behavior when throwing errors from
- // methods externed in this manner. See the testExportSymbolExceptions in
- // base_test.html for an example.
- if (!(parts[0] in cur) && cur.execScript) {
- cur.execScript('var ' + parts[0]);
- }
- for (var part; parts.length && (part = parts.shift());) {
- if (!parts.length && goog.isDef(opt_object)) {
- // last part and we have an object; use it
- cur[part] = opt_object;
- } else if (cur[part] && cur[part] !== Object.prototype[part]) {
- cur = cur[part];
- } else {
- cur = cur[part] = {};
- }
- }
- };
- /**
- * Defines a named value. In uncompiled mode, the value is retrieved from
- * CLOSURE_DEFINES or CLOSURE_UNCOMPILED_DEFINES if the object is defined and
- * has the property specified, and otherwise used the defined defaultValue.
- * When compiled the default can be overridden using the compiler
- * options or the value set in the CLOSURE_DEFINES object.
- *
- * @param {string} name The distinguished name to provide.
- * @param {string|number|boolean} defaultValue
- */
- goog.define = function(name, defaultValue) {
- var value = defaultValue;
- if (!COMPILED) {
- if (goog.global.CLOSURE_UNCOMPILED_DEFINES &&
- // Anti DOM-clobbering runtime check (b/37736576).
- /** @type {?} */ (goog.global.CLOSURE_UNCOMPILED_DEFINES).nodeType ===
- undefined &&
- Object.prototype.hasOwnProperty.call(
- goog.global.CLOSURE_UNCOMPILED_DEFINES, name)) {
- value = goog.global.CLOSURE_UNCOMPILED_DEFINES[name];
- } else if (
- goog.global.CLOSURE_DEFINES &&
- // Anti DOM-clobbering runtime check (b/37736576).
- /** @type {?} */ (goog.global.CLOSURE_DEFINES).nodeType === undefined &&
- Object.prototype.hasOwnProperty.call(
- goog.global.CLOSURE_DEFINES, name)) {
- value = goog.global.CLOSURE_DEFINES[name];
- }
- }
- goog.exportPath_(name, value);
- };
- /**
- * @define {boolean} DEBUG is provided as a convenience so that debugging code
- * that should not be included in a production. It can be easily stripped
- * by specifying --define goog.DEBUG=false to the Closure Compiler aka
- * JSCompiler. For example, most toString() methods should be declared inside an
- * "if (goog.DEBUG)" conditional because they are generally used for debugging
- * purposes and it is difficult for the JSCompiler to statically determine
- * whether they are used.
- */
- goog.define('goog.DEBUG', true);
- /**
- * @define {string} LOCALE defines the locale being used for compilation. It is
- * used to select locale specific data to be compiled in js binary. BUILD rule
- * can specify this value by "--define goog.LOCALE=<locale_name>" as a compiler
- * option.
- *
- * Take into account that the locale code format is important. You should use
- * the canonical Unicode format with hyphen as a delimiter. Language must be
- * lowercase, Language Script - Capitalized, Region - UPPERCASE.
- * There are few examples: pt-BR, en, en-US, sr-Latin-BO, zh-Hans-CN.
- *
- * See more info about locale codes here:
- * http://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers
- *
- * For language codes you should use values defined by ISO 693-1. See it here
- * http://www.w3.org/WAI/ER/IG/ert/iso639.htm. There is only one exception from
- * this rule: the Hebrew language. For legacy reasons the old code (iw) should
- * be used instead of the new code (he).
- *
- */
- goog.define('goog.LOCALE', 'en'); // default to en
- /**
- * @define {boolean} Whether this code is running on trusted sites.
- *
- * On untrusted sites, several native functions can be defined or overridden by
- * external libraries like Prototype, Datejs, and JQuery and setting this flag
- * to false forces closure to use its own implementations when possible.
- *
- * If your JavaScript can be loaded by a third party site and you are wary about
- * relying on non-standard implementations, specify
- * "--define goog.TRUSTED_SITE=false" to the compiler.
- */
- goog.define('goog.TRUSTED_SITE', true);
- /**
- * @define {boolean} Whether a project is expected to be running in strict mode.
- *
- * This define can be used to trigger alternate implementations compatible with
- * running in EcmaScript Strict mode or warn about unavailable functionality.
- * @see https://goo.gl/PudQ4y
- *
- */
- goog.define('goog.STRICT_MODE_COMPATIBLE', false);
- /**
- * @define {boolean} Whether code that calls {@link goog.setTestOnly} should
- * be disallowed in the compilation unit.
- */
- goog.define('goog.DISALLOW_TEST_ONLY_CODE', COMPILED && !goog.DEBUG);
- /**
- * @define {boolean} Whether to use a Chrome app CSP-compliant method for
- * loading scripts via goog.require. @see appendScriptSrcNode_.
- */
- goog.define('goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING', false);
- /**
- * Defines a namespace in Closure.
- *
- * A namespace may only be defined once in a codebase. It may be defined using
- * goog.provide() or goog.module().
- *
- * The presence of one or more goog.provide() calls in a file indicates
- * that the file defines the given objects/namespaces.
- * Provided symbols must not be null or undefined.
- *
- * In addition, goog.provide() creates the object stubs for a namespace
- * (for example, goog.provide("goog.foo.bar") will create the object
- * goog.foo.bar if it does not already exist).
- *
- * Build tools also scan for provide/require/module statements
- * to discern dependencies, build dependency files (see deps.js), etc.
- *
- * @see goog.require
- * @see goog.module
- * @param {string} name Namespace provided by this file in the form
- * "goog.package.part".
- */
- goog.provide = function(name) {
- if (goog.isInModuleLoader_()) {
- throw new Error('goog.provide can not be used within a goog.module.');
- }
- if (!COMPILED) {
- // Ensure that the same namespace isn't provided twice.
- // A goog.module/goog.provide maps a goog.require to a specific file
- if (goog.isProvided_(name)) {
- throw new Error('Namespace "' + name + '" already declared.');
- }
- }
- goog.constructNamespace_(name);
- };
- /**
- * @param {string} name Namespace provided by this file in the form
- * "goog.package.part".
- * @param {Object=} opt_obj The object to embed in the namespace.
- * @private
- */
- goog.constructNamespace_ = function(name, opt_obj) {
- if (!COMPILED) {
- delete goog.implicitNamespaces_[name];
- var namespace = name;
- while ((namespace = namespace.substring(0, namespace.lastIndexOf('.')))) {
- if (goog.getObjectByName(namespace)) {
- break;
- }
- goog.implicitNamespaces_[namespace] = true;
- }
- }
- goog.exportPath_(name, opt_obj);
- };
- /**
- * Module identifier validation regexp.
- * Note: This is a conservative check, it is very possible to be more lenient,
- * the primary exclusion here is "/" and "\" and a leading ".", these
- * restrictions are intended to leave the door open for using goog.require
- * with relative file paths rather than module identifiers.
- * @private
- */
- goog.VALID_MODULE_RE_ = /^[a-zA-Z_$][a-zA-Z0-9._$]*$/;
- /**
- * Defines a module in Closure.
- *
- * Marks that this file must be loaded as a module and claims the namespace.
- *
- * A namespace may only be defined once in a codebase. It may be defined using
- * goog.provide() or goog.module().
- *
- * goog.module() has three requirements:
- * - goog.module may not be used in the same file as goog.provide.
- * - goog.module must be the first statement in the file.
- * - only one goog.module is allowed per file.
- *
- * When a goog.module annotated file is loaded, it is enclosed in
- * a strict function closure. This means that:
- * - any variables declared in a goog.module file are private to the file
- * (not global), though the compiler is expected to inline the module.
- * - The code must obey all the rules of "strict" JavaScript.
- * - the file will be marked as "use strict"
- *
- * NOTE: unlike goog.provide, goog.module does not declare any symbols by
- * itself. If declared symbols are desired, use
- * goog.module.declareLegacyNamespace().
- *
- *
- * See the public goog.module proposal: http://goo.gl/Va1hin
- *
- * @param {string} name Namespace provided by this file in the form
- * "goog.package.part", is expected but not required.
- * @return {void}
- */
- goog.module = function(name) {
- if (!goog.isString(name) || !name ||
- name.search(goog.VALID_MODULE_RE_) == -1) {
- throw new Error('Invalid module identifier');
- }
- if (!goog.isInModuleLoader_()) {
- throw new Error(
- 'Module ' + name + ' has been loaded incorrectly. Note, ' +
- 'modules cannot be loaded as normal scripts. They require some kind of ' +
- 'pre-processing step. You\'re likely trying to load a module via a ' +
- 'script tag or as a part of a concatenated bundle without rewriting the ' +
- 'module. For more info see: ' +
- 'https://github.com/google/closure-library/wiki/goog.module:-an-ES6-module-like-alternative-to-goog.provide.');
- }
- if (goog.moduleLoaderState_.moduleName) {
- throw new Error('goog.module may only be called once per module.');
- }
- // Store the module name for the loader.
- goog.moduleLoaderState_.moduleName = name;
- if (!COMPILED) {
- // Ensure that the same namespace isn't provided twice.
- // A goog.module/goog.provide maps a goog.require to a specific file
- if (goog.isProvided_(name)) {
- throw new Error('Namespace "' + name + '" already declared.');
- }
- delete goog.implicitNamespaces_[name];
- }
- };
- /**
- * @param {string} name The module identifier.
- * @return {?} The module exports for an already loaded module or null.
- *
- * Note: This is not an alternative to goog.require, it does not
- * indicate a hard dependency, instead it is used to indicate
- * an optional dependency or to access the exports of a module
- * that has already been loaded.
- * @suppress {missingProvide}
- */
- goog.module.get = function(name) {
- return goog.module.getInternal_(name);
- };
- /**
- * @param {string} name The module identifier.
- * @return {?} The module exports for an already loaded module or null.
- * @private
- */
- goog.module.getInternal_ = function(name) {
- if (!COMPILED) {
- if (name in goog.loadedModules_) {
- return goog.loadedModules_[name];
- } else if (!goog.implicitNamespaces_[name]) {
- var ns = goog.getObjectByName(name);
- return ns != null ? ns : null;
- }
- }
- return null;
- };
- /**
- * @private {?{moduleName: (string|undefined), declareLegacyNamespace:boolean}}
- */
- goog.moduleLoaderState_ = null;
- /**
- * @private
- * @return {boolean} Whether a goog.module is currently being initialized.
- */
- goog.isInModuleLoader_ = function() {
- return goog.moduleLoaderState_ != null;
- };
- /**
- * Provide the module's exports as a globally accessible object under the
- * module's declared name. This is intended to ease migration to goog.module
- * for files that have existing usages.
- * @suppress {missingProvide}
- */
- goog.module.declareLegacyNamespace = function() {
- if (!COMPILED && !goog.isInModuleLoader_()) {
- throw new Error(
- 'goog.module.declareLegacyNamespace must be called from ' +
- 'within a goog.module');
- }
- if (!COMPILED && !goog.moduleLoaderState_.moduleName) {
- throw new Error(
- 'goog.module must be called prior to ' +
- 'goog.module.declareLegacyNamespace.');
- }
- goog.moduleLoaderState_.declareLegacyNamespace = true;
- };
- /**
- * Marks that the current file should only be used for testing, and never for
- * live code in production.
- *
- * In the case of unit tests, the message may optionally be an exact namespace
- * for the test (e.g. 'goog.stringTest'). The linter will then ignore the extra
- * provide (if not explicitly defined in the code).
- *
- * @param {string=} opt_message Optional message to add to the error that's
- * raised when used in production code.
- */
- goog.setTestOnly = function(opt_message) {
- if (goog.DISALLOW_TEST_ONLY_CODE) {
- opt_message = opt_message || '';
- throw new Error(
- 'Importing test-only code into non-debug environment' +
- (opt_message ? ': ' + opt_message : '.'));
- }
- };
- /**
- * Forward declares a symbol. This is an indication to the compiler that the
- * symbol may be used in the source yet is not required and may not be provided
- * in compilation.
- *
- * The most common usage of forward declaration is code that takes a type as a
- * function parameter but does not need to require it. By forward declaring
- * instead of requiring, no hard dependency is made, and (if not required
- * elsewhere) the namespace may never be required and thus, not be pulled
- * into the JavaScript binary. If it is required elsewhere, it will be type
- * checked as normal.
- *
- * Before using goog.forwardDeclare, please read the documentation at
- * https://github.com/google/closure-compiler/wiki/Bad-Type-Annotation to
- * understand the options and tradeoffs when working with forward declarations.
- *
- * @param {string} name The namespace to forward declare in the form of
- * "goog.package.part".
- */
- goog.forwardDeclare = function(name) {};
- /**
- * Forward declare type information. Used to assign types to goog.global
- * referenced object that would otherwise result in unknown type references
- * and thus block property disambiguation.
- */
- goog.forwardDeclare('Document');
- goog.forwardDeclare('HTMLScriptElement');
- goog.forwardDeclare('XMLHttpRequest');
- if (!COMPILED) {
- /**
- * Check if the given name has been goog.provided. This will return false for
- * names that are available only as implicit namespaces.
- * @param {string} name name of the object to look for.
- * @return {boolean} Whether the name has been provided.
- * @private
- */
- goog.isProvided_ = function(name) {
- return (name in goog.loadedModules_) ||
- (!goog.implicitNamespaces_[name] &&
- goog.isDefAndNotNull(goog.getObjectByName(name)));
- };
- /**
- * Namespaces implicitly defined by goog.provide. For example,
- * goog.provide('goog.events.Event') implicitly declares that 'goog' and
- * 'goog.events' must be namespaces.
- *
- * @type {!Object<string, (boolean|undefined)>}
- * @private
- */
- goog.implicitNamespaces_ = {'goog.module': true};
- // NOTE: We add goog.module as an implicit namespace as goog.module is defined
- // here and because the existing module package has not been moved yet out of
- // the goog.module namespace. This satisifies both the debug loader and
- // ahead-of-time dependency management.
- }
- /**
- * Returns an object based on its fully qualified external name. The object
- * is not found if null or undefined. If you are using a compilation pass that
- * renames property names beware that using this function will not find renamed
- * properties.
- *
- * @param {string} name The fully qualified name.
- * @param {Object=} opt_obj The object within which to look; default is
- * |goog.global|.
- * @return {?} The value (object or primitive) or, if not found, null.
- */
- goog.getObjectByName = function(name, opt_obj) {
- var parts = name.split('.');
- var cur = opt_obj || goog.global;
- for (var i = 0; i < parts.length; i++) {
- cur = cur[parts[i]];
- if (!goog.isDefAndNotNull(cur)) {
- return null;
- }
- }
- return cur;
- };
- /**
- * Globalizes a whole namespace, such as goog or goog.lang.
- *
- * @param {!Object} obj The namespace to globalize.
- * @param {Object=} opt_global The object to add the properties to.
- * @deprecated Properties may be explicitly exported to the global scope, but
- * this should no longer be done in bulk.
- */
- goog.globalize = function(obj, opt_global) {
- var global = opt_global || goog.global;
- for (var x in obj) {
- global[x] = obj[x];
- }
- };
- /**
- * Adds a dependency from a file to the files it requires.
- * @param {string} relPath The path to the js file.
- * @param {!Array<string>} provides An array of strings with
- * the names of the objects this file provides.
- * @param {!Array<string>} requires An array of strings with
- * the names of the objects this file requires.
- * @param {boolean|!Object<string>=} opt_loadFlags Parameters indicating
- * how the file must be loaded. The boolean 'true' is equivalent
- * to {'module': 'goog'} for backwards-compatibility. Valid properties
- * and values include {'module': 'goog'} and {'lang': 'es6'}.
- */
- goog.addDependency = function(relPath, provides, requires, opt_loadFlags) {
- if (goog.DEPENDENCIES_ENABLED) {
- var provide, require;
- var path = relPath.replace(/\\/g, '/');
- var deps = goog.dependencies_;
- if (!opt_loadFlags || typeof opt_loadFlags === 'boolean') {
- opt_loadFlags = opt_loadFlags ? {'module': 'goog'} : {};
- }
- for (var i = 0; provide = provides[i]; i++) {
- deps.nameToPath[provide] = path;
- deps.loadFlags[path] = opt_loadFlags;
- }
- for (var j = 0; require = requires[j]; j++) {
- if (!(path in deps.requires)) {
- deps.requires[path] = {};
- }
- deps.requires[path][require] = true;
- }
- }
- };
- // NOTE(nnaze): The debug DOM loader was included in base.js as an original way
- // to do "debug-mode" development. The dependency system can sometimes be
- // confusing, as can the debug DOM loader's asynchronous nature.
- //
- // With the DOM loader, a call to goog.require() is not blocking -- the script
- // will not load until some point after the current script. If a namespace is
- // needed at runtime, it needs to be defined in a previous script, or loaded via
- // require() with its registered dependencies.
- //
- // User-defined namespaces may need their own deps file. For a reference on
- // creating a deps file, see:
- // Externally: https://developers.google.com/closure/library/docs/depswriter
- //
- // Because of legacy clients, the DOM loader can't be easily removed from
- // base.js. Work was done to make it disableable or replaceable for
- // different environments (DOM-less JavaScript interpreters like Rhino or V8,
- // for example). See bootstrap/ for more information.
- /**
- * @define {boolean} Whether to enable the debug loader.
- *
- * If enabled, a call to goog.require() will attempt to load the namespace by
- * appending a script tag to the DOM (if the namespace has been registered).
- *
- * If disabled, goog.require() will simply assert that the namespace has been
- * provided (and depend on the fact that some outside tool correctly ordered
- * the script).
- */
- goog.define('goog.ENABLE_DEBUG_LOADER', true);
- /**
- * @param {string} msg
- * @private
- */
- goog.logToConsole_ = function(msg) {
- if (goog.global.console) {
- goog.global.console['error'](msg);
- }
- };
- /**
- * Implements a system for the dynamic resolution of dependencies that works in
- * parallel with the BUILD system. Note that all calls to goog.require will be
- * stripped by the compiler.
- * @see goog.provide
- * @param {string} name Namespace to include (as was given in goog.provide()) in
- * the form "goog.package.part".
- * @return {?} If called within a goog.module file, the associated namespace or
- * module otherwise null.
- */
- goog.require = function(name) {
- // If the object already exists we do not need to do anything.
- if (!COMPILED) {
- if (goog.ENABLE_DEBUG_LOADER && goog.IS_OLD_IE_) {
- goog.maybeProcessDeferredDep_(name);
- }
- if (goog.isProvided_(name)) {
- if (goog.isInModuleLoader_()) {
- return goog.module.getInternal_(name);
- }
- } else if (goog.ENABLE_DEBUG_LOADER) {
- var path = goog.getPathFromDeps_(name);
- if (path) {
- goog.writeScripts_(path);
- } else {
- var errorMessage = 'goog.require could not find: ' + name;
- goog.logToConsole_(errorMessage);
- throw new Error(errorMessage);
- }
- }
- return null;
- }
- };
- /**
- * Path for included scripts.
- * @type {string}
- */
- goog.basePath = '';
- /**
- * A hook for overriding the base path.
- * @type {string|undefined}
- */
- goog.global.CLOSURE_BASE_PATH;
- /**
- * Whether to attempt to load Closure's deps file. By default, when uncompiled,
- * deps files will attempt to be loaded.
- * @type {boolean|undefined}
- */
- goog.global.CLOSURE_NO_DEPS;
- /**
- * A function to import a single script. This is meant to be overridden when
- * Closure is being run in non-HTML contexts, such as web workers. It's defined
- * in the global scope so that it can be set before base.js is loaded, which
- * allows deps.js to be imported properly.
- *
- * The function is passed the script source, which is a relative URI. It should
- * return true if the script was imported, false otherwise.
- * @type {(function(string): boolean)|undefined}
- */
- goog.global.CLOSURE_IMPORT_SCRIPT;
- /**
- * Null function used for default values of callbacks, etc.
- * @return {void} Nothing.
- */
- goog.nullFunction = function() {};
- /**
- * When defining a class Foo with an abstract method bar(), you can do:
- * Foo.prototype.bar = goog.abstractMethod
- *
- * Now if a subclass of Foo fails to override bar(), an error will be thrown
- * when bar() is invoked.
- *
- * @type {!Function}
- * @throws {Error} when invoked to indicate the method should be overridden.
- */
- goog.abstractMethod = function() {
- throw new Error('unimplemented abstract method');
- };
- /**
- * Adds a {@code getInstance} static method that always returns the same
- * instance object.
- * @param {!Function} ctor The constructor for the class to add the static
- * method to.
- */
- goog.addSingletonGetter = function(ctor) {
- // instance_ is immediately set to prevent issues with sealed constructors
- // such as are encountered when a constructor is returned as the export object
- // of a goog.module in unoptimized code.
- ctor.instance_ = undefined;
- ctor.getInstance = function() {
- if (ctor.instance_) {
- return ctor.instance_;
- }
- if (goog.DEBUG) {
- // NOTE: JSCompiler can't optimize away Array#push.
- goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = ctor;
- }
- return ctor.instance_ = new ctor;
- };
- };
- /**
- * All singleton classes that have been instantiated, for testing. Don't read
- * it directly, use the {@code goog.testing.singleton} module. The compiler
- * removes this variable if unused.
- * @type {!Array<!Function>}
- * @private
- */
- goog.instantiatedSingletons_ = [];
- /**
- * @define {boolean} Whether to load goog.modules using {@code eval} when using
- * the debug loader. This provides a better debugging experience as the
- * source is unmodified and can be edited using Chrome Workspaces or similar.
- * However in some environments the use of {@code eval} is banned
- * so we provide an alternative.
- */
- goog.define('goog.LOAD_MODULE_USING_EVAL', true);
- /**
- * @define {boolean} Whether the exports of goog.modules should be sealed when
- * possible.
- */
- goog.define('goog.SEAL_MODULE_EXPORTS', goog.DEBUG);
- /**
- * The registry of initialized modules:
- * the module identifier to module exports map.
- * @private @const {!Object<string, ?>}
- */
- goog.loadedModules_ = {};
- /**
- * True if goog.dependencies_ is available.
- * @const {boolean}
- */
- goog.DEPENDENCIES_ENABLED = !COMPILED && goog.ENABLE_DEBUG_LOADER;
- /**
- * @define {string} How to decide whether to transpile. Valid values
- * are 'always', 'never', and 'detect'. The default ('detect') is to
- * use feature detection to determine which language levels need
- * transpilation.
- */
- // NOTE(user): we could expand this to accept a language level to bypass
- // detection: e.g. goog.TRANSPILE == 'es5' would transpile ES6 files but
- // would leave ES3 and ES5 files alone.
- goog.define('goog.TRANSPILE', 'detect');
- /**
- * @define {string} Path to the transpiler. Executing the script at this
- * path (relative to base.js) should define a function $jscomp.transpile.
- */
- goog.define('goog.TRANSPILER', 'transpile.js');
- if (goog.DEPENDENCIES_ENABLED) {
- /**
- * This object is used to keep track of dependencies and other data that is
- * used for loading scripts.
- * @private
- * @type {{
- * loadFlags: !Object<string, !Object<string, string>>,
- * nameToPath: !Object<string, string>,
- * requires: !Object<string, !Object<string, boolean>>,
- * visited: !Object<string, boolean>,
- * written: !Object<string, boolean>,
- * deferred: !Object<string, string>
- * }}
- */
- goog.dependencies_ = {
- loadFlags: {}, // 1 to 1
- nameToPath: {}, // 1 to 1
- requires: {}, // 1 to many
- // Used when resolving dependencies to prevent us from visiting file twice.
- visited: {},
- written: {}, // Used to keep track of script files we have written.
- deferred: {} // Used to track deferred module evaluations in old IEs
- };
- /**
- * Tries to detect whether is in the context of an HTML document.
- * @return {boolean} True if it looks like HTML document.
- * @private
- */
- goog.inHtmlDocument_ = function() {
- /** @type {Document} */
- var doc = goog.global.document;
- return doc != null && 'write' in doc; // XULDocument misses write.
- };
- /**
- * Tries to detect the base path of base.js script that bootstraps Closure.
- * @private
- */
- goog.findBasePath_ = function() {
- if (goog.isDef(goog.global.CLOSURE_BASE_PATH) &&
- // Anti DOM-clobbering runtime check (b/37736576).
- goog.isString(goog.global.CLOSURE_BASE_PATH)) {
- goog.basePath = goog.global.CLOSURE_BASE_PATH;
- return;
- } else if (!goog.inHtmlDocument_()) {
- return;
- }
- /** @type {Document} */
- var doc = goog.global.document;
- // If we have a currentScript available, use it exclusively.
- var currentScript = doc.currentScript;
- if (currentScript) {
- var scripts = [currentScript];
- } else {
- var scripts = doc.getElementsByTagName('SCRIPT');
- }
- // Search backwards since the current script is in almost all cases the one
- // that has base.js.
- for (var i = scripts.length - 1; i >= 0; --i) {
- var script = /** @type {!HTMLScriptElement} */ (scripts[i]);
- var src = script.src;
- var qmark = src.lastIndexOf('?');
- var l = qmark == -1 ? src.length : qmark;
- if (src.substr(l - 7, 7) == 'base.js') {
- goog.basePath = src.substr(0, l - 7);
- return;
- }
- }
- };
- /**
- * Imports a script if, and only if, that script hasn't already been imported.
- * (Must be called at execution time)
- * @param {string} src Script source.
- * @param {string=} opt_sourceText The optionally source text to evaluate
- * @private
- */
- goog.importScript_ = function(src, opt_sourceText) {
- var importScript =
- goog.global.CLOSURE_IMPORT_SCRIPT || goog.writeScriptTag_;
- if (importScript(src, opt_sourceText)) {
- goog.dependencies_.written[src] = true;
- }
- };
- /**
- * Whether the browser is IE9 or earlier, which needs special handling
- * for deferred modules.
- * @const @private {boolean}
- */
- goog.IS_OLD_IE_ =
- !!(!goog.global.atob && goog.global.document && goog.global.document.all);
- /**
- * Whether IE9 or earlier is waiting on a dependency. This ensures that
- * deferred modules that have no non-deferred dependencies actually get
- * loaded, since if we defer them and then never pull in a non-deferred
- * script, then `goog.loadQueuedModules_` will never be called. Instead,
- * if not waiting on anything we simply don't defer in the first place.
- * @private {boolean}
- */
- goog.oldIeWaiting_ = false;
- /**
- * Given a URL initiate retrieval and execution of a script that needs
- * pre-processing.
- * @param {string} src Script source URL.
- * @param {boolean} isModule Whether this is a goog.module.
- * @param {boolean} needsTranspile Whether this source needs transpilation.
- * @private
- */
- goog.importProcessedScript_ = function(src, isModule, needsTranspile) {
- // In an attempt to keep browsers from timing out loading scripts using
- // synchronous XHRs, put each load in its own script block.
- var bootstrap = 'goog.retrieveAndExec_("' + src + '", ' + isModule + ', ' +
- needsTranspile + ');';
- goog.importScript_('', bootstrap);
- };
- /** @private {!Array<string>} */
- goog.queuedModules_ = [];
- /**
- * Return an appropriate module text. Suitable to insert into
- * a script tag (that is unescaped).
- * @param {string} srcUrl
- * @param {string} scriptText
- * @return {string}
- * @private
- */
- goog.wrapModule_ = function(srcUrl, scriptText) {
- if (!goog.LOAD_MODULE_USING_EVAL || !goog.isDef(goog.global.JSON)) {
- return '' +
- 'goog.loadModule(function(exports) {' +
- '"use strict";' + scriptText +
- '\n' + // terminate any trailing single line comment.
- ';return exports' +
- '});' +
- '\n//# sourceURL=' + srcUrl + '\n';
- } else {
- return '' +
- 'goog.loadModule(' +
- goog.global.JSON.stringify(
- scriptText + '\n//# sourceURL=' + srcUrl + '\n') +
- ');';
- }
- };
- // On IE9 and earlier, it is necessary to handle
- // deferred module loads. In later browsers, the
- // code to be evaluated is simply inserted as a script
- // block in the correct order. To eval deferred
- // code at the right time, we piggy back on goog.require to call
- // goog.maybeProcessDeferredDep_.
- //
- // The goog.requires are used both to bootstrap
- // the loading process (when no deps are available) and
- // declare that they should be available.
- //
- // Here we eval the sources, if all the deps are available
- // either already eval'd or goog.require'd. This will
- // be the case when all the dependencies have already
- // been loaded, and the dependent module is loaded.
- //
- // But this alone isn't sufficient because it is also
- // necessary to handle the case where there is no root
- // that is not deferred. For that there we register for an event
- // and trigger goog.loadQueuedModules_ handle any remaining deferred
- // evaluations.
- /**
- * Handle any remaining deferred goog.module evals.
- * @private
- */
- goog.loadQueuedModules_ = function() {
- var count = goog.queuedModules_.length;
- if (count > 0) {
- var queue = goog.queuedModules_;
- goog.queuedModules_ = [];
- for (var i = 0; i < count; i++) {
- var path = queue[i];
- goog.maybeProcessDeferredPath_(path);
- }
- }
- goog.oldIeWaiting_ = false;
- };
- /**
- * Eval the named module if its dependencies are
- * available.
- * @param {string} name The module to load.
- * @private
- */
- goog.maybeProcessDeferredDep_ = function(name) {
- if (goog.isDeferredModule_(name) && goog.allDepsAreAvailable_(name)) {
- var path = goog.getPathFromDeps_(name);
- goog.maybeProcessDeferredPath_(goog.basePath + path);
- }
- };
- /**
- * @param {string} name The module to check.
- * @return {boolean} Whether the name represents a
- * module whose evaluation has been deferred.
- * @private
- */
- goog.isDeferredModule_ = function(name) {
- var path = goog.getPathFromDeps_(name);
- var loadFlags = path && goog.dependencies_.loadFlags[path] || {};
- var languageLevel = loadFlags['lang'] || 'es3';
- if (path && (loadFlags['module'] == 'goog' ||
- goog.needsTranspile_(languageLevel))) {
- var abspath = goog.basePath + path;
- return (abspath) in goog.dependencies_.deferred;
- }
- return false;
- };
- /**
- * @param {string} name The module to check.
- * @return {boolean} Whether the name represents a
- * module whose declared dependencies have all been loaded
- * (eval'd or a deferred module load)
- * @private
- */
- goog.allDepsAreAvailable_ = function(name) {
- var path = goog.getPathFromDeps_(name);
- if (path && (path in goog.dependencies_.requires)) {
- for (var requireName in goog.dependencies_.requires[path]) {
- if (!goog.isProvided_(requireName) &&
- !goog.isDeferredModule_(requireName)) {
- return false;
- }
- }
- }
- return true;
- };
- /**
- * @param {string} abspath
- * @private
- */
- goog.maybeProcessDeferredPath_ = function(abspath) {
- if (abspath in goog.dependencies_.deferred) {
- var src = goog.dependencies_.deferred[abspath];
- delete goog.dependencies_.deferred[abspath];
- goog.globalEval(src);
- }
- };
- /**
- * Load a goog.module from the provided URL. This is not a general purpose
- * code loader and does not support late loading code, that is it should only
- * be used during page load. This method exists to support unit tests and
- * "debug" loaders that would otherwise have inserted script tags. Under the
- * hood this needs to use a synchronous XHR and is not recommeneded for
- * production code.
- *
- * The module's goog.requires must have already been satisified; an exception
- * will be thrown if this is not the case. This assumption is that no
- * "deps.js" file exists, so there is no way to discover and locate the
- * module-to-be-loaded's dependencies and no attempt is made to do so.
- *
- * There should only be one attempt to load a module. If
- * "goog.loadModuleFromUrl" is called for an already loaded module, an
- * exception will be throw.
- *
- * @param {string} url The URL from which to attempt to load the goog.module.
- */
- goog.loadModuleFromUrl = function(url) {
- // Because this executes synchronously, we don't need to do any additional
- // bookkeeping. When "goog.loadModule" the namespace will be marked as
- // having been provided which is sufficient.
- goog.retrieveAndExec_(url, true, false);
- };
- /**
- * Writes a new script pointing to {@code src} directly into the DOM.
- *
- * NOTE: This method is not CSP-compliant. @see goog.appendScriptSrcNode_ for
- * the fallback mechanism.
- *
- * @param {string} src The script URL.
- * @private
- */
- goog.writeScriptSrcNode_ = function(src) {
- goog.global.document.write(
- '<script type="text/javascript" src="' + src + '"></' +
- 'script>');
- };
- /**
- * Appends a new script node to the DOM using a CSP-compliant mechanism. This
- * method exists as a fallback for document.write (which is not allowed in a
- * strict CSP context, e.g., Chrome apps).
- *
- * NOTE: This method is not analogous to using document.write to insert a
- * <script> tag; specifically, the user agent will execute a script added by
- * document.write immediately after the current script block finishes
- * executing, whereas the DOM-appended script node will not be executed until
- * the entire document is parsed and executed. That is to say, this script is
- * added to the end of the script execution queue.
- *
- * The page must not attempt to call goog.required entities until after the
- * document has loaded, e.g., in or after the window.onload callback.
- *
- * @param {string} src The script URL.
- * @private
- */
- goog.appendScriptSrcNode_ = function(src) {
- /** @type {Document} */
- var doc = goog.global.document;
- var scriptEl =
- /** @type {HTMLScriptElement} */ (doc.createElement('script'));
- scriptEl.type = 'text/javascript';
- scriptEl.src = src;
- scriptEl.defer = false;
- scriptEl.async = false;
- doc.head.appendChild(scriptEl);
- };
- /**
- * The default implementation of the import function. Writes a script tag to
- * import the script.
- *
- * @param {string} src The script url.
- * @param {string=} opt_sourceText The optionally source text to evaluate
- * @return {boolean} True if the script was imported, false otherwise.
- * @private
- */
- goog.writeScriptTag_ = function(src, opt_sourceText) {
- if (goog.inHtmlDocument_()) {
- /** @type {!HTMLDocument} */
- var doc = goog.global.document;
- // If the user tries to require a new symbol after document load,
- // something has gone terribly wrong. Doing a document.write would
- // wipe out the page. This does not apply to the CSP-compliant method
- // of writing script tags.
- if (!goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING &&
- doc.readyState == 'complete') {
- // Certain test frameworks load base.js multiple times, which tries
- // to write deps.js each time. If that happens, just fail silently.
- // These frameworks wipe the page between each load of base.js, so this
- // is OK.
- var isDeps = /\bdeps.js$/.test(src);
- if (isDeps) {
- return false;
- } else {
- throw new Error('Cannot write "' + src + '" after document load');
- }
- }
- if (opt_sourceText === undefined) {
- if (!goog.IS_OLD_IE_) {
- if (goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING) {
- goog.appendScriptSrcNode_(src);
- } else {
- goog.writeScriptSrcNode_(src);
- }
- } else {
- goog.oldIeWaiting_ = true;
- var state = ' onreadystatechange=\'goog.onScriptLoad_(this, ' +
- ++goog.lastNonModuleScriptIndex_ + ')\' ';
- doc.write(
- '<script type="text/javascript" src="' + src + '"' + state +
- '></' +
- 'script>');
- }
- } else {
- doc.write(
- '<script type="text/javascript">' +
- goog.protectScriptTag_(opt_sourceText) + '</' +
- 'script>');
- }
- return true;
- } else {
- return false;
- }
- };
- /**
- * Rewrites closing script tags in input to avoid ending an enclosing script
- * tag.
- *
- * @param {string} str
- * @return {string}
- * @private
- */
- goog.protectScriptTag_ = function(str) {
- return str.replace(/<\/(SCRIPT)/ig, '\\x3c/$1');
- };
- /**
- * Determines whether the given language needs to be transpiled.
- * @param {string} lang
- * @return {boolean}
- * @private
- */
- goog.needsTranspile_ = function(lang) {
- if (goog.TRANSPILE == 'always') {
- return true;
- } else if (goog.TRANSPILE == 'never') {
- return false;
- } else if (!goog.requiresTranspilation_) {
- goog.requiresTranspilation_ = goog.createRequiresTranspilation_();
- }
- if (lang in goog.requiresTranspilation_) {
- return goog.requiresTranspilation_[lang];
- } else {
- throw new Error('Unknown language mode: ' + lang);
- }
- };
- /** @private {?Object<string, boolean>} */
- goog.requiresTranspilation_ = null;
- /** @private {number} */
- goog.lastNonModuleScriptIndex_ = 0;
- /**
- * A readystatechange handler for legacy IE
- * @param {?} script
- * @param {number} scriptIndex
- * @return {boolean}
- * @private
- */
- goog.onScriptLoad_ = function(script, scriptIndex) {
- // for now load the modules when we reach the last script,
- // later allow more inter-mingling.
- if (script.readyState == 'complete' &&
- goog.lastNonModuleScriptIndex_ == scriptIndex) {
- goog.loadQueuedModules_();
- }
- return true;
- };
- /**
- * Resolves dependencies based on the dependencies added using addDependency
- * and calls importScript_ in the correct order.
- * @param {string} pathToLoad The path from which to start discovering
- * dependencies.
- * @private
- */
- goog.writeScripts_ = function(pathToLoad) {
- /** @type {!Array<string>} The scripts we need to write this time. */
- var scripts = [];
- var seenScript = {};
- var deps = goog.dependencies_;
- /** @param {string} path */
- function visitNode(path) {
- if (path in deps.written) {
- return;
- }
- // We have already visited this one. We can get here if we have cyclic
- // dependencies.
- if (path in deps.visited) {
- return;
- }
- deps.visited[path] = true;
- if (path in deps.requires) {
- for (var requireName in deps.requires[path]) {
- // If the required name is defined, we assume that it was already
- // bootstrapped by other means.
- if (!goog.isProvided_(requireName)) {
- if (requireName in deps.nameToPath) {
- visitNode(deps.nameToPath[requireName]);
- } else {
- throw new Error('Undefined nameToPath for ' + requireName);
- }
- }
- }
- }
- if (!(path in seenScript)) {
- seenScript[path] = true;
- scripts.push(path);
- }
- }
- visitNode(pathToLoad);
- // record that we are going to load all these scripts.
- for (var i = 0; i < scripts.length; i++) {
- var path = scripts[i];
- goog.dependencies_.written[path] = true;
- }
- // If a module is loaded synchronously then we need to
- // clear the current inModuleLoader value, and restore it when we are
- // done loading the current "requires".
- var moduleState = goog.moduleLoaderState_;
- goog.moduleLoaderState_ = null;
- for (var i = 0; i < scripts.length; i++) {
- var path = scripts[i];
- if (path) {
- var loadFlags = deps.loadFlags[path] || {};
- var languageLevel = loadFlags['lang'] || 'es3';
- var needsTranspile = goog.needsTranspile_(languageLevel);
- if (loadFlags['module'] == 'goog' || needsTranspile) {
- goog.importProcessedScript_(
- goog.basePath + path, loadFlags['module'] == 'goog',
- needsTranspile);
- } else {
- goog.importScript_(goog.basePath + path);
- }
- } else {
- goog.moduleLoaderState_ = moduleState;
- throw new Error('Undefined script input');
- }
- }
- // restore the current "module loading state"
- goog.moduleLoaderState_ = moduleState;
- };
- /**
- * Looks at the dependency rules and tries to determine the script file that
- * fulfills a particular rule.
- * @param {string} rule In the form goog.namespace.Class or project.script.
- * @return {?string} Url corresponding to the rule, or null.
- * @private
- */
- goog.getPathFromDeps_ = function(rule) {
- if (rule in goog.dependencies_.nameToPath) {
- return goog.dependencies_.nameToPath[rule];
- } else {
- return null;
- }
- };
- goog.findBasePath_();
- // Allow projects to manage the deps files themselves.
- if (!goog.global.CLOSURE_NO_DEPS) {
- goog.importScript_(goog.basePath + 'deps.js');
- }
- }
- /**
- * @package {?boolean}
- * Visible for testing.
- */
- goog.hasBadLetScoping = null;
- /**
- * @return {boolean}
- * @package Visible for testing.
- */
- goog.useSafari10Workaround = function() {
- if (goog.hasBadLetScoping == null) {
- var hasBadLetScoping;
- try {
- hasBadLetScoping = !eval(
- '"use strict";' +
- 'let x = 1; function f() { return typeof x; };' +
- 'f() == "number";');
- } catch (e) {
- // Assume that ES6 syntax isn't supported.
- hasBadLetScoping = false;
- }
- goog.hasBadLetScoping = hasBadLetScoping;
- }
- return goog.hasBadLetScoping;
- };
- /**
- * @param {string} moduleDef
- * @return {string}
- * @package Visible for testing.
- */
- goog.workaroundSafari10EvalBug = function(moduleDef) {
- return '(function(){' + moduleDef +
- '\n' + // Terminate any trailing single line comment.
- ';' + // Terminate any trailing expression.
- '})();\n';
- };
- /**
- * @param {function(?):?|string} moduleDef The module definition.
- */
- goog.loadModule = function(moduleDef) {
- // NOTE: we allow function definitions to be either in the from
- // of a string to eval (which keeps the original source intact) or
- // in a eval forbidden environment (CSP) we allow a function definition
- // which in its body must call {@code goog.module}, and return the exports
- // of the module.
- var previousState = goog.moduleLoaderState_;
- try {
- goog.moduleLoaderState_ = {
- moduleName: undefined,
- declareLegacyNamespace: false
- };
- var exports;
- if (goog.isFunction(moduleDef)) {
- exports = moduleDef.call(undefined, {});
- } else if (goog.isString(moduleDef)) {
- if (goog.useSafari10Workaround()) {
- moduleDef = goog.workaroundSafari10EvalBug(moduleDef);
- }
- exports = goog.loadModuleFromSource_.call(undefined, moduleDef);
- } else {
- throw new Error('Invalid module definition');
- }
- var moduleName = goog.moduleLoaderState_.moduleName;
- if (!goog.isString(moduleName) || !moduleName) {
- throw new Error('Invalid module name \"' + moduleName + '\"');
- }
- // Don't seal legacy namespaces as they may be uses as a parent of
- // another namespace
- if (goog.moduleLoaderState_.declareLegacyNamespace) {
- goog.constructNamespace_(moduleName, exports);
- } else if (
- goog.SEAL_MODULE_EXPORTS && Object.seal && typeof exports == 'object' &&
- exports != null) {
- Object.seal(exports);
- }
- goog.loadedModules_[moduleName] = exports;
- } finally {
- goog.moduleLoaderState_ = previousState;
- }
- };
- /**
- * @private @const
- */
- goog.loadModuleFromSource_ = /** @type {function(string):?} */ (function() {
- // NOTE: we avoid declaring parameters or local variables here to avoid
- // masking globals or leaking values into the module definition.
- 'use strict';
- var exports = {};
- eval(arguments[0]);
- return exports;
- });
- /**
- * Normalize a file path by removing redundant ".." and extraneous "." file
- * path components.
- * @param {string} path
- * @return {string}
- * @private
- */
- goog.normalizePath_ = function(path) {
- var components = path.split('/');
- var i = 0;
- while (i < components.length) {
- if (components[i] == '.') {
- components.splice(i, 1);
- } else if (
- i && components[i] == '..' && components[i - 1] &&
- components[i - 1] != '..') {
- components.splice(--i, 2);
- } else {
- i++;
- }
- }
- return components.join('/');
- };
- /**
- * Provides a hook for loading a file when using Closure's goog.require() API
- * with goog.modules. In particular this hook is provided to support Node.js.
- *
- * @type {(function(string):string)|undefined}
- */
- goog.global.CLOSURE_LOAD_FILE_SYNC;
- /**
- * Loads file by synchronous XHR. Should not be used in production environments.
- * @param {string} src Source URL.
- * @return {?string} File contents, or null if load failed.
- * @private
- */
- goog.loadFileSync_ = function(src) {
- if (goog.global.CLOSURE_LOAD_FILE_SYNC) {
- return goog.global.CLOSURE_LOAD_FILE_SYNC(src);
- } else {
- try {
- /** @type {XMLHttpRequest} */
- var xhr = new goog.global['XMLHttpRequest']();
- xhr.open('get', src, false);
- xhr.send();
- // NOTE: Successful http: requests have a status of 200, but successful
- // file: requests may have a status of zero. Any other status, or a
- // thrown exception (particularly in case of file: requests) indicates
- // some sort of error, which we treat as a missing or unavailable file.
- return xhr.status == 0 || xhr.status == 200 ? xhr.responseText : null;
- } catch (err) {
- // No need to rethrow or log, since errors should show up on their own.
- return null;
- }
- }
- };
- /**
- * Retrieve and execute a script that needs some sort of wrapping.
- * @param {string} src Script source URL.
- * @param {boolean} isModule Whether to load as a module.
- * @param {boolean} needsTranspile Whether to transpile down to ES3.
- * @private
- */
- goog.retrieveAndExec_ = function(src, isModule, needsTranspile) {
- if (!COMPILED) {
- // The full but non-canonicalized URL for later use.
- var originalPath = src;
- // Canonicalize the path, removing any /./ or /../ since Chrome's debugging
- // console doesn't auto-canonicalize XHR loads as it does <script> srcs.
- src = goog.normalizePath_(src);
- var importScript =
- goog.global.CLOSURE_IMPORT_SCRIPT || goog.writeScriptTag_;
- var scriptText = goog.loadFileSync_(src);
- if (scriptText == null) {
- throw new Error('Load of "' + src + '" failed');
- }
- if (needsTranspile) {
- scriptText = goog.transpile_.call(goog.global, scriptText, src);
- }
- if (isModule) {
- scriptText = goog.wrapModule_(src, scriptText);
- } else {
- scriptText += '\n//# sourceURL=' + src;
- }
- var isOldIE = goog.IS_OLD_IE_;
- if (isOldIE && goog.oldIeWaiting_) {
- goog.dependencies_.deferred[originalPath] = scriptText;
- goog.queuedModules_.push(originalPath);
- } else {
- importScript(src, scriptText);
- }
- }
- };
- /**
- * Lazily retrieves the transpiler and applies it to the source.
- * @param {string} code JS code.
- * @param {string} path Path to the code.
- * @return {string} The transpiled code.
- * @private
- */
- goog.transpile_ = function(code, path) {
- var jscomp = goog.global['$jscomp'];
- if (!jscomp) {
- goog.global['$jscomp'] = jscomp = {};
- }
- var transpile = jscomp.transpile;
- if (!transpile) {
- var transpilerPath = goog.basePath + goog.TRANSPILER;
- var transpilerCode = goog.loadFileSync_(transpilerPath);
- if (transpilerCode) {
- // This must be executed synchronously, since by the time we know we
- // need it, we're about to load and write the ES6 code synchronously,
- // so a normal script-tag load will be too slow.
- eval(transpilerCode + '\n//# sourceURL=' + transpilerPath);
- // Even though the transpiler is optional, if $gwtExport is found, it's
- // a sign the transpiler was loaded and the $jscomp.transpile *should*
- // be there.
- if (goog.global['$gwtExport'] && goog.global['$gwtExport']['$jscomp'] &&
- !goog.global['$gwtExport']['$jscomp']['transpile']) {
- throw new Error(
- 'The transpiler did not properly export the "transpile" ' +
- 'method. $gwtExport: ' + JSON.stringify(goog.global['$gwtExport']));
- }
- // transpile.js only exports a single $jscomp function, transpile. We
- // grab just that and add it to the existing definition of $jscomp which
- // contains the polyfills.
- goog.global['$jscomp'].transpile =
- goog.global['$gwtExport']['$jscomp']['transpile'];
- jscomp = goog.global['$jscomp'];
- transpile = jscomp.transpile;
- }
- }
- if (!transpile) {
- // The transpiler is an optional component. If it's not available then
- // replace it with a pass-through function that simply logs.
- var suffix = ' requires transpilation but no transpiler was found.';
- transpile = jscomp.transpile = function(code, path) {
- // TODO(user): figure out some way to get this error to show up
- // in test results, noting that the failure may occur in many
- // different ways, including in loadModule() before the test
- // runner even comes up.
- goog.logToConsole_(path + suffix);
- return code;
- };
- }
- // Note: any transpilation errors/warnings will be logged to the console.
- return transpile(code, path);
- };
- //==============================================================================
- // Language Enhancements
- //==============================================================================
- /**
- * This is a "fixed" version of the typeof operator. It differs from the typeof
- * operator in such a way that null returns 'null' and arrays return 'array'.
- * @param {?} value The value to get the type of.
- * @return {string} The name of the type.
- */
- goog.typeOf = function(value) {
- var s = typeof value;
- if (s == 'object') {
- if (value) {
- // Check these first, so we can avoid calling Object.prototype.toString if
- // possible.
- //
- // IE improperly marshals typeof across execution contexts, but a
- // cross-context object will still return false for "instanceof Object".
- if (value instanceof Array) {
- return 'array';
- } else if (value instanceof Object) {
- return s;
- }
- // HACK: In order to use an Object prototype method on the arbitrary
- // value, the compiler requires the value be cast to type Object,
- // even though the ECMA spec explicitly allows it.
- var className = Object.prototype.toString.call(
- /** @type {!Object} */ (value));
- // In Firefox 3.6, attempting to access iframe window objects' length
- // property throws an NS_ERROR_FAILURE, so we need to special-case it
- // here.
- if (className == '[object Window]') {
- return 'object';
- }
- // We cannot always use constructor == Array or instanceof Array because
- // different frames have different Array objects. In IE6, if the iframe
- // where the array was created is destroyed, the array loses its
- // prototype. Then dereferencing val.splice here throws an exception, so
- // we can't use goog.isFunction. Calling typeof directly returns 'unknown'
- // so that will work. In this case, this function will return false and
- // most array functions will still work because the array is still
- // array-like (supports length and []) even though it has lost its
- // prototype.
- // Mark Miller noticed that Object.prototype.toString
- // allows access to the unforgeable [[Class]] property.
- // 15.2.4.2 Object.prototype.toString ( )
- // When the toString method is called, the following steps are taken:
- // 1. Get the [[Class]] property of this object.
- // 2. Compute a string value by concatenating the three strings
- // "[object ", Result(1), and "]".
- // 3. Return Result(2).
- // and this behavior survives the destruction of the execution context.
- if ((className == '[object Array]' ||
- // In IE all non value types are wrapped as objects across window
- // boundaries (not iframe though) so we have to do object detection
- // for this edge case.
- typeof value.length == 'number' &&
- typeof value.splice != 'undefined' &&
- typeof value.propertyIsEnumerable != 'undefined' &&
- !value.propertyIsEnumerable('splice')
- )) {
- return 'array';
- }
- // HACK: There is still an array case that fails.
- // function ArrayImpostor() {}
- // ArrayImpostor.prototype = [];
- // var impostor = new ArrayImpostor;
- // this can be fixed by getting rid of the fast path
- // (value instanceof Array) and solely relying on
- // (value && Object.prototype.toString.vall(value) === '[object Array]')
- // but that would require many more function calls and is not warranted
- // unless closure code is receiving objects from untrusted sources.
- // IE in cross-window calls does not correctly marshal the function type
- // (it appears just as an object) so we cannot use just typeof val ==
- // 'function'. However, if the object has a call property, it is a
- // function.
- if ((className == '[object Function]' ||
- typeof value.call != 'undefined' &&
- typeof value.propertyIsEnumerable != 'undefined' &&
- !value.propertyIsEnumerable('call'))) {
- return 'function';
- }
- } else {
- return 'null';
- }
- } else if (s == 'function' && typeof value.call == 'undefined') {
- // In Safari typeof nodeList returns 'function', and on Firefox typeof
- // behaves similarly for HTML{Applet,Embed,Object}, Elements and RegExps. We
- // would like to return object for those and we can detect an invalid
- // function by making sure that the function object has a call method.
- return 'object';
- }
- return s;
- };
- /**
- * Returns true if the specified value is null.
- * @param {?} val Variable to test.
- * @return {boolean} Whether variable is null.
- */
- goog.isNull = function(val) {
- return val === null;
- };
- /**
- * Returns true if the specified value is defined and not null.
- * @param {?} val Variable to test.
- * @return {boolean} Whether variable is defined and not null.
- */
- goog.isDefAndNotNull = function(val) {
- // Note that undefined == null.
- return val != null;
- };
- /**
- * Returns true if the specified value is an array.
- * @param {?} val Variable to test.
- * @return {boolean} Whether variable is an array.
- */
- goog.isArray = function(val) {
- return goog.typeOf(val) == 'array';
- };
- /**
- * Returns true if the object looks like an array. To qualify as array like
- * the value needs to be either a NodeList or an object with a Number length
- * property. As a special case, a function value is not array like, because its
- * length property is fixed to correspond to the number of expected arguments.
- * @param {?} val Variable to test.
- * @return {boolean} Whether variable is an array.
- */
- goog.isArrayLike = function(val) {
- var type = goog.typeOf(val);
- // We do not use goog.isObject here in order to exclude function values.
- return type == 'array' || type == 'object' && typeof val.length == 'number';
- };
- /**
- * Returns true if the object looks like a Date. To qualify as Date-like the
- * value needs to be an object and have a getFullYear() function.
- * @param {?} val Variable to test.
- * @return {boolean} Whether variable is a like a Date.
- */
- goog.isDateLike = function(val) {
- return goog.isObject(val) && typeof val.getFullYear == 'function';
- };
- /**
- * Returns true if the specified value is a function.
- * @param {?} val Variable to test.
- * @return {boolean} Whether variable is a function.
- */
- goog.isFunction = function(val) {
- return goog.typeOf(val) == 'function';
- };
- /**
- * Returns true if the specified value is an object. This includes arrays and
- * functions.
- * @param {?} val Variable to test.
- * @return {boolean} Whether variable is an object.
- */
- goog.isObject = function(val) {
- var type = typeof val;
- return type == 'object' && val != null || type == 'function';
- // return Object(val) === val also works, but is slower, especially if val is
- // not an object.
- };
- /**
- * Gets a unique ID for an object. This mutates the object so that further calls
- * with the same object as a parameter returns the same value. The unique ID is
- * guaranteed to be unique across the current session amongst objects that are
- * passed into {@code getUid}. There is no guarantee that the ID is unique or
- * consistent across sessions. It is unsafe to generate unique ID for function
- * prototypes.
- *
- * @param {Object} obj The object to get the unique ID for.
- * @return {number} The unique ID for the object.
- */
- goog.getUid = function(obj) {
- // TODO(arv): Make the type stricter, do not accept null.
- // In Opera window.hasOwnProperty exists but always returns false so we avoid
- // using it. As a consequence the unique ID generated for BaseClass.prototype
- // and SubClass.prototype will be the same.
- return obj[goog.UID_PROPERTY_] ||
- (obj[goog.UID_PROPERTY_] = ++goog.uidCounter_);
- };
- /**
- * Whether the given object is already assigned a unique ID.
- *
- * This does not modify the object.
- *
- * @param {!Object} obj The object to check.
- * @return {boolean} Whether there is an assigned unique id for the object.
- */
- goog.hasUid = function(obj) {
- return !!obj[goog.UID_PROPERTY_];
- };
- /**
- * Removes the unique ID from an object. This is useful if the object was
- * previously mutated using {@code goog.getUid} in which case the mutation is
- * undone.
- * @param {Object} obj The object to remove the unique ID field from.
- */
- goog.removeUid = function(obj) {
- // TODO(arv): Make the type stricter, do not accept null.
- // In IE, DOM nodes are not instances of Object and throw an exception if we
- // try to delete. Instead we try to use removeAttribute.
- if (obj !== null && 'removeAttribute' in obj) {
- obj.removeAttribute(goog.UID_PROPERTY_);
- }
- try {
- delete obj[goog.UID_PROPERTY_];
- } catch (ex) {
- }
- };
- /**
- * Name for unique ID property. Initialized in a way to help avoid collisions
- * with other closure JavaScript on the same page.
- * @type {string}
- * @private
- */
- goog.UID_PROPERTY_ = 'closure_uid_' + ((Math.random() * 1e9) >>> 0);
- /**
- * Counter for UID.
- * @type {number}
- * @private
- */
- goog.uidCounter_ = 0;
- /**
- * Adds a hash code field to an object. The hash code is unique for the
- * given object.
- * @param {Object} obj The object to get the hash code for.
- * @return {number} The hash code for the object.
- * @deprecated Use goog.getUid instead.
- */
- goog.getHashCode = goog.getUid;
- /**
- * Removes the hash code field from an object.
- * @param {Object} obj The object to remove the field from.
- * @deprecated Use goog.removeUid instead.
- */
- goog.removeHashCode = goog.removeUid;
- /**
- * Clones a value. The input may be an Object, Array, or basic type. Objects and
- * arrays will be cloned recursively.
- *
- * WARNINGS:
- * <code>goog.cloneObject</code> does not detect reference loops. Objects that
- * refer to themselves will cause infinite recursion.
- *
- * <code>goog.cloneObject</code> is unaware of unique identifiers, and copies
- * UIDs created by <code>getUid</code> into cloned results.
- *
- * @param {*} obj The value to clone.
- * @return {*} A clone of the input value.
- * @deprecated goog.cloneObject is unsafe. Prefer the goog.object methods.
- */
- goog.cloneObject = function(obj) {
- var type = goog.typeOf(obj);
- if (type == 'object' || type == 'array') {
- if (obj.clone) {
- return obj.clone();
- }
- var clone = type == 'array' ? [] : {};
- for (var key in obj) {
- clone[key] = goog.cloneObject(obj[key]);
- }
- return clone;
- }
- return obj;
- };
- /**
- * A native implementation of goog.bind.
- * @param {?function(this:T, ...)} fn A function to partially apply.
- * @param {T} selfObj Specifies the object which this should point to when the
- * function is run.
- * @param {...*} var_args Additional arguments that are partially applied to the
- * function.
- * @return {!Function} A partially-applied form of the function goog.bind() was
- * invoked as a method of.
- * @template T
- * @private
- */
- goog.bindNative_ = function(fn, selfObj, var_args) {
- return /** @type {!Function} */ (fn.call.apply(fn.bind, arguments));
- };
- /**
- * A pure-JS implementation of goog.bind.
- * @param {?function(this:T, ...)} fn A function to partially apply.
- * @param {T} selfObj Specifies the object which this should point to when the
- * function is run.
- * @param {...*} var_args Additional arguments that are partially applied to the
- * function.
- * @return {!Function} A partially-applied form of the function goog.bind() was
- * invoked as a method of.
- * @template T
- * @private
- */
- goog.bindJs_ = function(fn, selfObj, var_args) {
- if (!fn) {
- throw new Error();
- }
- if (arguments.length > 2) {
- var boundArgs = Array.prototype.slice.call(arguments, 2);
- return function() {
- // Prepend the bound arguments to the current arguments.
- var newArgs = Array.prototype.slice.call(arguments);
- Array.prototype.unshift.apply(newArgs, boundArgs);
- return fn.apply(selfObj, newArgs);
- };
- } else {
- return function() {
- return fn.apply(selfObj, arguments);
- };
- }
- };
- /**
- * Partially applies this function to a particular 'this object' and zero or
- * more arguments. The result is a new function with some arguments of the first
- * function pre-filled and the value of this 'pre-specified'.
- *
- * Remaining arguments specified at call-time are appended to the pre-specified
- * ones.
- *
- * Also see: {@link #partial}.
- *
- * Usage:
- * <pre>var barMethBound = goog.bind(myFunction, myObj, 'arg1', 'arg2');
- * barMethBound('arg3', 'arg4');</pre>
- *
- * @param {?function(this:T, ...)} fn A function to partially apply.
- * @param {T} selfObj Specifies the object which this should point to when the
- * function is run.
- * @param {...*} var_args Additional arguments that are partially applied to the
- * function.
- * @return {!Function} A partially-applied form of the function goog.bind() was
- * invoked as a method of.
- * @template T
- * @suppress {deprecated} See above.
- */
- goog.bind = function(fn, selfObj, var_args) {
- // TODO(nicksantos): narrow the type signature.
- if (Function.prototype.bind &&
- // NOTE(nicksantos): Somebody pulled base.js into the default Chrome
- // extension environment. This means that for Chrome extensions, they get
- // the implementation of Function.prototype.bind that calls goog.bind
- // instead of the native one. Even worse, we don't want to introduce a
- // circular dependency between goog.bind and Function.prototype.bind, so
- // we have to hack this to make sure it works correctly.
- Function.prototype.bind.toString().indexOf('native code') != -1) {
- goog.bind = goog.bindNative_;
- } else {
- goog.bind = goog.bindJs_;
- }
- return goog.bind.apply(null, arguments);
- };
- /**
- * Like goog.bind(), except that a 'this object' is not required. Useful when
- * the target function is already bound.
- *
- * Usage:
- * var g = goog.partial(f, arg1, arg2);
- * g(arg3, arg4);
- *
- * @param {Function} fn A function to partially apply.
- * @param {...*} var_args Additional arguments that are partially applied to fn.
- * @return {!Function} A partially-applied form of the function goog.partial()
- * was invoked as a method of.
- */
- goog.partial = function(fn, var_args) {
- var args = Array.prototype.slice.call(arguments, 1);
- return function() {
- // Clone the array (with slice()) and append additional arguments
- // to the existing arguments.
- var newArgs = args.slice();
- newArgs.push.apply(newArgs, arguments);
- return fn.apply(this, newArgs);
- };
- };
- /**
- * Copies all the members of a source object to a target object. This method
- * does not work on all browsers for all objects that contain keys such as
- * toString or hasOwnProperty. Use goog.object.extend for this purpose.
- * @param {Object} target Target.
- * @param {Object} source Source.
- */
- goog.mixin = function(target, source) {
- for (var x in source) {
- target[x] = source[x];
- }
- // For IE7 or lower, the for-in-loop does not contain any properties that are
- // not enumerable on the prototype object (for example, isPrototypeOf from
- // Object.prototype) but also it will not include 'replace' on objects that
- // extend String and change 'replace' (not that it is common for anyone to
- // extend anything except Object).
- };
- /**
- * @return {number} An integer value representing the number of milliseconds
- * between midnight, January 1, 1970 and the current time.
- */
- goog.now = (goog.TRUSTED_SITE && Date.now) || (function() {
- // Unary plus operator converts its operand to a number which in
- // the case of
- // a date is done by calling getTime().
- return +new Date();
- });
- /**
- * Evals JavaScript in the global scope. In IE this uses execScript, other
- * browsers use goog.global.eval. If goog.global.eval does not evaluate in the
- * global scope (for example, in Safari), appends a script tag instead.
- * Throws an exception if neither execScript or eval is defined.
- * @param {string} script JavaScript string.
- */
- goog.globalEval = function(script) {
- if (goog.global.execScript) {
- goog.global.execScript(script, 'JavaScript');
- } else if (goog.global.eval) {
- // Test to see if eval works
- if (goog.evalWorksForGlobals_ == null) {
- goog.global.eval('var _evalTest_ = 1;');
- if (typeof goog.global['_evalTest_'] != 'undefined') {
- try {
- delete goog.global['_evalTest_'];
- } catch (ignore) {
- // Microsoft edge fails the deletion above in strict mode.
- }
- goog.evalWorksForGlobals_ = true;
- } else {
- goog.evalWorksForGlobals_ = false;
- }
- }
- if (goog.evalWorksForGlobals_) {
- goog.global.eval(script);
- } else {
- /** @type {Document} */
- var doc = goog.global.document;
- var scriptElt =
- /** @type {!HTMLScriptElement} */ (doc.createElement('SCRIPT'));
- scriptElt.type = 'text/javascript';
- scriptElt.defer = false;
- // Note(user): can't use .innerHTML since "t('<test>')" will fail and
- // .text doesn't work in Safari 2. Therefore we append a text node.
- scriptElt.appendChild(doc.createTextNode(script));
- doc.body.appendChild(scriptElt);
- doc.body.removeChild(scriptElt);
- }
- } else {
- throw new Error('goog.globalEval not available');
- }
- };
- /**
- * Indicates whether or not we can call 'eval' directly to eval code in the
- * global scope. Set to a Boolean by the first call to goog.globalEval (which
- * empirically tests whether eval works for globals). @see goog.globalEval
- * @type {?boolean}
- * @private
- */
- goog.evalWorksForGlobals_ = null;
- /**
- * Optional map of CSS class names to obfuscated names used with
- * goog.getCssName().
- * @private {!Object<string, string>|undefined}
- * @see goog.setCssNameMapping
- */
- goog.cssNameMapping_;
- /**
- * Optional obfuscation style for CSS class names. Should be set to either
- * 'BY_WHOLE' or 'BY_PART' if defined.
- * @type {string|undefined}
- * @private
- * @see goog.setCssNameMapping
- */
- goog.cssNameMappingStyle_;
- /**
- * A hook for modifying the default behavior goog.getCssName. The function
- * if present, will recieve the standard output of the goog.getCssName as
- * its input.
- *
- * @type {(function(string):string)|undefined}
- */
- goog.global.CLOSURE_CSS_NAME_MAP_FN;
- /**
- * Handles strings that are intended to be used as CSS class names.
- *
- * This function works in tandem with @see goog.setCssNameMapping.
- *
- * Without any mapping set, the arguments are simple joined with a hyphen and
- * passed through unaltered.
- *
- * When there is a mapping, there are two possible styles in which these
- * mappings are used. In the BY_PART style, each part (i.e. in between hyphens)
- * of the passed in css name is rewritten according to the map. In the BY_WHOLE
- * style, the full css name is looked up in the map directly. If a rewrite is
- * not specified by the map, the compiler will output a warning.
- *
- * When the mapping is passed to the compiler, it will replace calls to
- * goog.getCssName with the strings from the mapping, e.g.
- * var x = goog.getCssName('foo');
- * var y = goog.getCssName(this.baseClass, 'active');
- * becomes:
- * var x = 'foo';
- * var y = this.baseClass + '-active';
- *
- * If one argument is passed it will be processed, if two are passed only the
- * modifier will be processed, as it is assumed the first argument was generated
- * as a result of calling goog.getCssName.
- *
- * @param {string} className The class name.
- * @param {string=} opt_modifier A modifier to be appended to the class name.
- * @return {string} The class name or the concatenation of the class name and
- * the modifier.
- */
- goog.getCssName = function(className, opt_modifier) {
- // String() is used for compatibility with compiled soy where the passed
- // className can be non-string objects.
- if (String(className).charAt(0) == '.') {
- throw new Error(
- 'className passed in goog.getCssName must not start with ".".' +
- ' You passed: ' + className);
- }
- var getMapping = function(cssName) {
- return goog.cssNameMapping_[cssName] || cssName;
- };
- var renameByParts = function(cssName) {
- // Remap all the parts individually.
- var parts = cssName.split('-');
- var mapped = [];
- for (var i = 0; i < parts.length; i++) {
- mapped.push(getMapping(parts[i]));
- }
- return mapped.join('-');
- };
- var rename;
- if (goog.cssNameMapping_) {
- rename =
- goog.cssNameMappingStyle_ == 'BY_WHOLE' ? getMapping : renameByParts;
- } else {
- rename = function(a) {
- return a;
- };
- }
- var result =
- opt_modifier ? className + '-' + rename(opt_modifier) : rename(className);
- // The special CLOSURE_CSS_NAME_MAP_FN allows users to specify further
- // processing of the class name.
- if (goog.global.CLOSURE_CSS_NAME_MAP_FN) {
- return goog.global.CLOSURE_CSS_NAME_MAP_FN(result);
- }
- return result;
- };
- /**
- * Sets the map to check when returning a value from goog.getCssName(). Example:
- * <pre>
- * goog.setCssNameMapping({
- * "goog": "a",
- * "disabled": "b",
- * });
- *
- * var x = goog.getCssName('goog');
- * // The following evaluates to: "a a-b".
- * goog.getCssName('goog') + ' ' + goog.getCssName(x, 'disabled')
- * </pre>
- * When declared as a map of string literals to string literals, the JSCompiler
- * will replace all calls to goog.getCssName() using the supplied map if the
- * --process_closure_primitives flag is set.
- *
- * @param {!Object} mapping A map of strings to strings where keys are possible
- * arguments to goog.getCssName() and values are the corresponding values
- * that should be returned.
- * @param {string=} opt_style The style of css name mapping. There are two valid
- * options: 'BY_PART', and 'BY_WHOLE'.
- * @see goog.getCssName for a description.
- */
- goog.setCssNameMapping = function(mapping, opt_style) {
- goog.cssNameMapping_ = mapping;
- goog.cssNameMappingStyle_ = opt_style;
- };
- /**
- * To use CSS renaming in compiled mode, one of the input files should have a
- * call to goog.setCssNameMapping() with an object literal that the JSCompiler
- * can extract and use to replace all calls to goog.getCssName(). In uncompiled
- * mode, JavaScript code should be loaded before this base.js file that declares
- * a global variable, CLOSURE_CSS_NAME_MAPPING, which is used below. This is
- * to ensure that the mapping is loaded before any calls to goog.getCssName()
- * are made in uncompiled mode.
- *
- * A hook for overriding the CSS name mapping.
- * @type {!Object<string, string>|undefined}
- */
- goog.global.CLOSURE_CSS_NAME_MAPPING;
- if (!COMPILED && goog.global.CLOSURE_CSS_NAME_MAPPING) {
- // This does not call goog.setCssNameMapping() because the JSCompiler
- // requires that goog.setCssNameMapping() be called with an object literal.
- goog.cssNameMapping_ = goog.global.CLOSURE_CSS_NAME_MAPPING;
- }
- /**
- * Gets a localized message.
- *
- * This function is a compiler primitive. If you give the compiler a localized
- * message bundle, it will replace the string at compile-time with a localized
- * version, and expand goog.getMsg call to a concatenated string.
- *
- * Messages must be initialized in the form:
- * <code>
- * var MSG_NAME = goog.getMsg('Hello {$placeholder}', {'placeholder': 'world'});
- * </code>
- *
- * This function produces a string which should be treated as plain text. Use
- * {@link goog.html.SafeHtmlFormatter} in conjunction with goog.getMsg to
- * produce SafeHtml.
- *
- * @param {string} str Translatable string, places holders in the form {$foo}.
- * @param {Object<string, string>=} opt_values Maps place holder name to value.
- * @return {string} message with placeholders filled.
- */
- goog.getMsg = function(str, opt_values) {
- if (opt_values) {
- str = str.replace(/\{\$([^}]+)}/g, function(match, key) {
- return (opt_values != null && key in opt_values) ? opt_values[key] :
- match;
- });
- }
- return str;
- };
- /**
- * Gets a localized message. If the message does not have a translation, gives a
- * fallback message.
- *
- * This is useful when introducing a new message that has not yet been
- * translated into all languages.
- *
- * This function is a compiler primitive. Must be used in the form:
- * <code>var x = goog.getMsgWithFallback(MSG_A, MSG_B);</code>
- * where MSG_A and MSG_B were initialized with goog.getMsg.
- *
- * @param {string} a The preferred message.
- * @param {string} b The fallback message.
- * @return {string} The best translated message.
- */
- goog.getMsgWithFallback = function(a, b) {
- return a;
- };
- /**
- * Exposes an unobfuscated global namespace path for the given object.
- * Note that fields of the exported object *will* be obfuscated, unless they are
- * exported in turn via this function or goog.exportProperty.
- *
- * Also handy for making public items that are defined in anonymous closures.
- *
- * ex. goog.exportSymbol('public.path.Foo', Foo);
- *
- * ex. goog.exportSymbol('public.path.Foo.staticFunction', Foo.staticFunction);
- * public.path.Foo.staticFunction();
- *
- * ex. goog.exportSymbol('public.path.Foo.prototype.myMethod',
- * Foo.prototype.myMethod);
- * new public.path.Foo().myMethod();
- *
- * @param {string} publicPath Unobfuscated name to export.
- * @param {*} object Object the name should point to.
- * @param {Object=} opt_objectToExportTo The object to add the path to; default
- * is goog.global.
- */
- goog.exportSymbol = function(publicPath, object, opt_objectToExportTo) {
- goog.exportPath_(publicPath, object, opt_objectToExportTo);
- };
- /**
- * Exports a property unobfuscated into the object's namespace.
- * ex. goog.exportProperty(Foo, 'staticFunction', Foo.staticFunction);
- * ex. goog.exportProperty(Foo.prototype, 'myMethod', Foo.prototype.myMethod);
- * @param {Object} object Object whose static property is being exported.
- * @param {string} publicName Unobfuscated name to export.
- * @param {*} symbol Object the name should point to.
- */
- goog.exportProperty = function(object, publicName, symbol) {
- object[publicName] = symbol;
- };
- /**
- * Inherit the prototype methods from one constructor into another.
- *
- * Usage:
- * <pre>
- * function ParentClass(a, b) { }
- * ParentClass.prototype.foo = function(a) { };
- *
- * function ChildClass(a, b, c) {
- * ChildClass.base(this, 'constructor', a, b);
- * }
- * goog.inherits(ChildClass, ParentClass);
- *
- * var child = new ChildClass('a', 'b', 'see');
- * child.foo(); // This works.
- * </pre>
- *
- * @param {!Function} childCtor Child class.
- * @param {!Function} parentCtor Parent class.
- */
- goog.inherits = function(childCtor, parentCtor) {
- /** @constructor */
- function tempCtor() {}
- tempCtor.prototype = parentCtor.prototype;
- childCtor.superClass_ = parentCtor.prototype;
- childCtor.prototype = new tempCtor();
- /** @override */
- childCtor.prototype.constructor = childCtor;
- /**
- * Calls superclass constructor/method.
- *
- * This function is only available if you use goog.inherits to
- * express inheritance relationships between classes.
- *
- * NOTE: This is a replacement for goog.base and for superClass_
- * property defined in childCtor.
- *
- * @param {!Object} me Should always be "this".
- * @param {string} methodName The method name to call. Calling
- * superclass constructor can be done with the special string
- * 'constructor'.
- * @param {...*} var_args The arguments to pass to superclass
- * method/constructor.
- * @return {*} The return value of the superclass method/constructor.
- */
- childCtor.base = function(me, methodName, var_args) {
- // Copying using loop to avoid deop due to passing arguments object to
- // function. This is faster in many JS engines as of late 2014.
- var args = new Array(arguments.length - 2);
- for (var i = 2; i < arguments.length; i++) {
- args[i - 2] = arguments[i];
- }
- return parentCtor.prototype[methodName].apply(me, args);
- };
- };
- /**
- * Call up to the superclass.
- *
- * If this is called from a constructor, then this calls the superclass
- * constructor with arguments 1-N.
- *
- * If this is called from a prototype method, then you must pass the name of the
- * method as the second argument to this function. If you do not, you will get a
- * runtime error. This calls the superclass' method with arguments 2-N.
- *
- * This function only works if you use goog.inherits to express inheritance
- * relationships between your classes.
- *
- * This function is a compiler primitive. At compile-time, the compiler will do
- * macro expansion to remove a lot of the extra overhead that this function
- * introduces. The compiler will also enforce a lot of the assumptions that this
- * function makes, and treat it as a compiler error if you break them.
- *
- * @param {!Object} me Should always be "this".
- * @param {*=} opt_methodName The method name if calling a super method.
- * @param {...*} var_args The rest of the arguments.
- * @return {*} The return value of the superclass method.
- * @suppress {es5Strict} This method can not be used in strict mode, but
- * all Closure Library consumers must depend on this file.
- * @deprecated goog.base is not strict mode compatible. Prefer the static
- * "base" method added to the constructor by goog.inherits
- * or ES6 classes and the "super" keyword.
- */
- goog.base = function(me, opt_methodName, var_args) {
- var caller = arguments.callee.caller;
- if (goog.STRICT_MODE_COMPATIBLE || (goog.DEBUG && !caller)) {
- throw new Error(
- 'arguments.caller not defined. goog.base() cannot be used ' +
- 'with strict mode code. See ' +
- 'http://www.ecma-international.org/ecma-262/5.1/#sec-C');
- }
- if (caller.superClass_) {
- // Copying using loop to avoid deop due to passing arguments object to
- // function. This is faster in many JS engines as of late 2014.
- var ctorArgs = new Array(arguments.length - 1);
- for (var i = 1; i < arguments.length; i++) {
- ctorArgs[i - 1] = arguments[i];
- }
- // This is a constructor. Call the superclass constructor.
- return caller.superClass_.constructor.apply(me, ctorArgs);
- }
- // Copying using loop to avoid deop due to passing arguments object to
- // function. This is faster in many JS engines as of late 2014.
- var args = new Array(arguments.length - 2);
- for (var i = 2; i < arguments.length; i++) {
- args[i - 2] = arguments[i];
- }
- var foundCaller = false;
- for (var ctor = me.constructor; ctor;
- ctor = ctor.superClass_ && ctor.superClass_.constructor) {
- if (ctor.prototype[opt_methodName] === caller) {
- foundCaller = true;
- } else if (foundCaller) {
- return ctor.prototype[opt_methodName].apply(me, args);
- }
- }
- // If we did not find the caller in the prototype chain, then one of two
- // things happened:
- // 1) The caller is an instance method.
- // 2) This method was not called by the right caller.
- if (me[opt_methodName] === caller) {
- return me.constructor.prototype[opt_methodName].apply(me, args);
- } else {
- throw new Error(
- 'goog.base called from a method of one name ' +
- 'to a method of a different name');
- }
- };
- /**
- * Allow for aliasing within scope functions. This function exists for
- * uncompiled code - in compiled code the calls will be inlined and the aliases
- * applied. In uncompiled code the function is simply run since the aliases as
- * written are valid JavaScript.
- *
- *
- * @param {function()} fn Function to call. This function can contain aliases
- * to namespaces (e.g. "var dom = goog.dom") or classes
- * (e.g. "var Timer = goog.Timer").
- */
- goog.scope = function(fn) {
- if (goog.isInModuleLoader_()) {
- throw new Error('goog.scope is not supported within a goog.module.');
- }
- fn.call(goog.global);
- };
- /*
- * To support uncompiled, strict mode bundles that use eval to divide source
- * like so:
- * eval('someSource;//# sourceUrl sourcefile.js');
- * We need to export the globally defined symbols "goog" and "COMPILED".
- * Exporting "goog" breaks the compiler optimizations, so we required that
- * be defined externally.
- * NOTE: We don't use goog.exportSymbol here because we don't want to trigger
- * extern generation when that compiler option is enabled.
- */
- if (!COMPILED) {
- goog.global['COMPILED'] = COMPILED;
- }
- //==============================================================================
- // goog.defineClass implementation
- //==============================================================================
- /**
- * Creates a restricted form of a Closure "class":
- * - from the compiler's perspective, the instance returned from the
- * constructor is sealed (no new properties may be added). This enables
- * better checks.
- * - the compiler will rewrite this definition to a form that is optimal
- * for type checking and optimization (initially this will be a more
- * traditional form).
- *
- * @param {Function} superClass The superclass, Object or null.
- * @param {goog.defineClass.ClassDescriptor} def
- * An object literal describing
- * the class. It may have the following properties:
- * "constructor": the constructor function
- * "statics": an object literal containing methods to add to the constructor
- * as "static" methods or a function that will receive the constructor
- * function as its only parameter to which static properties can
- * be added.
- * all other properties are added to the prototype.
- * @return {!Function} The class constructor.
- */
- goog.defineClass = function(superClass, def) {
- // TODO(johnlenz): consider making the superClass an optional parameter.
- var constructor = def.constructor;
- var statics = def.statics;
- // Wrap the constructor prior to setting up the prototype and static methods.
- if (!constructor || constructor == Object.prototype.constructor) {
- constructor = function() {
- throw new Error(
- 'cannot instantiate an interface (no constructor defined).');
- };
- }
- var cls = goog.defineClass.createSealingConstructor_(constructor, superClass);
- if (superClass) {
- goog.inherits(cls, superClass);
- }
- // Remove all the properties that should not be copied to the prototype.
- delete def.constructor;
- delete def.statics;
- goog.defineClass.applyProperties_(cls.prototype, def);
- if (statics != null) {
- if (statics instanceof Function) {
- statics(cls);
- } else {
- goog.defineClass.applyProperties_(cls, statics);
- }
- }
- return cls;
- };
- /**
- * @typedef {{
- * constructor: (!Function|undefined),
- * statics: (Object|undefined|function(Function):void)
- * }}
- */
- goog.defineClass.ClassDescriptor;
- /**
- * @define {boolean} Whether the instances returned by goog.defineClass should
- * be sealed when possible.
- *
- * When sealing is disabled the constructor function will not be wrapped by
- * goog.defineClass, making it incompatible with ES6 class methods.
- */
- goog.define('goog.defineClass.SEAL_CLASS_INSTANCES', goog.DEBUG);
- /**
- * If goog.defineClass.SEAL_CLASS_INSTANCES is enabled and Object.seal is
- * defined, this function will wrap the constructor in a function that seals the
- * results of the provided constructor function.
- *
- * @param {!Function} ctr The constructor whose results maybe be sealed.
- * @param {Function} superClass The superclass constructor.
- * @return {!Function} The replacement constructor.
- * @private
- */
- goog.defineClass.createSealingConstructor_ = function(ctr, superClass) {
- if (!goog.defineClass.SEAL_CLASS_INSTANCES) {
- // Do now wrap the constructor when sealing is disabled. Angular code
- // depends on this for injection to work properly.
- return ctr;
- }
- // Compute whether the constructor is sealable at definition time, rather
- // than when the instance is being constructed.
- var superclassSealable = !goog.defineClass.isUnsealable_(superClass);
- /**
- * @this {Object}
- * @return {?}
- */
- var wrappedCtr = function() {
- // Don't seal an instance of a subclass when it calls the constructor of
- // its super class as there is most likely still setup to do.
- var instance = ctr.apply(this, arguments) || this;
- instance[goog.UID_PROPERTY_] = instance[goog.UID_PROPERTY_];
- if (this.constructor === wrappedCtr && superclassSealable &&
- Object.seal instanceof Function) {
- Object.seal(instance);
- }
- return instance;
- };
- return wrappedCtr;
- };
- /**
- * @param {Function} ctr The constructor to test.
- * @return {boolean} Whether the constructor has been tagged as unsealable
- * using goog.tagUnsealableClass.
- * @private
- */
- goog.defineClass.isUnsealable_ = function(ctr) {
- return ctr && ctr.prototype &&
- ctr.prototype[goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_];
- };
- // TODO(johnlenz): share these values with the goog.object
- /**
- * The names of the fields that are defined on Object.prototype.
- * @type {!Array<string>}
- * @private
- * @const
- */
- goog.defineClass.OBJECT_PROTOTYPE_FIELDS_ = [
- 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
- 'toLocaleString', 'toString', 'valueOf'
- ];
- // TODO(johnlenz): share this function with the goog.object
- /**
- * @param {!Object} target The object to add properties to.
- * @param {!Object} source The object to copy properties from.
- * @private
- */
- goog.defineClass.applyProperties_ = function(target, source) {
- // TODO(johnlenz): update this to support ES5 getters/setters
- var key;
- for (key in source) {
- if (Object.prototype.hasOwnProperty.call(source, key)) {
- target[key] = source[key];
- }
- }
- // For IE the for-in-loop does not contain any properties that are not
- // enumerable on the prototype object (for example isPrototypeOf from
- // Object.prototype) and it will also not include 'replace' on objects that
- // extend String and change 'replace' (not that it is common for anyone to
- // extend anything except Object).
- for (var i = 0; i < goog.defineClass.OBJECT_PROTOTYPE_FIELDS_.length; i++) {
- key = goog.defineClass.OBJECT_PROTOTYPE_FIELDS_[i];
- if (Object.prototype.hasOwnProperty.call(source, key)) {
- target[key] = source[key];
- }
- }
- };
- /**
- * Sealing classes breaks the older idiom of assigning properties on the
- * prototype rather than in the constructor. As such, goog.defineClass
- * must not seal subclasses of these old-style classes until they are fixed.
- * Until then, this marks a class as "broken", instructing defineClass
- * not to seal subclasses.
- * @param {!Function} ctr The legacy constructor to tag as unsealable.
- */
- goog.tagUnsealableClass = function(ctr) {
- if (!COMPILED && goog.defineClass.SEAL_CLASS_INSTANCES) {
- ctr.prototype[goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_] = true;
- }
- };
- /**
- * Name for unsealable tag property.
- * @const @private {string}
- */
- goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_ = 'goog_defineClass_legacy_unsealable';
- /**
- * Returns a newly created map from language mode string to a boolean
- * indicating whether transpilation should be done for that mode.
- *
- * Guaranteed invariant:
- * For any two modes, l1 and l2 where l2 is a newer mode than l1,
- * `map[l1] == true` implies that `map[l2] == true`.
- * @private
- * @return {!Object<string, boolean>}
- */
- goog.createRequiresTranspilation_ = function() {
- var /** !Object<string, boolean> */ requiresTranspilation = {'es3': false};
- var transpilationRequiredForAllLaterModes = false;
- /**
- * Adds an entry to requiresTranspliation for the given language mode.
- *
- * IMPORTANT: Calls must be made in order from oldest to newest language
- * mode.
- * @param {string} modeName
- * @param {function(): boolean} isSupported Returns true if the JS engine
- * supports the given mode.
- */
- function addNewerLanguageTranspilationCheck(modeName, isSupported) {
- if (transpilationRequiredForAllLaterModes) {
- requiresTranspilation[modeName] = true;
- } else if (isSupported()) {
- requiresTranspilation[modeName] = false;
- } else {
- requiresTranspilation[modeName] = true;
- transpilationRequiredForAllLaterModes = true;
- }
- }
- /**
- * Does the given code evaluate without syntax errors and return a truthy
- * result?
- */
- function /** boolean */ evalCheck(/** string */ code) {
- try {
- return !!eval(code);
- } catch (ignored) {
- return false;
- }
- }
- var userAgent = goog.global.navigator && goog.global.navigator.userAgent ?
- goog.global.navigator.userAgent :
- '';
- // Identify ES3-only browsers by their incorrect treatment of commas.
- addNewerLanguageTranspilationCheck('es5', function() {
- return evalCheck('[1,].length==1');
- });
- addNewerLanguageTranspilationCheck('es6', function() {
- // Edge has a non-deterministic (i.e., not reproducible) bug with ES6:
- // https://github.com/Microsoft/ChakraCore/issues/1496.
- var re = /Edge\/(\d+)(\.\d)*/i;
- var edgeUserAgent = userAgent.match(re);
- if (edgeUserAgent && Number(edgeUserAgent[1]) < 15) {
- return false;
- }
- // Test es6: [FF50 (?), Edge 14 (?), Chrome 50]
- // (a) default params (specifically shadowing locals),
- // (b) destructuring, (c) block-scoped functions,
- // (d) for-of (const), (e) new.target/Reflect.construct
- var es6fullTest =
- 'class X{constructor(){if(new.target!=String)throw 1;this.x=42}}' +
- 'let q=Reflect.construct(X,[],String);if(q.x!=42||!(q instanceof ' +
- 'String))throw 1;for(const a of[2,3]){if(a==2)continue;function ' +
- 'f(z={a}){let a=0;return z.a}{function f(){return 0;}}return f()' +
- '==3}';
- return evalCheck('(()=>{"use strict";' + es6fullTest + '})()');
- });
- // TODO(joeltine): Remove es6-impl references for b/31340605.
- // Consider es6-impl (widely-implemented es6 features) to be supported
- // whenever es6 is supported. Technically es6-impl is a lower level of
- // support than es6, but we don't have tests specifically for it.
- addNewerLanguageTranspilationCheck('es6-impl', function() {
- return true;
- });
- // ** and **= are the only new features in 'es7'
- addNewerLanguageTranspilationCheck('es7', function() {
- return evalCheck('2 ** 2 == 4');
- });
- // async functions are the only new features in 'es8'
- addNewerLanguageTranspilationCheck('es8', function() {
- return evalCheck('async () => 1, true');
- });
- return requiresTranspilation;
- };
- goog.provide('ol.array');
- /**
- * Performs a binary search on the provided sorted list and returns the index of the item if found. If it can't be found it'll return -1.
- * https://github.com/darkskyapp/binary-search
- *
- * @param {Array.<*>} haystack Items to search through.
- * @param {*} needle The item to look for.
- * @param {Function=} opt_comparator Comparator function.
- * @return {number} The index of the item if found, -1 if not.
- */
- ol.array.binarySearch = function(haystack, needle, opt_comparator) {
- var mid, cmp;
- var comparator = opt_comparator || ol.array.numberSafeCompareFunction;
- var low = 0;
- var high = haystack.length;
- var found = false;
- while (low < high) {
- /* Note that "(low + high) >>> 1" may overflow, and results in a typecast
- * to double (which gives the wrong results). */
- mid = low + (high - low >> 1);
- cmp = +comparator(haystack[mid], needle);
- if (cmp < 0.0) { /* Too low. */
- low = mid + 1;
- } else { /* Key found or too high */
- high = mid;
- found = !cmp;
- }
- }
- /* Key not found. */
- return found ? low : ~low;
- };
- /**
- * Compare function for array sort that is safe for numbers.
- * @param {*} a The first object to be compared.
- * @param {*} b The second object to be compared.
- * @return {number} A negative number, zero, or a positive number as the first
- * argument is less than, equal to, or greater than the second.
- */
- ol.array.numberSafeCompareFunction = function(a, b) {
- return a > b ? 1 : a < b ? -1 : 0;
- };
- /**
- * Whether the array contains the given object.
- * @param {Array.<*>} arr The array to test for the presence of the element.
- * @param {*} obj The object for which to test.
- * @return {boolean} The object is in the array.
- */
- ol.array.includes = function(arr, obj) {
- return arr.indexOf(obj) >= 0;
- };
- /**
- * @param {Array.<number>} arr Array.
- * @param {number} target Target.
- * @param {number} direction 0 means return the nearest, > 0
- * means return the largest nearest, < 0 means return the
- * smallest nearest.
- * @return {number} Index.
- */
- ol.array.linearFindNearest = function(arr, target, direction) {
- var n = arr.length;
- if (arr[0] <= target) {
- return 0;
- } else if (target <= arr[n - 1]) {
- return n - 1;
- } else {
- var i;
- if (direction > 0) {
- for (i = 1; i < n; ++i) {
- if (arr[i] < target) {
- return i - 1;
- }
- }
- } else if (direction < 0) {
- for (i = 1; i < n; ++i) {
- if (arr[i] <= target) {
- return i;
- }
- }
- } else {
- for (i = 1; i < n; ++i) {
- if (arr[i] == target) {
- return i;
- } else if (arr[i] < target) {
- if (arr[i - 1] - target < target - arr[i]) {
- return i - 1;
- } else {
- return i;
- }
- }
- }
- }
- return n - 1;
- }
- };
- /**
- * @param {Array.<*>} arr Array.
- * @param {number} begin Begin index.
- * @param {number} end End index.
- */
- ol.array.reverseSubArray = function(arr, begin, end) {
- while (begin < end) {
- var tmp = arr[begin];
- arr[begin] = arr[end];
- arr[end] = tmp;
- ++begin;
- --end;
- }
- };
- /**
- * @param {Array.<VALUE>} arr The array to modify.
- * @param {Array.<VALUE>|VALUE} data The elements or arrays of elements
- * to add to arr.
- * @template VALUE
- */
- ol.array.extend = function(arr, data) {
- var i;
- var extension = Array.isArray(data) ? data : [data];
- var length = extension.length;
- for (i = 0; i < length; i++) {
- arr[arr.length] = extension[i];
- }
- };
- /**
- * @param {Array.<VALUE>} arr The array to modify.
- * @param {VALUE} obj The element to remove.
- * @template VALUE
- * @return {boolean} If the element was removed.
- */
- ol.array.remove = function(arr, obj) {
- var i = arr.indexOf(obj);
- var found = i > -1;
- if (found) {
- arr.splice(i, 1);
- }
- return found;
- };
- /**
- * @param {Array.<VALUE>} arr The array to search in.
- * @param {function(VALUE, number, ?) : boolean} func The function to compare.
- * @template VALUE
- * @return {VALUE} The element found.
- */
- ol.array.find = function(arr, func) {
- var length = arr.length >>> 0;
- var value;
- for (var i = 0; i < length; i++) {
- value = arr[i];
- if (func(value, i, arr)) {
- return value;
- }
- }
- return null;
- };
- /**
- * @param {Array|Uint8ClampedArray} arr1 The first array to compare.
- * @param {Array|Uint8ClampedArray} arr2 The second array to compare.
- * @return {boolean} Whether the two arrays are equal.
- */
- ol.array.equals = function(arr1, arr2) {
- var len1 = arr1.length;
- if (len1 !== arr2.length) {
- return false;
- }
- for (var i = 0; i < len1; i++) {
- if (arr1[i] !== arr2[i]) {
- return false;
- }
- }
- return true;
- };
- /**
- * @param {Array.<*>} arr The array to sort (modifies original).
- * @param {Function} compareFnc Comparison function.
- */
- ol.array.stableSort = function(arr, compareFnc) {
- var length = arr.length;
- var tmp = Array(arr.length);
- var i;
- for (i = 0; i < length; i++) {
- tmp[i] = {index: i, value: arr[i]};
- }
- tmp.sort(function(a, b) {
- return compareFnc(a.value, b.value) || a.index - b.index;
- });
- for (i = 0; i < arr.length; i++) {
- arr[i] = tmp[i].value;
- }
- };
- /**
- * @param {Array.<*>} arr The array to search in.
- * @param {Function} func Comparison function.
- * @return {number} Return index.
- */
- ol.array.findIndex = function(arr, func) {
- var index;
- var found = !arr.every(function(el, idx) {
- index = idx;
- return !func(el, idx, arr);
- });
- return found ? index : -1;
- };
- /**
- * @param {Array.<*>} arr The array to test.
- * @param {Function=} opt_func Comparison function.
- * @param {boolean=} opt_strict Strictly sorted (default false).
- * @return {boolean} Return index.
- */
- ol.array.isSorted = function(arr, opt_func, opt_strict) {
- var compare = opt_func || ol.array.numberSafeCompareFunction;
- return arr.every(function(currentVal, index) {
- if (index === 0) {
- return true;
- }
- var res = compare(arr[index - 1], currentVal);
- return !(res > 0 || opt_strict && res === 0);
- });
- };
- goog.provide('ol');
- /**
- * Constants defined with the define tag cannot be changed in application
- * code, but can be set at compile time.
- * Some reduce the size of the build in advanced compile mode.
- */
- /**
- * @define {boolean} Assume touch. Default is `false`.
- */
- ol.ASSUME_TOUCH = false;
- /**
- * TODO: rename this to something having to do with tile grids
- * see https://github.com/openlayers/openlayers/issues/2076
- * @define {number} Default maximum zoom for default tile grids.
- */
- ol.DEFAULT_MAX_ZOOM = 42;
- /**
- * @define {number} Default min zoom level for the map view. Default is `0`.
- */
- ol.DEFAULT_MIN_ZOOM = 0;
- /**
- * @define {number} Default maximum allowed threshold (in pixels) for
- * reprojection triangulation. Default is `0.5`.
- */
- ol.DEFAULT_RASTER_REPROJECTION_ERROR_THRESHOLD = 0.5;
- /**
- * @define {number} Default tile size.
- */
- ol.DEFAULT_TILE_SIZE = 256;
- /**
- * @define {string} Default WMS version.
- */
- ol.DEFAULT_WMS_VERSION = '1.3.0';
- /**
- * @define {boolean} Enable the Canvas renderer. Default is `true`. Setting
- * this to false at compile time in advanced mode removes all code
- * supporting the Canvas renderer from the build.
- */
- ol.ENABLE_CANVAS = true;
- /**
- * @define {boolean} Enable integration with the Proj4js library. Default is
- * `true`.
- */
- ol.ENABLE_PROJ4JS = true;
- /**
- * @define {boolean} Enable automatic reprojection of raster sources. Default is
- * `true`.
- */
- ol.ENABLE_RASTER_REPROJECTION = true;
- /**
- * @define {boolean} Enable the WebGL renderer. Default is `true`. Setting
- * this to false at compile time in advanced mode removes all code
- * supporting the WebGL renderer from the build.
- */
- ol.ENABLE_WEBGL = true;
- /**
- * @define {boolean} Include debuggable shader sources. Default is `true`.
- * This should be set to `false` for production builds (if `ol.ENABLE_WEBGL`
- * is `true`).
- */
- ol.DEBUG_WEBGL = true;
- /**
- * @define {number} The size in pixels of the first atlas image. Default is
- * `256`.
- */
- ol.INITIAL_ATLAS_SIZE = 256;
- /**
- * @define {number} The maximum size in pixels of atlas images. Default is
- * `-1`, meaning it is not used (and `ol.WEBGL_MAX_TEXTURE_SIZE` is
- * used instead).
- */
- ol.MAX_ATLAS_SIZE = -1;
- /**
- * @define {number} Maximum mouse wheel delta.
- */
- ol.MOUSEWHEELZOOM_MAXDELTA = 1;
- /**
- * @define {number} Maximum width and/or height extent ratio that determines
- * when the overview map should be zoomed out.
- */
- ol.OVERVIEWMAP_MAX_RATIO = 0.75;
- /**
- * @define {number} Minimum width and/or height extent ratio that determines
- * when the overview map should be zoomed in.
- */
- ol.OVERVIEWMAP_MIN_RATIO = 0.1;
- /**
- * @define {number} Maximum number of source tiles for raster reprojection of
- * a single tile.
- * If too many source tiles are determined to be loaded to create a single
- * reprojected tile the browser can become unresponsive or even crash.
- * This can happen if the developer defines projections improperly and/or
- * with unlimited extents.
- * If too many tiles are required, no tiles are loaded and
- * `ol.TileState.ERROR` state is set. Default is `100`.
- */
- ol.RASTER_REPROJECTION_MAX_SOURCE_TILES = 100;
- /**
- * @define {number} Maximum number of subdivision steps during raster
- * reprojection triangulation. Prevents high memory usage and large
- * number of proj4 calls (for certain transformations and areas).
- * At most `2*(2^this)` triangles are created for each triangulated
- * extent (tile/image). Default is `10`.
- */
- ol.RASTER_REPROJECTION_MAX_SUBDIVISION = 10;
- /**
- * @define {number} Maximum allowed size of triangle relative to world width.
- * When transforming corners of world extent between certain projections,
- * the resulting triangulation seems to have zero error and no subdivision
- * is performed.
- * If the triangle width is more than this (relative to world width; 0-1),
- * subdivison is forced (up to `ol.RASTER_REPROJECTION_MAX_SUBDIVISION`).
- * Default is `0.25`.
- */
- ol.RASTER_REPROJECTION_MAX_TRIANGLE_WIDTH = 0.25;
- /**
- * @define {number} Tolerance for geometry simplification in device pixels.
- */
- ol.SIMPLIFY_TOLERANCE = 0.5;
- /**
- * @define {number} Texture cache high water mark.
- */
- ol.WEBGL_TEXTURE_CACHE_HIGH_WATER_MARK = 1024;
- /**
- * @define {string} OpenLayers version.
- */
- ol.VERSION = '';
- /**
- * The maximum supported WebGL texture size in pixels. If WebGL is not
- * supported, the value is set to `undefined`.
- * @const
- * @type {number|undefined}
- */
- ol.WEBGL_MAX_TEXTURE_SIZE; // value is set in `ol.has`
- /**
- * List of supported WebGL extensions.
- * @const
- * @type {Array.<string>}
- */
- ol.WEBGL_EXTENSIONS; // value is set in `ol.has`
- /**
- * Inherit the prototype methods from one constructor into another.
- *
- * Usage:
- *
- * function ParentClass(a, b) { }
- * ParentClass.prototype.foo = function(a) { }
- *
- * function ChildClass(a, b, c) {
- * // Call parent constructor
- * ParentClass.call(this, a, b);
- * }
- * ol.inherits(ChildClass, ParentClass);
- *
- * var child = new ChildClass('a', 'b', 'see');
- * child.foo(); // This works.
- *
- * @param {!Function} childCtor Child constructor.
- * @param {!Function} parentCtor Parent constructor.
- * @function
- * @api
- */
- ol.inherits = function(childCtor, parentCtor) {
- childCtor.prototype = Object.create(parentCtor.prototype);
- childCtor.prototype.constructor = childCtor;
- };
- /**
- * A reusable function, used e.g. as a default for callbacks.
- *
- * @return {undefined} Nothing.
- */
- ol.nullFunction = function() {};
- /**
- * Gets a unique ID for an object. This mutates the object so that further calls
- * with the same object as a parameter returns the same value. Unique IDs are generated
- * as a strictly increasing sequence. Adapted from goog.getUid.
- *
- * @param {Object} obj The object to get the unique ID for.
- * @return {number} The unique ID for the object.
- */
- ol.getUid = function(obj) {
- return obj.ol_uid ||
- (obj.ol_uid = ++ol.uidCounter_);
- };
- /**
- * Counter for getUid.
- * @type {number}
- * @private
- */
- ol.uidCounter_ = 0;
- goog.provide('ol.AssertionError');
- goog.require('ol');
- /**
- * Error object thrown when an assertion failed. This is an ECMA-262 Error,
- * extended with a `code` property.
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error}
- * @constructor
- * @extends {Error}
- * @implements {oli.AssertionError}
- * @param {number} code Error code.
- */
- ol.AssertionError = function(code) {
- var path = ol.VERSION ? ol.VERSION.split('-')[0] : 'latest';
- /**
- * @type {string}
- */
- this.message = 'Assertion failed. See https://openlayers.org/en/' + path +
- '/doc/errors/#' + code + ' for details.';
- /**
- * Error code. The meaning of the code can be found on
- * {@link https://openlayers.org/en/latest/doc/errors/} (replace `latest` with
- * the version found in the OpenLayers script's header comment if a version
- * other than the latest is used).
- * @type {number}
- * @api
- */
- this.code = code;
- this.name = 'AssertionError';
- };
- ol.inherits(ol.AssertionError, Error);
- goog.provide('ol.asserts');
- goog.require('ol.AssertionError');
- /**
- * @param {*} assertion Assertion we expected to be truthy.
- * @param {number} errorCode Error code.
- */
- ol.asserts.assert = function(assertion, errorCode) {
- if (!assertion) {
- throw new ol.AssertionError(errorCode);
- }
- };
- goog.provide('ol.TileRange');
- /**
- * A representation of a contiguous block of tiles. A tile range is specified
- * by its min/max tile coordinates and is inclusive of coordinates.
- *
- * @constructor
- * @param {number} minX Minimum X.
- * @param {number} maxX Maximum X.
- * @param {number} minY Minimum Y.
- * @param {number} maxY Maximum Y.
- * @struct
- */
- ol.TileRange = function(minX, maxX, minY, maxY) {
- /**
- * @type {number}
- */
- this.minX = minX;
- /**
- * @type {number}
- */
- this.maxX = maxX;
- /**
- * @type {number}
- */
- this.minY = minY;
- /**
- * @type {number}
- */
- this.maxY = maxY;
- };
- /**
- * @param {number} minX Minimum X.
- * @param {number} maxX Maximum X.
- * @param {number} minY Minimum Y.
- * @param {number} maxY Maximum Y.
- * @param {ol.TileRange|undefined} tileRange TileRange.
- * @return {ol.TileRange} Tile range.
- */
- ol.TileRange.createOrUpdate = function(minX, maxX, minY, maxY, tileRange) {
- if (tileRange !== undefined) {
- tileRange.minX = minX;
- tileRange.maxX = maxX;
- tileRange.minY = minY;
- tileRange.maxY = maxY;
- return tileRange;
- } else {
- return new ol.TileRange(minX, maxX, minY, maxY);
- }
- };
- /**
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @return {boolean} Contains tile coordinate.
- */
- ol.TileRange.prototype.contains = function(tileCoord) {
- return this.containsXY(tileCoord[1], tileCoord[2]);
- };
- /**
- * @param {ol.TileRange} tileRange Tile range.
- * @return {boolean} Contains.
- */
- ol.TileRange.prototype.containsTileRange = function(tileRange) {
- return this.minX <= tileRange.minX && tileRange.maxX <= this.maxX &&
- this.minY <= tileRange.minY && tileRange.maxY <= this.maxY;
- };
- /**
- * @param {number} x Tile coordinate x.
- * @param {number} y Tile coordinate y.
- * @return {boolean} Contains coordinate.
- */
- ol.TileRange.prototype.containsXY = function(x, y) {
- return this.minX <= x && x <= this.maxX && this.minY <= y && y <= this.maxY;
- };
- /**
- * @param {ol.TileRange} tileRange Tile range.
- * @return {boolean} Equals.
- */
- ol.TileRange.prototype.equals = function(tileRange) {
- return this.minX == tileRange.minX && this.minY == tileRange.minY &&
- this.maxX == tileRange.maxX && this.maxY == tileRange.maxY;
- };
- /**
- * @param {ol.TileRange} tileRange Tile range.
- */
- ol.TileRange.prototype.extend = function(tileRange) {
- if (tileRange.minX < this.minX) {
- this.minX = tileRange.minX;
- }
- if (tileRange.maxX > this.maxX) {
- this.maxX = tileRange.maxX;
- }
- if (tileRange.minY < this.minY) {
- this.minY = tileRange.minY;
- }
- if (tileRange.maxY > this.maxY) {
- this.maxY = tileRange.maxY;
- }
- };
- /**
- * @return {number} Height.
- */
- ol.TileRange.prototype.getHeight = function() {
- return this.maxY - this.minY + 1;
- };
- /**
- * @return {ol.Size} Size.
- */
- ol.TileRange.prototype.getSize = function() {
- return [this.getWidth(), this.getHeight()];
- };
- /**
- * @return {number} Width.
- */
- ol.TileRange.prototype.getWidth = function() {
- return this.maxX - this.minX + 1;
- };
- /**
- * @param {ol.TileRange} tileRange Tile range.
- * @return {boolean} Intersects.
- */
- ol.TileRange.prototype.intersects = function(tileRange) {
- return this.minX <= tileRange.maxX &&
- this.maxX >= tileRange.minX &&
- this.minY <= tileRange.maxY &&
- this.maxY >= tileRange.minY;
- };
- goog.provide('ol.math');
- goog.require('ol.asserts');
- /**
- * Takes a number and clamps it to within the provided bounds.
- * @param {number} value The input number.
- * @param {number} min The minimum value to return.
- * @param {number} max The maximum value to return.
- * @return {number} The input number if it is within bounds, or the nearest
- * number within the bounds.
- */
- ol.math.clamp = function(value, min, max) {
- return Math.min(Math.max(value, min), max);
- };
- /**
- * Return the hyperbolic cosine of a given number. The method will use the
- * native `Math.cosh` function if it is available, otherwise the hyperbolic
- * cosine will be calculated via the reference implementation of the Mozilla
- * developer network.
- *
- * @param {number} x X.
- * @return {number} Hyperbolic cosine of x.
- */
- ol.math.cosh = (function() {
- // Wrapped in a iife, to save the overhead of checking for the native
- // implementation on every invocation.
- var cosh;
- if ('cosh' in Math) {
- // The environment supports the native Math.cosh function, use it…
- cosh = Math.cosh;
- } else {
- // … else, use the reference implementation of MDN:
- cosh = function(x) {
- var y = Math.exp(x);
- return (y + 1 / y) / 2;
- };
- }
- return cosh;
- }());
- /**
- * @param {number} x X.
- * @return {number} The smallest power of two greater than or equal to x.
- */
- ol.math.roundUpToPowerOfTwo = function(x) {
- ol.asserts.assert(0 < x, 29); // `x` must be greater than `0`
- return Math.pow(2, Math.ceil(Math.log(x) / Math.LN2));
- };
- /**
- * Returns the square of the closest distance between the point (x, y) and the
- * line segment (x1, y1) to (x2, y2).
- * @param {number} x X.
- * @param {number} y Y.
- * @param {number} x1 X1.
- * @param {number} y1 Y1.
- * @param {number} x2 X2.
- * @param {number} y2 Y2.
- * @return {number} Squared distance.
- */
- ol.math.squaredSegmentDistance = function(x, y, x1, y1, x2, y2) {
- var dx = x2 - x1;
- var dy = y2 - y1;
- if (dx !== 0 || dy !== 0) {
- var t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);
- if (t > 1) {
- x1 = x2;
- y1 = y2;
- } else if (t > 0) {
- x1 += dx * t;
- y1 += dy * t;
- }
- }
- return ol.math.squaredDistance(x, y, x1, y1);
- };
- /**
- * Returns the square of the distance between the points (x1, y1) and (x2, y2).
- * @param {number} x1 X1.
- * @param {number} y1 Y1.
- * @param {number} x2 X2.
- * @param {number} y2 Y2.
- * @return {number} Squared distance.
- */
- ol.math.squaredDistance = function(x1, y1, x2, y2) {
- var dx = x2 - x1;
- var dy = y2 - y1;
- return dx * dx + dy * dy;
- };
- /**
- * Solves system of linear equations using Gaussian elimination method.
- *
- * @param {Array.<Array.<number>>} mat Augmented matrix (n x n + 1 column)
- * in row-major order.
- * @return {Array.<number>} The resulting vector.
- */
- ol.math.solveLinearSystem = function(mat) {
- var n = mat.length;
- for (var i = 0; i < n; i++) {
- // Find max in the i-th column (ignoring i - 1 first rows)
- var maxRow = i;
- var maxEl = Math.abs(mat[i][i]);
- for (var r = i + 1; r < n; r++) {
- var absValue = Math.abs(mat[r][i]);
- if (absValue > maxEl) {
- maxEl = absValue;
- maxRow = r;
- }
- }
- if (maxEl === 0) {
- return null; // matrix is singular
- }
- // Swap max row with i-th (current) row
- var tmp = mat[maxRow];
- mat[maxRow] = mat[i];
- mat[i] = tmp;
- // Subtract the i-th row to make all the remaining rows 0 in the i-th column
- for (var j = i + 1; j < n; j++) {
- var coef = -mat[j][i] / mat[i][i];
- for (var k = i; k < n + 1; k++) {
- if (i == k) {
- mat[j][k] = 0;
- } else {
- mat[j][k] += coef * mat[i][k];
- }
- }
- }
- }
- // Solve Ax=b for upper triangular matrix A (mat)
- var x = new Array(n);
- for (var l = n - 1; l >= 0; l--) {
- x[l] = mat[l][n] / mat[l][l];
- for (var m = l - 1; m >= 0; m--) {
- mat[m][n] -= mat[m][l] * x[l];
- }
- }
- return x;
- };
- /**
- * Converts radians to to degrees.
- *
- * @param {number} angleInRadians Angle in radians.
- * @return {number} Angle in degrees.
- */
- ol.math.toDegrees = function(angleInRadians) {
- return angleInRadians * 180 / Math.PI;
- };
- /**
- * Converts degrees to radians.
- *
- * @param {number} angleInDegrees Angle in degrees.
- * @return {number} Angle in radians.
- */
- ol.math.toRadians = function(angleInDegrees) {
- return angleInDegrees * Math.PI / 180;
- };
- /**
- * Returns the modulo of a / b, depending on the sign of b.
- *
- * @param {number} a Dividend.
- * @param {number} b Divisor.
- * @return {number} Modulo.
- */
- ol.math.modulo = function(a, b) {
- var r = a % b;
- return r * b < 0 ? r + b : r;
- };
- /**
- * Calculates the linearly interpolated value of x between a and b.
- *
- * @param {number} a Number
- * @param {number} b Number
- * @param {number} x Value to be interpolated.
- * @return {number} Interpolated value.
- */
- ol.math.lerp = function(a, b, x) {
- return a + x * (b - a);
- };
- goog.provide('ol.size');
- /**
- * Returns a buffered size.
- * @param {ol.Size} size Size.
- * @param {number} buffer Buffer.
- * @param {ol.Size=} opt_size Optional reusable size array.
- * @return {ol.Size} The buffered size.
- */
- ol.size.buffer = function(size, buffer, opt_size) {
- if (opt_size === undefined) {
- opt_size = [0, 0];
- }
- opt_size[0] = size[0] + 2 * buffer;
- opt_size[1] = size[1] + 2 * buffer;
- return opt_size;
- };
- /**
- * Determines if a size has a positive area.
- * @param {ol.Size} size The size to test.
- * @return {boolean} The size has a positive area.
- */
- ol.size.hasArea = function(size) {
- return size[0] > 0 && size[1] > 0;
- };
- /**
- * Returns a size scaled by a ratio. The result will be an array of integers.
- * @param {ol.Size} size Size.
- * @param {number} ratio Ratio.
- * @param {ol.Size=} opt_size Optional reusable size array.
- * @return {ol.Size} The scaled size.
- */
- ol.size.scale = function(size, ratio, opt_size) {
- if (opt_size === undefined) {
- opt_size = [0, 0];
- }
- opt_size[0] = (size[0] * ratio + 0.5) | 0;
- opt_size[1] = (size[1] * ratio + 0.5) | 0;
- return opt_size;
- };
- /**
- * Returns an `ol.Size` array for the passed in number (meaning: square) or
- * `ol.Size` array.
- * (meaning: non-square),
- * @param {number|ol.Size} size Width and height.
- * @param {ol.Size=} opt_size Optional reusable size array.
- * @return {ol.Size} Size.
- * @api
- */
- ol.size.toSize = function(size, opt_size) {
- if (Array.isArray(size)) {
- return size;
- } else {
- if (opt_size === undefined) {
- opt_size = [size, size];
- } else {
- opt_size[0] = opt_size[1] = /** @type {number} */ (size);
- }
- return opt_size;
- }
- };
- goog.provide('ol.extent.Corner');
- /**
- * Extent corner.
- * @enum {string}
- */
- ol.extent.Corner = {
- BOTTOM_LEFT: 'bottom-left',
- BOTTOM_RIGHT: 'bottom-right',
- TOP_LEFT: 'top-left',
- TOP_RIGHT: 'top-right'
- };
- goog.provide('ol.extent.Relationship');
- /**
- * Relationship to an extent.
- * @enum {number}
- */
- ol.extent.Relationship = {
- UNKNOWN: 0,
- INTERSECTING: 1,
- ABOVE: 2,
- RIGHT: 4,
- BELOW: 8,
- LEFT: 16
- };
- goog.provide('ol.extent');
- goog.require('ol.asserts');
- goog.require('ol.extent.Corner');
- goog.require('ol.extent.Relationship');
- /**
- * Build an extent that includes all given coordinates.
- *
- * @param {Array.<ol.Coordinate>} coordinates Coordinates.
- * @return {ol.Extent} Bounding extent.
- * @api
- */
- ol.extent.boundingExtent = function(coordinates) {
- var extent = ol.extent.createEmpty();
- for (var i = 0, ii = coordinates.length; i < ii; ++i) {
- ol.extent.extendCoordinate(extent, coordinates[i]);
- }
- return extent;
- };
- /**
- * @param {Array.<number>} xs Xs.
- * @param {Array.<number>} ys Ys.
- * @param {ol.Extent=} opt_extent Destination extent.
- * @private
- * @return {ol.Extent} Extent.
- */
- ol.extent.boundingExtentXYs_ = function(xs, ys, opt_extent) {
- var minX = Math.min.apply(null, xs);
- var minY = Math.min.apply(null, ys);
- var maxX = Math.max.apply(null, xs);
- var maxY = Math.max.apply(null, ys);
- return ol.extent.createOrUpdate(minX, minY, maxX, maxY, opt_extent);
- };
- /**
- * Return extent increased by the provided value.
- * @param {ol.Extent} extent Extent.
- * @param {number} value The amount by which the extent should be buffered.
- * @param {ol.Extent=} opt_extent Extent.
- * @return {ol.Extent} Extent.
- * @api
- */
- ol.extent.buffer = function(extent, value, opt_extent) {
- if (opt_extent) {
- opt_extent[0] = extent[0] - value;
- opt_extent[1] = extent[1] - value;
- opt_extent[2] = extent[2] + value;
- opt_extent[3] = extent[3] + value;
- return opt_extent;
- } else {
- return [
- extent[0] - value,
- extent[1] - value,
- extent[2] + value,
- extent[3] + value
- ];
- }
- };
- /**
- * Creates a clone of an extent.
- *
- * @param {ol.Extent} extent Extent to clone.
- * @param {ol.Extent=} opt_extent Extent.
- * @return {ol.Extent} The clone.
- */
- ol.extent.clone = function(extent, opt_extent) {
- if (opt_extent) {
- opt_extent[0] = extent[0];
- opt_extent[1] = extent[1];
- opt_extent[2] = extent[2];
- opt_extent[3] = extent[3];
- return opt_extent;
- } else {
- return extent.slice();
- }
- };
- /**
- * @param {ol.Extent} extent Extent.
- * @param {number} x X.
- * @param {number} y Y.
- * @return {number} Closest squared distance.
- */
- ol.extent.closestSquaredDistanceXY = function(extent, x, y) {
- var dx, dy;
- if (x < extent[0]) {
- dx = extent[0] - x;
- } else if (extent[2] < x) {
- dx = x - extent[2];
- } else {
- dx = 0;
- }
- if (y < extent[1]) {
- dy = extent[1] - y;
- } else if (extent[3] < y) {
- dy = y - extent[3];
- } else {
- dy = 0;
- }
- return dx * dx + dy * dy;
- };
- /**
- * Check if the passed coordinate is contained or on the edge of the extent.
- *
- * @param {ol.Extent} extent Extent.
- * @param {ol.Coordinate} coordinate Coordinate.
- * @return {boolean} The coordinate is contained in the extent.
- * @api
- */
- ol.extent.containsCoordinate = function(extent, coordinate) {
- return ol.extent.containsXY(extent, coordinate[0], coordinate[1]);
- };
- /**
- * Check if one extent contains another.
- *
- * An extent is deemed contained if it lies completely within the other extent,
- * including if they share one or more edges.
- *
- * @param {ol.Extent} extent1 Extent 1.
- * @param {ol.Extent} extent2 Extent 2.
- * @return {boolean} The second extent is contained by or on the edge of the
- * first.
- * @api
- */
- ol.extent.containsExtent = function(extent1, extent2) {
- return extent1[0] <= extent2[0] && extent2[2] <= extent1[2] &&
- extent1[1] <= extent2[1] && extent2[3] <= extent1[3];
- };
- /**
- * Check if the passed coordinate is contained or on the edge of the extent.
- *
- * @param {ol.Extent} extent Extent.
- * @param {number} x X coordinate.
- * @param {number} y Y coordinate.
- * @return {boolean} The x, y values are contained in the extent.
- * @api
- */
- ol.extent.containsXY = function(extent, x, y) {
- return extent[0] <= x && x <= extent[2] && extent[1] <= y && y <= extent[3];
- };
- /**
- * Get the relationship between a coordinate and extent.
- * @param {ol.Extent} extent The extent.
- * @param {ol.Coordinate} coordinate The coordinate.
- * @return {number} The relationship (bitwise compare with
- * ol.extent.Relationship).
- */
- ol.extent.coordinateRelationship = function(extent, coordinate) {
- var minX = extent[0];
- var minY = extent[1];
- var maxX = extent[2];
- var maxY = extent[3];
- var x = coordinate[0];
- var y = coordinate[1];
- var relationship = ol.extent.Relationship.UNKNOWN;
- if (x < minX) {
- relationship = relationship | ol.extent.Relationship.LEFT;
- } else if (x > maxX) {
- relationship = relationship | ol.extent.Relationship.RIGHT;
- }
- if (y < minY) {
- relationship = relationship | ol.extent.Relationship.BELOW;
- } else if (y > maxY) {
- relationship = relationship | ol.extent.Relationship.ABOVE;
- }
- if (relationship === ol.extent.Relationship.UNKNOWN) {
- relationship = ol.extent.Relationship.INTERSECTING;
- }
- return relationship;
- };
- /**
- * Create an empty extent.
- * @return {ol.Extent} Empty extent.
- * @api
- */
- ol.extent.createEmpty = function() {
- return [Infinity, Infinity, -Infinity, -Infinity];
- };
- /**
- * Create a new extent or update the provided extent.
- * @param {number} minX Minimum X.
- * @param {number} minY Minimum Y.
- * @param {number} maxX Maximum X.
- * @param {number} maxY Maximum Y.
- * @param {ol.Extent=} opt_extent Destination extent.
- * @return {ol.Extent} Extent.
- */
- ol.extent.createOrUpdate = function(minX, minY, maxX, maxY, opt_extent) {
- if (opt_extent) {
- opt_extent[0] = minX;
- opt_extent[1] = minY;
- opt_extent[2] = maxX;
- opt_extent[3] = maxY;
- return opt_extent;
- } else {
- return [minX, minY, maxX, maxY];
- }
- };
- /**
- * Create a new empty extent or make the provided one empty.
- * @param {ol.Extent=} opt_extent Extent.
- * @return {ol.Extent} Extent.
- */
- ol.extent.createOrUpdateEmpty = function(opt_extent) {
- return ol.extent.createOrUpdate(
- Infinity, Infinity, -Infinity, -Infinity, opt_extent);
- };
- /**
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {ol.Extent=} opt_extent Extent.
- * @return {ol.Extent} Extent.
- */
- ol.extent.createOrUpdateFromCoordinate = function(coordinate, opt_extent) {
- var x = coordinate[0];
- var y = coordinate[1];
- return ol.extent.createOrUpdate(x, y, x, y, opt_extent);
- };
- /**
- * @param {Array.<ol.Coordinate>} coordinates Coordinates.
- * @param {ol.Extent=} opt_extent Extent.
- * @return {ol.Extent} Extent.
- */
- ol.extent.createOrUpdateFromCoordinates = function(coordinates, opt_extent) {
- var extent = ol.extent.createOrUpdateEmpty(opt_extent);
- return ol.extent.extendCoordinates(extent, coordinates);
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {ol.Extent=} opt_extent Extent.
- * @return {ol.Extent} Extent.
- */
- ol.extent.createOrUpdateFromFlatCoordinates = function(flatCoordinates, offset, end, stride, opt_extent) {
- var extent = ol.extent.createOrUpdateEmpty(opt_extent);
- return ol.extent.extendFlatCoordinates(
- extent, flatCoordinates, offset, end, stride);
- };
- /**
- * @param {Array.<Array.<ol.Coordinate>>} rings Rings.
- * @param {ol.Extent=} opt_extent Extent.
- * @return {ol.Extent} Extent.
- */
- ol.extent.createOrUpdateFromRings = function(rings, opt_extent) {
- var extent = ol.extent.createOrUpdateEmpty(opt_extent);
- return ol.extent.extendRings(extent, rings);
- };
- /**
- * Determine if two extents are equivalent.
- * @param {ol.Extent} extent1 Extent 1.
- * @param {ol.Extent} extent2 Extent 2.
- * @return {boolean} The two extents are equivalent.
- * @api
- */
- ol.extent.equals = function(extent1, extent2) {
- return extent1[0] == extent2[0] && extent1[2] == extent2[2] &&
- extent1[1] == extent2[1] && extent1[3] == extent2[3];
- };
- /**
- * Modify an extent to include another extent.
- * @param {ol.Extent} extent1 The extent to be modified.
- * @param {ol.Extent} extent2 The extent that will be included in the first.
- * @return {ol.Extent} A reference to the first (extended) extent.
- * @api
- */
- ol.extent.extend = function(extent1, extent2) {
- if (extent2[0] < extent1[0]) {
- extent1[0] = extent2[0];
- }
- if (extent2[2] > extent1[2]) {
- extent1[2] = extent2[2];
- }
- if (extent2[1] < extent1[1]) {
- extent1[1] = extent2[1];
- }
- if (extent2[3] > extent1[3]) {
- extent1[3] = extent2[3];
- }
- return extent1;
- };
- /**
- * @param {ol.Extent} extent Extent.
- * @param {ol.Coordinate} coordinate Coordinate.
- */
- ol.extent.extendCoordinate = function(extent, coordinate) {
- if (coordinate[0] < extent[0]) {
- extent[0] = coordinate[0];
- }
- if (coordinate[0] > extent[2]) {
- extent[2] = coordinate[0];
- }
- if (coordinate[1] < extent[1]) {
- extent[1] = coordinate[1];
- }
- if (coordinate[1] > extent[3]) {
- extent[3] = coordinate[1];
- }
- };
- /**
- * @param {ol.Extent} extent Extent.
- * @param {Array.<ol.Coordinate>} coordinates Coordinates.
- * @return {ol.Extent} Extent.
- */
- ol.extent.extendCoordinates = function(extent, coordinates) {
- var i, ii;
- for (i = 0, ii = coordinates.length; i < ii; ++i) {
- ol.extent.extendCoordinate(extent, coordinates[i]);
- }
- return extent;
- };
- /**
- * @param {ol.Extent} extent Extent.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @return {ol.Extent} Extent.
- */
- ol.extent.extendFlatCoordinates = function(extent, flatCoordinates, offset, end, stride) {
- for (; offset < end; offset += stride) {
- ol.extent.extendXY(
- extent, flatCoordinates[offset], flatCoordinates[offset + 1]);
- }
- return extent;
- };
- /**
- * @param {ol.Extent} extent Extent.
- * @param {Array.<Array.<ol.Coordinate>>} rings Rings.
- * @return {ol.Extent} Extent.
- */
- ol.extent.extendRings = function(extent, rings) {
- var i, ii;
- for (i = 0, ii = rings.length; i < ii; ++i) {
- ol.extent.extendCoordinates(extent, rings[i]);
- }
- return extent;
- };
- /**
- * @param {ol.Extent} extent Extent.
- * @param {number} x X.
- * @param {number} y Y.
- */
- ol.extent.extendXY = function(extent, x, y) {
- extent[0] = Math.min(extent[0], x);
- extent[1] = Math.min(extent[1], y);
- extent[2] = Math.max(extent[2], x);
- extent[3] = Math.max(extent[3], y);
- };
- /**
- * This function calls `callback` for each corner of the extent. If the
- * callback returns a truthy value the function returns that value
- * immediately. Otherwise the function returns `false`.
- * @param {ol.Extent} extent Extent.
- * @param {function(this:T, ol.Coordinate): S} callback Callback.
- * @param {T=} opt_this Value to use as `this` when executing `callback`.
- * @return {S|boolean} Value.
- * @template S, T
- */
- ol.extent.forEachCorner = function(extent, callback, opt_this) {
- var val;
- val = callback.call(opt_this, ol.extent.getBottomLeft(extent));
- if (val) {
- return val;
- }
- val = callback.call(opt_this, ol.extent.getBottomRight(extent));
- if (val) {
- return val;
- }
- val = callback.call(opt_this, ol.extent.getTopRight(extent));
- if (val) {
- return val;
- }
- val = callback.call(opt_this, ol.extent.getTopLeft(extent));
- if (val) {
- return val;
- }
- return false;
- };
- /**
- * Get the size of an extent.
- * @param {ol.Extent} extent Extent.
- * @return {number} Area.
- * @api
- */
- ol.extent.getArea = function(extent) {
- var area = 0;
- if (!ol.extent.isEmpty(extent)) {
- area = ol.extent.getWidth(extent) * ol.extent.getHeight(extent);
- }
- return area;
- };
- /**
- * Get the bottom left coordinate of an extent.
- * @param {ol.Extent} extent Extent.
- * @return {ol.Coordinate} Bottom left coordinate.
- * @api
- */
- ol.extent.getBottomLeft = function(extent) {
- return [extent[0], extent[1]];
- };
- /**
- * Get the bottom right coordinate of an extent.
- * @param {ol.Extent} extent Extent.
- * @return {ol.Coordinate} Bottom right coordinate.
- * @api
- */
- ol.extent.getBottomRight = function(extent) {
- return [extent[2], extent[1]];
- };
- /**
- * Get the center coordinate of an extent.
- * @param {ol.Extent} extent Extent.
- * @return {ol.Coordinate} Center.
- * @api
- */
- ol.extent.getCenter = function(extent) {
- return [(extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2];
- };
- /**
- * Get a corner coordinate of an extent.
- * @param {ol.Extent} extent Extent.
- * @param {ol.extent.Corner} corner Corner.
- * @return {ol.Coordinate} Corner coordinate.
- */
- ol.extent.getCorner = function(extent, corner) {
- var coordinate;
- if (corner === ol.extent.Corner.BOTTOM_LEFT) {
- coordinate = ol.extent.getBottomLeft(extent);
- } else if (corner === ol.extent.Corner.BOTTOM_RIGHT) {
- coordinate = ol.extent.getBottomRight(extent);
- } else if (corner === ol.extent.Corner.TOP_LEFT) {
- coordinate = ol.extent.getTopLeft(extent);
- } else if (corner === ol.extent.Corner.TOP_RIGHT) {
- coordinate = ol.extent.getTopRight(extent);
- } else {
- ol.asserts.assert(false, 13); // Invalid corner
- }
- return /** @type {!ol.Coordinate} */ (coordinate);
- };
- /**
- * @param {ol.Extent} extent1 Extent 1.
- * @param {ol.Extent} extent2 Extent 2.
- * @return {number} Enlarged area.
- */
- ol.extent.getEnlargedArea = function(extent1, extent2) {
- var minX = Math.min(extent1[0], extent2[0]);
- var minY = Math.min(extent1[1], extent2[1]);
- var maxX = Math.max(extent1[2], extent2[2]);
- var maxY = Math.max(extent1[3], extent2[3]);
- return (maxX - minX) * (maxY - minY);
- };
- /**
- * @param {ol.Coordinate} center Center.
- * @param {number} resolution Resolution.
- * @param {number} rotation Rotation.
- * @param {ol.Size} size Size.
- * @param {ol.Extent=} opt_extent Destination extent.
- * @return {ol.Extent} Extent.
- */
- ol.extent.getForViewAndSize = function(center, resolution, rotation, size, opt_extent) {
- var dx = resolution * size[0] / 2;
- var dy = resolution * size[1] / 2;
- var cosRotation = Math.cos(rotation);
- var sinRotation = Math.sin(rotation);
- var xCos = dx * cosRotation;
- var xSin = dx * sinRotation;
- var yCos = dy * cosRotation;
- var ySin = dy * sinRotation;
- var x = center[0];
- var y = center[1];
- var x0 = x - xCos + ySin;
- var x1 = x - xCos - ySin;
- var x2 = x + xCos - ySin;
- var x3 = x + xCos + ySin;
- var y0 = y - xSin - yCos;
- var y1 = y - xSin + yCos;
- var y2 = y + xSin + yCos;
- var y3 = y + xSin - yCos;
- return ol.extent.createOrUpdate(
- Math.min(x0, x1, x2, x3), Math.min(y0, y1, y2, y3),
- Math.max(x0, x1, x2, x3), Math.max(y0, y1, y2, y3),
- opt_extent);
- };
- /**
- * Get the height of an extent.
- * @param {ol.Extent} extent Extent.
- * @return {number} Height.
- * @api
- */
- ol.extent.getHeight = function(extent) {
- return extent[3] - extent[1];
- };
- /**
- * @param {ol.Extent} extent1 Extent 1.
- * @param {ol.Extent} extent2 Extent 2.
- * @return {number} Intersection area.
- */
- ol.extent.getIntersectionArea = function(extent1, extent2) {
- var intersection = ol.extent.getIntersection(extent1, extent2);
- return ol.extent.getArea(intersection);
- };
- /**
- * Get the intersection of two extents.
- * @param {ol.Extent} extent1 Extent 1.
- * @param {ol.Extent} extent2 Extent 2.
- * @param {ol.Extent=} opt_extent Optional extent to populate with intersection.
- * @return {ol.Extent} Intersecting extent.
- * @api
- */
- ol.extent.getIntersection = function(extent1, extent2, opt_extent) {
- var intersection = opt_extent ? opt_extent : ol.extent.createEmpty();
- if (ol.extent.intersects(extent1, extent2)) {
- if (extent1[0] > extent2[0]) {
- intersection[0] = extent1[0];
- } else {
- intersection[0] = extent2[0];
- }
- if (extent1[1] > extent2[1]) {
- intersection[1] = extent1[1];
- } else {
- intersection[1] = extent2[1];
- }
- if (extent1[2] < extent2[2]) {
- intersection[2] = extent1[2];
- } else {
- intersection[2] = extent2[2];
- }
- if (extent1[3] < extent2[3]) {
- intersection[3] = extent1[3];
- } else {
- intersection[3] = extent2[3];
- }
- }
- return intersection;
- };
- /**
- * @param {ol.Extent} extent Extent.
- * @return {number} Margin.
- */
- ol.extent.getMargin = function(extent) {
- return ol.extent.getWidth(extent) + ol.extent.getHeight(extent);
- };
- /**
- * Get the size (width, height) of an extent.
- * @param {ol.Extent} extent The extent.
- * @return {ol.Size} The extent size.
- * @api
- */
- ol.extent.getSize = function(extent) {
- return [extent[2] - extent[0], extent[3] - extent[1]];
- };
- /**
- * Get the top left coordinate of an extent.
- * @param {ol.Extent} extent Extent.
- * @return {ol.Coordinate} Top left coordinate.
- * @api
- */
- ol.extent.getTopLeft = function(extent) {
- return [extent[0], extent[3]];
- };
- /**
- * Get the top right coordinate of an extent.
- * @param {ol.Extent} extent Extent.
- * @return {ol.Coordinate} Top right coordinate.
- * @api
- */
- ol.extent.getTopRight = function(extent) {
- return [extent[2], extent[3]];
- };
- /**
- * Get the width of an extent.
- * @param {ol.Extent} extent Extent.
- * @return {number} Width.
- * @api
- */
- ol.extent.getWidth = function(extent) {
- return extent[2] - extent[0];
- };
- /**
- * Determine if one extent intersects another.
- * @param {ol.Extent} extent1 Extent 1.
- * @param {ol.Extent} extent2 Extent.
- * @return {boolean} The two extents intersect.
- * @api
- */
- ol.extent.intersects = function(extent1, extent2) {
- return extent1[0] <= extent2[2] &&
- extent1[2] >= extent2[0] &&
- extent1[1] <= extent2[3] &&
- extent1[3] >= extent2[1];
- };
- /**
- * Determine if an extent is empty.
- * @param {ol.Extent} extent Extent.
- * @return {boolean} Is empty.
- * @api
- */
- ol.extent.isEmpty = function(extent) {
- return extent[2] < extent[0] || extent[3] < extent[1];
- };
- /**
- * @param {ol.Extent} extent Extent.
- * @param {ol.Extent=} opt_extent Extent.
- * @return {ol.Extent} Extent.
- */
- ol.extent.returnOrUpdate = function(extent, opt_extent) {
- if (opt_extent) {
- opt_extent[0] = extent[0];
- opt_extent[1] = extent[1];
- opt_extent[2] = extent[2];
- opt_extent[3] = extent[3];
- return opt_extent;
- } else {
- return extent;
- }
- };
- /**
- * @param {ol.Extent} extent Extent.
- * @param {number} value Value.
- */
- ol.extent.scaleFromCenter = function(extent, value) {
- var deltaX = ((extent[2] - extent[0]) / 2) * (value - 1);
- var deltaY = ((extent[3] - extent[1]) / 2) * (value - 1);
- extent[0] -= deltaX;
- extent[2] += deltaX;
- extent[1] -= deltaY;
- extent[3] += deltaY;
- };
- /**
- * Determine if the segment between two coordinates intersects (crosses,
- * touches, or is contained by) the provided extent.
- * @param {ol.Extent} extent The extent.
- * @param {ol.Coordinate} start Segment start coordinate.
- * @param {ol.Coordinate} end Segment end coordinate.
- * @return {boolean} The segment intersects the extent.
- */
- ol.extent.intersectsSegment = function(extent, start, end) {
- var intersects = false;
- var startRel = ol.extent.coordinateRelationship(extent, start);
- var endRel = ol.extent.coordinateRelationship(extent, end);
- if (startRel === ol.extent.Relationship.INTERSECTING ||
- endRel === ol.extent.Relationship.INTERSECTING) {
- intersects = true;
- } else {
- var minX = extent[0];
- var minY = extent[1];
- var maxX = extent[2];
- var maxY = extent[3];
- var startX = start[0];
- var startY = start[1];
- var endX = end[0];
- var endY = end[1];
- var slope = (endY - startY) / (endX - startX);
- var x, y;
- if (!!(endRel & ol.extent.Relationship.ABOVE) &&
- !(startRel & ol.extent.Relationship.ABOVE)) {
- // potentially intersects top
- x = endX - ((endY - maxY) / slope);
- intersects = x >= minX && x <= maxX;
- }
- if (!intersects && !!(endRel & ol.extent.Relationship.RIGHT) &&
- !(startRel & ol.extent.Relationship.RIGHT)) {
- // potentially intersects right
- y = endY - ((endX - maxX) * slope);
- intersects = y >= minY && y <= maxY;
- }
- if (!intersects && !!(endRel & ol.extent.Relationship.BELOW) &&
- !(startRel & ol.extent.Relationship.BELOW)) {
- // potentially intersects bottom
- x = endX - ((endY - minY) / slope);
- intersects = x >= minX && x <= maxX;
- }
- if (!intersects && !!(endRel & ol.extent.Relationship.LEFT) &&
- !(startRel & ol.extent.Relationship.LEFT)) {
- // potentially intersects left
- y = endY - ((endX - minX) * slope);
- intersects = y >= minY && y <= maxY;
- }
- }
- return intersects;
- };
- /**
- * Apply a transform function to the extent.
- * @param {ol.Extent} extent Extent.
- * @param {ol.TransformFunction} transformFn Transform function. Called with
- * [minX, minY, maxX, maxY] extent coordinates.
- * @param {ol.Extent=} opt_extent Destination extent.
- * @return {ol.Extent} Extent.
- * @api
- */
- ol.extent.applyTransform = function(extent, transformFn, opt_extent) {
- var coordinates = [
- extent[0], extent[1],
- extent[0], extent[3],
- extent[2], extent[1],
- extent[2], extent[3]
- ];
- transformFn(coordinates, coordinates, 2);
- var xs = [coordinates[0], coordinates[2], coordinates[4], coordinates[6]];
- var ys = [coordinates[1], coordinates[3], coordinates[5], coordinates[7]];
- return ol.extent.boundingExtentXYs_(xs, ys, opt_extent);
- };
- goog.provide('ol.obj');
- /**
- * Polyfill for Object.assign(). Assigns enumerable and own properties from
- * one or more source objects to a target object.
- *
- * @see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
- * @param {!Object} target The target object.
- * @param {...Object} var_sources The source object(s).
- * @return {!Object} The modified target object.
- */
- ol.obj.assign = (typeof Object.assign === 'function') ? Object.assign : function(target, var_sources) {
- if (target === undefined || target === null) {
- throw new TypeError('Cannot convert undefined or null to object');
- }
- var output = Object(target);
- for (var i = 1, ii = arguments.length; i < ii; ++i) {
- var source = arguments[i];
- if (source !== undefined && source !== null) {
- for (var key in source) {
- if (source.hasOwnProperty(key)) {
- output[key] = source[key];
- }
- }
- }
- }
- return output;
- };
- /**
- * Removes all properties from an object.
- * @param {Object} object The object to clear.
- */
- ol.obj.clear = function(object) {
- for (var property in object) {
- delete object[property];
- }
- };
- /**
- * Get an array of property values from an object.
- * @param {Object<K,V>} object The object from which to get the values.
- * @return {!Array<V>} The property values.
- * @template K,V
- */
- ol.obj.getValues = function(object) {
- var values = [];
- for (var property in object) {
- values.push(object[property]);
- }
- return values;
- };
- /**
- * Determine if an object has any properties.
- * @param {Object} object The object to check.
- * @return {boolean} The object is empty.
- */
- ol.obj.isEmpty = function(object) {
- var property;
- for (property in object) {
- return false;
- }
- return !property;
- };
- goog.provide('ol.geom.GeometryType');
- /**
- * The geometry type. One of `'Point'`, `'LineString'`, `'LinearRing'`,
- * `'Polygon'`, `'MultiPoint'`, `'MultiLineString'`, `'MultiPolygon'`,
- * `'GeometryCollection'`, `'Circle'`.
- * @enum {string}
- */
- ol.geom.GeometryType = {
- POINT: 'Point',
- LINE_STRING: 'LineString',
- LINEAR_RING: 'LinearRing',
- POLYGON: 'Polygon',
- MULTI_POINT: 'MultiPoint',
- MULTI_LINE_STRING: 'MultiLineString',
- MULTI_POLYGON: 'MultiPolygon',
- GEOMETRY_COLLECTION: 'GeometryCollection',
- CIRCLE: 'Circle'
- };
- /**
- * @license
- * Latitude/longitude spherical geodesy formulae taken from
- * http://www.movable-type.co.uk/scripts/latlong.html
- * Licensed under CC-BY-3.0.
- */
- goog.provide('ol.Sphere');
- goog.require('ol.math');
- goog.require('ol.geom.GeometryType');
- /**
- * @classdesc
- * Class to create objects that can be used with {@link
- * ol.geom.Polygon.circular}.
- *
- * For example to create a sphere whose radius is equal to the semi-major
- * axis of the WGS84 ellipsoid:
- *
- * ```js
- * var wgs84Sphere= new ol.Sphere(6378137);
- * ```
- *
- * @constructor
- * @param {number} radius Radius.
- * @api
- */
- ol.Sphere = function(radius) {
- /**
- * @type {number}
- */
- this.radius = radius;
- };
- /**
- * Returns the geodesic area for a list of coordinates.
- *
- * [Reference](https://trs-new.jpl.nasa.gov/handle/2014/40409)
- * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for
- * Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
- * Laboratory, Pasadena, CA, June 2007
- *
- * @param {Array.<ol.Coordinate>} coordinates List of coordinates of a linear
- * ring. If the ring is oriented clockwise, the area will be positive,
- * otherwise it will be negative.
- * @return {number} Area.
- * @api
- */
- ol.Sphere.prototype.geodesicArea = function(coordinates) {
- return ol.Sphere.getArea_(coordinates, this.radius);
- };
- /**
- * Returns the distance from c1 to c2 using the haversine formula.
- *
- * @param {ol.Coordinate} c1 Coordinate 1.
- * @param {ol.Coordinate} c2 Coordinate 2.
- * @return {number} Haversine distance.
- * @api
- */
- ol.Sphere.prototype.haversineDistance = function(c1, c2) {
- return ol.Sphere.getDistance_(c1, c2, this.radius);
- };
- /**
- * Returns the coordinate at the given distance and bearing from `c1`.
- *
- * @param {ol.Coordinate} c1 The origin point (`[lon, lat]` in degrees).
- * @param {number} distance The great-circle distance between the origin
- * point and the target point.
- * @param {number} bearing The bearing (in radians).
- * @return {ol.Coordinate} The target point.
- */
- ol.Sphere.prototype.offset = function(c1, distance, bearing) {
- var lat1 = ol.math.toRadians(c1[1]);
- var lon1 = ol.math.toRadians(c1[0]);
- var dByR = distance / this.radius;
- var lat = Math.asin(
- Math.sin(lat1) * Math.cos(dByR) +
- Math.cos(lat1) * Math.sin(dByR) * Math.cos(bearing));
- var lon = lon1 + Math.atan2(
- Math.sin(bearing) * Math.sin(dByR) * Math.cos(lat1),
- Math.cos(dByR) - Math.sin(lat1) * Math.sin(lat));
- return [ol.math.toDegrees(lon), ol.math.toDegrees(lat)];
- };
- /**
- * The mean Earth radius (1/3 * (2a + b)) for the WGS84 ellipsoid.
- * https://en.wikipedia.org/wiki/Earth_radius#Mean_radius
- * @type {number}
- */
- ol.Sphere.DEFAULT_RADIUS = 6371008.8;
- /**
- * Get the spherical length of a geometry. This length is the sum of the
- * great circle distances between coordinates. For polygons, the length is
- * the sum of all rings. For points, the length is zero. For multi-part
- * geometries, the length is the sum of the length of each part.
- * @param {ol.geom.Geometry} geometry A geometry.
- * @param {olx.SphereMetricOptions=} opt_options Options for the length
- * calculation. By default, geometries are assumed to be in 'EPSG:3857'.
- * You can change this by providing a `projection` option.
- * @return {number} The spherical length (in meters).
- * @api
- */
- ol.Sphere.getLength = function(geometry, opt_options) {
- var options = opt_options || {};
- var radius = options.radius || ol.Sphere.DEFAULT_RADIUS;
- var projection = options.projection || 'EPSG:3857';
- geometry = geometry.clone().transform(projection, 'EPSG:4326');
- var type = geometry.getType();
- var length = 0;
- var coordinates, coords, i, ii, j, jj;
- switch (type) {
- case ol.geom.GeometryType.POINT:
- case ol.geom.GeometryType.MULTI_POINT: {
- break;
- }
- case ol.geom.GeometryType.LINE_STRING:
- case ol.geom.GeometryType.LINEAR_RING: {
- coordinates = /** @type {ol.geom.SimpleGeometry} */ (geometry).getCoordinates();
- length = ol.Sphere.getLength_(coordinates, radius);
- break;
- }
- case ol.geom.GeometryType.MULTI_LINE_STRING:
- case ol.geom.GeometryType.POLYGON: {
- coordinates = /** @type {ol.geom.SimpleGeometry} */ (geometry).getCoordinates();
- for (i = 0, ii = coordinates.length; i < ii; ++i) {
- length += ol.Sphere.getLength_(coordinates[i], radius);
- }
- break;
- }
- case ol.geom.GeometryType.MULTI_POLYGON: {
- coordinates = /** @type {ol.geom.SimpleGeometry} */ (geometry).getCoordinates();
- for (i = 0, ii = coordinates.length; i < ii; ++i) {
- coords = coordinates[i];
- for (j = 0, jj = coords.length; j < jj; ++j) {
- length += ol.Sphere.getLength_(coords[j], radius);
- }
- }
- break;
- }
- case ol.geom.GeometryType.GEOMETRY_COLLECTION: {
- var geometries = /** @type {ol.geom.GeometryCollection} */ (geometry).getGeometries();
- for (i = 0, ii = geometries.length; i < ii; ++i) {
- length += ol.Sphere.getLength(geometries[i], opt_options);
- }
- break;
- }
- default: {
- throw new Error('Unsupported geometry type: ' + type);
- }
- }
- return length;
- };
- /**
- * Get the cumulative great circle length of linestring coordinates (geographic).
- * @param {Array} coordinates Linestring coordinates.
- * @param {number} radius The sphere radius to use.
- * @return {number} The length (in meters).
- */
- ol.Sphere.getLength_ = function(coordinates, radius) {
- var length = 0;
- for (var i = 0, ii = coordinates.length; i < ii - 1; ++i) {
- length += ol.Sphere.getDistance_(coordinates[i], coordinates[i + 1], radius);
- }
- return length;
- };
- /**
- * Get the great circle distance between two geographic coordinates.
- * @param {Array} c1 Starting coordinate.
- * @param {Array} c2 Ending coordinate.
- * @param {number} radius The sphere radius to use.
- * @return {number} The great circle distance between the points (in meters).
- */
- ol.Sphere.getDistance_ = function(c1, c2, radius) {
- var lat1 = ol.math.toRadians(c1[1]);
- var lat2 = ol.math.toRadians(c2[1]);
- var deltaLatBy2 = (lat2 - lat1) / 2;
- var deltaLonBy2 = ol.math.toRadians(c2[0] - c1[0]) / 2;
- var a = Math.sin(deltaLatBy2) * Math.sin(deltaLatBy2) +
- Math.sin(deltaLonBy2) * Math.sin(deltaLonBy2) *
- Math.cos(lat1) * Math.cos(lat2);
- return 2 * radius * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
- };
- /**
- * Get the spherical area of a geometry. This is the area (in meters) assuming
- * that polygon edges are segments of great circles on a sphere.
- * @param {ol.geom.Geometry} geometry A geometry.
- * @param {olx.SphereMetricOptions=} opt_options Options for the area
- * calculation. By default, geometries are assumed to be in 'EPSG:3857'.
- * You can change this by providing a `projection` option.
- * @return {number} The spherical area (in square meters).
- * @api
- */
- ol.Sphere.getArea = function(geometry, opt_options) {
- var options = opt_options || {};
- var radius = options.radius || ol.Sphere.DEFAULT_RADIUS;
- var projection = options.projection || 'EPSG:3857';
- geometry = geometry.clone().transform(projection, 'EPSG:4326');
- var type = geometry.getType();
- var area = 0;
- var coordinates, coords, i, ii, j, jj;
- switch (type) {
- case ol.geom.GeometryType.POINT:
- case ol.geom.GeometryType.MULTI_POINT:
- case ol.geom.GeometryType.LINE_STRING:
- case ol.geom.GeometryType.MULTI_LINE_STRING:
- case ol.geom.GeometryType.LINEAR_RING: {
- break;
- }
- case ol.geom.GeometryType.POLYGON: {
- coordinates = /** @type {ol.geom.Polygon} */ (geometry).getCoordinates();
- area = Math.abs(ol.Sphere.getArea_(coordinates[0], radius));
- for (i = 1, ii = coordinates.length; i < ii; ++i) {
- area -= Math.abs(ol.Sphere.getArea_(coordinates[i], radius));
- }
- break;
- }
- case ol.geom.GeometryType.MULTI_POLYGON: {
- coordinates = /** @type {ol.geom.SimpleGeometry} */ (geometry).getCoordinates();
- for (i = 0, ii = coordinates.length; i < ii; ++i) {
- coords = coordinates[i];
- area += Math.abs(ol.Sphere.getArea_(coords[0], radius));
- for (j = 1, jj = coords.length; j < jj; ++j) {
- area -= Math.abs(ol.Sphere.getArea_(coords[j], radius));
- }
- }
- break;
- }
- case ol.geom.GeometryType.GEOMETRY_COLLECTION: {
- var geometries = /** @type {ol.geom.GeometryCollection} */ (geometry).getGeometries();
- for (i = 0, ii = geometries.length; i < ii; ++i) {
- area += ol.Sphere.getArea(geometries[i], opt_options);
- }
- break;
- }
- default: {
- throw new Error('Unsupported geometry type: ' + type);
- }
- }
- return area;
- };
- /**
- * Returns the spherical area for a list of coordinates.
- *
- * [Reference](https://trs-new.jpl.nasa.gov/handle/2014/40409)
- * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for
- * Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
- * Laboratory, Pasadena, CA, June 2007
- *
- * @param {Array.<ol.Coordinate>} coordinates List of coordinates of a linear
- * ring. If the ring is oriented clockwise, the area will be positive,
- * otherwise it will be negative.
- * @param {number} radius The sphere radius.
- * @return {number} Area (in square meters).
- */
- ol.Sphere.getArea_ = function(coordinates, radius) {
- var area = 0, len = coordinates.length;
- var x1 = coordinates[len - 1][0];
- var y1 = coordinates[len - 1][1];
- for (var i = 0; i < len; i++) {
- var x2 = coordinates[i][0], y2 = coordinates[i][1];
- area += ol.math.toRadians(x2 - x1) *
- (2 + Math.sin(ol.math.toRadians(y1)) +
- Math.sin(ol.math.toRadians(y2)));
- x1 = x2;
- y1 = y2;
- }
- return area * radius * radius / 2.0;
- };
- goog.provide('ol.proj.Units');
- /**
- * Projection units: `'degrees'`, `'ft'`, `'m'`, `'pixels'`, `'tile-pixels'` or
- * `'us-ft'`.
- * @enum {string}
- */
- ol.proj.Units = {
- DEGREES: 'degrees',
- FEET: 'ft',
- METERS: 'm',
- PIXELS: 'pixels',
- TILE_PIXELS: 'tile-pixels',
- USFEET: 'us-ft'
- };
- /**
- * Meters per unit lookup table.
- * @const
- * @type {Object.<ol.proj.Units, number>}
- * @api
- */
- ol.proj.Units.METERS_PER_UNIT = {};
- // use the radius of the Normal sphere
- ol.proj.Units.METERS_PER_UNIT[ol.proj.Units.DEGREES] =
- 2 * Math.PI * 6370997 / 360;
- ol.proj.Units.METERS_PER_UNIT[ol.proj.Units.FEET] = 0.3048;
- ol.proj.Units.METERS_PER_UNIT[ol.proj.Units.METERS] = 1;
- ol.proj.Units.METERS_PER_UNIT[ol.proj.Units.USFEET] = 1200 / 3937;
- goog.provide('ol.proj.proj4');
- /**
- * @private
- * @type {Proj4}
- */
- ol.proj.proj4.cache_ = null;
- /**
- * Store the proj4 function.
- * @param {Proj4} proj4 The proj4 function.
- */
- ol.proj.proj4.set = function(proj4) {
- ol.proj.proj4.cache_ = proj4;
- };
- /**
- * Get proj4.
- * @return {Proj4} The proj4 function set above or available globally.
- */
- ol.proj.proj4.get = function() {
- return ol.proj.proj4.cache_ || window['proj4'];
- };
- goog.provide('ol.proj.Projection');
- goog.require('ol');
- goog.require('ol.proj.Units');
- goog.require('ol.proj.proj4');
- /**
- * @classdesc
- * Projection definition class. One of these is created for each projection
- * supported in the application and stored in the {@link ol.proj} namespace.
- * You can use these in applications, but this is not required, as API params
- * and options use {@link ol.ProjectionLike} which means the simple string
- * code will suffice.
- *
- * You can use {@link ol.proj.get} to retrieve the object for a particular
- * projection.
- *
- * The library includes definitions for `EPSG:4326` and `EPSG:3857`, together
- * with the following aliases:
- * * `EPSG:4326`: CRS:84, urn:ogc:def:crs:EPSG:6.6:4326,
- * urn:ogc:def:crs:OGC:1.3:CRS84, urn:ogc:def:crs:OGC:2:84,
- * http://www.opengis.net/gml/srs/epsg.xml#4326,
- * urn:x-ogc:def:crs:EPSG:4326
- * * `EPSG:3857`: EPSG:102100, EPSG:102113, EPSG:900913,
- * urn:ogc:def:crs:EPSG:6.18:3:3857,
- * http://www.opengis.net/gml/srs/epsg.xml#3857
- *
- * If you use proj4js, aliases can be added using `proj4.defs()`; see
- * [documentation](https://github.com/proj4js/proj4js). To set an alternative
- * namespace for proj4, use {@link ol.proj.setProj4}.
- *
- * @constructor
- * @param {olx.ProjectionOptions} options Projection options.
- * @struct
- * @api
- */
- ol.proj.Projection = function(options) {
- /**
- * @private
- * @type {string}
- */
- this.code_ = options.code;
- /**
- * Units of projected coordinates. When set to `ol.proj.Units.TILE_PIXELS`, a
- * `this.extent_` and `this.worldExtent_` must be configured properly for each
- * tile.
- * @private
- * @type {ol.proj.Units}
- */
- this.units_ = /** @type {ol.proj.Units} */ (options.units);
- /**
- * Validity extent of the projection in projected coordinates. For projections
- * with `ol.proj.Units.TILE_PIXELS` units, this is the extent of the tile in
- * tile pixel space.
- * @private
- * @type {ol.Extent}
- */
- this.extent_ = options.extent !== undefined ? options.extent : null;
- /**
- * Extent of the world in EPSG:4326. For projections with
- * `ol.proj.Units.TILE_PIXELS` units, this is the extent of the tile in
- * projected coordinate space.
- * @private
- * @type {ol.Extent}
- */
- this.worldExtent_ = options.worldExtent !== undefined ?
- options.worldExtent : null;
- /**
- * @private
- * @type {string}
- */
- this.axisOrientation_ = options.axisOrientation !== undefined ?
- options.axisOrientation : 'enu';
- /**
- * @private
- * @type {boolean}
- */
- this.global_ = options.global !== undefined ? options.global : false;
- /**
- * @private
- * @type {boolean}
- */
- this.canWrapX_ = !!(this.global_ && this.extent_);
- /**
- * @private
- * @type {function(number, ol.Coordinate):number|undefined}
- */
- this.getPointResolutionFunc_ = options.getPointResolution;
- /**
- * @private
- * @type {ol.tilegrid.TileGrid}
- */
- this.defaultTileGrid_ = null;
- /**
- * @private
- * @type {number|undefined}
- */
- this.metersPerUnit_ = options.metersPerUnit;
- var code = options.code;
- if (ol.ENABLE_PROJ4JS) {
- var proj4js = ol.proj.proj4.get();
- if (typeof proj4js == 'function') {
- var def = proj4js.defs(code);
- if (def !== undefined) {
- if (def.axis !== undefined && options.axisOrientation === undefined) {
- this.axisOrientation_ = def.axis;
- }
- if (options.metersPerUnit === undefined) {
- this.metersPerUnit_ = def.to_meter;
- }
- if (options.units === undefined) {
- this.units_ = def.units;
- }
- }
- }
- }
- };
- /**
- * @return {boolean} The projection is suitable for wrapping the x-axis
- */
- ol.proj.Projection.prototype.canWrapX = function() {
- return this.canWrapX_;
- };
- /**
- * Get the code for this projection, e.g. 'EPSG:4326'.
- * @return {string} Code.
- * @api
- */
- ol.proj.Projection.prototype.getCode = function() {
- return this.code_;
- };
- /**
- * Get the validity extent for this projection.
- * @return {ol.Extent} Extent.
- * @api
- */
- ol.proj.Projection.prototype.getExtent = function() {
- return this.extent_;
- };
- /**
- * Get the units of this projection.
- * @return {ol.proj.Units} Units.
- * @api
- */
- ol.proj.Projection.prototype.getUnits = function() {
- return this.units_;
- };
- /**
- * Get the amount of meters per unit of this projection. If the projection is
- * not configured with `metersPerUnit` or a units identifier, the return is
- * `undefined`.
- * @return {number|undefined} Meters.
- * @api
- */
- ol.proj.Projection.prototype.getMetersPerUnit = function() {
- return this.metersPerUnit_ || ol.proj.Units.METERS_PER_UNIT[this.units_];
- };
- /**
- * Get the world extent for this projection.
- * @return {ol.Extent} Extent.
- * @api
- */
- ol.proj.Projection.prototype.getWorldExtent = function() {
- return this.worldExtent_;
- };
- /**
- * Get the axis orientation of this projection.
- * Example values are:
- * enu - the default easting, northing, elevation.
- * neu - northing, easting, up - useful for "lat/long" geographic coordinates,
- * or south orientated transverse mercator.
- * wnu - westing, northing, up - some planetary coordinate systems have
- * "west positive" coordinate systems
- * @return {string} Axis orientation.
- * @api
- */
- ol.proj.Projection.prototype.getAxisOrientation = function() {
- return this.axisOrientation_;
- };
- /**
- * Is this projection a global projection which spans the whole world?
- * @return {boolean} Whether the projection is global.
- * @api
- */
- ol.proj.Projection.prototype.isGlobal = function() {
- return this.global_;
- };
- /**
- * Set if the projection is a global projection which spans the whole world
- * @param {boolean} global Whether the projection is global.
- * @api
- */
- ol.proj.Projection.prototype.setGlobal = function(global) {
- this.global_ = global;
- this.canWrapX_ = !!(global && this.extent_);
- };
- /**
- * @return {ol.tilegrid.TileGrid} The default tile grid.
- */
- ol.proj.Projection.prototype.getDefaultTileGrid = function() {
- return this.defaultTileGrid_;
- };
- /**
- * @param {ol.tilegrid.TileGrid} tileGrid The default tile grid.
- */
- ol.proj.Projection.prototype.setDefaultTileGrid = function(tileGrid) {
- this.defaultTileGrid_ = tileGrid;
- };
- /**
- * Set the validity extent for this projection.
- * @param {ol.Extent} extent Extent.
- * @api
- */
- ol.proj.Projection.prototype.setExtent = function(extent) {
- this.extent_ = extent;
- this.canWrapX_ = !!(this.global_ && extent);
- };
- /**
- * Set the world extent for this projection.
- * @param {ol.Extent} worldExtent World extent
- * [minlon, minlat, maxlon, maxlat].
- * @api
- */
- ol.proj.Projection.prototype.setWorldExtent = function(worldExtent) {
- this.worldExtent_ = worldExtent;
- };
- /**
- * Set the getPointResolution function (see {@link ol.proj#getPointResolution}
- * for this projection.
- * @param {function(number, ol.Coordinate):number} func Function
- * @api
- */
- ol.proj.Projection.prototype.setGetPointResolution = function(func) {
- this.getPointResolutionFunc_ = func;
- };
- /**
- * Get the custom point resolution function for this projection (if set).
- * @return {function(number, ol.Coordinate):number|undefined} The custom point
- * resolution function (if set).
- */
- ol.proj.Projection.prototype.getPointResolutionFunc = function() {
- return this.getPointResolutionFunc_;
- };
- goog.provide('ol.proj.EPSG3857');
- goog.require('ol');
- goog.require('ol.math');
- goog.require('ol.proj.Projection');
- goog.require('ol.proj.Units');
- /**
- * @classdesc
- * Projection object for web/spherical Mercator (EPSG:3857).
- *
- * @constructor
- * @extends {ol.proj.Projection}
- * @param {string} code Code.
- * @private
- */
- ol.proj.EPSG3857.Projection_ = function(code) {
- ol.proj.Projection.call(this, {
- code: code,
- units: ol.proj.Units.METERS,
- extent: ol.proj.EPSG3857.EXTENT,
- global: true,
- worldExtent: ol.proj.EPSG3857.WORLD_EXTENT,
- getPointResolution: function(resolution, point) {
- return resolution / ol.math.cosh(point[1] / ol.proj.EPSG3857.RADIUS);
- }
- });
- };
- ol.inherits(ol.proj.EPSG3857.Projection_, ol.proj.Projection);
- /**
- * Radius of WGS84 sphere
- *
- * @const
- * @type {number}
- */
- ol.proj.EPSG3857.RADIUS = 6378137;
- /**
- * @const
- * @type {number}
- */
- ol.proj.EPSG3857.HALF_SIZE = Math.PI * ol.proj.EPSG3857.RADIUS;
- /**
- * @const
- * @type {ol.Extent}
- */
- ol.proj.EPSG3857.EXTENT = [
- -ol.proj.EPSG3857.HALF_SIZE, -ol.proj.EPSG3857.HALF_SIZE,
- ol.proj.EPSG3857.HALF_SIZE, ol.proj.EPSG3857.HALF_SIZE
- ];
- /**
- * @const
- * @type {ol.Extent}
- */
- ol.proj.EPSG3857.WORLD_EXTENT = [-180, -85, 180, 85];
- /**
- * Projections equal to EPSG:3857.
- *
- * @const
- * @type {Array.<ol.proj.Projection>}
- */
- ol.proj.EPSG3857.PROJECTIONS = [
- new ol.proj.EPSG3857.Projection_('EPSG:3857'),
- new ol.proj.EPSG3857.Projection_('EPSG:102100'),
- new ol.proj.EPSG3857.Projection_('EPSG:102113'),
- new ol.proj.EPSG3857.Projection_('EPSG:900913'),
- new ol.proj.EPSG3857.Projection_('urn:ogc:def:crs:EPSG:6.18:3:3857'),
- new ol.proj.EPSG3857.Projection_('urn:ogc:def:crs:EPSG::3857'),
- new ol.proj.EPSG3857.Projection_('http://www.opengis.net/gml/srs/epsg.xml#3857')
- ];
- /**
- * Transformation from EPSG:4326 to EPSG:3857.
- *
- * @param {Array.<number>} input Input array of coordinate values.
- * @param {Array.<number>=} opt_output Output array of coordinate values.
- * @param {number=} opt_dimension Dimension (default is `2`).
- * @return {Array.<number>} Output array of coordinate values.
- */
- ol.proj.EPSG3857.fromEPSG4326 = function(input, opt_output, opt_dimension) {
- var length = input.length,
- dimension = opt_dimension > 1 ? opt_dimension : 2,
- output = opt_output;
- if (output === undefined) {
- if (dimension > 2) {
- // preserve values beyond second dimension
- output = input.slice();
- } else {
- output = new Array(length);
- }
- }
- var halfSize = ol.proj.EPSG3857.HALF_SIZE;
- for (var i = 0; i < length; i += dimension) {
- output[i] = halfSize * input[i] / 180;
- var y = ol.proj.EPSG3857.RADIUS *
- Math.log(Math.tan(Math.PI * (input[i + 1] + 90) / 360));
- if (y > halfSize) {
- y = halfSize;
- } else if (y < -halfSize) {
- y = -halfSize;
- }
- output[i + 1] = y;
- }
- return output;
- };
- /**
- * Transformation from EPSG:3857 to EPSG:4326.
- *
- * @param {Array.<number>} input Input array of coordinate values.
- * @param {Array.<number>=} opt_output Output array of coordinate values.
- * @param {number=} opt_dimension Dimension (default is `2`).
- * @return {Array.<number>} Output array of coordinate values.
- */
- ol.proj.EPSG3857.toEPSG4326 = function(input, opt_output, opt_dimension) {
- var length = input.length,
- dimension = opt_dimension > 1 ? opt_dimension : 2,
- output = opt_output;
- if (output === undefined) {
- if (dimension > 2) {
- // preserve values beyond second dimension
- output = input.slice();
- } else {
- output = new Array(length);
- }
- }
- for (var i = 0; i < length; i += dimension) {
- output[i] = 180 * input[i] / ol.proj.EPSG3857.HALF_SIZE;
- output[i + 1] = 360 * Math.atan(
- Math.exp(input[i + 1] / ol.proj.EPSG3857.RADIUS)) / Math.PI - 90;
- }
- return output;
- };
- goog.provide('ol.proj.EPSG4326');
- goog.require('ol');
- goog.require('ol.proj.Projection');
- goog.require('ol.proj.Units');
- /**
- * @classdesc
- * Projection object for WGS84 geographic coordinates (EPSG:4326).
- *
- * Note that OpenLayers does not strictly comply with the EPSG definition.
- * The EPSG registry defines 4326 as a CRS for Latitude,Longitude (y,x).
- * OpenLayers treats EPSG:4326 as a pseudo-projection, with x,y coordinates.
- *
- * @constructor
- * @extends {ol.proj.Projection}
- * @param {string} code Code.
- * @param {string=} opt_axisOrientation Axis orientation.
- * @private
- */
- ol.proj.EPSG4326.Projection_ = function(code, opt_axisOrientation) {
- ol.proj.Projection.call(this, {
- code: code,
- units: ol.proj.Units.DEGREES,
- extent: ol.proj.EPSG4326.EXTENT,
- axisOrientation: opt_axisOrientation,
- global: true,
- metersPerUnit: ol.proj.EPSG4326.METERS_PER_UNIT,
- worldExtent: ol.proj.EPSG4326.EXTENT
- });
- };
- ol.inherits(ol.proj.EPSG4326.Projection_, ol.proj.Projection);
- /**
- * Radius of WGS84 sphere
- *
- * @const
- * @type {number}
- */
- ol.proj.EPSG4326.RADIUS = 6378137;
- /**
- * Extent of the EPSG:4326 projection which is the whole world.
- *
- * @const
- * @type {ol.Extent}
- */
- ol.proj.EPSG4326.EXTENT = [-180, -90, 180, 90];
- /**
- * @const
- * @type {number}
- */
- ol.proj.EPSG4326.METERS_PER_UNIT = Math.PI * ol.proj.EPSG4326.RADIUS / 180;
- /**
- * Projections equal to EPSG:4326.
- *
- * @const
- * @type {Array.<ol.proj.Projection>}
- */
- ol.proj.EPSG4326.PROJECTIONS = [
- new ol.proj.EPSG4326.Projection_('CRS:84'),
- new ol.proj.EPSG4326.Projection_('EPSG:4326', 'neu'),
- new ol.proj.EPSG4326.Projection_('urn:ogc:def:crs:EPSG::4326', 'neu'),
- new ol.proj.EPSG4326.Projection_('urn:ogc:def:crs:EPSG:6.6:4326', 'neu'),
- new ol.proj.EPSG4326.Projection_('urn:ogc:def:crs:OGC:1.3:CRS84'),
- new ol.proj.EPSG4326.Projection_('urn:ogc:def:crs:OGC:2:84'),
- new ol.proj.EPSG4326.Projection_('http://www.opengis.net/gml/srs/epsg.xml#4326', 'neu'),
- new ol.proj.EPSG4326.Projection_('urn:x-ogc:def:crs:EPSG:4326', 'neu')
- ];
- goog.provide('ol.proj.projections');
- /**
- * @private
- * @type {Object.<string, ol.proj.Projection>}
- */
- ol.proj.projections.cache_ = {};
- /**
- * Clear the projections cache.
- */
- ol.proj.projections.clear = function() {
- ol.proj.projections.cache_ = {};
- };
- /**
- * Get a cached projection by code.
- * @param {string} code The code for the projection.
- * @return {ol.proj.Projection} The projection (if cached).
- */
- ol.proj.projections.get = function(code) {
- var projections = ol.proj.projections.cache_;
- return projections[code] || null;
- };
- /**
- * Add a projection to the cache.
- * @param {string} code The projection code.
- * @param {ol.proj.Projection} projection The projection to cache.
- */
- ol.proj.projections.add = function(code, projection) {
- var projections = ol.proj.projections.cache_;
- projections[code] = projection;
- };
- goog.provide('ol.proj.transforms');
- goog.require('ol.obj');
- /**
- * @private
- * @type {Object.<string, Object.<string, ol.TransformFunction>>}
- */
- ol.proj.transforms.cache_ = {};
- /**
- * Clear the transform cache.
- */
- ol.proj.transforms.clear = function() {
- ol.proj.transforms.cache_ = {};
- };
- /**
- * Registers a conversion function to convert coordinates from the source
- * projection to the destination projection.
- *
- * @param {ol.proj.Projection} source Source.
- * @param {ol.proj.Projection} destination Destination.
- * @param {ol.TransformFunction} transformFn Transform.
- */
- ol.proj.transforms.add = function(source, destination, transformFn) {
- var sourceCode = source.getCode();
- var destinationCode = destination.getCode();
- var transforms = ol.proj.transforms.cache_;
- if (!(sourceCode in transforms)) {
- transforms[sourceCode] = {};
- }
- transforms[sourceCode][destinationCode] = transformFn;
- };
- /**
- * Unregisters the conversion function to convert coordinates from the source
- * projection to the destination projection. This method is used to clean up
- * cached transforms during testing.
- *
- * @param {ol.proj.Projection} source Source projection.
- * @param {ol.proj.Projection} destination Destination projection.
- * @return {ol.TransformFunction} transformFn The unregistered transform.
- */
- ol.proj.transforms.remove = function(source, destination) {
- var sourceCode = source.getCode();
- var destinationCode = destination.getCode();
- var transforms = ol.proj.transforms.cache_;
- var transform = transforms[sourceCode][destinationCode];
- delete transforms[sourceCode][destinationCode];
- if (ol.obj.isEmpty(transforms[sourceCode])) {
- delete transforms[sourceCode];
- }
- return transform;
- };
- /**
- * Get a transform given a source code and a destination code.
- * @param {string} sourceCode The code for the source projection.
- * @param {string} destinationCode The code for the destination projection.
- * @return {ol.TransformFunction|undefined} The transform function (if found).
- */
- ol.proj.transforms.get = function(sourceCode, destinationCode) {
- var transform;
- var transforms = ol.proj.transforms.cache_;
- if (sourceCode in transforms && destinationCode in transforms[sourceCode]) {
- transform = transforms[sourceCode][destinationCode];
- }
- return transform;
- };
- goog.provide('ol.proj');
- goog.require('ol');
- goog.require('ol.Sphere');
- goog.require('ol.extent');
- goog.require('ol.math');
- goog.require('ol.proj.EPSG3857');
- goog.require('ol.proj.EPSG4326');
- goog.require('ol.proj.Projection');
- goog.require('ol.proj.Units');
- goog.require('ol.proj.proj4');
- goog.require('ol.proj.projections');
- goog.require('ol.proj.transforms');
- /**
- * Meters per unit lookup table.
- * @const
- * @type {Object.<ol.proj.Units, number>}
- * @api
- */
- ol.proj.METERS_PER_UNIT = ol.proj.Units.METERS_PER_UNIT;
- /**
- * A place to store the mean radius of the Earth.
- * @private
- * @type {ol.Sphere}
- */
- ol.proj.SPHERE_ = new ol.Sphere(ol.Sphere.DEFAULT_RADIUS);
- if (ol.ENABLE_PROJ4JS) {
- /**
- * Register proj4. If not explicitly registered, it will be assumed that
- * proj4js will be loaded in the global namespace. For example in a
- * browserify ES6 environment you could use:
- *
- * import ol from 'openlayers';
- * import proj4 from 'proj4';
- * ol.proj.setProj4(proj4);
- *
- * @param {Proj4} proj4 Proj4.
- * @api
- */
- ol.proj.setProj4 = function(proj4) {
- ol.proj.proj4.set(proj4);
- };
- }
- /**
- * Get the resolution of the point in degrees or distance units.
- * For projections with degrees as the unit this will simply return the
- * provided resolution. For other projections the point resolution is
- * by default estimated by transforming the 'point' pixel to EPSG:4326,
- * measuring its width and height on the normal sphere,
- * and taking the average of the width and height.
- * A custom function can be provided for a specific projection, either
- * by setting the `getPointResolution` option in the
- * {@link ol.proj.Projection} constructor or by using
- * {@link ol.proj.Projection#setGetPointResolution} to change an existing
- * projection object.
- * @param {ol.ProjectionLike} projection The projection.
- * @param {number} resolution Nominal resolution in projection units.
- * @param {ol.Coordinate} point Point to find adjusted resolution at.
- * @param {ol.proj.Units=} opt_units Units to get the point resolution in.
- * Default is the projection's units.
- * @return {number} Point resolution.
- * @api
- */
- ol.proj.getPointResolution = function(projection, resolution, point, opt_units) {
- projection = ol.proj.get(projection);
- var pointResolution;
- var getter = projection.getPointResolutionFunc();
- if (getter) {
- pointResolution = getter(resolution, point);
- } else {
- var units = projection.getUnits();
- if (units == ol.proj.Units.DEGREES && !opt_units || opt_units == ol.proj.Units.DEGREES) {
- pointResolution = resolution;
- } else {
- // Estimate point resolution by transforming the center pixel to EPSG:4326,
- // measuring its width and height on the normal sphere, and taking the
- // average of the width and height.
- var toEPSG4326 = ol.proj.getTransformFromProjections(projection, ol.proj.get('EPSG:4326'));
- var vertices = [
- point[0] - resolution / 2, point[1],
- point[0] + resolution / 2, point[1],
- point[0], point[1] - resolution / 2,
- point[0], point[1] + resolution / 2
- ];
- vertices = toEPSG4326(vertices, vertices, 2);
- var width = ol.proj.SPHERE_.haversineDistance(
- vertices.slice(0, 2), vertices.slice(2, 4));
- var height = ol.proj.SPHERE_.haversineDistance(
- vertices.slice(4, 6), vertices.slice(6, 8));
- pointResolution = (width + height) / 2;
- var metersPerUnit = opt_units ?
- ol.proj.Units.METERS_PER_UNIT[opt_units] :
- projection.getMetersPerUnit();
- if (metersPerUnit !== undefined) {
- pointResolution /= metersPerUnit;
- }
- }
- }
- return pointResolution;
- };
- /**
- * Registers transformation functions that don't alter coordinates. Those allow
- * to transform between projections with equal meaning.
- *
- * @param {Array.<ol.proj.Projection>} projections Projections.
- * @api
- */
- ol.proj.addEquivalentProjections = function(projections) {
- ol.proj.addProjections(projections);
- projections.forEach(function(source) {
- projections.forEach(function(destination) {
- if (source !== destination) {
- ol.proj.transforms.add(source, destination, ol.proj.cloneTransform);
- }
- });
- });
- };
- /**
- * Registers transformation functions to convert coordinates in any projection
- * in projection1 to any projection in projection2.
- *
- * @param {Array.<ol.proj.Projection>} projections1 Projections with equal
- * meaning.
- * @param {Array.<ol.proj.Projection>} projections2 Projections with equal
- * meaning.
- * @param {ol.TransformFunction} forwardTransform Transformation from any
- * projection in projection1 to any projection in projection2.
- * @param {ol.TransformFunction} inverseTransform Transform from any projection
- * in projection2 to any projection in projection1..
- */
- ol.proj.addEquivalentTransforms = function(projections1, projections2, forwardTransform, inverseTransform) {
- projections1.forEach(function(projection1) {
- projections2.forEach(function(projection2) {
- ol.proj.transforms.add(projection1, projection2, forwardTransform);
- ol.proj.transforms.add(projection2, projection1, inverseTransform);
- });
- });
- };
- /**
- * Add a Projection object to the list of supported projections that can be
- * looked up by their code.
- *
- * @param {ol.proj.Projection} projection Projection instance.
- * @api
- */
- ol.proj.addProjection = function(projection) {
- ol.proj.projections.add(projection.getCode(), projection);
- ol.proj.transforms.add(projection, projection, ol.proj.cloneTransform);
- };
- /**
- * @param {Array.<ol.proj.Projection>} projections Projections.
- */
- ol.proj.addProjections = function(projections) {
- projections.forEach(ol.proj.addProjection);
- };
- /**
- * Clear all cached projections and transforms.
- */
- ol.proj.clearAllProjections = function() {
- ol.proj.projections.clear();
- ol.proj.transforms.clear();
- };
- /**
- * @param {ol.proj.Projection|string|undefined} projection Projection.
- * @param {string} defaultCode Default code.
- * @return {ol.proj.Projection} Projection.
- */
- ol.proj.createProjection = function(projection, defaultCode) {
- if (!projection) {
- return ol.proj.get(defaultCode);
- } else if (typeof projection === 'string') {
- return ol.proj.get(projection);
- } else {
- return /** @type {ol.proj.Projection} */ (projection);
- }
- };
- /**
- * Registers coordinate transform functions to convert coordinates between the
- * source projection and the destination projection.
- * The forward and inverse functions convert coordinate pairs; this function
- * converts these into the functions used internally which also handle
- * extents and coordinate arrays.
- *
- * @param {ol.ProjectionLike} source Source projection.
- * @param {ol.ProjectionLike} destination Destination projection.
- * @param {function(ol.Coordinate): ol.Coordinate} forward The forward transform
- * function (that is, from the source projection to the destination
- * projection) that takes a {@link ol.Coordinate} as argument and returns
- * the transformed {@link ol.Coordinate}.
- * @param {function(ol.Coordinate): ol.Coordinate} inverse The inverse transform
- * function (that is, from the destination projection to the source
- * projection) that takes a {@link ol.Coordinate} as argument and returns
- * the transformed {@link ol.Coordinate}.
- * @api
- */
- ol.proj.addCoordinateTransforms = function(source, destination, forward, inverse) {
- var sourceProj = ol.proj.get(source);
- var destProj = ol.proj.get(destination);
- ol.proj.transforms.add(sourceProj, destProj,
- ol.proj.createTransformFromCoordinateTransform(forward));
- ol.proj.transforms.add(destProj, sourceProj,
- ol.proj.createTransformFromCoordinateTransform(inverse));
- };
- /**
- * Creates a {@link ol.TransformFunction} from a simple 2D coordinate transform
- * function.
- * @param {function(ol.Coordinate): ol.Coordinate} transform Coordinate
- * transform.
- * @return {ol.TransformFunction} Transform function.
- */
- ol.proj.createTransformFromCoordinateTransform = function(transform) {
- return (
- /**
- * @param {Array.<number>} input Input.
- * @param {Array.<number>=} opt_output Output.
- * @param {number=} opt_dimension Dimension.
- * @return {Array.<number>} Output.
- */
- function(input, opt_output, opt_dimension) {
- var length = input.length;
- var dimension = opt_dimension !== undefined ? opt_dimension : 2;
- var output = opt_output !== undefined ? opt_output : new Array(length);
- var point, i, j;
- for (i = 0; i < length; i += dimension) {
- point = transform([input[i], input[i + 1]]);
- output[i] = point[0];
- output[i + 1] = point[1];
- for (j = dimension - 1; j >= 2; --j) {
- output[i + j] = input[i + j];
- }
- }
- return output;
- });
- };
- /**
- * Transforms a coordinate from longitude/latitude to a different projection.
- * @param {ol.Coordinate} coordinate Coordinate as longitude and latitude, i.e.
- * an array with longitude as 1st and latitude as 2nd element.
- * @param {ol.ProjectionLike=} opt_projection Target projection. The
- * default is Web Mercator, i.e. 'EPSG:3857'.
- * @return {ol.Coordinate} Coordinate projected to the target projection.
- * @api
- */
- ol.proj.fromLonLat = function(coordinate, opt_projection) {
- return ol.proj.transform(coordinate, 'EPSG:4326',
- opt_projection !== undefined ? opt_projection : 'EPSG:3857');
- };
- /**
- * Transforms a coordinate to longitude/latitude.
- * @param {ol.Coordinate} coordinate Projected coordinate.
- * @param {ol.ProjectionLike=} opt_projection Projection of the coordinate.
- * The default is Web Mercator, i.e. 'EPSG:3857'.
- * @return {ol.Coordinate} Coordinate as longitude and latitude, i.e. an array
- * with longitude as 1st and latitude as 2nd element.
- * @api
- */
- ol.proj.toLonLat = function(coordinate, opt_projection) {
- var lonLat = ol.proj.transform(coordinate,
- opt_projection !== undefined ? opt_projection : 'EPSG:3857', 'EPSG:4326');
- var lon = lonLat[0];
- if (lon < -180 || lon > 180) {
- lonLat[0] = ol.math.modulo(lon + 180, 360) - 180;
- }
- return lonLat;
- };
- /**
- * Fetches a Projection object for the code specified.
- *
- * @param {ol.ProjectionLike} projectionLike Either a code string which is
- * a combination of authority and identifier such as "EPSG:4326", or an
- * existing projection object, or undefined.
- * @return {ol.proj.Projection} Projection object, or null if not in list.
- * @api
- */
- ol.proj.get = function(projectionLike) {
- var projection = null;
- if (projectionLike instanceof ol.proj.Projection) {
- projection = projectionLike;
- } else if (typeof projectionLike === 'string') {
- var code = projectionLike;
- projection = ol.proj.projections.get(code);
- if (ol.ENABLE_PROJ4JS && !projection) {
- var proj4js = ol.proj.proj4.get();
- if (typeof proj4js == 'function' &&
- proj4js.defs(code) !== undefined) {
- projection = new ol.proj.Projection({code: code});
- ol.proj.addProjection(projection);
- }
- }
- }
- return projection;
- };
- /**
- * Checks if two projections are the same, that is every coordinate in one
- * projection does represent the same geographic point as the same coordinate in
- * the other projection.
- *
- * @param {ol.proj.Projection} projection1 Projection 1.
- * @param {ol.proj.Projection} projection2 Projection 2.
- * @return {boolean} Equivalent.
- * @api
- */
- ol.proj.equivalent = function(projection1, projection2) {
- if (projection1 === projection2) {
- return true;
- }
- var equalUnits = projection1.getUnits() === projection2.getUnits();
- if (projection1.getCode() === projection2.getCode()) {
- return equalUnits;
- } else {
- var transformFn = ol.proj.getTransformFromProjections(
- projection1, projection2);
- return transformFn === ol.proj.cloneTransform && equalUnits;
- }
- };
- /**
- * Given the projection-like objects, searches for a transformation
- * function to convert a coordinates array from the source projection to the
- * destination projection.
- *
- * @param {ol.ProjectionLike} source Source.
- * @param {ol.ProjectionLike} destination Destination.
- * @return {ol.TransformFunction} Transform function.
- * @api
- */
- ol.proj.getTransform = function(source, destination) {
- var sourceProjection = ol.proj.get(source);
- var destinationProjection = ol.proj.get(destination);
- return ol.proj.getTransformFromProjections(
- sourceProjection, destinationProjection);
- };
- /**
- * Searches in the list of transform functions for the function for converting
- * coordinates from the source projection to the destination projection.
- *
- * @param {ol.proj.Projection} sourceProjection Source Projection object.
- * @param {ol.proj.Projection} destinationProjection Destination Projection
- * object.
- * @return {ol.TransformFunction} Transform function.
- */
- ol.proj.getTransformFromProjections = function(sourceProjection, destinationProjection) {
- var sourceCode = sourceProjection.getCode();
- var destinationCode = destinationProjection.getCode();
- var transform = ol.proj.transforms.get(sourceCode, destinationCode);
- if (ol.ENABLE_PROJ4JS && !transform) {
- var proj4js = ol.proj.proj4.get();
- if (typeof proj4js == 'function') {
- var sourceDef = proj4js.defs(sourceCode);
- var destinationDef = proj4js.defs(destinationCode);
- if (sourceDef !== undefined && destinationDef !== undefined) {
- if (sourceDef === destinationDef) {
- ol.proj.addEquivalentProjections([destinationProjection, sourceProjection]);
- } else {
- var proj4Transform = proj4js(destinationCode, sourceCode);
- ol.proj.addCoordinateTransforms(destinationProjection, sourceProjection,
- proj4Transform.forward, proj4Transform.inverse);
- }
- transform = ol.proj.transforms.get(sourceCode, destinationCode);
- }
- }
- }
- if (!transform) {
- transform = ol.proj.identityTransform;
- }
- return transform;
- };
- /**
- * @param {Array.<number>} input Input coordinate array.
- * @param {Array.<number>=} opt_output Output array of coordinate values.
- * @param {number=} opt_dimension Dimension.
- * @return {Array.<number>} Input coordinate array (same array as input).
- */
- ol.proj.identityTransform = function(input, opt_output, opt_dimension) {
- if (opt_output !== undefined && input !== opt_output) {
- for (var i = 0, ii = input.length; i < ii; ++i) {
- opt_output[i] = input[i];
- }
- input = opt_output;
- }
- return input;
- };
- /**
- * @param {Array.<number>} input Input coordinate array.
- * @param {Array.<number>=} opt_output Output array of coordinate values.
- * @param {number=} opt_dimension Dimension.
- * @return {Array.<number>} Output coordinate array (new array, same coordinate
- * values).
- */
- ol.proj.cloneTransform = function(input, opt_output, opt_dimension) {
- var output;
- if (opt_output !== undefined) {
- for (var i = 0, ii = input.length; i < ii; ++i) {
- opt_output[i] = input[i];
- }
- output = opt_output;
- } else {
- output = input.slice();
- }
- return output;
- };
- /**
- * Transforms a coordinate from source projection to destination projection.
- * This returns a new coordinate (and does not modify the original).
- *
- * See {@link ol.proj.transformExtent} for extent transformation.
- * See the transform method of {@link ol.geom.Geometry} and its subclasses for
- * geometry transforms.
- *
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {ol.ProjectionLike} source Source projection-like.
- * @param {ol.ProjectionLike} destination Destination projection-like.
- * @return {ol.Coordinate} Coordinate.
- * @api
- */
- ol.proj.transform = function(coordinate, source, destination) {
- var transformFn = ol.proj.getTransform(source, destination);
- return transformFn(coordinate, undefined, coordinate.length);
- };
- /**
- * Transforms an extent from source projection to destination projection. This
- * returns a new extent (and does not modify the original).
- *
- * @param {ol.Extent} extent The extent to transform.
- * @param {ol.ProjectionLike} source Source projection-like.
- * @param {ol.ProjectionLike} destination Destination projection-like.
- * @return {ol.Extent} The transformed extent.
- * @api
- */
- ol.proj.transformExtent = function(extent, source, destination) {
- var transformFn = ol.proj.getTransform(source, destination);
- return ol.extent.applyTransform(extent, transformFn);
- };
- /**
- * Transforms the given point to the destination projection.
- *
- * @param {ol.Coordinate} point Point.
- * @param {ol.proj.Projection} sourceProjection Source projection.
- * @param {ol.proj.Projection} destinationProjection Destination projection.
- * @return {ol.Coordinate} Point.
- */
- ol.proj.transformWithProjections = function(point, sourceProjection, destinationProjection) {
- var transformFn = ol.proj.getTransformFromProjections(
- sourceProjection, destinationProjection);
- return transformFn(point);
- };
- /**
- * Add transforms to and from EPSG:4326 and EPSG:3857. This function is called
- * by when this module is executed and should only need to be called again after
- * `ol.proj.clearAllProjections()` is called (e.g. in tests).
- */
- ol.proj.addCommon = function() {
- // Add transformations that don't alter coordinates to convert within set of
- // projections with equal meaning.
- ol.proj.addEquivalentProjections(ol.proj.EPSG3857.PROJECTIONS);
- ol.proj.addEquivalentProjections(ol.proj.EPSG4326.PROJECTIONS);
- // Add transformations to convert EPSG:4326 like coordinates to EPSG:3857 like
- // coordinates and back.
- ol.proj.addEquivalentTransforms(
- ol.proj.EPSG4326.PROJECTIONS,
- ol.proj.EPSG3857.PROJECTIONS,
- ol.proj.EPSG3857.fromEPSG4326,
- ol.proj.EPSG3857.toEPSG4326);
- };
- ol.proj.addCommon();
- goog.provide('ol.tilecoord');
- /**
- * @param {number} z Z.
- * @param {number} x X.
- * @param {number} y Y.
- * @param {ol.TileCoord=} opt_tileCoord Tile coordinate.
- * @return {ol.TileCoord} Tile coordinate.
- */
- ol.tilecoord.createOrUpdate = function(z, x, y, opt_tileCoord) {
- if (opt_tileCoord !== undefined) {
- opt_tileCoord[0] = z;
- opt_tileCoord[1] = x;
- opt_tileCoord[2] = y;
- return opt_tileCoord;
- } else {
- return [z, x, y];
- }
- };
- /**
- * @param {number} z Z.
- * @param {number} x X.
- * @param {number} y Y.
- * @return {string} Key.
- */
- ol.tilecoord.getKeyZXY = function(z, x, y) {
- return z + '/' + x + '/' + y;
- };
- /**
- * Get the key for a tile coord.
- * @param {ol.TileCoord} tileCoord The tile coord.
- * @return {string} Key.
- */
- ol.tilecoord.getKey = function(tileCoord) {
- return ol.tilecoord.getKeyZXY(tileCoord[0], tileCoord[1], tileCoord[2]);
- };
- /**
- * Get a tile coord given a key.
- * @param {string} key The tile coord key.
- * @return {ol.TileCoord} The tile coord.
- */
- ol.tilecoord.fromKey = function(key) {
- return key.split('/').map(Number);
- };
- /**
- * @param {ol.TileCoord} tileCoord Tile coord.
- * @return {number} Hash.
- */
- ol.tilecoord.hash = function(tileCoord) {
- return (tileCoord[1] << tileCoord[0]) + tileCoord[2];
- };
- /**
- * @param {ol.TileCoord} tileCoord Tile coord.
- * @return {string} Quad key.
- */
- ol.tilecoord.quadKey = function(tileCoord) {
- var z = tileCoord[0];
- var digits = new Array(z);
- var mask = 1 << (z - 1);
- var i, charCode;
- for (i = 0; i < z; ++i) {
- // 48 is charCode for 0 - '0'.charCodeAt(0)
- charCode = 48;
- if (tileCoord[1] & mask) {
- charCode += 1;
- }
- if (tileCoord[2] & mask) {
- charCode += 2;
- }
- digits[i] = String.fromCharCode(charCode);
- mask >>= 1;
- }
- return digits.join('');
- };
- /**
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {!ol.tilegrid.TileGrid} tileGrid Tile grid.
- * @return {boolean} Tile coordinate is within extent and zoom level range.
- */
- ol.tilecoord.withinExtentAndZ = function(tileCoord, tileGrid) {
- var z = tileCoord[0];
- var x = tileCoord[1];
- var y = tileCoord[2];
- if (tileGrid.getMinZoom() > z || z > tileGrid.getMaxZoom()) {
- return false;
- }
- var extent = tileGrid.getExtent();
- var tileRange;
- if (!extent) {
- tileRange = tileGrid.getFullTileRange(z);
- } else {
- tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
- }
- if (!tileRange) {
- return true;
- } else {
- return tileRange.containsXY(x, y);
- }
- };
- goog.provide('ol.tilegrid.TileGrid');
- goog.require('ol');
- goog.require('ol.asserts');
- goog.require('ol.TileRange');
- goog.require('ol.array');
- goog.require('ol.extent');
- goog.require('ol.math');
- goog.require('ol.size');
- goog.require('ol.tilecoord');
- /**
- * @classdesc
- * Base class for setting the grid pattern for sources accessing tiled-image
- * servers.
- *
- * @constructor
- * @param {olx.tilegrid.TileGridOptions} options Tile grid options.
- * @struct
- * @api
- */
- ol.tilegrid.TileGrid = function(options) {
- /**
- * @protected
- * @type {number}
- */
- this.minZoom = options.minZoom !== undefined ? options.minZoom : 0;
- /**
- * @private
- * @type {!Array.<number>}
- */
- this.resolutions_ = options.resolutions;
- ol.asserts.assert(ol.array.isSorted(this.resolutions_, function(a, b) {
- return b - a;
- }, true), 17); // `resolutions` must be sorted in descending order
- // check if we've got a consistent zoom factor and origin
- var zoomFactor;
- if (!options.origins) {
- for (var i = 0, ii = this.resolutions_.length - 1; i < ii; ++i) {
- if (!zoomFactor) {
- zoomFactor = this.resolutions_[i] / this.resolutions_[i + 1];
- } else {
- if (this.resolutions_[i] / this.resolutions_[i + 1] !== zoomFactor) {
- zoomFactor = undefined;
- break;
- }
- }
- }
- }
- /**
- * @private
- * @type {number|undefined}
- */
- this.zoomFactor_ = zoomFactor;
- /**
- * @protected
- * @type {number}
- */
- this.maxZoom = this.resolutions_.length - 1;
- /**
- * @private
- * @type {ol.Coordinate}
- */
- this.origin_ = options.origin !== undefined ? options.origin : null;
- /**
- * @private
- * @type {Array.<ol.Coordinate>}
- */
- this.origins_ = null;
- if (options.origins !== undefined) {
- this.origins_ = options.origins;
- ol.asserts.assert(this.origins_.length == this.resolutions_.length,
- 20); // Number of `origins` and `resolutions` must be equal
- }
- var extent = options.extent;
- if (extent !== undefined &&
- !this.origin_ && !this.origins_) {
- this.origin_ = ol.extent.getTopLeft(extent);
- }
- ol.asserts.assert(
- (!this.origin_ && this.origins_) || (this.origin_ && !this.origins_),
- 18); // Either `origin` or `origins` must be configured, never both
- /**
- * @private
- * @type {Array.<number|ol.Size>}
- */
- this.tileSizes_ = null;
- if (options.tileSizes !== undefined) {
- this.tileSizes_ = options.tileSizes;
- ol.asserts.assert(this.tileSizes_.length == this.resolutions_.length,
- 19); // Number of `tileSizes` and `resolutions` must be equal
- }
- /**
- * @private
- * @type {number|ol.Size}
- */
- this.tileSize_ = options.tileSize !== undefined ?
- options.tileSize :
- !this.tileSizes_ ? ol.DEFAULT_TILE_SIZE : null;
- ol.asserts.assert(
- (!this.tileSize_ && this.tileSizes_) ||
- (this.tileSize_ && !this.tileSizes_),
- 22); // Either `tileSize` or `tileSizes` must be configured, never both
- /**
- * @private
- * @type {ol.Extent}
- */
- this.extent_ = extent !== undefined ? extent : null;
- /**
- * @private
- * @type {Array.<ol.TileRange>}
- */
- this.fullTileRanges_ = null;
- /**
- * @private
- * @type {ol.Size}
- */
- this.tmpSize_ = [0, 0];
- if (options.sizes !== undefined) {
- this.fullTileRanges_ = options.sizes.map(function(size, z) {
- var tileRange = new ol.TileRange(
- Math.min(0, size[0]), Math.max(size[0] - 1, -1),
- Math.min(0, size[1]), Math.max(size[1] - 1, -1));
- return tileRange;
- }, this);
- } else if (extent) {
- this.calculateTileRanges_(extent);
- }
- };
- /**
- * @private
- * @type {ol.TileCoord}
- */
- ol.tilegrid.TileGrid.tmpTileCoord_ = [0, 0, 0];
- /**
- * Call a function with each tile coordinate for a given extent and zoom level.
- *
- * @param {ol.Extent} extent Extent.
- * @param {number} zoom Integer zoom level.
- * @param {function(ol.TileCoord)} callback Function called with each tile coordinate.
- * @api
- */
- ol.tilegrid.TileGrid.prototype.forEachTileCoord = function(extent, zoom, callback) {
- var tileRange = this.getTileRangeForExtentAndZ(extent, zoom);
- for (var i = tileRange.minX, ii = tileRange.maxX; i <= ii; ++i) {
- for (var j = tileRange.minY, jj = tileRange.maxY; j <= jj; ++j) {
- callback([zoom, i, j]);
- }
- }
- };
- /**
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {function(this: T, number, ol.TileRange): boolean} callback Callback.
- * @param {T=} opt_this The object to use as `this` in `callback`.
- * @param {ol.TileRange=} opt_tileRange Temporary ol.TileRange object.
- * @param {ol.Extent=} opt_extent Temporary ol.Extent object.
- * @return {boolean} Callback succeeded.
- * @template T
- */
- ol.tilegrid.TileGrid.prototype.forEachTileCoordParentTileRange = function(tileCoord, callback, opt_this, opt_tileRange, opt_extent) {
- var tileRange, x, y;
- var tileCoordExtent = null;
- var z = tileCoord[0] - 1;
- if (this.zoomFactor_ === 2) {
- x = tileCoord[1];
- y = tileCoord[2];
- } else {
- tileCoordExtent = this.getTileCoordExtent(tileCoord, opt_extent);
- }
- while (z >= this.minZoom) {
- if (this.zoomFactor_ === 2) {
- x = Math.floor(x / 2);
- y = Math.floor(y / 2);
- tileRange = ol.TileRange.createOrUpdate(x, x, y, y, opt_tileRange);
- } else {
- tileRange = this.getTileRangeForExtentAndZ(tileCoordExtent, z, opt_tileRange);
- }
- if (callback.call(opt_this, z, tileRange)) {
- return true;
- }
- --z;
- }
- return false;
- };
- /**
- * Get the extent for this tile grid, if it was configured.
- * @return {ol.Extent} Extent.
- */
- ol.tilegrid.TileGrid.prototype.getExtent = function() {
- return this.extent_;
- };
- /**
- * Get the maximum zoom level for the grid.
- * @return {number} Max zoom.
- * @api
- */
- ol.tilegrid.TileGrid.prototype.getMaxZoom = function() {
- return this.maxZoom;
- };
- /**
- * Get the minimum zoom level for the grid.
- * @return {number} Min zoom.
- * @api
- */
- ol.tilegrid.TileGrid.prototype.getMinZoom = function() {
- return this.minZoom;
- };
- /**
- * Get the origin for the grid at the given zoom level.
- * @param {number} z Integer zoom level.
- * @return {ol.Coordinate} Origin.
- * @api
- */
- ol.tilegrid.TileGrid.prototype.getOrigin = function(z) {
- if (this.origin_) {
- return this.origin_;
- } else {
- return this.origins_[z];
- }
- };
- /**
- * Get the resolution for the given zoom level.
- * @param {number} z Integer zoom level.
- * @return {number} Resolution.
- * @api
- */
- ol.tilegrid.TileGrid.prototype.getResolution = function(z) {
- return this.resolutions_[z];
- };
- /**
- * Get the list of resolutions for the tile grid.
- * @return {Array.<number>} Resolutions.
- * @api
- */
- ol.tilegrid.TileGrid.prototype.getResolutions = function() {
- return this.resolutions_;
- };
- /**
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {ol.TileRange=} opt_tileRange Temporary ol.TileRange object.
- * @param {ol.Extent=} opt_extent Temporary ol.Extent object.
- * @return {ol.TileRange} Tile range.
- */
- ol.tilegrid.TileGrid.prototype.getTileCoordChildTileRange = function(tileCoord, opt_tileRange, opt_extent) {
- if (tileCoord[0] < this.maxZoom) {
- if (this.zoomFactor_ === 2) {
- var minX = tileCoord[1] * 2;
- var minY = tileCoord[2] * 2;
- return ol.TileRange.createOrUpdate(minX, minX + 1, minY, minY + 1, opt_tileRange);
- }
- var tileCoordExtent = this.getTileCoordExtent(tileCoord, opt_extent);
- return this.getTileRangeForExtentAndZ(
- tileCoordExtent, tileCoord[0] + 1, opt_tileRange);
- }
- return null;
- };
- /**
- * Get the extent for a tile range.
- * @param {number} z Integer zoom level.
- * @param {ol.TileRange} tileRange Tile range.
- * @param {ol.Extent=} opt_extent Temporary ol.Extent object.
- * @return {ol.Extent} Extent.
- */
- ol.tilegrid.TileGrid.prototype.getTileRangeExtent = function(z, tileRange, opt_extent) {
- var origin = this.getOrigin(z);
- var resolution = this.getResolution(z);
- var tileSize = ol.size.toSize(this.getTileSize(z), this.tmpSize_);
- var minX = origin[0] + tileRange.minX * tileSize[0] * resolution;
- var maxX = origin[0] + (tileRange.maxX + 1) * tileSize[0] * resolution;
- var minY = origin[1] + tileRange.minY * tileSize[1] * resolution;
- var maxY = origin[1] + (tileRange.maxY + 1) * tileSize[1] * resolution;
- return ol.extent.createOrUpdate(minX, minY, maxX, maxY, opt_extent);
- };
- /**
- * Get a tile range for the given extent and integer zoom level.
- * @param {ol.Extent} extent Extent.
- * @param {number} z Integer zoom level.
- * @param {ol.TileRange=} opt_tileRange Temporary tile range object.
- * @return {ol.TileRange} Tile range.
- */
- ol.tilegrid.TileGrid.prototype.getTileRangeForExtentAndZ = function(extent, z, opt_tileRange) {
- var tileCoord = ol.tilegrid.TileGrid.tmpTileCoord_;
- this.getTileCoordForXYAndZ_(extent[0], extent[1], z, false, tileCoord);
- var minX = tileCoord[1];
- var minY = tileCoord[2];
- this.getTileCoordForXYAndZ_(extent[2], extent[3], z, true, tileCoord);
- return ol.TileRange.createOrUpdate(
- minX, tileCoord[1], minY, tileCoord[2], opt_tileRange);
- };
- /**
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @return {ol.Coordinate} Tile center.
- */
- ol.tilegrid.TileGrid.prototype.getTileCoordCenter = function(tileCoord) {
- var origin = this.getOrigin(tileCoord[0]);
- var resolution = this.getResolution(tileCoord[0]);
- var tileSize = ol.size.toSize(this.getTileSize(tileCoord[0]), this.tmpSize_);
- return [
- origin[0] + (tileCoord[1] + 0.5) * tileSize[0] * resolution,
- origin[1] + (tileCoord[2] + 0.5) * tileSize[1] * resolution
- ];
- };
- /**
- * Get the extent of a tile coordinate.
- *
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {ol.Extent=} opt_extent Temporary extent object.
- * @return {ol.Extent} Extent.
- * @api
- */
- ol.tilegrid.TileGrid.prototype.getTileCoordExtent = function(tileCoord, opt_extent) {
- var origin = this.getOrigin(tileCoord[0]);
- var resolution = this.getResolution(tileCoord[0]);
- var tileSize = ol.size.toSize(this.getTileSize(tileCoord[0]), this.tmpSize_);
- var minX = origin[0] + tileCoord[1] * tileSize[0] * resolution;
- var minY = origin[1] + tileCoord[2] * tileSize[1] * resolution;
- var maxX = minX + tileSize[0] * resolution;
- var maxY = minY + tileSize[1] * resolution;
- return ol.extent.createOrUpdate(minX, minY, maxX, maxY, opt_extent);
- };
- /**
- * Get the tile coordinate for the given map coordinate and resolution. This
- * method considers that coordinates that intersect tile boundaries should be
- * assigned the higher tile coordinate.
- *
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {number} resolution Resolution.
- * @param {ol.TileCoord=} opt_tileCoord Destination ol.TileCoord object.
- * @return {ol.TileCoord} Tile coordinate.
- * @api
- */
- ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndResolution = function(coordinate, resolution, opt_tileCoord) {
- return this.getTileCoordForXYAndResolution_(
- coordinate[0], coordinate[1], resolution, false, opt_tileCoord);
- };
- /**
- * Note that this method should not be called for resolutions that correspond
- * to an integer zoom level. Instead call the `getTileCoordForXYAndZ_` method.
- * @param {number} x X.
- * @param {number} y Y.
- * @param {number} resolution Resolution (for a non-integer zoom level).
- * @param {boolean} reverseIntersectionPolicy Instead of letting edge
- * intersections go to the higher tile coordinate, let edge intersections
- * go to the lower tile coordinate.
- * @param {ol.TileCoord=} opt_tileCoord Temporary ol.TileCoord object.
- * @return {ol.TileCoord} Tile coordinate.
- * @private
- */
- ol.tilegrid.TileGrid.prototype.getTileCoordForXYAndResolution_ = function(
- x, y, resolution, reverseIntersectionPolicy, opt_tileCoord) {
- var z = this.getZForResolution(resolution);
- var scale = resolution / this.getResolution(z);
- var origin = this.getOrigin(z);
- var tileSize = ol.size.toSize(this.getTileSize(z), this.tmpSize_);
- var adjustX = reverseIntersectionPolicy ? 0.5 : 0;
- var adjustY = reverseIntersectionPolicy ? 0 : 0.5;
- var xFromOrigin = Math.floor((x - origin[0]) / resolution + adjustX);
- var yFromOrigin = Math.floor((y - origin[1]) / resolution + adjustY);
- var tileCoordX = scale * xFromOrigin / tileSize[0];
- var tileCoordY = scale * yFromOrigin / tileSize[1];
- if (reverseIntersectionPolicy) {
- tileCoordX = Math.ceil(tileCoordX) - 1;
- tileCoordY = Math.ceil(tileCoordY) - 1;
- } else {
- tileCoordX = Math.floor(tileCoordX);
- tileCoordY = Math.floor(tileCoordY);
- }
- return ol.tilecoord.createOrUpdate(z, tileCoordX, tileCoordY, opt_tileCoord);
- };
- /**
- * Although there is repetition between this method and `getTileCoordForXYAndResolution_`,
- * they should have separate implementations. This method is for integer zoom
- * levels. The other method should only be called for resolutions corresponding
- * to non-integer zoom levels.
- * @param {number} x Map x coordinate.
- * @param {number} y Map y coordinate.
- * @param {number} z Integer zoom level.
- * @param {boolean} reverseIntersectionPolicy Instead of letting edge
- * intersections go to the higher tile coordinate, let edge intersections
- * go to the lower tile coordinate.
- * @param {ol.TileCoord=} opt_tileCoord Temporary ol.TileCoord object.
- * @return {ol.TileCoord} Tile coordinate.
- * @private
- */
- ol.tilegrid.TileGrid.prototype.getTileCoordForXYAndZ_ = function(x, y, z, reverseIntersectionPolicy, opt_tileCoord) {
- var origin = this.getOrigin(z);
- var resolution = this.getResolution(z);
- var tileSize = ol.size.toSize(this.getTileSize(z), this.tmpSize_);
- var adjustX = reverseIntersectionPolicy ? 0.5 : 0;
- var adjustY = reverseIntersectionPolicy ? 0 : 0.5;
- var xFromOrigin = Math.floor((x - origin[0]) / resolution + adjustX);
- var yFromOrigin = Math.floor((y - origin[1]) / resolution + adjustY);
- var tileCoordX = xFromOrigin / tileSize[0];
- var tileCoordY = yFromOrigin / tileSize[1];
- if (reverseIntersectionPolicy) {
- tileCoordX = Math.ceil(tileCoordX) - 1;
- tileCoordY = Math.ceil(tileCoordY) - 1;
- } else {
- tileCoordX = Math.floor(tileCoordX);
- tileCoordY = Math.floor(tileCoordY);
- }
- return ol.tilecoord.createOrUpdate(z, tileCoordX, tileCoordY, opt_tileCoord);
- };
- /**
- * Get a tile coordinate given a map coordinate and zoom level.
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {number} z Zoom level.
- * @param {ol.TileCoord=} opt_tileCoord Destination ol.TileCoord object.
- * @return {ol.TileCoord} Tile coordinate.
- * @api
- */
- ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndZ = function(coordinate, z, opt_tileCoord) {
- return this.getTileCoordForXYAndZ_(
- coordinate[0], coordinate[1], z, false, opt_tileCoord);
- };
- /**
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @return {number} Tile resolution.
- */
- ol.tilegrid.TileGrid.prototype.getTileCoordResolution = function(tileCoord) {
- return this.resolutions_[tileCoord[0]];
- };
- /**
- * Get the tile size for a zoom level. The type of the return value matches the
- * `tileSize` or `tileSizes` that the tile grid was configured with. To always
- * get an `ol.Size`, run the result through `ol.size.toSize()`.
- * @param {number} z Z.
- * @return {number|ol.Size} Tile size.
- * @api
- */
- ol.tilegrid.TileGrid.prototype.getTileSize = function(z) {
- if (this.tileSize_) {
- return this.tileSize_;
- } else {
- return this.tileSizes_[z];
- }
- };
- /**
- * @param {number} z Zoom level.
- * @return {ol.TileRange} Extent tile range for the specified zoom level.
- */
- ol.tilegrid.TileGrid.prototype.getFullTileRange = function(z) {
- if (!this.fullTileRanges_) {
- return null;
- } else {
- return this.fullTileRanges_[z];
- }
- };
- /**
- * @param {number} resolution Resolution.
- * @param {number=} opt_direction If 0, the nearest resolution will be used.
- * If 1, the nearest lower resolution will be used. If -1, the nearest
- * higher resolution will be used. Default is 0.
- * @return {number} Z.
- * @api
- */
- ol.tilegrid.TileGrid.prototype.getZForResolution = function(
- resolution, opt_direction) {
- var z = ol.array.linearFindNearest(this.resolutions_, resolution,
- opt_direction || 0);
- return ol.math.clamp(z, this.minZoom, this.maxZoom);
- };
- /**
- * @param {!ol.Extent} extent Extent for this tile grid.
- * @private
- */
- ol.tilegrid.TileGrid.prototype.calculateTileRanges_ = function(extent) {
- var length = this.resolutions_.length;
- var fullTileRanges = new Array(length);
- for (var z = this.minZoom; z < length; ++z) {
- fullTileRanges[z] = this.getTileRangeForExtentAndZ(extent, z);
- }
- this.fullTileRanges_ = fullTileRanges;
- };
- goog.provide('ol.tilegrid');
- goog.require('ol');
- goog.require('ol.size');
- goog.require('ol.extent');
- goog.require('ol.extent.Corner');
- goog.require('ol.obj');
- goog.require('ol.proj');
- goog.require('ol.proj.Units');
- goog.require('ol.tilegrid.TileGrid');
- /**
- * @param {ol.proj.Projection} projection Projection.
- * @return {!ol.tilegrid.TileGrid} Default tile grid for the passed projection.
- */
- ol.tilegrid.getForProjection = function(projection) {
- var tileGrid = projection.getDefaultTileGrid();
- if (!tileGrid) {
- tileGrid = ol.tilegrid.createForProjection(projection);
- projection.setDefaultTileGrid(tileGrid);
- }
- return tileGrid;
- };
- /**
- * @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {ol.proj.Projection} projection Projection.
- * @return {ol.TileCoord} Tile coordinate.
- */
- ol.tilegrid.wrapX = function(tileGrid, tileCoord, projection) {
- var z = tileCoord[0];
- var center = tileGrid.getTileCoordCenter(tileCoord);
- var projectionExtent = ol.tilegrid.extentFromProjection(projection);
- if (!ol.extent.containsCoordinate(projectionExtent, center)) {
- var worldWidth = ol.extent.getWidth(projectionExtent);
- var worldsAway = Math.ceil((projectionExtent[0] - center[0]) / worldWidth);
- center[0] += worldWidth * worldsAway;
- return tileGrid.getTileCoordForCoordAndZ(center, z);
- } else {
- return tileCoord;
- }
- };
- /**
- * @param {ol.Extent} extent Extent.
- * @param {number=} opt_maxZoom Maximum zoom level (default is
- * ol.DEFAULT_MAX_ZOOM).
- * @param {number|ol.Size=} opt_tileSize Tile size (default uses
- * ol.DEFAULT_TILE_SIZE).
- * @param {ol.extent.Corner=} opt_corner Extent corner (default is
- * ol.extent.Corner.TOP_LEFT).
- * @return {!ol.tilegrid.TileGrid} TileGrid instance.
- */
- ol.tilegrid.createForExtent = function(extent, opt_maxZoom, opt_tileSize, opt_corner) {
- var corner = opt_corner !== undefined ?
- opt_corner : ol.extent.Corner.TOP_LEFT;
- var resolutions = ol.tilegrid.resolutionsFromExtent(
- extent, opt_maxZoom, opt_tileSize);
- return new ol.tilegrid.TileGrid({
- extent: extent,
- origin: ol.extent.getCorner(extent, corner),
- resolutions: resolutions,
- tileSize: opt_tileSize
- });
- };
- /**
- * Creates a tile grid with a standard XYZ tiling scheme.
- * @param {olx.tilegrid.XYZOptions=} opt_options Tile grid options.
- * @return {!ol.tilegrid.TileGrid} Tile grid instance.
- * @api
- */
- ol.tilegrid.createXYZ = function(opt_options) {
- var options = /** @type {olx.tilegrid.TileGridOptions} */ ({});
- ol.obj.assign(options, opt_options !== undefined ?
- opt_options : /** @type {olx.tilegrid.XYZOptions} */ ({}));
- if (options.extent === undefined) {
- options.extent = ol.proj.get('EPSG:3857').getExtent();
- }
- options.resolutions = ol.tilegrid.resolutionsFromExtent(
- options.extent, options.maxZoom, options.tileSize);
- delete options.maxZoom;
- return new ol.tilegrid.TileGrid(options);
- };
- /**
- * Create a resolutions array from an extent. A zoom factor of 2 is assumed.
- * @param {ol.Extent} extent Extent.
- * @param {number=} opt_maxZoom Maximum zoom level (default is
- * ol.DEFAULT_MAX_ZOOM).
- * @param {number|ol.Size=} opt_tileSize Tile size (default uses
- * ol.DEFAULT_TILE_SIZE).
- * @return {!Array.<number>} Resolutions array.
- */
- ol.tilegrid.resolutionsFromExtent = function(extent, opt_maxZoom, opt_tileSize) {
- var maxZoom = opt_maxZoom !== undefined ?
- opt_maxZoom : ol.DEFAULT_MAX_ZOOM;
- var height = ol.extent.getHeight(extent);
- var width = ol.extent.getWidth(extent);
- var tileSize = ol.size.toSize(opt_tileSize !== undefined ?
- opt_tileSize : ol.DEFAULT_TILE_SIZE);
- var maxResolution = Math.max(
- width / tileSize[0], height / tileSize[1]);
- var length = maxZoom + 1;
- var resolutions = new Array(length);
- for (var z = 0; z < length; ++z) {
- resolutions[z] = maxResolution / Math.pow(2, z);
- }
- return resolutions;
- };
- /**
- * @param {ol.ProjectionLike} projection Projection.
- * @param {number=} opt_maxZoom Maximum zoom level (default is
- * ol.DEFAULT_MAX_ZOOM).
- * @param {number|ol.Size=} opt_tileSize Tile size (default uses
- * ol.DEFAULT_TILE_SIZE).
- * @param {ol.extent.Corner=} opt_corner Extent corner (default is
- * ol.extent.Corner.BOTTOM_LEFT).
- * @return {!ol.tilegrid.TileGrid} TileGrid instance.
- */
- ol.tilegrid.createForProjection = function(projection, opt_maxZoom, opt_tileSize, opt_corner) {
- var extent = ol.tilegrid.extentFromProjection(projection);
- return ol.tilegrid.createForExtent(
- extent, opt_maxZoom, opt_tileSize, opt_corner);
- };
- /**
- * Generate a tile grid extent from a projection. If the projection has an
- * extent, it is used. If not, a global extent is assumed.
- * @param {ol.ProjectionLike} projection Projection.
- * @return {ol.Extent} Extent.
- */
- ol.tilegrid.extentFromProjection = function(projection) {
- projection = ol.proj.get(projection);
- var extent = projection.getExtent();
- if (!extent) {
- var half = 180 * ol.proj.METERS_PER_UNIT[ol.proj.Units.DEGREES] /
- projection.getMetersPerUnit();
- extent = ol.extent.createOrUpdate(-half, -half, half, half);
- }
- return extent;
- };
- goog.provide('ol.Attribution');
- goog.require('ol.TileRange');
- goog.require('ol.math');
- goog.require('ol.tilegrid');
- /**
- * @classdesc
- * An attribution for a layer source.
- *
- * Example:
- *
- * source: new ol.source.OSM({
- * attributions: [
- * new ol.Attribution({
- * html: 'All maps © ' +
- * '<a href="https://www.opencyclemap.org/">OpenCycleMap</a>'
- * }),
- * ol.source.OSM.ATTRIBUTION
- * ],
- * ..
- *
- * @constructor
- * @deprecated This class is deprecated and will removed in the next major release.
- * @param {olx.AttributionOptions} options Attribution options.
- * @struct
- * @api
- */
- ol.Attribution = function(options) {
- /**
- * @private
- * @type {string}
- */
- this.html_ = options.html;
- /**
- * @private
- * @type {Object.<string, Array.<ol.TileRange>>}
- */
- this.tileRanges_ = options.tileRanges ? options.tileRanges : null;
- };
- /**
- * Get the attribution markup.
- * @return {string} The attribution HTML.
- * @api
- */
- ol.Attribution.prototype.getHTML = function() {
- return this.html_;
- };
- /**
- * @param {Object.<string, ol.TileRange>} tileRanges Tile ranges.
- * @param {!ol.tilegrid.TileGrid} tileGrid Tile grid.
- * @param {!ol.proj.Projection} projection Projection.
- * @return {boolean} Intersects any tile range.
- */
- ol.Attribution.prototype.intersectsAnyTileRange = function(tileRanges, tileGrid, projection) {
- if (!this.tileRanges_) {
- return true;
- }
- var i, ii, tileRange, zKey;
- for (zKey in tileRanges) {
- if (!(zKey in this.tileRanges_)) {
- continue;
- }
- tileRange = tileRanges[zKey];
- var testTileRange;
- for (i = 0, ii = this.tileRanges_[zKey].length; i < ii; ++i) {
- testTileRange = this.tileRanges_[zKey][i];
- if (testTileRange.intersects(tileRange)) {
- return true;
- }
- var extentTileRange = tileGrid.getTileRangeForExtentAndZ(
- ol.tilegrid.extentFromProjection(projection), parseInt(zKey, 10));
- var width = extentTileRange.getWidth();
- if (tileRange.minX < extentTileRange.minX ||
- tileRange.maxX > extentTileRange.maxX) {
- if (testTileRange.intersects(new ol.TileRange(
- ol.math.modulo(tileRange.minX, width),
- ol.math.modulo(tileRange.maxX, width),
- tileRange.minY, tileRange.maxY))) {
- return true;
- }
- if (tileRange.getWidth() > width &&
- testTileRange.intersects(extentTileRange)) {
- return true;
- }
- }
- }
- }
- return false;
- };
- goog.provide('ol.CollectionEventType');
- /**
- * @enum {string}
- */
- ol.CollectionEventType = {
- /**
- * Triggered when an item is added to the collection.
- * @event ol.Collection.Event#add
- * @api
- */
- ADD: 'add',
- /**
- * Triggered when an item is removed from the collection.
- * @event ol.Collection.Event#remove
- * @api
- */
- REMOVE: 'remove'
- };
- goog.provide('ol.ObjectEventType');
- /**
- * @enum {string}
- */
- ol.ObjectEventType = {
- /**
- * Triggered when a property is changed.
- * @event ol.Object.Event#propertychange
- * @api
- */
- PROPERTYCHANGE: 'propertychange'
- };
- goog.provide('ol.events');
- goog.require('ol.obj');
- /**
- * @param {ol.EventsKey} listenerObj Listener object.
- * @return {ol.EventsListenerFunctionType} Bound listener.
- */
- ol.events.bindListener_ = function(listenerObj) {
- var boundListener = function(evt) {
- var listener = listenerObj.listener;
- var bindTo = listenerObj.bindTo || listenerObj.target;
- if (listenerObj.callOnce) {
- ol.events.unlistenByKey(listenerObj);
- }
- return listener.call(bindTo, evt);
- };
- listenerObj.boundListener = boundListener;
- return boundListener;
- };
- /**
- * Finds the matching {@link ol.EventsKey} in the given listener
- * array.
- *
- * @param {!Array<!ol.EventsKey>} listeners Array of listeners.
- * @param {!Function} listener The listener function.
- * @param {Object=} opt_this The `this` value inside the listener.
- * @param {boolean=} opt_setDeleteIndex Set the deleteIndex on the matching
- * listener, for {@link ol.events.unlistenByKey}.
- * @return {ol.EventsKey|undefined} The matching listener object.
- * @private
- */
- ol.events.findListener_ = function(listeners, listener, opt_this,
- opt_setDeleteIndex) {
- var listenerObj;
- for (var i = 0, ii = listeners.length; i < ii; ++i) {
- listenerObj = listeners[i];
- if (listenerObj.listener === listener &&
- listenerObj.bindTo === opt_this) {
- if (opt_setDeleteIndex) {
- listenerObj.deleteIndex = i;
- }
- return listenerObj;
- }
- }
- return undefined;
- };
- /**
- * @param {ol.EventTargetLike} target Target.
- * @param {string} type Type.
- * @return {Array.<ol.EventsKey>|undefined} Listeners.
- */
- ol.events.getListeners = function(target, type) {
- var listenerMap = target.ol_lm;
- return listenerMap ? listenerMap[type] : undefined;
- };
- /**
- * Get the lookup of listeners. If one does not exist on the target, it is
- * created.
- * @param {ol.EventTargetLike} target Target.
- * @return {!Object.<string, Array.<ol.EventsKey>>} Map of
- * listeners by event type.
- * @private
- */
- ol.events.getListenerMap_ = function(target) {
- var listenerMap = target.ol_lm;
- if (!listenerMap) {
- listenerMap = target.ol_lm = {};
- }
- return listenerMap;
- };
- /**
- * Clean up all listener objects of the given type. All properties on the
- * listener objects will be removed, and if no listeners remain in the listener
- * map, it will be removed from the target.
- * @param {ol.EventTargetLike} target Target.
- * @param {string} type Type.
- * @private
- */
- ol.events.removeListeners_ = function(target, type) {
- var listeners = ol.events.getListeners(target, type);
- if (listeners) {
- for (var i = 0, ii = listeners.length; i < ii; ++i) {
- target.removeEventListener(type, listeners[i].boundListener);
- ol.obj.clear(listeners[i]);
- }
- listeners.length = 0;
- var listenerMap = target.ol_lm;
- if (listenerMap) {
- delete listenerMap[type];
- if (Object.keys(listenerMap).length === 0) {
- delete target.ol_lm;
- }
- }
- }
- };
- /**
- * Registers an event listener on an event target. Inspired by
- * {@link https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html}
- *
- * This function efficiently binds a `listener` to a `this` object, and returns
- * a key for use with {@link ol.events.unlistenByKey}.
- *
- * @param {ol.EventTargetLike} target Event target.
- * @param {string} type Event type.
- * @param {ol.EventsListenerFunctionType} listener Listener.
- * @param {Object=} opt_this Object referenced by the `this` keyword in the
- * listener. Default is the `target`.
- * @param {boolean=} opt_once If true, add the listener as one-off listener.
- * @return {ol.EventsKey} Unique key for the listener.
- */
- ol.events.listen = function(target, type, listener, opt_this, opt_once) {
- var listenerMap = ol.events.getListenerMap_(target);
- var listeners = listenerMap[type];
- if (!listeners) {
- listeners = listenerMap[type] = [];
- }
- var listenerObj = ol.events.findListener_(listeners, listener, opt_this,
- false);
- if (listenerObj) {
- if (!opt_once) {
- // Turn one-off listener into a permanent one.
- listenerObj.callOnce = false;
- }
- } else {
- listenerObj = /** @type {ol.EventsKey} */ ({
- bindTo: opt_this,
- callOnce: !!opt_once,
- listener: listener,
- target: target,
- type: type
- });
- target.addEventListener(type, ol.events.bindListener_(listenerObj));
- listeners.push(listenerObj);
- }
- return listenerObj;
- };
- /**
- * Registers a one-off event listener on an event target. Inspired by
- * {@link https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html}
- *
- * This function efficiently binds a `listener` as self-unregistering listener
- * to a `this` object, and returns a key for use with
- * {@link ol.events.unlistenByKey} in case the listener needs to be unregistered
- * before it is called.
- *
- * When {@link ol.events.listen} is called with the same arguments after this
- * function, the self-unregistering listener will be turned into a permanent
- * listener.
- *
- * @param {ol.EventTargetLike} target Event target.
- * @param {string} type Event type.
- * @param {ol.EventsListenerFunctionType} listener Listener.
- * @param {Object=} opt_this Object referenced by the `this` keyword in the
- * listener. Default is the `target`.
- * @return {ol.EventsKey} Key for unlistenByKey.
- */
- ol.events.listenOnce = function(target, type, listener, opt_this) {
- return ol.events.listen(target, type, listener, opt_this, true);
- };
- /**
- * Unregisters an event listener on an event target. Inspired by
- * {@link https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html}
- *
- * To return a listener, this function needs to be called with the exact same
- * arguments that were used for a previous {@link ol.events.listen} call.
- *
- * @param {ol.EventTargetLike} target Event target.
- * @param {string} type Event type.
- * @param {ol.EventsListenerFunctionType} listener Listener.
- * @param {Object=} opt_this Object referenced by the `this` keyword in the
- * listener. Default is the `target`.
- */
- ol.events.unlisten = function(target, type, listener, opt_this) {
- var listeners = ol.events.getListeners(target, type);
- if (listeners) {
- var listenerObj = ol.events.findListener_(listeners, listener, opt_this,
- true);
- if (listenerObj) {
- ol.events.unlistenByKey(listenerObj);
- }
- }
- };
- /**
- * Unregisters event listeners on an event target. Inspired by
- * {@link https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html}
- *
- * The argument passed to this function is the key returned from
- * {@link ol.events.listen} or {@link ol.events.listenOnce}.
- *
- * @param {ol.EventsKey} key The key.
- */
- ol.events.unlistenByKey = function(key) {
- if (key && key.target) {
- key.target.removeEventListener(key.type, key.boundListener);
- var listeners = ol.events.getListeners(key.target, key.type);
- if (listeners) {
- var i = 'deleteIndex' in key ? key.deleteIndex : listeners.indexOf(key);
- if (i !== -1) {
- listeners.splice(i, 1);
- }
- if (listeners.length === 0) {
- ol.events.removeListeners_(key.target, key.type);
- }
- }
- ol.obj.clear(key);
- }
- };
- /**
- * Unregisters all event listeners on an event target. Inspired by
- * {@link https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html}
- *
- * @param {ol.EventTargetLike} target Target.
- */
- ol.events.unlistenAll = function(target) {
- var listenerMap = ol.events.getListenerMap_(target);
- for (var type in listenerMap) {
- ol.events.removeListeners_(target, type);
- }
- };
- goog.provide('ol.Disposable');
- goog.require('ol');
- /**
- * Objects that need to clean up after themselves.
- * @constructor
- */
- ol.Disposable = function() {};
- /**
- * The object has already been disposed.
- * @type {boolean}
- * @private
- */
- ol.Disposable.prototype.disposed_ = false;
- /**
- * Clean up.
- */
- ol.Disposable.prototype.dispose = function() {
- if (!this.disposed_) {
- this.disposed_ = true;
- this.disposeInternal();
- }
- };
- /**
- * Extension point for disposable objects.
- * @protected
- */
- ol.Disposable.prototype.disposeInternal = ol.nullFunction;
- goog.provide('ol.events.Event');
- /**
- * @classdesc
- * Stripped down implementation of the W3C DOM Level 2 Event interface.
- * @see {@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-interface}
- *
- * This implementation only provides `type` and `target` properties, and
- * `stopPropagation` and `preventDefault` methods. It is meant as base class
- * for higher level events defined in the library, and works with
- * {@link ol.events.EventTarget}.
- *
- * @constructor
- * @implements {oli.events.Event}
- * @param {string} type Type.
- */
- ol.events.Event = function(type) {
- /**
- * @type {boolean}
- */
- this.propagationStopped;
- /**
- * The event type.
- * @type {string}
- * @api
- */
- this.type = type;
- /**
- * The event target.
- * @type {Object}
- * @api
- */
- this.target = null;
- };
- /**
- * Stop event propagation.
- * @function
- * @override
- * @api
- */
- ol.events.Event.prototype.preventDefault =
- /**
- * Stop event propagation.
- * @function
- * @override
- * @api
- */
- ol.events.Event.prototype.stopPropagation = function() {
- this.propagationStopped = true;
- };
- /**
- * @param {Event|ol.events.Event} evt Event
- */
- ol.events.Event.stopPropagation = function(evt) {
- evt.stopPropagation();
- };
- /**
- * @param {Event|ol.events.Event} evt Event
- */
- ol.events.Event.preventDefault = function(evt) {
- evt.preventDefault();
- };
- goog.provide('ol.events.EventTarget');
- goog.require('ol');
- goog.require('ol.Disposable');
- goog.require('ol.events');
- goog.require('ol.events.Event');
- /**
- * @classdesc
- * A simplified implementation of the W3C DOM Level 2 EventTarget interface.
- * @see {@link https://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-EventTarget}
- *
- * There are two important simplifications compared to the specification:
- *
- * 1. The handling of `useCapture` in `addEventListener` and
- * `removeEventListener`. There is no real capture model.
- * 2. The handling of `stopPropagation` and `preventDefault` on `dispatchEvent`.
- * There is no event target hierarchy. When a listener calls
- * `stopPropagation` or `preventDefault` on an event object, it means that no
- * more listeners after this one will be called. Same as when the listener
- * returns false.
- *
- * @constructor
- * @extends {ol.Disposable}
- */
- ol.events.EventTarget = function() {
- ol.Disposable.call(this);
- /**
- * @private
- * @type {!Object.<string, number>}
- */
- this.pendingRemovals_ = {};
- /**
- * @private
- * @type {!Object.<string, number>}
- */
- this.dispatching_ = {};
- /**
- * @private
- * @type {!Object.<string, Array.<ol.EventsListenerFunctionType>>}
- */
- this.listeners_ = {};
- };
- ol.inherits(ol.events.EventTarget, ol.Disposable);
- /**
- * @param {string} type Type.
- * @param {ol.EventsListenerFunctionType} listener Listener.
- */
- ol.events.EventTarget.prototype.addEventListener = function(type, listener) {
- var listeners = this.listeners_[type];
- if (!listeners) {
- listeners = this.listeners_[type] = [];
- }
- if (listeners.indexOf(listener) === -1) {
- listeners.push(listener);
- }
- };
- /**
- * @param {{type: string,
- * target: (EventTarget|ol.events.EventTarget|undefined)}|ol.events.Event|
- * string} event Event or event type.
- * @return {boolean|undefined} `false` if anyone called preventDefault on the
- * event object or if any of the listeners returned false.
- */
- ol.events.EventTarget.prototype.dispatchEvent = function(event) {
- var evt = typeof event === 'string' ? new ol.events.Event(event) : event;
- var type = evt.type;
- evt.target = this;
- var listeners = this.listeners_[type];
- var propagate;
- if (listeners) {
- if (!(type in this.dispatching_)) {
- this.dispatching_[type] = 0;
- this.pendingRemovals_[type] = 0;
- }
- ++this.dispatching_[type];
- for (var i = 0, ii = listeners.length; i < ii; ++i) {
- if (listeners[i].call(this, evt) === false || evt.propagationStopped) {
- propagate = false;
- break;
- }
- }
- --this.dispatching_[type];
- if (this.dispatching_[type] === 0) {
- var pendingRemovals = this.pendingRemovals_[type];
- delete this.pendingRemovals_[type];
- while (pendingRemovals--) {
- this.removeEventListener(type, ol.nullFunction);
- }
- delete this.dispatching_[type];
- }
- return propagate;
- }
- };
- /**
- * @inheritDoc
- */
- ol.events.EventTarget.prototype.disposeInternal = function() {
- ol.events.unlistenAll(this);
- };
- /**
- * Get the listeners for a specified event type. Listeners are returned in the
- * order that they will be called in.
- *
- * @param {string} type Type.
- * @return {Array.<ol.EventsListenerFunctionType>} Listeners.
- */
- ol.events.EventTarget.prototype.getListeners = function(type) {
- return this.listeners_[type];
- };
- /**
- * @param {string=} opt_type Type. If not provided,
- * `true` will be returned if this EventTarget has any listeners.
- * @return {boolean} Has listeners.
- */
- ol.events.EventTarget.prototype.hasListener = function(opt_type) {
- return opt_type ?
- opt_type in this.listeners_ :
- Object.keys(this.listeners_).length > 0;
- };
- /**
- * @param {string} type Type.
- * @param {ol.EventsListenerFunctionType} listener Listener.
- */
- ol.events.EventTarget.prototype.removeEventListener = function(type, listener) {
- var listeners = this.listeners_[type];
- if (listeners) {
- var index = listeners.indexOf(listener);
- if (type in this.pendingRemovals_) {
- // make listener a no-op, and remove later in #dispatchEvent()
- listeners[index] = ol.nullFunction;
- ++this.pendingRemovals_[type];
- } else {
- listeners.splice(index, 1);
- if (listeners.length === 0) {
- delete this.listeners_[type];
- }
- }
- }
- };
- goog.provide('ol.events.EventType');
- /**
- * @enum {string}
- * @const
- */
- ol.events.EventType = {
- /**
- * Generic change event. Triggered when the revision counter is increased.
- * @event ol.events.Event#change
- * @api
- */
- CHANGE: 'change',
- CLEAR: 'clear',
- CLICK: 'click',
- DBLCLICK: 'dblclick',
- DRAGENTER: 'dragenter',
- DRAGOVER: 'dragover',
- DROP: 'drop',
- ERROR: 'error',
- KEYDOWN: 'keydown',
- KEYPRESS: 'keypress',
- LOAD: 'load',
- MOUSEDOWN: 'mousedown',
- MOUSEMOVE: 'mousemove',
- MOUSEOUT: 'mouseout',
- MOUSEUP: 'mouseup',
- MOUSEWHEEL: 'mousewheel',
- MSPOINTERDOWN: 'MSPointerDown',
- RESIZE: 'resize',
- TOUCHSTART: 'touchstart',
- TOUCHMOVE: 'touchmove',
- TOUCHEND: 'touchend',
- WHEEL: 'wheel'
- };
- goog.provide('ol.Observable');
- goog.require('ol');
- goog.require('ol.events');
- goog.require('ol.events.EventTarget');
- goog.require('ol.events.EventType');
- /**
- * @classdesc
- * Abstract base class; normally only used for creating subclasses and not
- * instantiated in apps.
- * An event target providing convenient methods for listener registration
- * and unregistration. A generic `change` event is always available through
- * {@link ol.Observable#changed}.
- *
- * @constructor
- * @extends {ol.events.EventTarget}
- * @fires ol.events.Event
- * @struct
- * @api
- */
- ol.Observable = function() {
- ol.events.EventTarget.call(this);
- /**
- * @private
- * @type {number}
- */
- this.revision_ = 0;
- };
- ol.inherits(ol.Observable, ol.events.EventTarget);
- /**
- * Removes an event listener using the key returned by `on()` or `once()`.
- * @param {ol.EventsKey|Array.<ol.EventsKey>} key The key returned by `on()`
- * or `once()` (or an array of keys).
- * @api
- */
- ol.Observable.unByKey = function(key) {
- if (Array.isArray(key)) {
- for (var i = 0, ii = key.length; i < ii; ++i) {
- ol.events.unlistenByKey(key[i]);
- }
- } else {
- ol.events.unlistenByKey(/** @type {ol.EventsKey} */ (key));
- }
- };
- /**
- * Increases the revision counter and dispatches a 'change' event.
- * @api
- */
- ol.Observable.prototype.changed = function() {
- ++this.revision_;
- this.dispatchEvent(ol.events.EventType.CHANGE);
- };
- /**
- * Dispatches an event and calls all listeners listening for events
- * of this type. The event parameter can either be a string or an
- * Object with a `type` property.
- *
- * @param {{type: string,
- * target: (EventTarget|ol.events.EventTarget|undefined)}|ol.events.Event|
- * string} event Event object.
- * @function
- * @api
- */
- ol.Observable.prototype.dispatchEvent;
- /**
- * Get the version number for this object. Each time the object is modified,
- * its version number will be incremented.
- * @return {number} Revision.
- * @api
- */
- ol.Observable.prototype.getRevision = function() {
- return this.revision_;
- };
- /**
- * Listen for a certain type of event.
- * @param {string|Array.<string>} type The event type or array of event types.
- * @param {function(?): ?} listener The listener function.
- * @param {Object=} opt_this The object to use as `this` in `listener`.
- * @return {ol.EventsKey|Array.<ol.EventsKey>} Unique key for the listener. If
- * called with an array of event types as the first argument, the return
- * will be an array of keys.
- * @api
- */
- ol.Observable.prototype.on = function(type, listener, opt_this) {
- if (Array.isArray(type)) {
- var len = type.length;
- var keys = new Array(len);
- for (var i = 0; i < len; ++i) {
- keys[i] = ol.events.listen(this, type[i], listener, opt_this);
- }
- return keys;
- } else {
- return ol.events.listen(
- this, /** @type {string} */ (type), listener, opt_this);
- }
- };
- /**
- * Listen once for a certain type of event.
- * @param {string|Array.<string>} type The event type or array of event types.
- * @param {function(?): ?} listener The listener function.
- * @param {Object=} opt_this The object to use as `this` in `listener`.
- * @return {ol.EventsKey|Array.<ol.EventsKey>} Unique key for the listener. If
- * called with an array of event types as the first argument, the return
- * will be an array of keys.
- * @api
- */
- ol.Observable.prototype.once = function(type, listener, opt_this) {
- if (Array.isArray(type)) {
- var len = type.length;
- var keys = new Array(len);
- for (var i = 0; i < len; ++i) {
- keys[i] = ol.events.listenOnce(this, type[i], listener, opt_this);
- }
- return keys;
- } else {
- return ol.events.listenOnce(
- this, /** @type {string} */ (type), listener, opt_this);
- }
- };
- /**
- * Unlisten for a certain type of event.
- * @param {string|Array.<string>} type The event type or array of event types.
- * @param {function(?): ?} listener The listener function.
- * @param {Object=} opt_this The object which was used as `this` by the
- * `listener`.
- * @api
- */
- ol.Observable.prototype.un = function(type, listener, opt_this) {
- if (Array.isArray(type)) {
- for (var i = 0, ii = type.length; i < ii; ++i) {
- ol.events.unlisten(this, type[i], listener, opt_this);
- }
- return;
- } else {
- ol.events.unlisten(this, /** @type {string} */ (type), listener, opt_this);
- }
- };
- goog.provide('ol.Object');
- goog.require('ol');
- goog.require('ol.ObjectEventType');
- goog.require('ol.Observable');
- goog.require('ol.events.Event');
- goog.require('ol.obj');
- /**
- * @classdesc
- * Abstract base class; normally only used for creating subclasses and not
- * instantiated in apps.
- * Most non-trivial classes inherit from this.
- *
- * This extends {@link ol.Observable} with observable properties, where each
- * property is observable as well as the object as a whole.
- *
- * Classes that inherit from this have pre-defined properties, to which you can
- * add your owns. The pre-defined properties are listed in this documentation as
- * 'Observable Properties', and have their own accessors; for example,
- * {@link ol.Map} has a `target` property, accessed with `getTarget()` and
- * changed with `setTarget()`. Not all properties are however settable. There
- * are also general-purpose accessors `get()` and `set()`. For example,
- * `get('target')` is equivalent to `getTarget()`.
- *
- * The `set` accessors trigger a change event, and you can monitor this by
- * registering a listener. For example, {@link ol.View} has a `center`
- * property, so `view.on('change:center', function(evt) {...});` would call the
- * function whenever the value of the center property changes. Within the
- * function, `evt.target` would be the view, so `evt.target.getCenter()` would
- * return the new center.
- *
- * You can add your own observable properties with
- * `object.set('prop', 'value')`, and retrieve that with `object.get('prop')`.
- * You can listen for changes on that property value with
- * `object.on('change:prop', listener)`. You can get a list of all
- * properties with {@link ol.Object#getProperties object.getProperties()}.
- *
- * Note that the observable properties are separate from standard JS properties.
- * You can, for example, give your map object a title with
- * `map.title='New title'` and with `map.set('title', 'Another title')`. The
- * first will be a `hasOwnProperty`; the second will appear in
- * `getProperties()`. Only the second is observable.
- *
- * Properties can be deleted by using the unset method. E.g.
- * object.unset('foo').
- *
- * @constructor
- * @extends {ol.Observable}
- * @param {Object.<string, *>=} opt_values An object with key-value pairs.
- * @fires ol.Object.Event
- * @api
- */
- ol.Object = function(opt_values) {
- ol.Observable.call(this);
- // Call ol.getUid to ensure that the order of objects' ids is the same as
- // the order in which they were created. This also helps to ensure that
- // object properties are always added in the same order, which helps many
- // JavaScript engines generate faster code.
- ol.getUid(this);
- /**
- * @private
- * @type {!Object.<string, *>}
- */
- this.values_ = {};
- if (opt_values !== undefined) {
- this.setProperties(opt_values);
- }
- };
- ol.inherits(ol.Object, ol.Observable);
- /**
- * @private
- * @type {Object.<string, string>}
- */
- ol.Object.changeEventTypeCache_ = {};
- /**
- * @param {string} key Key name.
- * @return {string} Change name.
- */
- ol.Object.getChangeEventType = function(key) {
- return ol.Object.changeEventTypeCache_.hasOwnProperty(key) ?
- ol.Object.changeEventTypeCache_[key] :
- (ol.Object.changeEventTypeCache_[key] = 'change:' + key);
- };
- /**
- * Gets a value.
- * @param {string} key Key name.
- * @return {*} Value.
- * @api
- */
- ol.Object.prototype.get = function(key) {
- var value;
- if (this.values_.hasOwnProperty(key)) {
- value = this.values_[key];
- }
- return value;
- };
- /**
- * Get a list of object property names.
- * @return {Array.<string>} List of property names.
- * @api
- */
- ol.Object.prototype.getKeys = function() {
- return Object.keys(this.values_);
- };
- /**
- * Get an object of all property names and values.
- * @return {Object.<string, *>} Object.
- * @api
- */
- ol.Object.prototype.getProperties = function() {
- return ol.obj.assign({}, this.values_);
- };
- /**
- * @param {string} key Key name.
- * @param {*} oldValue Old value.
- */
- ol.Object.prototype.notify = function(key, oldValue) {
- var eventType;
- eventType = ol.Object.getChangeEventType(key);
- this.dispatchEvent(new ol.Object.Event(eventType, key, oldValue));
- eventType = ol.ObjectEventType.PROPERTYCHANGE;
- this.dispatchEvent(new ol.Object.Event(eventType, key, oldValue));
- };
- /**
- * Sets a value.
- * @param {string} key Key name.
- * @param {*} value Value.
- * @param {boolean=} opt_silent Update without triggering an event.
- * @api
- */
- ol.Object.prototype.set = function(key, value, opt_silent) {
- if (opt_silent) {
- this.values_[key] = value;
- } else {
- var oldValue = this.values_[key];
- this.values_[key] = value;
- if (oldValue !== value) {
- this.notify(key, oldValue);
- }
- }
- };
- /**
- * Sets a collection of key-value pairs. Note that this changes any existing
- * properties and adds new ones (it does not remove any existing properties).
- * @param {Object.<string, *>} values Values.
- * @param {boolean=} opt_silent Update without triggering an event.
- * @api
- */
- ol.Object.prototype.setProperties = function(values, opt_silent) {
- var key;
- for (key in values) {
- this.set(key, values[key], opt_silent);
- }
- };
- /**
- * Unsets a property.
- * @param {string} key Key name.
- * @param {boolean=} opt_silent Unset without triggering an event.
- * @api
- */
- ol.Object.prototype.unset = function(key, opt_silent) {
- if (key in this.values_) {
- var oldValue = this.values_[key];
- delete this.values_[key];
- if (!opt_silent) {
- this.notify(key, oldValue);
- }
- }
- };
- /**
- * @classdesc
- * Events emitted by {@link ol.Object} instances are instances of this type.
- *
- * @param {string} type The event type.
- * @param {string} key The property name.
- * @param {*} oldValue The old value for `key`.
- * @extends {ol.events.Event}
- * @implements {oli.Object.Event}
- * @constructor
- */
- ol.Object.Event = function(type, key, oldValue) {
- ol.events.Event.call(this, type);
- /**
- * The name of the property whose value is changing.
- * @type {string}
- * @api
- */
- this.key = key;
- /**
- * The old value. To get the new value use `e.target.get(e.key)` where
- * `e` is the event object.
- * @type {*}
- * @api
- */
- this.oldValue = oldValue;
- };
- ol.inherits(ol.Object.Event, ol.events.Event);
- /**
- * An implementation of Google Maps' MVCArray.
- * @see https://developers.google.com/maps/documentation/javascript/reference
- */
- goog.provide('ol.Collection');
- goog.require('ol');
- goog.require('ol.AssertionError');
- goog.require('ol.CollectionEventType');
- goog.require('ol.Object');
- goog.require('ol.events.Event');
- /**
- * @classdesc
- * An expanded version of standard JS Array, adding convenience methods for
- * manipulation. Add and remove changes to the Collection trigger a Collection
- * event. Note that this does not cover changes to the objects _within_ the
- * Collection; they trigger events on the appropriate object, not on the
- * Collection as a whole.
- *
- * @constructor
- * @extends {ol.Object}
- * @fires ol.Collection.Event
- * @param {Array.<T>=} opt_array Array.
- * @param {olx.CollectionOptions=} opt_options Collection options.
- * @template T
- * @api
- */
- ol.Collection = function(opt_array, opt_options) {
- ol.Object.call(this);
- var options = opt_options || {};
- /**
- * @private
- * @type {boolean}
- */
- this.unique_ = !!options.unique;
- /**
- * @private
- * @type {!Array.<T>}
- */
- this.array_ = opt_array ? opt_array : [];
- if (this.unique_) {
- for (var i = 0, ii = this.array_.length; i < ii; ++i) {
- this.assertUnique_(this.array_[i], i);
- }
- }
- this.updateLength_();
- };
- ol.inherits(ol.Collection, ol.Object);
- /**
- * Remove all elements from the collection.
- * @api
- */
- ol.Collection.prototype.clear = function() {
- while (this.getLength() > 0) {
- this.pop();
- }
- };
- /**
- * Add elements to the collection. This pushes each item in the provided array
- * to the end of the collection.
- * @param {!Array.<T>} arr Array.
- * @return {ol.Collection.<T>} This collection.
- * @api
- */
- ol.Collection.prototype.extend = function(arr) {
- var i, ii;
- for (i = 0, ii = arr.length; i < ii; ++i) {
- this.push(arr[i]);
- }
- return this;
- };
- /**
- * Iterate over each element, calling the provided callback.
- * @param {function(this: S, T, number, Array.<T>): *} f The function to call
- * for every element. This function takes 3 arguments (the element, the
- * index and the array). The return value is ignored.
- * @param {S=} opt_this The object to use as `this` in `f`.
- * @template S
- * @api
- */
- ol.Collection.prototype.forEach = function(f, opt_this) {
- var fn = (opt_this) ? f.bind(opt_this) : f;
- var array = this.array_;
- for (var i = 0, ii = array.length; i < ii; ++i) {
- fn(array[i], i, array);
- }
- };
- /**
- * Get a reference to the underlying Array object. Warning: if the array
- * is mutated, no events will be dispatched by the collection, and the
- * collection's "length" property won't be in sync with the actual length
- * of the array.
- * @return {!Array.<T>} Array.
- * @api
- */
- ol.Collection.prototype.getArray = function() {
- return this.array_;
- };
- /**
- * Get the element at the provided index.
- * @param {number} index Index.
- * @return {T} Element.
- * @api
- */
- ol.Collection.prototype.item = function(index) {
- return this.array_[index];
- };
- /**
- * Get the length of this collection.
- * @return {number} The length of the array.
- * @observable
- * @api
- */
- ol.Collection.prototype.getLength = function() {
- return /** @type {number} */ (this.get(ol.Collection.Property_.LENGTH));
- };
- /**
- * Insert an element at the provided index.
- * @param {number} index Index.
- * @param {T} elem Element.
- * @api
- */
- ol.Collection.prototype.insertAt = function(index, elem) {
- if (this.unique_) {
- this.assertUnique_(elem);
- }
- this.array_.splice(index, 0, elem);
- this.updateLength_();
- this.dispatchEvent(
- new ol.Collection.Event(ol.CollectionEventType.ADD, elem));
- };
- /**
- * Remove the last element of the collection and return it.
- * Return `undefined` if the collection is empty.
- * @return {T|undefined} Element.
- * @api
- */
- ol.Collection.prototype.pop = function() {
- return this.removeAt(this.getLength() - 1);
- };
- /**
- * Insert the provided element at the end of the collection.
- * @param {T} elem Element.
- * @return {number} New length of the collection.
- * @api
- */
- ol.Collection.prototype.push = function(elem) {
- if (this.unique_) {
- this.assertUnique_(elem);
- }
- var n = this.getLength();
- this.insertAt(n, elem);
- return this.getLength();
- };
- /**
- * Remove the first occurrence of an element from the collection.
- * @param {T} elem Element.
- * @return {T|undefined} The removed element or undefined if none found.
- * @api
- */
- ol.Collection.prototype.remove = function(elem) {
- var arr = this.array_;
- var i, ii;
- for (i = 0, ii = arr.length; i < ii; ++i) {
- if (arr[i] === elem) {
- return this.removeAt(i);
- }
- }
- return undefined;
- };
- /**
- * Remove the element at the provided index and return it.
- * Return `undefined` if the collection does not contain this index.
- * @param {number} index Index.
- * @return {T|undefined} Value.
- * @api
- */
- ol.Collection.prototype.removeAt = function(index) {
- var prev = this.array_[index];
- this.array_.splice(index, 1);
- this.updateLength_();
- this.dispatchEvent(
- new ol.Collection.Event(ol.CollectionEventType.REMOVE, prev));
- return prev;
- };
- /**
- * Set the element at the provided index.
- * @param {number} index Index.
- * @param {T} elem Element.
- * @api
- */
- ol.Collection.prototype.setAt = function(index, elem) {
- var n = this.getLength();
- if (index < n) {
- if (this.unique_) {
- this.assertUnique_(elem, index);
- }
- var prev = this.array_[index];
- this.array_[index] = elem;
- this.dispatchEvent(
- new ol.Collection.Event(ol.CollectionEventType.REMOVE, prev));
- this.dispatchEvent(
- new ol.Collection.Event(ol.CollectionEventType.ADD, elem));
- } else {
- var j;
- for (j = n; j < index; ++j) {
- this.insertAt(j, undefined);
- }
- this.insertAt(index, elem);
- }
- };
- /**
- * @private
- */
- ol.Collection.prototype.updateLength_ = function() {
- this.set(ol.Collection.Property_.LENGTH, this.array_.length);
- };
- /**
- * @private
- * @param {T} elem Element.
- * @param {number=} opt_except Optional index to ignore.
- */
- ol.Collection.prototype.assertUnique_ = function(elem, opt_except) {
- for (var i = 0, ii = this.array_.length; i < ii; ++i) {
- if (this.array_[i] === elem && i !== opt_except) {
- throw new ol.AssertionError(58);
- }
- }
- };
- /**
- * @enum {string}
- * @private
- */
- ol.Collection.Property_ = {
- LENGTH: 'length'
- };
- /**
- * @classdesc
- * Events emitted by {@link ol.Collection} instances are instances of this
- * type.
- *
- * @constructor
- * @extends {ol.events.Event}
- * @implements {oli.Collection.Event}
- * @param {ol.CollectionEventType} type Type.
- * @param {*=} opt_element Element.
- */
- ol.Collection.Event = function(type, opt_element) {
- ol.events.Event.call(this, type);
- /**
- * The element that is added to or removed from the collection.
- * @type {*}
- * @api
- */
- this.element = opt_element;
- };
- ol.inherits(ol.Collection.Event, ol.events.Event);
- goog.provide('ol.MapEvent');
- goog.require('ol');
- goog.require('ol.events.Event');
- /**
- * @classdesc
- * Events emitted as map events are instances of this type.
- * See {@link ol.Map} for which events trigger a map event.
- *
- * @constructor
- * @extends {ol.events.Event}
- * @implements {oli.MapEvent}
- * @param {string} type Event type.
- * @param {ol.PluggableMap} map Map.
- * @param {?olx.FrameState=} opt_frameState Frame state.
- */
- ol.MapEvent = function(type, map, opt_frameState) {
- ol.events.Event.call(this, type);
- /**
- * The map where the event occurred.
- * @type {ol.PluggableMap}
- * @api
- */
- this.map = map;
- /**
- * The frame state at the time of the event.
- * @type {?olx.FrameState}
- * @api
- */
- this.frameState = opt_frameState !== undefined ? opt_frameState : null;
- };
- ol.inherits(ol.MapEvent, ol.events.Event);
- goog.provide('ol.MapBrowserEvent');
- goog.require('ol');
- goog.require('ol.MapEvent');
- /**
- * @classdesc
- * Events emitted as map browser events are instances of this type.
- * See {@link ol.Map} for which events trigger a map browser event.
- *
- * @constructor
- * @extends {ol.MapEvent}
- * @implements {oli.MapBrowserEvent}
- * @param {string} type Event type.
- * @param {ol.PluggableMap} map Map.
- * @param {Event} browserEvent Browser event.
- * @param {boolean=} opt_dragging Is the map currently being dragged?
- * @param {?olx.FrameState=} opt_frameState Frame state.
- */
- ol.MapBrowserEvent = function(type, map, browserEvent, opt_dragging,
- opt_frameState) {
- ol.MapEvent.call(this, type, map, opt_frameState);
- /**
- * The original browser event.
- * @const
- * @type {Event}
- * @api
- */
- this.originalEvent = browserEvent;
- /**
- * The map pixel relative to the viewport corresponding to the original browser event.
- * @type {ol.Pixel}
- * @api
- */
- this.pixel = map.getEventPixel(browserEvent);
- /**
- * The coordinate in view projection corresponding to the original browser event.
- * @type {ol.Coordinate}
- * @api
- */
- this.coordinate = map.getCoordinateFromPixel(this.pixel);
- /**
- * Indicates if the map is currently being dragged. Only set for
- * `POINTERDRAG` and `POINTERMOVE` events. Default is `false`.
- *
- * @type {boolean}
- * @api
- */
- this.dragging = opt_dragging !== undefined ? opt_dragging : false;
- };
- ol.inherits(ol.MapBrowserEvent, ol.MapEvent);
- /**
- * Prevents the default browser action.
- * @see https://developer.mozilla.org/en-US/docs/Web/API/event.preventDefault
- * @override
- * @api
- */
- ol.MapBrowserEvent.prototype.preventDefault = function() {
- ol.MapEvent.prototype.preventDefault.call(this);
- this.originalEvent.preventDefault();
- };
- /**
- * Prevents further propagation of the current event.
- * @see https://developer.mozilla.org/en-US/docs/Web/API/event.stopPropagation
- * @override
- * @api
- */
- ol.MapBrowserEvent.prototype.stopPropagation = function() {
- ol.MapEvent.prototype.stopPropagation.call(this);
- this.originalEvent.stopPropagation();
- };
- goog.provide('ol.webgl');
- /**
- * Constants taken from goog.webgl
- */
- /**
- * @const
- * @type {number}
- */
- ol.webgl.ONE = 1;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.SRC_ALPHA = 0x0302;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.COLOR_ATTACHMENT0 = 0x8CE0;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.COLOR_BUFFER_BIT = 0x00004000;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.TRIANGLES = 0x0004;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.TRIANGLE_STRIP = 0x0005;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.ONE_MINUS_SRC_ALPHA = 0x0303;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.ARRAY_BUFFER = 0x8892;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.ELEMENT_ARRAY_BUFFER = 0x8893;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.STREAM_DRAW = 0x88E0;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.STATIC_DRAW = 0x88E4;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.DYNAMIC_DRAW = 0x88E8;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.CULL_FACE = 0x0B44;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.BLEND = 0x0BE2;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.STENCIL_TEST = 0x0B90;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.DEPTH_TEST = 0x0B71;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.SCISSOR_TEST = 0x0C11;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.UNSIGNED_BYTE = 0x1401;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.UNSIGNED_SHORT = 0x1403;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.UNSIGNED_INT = 0x1405;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.FLOAT = 0x1406;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.RGBA = 0x1908;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.FRAGMENT_SHADER = 0x8B30;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.VERTEX_SHADER = 0x8B31;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.LINK_STATUS = 0x8B82;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.LINEAR = 0x2601;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.TEXTURE_MAG_FILTER = 0x2800;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.TEXTURE_MIN_FILTER = 0x2801;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.TEXTURE_WRAP_S = 0x2802;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.TEXTURE_WRAP_T = 0x2803;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.TEXTURE_2D = 0x0DE1;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.TEXTURE0 = 0x84C0;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.CLAMP_TO_EDGE = 0x812F;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.COMPILE_STATUS = 0x8B81;
- /**
- * @const
- * @type {number}
- */
- ol.webgl.FRAMEBUFFER = 0x8D40;
- /** end of goog.webgl constants
- */
- /**
- * @const
- * @private
- * @type {Array.<string>}
- */
- ol.webgl.CONTEXT_IDS_ = [
- 'experimental-webgl',
- 'webgl',
- 'webkit-3d',
- 'moz-webgl'
- ];
- /**
- * @param {HTMLCanvasElement} canvas Canvas.
- * @param {Object=} opt_attributes Attributes.
- * @return {WebGLRenderingContext} WebGL rendering context.
- */
- ol.webgl.getContext = function(canvas, opt_attributes) {
- var context, i, ii = ol.webgl.CONTEXT_IDS_.length;
- for (i = 0; i < ii; ++i) {
- try {
- context = canvas.getContext(ol.webgl.CONTEXT_IDS_[i], opt_attributes);
- if (context) {
- return /** @type {!WebGLRenderingContext} */ (context);
- }
- } catch (e) {
- // pass
- }
- }
- return null;
- };
- goog.provide('ol.has');
- goog.require('ol');
- goog.require('ol.webgl');
- var ua = typeof navigator !== 'undefined' ?
- navigator.userAgent.toLowerCase() : '';
- /**
- * User agent string says we are dealing with Firefox as browser.
- * @type {boolean}
- */
- ol.has.FIREFOX = ua.indexOf('firefox') !== -1;
- /**
- * User agent string says we are dealing with Safari as browser.
- * @type {boolean}
- */
- ol.has.SAFARI = ua.indexOf('safari') !== -1 && ua.indexOf('chrom') == -1;
- /**
- * User agent string says we are dealing with a WebKit engine.
- * @type {boolean}
- */
- ol.has.WEBKIT = ua.indexOf('webkit') !== -1 && ua.indexOf('edge') == -1;
- /**
- * User agent string says we are dealing with a Mac as platform.
- * @type {boolean}
- */
- ol.has.MAC = ua.indexOf('macintosh') !== -1;
- /**
- * The ratio between physical pixels and device-independent pixels
- * (dips) on the device (`window.devicePixelRatio`).
- * @const
- * @type {number}
- * @api
- */
- ol.has.DEVICE_PIXEL_RATIO = window.devicePixelRatio || 1;
- /**
- * True if the browser's Canvas implementation implements {get,set}LineDash.
- * @type {boolean}
- */
- ol.has.CANVAS_LINE_DASH = false;
- /**
- * True if both the library and browser support Canvas. Always `false`
- * if `ol.ENABLE_CANVAS` is set to `false` at compile time.
- * @const
- * @type {boolean}
- * @api
- */
- ol.has.CANVAS = ol.ENABLE_CANVAS && (
- /**
- * @return {boolean} Canvas supported.
- */
- function() {
- if (!('HTMLCanvasElement' in window)) {
- return false;
- }
- try {
- var context = document.createElement('CANVAS').getContext('2d');
- if (!context) {
- return false;
- } else {
- if (context.setLineDash !== undefined) {
- ol.has.CANVAS_LINE_DASH = true;
- }
- return true;
- }
- } catch (e) {
- return false;
- }
- })();
- /**
- * Indicates if DeviceOrientation is supported in the user's browser.
- * @const
- * @type {boolean}
- * @api
- */
- ol.has.DEVICE_ORIENTATION = 'DeviceOrientationEvent' in window;
- /**
- * Is HTML5 geolocation supported in the current browser?
- * @const
- * @type {boolean}
- * @api
- */
- ol.has.GEOLOCATION = 'geolocation' in navigator;
- /**
- * True if browser supports touch events.
- * @const
- * @type {boolean}
- * @api
- */
- ol.has.TOUCH = ol.ASSUME_TOUCH || 'ontouchstart' in window;
- /**
- * True if browser supports pointer events.
- * @const
- * @type {boolean}
- */
- ol.has.POINTER = 'PointerEvent' in window;
- /**
- * True if browser supports ms pointer events (IE 10).
- * @const
- * @type {boolean}
- */
- ol.has.MSPOINTER = !!(navigator.msPointerEnabled);
- /**
- * True if both OpenLayers and browser support WebGL. Always `false`
- * if `ol.ENABLE_WEBGL` is set to `false` at compile time.
- * @const
- * @type {boolean}
- * @api
- */
- ol.has.WEBGL;
- (function() {
- if (ol.ENABLE_WEBGL) {
- var hasWebGL = false;
- var textureSize;
- var /** @type {Array.<string>} */ extensions = [];
- if ('WebGLRenderingContext' in window) {
- try {
- var canvas = /** @type {HTMLCanvasElement} */
- (document.createElement('CANVAS'));
- var gl = ol.webgl.getContext(canvas, {
- failIfMajorPerformanceCaveat: true
- });
- if (gl) {
- hasWebGL = true;
- textureSize = /** @type {number} */
- (gl.getParameter(gl.MAX_TEXTURE_SIZE));
- extensions = gl.getSupportedExtensions();
- }
- } catch (e) {
- // pass
- }
- }
- ol.has.WEBGL = hasWebGL;
- ol.WEBGL_EXTENSIONS = extensions;
- ol.WEBGL_MAX_TEXTURE_SIZE = textureSize;
- }
- })();
- goog.provide('ol.MapBrowserEventType');
- goog.require('ol.events.EventType');
- /**
- * Constants for event names.
- * @enum {string}
- */
- ol.MapBrowserEventType = {
- /**
- * A true single click with no dragging and no double click. Note that this
- * event is delayed by 250 ms to ensure that it is not a double click.
- * @event ol.MapBrowserEvent#singleclick
- * @api
- */
- SINGLECLICK: 'singleclick',
- /**
- * A click with no dragging. A double click will fire two of this.
- * @event ol.MapBrowserEvent#click
- * @api
- */
- CLICK: ol.events.EventType.CLICK,
- /**
- * A true double click, with no dragging.
- * @event ol.MapBrowserEvent#dblclick
- * @api
- */
- DBLCLICK: ol.events.EventType.DBLCLICK,
- /**
- * Triggered when a pointer is dragged.
- * @event ol.MapBrowserEvent#pointerdrag
- * @api
- */
- POINTERDRAG: 'pointerdrag',
- /**
- * Triggered when a pointer is moved. Note that on touch devices this is
- * triggered when the map is panned, so is not the same as mousemove.
- * @event ol.MapBrowserEvent#pointermove
- * @api
- */
- POINTERMOVE: 'pointermove',
- POINTERDOWN: 'pointerdown',
- POINTERUP: 'pointerup',
- POINTEROVER: 'pointerover',
- POINTEROUT: 'pointerout',
- POINTERENTER: 'pointerenter',
- POINTERLEAVE: 'pointerleave',
- POINTERCANCEL: 'pointercancel'
- };
- goog.provide('ol.MapBrowserPointerEvent');
- goog.require('ol');
- goog.require('ol.MapBrowserEvent');
- /**
- * @constructor
- * @extends {ol.MapBrowserEvent}
- * @param {string} type Event type.
- * @param {ol.PluggableMap} map Map.
- * @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
- * @param {boolean=} opt_dragging Is the map currently being dragged?
- * @param {?olx.FrameState=} opt_frameState Frame state.
- */
- ol.MapBrowserPointerEvent = function(type, map, pointerEvent, opt_dragging,
- opt_frameState) {
- ol.MapBrowserEvent.call(this, type, map, pointerEvent.originalEvent, opt_dragging,
- opt_frameState);
- /**
- * @const
- * @type {ol.pointer.PointerEvent}
- */
- this.pointerEvent = pointerEvent;
- };
- ol.inherits(ol.MapBrowserPointerEvent, ol.MapBrowserEvent);
- goog.provide('ol.pointer.EventType');
- /**
- * Constants for event names.
- * @enum {string}
- */
- ol.pointer.EventType = {
- POINTERMOVE: 'pointermove',
- POINTERDOWN: 'pointerdown',
- POINTERUP: 'pointerup',
- POINTEROVER: 'pointerover',
- POINTEROUT: 'pointerout',
- POINTERENTER: 'pointerenter',
- POINTERLEAVE: 'pointerleave',
- POINTERCANCEL: 'pointercancel'
- };
- goog.provide('ol.pointer.EventSource');
- /**
- * @param {ol.pointer.PointerEventHandler} dispatcher Event handler.
- * @param {!Object.<string, function(Event)>} mapping Event
- * mapping.
- * @constructor
- */
- ol.pointer.EventSource = function(dispatcher, mapping) {
- /**
- * @type {ol.pointer.PointerEventHandler}
- */
- this.dispatcher = dispatcher;
- /**
- * @private
- * @const
- * @type {!Object.<string, function(Event)>}
- */
- this.mapping_ = mapping;
- };
- /**
- * List of events supported by this source.
- * @return {Array.<string>} Event names
- */
- ol.pointer.EventSource.prototype.getEvents = function() {
- return Object.keys(this.mapping_);
- };
- /**
- * Returns the handler that should handle a given event type.
- * @param {string} eventType The event type.
- * @return {function(Event)} Handler
- */
- ol.pointer.EventSource.prototype.getHandlerForEvent = function(eventType) {
- return this.mapping_[eventType];
- };
- // Based on https://github.com/Polymer/PointerEvents
- // Copyright (c) 2013 The Polymer Authors. All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are
- // met:
- //
- // * Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- // * Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following disclaimer
- // in the documentation and/or other materials provided with the
- // distribution.
- // * Neither the name of Google Inc. nor the names of its
- // contributors may be used to endorse or promote products derived from
- // this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- goog.provide('ol.pointer.MouseSource');
- goog.require('ol');
- goog.require('ol.pointer.EventSource');
- /**
- * @param {ol.pointer.PointerEventHandler} dispatcher Event handler.
- * @constructor
- * @extends {ol.pointer.EventSource}
- */
- ol.pointer.MouseSource = function(dispatcher) {
- var mapping = {
- 'mousedown': this.mousedown,
- 'mousemove': this.mousemove,
- 'mouseup': this.mouseup,
- 'mouseover': this.mouseover,
- 'mouseout': this.mouseout
- };
- ol.pointer.EventSource.call(this, dispatcher, mapping);
- /**
- * @const
- * @type {!Object.<string, Event|Object>}
- */
- this.pointerMap = dispatcher.pointerMap;
- /**
- * @const
- * @type {Array.<ol.Pixel>}
- */
- this.lastTouches = [];
- };
- ol.inherits(ol.pointer.MouseSource, ol.pointer.EventSource);
- /**
- * @const
- * @type {number}
- */
- ol.pointer.MouseSource.POINTER_ID = 1;
- /**
- * @const
- * @type {string}
- */
- ol.pointer.MouseSource.POINTER_TYPE = 'mouse';
- /**
- * Radius around touchend that swallows mouse events.
- *
- * @const
- * @type {number}
- */
- ol.pointer.MouseSource.DEDUP_DIST = 25;
- /**
- * Detect if a mouse event was simulated from a touch by
- * checking if previously there was a touch event at the
- * same position.
- *
- * FIXME - Known problem with the native Android browser on
- * Samsung GT-I9100 (Android 4.1.2):
- * In case the page is scrolled, this function does not work
- * correctly when a canvas is used (WebGL or canvas renderer).
- * Mouse listeners on canvas elements (for this browser), create
- * two mouse events: One 'good' and one 'bad' one (on other browsers or
- * when a div is used, there is only one event). For the 'bad' one,
- * clientX/clientY and also pageX/pageY are wrong when the page
- * is scrolled. Because of that, this function can not detect if
- * the events were simulated from a touch event. As result, a
- * pointer event at a wrong position is dispatched, which confuses
- * the map interactions.
- * It is unclear, how one can get the correct position for the event
- * or detect that the positions are invalid.
- *
- * @private
- * @param {Event} inEvent The in event.
- * @return {boolean} True, if the event was generated by a touch.
- */
- ol.pointer.MouseSource.prototype.isEventSimulatedFromTouch_ = function(inEvent) {
- var lts = this.lastTouches;
- var x = inEvent.clientX, y = inEvent.clientY;
- for (var i = 0, l = lts.length, t; i < l && (t = lts[i]); i++) {
- // simulated mouse events will be swallowed near a primary touchend
- var dx = Math.abs(x - t[0]), dy = Math.abs(y - t[1]);
- if (dx <= ol.pointer.MouseSource.DEDUP_DIST &&
- dy <= ol.pointer.MouseSource.DEDUP_DIST) {
- return true;
- }
- }
- return false;
- };
- /**
- * Creates a copy of the original event that will be used
- * for the fake pointer event.
- *
- * @param {Event} inEvent The in event.
- * @param {ol.pointer.PointerEventHandler} dispatcher Event handler.
- * @return {Object} The copied event.
- */
- ol.pointer.MouseSource.prepareEvent = function(inEvent, dispatcher) {
- var e = dispatcher.cloneEvent(inEvent, inEvent);
- // forward mouse preventDefault
- var pd = e.preventDefault;
- e.preventDefault = function() {
- inEvent.preventDefault();
- pd();
- };
- e.pointerId = ol.pointer.MouseSource.POINTER_ID;
- e.isPrimary = true;
- e.pointerType = ol.pointer.MouseSource.POINTER_TYPE;
- return e;
- };
- /**
- * Handler for `mousedown`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.MouseSource.prototype.mousedown = function(inEvent) {
- if (!this.isEventSimulatedFromTouch_(inEvent)) {
- // TODO(dfreedman) workaround for some elements not sending mouseup
- // http://crbug/149091
- if (ol.pointer.MouseSource.POINTER_ID.toString() in this.pointerMap) {
- this.cancel(inEvent);
- }
- var e = ol.pointer.MouseSource.prepareEvent(inEvent, this.dispatcher);
- this.pointerMap[ol.pointer.MouseSource.POINTER_ID.toString()] = inEvent;
- this.dispatcher.down(e, inEvent);
- }
- };
- /**
- * Handler for `mousemove`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.MouseSource.prototype.mousemove = function(inEvent) {
- if (!this.isEventSimulatedFromTouch_(inEvent)) {
- var e = ol.pointer.MouseSource.prepareEvent(inEvent, this.dispatcher);
- this.dispatcher.move(e, inEvent);
- }
- };
- /**
- * Handler for `mouseup`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.MouseSource.prototype.mouseup = function(inEvent) {
- if (!this.isEventSimulatedFromTouch_(inEvent)) {
- var p = this.pointerMap[ol.pointer.MouseSource.POINTER_ID.toString()];
- if (p && p.button === inEvent.button) {
- var e = ol.pointer.MouseSource.prepareEvent(inEvent, this.dispatcher);
- this.dispatcher.up(e, inEvent);
- this.cleanupMouse();
- }
- }
- };
- /**
- * Handler for `mouseover`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.MouseSource.prototype.mouseover = function(inEvent) {
- if (!this.isEventSimulatedFromTouch_(inEvent)) {
- var e = ol.pointer.MouseSource.prepareEvent(inEvent, this.dispatcher);
- this.dispatcher.enterOver(e, inEvent);
- }
- };
- /**
- * Handler for `mouseout`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.MouseSource.prototype.mouseout = function(inEvent) {
- if (!this.isEventSimulatedFromTouch_(inEvent)) {
- var e = ol.pointer.MouseSource.prepareEvent(inEvent, this.dispatcher);
- this.dispatcher.leaveOut(e, inEvent);
- }
- };
- /**
- * Dispatches a `pointercancel` event.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.MouseSource.prototype.cancel = function(inEvent) {
- var e = ol.pointer.MouseSource.prepareEvent(inEvent, this.dispatcher);
- this.dispatcher.cancel(e, inEvent);
- this.cleanupMouse();
- };
- /**
- * Remove the mouse from the list of active pointers.
- */
- ol.pointer.MouseSource.prototype.cleanupMouse = function() {
- delete this.pointerMap[ol.pointer.MouseSource.POINTER_ID.toString()];
- };
- // Based on https://github.com/Polymer/PointerEvents
- // Copyright (c) 2013 The Polymer Authors. All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are
- // met:
- //
- // * Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- // * Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following disclaimer
- // in the documentation and/or other materials provided with the
- // distribution.
- // * Neither the name of Google Inc. nor the names of its
- // contributors may be used to endorse or promote products derived from
- // this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- goog.provide('ol.pointer.MsSource');
- goog.require('ol');
- goog.require('ol.pointer.EventSource');
- /**
- * @param {ol.pointer.PointerEventHandler} dispatcher Event handler.
- * @constructor
- * @extends {ol.pointer.EventSource}
- */
- ol.pointer.MsSource = function(dispatcher) {
- var mapping = {
- 'MSPointerDown': this.msPointerDown,
- 'MSPointerMove': this.msPointerMove,
- 'MSPointerUp': this.msPointerUp,
- 'MSPointerOut': this.msPointerOut,
- 'MSPointerOver': this.msPointerOver,
- 'MSPointerCancel': this.msPointerCancel,
- 'MSGotPointerCapture': this.msGotPointerCapture,
- 'MSLostPointerCapture': this.msLostPointerCapture
- };
- ol.pointer.EventSource.call(this, dispatcher, mapping);
- /**
- * @const
- * @type {!Object.<string, Event|Object>}
- */
- this.pointerMap = dispatcher.pointerMap;
- /**
- * @const
- * @type {Array.<string>}
- */
- this.POINTER_TYPES = [
- '',
- 'unavailable',
- 'touch',
- 'pen',
- 'mouse'
- ];
- };
- ol.inherits(ol.pointer.MsSource, ol.pointer.EventSource);
- /**
- * Creates a copy of the original event that will be used
- * for the fake pointer event.
- *
- * @private
- * @param {Event} inEvent The in event.
- * @return {Object} The copied event.
- */
- ol.pointer.MsSource.prototype.prepareEvent_ = function(inEvent) {
- var e = inEvent;
- if (typeof inEvent.pointerType === 'number') {
- e = this.dispatcher.cloneEvent(inEvent, inEvent);
- e.pointerType = this.POINTER_TYPES[inEvent.pointerType];
- }
- return e;
- };
- /**
- * Remove this pointer from the list of active pointers.
- * @param {number} pointerId Pointer identifier.
- */
- ol.pointer.MsSource.prototype.cleanup = function(pointerId) {
- delete this.pointerMap[pointerId.toString()];
- };
- /**
- * Handler for `msPointerDown`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.MsSource.prototype.msPointerDown = function(inEvent) {
- this.pointerMap[inEvent.pointerId.toString()] = inEvent;
- var e = this.prepareEvent_(inEvent);
- this.dispatcher.down(e, inEvent);
- };
- /**
- * Handler for `msPointerMove`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.MsSource.prototype.msPointerMove = function(inEvent) {
- var e = this.prepareEvent_(inEvent);
- this.dispatcher.move(e, inEvent);
- };
- /**
- * Handler for `msPointerUp`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.MsSource.prototype.msPointerUp = function(inEvent) {
- var e = this.prepareEvent_(inEvent);
- this.dispatcher.up(e, inEvent);
- this.cleanup(inEvent.pointerId);
- };
- /**
- * Handler for `msPointerOut`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.MsSource.prototype.msPointerOut = function(inEvent) {
- var e = this.prepareEvent_(inEvent);
- this.dispatcher.leaveOut(e, inEvent);
- };
- /**
- * Handler for `msPointerOver`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.MsSource.prototype.msPointerOver = function(inEvent) {
- var e = this.prepareEvent_(inEvent);
- this.dispatcher.enterOver(e, inEvent);
- };
- /**
- * Handler for `msPointerCancel`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.MsSource.prototype.msPointerCancel = function(inEvent) {
- var e = this.prepareEvent_(inEvent);
- this.dispatcher.cancel(e, inEvent);
- this.cleanup(inEvent.pointerId);
- };
- /**
- * Handler for `msLostPointerCapture`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.MsSource.prototype.msLostPointerCapture = function(inEvent) {
- var e = this.dispatcher.makeEvent('lostpointercapture',
- inEvent, inEvent);
- this.dispatcher.dispatchEvent(e);
- };
- /**
- * Handler for `msGotPointerCapture`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.MsSource.prototype.msGotPointerCapture = function(inEvent) {
- var e = this.dispatcher.makeEvent('gotpointercapture',
- inEvent, inEvent);
- this.dispatcher.dispatchEvent(e);
- };
- // Based on https://github.com/Polymer/PointerEvents
- // Copyright (c) 2013 The Polymer Authors. All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are
- // met:
- //
- // * Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- // * Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following disclaimer
- // in the documentation and/or other materials provided with the
- // distribution.
- // * Neither the name of Google Inc. nor the names of its
- // contributors may be used to endorse or promote products derived from
- // this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- goog.provide('ol.pointer.NativeSource');
- goog.require('ol');
- goog.require('ol.pointer.EventSource');
- /**
- * @param {ol.pointer.PointerEventHandler} dispatcher Event handler.
- * @constructor
- * @extends {ol.pointer.EventSource}
- */
- ol.pointer.NativeSource = function(dispatcher) {
- var mapping = {
- 'pointerdown': this.pointerDown,
- 'pointermove': this.pointerMove,
- 'pointerup': this.pointerUp,
- 'pointerout': this.pointerOut,
- 'pointerover': this.pointerOver,
- 'pointercancel': this.pointerCancel,
- 'gotpointercapture': this.gotPointerCapture,
- 'lostpointercapture': this.lostPointerCapture
- };
- ol.pointer.EventSource.call(this, dispatcher, mapping);
- };
- ol.inherits(ol.pointer.NativeSource, ol.pointer.EventSource);
- /**
- * Handler for `pointerdown`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.NativeSource.prototype.pointerDown = function(inEvent) {
- this.dispatcher.fireNativeEvent(inEvent);
- };
- /**
- * Handler for `pointermove`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.NativeSource.prototype.pointerMove = function(inEvent) {
- this.dispatcher.fireNativeEvent(inEvent);
- };
- /**
- * Handler for `pointerup`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.NativeSource.prototype.pointerUp = function(inEvent) {
- this.dispatcher.fireNativeEvent(inEvent);
- };
- /**
- * Handler for `pointerout`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.NativeSource.prototype.pointerOut = function(inEvent) {
- this.dispatcher.fireNativeEvent(inEvent);
- };
- /**
- * Handler for `pointerover`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.NativeSource.prototype.pointerOver = function(inEvent) {
- this.dispatcher.fireNativeEvent(inEvent);
- };
- /**
- * Handler for `pointercancel`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.NativeSource.prototype.pointerCancel = function(inEvent) {
- this.dispatcher.fireNativeEvent(inEvent);
- };
- /**
- * Handler for `lostpointercapture`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.NativeSource.prototype.lostPointerCapture = function(inEvent) {
- this.dispatcher.fireNativeEvent(inEvent);
- };
- /**
- * Handler for `gotpointercapture`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.NativeSource.prototype.gotPointerCapture = function(inEvent) {
- this.dispatcher.fireNativeEvent(inEvent);
- };
- // Based on https://github.com/Polymer/PointerEvents
- // Copyright (c) 2013 The Polymer Authors. All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are
- // met:
- //
- // * Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- // * Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following disclaimer
- // in the documentation and/or other materials provided with the
- // distribution.
- // * Neither the name of Google Inc. nor the names of its
- // contributors may be used to endorse or promote products derived from
- // this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- goog.provide('ol.pointer.PointerEvent');
- goog.require('ol');
- goog.require('ol.events.Event');
- /**
- * A class for pointer events.
- *
- * This class is used as an abstraction for mouse events,
- * touch events and even native pointer events.
- *
- * @constructor
- * @extends {ol.events.Event}
- * @param {string} type The type of the event to create.
- * @param {Event} originalEvent The event.
- * @param {Object.<string, ?>=} opt_eventDict An optional dictionary of
- * initial event properties.
- */
- ol.pointer.PointerEvent = function(type, originalEvent, opt_eventDict) {
- ol.events.Event.call(this, type);
- /**
- * @const
- * @type {Event}
- */
- this.originalEvent = originalEvent;
- var eventDict = opt_eventDict ? opt_eventDict : {};
- /**
- * @type {number}
- */
- this.buttons = this.getButtons_(eventDict);
- /**
- * @type {number}
- */
- this.pressure = this.getPressure_(eventDict, this.buttons);
- // MouseEvent related properties
- /**
- * @type {boolean}
- */
- this.bubbles = 'bubbles' in eventDict ? eventDict['bubbles'] : false;
- /**
- * @type {boolean}
- */
- this.cancelable = 'cancelable' in eventDict ? eventDict['cancelable'] : false;
- /**
- * @type {Object}
- */
- this.view = 'view' in eventDict ? eventDict['view'] : null;
- /**
- * @type {number}
- */
- this.detail = 'detail' in eventDict ? eventDict['detail'] : null;
- /**
- * @type {number}
- */
- this.screenX = 'screenX' in eventDict ? eventDict['screenX'] : 0;
- /**
- * @type {number}
- */
- this.screenY = 'screenY' in eventDict ? eventDict['screenY'] : 0;
- /**
- * @type {number}
- */
- this.clientX = 'clientX' in eventDict ? eventDict['clientX'] : 0;
- /**
- * @type {number}
- */
- this.clientY = 'clientY' in eventDict ? eventDict['clientY'] : 0;
- /**
- * @type {boolean}
- */
- this.ctrlKey = 'ctrlKey' in eventDict ? eventDict['ctrlKey'] : false;
- /**
- * @type {boolean}
- */
- this.altKey = 'altKey' in eventDict ? eventDict['altKey'] : false;
- /**
- * @type {boolean}
- */
- this.shiftKey = 'shiftKey' in eventDict ? eventDict['shiftKey'] : false;
- /**
- * @type {boolean}
- */
- this.metaKey = 'metaKey' in eventDict ? eventDict['metaKey'] : false;
- /**
- * @type {number}
- */
- this.button = 'button' in eventDict ? eventDict['button'] : 0;
- /**
- * @type {Node}
- */
- this.relatedTarget = 'relatedTarget' in eventDict ?
- eventDict['relatedTarget'] : null;
- // PointerEvent related properties
- /**
- * @const
- * @type {number}
- */
- this.pointerId = 'pointerId' in eventDict ? eventDict['pointerId'] : 0;
- /**
- * @type {number}
- */
- this.width = 'width' in eventDict ? eventDict['width'] : 0;
- /**
- * @type {number}
- */
- this.height = 'height' in eventDict ? eventDict['height'] : 0;
- /**
- * @type {number}
- */
- this.tiltX = 'tiltX' in eventDict ? eventDict['tiltX'] : 0;
- /**
- * @type {number}
- */
- this.tiltY = 'tiltY' in eventDict ? eventDict['tiltY'] : 0;
- /**
- * @type {string}
- */
- this.pointerType = 'pointerType' in eventDict ? eventDict['pointerType'] : '';
- /**
- * @type {number}
- */
- this.hwTimestamp = 'hwTimestamp' in eventDict ? eventDict['hwTimestamp'] : 0;
- /**
- * @type {boolean}
- */
- this.isPrimary = 'isPrimary' in eventDict ? eventDict['isPrimary'] : false;
- // keep the semantics of preventDefault
- if (originalEvent.preventDefault) {
- this.preventDefault = function() {
- originalEvent.preventDefault();
- };
- }
- };
- ol.inherits(ol.pointer.PointerEvent, ol.events.Event);
- /**
- * @private
- * @param {Object.<string, ?>} eventDict The event dictionary.
- * @return {number} Button indicator.
- */
- ol.pointer.PointerEvent.prototype.getButtons_ = function(eventDict) {
- // According to the w3c spec,
- // http://www.w3.org/TR/DOM-Level-3-Events/#events-MouseEvent-button
- // MouseEvent.button == 0 can mean either no mouse button depressed, or the
- // left mouse button depressed.
- //
- // As of now, the only way to distinguish between the two states of
- // MouseEvent.button is by using the deprecated MouseEvent.which property, as
- // this maps mouse buttons to positive integers > 0, and uses 0 to mean that
- // no mouse button is held.
- //
- // MouseEvent.which is derived from MouseEvent.button at MouseEvent creation,
- // but initMouseEvent does not expose an argument with which to set
- // MouseEvent.which. Calling initMouseEvent with a buttonArg of 0 will set
- // MouseEvent.button == 0 and MouseEvent.which == 1, breaking the expectations
- // of app developers.
- //
- // The only way to propagate the correct state of MouseEvent.which and
- // MouseEvent.button to a new MouseEvent.button == 0 and MouseEvent.which == 0
- // is to call initMouseEvent with a buttonArg value of -1.
- //
- // This is fixed with DOM Level 4's use of buttons
- var buttons;
- if (eventDict.buttons || ol.pointer.PointerEvent.HAS_BUTTONS) {
- buttons = eventDict.buttons;
- } else {
- switch (eventDict.which) {
- case 1: buttons = 1; break;
- case 2: buttons = 4; break;
- case 3: buttons = 2; break;
- default: buttons = 0;
- }
- }
- return buttons;
- };
- /**
- * @private
- * @param {Object.<string, ?>} eventDict The event dictionary.
- * @param {number} buttons Button indicator.
- * @return {number} The pressure.
- */
- ol.pointer.PointerEvent.prototype.getPressure_ = function(eventDict, buttons) {
- // Spec requires that pointers without pressure specified use 0.5 for down
- // state and 0 for up state.
- var pressure = 0;
- if (eventDict.pressure) {
- pressure = eventDict.pressure;
- } else {
- pressure = buttons ? 0.5 : 0;
- }
- return pressure;
- };
- /**
- * Is the `buttons` property supported?
- * @type {boolean}
- */
- ol.pointer.PointerEvent.HAS_BUTTONS = false;
- /**
- * Checks if the `buttons` property is supported.
- */
- (function() {
- try {
- var ev = new MouseEvent('click', {buttons: 1});
- ol.pointer.PointerEvent.HAS_BUTTONS = ev.buttons === 1;
- } catch (e) {
- // pass
- }
- })();
- // Based on https://github.com/Polymer/PointerEvents
- // Copyright (c) 2013 The Polymer Authors. All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are
- // met:
- //
- // * Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- // * Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following disclaimer
- // in the documentation and/or other materials provided with the
- // distribution.
- // * Neither the name of Google Inc. nor the names of its
- // contributors may be used to endorse or promote products derived from
- // this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- goog.provide('ol.pointer.TouchSource');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.pointer.EventSource');
- goog.require('ol.pointer.MouseSource');
- /**
- * @constructor
- * @param {ol.pointer.PointerEventHandler} dispatcher The event handler.
- * @param {ol.pointer.MouseSource} mouseSource Mouse source.
- * @extends {ol.pointer.EventSource}
- */
- ol.pointer.TouchSource = function(dispatcher, mouseSource) {
- var mapping = {
- 'touchstart': this.touchstart,
- 'touchmove': this.touchmove,
- 'touchend': this.touchend,
- 'touchcancel': this.touchcancel
- };
- ol.pointer.EventSource.call(this, dispatcher, mapping);
- /**
- * @const
- * @type {!Object.<string, Event|Object>}
- */
- this.pointerMap = dispatcher.pointerMap;
- /**
- * @const
- * @type {ol.pointer.MouseSource}
- */
- this.mouseSource = mouseSource;
- /**
- * @private
- * @type {number|undefined}
- */
- this.firstTouchId_ = undefined;
- /**
- * @private
- * @type {number}
- */
- this.clickCount_ = 0;
- /**
- * @private
- * @type {number|undefined}
- */
- this.resetId_ = undefined;
- };
- ol.inherits(ol.pointer.TouchSource, ol.pointer.EventSource);
- /**
- * Mouse event timeout: This should be long enough to
- * ignore compat mouse events made by touch.
- * @const
- * @type {number}
- */
- ol.pointer.TouchSource.DEDUP_TIMEOUT = 2500;
- /**
- * @const
- * @type {number}
- */
- ol.pointer.TouchSource.CLICK_COUNT_TIMEOUT = 200;
- /**
- * @const
- * @type {string}
- */
- ol.pointer.TouchSource.POINTER_TYPE = 'touch';
- /**
- * @private
- * @param {Touch} inTouch The in touch.
- * @return {boolean} True, if this is the primary touch.
- */
- ol.pointer.TouchSource.prototype.isPrimaryTouch_ = function(inTouch) {
- return this.firstTouchId_ === inTouch.identifier;
- };
- /**
- * Set primary touch if there are no pointers, or the only pointer is the mouse.
- * @param {Touch} inTouch The in touch.
- * @private
- */
- ol.pointer.TouchSource.prototype.setPrimaryTouch_ = function(inTouch) {
- var count = Object.keys(this.pointerMap).length;
- if (count === 0 || (count === 1 &&
- ol.pointer.MouseSource.POINTER_ID.toString() in this.pointerMap)) {
- this.firstTouchId_ = inTouch.identifier;
- this.cancelResetClickCount_();
- }
- };
- /**
- * @private
- * @param {Object} inPointer The in pointer object.
- */
- ol.pointer.TouchSource.prototype.removePrimaryPointer_ = function(inPointer) {
- if (inPointer.isPrimary) {
- this.firstTouchId_ = undefined;
- this.resetClickCount_();
- }
- };
- /**
- * @private
- */
- ol.pointer.TouchSource.prototype.resetClickCount_ = function() {
- this.resetId_ = setTimeout(
- this.resetClickCountHandler_.bind(this),
- ol.pointer.TouchSource.CLICK_COUNT_TIMEOUT);
- };
- /**
- * @private
- */
- ol.pointer.TouchSource.prototype.resetClickCountHandler_ = function() {
- this.clickCount_ = 0;
- this.resetId_ = undefined;
- };
- /**
- * @private
- */
- ol.pointer.TouchSource.prototype.cancelResetClickCount_ = function() {
- if (this.resetId_ !== undefined) {
- clearTimeout(this.resetId_);
- }
- };
- /**
- * @private
- * @param {Event} browserEvent Browser event
- * @param {Touch} inTouch Touch event
- * @return {Object} A pointer object.
- */
- ol.pointer.TouchSource.prototype.touchToPointer_ = function(browserEvent, inTouch) {
- var e = this.dispatcher.cloneEvent(browserEvent, inTouch);
- // Spec specifies that pointerId 1 is reserved for Mouse.
- // Touch identifiers can start at 0.
- // Add 2 to the touch identifier for compatibility.
- e.pointerId = inTouch.identifier + 2;
- // TODO: check if this is necessary?
- //e.target = findTarget(e);
- e.bubbles = true;
- e.cancelable = true;
- e.detail = this.clickCount_;
- e.button = 0;
- e.buttons = 1;
- e.width = inTouch.webkitRadiusX || inTouch.radiusX || 0;
- e.height = inTouch.webkitRadiusY || inTouch.radiusY || 0;
- e.pressure = inTouch.webkitForce || inTouch.force || 0.5;
- e.isPrimary = this.isPrimaryTouch_(inTouch);
- e.pointerType = ol.pointer.TouchSource.POINTER_TYPE;
- // make sure that the properties that are different for
- // each `Touch` object are not copied from the BrowserEvent object
- e.clientX = inTouch.clientX;
- e.clientY = inTouch.clientY;
- e.screenX = inTouch.screenX;
- e.screenY = inTouch.screenY;
- return e;
- };
- /**
- * @private
- * @param {Event} inEvent Touch event
- * @param {function(Event, Object)} inFunction In function.
- */
- ol.pointer.TouchSource.prototype.processTouches_ = function(inEvent, inFunction) {
- var touches = Array.prototype.slice.call(
- inEvent.changedTouches);
- var count = touches.length;
- function preventDefault() {
- inEvent.preventDefault();
- }
- var i, pointer;
- for (i = 0; i < count; ++i) {
- pointer = this.touchToPointer_(inEvent, touches[i]);
- // forward touch preventDefaults
- pointer.preventDefault = preventDefault;
- inFunction.call(this, inEvent, pointer);
- }
- };
- /**
- * @private
- * @param {TouchList} touchList The touch list.
- * @param {number} searchId Search identifier.
- * @return {boolean} True, if the `Touch` with the given id is in the list.
- */
- ol.pointer.TouchSource.prototype.findTouch_ = function(touchList, searchId) {
- var l = touchList.length;
- var touch;
- for (var i = 0; i < l; i++) {
- touch = touchList[i];
- if (touch.identifier === searchId) {
- return true;
- }
- }
- return false;
- };
- /**
- * In some instances, a touchstart can happen without a touchend. This
- * leaves the pointermap in a broken state.
- * Therefore, on every touchstart, we remove the touches that did not fire a
- * touchend event.
- * To keep state globally consistent, we fire a pointercancel for
- * this "abandoned" touch
- *
- * @private
- * @param {Event} inEvent The in event.
- */
- ol.pointer.TouchSource.prototype.vacuumTouches_ = function(inEvent) {
- var touchList = inEvent.touches;
- // pointerMap.getCount() should be < touchList.length here,
- // as the touchstart has not been processed yet.
- var keys = Object.keys(this.pointerMap);
- var count = keys.length;
- if (count >= touchList.length) {
- var d = [];
- var i, key, value;
- for (i = 0; i < count; ++i) {
- key = keys[i];
- value = this.pointerMap[key];
- // Never remove pointerId == 1, which is mouse.
- // Touch identifiers are 2 smaller than their pointerId, which is the
- // index in pointermap.
- if (key != ol.pointer.MouseSource.POINTER_ID &&
- !this.findTouch_(touchList, key - 2)) {
- d.push(value.out);
- }
- }
- for (i = 0; i < d.length; ++i) {
- this.cancelOut_(inEvent, d[i]);
- }
- }
- };
- /**
- * Handler for `touchstart`, triggers `pointerover`,
- * `pointerenter` and `pointerdown` events.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.TouchSource.prototype.touchstart = function(inEvent) {
- this.vacuumTouches_(inEvent);
- this.setPrimaryTouch_(inEvent.changedTouches[0]);
- this.dedupSynthMouse_(inEvent);
- this.clickCount_++;
- this.processTouches_(inEvent, this.overDown_);
- };
- /**
- * @private
- * @param {Event} browserEvent The event.
- * @param {Object} inPointer The in pointer object.
- */
- ol.pointer.TouchSource.prototype.overDown_ = function(browserEvent, inPointer) {
- this.pointerMap[inPointer.pointerId] = {
- target: inPointer.target,
- out: inPointer,
- outTarget: inPointer.target
- };
- this.dispatcher.over(inPointer, browserEvent);
- this.dispatcher.enter(inPointer, browserEvent);
- this.dispatcher.down(inPointer, browserEvent);
- };
- /**
- * Handler for `touchmove`.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.TouchSource.prototype.touchmove = function(inEvent) {
- inEvent.preventDefault();
- this.processTouches_(inEvent, this.moveOverOut_);
- };
- /**
- * @private
- * @param {Event} browserEvent The event.
- * @param {Object} inPointer The in pointer.
- */
- ol.pointer.TouchSource.prototype.moveOverOut_ = function(browserEvent, inPointer) {
- var event = inPointer;
- var pointer = this.pointerMap[event.pointerId];
- // a finger drifted off the screen, ignore it
- if (!pointer) {
- return;
- }
- var outEvent = pointer.out;
- var outTarget = pointer.outTarget;
- this.dispatcher.move(event, browserEvent);
- if (outEvent && outTarget !== event.target) {
- outEvent.relatedTarget = event.target;
- event.relatedTarget = outTarget;
- // recover from retargeting by shadow
- outEvent.target = outTarget;
- if (event.target) {
- this.dispatcher.leaveOut(outEvent, browserEvent);
- this.dispatcher.enterOver(event, browserEvent);
- } else {
- // clean up case when finger leaves the screen
- event.target = outTarget;
- event.relatedTarget = null;
- this.cancelOut_(browserEvent, event);
- }
- }
- pointer.out = event;
- pointer.outTarget = event.target;
- };
- /**
- * Handler for `touchend`, triggers `pointerup`,
- * `pointerout` and `pointerleave` events.
- *
- * @param {Event} inEvent The event.
- */
- ol.pointer.TouchSource.prototype.touchend = function(inEvent) {
- this.dedupSynthMouse_(inEvent);
- this.processTouches_(inEvent, this.upOut_);
- };
- /**
- * @private
- * @param {Event} browserEvent An event.
- * @param {Object} inPointer The inPointer object.
- */
- ol.pointer.TouchSource.prototype.upOut_ = function(browserEvent, inPointer) {
- this.dispatcher.up(inPointer, browserEvent);
- this.dispatcher.out(inPointer, browserEvent);
- this.dispatcher.leave(inPointer, browserEvent);
- this.cleanUpPointer_(inPointer);
- };
- /**
- * Handler for `touchcancel`, triggers `pointercancel`,
- * `pointerout` and `pointerleave` events.
- *
- * @param {Event} inEvent The in event.
- */
- ol.pointer.TouchSource.prototype.touchcancel = function(inEvent) {
- this.processTouches_(inEvent, this.cancelOut_);
- };
- /**
- * @private
- * @param {Event} browserEvent The event.
- * @param {Object} inPointer The in pointer.
- */
- ol.pointer.TouchSource.prototype.cancelOut_ = function(browserEvent, inPointer) {
- this.dispatcher.cancel(inPointer, browserEvent);
- this.dispatcher.out(inPointer, browserEvent);
- this.dispatcher.leave(inPointer, browserEvent);
- this.cleanUpPointer_(inPointer);
- };
- /**
- * @private
- * @param {Object} inPointer The inPointer object.
- */
- ol.pointer.TouchSource.prototype.cleanUpPointer_ = function(inPointer) {
- delete this.pointerMap[inPointer.pointerId];
- this.removePrimaryPointer_(inPointer);
- };
- /**
- * Prevent synth mouse events from creating pointer events.
- *
- * @private
- * @param {Event} inEvent The in event.
- */
- ol.pointer.TouchSource.prototype.dedupSynthMouse_ = function(inEvent) {
- var lts = this.mouseSource.lastTouches;
- var t = inEvent.changedTouches[0];
- // only the primary finger will synth mouse events
- if (this.isPrimaryTouch_(t)) {
- // remember x/y of last touch
- var lt = [t.clientX, t.clientY];
- lts.push(lt);
- setTimeout(function() {
- // remove touch after timeout
- ol.array.remove(lts, lt);
- }, ol.pointer.TouchSource.DEDUP_TIMEOUT);
- }
- };
- // Based on https://github.com/Polymer/PointerEvents
- // Copyright (c) 2013 The Polymer Authors. All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are
- // met:
- //
- // * Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- // * Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following disclaimer
- // in the documentation and/or other materials provided with the
- // distribution.
- // * Neither the name of Google Inc. nor the names of its
- // contributors may be used to endorse or promote products derived from
- // this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- goog.provide('ol.pointer.PointerEventHandler');
- goog.require('ol');
- goog.require('ol.events');
- goog.require('ol.events.EventTarget');
- goog.require('ol.has');
- goog.require('ol.pointer.EventType');
- goog.require('ol.pointer.MouseSource');
- goog.require('ol.pointer.MsSource');
- goog.require('ol.pointer.NativeSource');
- goog.require('ol.pointer.PointerEvent');
- goog.require('ol.pointer.TouchSource');
- /**
- * @constructor
- * @extends {ol.events.EventTarget}
- * @param {Element|HTMLDocument} element Viewport element.
- */
- ol.pointer.PointerEventHandler = function(element) {
- ol.events.EventTarget.call(this);
- /**
- * @const
- * @private
- * @type {Element|HTMLDocument}
- */
- this.element_ = element;
- /**
- * @const
- * @type {!Object.<string, Event|Object>}
- */
- this.pointerMap = {};
- /**
- * @type {Object.<string, function(Event)>}
- * @private
- */
- this.eventMap_ = {};
- /**
- * @type {Array.<ol.pointer.EventSource>}
- * @private
- */
- this.eventSourceList_ = [];
- this.registerSources();
- };
- ol.inherits(ol.pointer.PointerEventHandler, ol.events.EventTarget);
- /**
- * Set up the event sources (mouse, touch and native pointers)
- * that generate pointer events.
- */
- ol.pointer.PointerEventHandler.prototype.registerSources = function() {
- if (ol.has.POINTER) {
- this.registerSource('native', new ol.pointer.NativeSource(this));
- } else if (ol.has.MSPOINTER) {
- this.registerSource('ms', new ol.pointer.MsSource(this));
- } else {
- var mouseSource = new ol.pointer.MouseSource(this);
- this.registerSource('mouse', mouseSource);
- if (ol.has.TOUCH) {
- this.registerSource('touch',
- new ol.pointer.TouchSource(this, mouseSource));
- }
- }
- // register events on the viewport element
- this.register_();
- };
- /**
- * Add a new event source that will generate pointer events.
- *
- * @param {string} name A name for the event source
- * @param {ol.pointer.EventSource} source The source event.
- */
- ol.pointer.PointerEventHandler.prototype.registerSource = function(name, source) {
- var s = source;
- var newEvents = s.getEvents();
- if (newEvents) {
- newEvents.forEach(function(e) {
- var handler = s.getHandlerForEvent(e);
- if (handler) {
- this.eventMap_[e] = handler.bind(s);
- }
- }, this);
- this.eventSourceList_.push(s);
- }
- };
- /**
- * Set up the events for all registered event sources.
- * @private
- */
- ol.pointer.PointerEventHandler.prototype.register_ = function() {
- var l = this.eventSourceList_.length;
- var eventSource;
- for (var i = 0; i < l; i++) {
- eventSource = this.eventSourceList_[i];
- this.addEvents_(eventSource.getEvents());
- }
- };
- /**
- * Remove all registered events.
- * @private
- */
- ol.pointer.PointerEventHandler.prototype.unregister_ = function() {
- var l = this.eventSourceList_.length;
- var eventSource;
- for (var i = 0; i < l; i++) {
- eventSource = this.eventSourceList_[i];
- this.removeEvents_(eventSource.getEvents());
- }
- };
- /**
- * Calls the right handler for a new event.
- * @private
- * @param {Event} inEvent Browser event.
- */
- ol.pointer.PointerEventHandler.prototype.eventHandler_ = function(inEvent) {
- var type = inEvent.type;
- var handler = this.eventMap_[type];
- if (handler) {
- handler(inEvent);
- }
- };
- /**
- * Setup listeners for the given events.
- * @private
- * @param {Array.<string>} events List of events.
- */
- ol.pointer.PointerEventHandler.prototype.addEvents_ = function(events) {
- events.forEach(function(eventName) {
- ol.events.listen(this.element_, eventName, this.eventHandler_, this);
- }, this);
- };
- /**
- * Unregister listeners for the given events.
- * @private
- * @param {Array.<string>} events List of events.
- */
- ol.pointer.PointerEventHandler.prototype.removeEvents_ = function(events) {
- events.forEach(function(e) {
- ol.events.unlisten(this.element_, e, this.eventHandler_, this);
- }, this);
- };
- /**
- * Returns a snapshot of inEvent, with writable properties.
- *
- * @param {Event} event Browser event.
- * @param {Event|Touch} inEvent An event that contains
- * properties to copy.
- * @return {Object} An object containing shallow copies of
- * `inEvent`'s properties.
- */
- ol.pointer.PointerEventHandler.prototype.cloneEvent = function(event, inEvent) {
- var eventCopy = {}, p;
- for (var i = 0, ii = ol.pointer.PointerEventHandler.CLONE_PROPS.length; i < ii; i++) {
- p = ol.pointer.PointerEventHandler.CLONE_PROPS[i][0];
- eventCopy[p] = event[p] || inEvent[p] || ol.pointer.PointerEventHandler.CLONE_PROPS[i][1];
- }
- return eventCopy;
- };
- // EVENTS
- /**
- * Triggers a 'pointerdown' event.
- * @param {Object} data Pointer event data.
- * @param {Event} event The event.
- */
- ol.pointer.PointerEventHandler.prototype.down = function(data, event) {
- this.fireEvent(ol.pointer.EventType.POINTERDOWN, data, event);
- };
- /**
- * Triggers a 'pointermove' event.
- * @param {Object} data Pointer event data.
- * @param {Event} event The event.
- */
- ol.pointer.PointerEventHandler.prototype.move = function(data, event) {
- this.fireEvent(ol.pointer.EventType.POINTERMOVE, data, event);
- };
- /**
- * Triggers a 'pointerup' event.
- * @param {Object} data Pointer event data.
- * @param {Event} event The event.
- */
- ol.pointer.PointerEventHandler.prototype.up = function(data, event) {
- this.fireEvent(ol.pointer.EventType.POINTERUP, data, event);
- };
- /**
- * Triggers a 'pointerenter' event.
- * @param {Object} data Pointer event data.
- * @param {Event} event The event.
- */
- ol.pointer.PointerEventHandler.prototype.enter = function(data, event) {
- data.bubbles = false;
- this.fireEvent(ol.pointer.EventType.POINTERENTER, data, event);
- };
- /**
- * Triggers a 'pointerleave' event.
- * @param {Object} data Pointer event data.
- * @param {Event} event The event.
- */
- ol.pointer.PointerEventHandler.prototype.leave = function(data, event) {
- data.bubbles = false;
- this.fireEvent(ol.pointer.EventType.POINTERLEAVE, data, event);
- };
- /**
- * Triggers a 'pointerover' event.
- * @param {Object} data Pointer event data.
- * @param {Event} event The event.
- */
- ol.pointer.PointerEventHandler.prototype.over = function(data, event) {
- data.bubbles = true;
- this.fireEvent(ol.pointer.EventType.POINTEROVER, data, event);
- };
- /**
- * Triggers a 'pointerout' event.
- * @param {Object} data Pointer event data.
- * @param {Event} event The event.
- */
- ol.pointer.PointerEventHandler.prototype.out = function(data, event) {
- data.bubbles = true;
- this.fireEvent(ol.pointer.EventType.POINTEROUT, data, event);
- };
- /**
- * Triggers a 'pointercancel' event.
- * @param {Object} data Pointer event data.
- * @param {Event} event The event.
- */
- ol.pointer.PointerEventHandler.prototype.cancel = function(data, event) {
- this.fireEvent(ol.pointer.EventType.POINTERCANCEL, data, event);
- };
- /**
- * Triggers a combination of 'pointerout' and 'pointerleave' events.
- * @param {Object} data Pointer event data.
- * @param {Event} event The event.
- */
- ol.pointer.PointerEventHandler.prototype.leaveOut = function(data, event) {
- this.out(data, event);
- if (!this.contains_(data.target, data.relatedTarget)) {
- this.leave(data, event);
- }
- };
- /**
- * Triggers a combination of 'pointerover' and 'pointerevents' events.
- * @param {Object} data Pointer event data.
- * @param {Event} event The event.
- */
- ol.pointer.PointerEventHandler.prototype.enterOver = function(data, event) {
- this.over(data, event);
- if (!this.contains_(data.target, data.relatedTarget)) {
- this.enter(data, event);
- }
- };
- /**
- * @private
- * @param {Element} container The container element.
- * @param {Element} contained The contained element.
- * @return {boolean} Returns true if the container element
- * contains the other element.
- */
- ol.pointer.PointerEventHandler.prototype.contains_ = function(container, contained) {
- if (!container || !contained) {
- return false;
- }
- return container.contains(contained);
- };
- // EVENT CREATION AND TRACKING
- /**
- * Creates a new Event of type `inType`, based on the information in
- * `data`.
- *
- * @param {string} inType A string representing the type of event to create.
- * @param {Object} data Pointer event data.
- * @param {Event} event The event.
- * @return {ol.pointer.PointerEvent} A PointerEvent of type `inType`.
- */
- ol.pointer.PointerEventHandler.prototype.makeEvent = function(inType, data, event) {
- return new ol.pointer.PointerEvent(inType, event, data);
- };
- /**
- * Make and dispatch an event in one call.
- * @param {string} inType A string representing the type of event.
- * @param {Object} data Pointer event data.
- * @param {Event} event The event.
- */
- ol.pointer.PointerEventHandler.prototype.fireEvent = function(inType, data, event) {
- var e = this.makeEvent(inType, data, event);
- this.dispatchEvent(e);
- };
- /**
- * Creates a pointer event from a native pointer event
- * and dispatches this event.
- * @param {Event} event A platform event with a target.
- */
- ol.pointer.PointerEventHandler.prototype.fireNativeEvent = function(event) {
- var e = this.makeEvent(event.type, event, event);
- this.dispatchEvent(e);
- };
- /**
- * Wrap a native mouse event into a pointer event.
- * This proxy method is required for the legacy IE support.
- * @param {string} eventType The pointer event type.
- * @param {Event} event The event.
- * @return {ol.pointer.PointerEvent} The wrapped event.
- */
- ol.pointer.PointerEventHandler.prototype.wrapMouseEvent = function(eventType, event) {
- var pointerEvent = this.makeEvent(
- eventType, ol.pointer.MouseSource.prepareEvent(event, this), event);
- return pointerEvent;
- };
- /**
- * @inheritDoc
- */
- ol.pointer.PointerEventHandler.prototype.disposeInternal = function() {
- this.unregister_();
- ol.events.EventTarget.prototype.disposeInternal.call(this);
- };
- /**
- * Properties to copy when cloning an event, with default values.
- * @type {Array.<Array>}
- */
- ol.pointer.PointerEventHandler.CLONE_PROPS = [
- // MouseEvent
- ['bubbles', false],
- ['cancelable', false],
- ['view', null],
- ['detail', null],
- ['screenX', 0],
- ['screenY', 0],
- ['clientX', 0],
- ['clientY', 0],
- ['ctrlKey', false],
- ['altKey', false],
- ['shiftKey', false],
- ['metaKey', false],
- ['button', 0],
- ['relatedTarget', null],
- // DOM Level 3
- ['buttons', 0],
- // PointerEvent
- ['pointerId', 0],
- ['width', 0],
- ['height', 0],
- ['pressure', 0],
- ['tiltX', 0],
- ['tiltY', 0],
- ['pointerType', ''],
- ['hwTimestamp', 0],
- ['isPrimary', false],
- // event instance
- ['type', ''],
- ['target', null],
- ['currentTarget', null],
- ['which', 0]
- ];
- goog.provide('ol.MapBrowserEventHandler');
- goog.require('ol');
- goog.require('ol.has');
- goog.require('ol.MapBrowserEventType');
- goog.require('ol.MapBrowserPointerEvent');
- goog.require('ol.events');
- goog.require('ol.events.EventTarget');
- goog.require('ol.pointer.EventType');
- goog.require('ol.pointer.PointerEventHandler');
- /**
- * @param {ol.PluggableMap} map The map with the viewport to listen to events on.
- * @param {number|undefined} moveTolerance The minimal distance the pointer must travel to trigger a move.
- * @constructor
- * @extends {ol.events.EventTarget}
- */
- ol.MapBrowserEventHandler = function(map, moveTolerance) {
- ol.events.EventTarget.call(this);
- /**
- * This is the element that we will listen to the real events on.
- * @type {ol.PluggableMap}
- * @private
- */
- this.map_ = map;
- /**
- * @type {number}
- * @private
- */
- this.clickTimeoutId_ = 0;
- /**
- * @type {boolean}
- * @private
- */
- this.dragging_ = false;
- /**
- * @type {!Array.<ol.EventsKey>}
- * @private
- */
- this.dragListenerKeys_ = [];
- /**
- * @type {number}
- * @private
- */
- this.moveTolerance_ = moveTolerance ?
- moveTolerance * ol.has.DEVICE_PIXEL_RATIO : ol.has.DEVICE_PIXEL_RATIO;
- /**
- * The most recent "down" type event (or null if none have occurred).
- * Set on pointerdown.
- * @type {ol.pointer.PointerEvent}
- * @private
- */
- this.down_ = null;
- var element = this.map_.getViewport();
- /**
- * @type {number}
- * @private
- */
- this.activePointers_ = 0;
- /**
- * @type {!Object.<number, boolean>}
- * @private
- */
- this.trackedTouches_ = {};
- /**
- * Event handler which generates pointer events for
- * the viewport element.
- *
- * @type {ol.pointer.PointerEventHandler}
- * @private
- */
- this.pointerEventHandler_ = new ol.pointer.PointerEventHandler(element);
- /**
- * Event handler which generates pointer events for
- * the document (used when dragging).
- *
- * @type {ol.pointer.PointerEventHandler}
- * @private
- */
- this.documentPointerEventHandler_ = null;
- /**
- * @type {?ol.EventsKey}
- * @private
- */
- this.pointerdownListenerKey_ = ol.events.listen(this.pointerEventHandler_,
- ol.pointer.EventType.POINTERDOWN,
- this.handlePointerDown_, this);
- /**
- * @type {?ol.EventsKey}
- * @private
- */
- this.relayedListenerKey_ = ol.events.listen(this.pointerEventHandler_,
- ol.pointer.EventType.POINTERMOVE,
- this.relayEvent_, this);
- };
- ol.inherits(ol.MapBrowserEventHandler, ol.events.EventTarget);
- /**
- * @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
- * @private
- */
- ol.MapBrowserEventHandler.prototype.emulateClick_ = function(pointerEvent) {
- var newEvent = new ol.MapBrowserPointerEvent(
- ol.MapBrowserEventType.CLICK, this.map_, pointerEvent);
- this.dispatchEvent(newEvent);
- if (this.clickTimeoutId_ !== 0) {
- // double-click
- clearTimeout(this.clickTimeoutId_);
- this.clickTimeoutId_ = 0;
- newEvent = new ol.MapBrowserPointerEvent(
- ol.MapBrowserEventType.DBLCLICK, this.map_, pointerEvent);
- this.dispatchEvent(newEvent);
- } else {
- // click
- this.clickTimeoutId_ = setTimeout(function() {
- this.clickTimeoutId_ = 0;
- var newEvent = new ol.MapBrowserPointerEvent(
- ol.MapBrowserEventType.SINGLECLICK, this.map_, pointerEvent);
- this.dispatchEvent(newEvent);
- }.bind(this), 250);
- }
- };
- /**
- * Keeps track on how many pointers are currently active.
- *
- * @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
- * @private
- */
- ol.MapBrowserEventHandler.prototype.updateActivePointers_ = function(pointerEvent) {
- var event = pointerEvent;
- if (event.type == ol.MapBrowserEventType.POINTERUP ||
- event.type == ol.MapBrowserEventType.POINTERCANCEL) {
- delete this.trackedTouches_[event.pointerId];
- } else if (event.type == ol.MapBrowserEventType.POINTERDOWN) {
- this.trackedTouches_[event.pointerId] = true;
- }
- this.activePointers_ = Object.keys(this.trackedTouches_).length;
- };
- /**
- * @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
- * @private
- */
- ol.MapBrowserEventHandler.prototype.handlePointerUp_ = function(pointerEvent) {
- this.updateActivePointers_(pointerEvent);
- var newEvent = new ol.MapBrowserPointerEvent(
- ol.MapBrowserEventType.POINTERUP, this.map_, pointerEvent);
- this.dispatchEvent(newEvent);
- // We emulate click events on left mouse button click, touch contact, and pen
- // contact. isMouseActionButton returns true in these cases (evt.button is set
- // to 0).
- // See http://www.w3.org/TR/pointerevents/#button-states
- // We only fire click, singleclick, and doubleclick if nobody has called
- // event.stopPropagation() or event.preventDefault().
- if (!newEvent.propagationStopped && !this.dragging_ && this.isMouseActionButton_(pointerEvent)) {
- this.emulateClick_(this.down_);
- }
- if (this.activePointers_ === 0) {
- this.dragListenerKeys_.forEach(ol.events.unlistenByKey);
- this.dragListenerKeys_.length = 0;
- this.dragging_ = false;
- this.down_ = null;
- this.documentPointerEventHandler_.dispose();
- this.documentPointerEventHandler_ = null;
- }
- };
- /**
- * @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
- * @return {boolean} If the left mouse button was pressed.
- * @private
- */
- ol.MapBrowserEventHandler.prototype.isMouseActionButton_ = function(pointerEvent) {
- return pointerEvent.button === 0;
- };
- /**
- * @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
- * @private
- */
- ol.MapBrowserEventHandler.prototype.handlePointerDown_ = function(pointerEvent) {
- this.updateActivePointers_(pointerEvent);
- var newEvent = new ol.MapBrowserPointerEvent(
- ol.MapBrowserEventType.POINTERDOWN, this.map_, pointerEvent);
- this.dispatchEvent(newEvent);
- this.down_ = pointerEvent;
- if (this.dragListenerKeys_.length === 0) {
- /* Set up a pointer event handler on the `document`,
- * which is required when the pointer is moved outside
- * the viewport when dragging.
- */
- this.documentPointerEventHandler_ =
- new ol.pointer.PointerEventHandler(document);
- this.dragListenerKeys_.push(
- ol.events.listen(this.documentPointerEventHandler_,
- ol.MapBrowserEventType.POINTERMOVE,
- this.handlePointerMove_, this),
- ol.events.listen(this.documentPointerEventHandler_,
- ol.MapBrowserEventType.POINTERUP,
- this.handlePointerUp_, this),
- /* Note that the listener for `pointercancel is set up on
- * `pointerEventHandler_` and not `documentPointerEventHandler_` like
- * the `pointerup` and `pointermove` listeners.
- *
- * The reason for this is the following: `TouchSource.vacuumTouches_()`
- * issues `pointercancel` events, when there was no `touchend` for a
- * `touchstart`. Now, let's say a first `touchstart` is registered on
- * `pointerEventHandler_`. The `documentPointerEventHandler_` is set up.
- * But `documentPointerEventHandler_` doesn't know about the first
- * `touchstart`. If there is no `touchend` for the `touchstart`, we can
- * only receive a `touchcancel` from `pointerEventHandler_`, because it is
- * only registered there.
- */
- ol.events.listen(this.pointerEventHandler_,
- ol.MapBrowserEventType.POINTERCANCEL,
- this.handlePointerUp_, this)
- );
- }
- };
- /**
- * @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
- * @private
- */
- ol.MapBrowserEventHandler.prototype.handlePointerMove_ = function(pointerEvent) {
- // Between pointerdown and pointerup, pointermove events are triggered.
- // To avoid a 'false' touchmove event to be dispatched, we test if the pointer
- // moved a significant distance.
- if (this.isMoving_(pointerEvent)) {
- this.dragging_ = true;
- var newEvent = new ol.MapBrowserPointerEvent(
- ol.MapBrowserEventType.POINTERDRAG, this.map_, pointerEvent,
- this.dragging_);
- this.dispatchEvent(newEvent);
- }
- // Some native android browser triggers mousemove events during small period
- // of time. See: https://code.google.com/p/android/issues/detail?id=5491 or
- // https://code.google.com/p/android/issues/detail?id=19827
- // ex: Galaxy Tab P3110 + Android 4.1.1
- pointerEvent.preventDefault();
- };
- /**
- * Wrap and relay a pointer event. Note that this requires that the type
- * string for the MapBrowserPointerEvent matches the PointerEvent type.
- * @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
- * @private
- */
- ol.MapBrowserEventHandler.prototype.relayEvent_ = function(pointerEvent) {
- var dragging = !!(this.down_ && this.isMoving_(pointerEvent));
- this.dispatchEvent(new ol.MapBrowserPointerEvent(
- pointerEvent.type, this.map_, pointerEvent, dragging));
- };
- /**
- * @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
- * @return {boolean} Is moving.
- * @private
- */
- ol.MapBrowserEventHandler.prototype.isMoving_ = function(pointerEvent) {
- return Math.abs(pointerEvent.clientX - this.down_.clientX) > this.moveTolerance_ ||
- Math.abs(pointerEvent.clientY - this.down_.clientY) > this.moveTolerance_;
- };
- /**
- * @inheritDoc
- */
- ol.MapBrowserEventHandler.prototype.disposeInternal = function() {
- if (this.relayedListenerKey_) {
- ol.events.unlistenByKey(this.relayedListenerKey_);
- this.relayedListenerKey_ = null;
- }
- if (this.pointerdownListenerKey_) {
- ol.events.unlistenByKey(this.pointerdownListenerKey_);
- this.pointerdownListenerKey_ = null;
- }
- this.dragListenerKeys_.forEach(ol.events.unlistenByKey);
- this.dragListenerKeys_.length = 0;
- if (this.documentPointerEventHandler_) {
- this.documentPointerEventHandler_.dispose();
- this.documentPointerEventHandler_ = null;
- }
- if (this.pointerEventHandler_) {
- this.pointerEventHandler_.dispose();
- this.pointerEventHandler_ = null;
- }
- ol.events.EventTarget.prototype.disposeInternal.call(this);
- };
- goog.provide('ol.MapEventType');
- /**
- * @enum {string}
- */
- ol.MapEventType = {
- /**
- * Triggered after a map frame is rendered.
- * @event ol.MapEvent#postrender
- * @api
- */
- POSTRENDER: 'postrender',
- /**
- * Triggered when the map starts moving.
- * @event ol.MapEvent#movestart
- * @api
- */
- MOVESTART: 'movestart',
- /**
- * Triggered after the map is moved.
- * @event ol.MapEvent#moveend
- * @api
- */
- MOVEEND: 'moveend'
- };
- goog.provide('ol.MapProperty');
- /**
- * @enum {string}
- */
- ol.MapProperty = {
- LAYERGROUP: 'layergroup',
- SIZE: 'size',
- TARGET: 'target',
- VIEW: 'view'
- };
- goog.provide('ol.TileState');
- /**
- * @enum {number}
- */
- ol.TileState = {
- IDLE: 0,
- LOADING: 1,
- LOADED: 2,
- ERROR: 3,
- EMPTY: 4,
- ABORT: 5
- };
- goog.provide('ol.structs.PriorityQueue');
- goog.require('ol.asserts');
- goog.require('ol.obj');
- /**
- * Priority queue.
- *
- * The implementation is inspired from the Closure Library's Heap class and
- * Python's heapq module.
- *
- * @see http://closure-library.googlecode.com/svn/docs/closure_goog_structs_heap.js.source.html
- * @see http://hg.python.org/cpython/file/2.7/Lib/heapq.py
- *
- * @constructor
- * @param {function(T): number} priorityFunction Priority function.
- * @param {function(T): string} keyFunction Key function.
- * @struct
- * @template T
- */
- ol.structs.PriorityQueue = function(priorityFunction, keyFunction) {
- /**
- * @type {function(T): number}
- * @private
- */
- this.priorityFunction_ = priorityFunction;
- /**
- * @type {function(T): string}
- * @private
- */
- this.keyFunction_ = keyFunction;
- /**
- * @type {Array.<T>}
- * @private
- */
- this.elements_ = [];
- /**
- * @type {Array.<number>}
- * @private
- */
- this.priorities_ = [];
- /**
- * @type {Object.<string, boolean>}
- * @private
- */
- this.queuedElements_ = {};
- };
- /**
- * @const
- * @type {number}
- */
- ol.structs.PriorityQueue.DROP = Infinity;
- /**
- * FIXME empty description for jsdoc
- */
- ol.structs.PriorityQueue.prototype.clear = function() {
- this.elements_.length = 0;
- this.priorities_.length = 0;
- ol.obj.clear(this.queuedElements_);
- };
- /**
- * Remove and return the highest-priority element. O(log N).
- * @return {T} Element.
- */
- ol.structs.PriorityQueue.prototype.dequeue = function() {
- var elements = this.elements_;
- var priorities = this.priorities_;
- var element = elements[0];
- if (elements.length == 1) {
- elements.length = 0;
- priorities.length = 0;
- } else {
- elements[0] = elements.pop();
- priorities[0] = priorities.pop();
- this.siftUp_(0);
- }
- var elementKey = this.keyFunction_(element);
- delete this.queuedElements_[elementKey];
- return element;
- };
- /**
- * Enqueue an element. O(log N).
- * @param {T} element Element.
- * @return {boolean} The element was added to the queue.
- */
- ol.structs.PriorityQueue.prototype.enqueue = function(element) {
- ol.asserts.assert(!(this.keyFunction_(element) in this.queuedElements_),
- 31); // Tried to enqueue an `element` that was already added to the queue
- var priority = this.priorityFunction_(element);
- if (priority != ol.structs.PriorityQueue.DROP) {
- this.elements_.push(element);
- this.priorities_.push(priority);
- this.queuedElements_[this.keyFunction_(element)] = true;
- this.siftDown_(0, this.elements_.length - 1);
- return true;
- }
- return false;
- };
- /**
- * @return {number} Count.
- */
- ol.structs.PriorityQueue.prototype.getCount = function() {
- return this.elements_.length;
- };
- /**
- * Gets the index of the left child of the node at the given index.
- * @param {number} index The index of the node to get the left child for.
- * @return {number} The index of the left child.
- * @private
- */
- ol.structs.PriorityQueue.prototype.getLeftChildIndex_ = function(index) {
- return index * 2 + 1;
- };
- /**
- * Gets the index of the right child of the node at the given index.
- * @param {number} index The index of the node to get the right child for.
- * @return {number} The index of the right child.
- * @private
- */
- ol.structs.PriorityQueue.prototype.getRightChildIndex_ = function(index) {
- return index * 2 + 2;
- };
- /**
- * Gets the index of the parent of the node at the given index.
- * @param {number} index The index of the node to get the parent for.
- * @return {number} The index of the parent.
- * @private
- */
- ol.structs.PriorityQueue.prototype.getParentIndex_ = function(index) {
- return (index - 1) >> 1;
- };
- /**
- * Make this a heap. O(N).
- * @private
- */
- ol.structs.PriorityQueue.prototype.heapify_ = function() {
- var i;
- for (i = (this.elements_.length >> 1) - 1; i >= 0; i--) {
- this.siftUp_(i);
- }
- };
- /**
- * @return {boolean} Is empty.
- */
- ol.structs.PriorityQueue.prototype.isEmpty = function() {
- return this.elements_.length === 0;
- };
- /**
- * @param {string} key Key.
- * @return {boolean} Is key queued.
- */
- ol.structs.PriorityQueue.prototype.isKeyQueued = function(key) {
- return key in this.queuedElements_;
- };
- /**
- * @param {T} element Element.
- * @return {boolean} Is queued.
- */
- ol.structs.PriorityQueue.prototype.isQueued = function(element) {
- return this.isKeyQueued(this.keyFunction_(element));
- };
- /**
- * @param {number} index The index of the node to move down.
- * @private
- */
- ol.structs.PriorityQueue.prototype.siftUp_ = function(index) {
- var elements = this.elements_;
- var priorities = this.priorities_;
- var count = elements.length;
- var element = elements[index];
- var priority = priorities[index];
- var startIndex = index;
- while (index < (count >> 1)) {
- var lIndex = this.getLeftChildIndex_(index);
- var rIndex = this.getRightChildIndex_(index);
- var smallerChildIndex = rIndex < count &&
- priorities[rIndex] < priorities[lIndex] ?
- rIndex : lIndex;
- elements[index] = elements[smallerChildIndex];
- priorities[index] = priorities[smallerChildIndex];
- index = smallerChildIndex;
- }
- elements[index] = element;
- priorities[index] = priority;
- this.siftDown_(startIndex, index);
- };
- /**
- * @param {number} startIndex The index of the root.
- * @param {number} index The index of the node to move up.
- * @private
- */
- ol.structs.PriorityQueue.prototype.siftDown_ = function(startIndex, index) {
- var elements = this.elements_;
- var priorities = this.priorities_;
- var element = elements[index];
- var priority = priorities[index];
- while (index > startIndex) {
- var parentIndex = this.getParentIndex_(index);
- if (priorities[parentIndex] > priority) {
- elements[index] = elements[parentIndex];
- priorities[index] = priorities[parentIndex];
- index = parentIndex;
- } else {
- break;
- }
- }
- elements[index] = element;
- priorities[index] = priority;
- };
- /**
- * FIXME empty description for jsdoc
- */
- ol.structs.PriorityQueue.prototype.reprioritize = function() {
- var priorityFunction = this.priorityFunction_;
- var elements = this.elements_;
- var priorities = this.priorities_;
- var index = 0;
- var n = elements.length;
- var element, i, priority;
- for (i = 0; i < n; ++i) {
- element = elements[i];
- priority = priorityFunction(element);
- if (priority == ol.structs.PriorityQueue.DROP) {
- delete this.queuedElements_[this.keyFunction_(element)];
- } else {
- priorities[index] = priority;
- elements[index++] = element;
- }
- }
- elements.length = index;
- priorities.length = index;
- this.heapify_();
- };
- goog.provide('ol.TileQueue');
- goog.require('ol');
- goog.require('ol.TileState');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.structs.PriorityQueue');
- /**
- * @constructor
- * @extends {ol.structs.PriorityQueue.<Array>}
- * @param {ol.TilePriorityFunction} tilePriorityFunction
- * Tile priority function.
- * @param {function(): ?} tileChangeCallback
- * Function called on each tile change event.
- * @struct
- */
- ol.TileQueue = function(tilePriorityFunction, tileChangeCallback) {
- ol.structs.PriorityQueue.call(
- this,
- /**
- * @param {Array} element Element.
- * @return {number} Priority.
- */
- function(element) {
- return tilePriorityFunction.apply(null, element);
- },
- /**
- * @param {Array} element Element.
- * @return {string} Key.
- */
- function(element) {
- return /** @type {ol.Tile} */ (element[0]).getKey();
- });
- /**
- * @private
- * @type {function(): ?}
- */
- this.tileChangeCallback_ = tileChangeCallback;
- /**
- * @private
- * @type {number}
- */
- this.tilesLoading_ = 0;
- /**
- * @private
- * @type {!Object.<string,boolean>}
- */
- this.tilesLoadingKeys_ = {};
- };
- ol.inherits(ol.TileQueue, ol.structs.PriorityQueue);
- /**
- * @inheritDoc
- */
- ol.TileQueue.prototype.enqueue = function(element) {
- var added = ol.structs.PriorityQueue.prototype.enqueue.call(this, element);
- if (added) {
- var tile = element[0];
- ol.events.listen(tile, ol.events.EventType.CHANGE,
- this.handleTileChange, this);
- }
- return added;
- };
- /**
- * @return {number} Number of tiles loading.
- */
- ol.TileQueue.prototype.getTilesLoading = function() {
- return this.tilesLoading_;
- };
- /**
- * @param {ol.events.Event} event Event.
- * @protected
- */
- ol.TileQueue.prototype.handleTileChange = function(event) {
- var tile = /** @type {ol.Tile} */ (event.target);
- var state = tile.getState();
- if (state === ol.TileState.LOADED || state === ol.TileState.ERROR ||
- state === ol.TileState.EMPTY || state === ol.TileState.ABORT) {
- ol.events.unlisten(tile, ol.events.EventType.CHANGE,
- this.handleTileChange, this);
- var tileKey = tile.getKey();
- if (tileKey in this.tilesLoadingKeys_) {
- delete this.tilesLoadingKeys_[tileKey];
- --this.tilesLoading_;
- }
- this.tileChangeCallback_();
- }
- };
- /**
- * @param {number} maxTotalLoading Maximum number tiles to load simultaneously.
- * @param {number} maxNewLoads Maximum number of new tiles to load.
- */
- ol.TileQueue.prototype.loadMoreTiles = function(maxTotalLoading, maxNewLoads) {
- var newLoads = 0;
- var abortedTiles = false;
- var state, tile, tileKey;
- while (this.tilesLoading_ < maxTotalLoading && newLoads < maxNewLoads &&
- this.getCount() > 0) {
- tile = /** @type {ol.Tile} */ (this.dequeue()[0]);
- tileKey = tile.getKey();
- state = tile.getState();
- if (state === ol.TileState.ABORT) {
- abortedTiles = true;
- } else if (state === ol.TileState.IDLE && !(tileKey in this.tilesLoadingKeys_)) {
- this.tilesLoadingKeys_[tileKey] = true;
- ++this.tilesLoading_;
- ++newLoads;
- tile.load();
- }
- }
- if (newLoads === 0 && abortedTiles) {
- // Do not stop the render loop when all wanted tiles were aborted due to
- // a small, saturated tile cache.
- this.tileChangeCallback_();
- }
- };
- goog.provide('ol.CenterConstraint');
- goog.require('ol.math');
- /**
- * @param {ol.Extent} extent Extent.
- * @return {ol.CenterConstraintType} The constraint.
- */
- ol.CenterConstraint.createExtent = function(extent) {
- return (
- /**
- * @param {ol.Coordinate|undefined} center Center.
- * @return {ol.Coordinate|undefined} Center.
- */
- function(center) {
- if (center) {
- return [
- ol.math.clamp(center[0], extent[0], extent[2]),
- ol.math.clamp(center[1], extent[1], extent[3])
- ];
- } else {
- return undefined;
- }
- });
- };
- /**
- * @param {ol.Coordinate|undefined} center Center.
- * @return {ol.Coordinate|undefined} Center.
- */
- ol.CenterConstraint.none = function(center) {
- return center;
- };
- goog.provide('ol.ResolutionConstraint');
- goog.require('ol.array');
- goog.require('ol.math');
- /**
- * @param {Array.<number>} resolutions Resolutions.
- * @return {ol.ResolutionConstraintType} Zoom function.
- */
- ol.ResolutionConstraint.createSnapToResolutions = function(resolutions) {
- return (
- /**
- * @param {number|undefined} resolution Resolution.
- * @param {number} delta Delta.
- * @param {number} direction Direction.
- * @return {number|undefined} Resolution.
- */
- function(resolution, delta, direction) {
- if (resolution !== undefined) {
- var z =
- ol.array.linearFindNearest(resolutions, resolution, direction);
- z = ol.math.clamp(z + delta, 0, resolutions.length - 1);
- var index = Math.floor(z);
- if (z != index && index < resolutions.length - 1) {
- var power = resolutions[index] / resolutions[index + 1];
- return resolutions[index] / Math.pow(power, z - index);
- } else {
- return resolutions[index];
- }
- } else {
- return undefined;
- }
- });
- };
- /**
- * @param {number} power Power.
- * @param {number} maxResolution Maximum resolution.
- * @param {number=} opt_maxLevel Maximum level.
- * @return {ol.ResolutionConstraintType} Zoom function.
- */
- ol.ResolutionConstraint.createSnapToPower = function(power, maxResolution, opt_maxLevel) {
- return (
- /**
- * @param {number|undefined} resolution Resolution.
- * @param {number} delta Delta.
- * @param {number} direction Direction.
- * @return {number|undefined} Resolution.
- */
- function(resolution, delta, direction) {
- if (resolution !== undefined) {
- var offset = -direction / 2 + 0.5;
- var oldLevel = Math.floor(
- Math.log(maxResolution / resolution) / Math.log(power) + offset);
- var newLevel = Math.max(oldLevel + delta, 0);
- if (opt_maxLevel !== undefined) {
- newLevel = Math.min(newLevel, opt_maxLevel);
- }
- return maxResolution / Math.pow(power, newLevel);
- } else {
- return undefined;
- }
- });
- };
- goog.provide('ol.RotationConstraint');
- goog.require('ol.math');
- /**
- * @param {number|undefined} rotation Rotation.
- * @param {number} delta Delta.
- * @return {number|undefined} Rotation.
- */
- ol.RotationConstraint.disable = function(rotation, delta) {
- if (rotation !== undefined) {
- return 0;
- } else {
- return undefined;
- }
- };
- /**
- * @param {number|undefined} rotation Rotation.
- * @param {number} delta Delta.
- * @return {number|undefined} Rotation.
- */
- ol.RotationConstraint.none = function(rotation, delta) {
- if (rotation !== undefined) {
- return rotation + delta;
- } else {
- return undefined;
- }
- };
- /**
- * @param {number} n N.
- * @return {ol.RotationConstraintType} Rotation constraint.
- */
- ol.RotationConstraint.createSnapToN = function(n) {
- var theta = 2 * Math.PI / n;
- return (
- /**
- * @param {number|undefined} rotation Rotation.
- * @param {number} delta Delta.
- * @return {number|undefined} Rotation.
- */
- function(rotation, delta) {
- if (rotation !== undefined) {
- rotation = Math.floor((rotation + delta) / theta + 0.5) * theta;
- return rotation;
- } else {
- return undefined;
- }
- });
- };
- /**
- * @param {number=} opt_tolerance Tolerance.
- * @return {ol.RotationConstraintType} Rotation constraint.
- */
- ol.RotationConstraint.createSnapToZero = function(opt_tolerance) {
- var tolerance = opt_tolerance || ol.math.toRadians(5);
- return (
- /**
- * @param {number|undefined} rotation Rotation.
- * @param {number} delta Delta.
- * @return {number|undefined} Rotation.
- */
- function(rotation, delta) {
- if (rotation !== undefined) {
- if (Math.abs(rotation + delta) <= tolerance) {
- return 0;
- } else {
- return rotation + delta;
- }
- } else {
- return undefined;
- }
- });
- };
- goog.provide('ol.ViewHint');
- /**
- * @enum {number}
- */
- ol.ViewHint = {
- ANIMATING: 0,
- INTERACTING: 1
- };
- goog.provide('ol.ViewProperty');
- /**
- * @enum {string}
- */
- ol.ViewProperty = {
- CENTER: 'center',
- RESOLUTION: 'resolution',
- ROTATION: 'rotation'
- };
- goog.provide('ol.string');
- /**
- * @param {number} number Number to be formatted
- * @param {number} width The desired width
- * @param {number=} opt_precision Precision of the output string (i.e. number of decimal places)
- * @returns {string} Formatted string
- */
- ol.string.padNumber = function(number, width, opt_precision) {
- var numberString = opt_precision !== undefined ? number.toFixed(opt_precision) : '' + number;
- var decimal = numberString.indexOf('.');
- decimal = decimal === -1 ? numberString.length : decimal;
- return decimal > width ? numberString : new Array(1 + width - decimal).join('0') + numberString;
- };
- /**
- * Adapted from https://github.com/omichelsen/compare-versions/blob/master/index.js
- * @param {string|number} v1 First version
- * @param {string|number} v2 Second version
- * @returns {number} Value
- */
- ol.string.compareVersions = function(v1, v2) {
- var s1 = ('' + v1).split('.');
- var s2 = ('' + v2).split('.');
- for (var i = 0; i < Math.max(s1.length, s2.length); i++) {
- var n1 = parseInt(s1[i] || '0', 10);
- var n2 = parseInt(s2[i] || '0', 10);
- if (n1 > n2) {
- return 1;
- }
- if (n2 > n1) {
- return -1;
- }
- }
- return 0;
- };
- goog.provide('ol.coordinate');
- goog.require('ol.math');
- goog.require('ol.string');
- /**
- * Add `delta` to `coordinate`. `coordinate` is modified in place and returned
- * by the function.
- *
- * Example:
- *
- * var coord = [7.85, 47.983333];
- * ol.coordinate.add(coord, [-2, 4]);
- * // coord is now [5.85, 51.983333]
- *
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {ol.Coordinate} delta Delta.
- * @return {ol.Coordinate} The input coordinate adjusted by the given delta.
- * @api
- */
- ol.coordinate.add = function(coordinate, delta) {
- coordinate[0] += delta[0];
- coordinate[1] += delta[1];
- return coordinate;
- };
- /**
- * Calculates the point closest to the passed coordinate on the passed circle.
- *
- * @param {ol.Coordinate} coordinate The coordinate.
- * @param {ol.geom.Circle} circle The circle.
- * @return {ol.Coordinate} Closest point on the circumference
- */
- ol.coordinate.closestOnCircle = function(coordinate, circle) {
- var r = circle.getRadius();
- var center = circle.getCenter();
- var x0 = center[0];
- var y0 = center[1];
- var x1 = coordinate[0];
- var y1 = coordinate[1];
- var dx = x1 - x0;
- var dy = y1 - y0;
- if (dx === 0 && dy === 0) {
- dx = 1;
- }
- var d = Math.sqrt(dx * dx + dy * dy);
- var x, y;
- x = x0 + r * dx / d;
- y = y0 + r * dy / d;
- return [x, y];
- };
- /**
- * Calculates the point closest to the passed coordinate on the passed segment.
- * This is the foot of the perpendicular of the coordinate to the segment when
- * the foot is on the segment, or the closest segment coordinate when the foot
- * is outside the segment.
- *
- * @param {ol.Coordinate} coordinate The coordinate.
- * @param {Array.<ol.Coordinate>} segment The two coordinates of the segment.
- * @return {ol.Coordinate} The foot of the perpendicular of the coordinate to
- * the segment.
- */
- ol.coordinate.closestOnSegment = function(coordinate, segment) {
- var x0 = coordinate[0];
- var y0 = coordinate[1];
- var start = segment[0];
- var end = segment[1];
- var x1 = start[0];
- var y1 = start[1];
- var x2 = end[0];
- var y2 = end[1];
- var dx = x2 - x1;
- var dy = y2 - y1;
- var along = (dx === 0 && dy === 0) ? 0 :
- ((dx * (x0 - x1)) + (dy * (y0 - y1))) / ((dx * dx + dy * dy) || 0);
- var x, y;
- if (along <= 0) {
- x = x1;
- y = y1;
- } else if (along >= 1) {
- x = x2;
- y = y2;
- } else {
- x = x1 + along * dx;
- y = y1 + along * dy;
- }
- return [x, y];
- };
- /**
- * Returns a {@link ol.CoordinateFormatType} function that can be used to format
- * a {ol.Coordinate} to a string.
- *
- * Example without specifying the fractional digits:
- *
- * var coord = [7.85, 47.983333];
- * var stringifyFunc = ol.coordinate.createStringXY();
- * var out = stringifyFunc(coord);
- * // out is now '8, 48'
- *
- * Example with explicitly specifying 2 fractional digits:
- *
- * var coord = [7.85, 47.983333];
- * var stringifyFunc = ol.coordinate.createStringXY(2);
- * var out = stringifyFunc(coord);
- * // out is now '7.85, 47.98'
- *
- * @param {number=} opt_fractionDigits The number of digits to include
- * after the decimal point. Default is `0`.
- * @return {ol.CoordinateFormatType} Coordinate format.
- * @api
- */
- ol.coordinate.createStringXY = function(opt_fractionDigits) {
- return (
- /**
- * @param {ol.Coordinate|undefined} coordinate Coordinate.
- * @return {string} String XY.
- */
- function(coordinate) {
- return ol.coordinate.toStringXY(coordinate, opt_fractionDigits);
- });
- };
- /**
- * @param {string} hemispheres Hemispheres.
- * @param {number} degrees Degrees.
- * @param {number=} opt_fractionDigits The number of digits to include
- * after the decimal point. Default is `0`.
- * @return {string} String.
- */
- ol.coordinate.degreesToStringHDMS = function(hemispheres, degrees, opt_fractionDigits) {
- var normalizedDegrees = ol.math.modulo(degrees + 180, 360) - 180;
- var x = Math.abs(3600 * normalizedDegrees);
- var dflPrecision = opt_fractionDigits || 0;
- var precision = Math.pow(10, dflPrecision);
- var deg = Math.floor(x / 3600);
- var min = Math.floor((x - deg * 3600) / 60);
- var sec = x - (deg * 3600) - (min * 60);
- sec = Math.ceil(sec * precision) / precision;
- if (sec >= 60) {
- sec = 0;
- min += 1;
- }
- if (min >= 60) {
- min = 0;
- deg += 1;
- }
- return deg + '\u00b0 ' + ol.string.padNumber(min, 2) + '\u2032 ' +
- ol.string.padNumber(sec, 2, dflPrecision) + '\u2033' +
- (normalizedDegrees == 0 ? '' : ' ' + hemispheres.charAt(normalizedDegrees < 0 ? 1 : 0));
- };
- /**
- * Transforms the given {@link ol.Coordinate} to a string using the given string
- * template. The strings `{x}` and `{y}` in the template will be replaced with
- * the first and second coordinate values respectively.
- *
- * Example without specifying the fractional digits:
- *
- * var coord = [7.85, 47.983333];
- * var template = 'Coordinate is ({x}|{y}).';
- * var out = ol.coordinate.format(coord, template);
- * // out is now 'Coordinate is (8|48).'
- *
- * Example explicitly specifying the fractional digits:
- *
- * var coord = [7.85, 47.983333];
- * var template = 'Coordinate is ({x}|{y}).';
- * var out = ol.coordinate.format(coord, template, 2);
- * // out is now 'Coordinate is (7.85|47.98).'
- *
- * @param {ol.Coordinate|undefined} coordinate Coordinate.
- * @param {string} template A template string with `{x}` and `{y}` placeholders
- * that will be replaced by first and second coordinate values.
- * @param {number=} opt_fractionDigits The number of digits to include
- * after the decimal point. Default is `0`.
- * @return {string} Formatted coordinate.
- * @api
- */
- ol.coordinate.format = function(coordinate, template, opt_fractionDigits) {
- if (coordinate) {
- return template
- .replace('{x}', coordinate[0].toFixed(opt_fractionDigits))
- .replace('{y}', coordinate[1].toFixed(opt_fractionDigits));
- } else {
- return '';
- }
- };
- /**
- * @param {ol.Coordinate} coordinate1 First coordinate.
- * @param {ol.Coordinate} coordinate2 Second coordinate.
- * @return {boolean} Whether the passed coordinates are equal.
- */
- ol.coordinate.equals = function(coordinate1, coordinate2) {
- var equals = true;
- for (var i = coordinate1.length - 1; i >= 0; --i) {
- if (coordinate1[i] != coordinate2[i]) {
- equals = false;
- break;
- }
- }
- return equals;
- };
- /**
- * Rotate `coordinate` by `angle`. `coordinate` is modified in place and
- * returned by the function.
- *
- * Example:
- *
- * var coord = [7.85, 47.983333];
- * var rotateRadians = Math.PI / 2; // 90 degrees
- * ol.coordinate.rotate(coord, rotateRadians);
- * // coord is now [-47.983333, 7.85]
- *
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {number} angle Angle in radian.
- * @return {ol.Coordinate} Coordinate.
- * @api
- */
- ol.coordinate.rotate = function(coordinate, angle) {
- var cosAngle = Math.cos(angle);
- var sinAngle = Math.sin(angle);
- var x = coordinate[0] * cosAngle - coordinate[1] * sinAngle;
- var y = coordinate[1] * cosAngle + coordinate[0] * sinAngle;
- coordinate[0] = x;
- coordinate[1] = y;
- return coordinate;
- };
- /**
- * Scale `coordinate` by `scale`. `coordinate` is modified in place and returned
- * by the function.
- *
- * Example:
- *
- * var coord = [7.85, 47.983333];
- * var scale = 1.2;
- * ol.coordinate.scale(coord, scale);
- * // coord is now [9.42, 57.5799996]
- *
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {number} scale Scale factor.
- * @return {ol.Coordinate} Coordinate.
- */
- ol.coordinate.scale = function(coordinate, scale) {
- coordinate[0] *= scale;
- coordinate[1] *= scale;
- return coordinate;
- };
- /**
- * Subtract `delta` to `coordinate`. `coordinate` is modified in place and
- * returned by the function.
- *
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {ol.Coordinate} delta Delta.
- * @return {ol.Coordinate} Coordinate.
- */
- ol.coordinate.sub = function(coordinate, delta) {
- coordinate[0] -= delta[0];
- coordinate[1] -= delta[1];
- return coordinate;
- };
- /**
- * @param {ol.Coordinate} coord1 First coordinate.
- * @param {ol.Coordinate} coord2 Second coordinate.
- * @return {number} Squared distance between coord1 and coord2.
- */
- ol.coordinate.squaredDistance = function(coord1, coord2) {
- var dx = coord1[0] - coord2[0];
- var dy = coord1[1] - coord2[1];
- return dx * dx + dy * dy;
- };
- /**
- * @param {ol.Coordinate} coord1 First coordinate.
- * @param {ol.Coordinate} coord2 Second coordinate.
- * @return {number} Distance between coord1 and coord2.
- */
- ol.coordinate.distance = function(coord1, coord2) {
- return Math.sqrt(ol.coordinate.squaredDistance(coord1, coord2));
- };
- /**
- * Calculate the squared distance from a coordinate to a line segment.
- *
- * @param {ol.Coordinate} coordinate Coordinate of the point.
- * @param {Array.<ol.Coordinate>} segment Line segment (2 coordinates).
- * @return {number} Squared distance from the point to the line segment.
- */
- ol.coordinate.squaredDistanceToSegment = function(coordinate, segment) {
- return ol.coordinate.squaredDistance(coordinate,
- ol.coordinate.closestOnSegment(coordinate, segment));
- };
- /**
- * Format a geographic coordinate with the hemisphere, degrees, minutes, and
- * seconds.
- *
- * Example without specifying fractional digits:
- *
- * var coord = [7.85, 47.983333];
- * var out = ol.coordinate.toStringHDMS(coord);
- * // out is now '47° 58′ 60″ N 7° 50′ 60″ E'
- *
- * Example explicitly specifying 1 fractional digit:
- *
- * var coord = [7.85, 47.983333];
- * var out = ol.coordinate.toStringHDMS(coord, 1);
- * // out is now '47° 58′ 60.0″ N 7° 50′ 60.0″ E'
- *
- * @param {ol.Coordinate|undefined} coordinate Coordinate.
- * @param {number=} opt_fractionDigits The number of digits to include
- * after the decimal point. Default is `0`.
- * @return {string} Hemisphere, degrees, minutes and seconds.
- * @api
- */
- ol.coordinate.toStringHDMS = function(coordinate, opt_fractionDigits) {
- if (coordinate) {
- return ol.coordinate.degreesToStringHDMS('NS', coordinate[1], opt_fractionDigits) + ' ' +
- ol.coordinate.degreesToStringHDMS('EW', coordinate[0], opt_fractionDigits);
- } else {
- return '';
- }
- };
- /**
- * Format a coordinate as a comma delimited string.
- *
- * Example without specifying fractional digits:
- *
- * var coord = [7.85, 47.983333];
- * var out = ol.coordinate.toStringXY(coord);
- * // out is now '8, 48'
- *
- * Example explicitly specifying 1 fractional digit:
- *
- * var coord = [7.85, 47.983333];
- * var out = ol.coordinate.toStringXY(coord, 1);
- * // out is now '7.8, 48.0'
- *
- * @param {ol.Coordinate|undefined} coordinate Coordinate.
- * @param {number=} opt_fractionDigits The number of digits to include
- * after the decimal point. Default is `0`.
- * @return {string} XY.
- * @api
- */
- ol.coordinate.toStringXY = function(coordinate, opt_fractionDigits) {
- return ol.coordinate.format(coordinate, '{x}, {y}', opt_fractionDigits);
- };
- goog.provide('ol.easing');
- /**
- * Start slow and speed up.
- * @param {number} t Input between 0 and 1.
- * @return {number} Output between 0 and 1.
- * @api
- */
- ol.easing.easeIn = function(t) {
- return Math.pow(t, 3);
- };
- /**
- * Start fast and slow down.
- * @param {number} t Input between 0 and 1.
- * @return {number} Output between 0 and 1.
- * @api
- */
- ol.easing.easeOut = function(t) {
- return 1 - ol.easing.easeIn(1 - t);
- };
- /**
- * Start slow, speed up, and then slow down again.
- * @param {number} t Input between 0 and 1.
- * @return {number} Output between 0 and 1.
- * @api
- */
- ol.easing.inAndOut = function(t) {
- return 3 * t * t - 2 * t * t * t;
- };
- /**
- * Maintain a constant speed over time.
- * @param {number} t Input between 0 and 1.
- * @return {number} Output between 0 and 1.
- * @api
- */
- ol.easing.linear = function(t) {
- return t;
- };
- /**
- * Start slow, speed up, and at the very end slow down again. This has the
- * same general behavior as {@link ol.easing.inAndOut}, but the final slowdown
- * is delayed.
- * @param {number} t Input between 0 and 1.
- * @return {number} Output between 0 and 1.
- * @api
- */
- ol.easing.upAndDown = function(t) {
- if (t < 0.5) {
- return ol.easing.inAndOut(2 * t);
- } else {
- return 1 - ol.easing.inAndOut(2 * (t - 0.5));
- }
- };
- goog.provide('ol.geom.GeometryLayout');
- /**
- * The coordinate layout for geometries, indicating whether a 3rd or 4th z ('Z')
- * or measure ('M') coordinate is available. Supported values are `'XY'`,
- * `'XYZ'`, `'XYM'`, `'XYZM'`.
- * @enum {string}
- */
- ol.geom.GeometryLayout = {
- XY: 'XY',
- XYZ: 'XYZ',
- XYM: 'XYM',
- XYZM: 'XYZM'
- };
- goog.provide('ol.functions');
- /**
- * Always returns true.
- * @returns {boolean} true.
- */
- ol.functions.TRUE = function() {
- return true;
- };
- /**
- * Always returns false.
- * @returns {boolean} false.
- */
- ol.functions.FALSE = function() {
- return false;
- };
- goog.provide('ol.geom.flat.transform');
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {ol.Transform} transform Transform.
- * @param {Array.<number>=} opt_dest Destination.
- * @return {Array.<number>} Transformed coordinates.
- */
- ol.geom.flat.transform.transform2D = function(flatCoordinates, offset, end, stride, transform, opt_dest) {
- var dest = opt_dest ? opt_dest : [];
- var i = 0;
- var j;
- for (j = offset; j < end; j += stride) {
- var x = flatCoordinates[j];
- var y = flatCoordinates[j + 1];
- dest[i++] = transform[0] * x + transform[2] * y + transform[4];
- dest[i++] = transform[1] * x + transform[3] * y + transform[5];
- }
- if (opt_dest && dest.length != i) {
- dest.length = i;
- }
- return dest;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {number} angle Angle.
- * @param {Array.<number>} anchor Rotation anchor point.
- * @param {Array.<number>=} opt_dest Destination.
- * @return {Array.<number>} Transformed coordinates.
- */
- ol.geom.flat.transform.rotate = function(flatCoordinates, offset, end, stride, angle, anchor, opt_dest) {
- var dest = opt_dest ? opt_dest : [];
- var cos = Math.cos(angle);
- var sin = Math.sin(angle);
- var anchorX = anchor[0];
- var anchorY = anchor[1];
- var i = 0;
- for (var j = offset; j < end; j += stride) {
- var deltaX = flatCoordinates[j] - anchorX;
- var deltaY = flatCoordinates[j + 1] - anchorY;
- dest[i++] = anchorX + deltaX * cos - deltaY * sin;
- dest[i++] = anchorY + deltaX * sin + deltaY * cos;
- for (var k = j + 2; k < j + stride; ++k) {
- dest[i++] = flatCoordinates[k];
- }
- }
- if (opt_dest && dest.length != i) {
- dest.length = i;
- }
- return dest;
- };
- /**
- * Scale the coordinates.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {number} sx Scale factor in the x-direction.
- * @param {number} sy Scale factor in the y-direction.
- * @param {Array.<number>} anchor Scale anchor point.
- * @param {Array.<number>=} opt_dest Destination.
- * @return {Array.<number>} Transformed coordinates.
- */
- ol.geom.flat.transform.scale = function(flatCoordinates, offset, end, stride, sx, sy, anchor, opt_dest) {
- var dest = opt_dest ? opt_dest : [];
- var anchorX = anchor[0];
- var anchorY = anchor[1];
- var i = 0;
- for (var j = offset; j < end; j += stride) {
- var deltaX = flatCoordinates[j] - anchorX;
- var deltaY = flatCoordinates[j + 1] - anchorY;
- dest[i++] = anchorX + sx * deltaX;
- dest[i++] = anchorY + sy * deltaY;
- for (var k = j + 2; k < j + stride; ++k) {
- dest[i++] = flatCoordinates[k];
- }
- }
- if (opt_dest && dest.length != i) {
- dest.length = i;
- }
- return dest;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {number} deltaX Delta X.
- * @param {number} deltaY Delta Y.
- * @param {Array.<number>=} opt_dest Destination.
- * @return {Array.<number>} Transformed coordinates.
- */
- ol.geom.flat.transform.translate = function(flatCoordinates, offset, end, stride, deltaX, deltaY, opt_dest) {
- var dest = opt_dest ? opt_dest : [];
- var i = 0;
- var j, k;
- for (j = offset; j < end; j += stride) {
- dest[i++] = flatCoordinates[j] + deltaX;
- dest[i++] = flatCoordinates[j + 1] + deltaY;
- for (k = j + 2; k < j + stride; ++k) {
- dest[i++] = flatCoordinates[k];
- }
- }
- if (opt_dest && dest.length != i) {
- dest.length = i;
- }
- return dest;
- };
- goog.provide('ol.transform');
- goog.require('ol.asserts');
- /**
- * Collection of affine 2d transformation functions. The functions work on an
- * array of 6 elements. The element order is compatible with the [SVGMatrix
- * interface](https://developer.mozilla.org/en-US/docs/Web/API/SVGMatrix) and is
- * a subset (elements a to f) of a 3x3 martrix:
- * ```
- * [ a c e ]
- * [ b d f ]
- * [ 0 0 1 ]
- * ```
- */
- /**
- * @private
- * @type {ol.Transform}
- */
- ol.transform.tmp_ = new Array(6);
- /**
- * Create an identity transform.
- * @return {!ol.Transform} Identity transform.
- */
- ol.transform.create = function() {
- return [1, 0, 0, 1, 0, 0];
- };
- /**
- * Resets the given transform to an identity transform.
- * @param {!ol.Transform} transform Transform.
- * @return {!ol.Transform} Transform.
- */
- ol.transform.reset = function(transform) {
- return ol.transform.set(transform, 1, 0, 0, 1, 0, 0);
- };
- /**
- * Multiply the underlying matrices of two transforms and return the result in
- * the first transform.
- * @param {!ol.Transform} transform1 Transform parameters of matrix 1.
- * @param {!ol.Transform} transform2 Transform parameters of matrix 2.
- * @return {!ol.Transform} transform1 multiplied with transform2.
- */
- ol.transform.multiply = function(transform1, transform2) {
- var a1 = transform1[0];
- var b1 = transform1[1];
- var c1 = transform1[2];
- var d1 = transform1[3];
- var e1 = transform1[4];
- var f1 = transform1[5];
- var a2 = transform2[0];
- var b2 = transform2[1];
- var c2 = transform2[2];
- var d2 = transform2[3];
- var e2 = transform2[4];
- var f2 = transform2[5];
- transform1[0] = a1 * a2 + c1 * b2;
- transform1[1] = b1 * a2 + d1 * b2;
- transform1[2] = a1 * c2 + c1 * d2;
- transform1[3] = b1 * c2 + d1 * d2;
- transform1[4] = a1 * e2 + c1 * f2 + e1;
- transform1[5] = b1 * e2 + d1 * f2 + f1;
- return transform1;
- };
- /**
- * Set the transform components a-f on a given transform.
- * @param {!ol.Transform} transform Transform.
- * @param {number} a The a component of the transform.
- * @param {number} b The b component of the transform.
- * @param {number} c The c component of the transform.
- * @param {number} d The d component of the transform.
- * @param {number} e The e component of the transform.
- * @param {number} f The f component of the transform.
- * @return {!ol.Transform} Matrix with transform applied.
- */
- ol.transform.set = function(transform, a, b, c, d, e, f) {
- transform[0] = a;
- transform[1] = b;
- transform[2] = c;
- transform[3] = d;
- transform[4] = e;
- transform[5] = f;
- return transform;
- };
- /**
- * Set transform on one matrix from another matrix.
- * @param {!ol.Transform} transform1 Matrix to set transform to.
- * @param {!ol.Transform} transform2 Matrix to set transform from.
- * @return {!ol.Transform} transform1 with transform from transform2 applied.
- */
- ol.transform.setFromArray = function(transform1, transform2) {
- transform1[0] = transform2[0];
- transform1[1] = transform2[1];
- transform1[2] = transform2[2];
- transform1[3] = transform2[3];
- transform1[4] = transform2[4];
- transform1[5] = transform2[5];
- return transform1;
- };
- /**
- * Transforms the given coordinate with the given transform returning the
- * resulting, transformed coordinate. The coordinate will be modified in-place.
- *
- * @param {ol.Transform} transform The transformation.
- * @param {ol.Coordinate|ol.Pixel} coordinate The coordinate to transform.
- * @return {ol.Coordinate|ol.Pixel} return coordinate so that operations can be
- * chained together.
- */
- ol.transform.apply = function(transform, coordinate) {
- var x = coordinate[0], y = coordinate[1];
- coordinate[0] = transform[0] * x + transform[2] * y + transform[4];
- coordinate[1] = transform[1] * x + transform[3] * y + transform[5];
- return coordinate;
- };
- /**
- * Applies rotation to the given transform.
- * @param {!ol.Transform} transform Transform.
- * @param {number} angle Angle in radians.
- * @return {!ol.Transform} The rotated transform.
- */
- ol.transform.rotate = function(transform, angle) {
- var cos = Math.cos(angle);
- var sin = Math.sin(angle);
- return ol.transform.multiply(transform,
- ol.transform.set(ol.transform.tmp_, cos, sin, -sin, cos, 0, 0));
- };
- /**
- * Applies scale to a given transform.
- * @param {!ol.Transform} transform Transform.
- * @param {number} x Scale factor x.
- * @param {number} y Scale factor y.
- * @return {!ol.Transform} The scaled transform.
- */
- ol.transform.scale = function(transform, x, y) {
- return ol.transform.multiply(transform,
- ol.transform.set(ol.transform.tmp_, x, 0, 0, y, 0, 0));
- };
- /**
- * Applies translation to the given transform.
- * @param {!ol.Transform} transform Transform.
- * @param {number} dx Translation x.
- * @param {number} dy Translation y.
- * @return {!ol.Transform} The translated transform.
- */
- ol.transform.translate = function(transform, dx, dy) {
- return ol.transform.multiply(transform,
- ol.transform.set(ol.transform.tmp_, 1, 0, 0, 1, dx, dy));
- };
- /**
- * Creates a composite transform given an initial translation, scale, rotation, and
- * final translation (in that order only, not commutative).
- * @param {!ol.Transform} transform The transform (will be modified in place).
- * @param {number} dx1 Initial translation x.
- * @param {number} dy1 Initial translation y.
- * @param {number} sx Scale factor x.
- * @param {number} sy Scale factor y.
- * @param {number} angle Rotation (in counter-clockwise radians).
- * @param {number} dx2 Final translation x.
- * @param {number} dy2 Final translation y.
- * @return {!ol.Transform} The composite transform.
- */
- ol.transform.compose = function(transform, dx1, dy1, sx, sy, angle, dx2, dy2) {
- var sin = Math.sin(angle);
- var cos = Math.cos(angle);
- transform[0] = sx * cos;
- transform[1] = sy * sin;
- transform[2] = -sx * sin;
- transform[3] = sy * cos;
- transform[4] = dx2 * sx * cos - dy2 * sx * sin + dx1;
- transform[5] = dx2 * sy * sin + dy2 * sy * cos + dy1;
- return transform;
- };
- /**
- * Invert the given transform.
- * @param {!ol.Transform} transform Transform.
- * @return {!ol.Transform} Inverse of the transform.
- */
- ol.transform.invert = function(transform) {
- var det = ol.transform.determinant(transform);
- ol.asserts.assert(det !== 0, 32); // Transformation matrix cannot be inverted
- var a = transform[0];
- var b = transform[1];
- var c = transform[2];
- var d = transform[3];
- var e = transform[4];
- var f = transform[5];
- transform[0] = d / det;
- transform[1] = -b / det;
- transform[2] = -c / det;
- transform[3] = a / det;
- transform[4] = (c * f - d * e) / det;
- transform[5] = -(a * f - b * e) / det;
- return transform;
- };
- /**
- * Returns the determinant of the given matrix.
- * @param {!ol.Transform} mat Matrix.
- * @return {number} Determinant.
- */
- ol.transform.determinant = function(mat) {
- return mat[0] * mat[3] - mat[1] * mat[2];
- };
- goog.provide('ol.geom.Geometry');
- goog.require('ol');
- goog.require('ol.Object');
- goog.require('ol.extent');
- goog.require('ol.functions');
- goog.require('ol.geom.flat.transform');
- goog.require('ol.proj');
- goog.require('ol.proj.Units');
- goog.require('ol.transform');
- /**
- * @classdesc
- * Abstract base class; normally only used for creating subclasses and not
- * instantiated in apps.
- * Base class for vector geometries.
- *
- * To get notified of changes to the geometry, register a listener for the
- * generic `change` event on your geometry instance.
- *
- * @constructor
- * @abstract
- * @extends {ol.Object}
- * @api
- */
- ol.geom.Geometry = function() {
- ol.Object.call(this);
- /**
- * @private
- * @type {ol.Extent}
- */
- this.extent_ = ol.extent.createEmpty();
- /**
- * @private
- * @type {number}
- */
- this.extentRevision_ = -1;
- /**
- * @protected
- * @type {Object.<string, ol.geom.Geometry>}
- */
- this.simplifiedGeometryCache = {};
- /**
- * @protected
- * @type {number}
- */
- this.simplifiedGeometryMaxMinSquaredTolerance = 0;
- /**
- * @protected
- * @type {number}
- */
- this.simplifiedGeometryRevision = 0;
- /**
- * @private
- * @type {ol.Transform}
- */
- this.tmpTransform_ = ol.transform.create();
- };
- ol.inherits(ol.geom.Geometry, ol.Object);
- /**
- * Make a complete copy of the geometry.
- * @abstract
- * @return {!ol.geom.Geometry} Clone.
- */
- ol.geom.Geometry.prototype.clone = function() {};
- /**
- * @abstract
- * @param {number} x X.
- * @param {number} y Y.
- * @param {ol.Coordinate} closestPoint Closest point.
- * @param {number} minSquaredDistance Minimum squared distance.
- * @return {number} Minimum squared distance.
- */
- ol.geom.Geometry.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) {};
- /**
- * Return the closest point of the geometry to the passed point as
- * {@link ol.Coordinate coordinate}.
- * @param {ol.Coordinate} point Point.
- * @param {ol.Coordinate=} opt_closestPoint Closest point.
- * @return {ol.Coordinate} Closest point.
- * @api
- */
- ol.geom.Geometry.prototype.getClosestPoint = function(point, opt_closestPoint) {
- var closestPoint = opt_closestPoint ? opt_closestPoint : [NaN, NaN];
- this.closestPointXY(point[0], point[1], closestPoint, Infinity);
- return closestPoint;
- };
- /**
- * Returns true if this geometry includes the specified coordinate. If the
- * coordinate is on the boundary of the geometry, returns false.
- * @param {ol.Coordinate} coordinate Coordinate.
- * @return {boolean} Contains coordinate.
- * @api
- */
- ol.geom.Geometry.prototype.intersectsCoordinate = function(coordinate) {
- return this.containsXY(coordinate[0], coordinate[1]);
- };
- /**
- * @abstract
- * @param {ol.Extent} extent Extent.
- * @protected
- * @return {ol.Extent} extent Extent.
- */
- ol.geom.Geometry.prototype.computeExtent = function(extent) {};
- /**
- * @param {number} x X.
- * @param {number} y Y.
- * @return {boolean} Contains (x, y).
- */
- ol.geom.Geometry.prototype.containsXY = ol.functions.FALSE;
- /**
- * Get the extent of the geometry.
- * @param {ol.Extent=} opt_extent Extent.
- * @return {ol.Extent} extent Extent.
- * @api
- */
- ol.geom.Geometry.prototype.getExtent = function(opt_extent) {
- if (this.extentRevision_ != this.getRevision()) {
- this.extent_ = this.computeExtent(this.extent_);
- this.extentRevision_ = this.getRevision();
- }
- return ol.extent.returnOrUpdate(this.extent_, opt_extent);
- };
- /**
- * Rotate the geometry around a given coordinate. This modifies the geometry
- * coordinates in place.
- * @abstract
- * @param {number} angle Rotation angle in radians.
- * @param {ol.Coordinate} anchor The rotation center.
- * @api
- */
- ol.geom.Geometry.prototype.rotate = function(angle, anchor) {};
- /**
- * Scale the geometry (with an optional origin). This modifies the geometry
- * coordinates in place.
- * @abstract
- * @param {number} sx The scaling factor in the x-direction.
- * @param {number=} opt_sy The scaling factor in the y-direction (defaults to
- * sx).
- * @param {ol.Coordinate=} opt_anchor The scale origin (defaults to the center
- * of the geometry extent).
- * @api
- */
- ol.geom.Geometry.prototype.scale = function(sx, opt_sy, opt_anchor) {};
- /**
- * Create a simplified version of this geometry. For linestrings, this uses
- * the the {@link
- * https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
- * Douglas Peucker} algorithm. For polygons, a quantization-based
- * simplification is used to preserve topology.
- * @function
- * @param {number} tolerance The tolerance distance for simplification.
- * @return {ol.geom.Geometry} A new, simplified version of the original
- * geometry.
- * @api
- */
- ol.geom.Geometry.prototype.simplify = function(tolerance) {
- return this.getSimplifiedGeometry(tolerance * tolerance);
- };
- /**
- * Create a simplified version of this geometry using the Douglas Peucker
- * algorithm.
- * @see https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
- * @abstract
- * @param {number} squaredTolerance Squared tolerance.
- * @return {ol.geom.Geometry} Simplified geometry.
- */
- ol.geom.Geometry.prototype.getSimplifiedGeometry = function(squaredTolerance) {};
- /**
- * Get the type of this geometry.
- * @abstract
- * @return {ol.geom.GeometryType} Geometry type.
- */
- ol.geom.Geometry.prototype.getType = function() {};
- /**
- * Apply a transform function to each coordinate of the geometry.
- * The geometry is modified in place.
- * If you do not want the geometry modified in place, first `clone()` it and
- * then use this function on the clone.
- * @abstract
- * @param {ol.TransformFunction} transformFn Transform.
- */
- ol.geom.Geometry.prototype.applyTransform = function(transformFn) {};
- /**
- * Test if the geometry and the passed extent intersect.
- * @abstract
- * @param {ol.Extent} extent Extent.
- * @return {boolean} `true` if the geometry and the extent intersect.
- */
- ol.geom.Geometry.prototype.intersectsExtent = function(extent) {};
- /**
- * Translate the geometry. This modifies the geometry coordinates in place. If
- * instead you want a new geometry, first `clone()` this geometry.
- * @abstract
- * @param {number} deltaX Delta X.
- * @param {number} deltaY Delta Y.
- */
- ol.geom.Geometry.prototype.translate = function(deltaX, deltaY) {};
- /**
- * Transform each coordinate of the geometry from one coordinate reference
- * system to another. The geometry is modified in place.
- * For example, a line will be transformed to a line and a circle to a circle.
- * If you do not want the geometry modified in place, first `clone()` it and
- * then use this function on the clone.
- *
- * @param {ol.ProjectionLike} source The current projection. Can be a
- * string identifier or a {@link ol.proj.Projection} object.
- * @param {ol.ProjectionLike} destination The desired projection. Can be a
- * string identifier or a {@link ol.proj.Projection} object.
- * @return {ol.geom.Geometry} This geometry. Note that original geometry is
- * modified in place.
- * @api
- */
- ol.geom.Geometry.prototype.transform = function(source, destination) {
- var tmpTransform = this.tmpTransform_;
- source = ol.proj.get(source);
- var transformFn = source.getUnits() == ol.proj.Units.TILE_PIXELS ?
- function(inCoordinates, outCoordinates, stride) {
- var pixelExtent = source.getExtent();
- var projectedExtent = source.getWorldExtent();
- var scale = ol.extent.getHeight(projectedExtent) / ol.extent.getHeight(pixelExtent);
- ol.transform.compose(tmpTransform,
- projectedExtent[0], projectedExtent[3],
- scale, -scale, 0,
- 0, 0);
- ol.geom.flat.transform.transform2D(inCoordinates, 0, inCoordinates.length, stride,
- tmpTransform, outCoordinates);
- return ol.proj.getTransform(source, destination)(inCoordinates, outCoordinates, stride);
- } :
- ol.proj.getTransform(source, destination);
- this.applyTransform(transformFn);
- return this;
- };
- goog.provide('ol.geom.SimpleGeometry');
- goog.require('ol');
- goog.require('ol.functions');
- goog.require('ol.extent');
- goog.require('ol.geom.Geometry');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.flat.transform');
- goog.require('ol.obj');
- /**
- * @classdesc
- * Abstract base class; only used for creating subclasses; do not instantiate
- * in apps, as cannot be rendered.
- *
- * @constructor
- * @abstract
- * @extends {ol.geom.Geometry}
- * @api
- */
- ol.geom.SimpleGeometry = function() {
- ol.geom.Geometry.call(this);
- /**
- * @protected
- * @type {ol.geom.GeometryLayout}
- */
- this.layout = ol.geom.GeometryLayout.XY;
- /**
- * @protected
- * @type {number}
- */
- this.stride = 2;
- /**
- * @protected
- * @type {Array.<number>}
- */
- this.flatCoordinates = null;
- };
- ol.inherits(ol.geom.SimpleGeometry, ol.geom.Geometry);
- /**
- * @param {number} stride Stride.
- * @private
- * @return {ol.geom.GeometryLayout} layout Layout.
- */
- ol.geom.SimpleGeometry.getLayoutForStride_ = function(stride) {
- var layout;
- if (stride == 2) {
- layout = ol.geom.GeometryLayout.XY;
- } else if (stride == 3) {
- layout = ol.geom.GeometryLayout.XYZ;
- } else if (stride == 4) {
- layout = ol.geom.GeometryLayout.XYZM;
- }
- return /** @type {ol.geom.GeometryLayout} */ (layout);
- };
- /**
- * @param {ol.geom.GeometryLayout} layout Layout.
- * @return {number} Stride.
- */
- ol.geom.SimpleGeometry.getStrideForLayout = function(layout) {
- var stride;
- if (layout == ol.geom.GeometryLayout.XY) {
- stride = 2;
- } else if (layout == ol.geom.GeometryLayout.XYZ || layout == ol.geom.GeometryLayout.XYM) {
- stride = 3;
- } else if (layout == ol.geom.GeometryLayout.XYZM) {
- stride = 4;
- }
- return /** @type {number} */ (stride);
- };
- /**
- * @inheritDoc
- */
- ol.geom.SimpleGeometry.prototype.containsXY = ol.functions.FALSE;
- /**
- * @inheritDoc
- */
- ol.geom.SimpleGeometry.prototype.computeExtent = function(extent) {
- return ol.extent.createOrUpdateFromFlatCoordinates(
- this.flatCoordinates, 0, this.flatCoordinates.length, this.stride,
- extent);
- };
- /**
- * @abstract
- * @return {Array} Coordinates.
- */
- ol.geom.SimpleGeometry.prototype.getCoordinates = function() {};
- /**
- * Return the first coordinate of the geometry.
- * @return {ol.Coordinate} First coordinate.
- * @api
- */
- ol.geom.SimpleGeometry.prototype.getFirstCoordinate = function() {
- return this.flatCoordinates.slice(0, this.stride);
- };
- /**
- * @return {Array.<number>} Flat coordinates.
- */
- ol.geom.SimpleGeometry.prototype.getFlatCoordinates = function() {
- return this.flatCoordinates;
- };
- /**
- * Return the last coordinate of the geometry.
- * @return {ol.Coordinate} Last point.
- * @api
- */
- ol.geom.SimpleGeometry.prototype.getLastCoordinate = function() {
- return this.flatCoordinates.slice(this.flatCoordinates.length - this.stride);
- };
- /**
- * Return the {@link ol.geom.GeometryLayout layout} of the geometry.
- * @return {ol.geom.GeometryLayout} Layout.
- * @api
- */
- ol.geom.SimpleGeometry.prototype.getLayout = function() {
- return this.layout;
- };
- /**
- * @inheritDoc
- */
- ol.geom.SimpleGeometry.prototype.getSimplifiedGeometry = function(squaredTolerance) {
- if (this.simplifiedGeometryRevision != this.getRevision()) {
- ol.obj.clear(this.simplifiedGeometryCache);
- this.simplifiedGeometryMaxMinSquaredTolerance = 0;
- this.simplifiedGeometryRevision = this.getRevision();
- }
- // If squaredTolerance is negative or if we know that simplification will not
- // have any effect then just return this.
- if (squaredTolerance < 0 ||
- (this.simplifiedGeometryMaxMinSquaredTolerance !== 0 &&
- squaredTolerance <= this.simplifiedGeometryMaxMinSquaredTolerance)) {
- return this;
- }
- var key = squaredTolerance.toString();
- if (this.simplifiedGeometryCache.hasOwnProperty(key)) {
- return this.simplifiedGeometryCache[key];
- } else {
- var simplifiedGeometry =
- this.getSimplifiedGeometryInternal(squaredTolerance);
- var simplifiedFlatCoordinates = simplifiedGeometry.getFlatCoordinates();
- if (simplifiedFlatCoordinates.length < this.flatCoordinates.length) {
- this.simplifiedGeometryCache[key] = simplifiedGeometry;
- return simplifiedGeometry;
- } else {
- // Simplification did not actually remove any coordinates. We now know
- // that any calls to getSimplifiedGeometry with a squaredTolerance less
- // than or equal to the current squaredTolerance will also not have any
- // effect. This allows us to short circuit simplification (saving CPU
- // cycles) and prevents the cache of simplified geometries from filling
- // up with useless identical copies of this geometry (saving memory).
- this.simplifiedGeometryMaxMinSquaredTolerance = squaredTolerance;
- return this;
- }
- }
- };
- /**
- * @param {number} squaredTolerance Squared tolerance.
- * @return {ol.geom.SimpleGeometry} Simplified geometry.
- * @protected
- */
- ol.geom.SimpleGeometry.prototype.getSimplifiedGeometryInternal = function(squaredTolerance) {
- return this;
- };
- /**
- * @return {number} Stride.
- */
- ol.geom.SimpleGeometry.prototype.getStride = function() {
- return this.stride;
- };
- /**
- * @param {ol.geom.GeometryLayout} layout Layout.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @protected
- */
- ol.geom.SimpleGeometry.prototype.setFlatCoordinatesInternal = function(layout, flatCoordinates) {
- this.stride = ol.geom.SimpleGeometry.getStrideForLayout(layout);
- this.layout = layout;
- this.flatCoordinates = flatCoordinates;
- };
- /**
- * @abstract
- * @param {Array} coordinates Coordinates.
- * @param {ol.geom.GeometryLayout=} opt_layout Layout.
- */
- ol.geom.SimpleGeometry.prototype.setCoordinates = function(coordinates, opt_layout) {};
- /**
- * @param {ol.geom.GeometryLayout|undefined} layout Layout.
- * @param {Array} coordinates Coordinates.
- * @param {number} nesting Nesting.
- * @protected
- */
- ol.geom.SimpleGeometry.prototype.setLayout = function(layout, coordinates, nesting) {
- /** @type {number} */
- var stride;
- if (layout) {
- stride = ol.geom.SimpleGeometry.getStrideForLayout(layout);
- } else {
- var i;
- for (i = 0; i < nesting; ++i) {
- if (coordinates.length === 0) {
- this.layout = ol.geom.GeometryLayout.XY;
- this.stride = 2;
- return;
- } else {
- coordinates = /** @type {Array} */ (coordinates[0]);
- }
- }
- stride = coordinates.length;
- layout = ol.geom.SimpleGeometry.getLayoutForStride_(stride);
- }
- this.layout = layout;
- this.stride = stride;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.SimpleGeometry.prototype.applyTransform = function(transformFn) {
- if (this.flatCoordinates) {
- transformFn(this.flatCoordinates, this.flatCoordinates, this.stride);
- this.changed();
- }
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.SimpleGeometry.prototype.rotate = function(angle, anchor) {
- var flatCoordinates = this.getFlatCoordinates();
- if (flatCoordinates) {
- var stride = this.getStride();
- ol.geom.flat.transform.rotate(
- flatCoordinates, 0, flatCoordinates.length,
- stride, angle, anchor, flatCoordinates);
- this.changed();
- }
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.SimpleGeometry.prototype.scale = function(sx, opt_sy, opt_anchor) {
- var sy = opt_sy;
- if (sy === undefined) {
- sy = sx;
- }
- var anchor = opt_anchor;
- if (!anchor) {
- anchor = ol.extent.getCenter(this.getExtent());
- }
- var flatCoordinates = this.getFlatCoordinates();
- if (flatCoordinates) {
- var stride = this.getStride();
- ol.geom.flat.transform.scale(
- flatCoordinates, 0, flatCoordinates.length,
- stride, sx, sy, anchor, flatCoordinates);
- this.changed();
- }
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.SimpleGeometry.prototype.translate = function(deltaX, deltaY) {
- var flatCoordinates = this.getFlatCoordinates();
- if (flatCoordinates) {
- var stride = this.getStride();
- ol.geom.flat.transform.translate(
- flatCoordinates, 0, flatCoordinates.length, stride,
- deltaX, deltaY, flatCoordinates);
- this.changed();
- }
- };
- /**
- * @param {ol.geom.SimpleGeometry} simpleGeometry Simple geometry.
- * @param {ol.Transform} transform Transform.
- * @param {Array.<number>=} opt_dest Destination.
- * @return {Array.<number>} Transformed flat coordinates.
- */
- ol.geom.SimpleGeometry.transform2D = function(simpleGeometry, transform, opt_dest) {
- var flatCoordinates = simpleGeometry.getFlatCoordinates();
- if (!flatCoordinates) {
- return null;
- } else {
- var stride = simpleGeometry.getStride();
- return ol.geom.flat.transform.transform2D(
- flatCoordinates, 0, flatCoordinates.length, stride,
- transform, opt_dest);
- }
- };
- goog.provide('ol.geom.flat.area');
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @return {number} Area.
- */
- ol.geom.flat.area.linearRing = function(flatCoordinates, offset, end, stride) {
- var twiceArea = 0;
- var x1 = flatCoordinates[end - stride];
- var y1 = flatCoordinates[end - stride + 1];
- for (; offset < end; offset += stride) {
- var x2 = flatCoordinates[offset];
- var y2 = flatCoordinates[offset + 1];
- twiceArea += y1 * x2 - x1 * y2;
- x1 = x2;
- y1 = y2;
- }
- return twiceArea / 2;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<number>} ends Ends.
- * @param {number} stride Stride.
- * @return {number} Area.
- */
- ol.geom.flat.area.linearRings = function(flatCoordinates, offset, ends, stride) {
- var area = 0;
- var i, ii;
- for (i = 0, ii = ends.length; i < ii; ++i) {
- var end = ends[i];
- area += ol.geom.flat.area.linearRing(flatCoordinates, offset, end, stride);
- offset = end;
- }
- return area;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<Array.<number>>} endss Endss.
- * @param {number} stride Stride.
- * @return {number} Area.
- */
- ol.geom.flat.area.linearRingss = function(flatCoordinates, offset, endss, stride) {
- var area = 0;
- var i, ii;
- for (i = 0, ii = endss.length; i < ii; ++i) {
- var ends = endss[i];
- area +=
- ol.geom.flat.area.linearRings(flatCoordinates, offset, ends, stride);
- offset = ends[ends.length - 1];
- }
- return area;
- };
- goog.provide('ol.geom.flat.closest');
- goog.require('ol.math');
- /**
- * Returns the point on the 2D line segment flatCoordinates[offset1] to
- * flatCoordinates[offset2] that is closest to the point (x, y). Extra
- * dimensions are linearly interpolated.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset1 Offset 1.
- * @param {number} offset2 Offset 2.
- * @param {number} stride Stride.
- * @param {number} x X.
- * @param {number} y Y.
- * @param {Array.<number>} closestPoint Closest point.
- */
- ol.geom.flat.closest.point = function(flatCoordinates, offset1, offset2, stride, x, y, closestPoint) {
- var x1 = flatCoordinates[offset1];
- var y1 = flatCoordinates[offset1 + 1];
- var dx = flatCoordinates[offset2] - x1;
- var dy = flatCoordinates[offset2 + 1] - y1;
- var i, offset;
- if (dx === 0 && dy === 0) {
- offset = offset1;
- } else {
- var t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);
- if (t > 1) {
- offset = offset2;
- } else if (t > 0) {
- for (i = 0; i < stride; ++i) {
- closestPoint[i] = ol.math.lerp(flatCoordinates[offset1 + i],
- flatCoordinates[offset2 + i], t);
- }
- closestPoint.length = stride;
- return;
- } else {
- offset = offset1;
- }
- }
- for (i = 0; i < stride; ++i) {
- closestPoint[i] = flatCoordinates[offset + i];
- }
- closestPoint.length = stride;
- };
- /**
- * Return the squared of the largest distance between any pair of consecutive
- * coordinates.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {number} maxSquaredDelta Max squared delta.
- * @return {number} Max squared delta.
- */
- ol.geom.flat.closest.getMaxSquaredDelta = function(flatCoordinates, offset, end, stride, maxSquaredDelta) {
- var x1 = flatCoordinates[offset];
- var y1 = flatCoordinates[offset + 1];
- for (offset += stride; offset < end; offset += stride) {
- var x2 = flatCoordinates[offset];
- var y2 = flatCoordinates[offset + 1];
- var squaredDelta = ol.math.squaredDistance(x1, y1, x2, y2);
- if (squaredDelta > maxSquaredDelta) {
- maxSquaredDelta = squaredDelta;
- }
- x1 = x2;
- y1 = y2;
- }
- return maxSquaredDelta;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<number>} ends Ends.
- * @param {number} stride Stride.
- * @param {number} maxSquaredDelta Max squared delta.
- * @return {number} Max squared delta.
- */
- ol.geom.flat.closest.getsMaxSquaredDelta = function(flatCoordinates, offset, ends, stride, maxSquaredDelta) {
- var i, ii;
- for (i = 0, ii = ends.length; i < ii; ++i) {
- var end = ends[i];
- maxSquaredDelta = ol.geom.flat.closest.getMaxSquaredDelta(
- flatCoordinates, offset, end, stride, maxSquaredDelta);
- offset = end;
- }
- return maxSquaredDelta;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<Array.<number>>} endss Endss.
- * @param {number} stride Stride.
- * @param {number} maxSquaredDelta Max squared delta.
- * @return {number} Max squared delta.
- */
- ol.geom.flat.closest.getssMaxSquaredDelta = function(flatCoordinates, offset, endss, stride, maxSquaredDelta) {
- var i, ii;
- for (i = 0, ii = endss.length; i < ii; ++i) {
- var ends = endss[i];
- maxSquaredDelta = ol.geom.flat.closest.getsMaxSquaredDelta(
- flatCoordinates, offset, ends, stride, maxSquaredDelta);
- offset = ends[ends.length - 1];
- }
- return maxSquaredDelta;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {number} maxDelta Max delta.
- * @param {boolean} isRing Is ring.
- * @param {number} x X.
- * @param {number} y Y.
- * @param {Array.<number>} closestPoint Closest point.
- * @param {number} minSquaredDistance Minimum squared distance.
- * @param {Array.<number>=} opt_tmpPoint Temporary point object.
- * @return {number} Minimum squared distance.
- */
- ol.geom.flat.closest.getClosestPoint = function(flatCoordinates, offset, end,
- stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance,
- opt_tmpPoint) {
- if (offset == end) {
- return minSquaredDistance;
- }
- var i, squaredDistance;
- if (maxDelta === 0) {
- // All points are identical, so just test the first point.
- squaredDistance = ol.math.squaredDistance(
- x, y, flatCoordinates[offset], flatCoordinates[offset + 1]);
- if (squaredDistance < minSquaredDistance) {
- for (i = 0; i < stride; ++i) {
- closestPoint[i] = flatCoordinates[offset + i];
- }
- closestPoint.length = stride;
- return squaredDistance;
- } else {
- return minSquaredDistance;
- }
- }
- var tmpPoint = opt_tmpPoint ? opt_tmpPoint : [NaN, NaN];
- var index = offset + stride;
- while (index < end) {
- ol.geom.flat.closest.point(
- flatCoordinates, index - stride, index, stride, x, y, tmpPoint);
- squaredDistance = ol.math.squaredDistance(x, y, tmpPoint[0], tmpPoint[1]);
- if (squaredDistance < minSquaredDistance) {
- minSquaredDistance = squaredDistance;
- for (i = 0; i < stride; ++i) {
- closestPoint[i] = tmpPoint[i];
- }
- closestPoint.length = stride;
- index += stride;
- } else {
- // Skip ahead multiple points, because we know that all the skipped
- // points cannot be any closer than the closest point we have found so
- // far. We know this because we know how close the current point is, how
- // close the closest point we have found so far is, and the maximum
- // distance between consecutive points. For example, if we're currently
- // at distance 10, the best we've found so far is 3, and that the maximum
- // distance between consecutive points is 2, then we'll need to skip at
- // least (10 - 3) / 2 == 3 (rounded down) points to have any chance of
- // finding a closer point. We use Math.max(..., 1) to ensure that we
- // always advance at least one point, to avoid an infinite loop.
- index += stride * Math.max(
- ((Math.sqrt(squaredDistance) -
- Math.sqrt(minSquaredDistance)) / maxDelta) | 0, 1);
- }
- }
- if (isRing) {
- // Check the closing segment.
- ol.geom.flat.closest.point(
- flatCoordinates, end - stride, offset, stride, x, y, tmpPoint);
- squaredDistance = ol.math.squaredDistance(x, y, tmpPoint[0], tmpPoint[1]);
- if (squaredDistance < minSquaredDistance) {
- minSquaredDistance = squaredDistance;
- for (i = 0; i < stride; ++i) {
- closestPoint[i] = tmpPoint[i];
- }
- closestPoint.length = stride;
- }
- }
- return minSquaredDistance;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<number>} ends Ends.
- * @param {number} stride Stride.
- * @param {number} maxDelta Max delta.
- * @param {boolean} isRing Is ring.
- * @param {number} x X.
- * @param {number} y Y.
- * @param {Array.<number>} closestPoint Closest point.
- * @param {number} minSquaredDistance Minimum squared distance.
- * @param {Array.<number>=} opt_tmpPoint Temporary point object.
- * @return {number} Minimum squared distance.
- */
- ol.geom.flat.closest.getsClosestPoint = function(flatCoordinates, offset, ends,
- stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance,
- opt_tmpPoint) {
- var tmpPoint = opt_tmpPoint ? opt_tmpPoint : [NaN, NaN];
- var i, ii;
- for (i = 0, ii = ends.length; i < ii; ++i) {
- var end = ends[i];
- minSquaredDistance = ol.geom.flat.closest.getClosestPoint(
- flatCoordinates, offset, end, stride,
- maxDelta, isRing, x, y, closestPoint, minSquaredDistance, tmpPoint);
- offset = end;
- }
- return minSquaredDistance;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<Array.<number>>} endss Endss.
- * @param {number} stride Stride.
- * @param {number} maxDelta Max delta.
- * @param {boolean} isRing Is ring.
- * @param {number} x X.
- * @param {number} y Y.
- * @param {Array.<number>} closestPoint Closest point.
- * @param {number} minSquaredDistance Minimum squared distance.
- * @param {Array.<number>=} opt_tmpPoint Temporary point object.
- * @return {number} Minimum squared distance.
- */
- ol.geom.flat.closest.getssClosestPoint = function(flatCoordinates, offset,
- endss, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance,
- opt_tmpPoint) {
- var tmpPoint = opt_tmpPoint ? opt_tmpPoint : [NaN, NaN];
- var i, ii;
- for (i = 0, ii = endss.length; i < ii; ++i) {
- var ends = endss[i];
- minSquaredDistance = ol.geom.flat.closest.getsClosestPoint(
- flatCoordinates, offset, ends, stride,
- maxDelta, isRing, x, y, closestPoint, minSquaredDistance, tmpPoint);
- offset = ends[ends.length - 1];
- }
- return minSquaredDistance;
- };
- goog.provide('ol.geom.flat.deflate');
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {number} stride Stride.
- * @return {number} offset Offset.
- */
- ol.geom.flat.deflate.coordinate = function(flatCoordinates, offset, coordinate, stride) {
- var i, ii;
- for (i = 0, ii = coordinate.length; i < ii; ++i) {
- flatCoordinates[offset++] = coordinate[i];
- }
- return offset;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<ol.Coordinate>} coordinates Coordinates.
- * @param {number} stride Stride.
- * @return {number} offset Offset.
- */
- ol.geom.flat.deflate.coordinates = function(flatCoordinates, offset, coordinates, stride) {
- var i, ii;
- for (i = 0, ii = coordinates.length; i < ii; ++i) {
- var coordinate = coordinates[i];
- var j;
- for (j = 0; j < stride; ++j) {
- flatCoordinates[offset++] = coordinate[j];
- }
- }
- return offset;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<Array.<ol.Coordinate>>} coordinatess Coordinatess.
- * @param {number} stride Stride.
- * @param {Array.<number>=} opt_ends Ends.
- * @return {Array.<number>} Ends.
- */
- ol.geom.flat.deflate.coordinatess = function(flatCoordinates, offset, coordinatess, stride, opt_ends) {
- var ends = opt_ends ? opt_ends : [];
- var i = 0;
- var j, jj;
- for (j = 0, jj = coordinatess.length; j < jj; ++j) {
- var end = ol.geom.flat.deflate.coordinates(
- flatCoordinates, offset, coordinatess[j], stride);
- ends[i++] = end;
- offset = end;
- }
- ends.length = i;
- return ends;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<Array.<Array.<ol.Coordinate>>>} coordinatesss Coordinatesss.
- * @param {number} stride Stride.
- * @param {Array.<Array.<number>>=} opt_endss Endss.
- * @return {Array.<Array.<number>>} Endss.
- */
- ol.geom.flat.deflate.coordinatesss = function(flatCoordinates, offset, coordinatesss, stride, opt_endss) {
- var endss = opt_endss ? opt_endss : [];
- var i = 0;
- var j, jj;
- for (j = 0, jj = coordinatesss.length; j < jj; ++j) {
- var ends = ol.geom.flat.deflate.coordinatess(
- flatCoordinates, offset, coordinatesss[j], stride, endss[i]);
- endss[i++] = ends;
- offset = ends[ends.length - 1];
- }
- endss.length = i;
- return endss;
- };
- goog.provide('ol.geom.flat.inflate');
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {Array.<ol.Coordinate>=} opt_coordinates Coordinates.
- * @return {Array.<ol.Coordinate>} Coordinates.
- */
- ol.geom.flat.inflate.coordinates = function(flatCoordinates, offset, end, stride, opt_coordinates) {
- var coordinates = opt_coordinates !== undefined ? opt_coordinates : [];
- var i = 0;
- var j;
- for (j = offset; j < end; j += stride) {
- coordinates[i++] = flatCoordinates.slice(j, j + stride);
- }
- coordinates.length = i;
- return coordinates;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<number>} ends Ends.
- * @param {number} stride Stride.
- * @param {Array.<Array.<ol.Coordinate>>=} opt_coordinatess Coordinatess.
- * @return {Array.<Array.<ol.Coordinate>>} Coordinatess.
- */
- ol.geom.flat.inflate.coordinatess = function(flatCoordinates, offset, ends, stride, opt_coordinatess) {
- var coordinatess = opt_coordinatess !== undefined ? opt_coordinatess : [];
- var i = 0;
- var j, jj;
- for (j = 0, jj = ends.length; j < jj; ++j) {
- var end = ends[j];
- coordinatess[i++] = ol.geom.flat.inflate.coordinates(
- flatCoordinates, offset, end, stride, coordinatess[i]);
- offset = end;
- }
- coordinatess.length = i;
- return coordinatess;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<Array.<number>>} endss Endss.
- * @param {number} stride Stride.
- * @param {Array.<Array.<Array.<ol.Coordinate>>>=} opt_coordinatesss
- * Coordinatesss.
- * @return {Array.<Array.<Array.<ol.Coordinate>>>} Coordinatesss.
- */
- ol.geom.flat.inflate.coordinatesss = function(flatCoordinates, offset, endss, stride, opt_coordinatesss) {
- var coordinatesss = opt_coordinatesss !== undefined ? opt_coordinatesss : [];
- var i = 0;
- var j, jj;
- for (j = 0, jj = endss.length; j < jj; ++j) {
- var ends = endss[j];
- coordinatesss[i++] = ol.geom.flat.inflate.coordinatess(
- flatCoordinates, offset, ends, stride, coordinatesss[i]);
- offset = ends[ends.length - 1];
- }
- coordinatesss.length = i;
- return coordinatesss;
- };
- // Based on simplify-js https://github.com/mourner/simplify-js
- // Copyright (c) 2012, Vladimir Agafonkin
- // All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are met:
- //
- // 1. Redistributions of source code must retain the above copyright notice,
- // this list of conditions and the following disclaimer.
- //
- // 2. Redistributions in binary form must reproduce the above copyright
- // notice, this list of conditions and the following disclaimer in the
- // documentation and/or other materials provided with the distribution.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- // POSSIBILITY OF SUCH DAMAGE.
- goog.provide('ol.geom.flat.simplify');
- goog.require('ol.math');
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {number} squaredTolerance Squared tolerance.
- * @param {boolean} highQuality Highest quality.
- * @param {Array.<number>=} opt_simplifiedFlatCoordinates Simplified flat
- * coordinates.
- * @return {Array.<number>} Simplified line string.
- */
- ol.geom.flat.simplify.lineString = function(flatCoordinates, offset, end,
- stride, squaredTolerance, highQuality, opt_simplifiedFlatCoordinates) {
- var simplifiedFlatCoordinates = opt_simplifiedFlatCoordinates !== undefined ?
- opt_simplifiedFlatCoordinates : [];
- if (!highQuality) {
- end = ol.geom.flat.simplify.radialDistance(flatCoordinates, offset, end,
- stride, squaredTolerance,
- simplifiedFlatCoordinates, 0);
- flatCoordinates = simplifiedFlatCoordinates;
- offset = 0;
- stride = 2;
- }
- simplifiedFlatCoordinates.length = ol.geom.flat.simplify.douglasPeucker(
- flatCoordinates, offset, end, stride, squaredTolerance,
- simplifiedFlatCoordinates, 0);
- return simplifiedFlatCoordinates;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {number} squaredTolerance Squared tolerance.
- * @param {Array.<number>} simplifiedFlatCoordinates Simplified flat
- * coordinates.
- * @param {number} simplifiedOffset Simplified offset.
- * @return {number} Simplified offset.
- */
- ol.geom.flat.simplify.douglasPeucker = function(flatCoordinates, offset, end,
- stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset) {
- var n = (end - offset) / stride;
- if (n < 3) {
- for (; offset < end; offset += stride) {
- simplifiedFlatCoordinates[simplifiedOffset++] =
- flatCoordinates[offset];
- simplifiedFlatCoordinates[simplifiedOffset++] =
- flatCoordinates[offset + 1];
- }
- return simplifiedOffset;
- }
- /** @type {Array.<number>} */
- var markers = new Array(n);
- markers[0] = 1;
- markers[n - 1] = 1;
- /** @type {Array.<number>} */
- var stack = [offset, end - stride];
- var index = 0;
- var i;
- while (stack.length > 0) {
- var last = stack.pop();
- var first = stack.pop();
- var maxSquaredDistance = 0;
- var x1 = flatCoordinates[first];
- var y1 = flatCoordinates[first + 1];
- var x2 = flatCoordinates[last];
- var y2 = flatCoordinates[last + 1];
- for (i = first + stride; i < last; i += stride) {
- var x = flatCoordinates[i];
- var y = flatCoordinates[i + 1];
- var squaredDistance = ol.math.squaredSegmentDistance(
- x, y, x1, y1, x2, y2);
- if (squaredDistance > maxSquaredDistance) {
- index = i;
- maxSquaredDistance = squaredDistance;
- }
- }
- if (maxSquaredDistance > squaredTolerance) {
- markers[(index - offset) / stride] = 1;
- if (first + stride < index) {
- stack.push(first, index);
- }
- if (index + stride < last) {
- stack.push(index, last);
- }
- }
- }
- for (i = 0; i < n; ++i) {
- if (markers[i]) {
- simplifiedFlatCoordinates[simplifiedOffset++] =
- flatCoordinates[offset + i * stride];
- simplifiedFlatCoordinates[simplifiedOffset++] =
- flatCoordinates[offset + i * stride + 1];
- }
- }
- return simplifiedOffset;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<number>} ends Ends.
- * @param {number} stride Stride.
- * @param {number} squaredTolerance Squared tolerance.
- * @param {Array.<number>} simplifiedFlatCoordinates Simplified flat
- * coordinates.
- * @param {number} simplifiedOffset Simplified offset.
- * @param {Array.<number>} simplifiedEnds Simplified ends.
- * @return {number} Simplified offset.
- */
- ol.geom.flat.simplify.douglasPeuckers = function(flatCoordinates, offset,
- ends, stride, squaredTolerance, simplifiedFlatCoordinates,
- simplifiedOffset, simplifiedEnds) {
- var i, ii;
- for (i = 0, ii = ends.length; i < ii; ++i) {
- var end = ends[i];
- simplifiedOffset = ol.geom.flat.simplify.douglasPeucker(
- flatCoordinates, offset, end, stride, squaredTolerance,
- simplifiedFlatCoordinates, simplifiedOffset);
- simplifiedEnds.push(simplifiedOffset);
- offset = end;
- }
- return simplifiedOffset;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<Array.<number>>} endss Endss.
- * @param {number} stride Stride.
- * @param {number} squaredTolerance Squared tolerance.
- * @param {Array.<number>} simplifiedFlatCoordinates Simplified flat
- * coordinates.
- * @param {number} simplifiedOffset Simplified offset.
- * @param {Array.<Array.<number>>} simplifiedEndss Simplified endss.
- * @return {number} Simplified offset.
- */
- ol.geom.flat.simplify.douglasPeuckerss = function(
- flatCoordinates, offset, endss, stride, squaredTolerance,
- simplifiedFlatCoordinates, simplifiedOffset, simplifiedEndss) {
- var i, ii;
- for (i = 0, ii = endss.length; i < ii; ++i) {
- var ends = endss[i];
- var simplifiedEnds = [];
- simplifiedOffset = ol.geom.flat.simplify.douglasPeuckers(
- flatCoordinates, offset, ends, stride, squaredTolerance,
- simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds);
- simplifiedEndss.push(simplifiedEnds);
- offset = ends[ends.length - 1];
- }
- return simplifiedOffset;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {number} squaredTolerance Squared tolerance.
- * @param {Array.<number>} simplifiedFlatCoordinates Simplified flat
- * coordinates.
- * @param {number} simplifiedOffset Simplified offset.
- * @return {number} Simplified offset.
- */
- ol.geom.flat.simplify.radialDistance = function(flatCoordinates, offset, end,
- stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset) {
- if (end <= offset + stride) {
- // zero or one point, no simplification possible, so copy and return
- for (; offset < end; offset += stride) {
- simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset];
- simplifiedFlatCoordinates[simplifiedOffset++] =
- flatCoordinates[offset + 1];
- }
- return simplifiedOffset;
- }
- var x1 = flatCoordinates[offset];
- var y1 = flatCoordinates[offset + 1];
- // copy first point
- simplifiedFlatCoordinates[simplifiedOffset++] = x1;
- simplifiedFlatCoordinates[simplifiedOffset++] = y1;
- var x2 = x1;
- var y2 = y1;
- for (offset += stride; offset < end; offset += stride) {
- x2 = flatCoordinates[offset];
- y2 = flatCoordinates[offset + 1];
- if (ol.math.squaredDistance(x1, y1, x2, y2) > squaredTolerance) {
- // copy point at offset
- simplifiedFlatCoordinates[simplifiedOffset++] = x2;
- simplifiedFlatCoordinates[simplifiedOffset++] = y2;
- x1 = x2;
- y1 = y2;
- }
- }
- if (x2 != x1 || y2 != y1) {
- // copy last point
- simplifiedFlatCoordinates[simplifiedOffset++] = x2;
- simplifiedFlatCoordinates[simplifiedOffset++] = y2;
- }
- return simplifiedOffset;
- };
- /**
- * @param {number} value Value.
- * @param {number} tolerance Tolerance.
- * @return {number} Rounded value.
- */
- ol.geom.flat.simplify.snap = function(value, tolerance) {
- return tolerance * Math.round(value / tolerance);
- };
- /**
- * Simplifies a line string using an algorithm designed by Tim Schaub.
- * Coordinates are snapped to the nearest value in a virtual grid and
- * consecutive duplicate coordinates are discarded. This effectively preserves
- * topology as the simplification of any subsection of a line string is
- * independent of the rest of the line string. This means that, for examples,
- * the common edge between two polygons will be simplified to the same line
- * string independently in both polygons. This implementation uses a single
- * pass over the coordinates and eliminates intermediate collinear points.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {number} tolerance Tolerance.
- * @param {Array.<number>} simplifiedFlatCoordinates Simplified flat
- * coordinates.
- * @param {number} simplifiedOffset Simplified offset.
- * @return {number} Simplified offset.
- */
- ol.geom.flat.simplify.quantize = function(flatCoordinates, offset, end, stride,
- tolerance, simplifiedFlatCoordinates, simplifiedOffset) {
- // do nothing if the line is empty
- if (offset == end) {
- return simplifiedOffset;
- }
- // snap the first coordinate (P1)
- var x1 = ol.geom.flat.simplify.snap(flatCoordinates[offset], tolerance);
- var y1 = ol.geom.flat.simplify.snap(flatCoordinates[offset + 1], tolerance);
- offset += stride;
- // add the first coordinate to the output
- simplifiedFlatCoordinates[simplifiedOffset++] = x1;
- simplifiedFlatCoordinates[simplifiedOffset++] = y1;
- // find the next coordinate that does not snap to the same value as the first
- // coordinate (P2)
- var x2, y2;
- do {
- x2 = ol.geom.flat.simplify.snap(flatCoordinates[offset], tolerance);
- y2 = ol.geom.flat.simplify.snap(flatCoordinates[offset + 1], tolerance);
- offset += stride;
- if (offset == end) {
- // all coordinates snap to the same value, the line collapses to a point
- // push the last snapped value anyway to ensure that the output contains
- // at least two points
- // FIXME should we really return at least two points anyway?
- simplifiedFlatCoordinates[simplifiedOffset++] = x2;
- simplifiedFlatCoordinates[simplifiedOffset++] = y2;
- return simplifiedOffset;
- }
- } while (x2 == x1 && y2 == y1);
- while (offset < end) {
- var x3, y3;
- // snap the next coordinate (P3)
- x3 = ol.geom.flat.simplify.snap(flatCoordinates[offset], tolerance);
- y3 = ol.geom.flat.simplify.snap(flatCoordinates[offset + 1], tolerance);
- offset += stride;
- // skip P3 if it is equal to P2
- if (x3 == x2 && y3 == y2) {
- continue;
- }
- // calculate the delta between P1 and P2
- var dx1 = x2 - x1;
- var dy1 = y2 - y1;
- // calculate the delta between P3 and P1
- var dx2 = x3 - x1;
- var dy2 = y3 - y1;
- // if P1, P2, and P3 are colinear and P3 is further from P1 than P2 is from
- // P1 in the same direction then P2 is on the straight line between P1 and
- // P3
- if ((dx1 * dy2 == dy1 * dx2) &&
- ((dx1 < 0 && dx2 < dx1) || dx1 == dx2 || (dx1 > 0 && dx2 > dx1)) &&
- ((dy1 < 0 && dy2 < dy1) || dy1 == dy2 || (dy1 > 0 && dy2 > dy1))) {
- // discard P2 and set P2 = P3
- x2 = x3;
- y2 = y3;
- continue;
- }
- // either P1, P2, and P3 are not colinear, or they are colinear but P3 is
- // between P3 and P1 or on the opposite half of the line to P2. add P2,
- // and continue with P1 = P2 and P2 = P3
- simplifiedFlatCoordinates[simplifiedOffset++] = x2;
- simplifiedFlatCoordinates[simplifiedOffset++] = y2;
- x1 = x2;
- y1 = y2;
- x2 = x3;
- y2 = y3;
- }
- // add the last point (P2)
- simplifiedFlatCoordinates[simplifiedOffset++] = x2;
- simplifiedFlatCoordinates[simplifiedOffset++] = y2;
- return simplifiedOffset;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<number>} ends Ends.
- * @param {number} stride Stride.
- * @param {number} tolerance Tolerance.
- * @param {Array.<number>} simplifiedFlatCoordinates Simplified flat
- * coordinates.
- * @param {number} simplifiedOffset Simplified offset.
- * @param {Array.<number>} simplifiedEnds Simplified ends.
- * @return {number} Simplified offset.
- */
- ol.geom.flat.simplify.quantizes = function(
- flatCoordinates, offset, ends, stride,
- tolerance,
- simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds) {
- var i, ii;
- for (i = 0, ii = ends.length; i < ii; ++i) {
- var end = ends[i];
- simplifiedOffset = ol.geom.flat.simplify.quantize(
- flatCoordinates, offset, end, stride,
- tolerance,
- simplifiedFlatCoordinates, simplifiedOffset);
- simplifiedEnds.push(simplifiedOffset);
- offset = end;
- }
- return simplifiedOffset;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<Array.<number>>} endss Endss.
- * @param {number} stride Stride.
- * @param {number} tolerance Tolerance.
- * @param {Array.<number>} simplifiedFlatCoordinates Simplified flat
- * coordinates.
- * @param {number} simplifiedOffset Simplified offset.
- * @param {Array.<Array.<number>>} simplifiedEndss Simplified endss.
- * @return {number} Simplified offset.
- */
- ol.geom.flat.simplify.quantizess = function(
- flatCoordinates, offset, endss, stride,
- tolerance,
- simplifiedFlatCoordinates, simplifiedOffset, simplifiedEndss) {
- var i, ii;
- for (i = 0, ii = endss.length; i < ii; ++i) {
- var ends = endss[i];
- var simplifiedEnds = [];
- simplifiedOffset = ol.geom.flat.simplify.quantizes(
- flatCoordinates, offset, ends, stride,
- tolerance,
- simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds);
- simplifiedEndss.push(simplifiedEnds);
- offset = ends[ends.length - 1];
- }
- return simplifiedOffset;
- };
- goog.provide('ol.geom.LinearRing');
- goog.require('ol');
- goog.require('ol.extent');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.SimpleGeometry');
- goog.require('ol.geom.flat.area');
- goog.require('ol.geom.flat.closest');
- goog.require('ol.geom.flat.deflate');
- goog.require('ol.geom.flat.inflate');
- goog.require('ol.geom.flat.simplify');
- /**
- * @classdesc
- * Linear ring geometry. Only used as part of polygon; cannot be rendered
- * on its own.
- *
- * @constructor
- * @extends {ol.geom.SimpleGeometry}
- * @param {Array.<ol.Coordinate>} coordinates Coordinates.
- * @param {ol.geom.GeometryLayout=} opt_layout Layout.
- * @api
- */
- ol.geom.LinearRing = function(coordinates, opt_layout) {
- ol.geom.SimpleGeometry.call(this);
- /**
- * @private
- * @type {number}
- */
- this.maxDelta_ = -1;
- /**
- * @private
- * @type {number}
- */
- this.maxDeltaRevision_ = -1;
- this.setCoordinates(coordinates, opt_layout);
- };
- ol.inherits(ol.geom.LinearRing, ol.geom.SimpleGeometry);
- /**
- * Make a complete copy of the geometry.
- * @return {!ol.geom.LinearRing} Clone.
- * @override
- * @api
- */
- ol.geom.LinearRing.prototype.clone = function() {
- var linearRing = new ol.geom.LinearRing(null);
- linearRing.setFlatCoordinates(this.layout, this.flatCoordinates.slice());
- return linearRing;
- };
- /**
- * @inheritDoc
- */
- ol.geom.LinearRing.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) {
- if (minSquaredDistance <
- ol.extent.closestSquaredDistanceXY(this.getExtent(), x, y)) {
- return minSquaredDistance;
- }
- if (this.maxDeltaRevision_ != this.getRevision()) {
- this.maxDelta_ = Math.sqrt(ol.geom.flat.closest.getMaxSquaredDelta(
- this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, 0));
- this.maxDeltaRevision_ = this.getRevision();
- }
- return ol.geom.flat.closest.getClosestPoint(
- this.flatCoordinates, 0, this.flatCoordinates.length, this.stride,
- this.maxDelta_, true, x, y, closestPoint, minSquaredDistance);
- };
- /**
- * Return the area of the linear ring on projected plane.
- * @return {number} Area (on projected plane).
- * @api
- */
- ol.geom.LinearRing.prototype.getArea = function() {
- return ol.geom.flat.area.linearRing(
- this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);
- };
- /**
- * Return the coordinates of the linear ring.
- * @return {Array.<ol.Coordinate>} Coordinates.
- * @override
- * @api
- */
- ol.geom.LinearRing.prototype.getCoordinates = function() {
- return ol.geom.flat.inflate.coordinates(
- this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);
- };
- /**
- * @inheritDoc
- */
- ol.geom.LinearRing.prototype.getSimplifiedGeometryInternal = function(squaredTolerance) {
- var simplifiedFlatCoordinates = [];
- simplifiedFlatCoordinates.length = ol.geom.flat.simplify.douglasPeucker(
- this.flatCoordinates, 0, this.flatCoordinates.length, this.stride,
- squaredTolerance, simplifiedFlatCoordinates, 0);
- var simplifiedLinearRing = new ol.geom.LinearRing(null);
- simplifiedLinearRing.setFlatCoordinates(
- ol.geom.GeometryLayout.XY, simplifiedFlatCoordinates);
- return simplifiedLinearRing;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.LinearRing.prototype.getType = function() {
- return ol.geom.GeometryType.LINEAR_RING;
- };
- /**
- * @inheritDoc
- */
- ol.geom.LinearRing.prototype.intersectsExtent = function(extent) {};
- /**
- * Set the coordinates of the linear ring.
- * @param {Array.<ol.Coordinate>} coordinates Coordinates.
- * @param {ol.geom.GeometryLayout=} opt_layout Layout.
- * @override
- * @api
- */
- ol.geom.LinearRing.prototype.setCoordinates = function(coordinates, opt_layout) {
- if (!coordinates) {
- this.setFlatCoordinates(ol.geom.GeometryLayout.XY, null);
- } else {
- this.setLayout(opt_layout, coordinates, 1);
- if (!this.flatCoordinates) {
- this.flatCoordinates = [];
- }
- this.flatCoordinates.length = ol.geom.flat.deflate.coordinates(
- this.flatCoordinates, 0, coordinates, this.stride);
- this.changed();
- }
- };
- /**
- * @param {ol.geom.GeometryLayout} layout Layout.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- */
- ol.geom.LinearRing.prototype.setFlatCoordinates = function(layout, flatCoordinates) {
- this.setFlatCoordinatesInternal(layout, flatCoordinates);
- this.changed();
- };
- goog.provide('ol.geom.Point');
- goog.require('ol');
- goog.require('ol.extent');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.SimpleGeometry');
- goog.require('ol.geom.flat.deflate');
- goog.require('ol.math');
- /**
- * @classdesc
- * Point geometry.
- *
- * @constructor
- * @extends {ol.geom.SimpleGeometry}
- * @param {ol.Coordinate} coordinates Coordinates.
- * @param {ol.geom.GeometryLayout=} opt_layout Layout.
- * @api
- */
- ol.geom.Point = function(coordinates, opt_layout) {
- ol.geom.SimpleGeometry.call(this);
- this.setCoordinates(coordinates, opt_layout);
- };
- ol.inherits(ol.geom.Point, ol.geom.SimpleGeometry);
- /**
- * Make a complete copy of the geometry.
- * @return {!ol.geom.Point} Clone.
- * @override
- * @api
- */
- ol.geom.Point.prototype.clone = function() {
- var point = new ol.geom.Point(null);
- point.setFlatCoordinates(this.layout, this.flatCoordinates.slice());
- return point;
- };
- /**
- * @inheritDoc
- */
- ol.geom.Point.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) {
- var flatCoordinates = this.flatCoordinates;
- var squaredDistance = ol.math.squaredDistance(
- x, y, flatCoordinates[0], flatCoordinates[1]);
- if (squaredDistance < minSquaredDistance) {
- var stride = this.stride;
- var i;
- for (i = 0; i < stride; ++i) {
- closestPoint[i] = flatCoordinates[i];
- }
- closestPoint.length = stride;
- return squaredDistance;
- } else {
- return minSquaredDistance;
- }
- };
- /**
- * Return the coordinate of the point.
- * @return {ol.Coordinate} Coordinates.
- * @override
- * @api
- */
- ol.geom.Point.prototype.getCoordinates = function() {
- return !this.flatCoordinates ? [] : this.flatCoordinates.slice();
- };
- /**
- * @inheritDoc
- */
- ol.geom.Point.prototype.computeExtent = function(extent) {
- return ol.extent.createOrUpdateFromCoordinate(this.flatCoordinates, extent);
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.Point.prototype.getType = function() {
- return ol.geom.GeometryType.POINT;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.Point.prototype.intersectsExtent = function(extent) {
- return ol.extent.containsXY(extent,
- this.flatCoordinates[0], this.flatCoordinates[1]);
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.Point.prototype.setCoordinates = function(coordinates, opt_layout) {
- if (!coordinates) {
- this.setFlatCoordinates(ol.geom.GeometryLayout.XY, null);
- } else {
- this.setLayout(opt_layout, coordinates, 0);
- if (!this.flatCoordinates) {
- this.flatCoordinates = [];
- }
- this.flatCoordinates.length = ol.geom.flat.deflate.coordinate(
- this.flatCoordinates, 0, coordinates, this.stride);
- this.changed();
- }
- };
- /**
- * @param {ol.geom.GeometryLayout} layout Layout.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- */
- ol.geom.Point.prototype.setFlatCoordinates = function(layout, flatCoordinates) {
- this.setFlatCoordinatesInternal(layout, flatCoordinates);
- this.changed();
- };
- goog.provide('ol.geom.flat.contains');
- goog.require('ol.extent');
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {ol.Extent} extent Extent.
- * @return {boolean} Contains extent.
- */
- ol.geom.flat.contains.linearRingContainsExtent = function(flatCoordinates, offset, end, stride, extent) {
- var outside = ol.extent.forEachCorner(extent,
- /**
- * @param {ol.Coordinate} coordinate Coordinate.
- * @return {boolean} Contains (x, y).
- */
- function(coordinate) {
- return !ol.geom.flat.contains.linearRingContainsXY(flatCoordinates,
- offset, end, stride, coordinate[0], coordinate[1]);
- });
- return !outside;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {number} x X.
- * @param {number} y Y.
- * @return {boolean} Contains (x, y).
- */
- ol.geom.flat.contains.linearRingContainsXY = function(flatCoordinates, offset, end, stride, x, y) {
- // http://geomalgorithms.com/a03-_inclusion.html
- // Copyright 2000 softSurfer, 2012 Dan Sunday
- // This code may be freely used and modified for any purpose
- // providing that this copyright notice is included with it.
- // SoftSurfer makes no warranty for this code, and cannot be held
- // liable for any real or imagined damage resulting from its use.
- // Users of this code must verify correctness for their application.
- var wn = 0;
- var x1 = flatCoordinates[end - stride];
- var y1 = flatCoordinates[end - stride + 1];
- for (; offset < end; offset += stride) {
- var x2 = flatCoordinates[offset];
- var y2 = flatCoordinates[offset + 1];
- if (y1 <= y) {
- if (y2 > y && ((x2 - x1) * (y - y1)) - ((x - x1) * (y2 - y1)) > 0) {
- wn++;
- }
- } else if (y2 <= y && ((x2 - x1) * (y - y1)) - ((x - x1) * (y2 - y1)) < 0) {
- wn--;
- }
- x1 = x2;
- y1 = y2;
- }
- return wn !== 0;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<number>} ends Ends.
- * @param {number} stride Stride.
- * @param {number} x X.
- * @param {number} y Y.
- * @return {boolean} Contains (x, y).
- */
- ol.geom.flat.contains.linearRingsContainsXY = function(flatCoordinates, offset, ends, stride, x, y) {
- if (ends.length === 0) {
- return false;
- }
- if (!ol.geom.flat.contains.linearRingContainsXY(
- flatCoordinates, offset, ends[0], stride, x, y)) {
- return false;
- }
- var i, ii;
- for (i = 1, ii = ends.length; i < ii; ++i) {
- if (ol.geom.flat.contains.linearRingContainsXY(
- flatCoordinates, ends[i - 1], ends[i], stride, x, y)) {
- return false;
- }
- }
- return true;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<Array.<number>>} endss Endss.
- * @param {number} stride Stride.
- * @param {number} x X.
- * @param {number} y Y.
- * @return {boolean} Contains (x, y).
- */
- ol.geom.flat.contains.linearRingssContainsXY = function(flatCoordinates, offset, endss, stride, x, y) {
- if (endss.length === 0) {
- return false;
- }
- var i, ii;
- for (i = 0, ii = endss.length; i < ii; ++i) {
- var ends = endss[i];
- if (ol.geom.flat.contains.linearRingsContainsXY(
- flatCoordinates, offset, ends, stride, x, y)) {
- return true;
- }
- offset = ends[ends.length - 1];
- }
- return false;
- };
- goog.provide('ol.geom.flat.interiorpoint');
- goog.require('ol.array');
- goog.require('ol.geom.flat.contains');
- /**
- * Calculates a point that is likely to lie in the interior of the linear rings.
- * Inspired by JTS's com.vividsolutions.jts.geom.Geometry#getInteriorPoint.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<number>} ends Ends.
- * @param {number} stride Stride.
- * @param {Array.<number>} flatCenters Flat centers.
- * @param {number} flatCentersOffset Flat center offset.
- * @param {Array.<number>=} opt_dest Destination.
- * @return {Array.<number>} Destination point as XYM coordinate, where M is the
- * length of the horizontal intersection that the point belongs to.
- */
- ol.geom.flat.interiorpoint.linearRings = function(flatCoordinates, offset,
- ends, stride, flatCenters, flatCentersOffset, opt_dest) {
- var i, ii, x, x1, x2, y1, y2;
- var y = flatCenters[flatCentersOffset + 1];
- /** @type {Array.<number>} */
- var intersections = [];
- // Calculate intersections with the horizontal line
- for (var r = 0, rr = ends.length; r < rr; ++r) {
- var end = ends[r];
- x1 = flatCoordinates[end - stride];
- y1 = flatCoordinates[end - stride + 1];
- for (i = offset; i < end; i += stride) {
- x2 = flatCoordinates[i];
- y2 = flatCoordinates[i + 1];
- if ((y <= y1 && y2 <= y) || (y1 <= y && y <= y2)) {
- x = (y - y1) / (y2 - y1) * (x2 - x1) + x1;
- intersections.push(x);
- }
- x1 = x2;
- y1 = y2;
- }
- }
- // Find the longest segment of the horizontal line that has its center point
- // inside the linear ring.
- var pointX = NaN;
- var maxSegmentLength = -Infinity;
- intersections.sort(ol.array.numberSafeCompareFunction);
- x1 = intersections[0];
- for (i = 1, ii = intersections.length; i < ii; ++i) {
- x2 = intersections[i];
- var segmentLength = Math.abs(x2 - x1);
- if (segmentLength > maxSegmentLength) {
- x = (x1 + x2) / 2;
- if (ol.geom.flat.contains.linearRingsContainsXY(
- flatCoordinates, offset, ends, stride, x, y)) {
- pointX = x;
- maxSegmentLength = segmentLength;
- }
- }
- x1 = x2;
- }
- if (isNaN(pointX)) {
- // There is no horizontal line that has its center point inside the linear
- // ring. Use the center of the the linear ring's extent.
- pointX = flatCenters[flatCentersOffset];
- }
- if (opt_dest) {
- opt_dest.push(pointX, y, maxSegmentLength);
- return opt_dest;
- } else {
- return [pointX, y, maxSegmentLength];
- }
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<Array.<number>>} endss Endss.
- * @param {number} stride Stride.
- * @param {Array.<number>} flatCenters Flat centers.
- * @return {Array.<number>} Interior points as XYM coordinates, where M is the
- * length of the horizontal intersection that the point belongs to.
- */
- ol.geom.flat.interiorpoint.linearRingss = function(flatCoordinates, offset, endss, stride, flatCenters) {
- var interiorPoints = [];
- var i, ii;
- for (i = 0, ii = endss.length; i < ii; ++i) {
- var ends = endss[i];
- interiorPoints = ol.geom.flat.interiorpoint.linearRings(flatCoordinates,
- offset, ends, stride, flatCenters, 2 * i, interiorPoints);
- offset = ends[ends.length - 1];
- }
- return interiorPoints;
- };
- goog.provide('ol.geom.flat.segments');
- /**
- * This function calls `callback` for each segment of the flat coordinates
- * array. If the callback returns a truthy value the function returns that
- * value immediately. Otherwise the function returns `false`.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {function(this: S, ol.Coordinate, ol.Coordinate): T} callback Function
- * called for each segment.
- * @param {S=} opt_this The object to be used as the value of 'this'
- * within callback.
- * @return {T|boolean} Value.
- * @template T,S
- */
- ol.geom.flat.segments.forEach = function(flatCoordinates, offset, end, stride, callback, opt_this) {
- var point1 = [flatCoordinates[offset], flatCoordinates[offset + 1]];
- var point2 = [];
- var ret;
- for (; (offset + stride) < end; offset += stride) {
- point2[0] = flatCoordinates[offset + stride];
- point2[1] = flatCoordinates[offset + stride + 1];
- ret = callback.call(opt_this, point1, point2);
- if (ret) {
- return ret;
- }
- point1[0] = point2[0];
- point1[1] = point2[1];
- }
- return false;
- };
- goog.provide('ol.geom.flat.intersectsextent');
- goog.require('ol.extent');
- goog.require('ol.geom.flat.contains');
- goog.require('ol.geom.flat.segments');
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {ol.Extent} extent Extent.
- * @return {boolean} True if the geometry and the extent intersect.
- */
- ol.geom.flat.intersectsextent.lineString = function(flatCoordinates, offset, end, stride, extent) {
- var coordinatesExtent = ol.extent.extendFlatCoordinates(
- ol.extent.createEmpty(), flatCoordinates, offset, end, stride);
- if (!ol.extent.intersects(extent, coordinatesExtent)) {
- return false;
- }
- if (ol.extent.containsExtent(extent, coordinatesExtent)) {
- return true;
- }
- if (coordinatesExtent[0] >= extent[0] &&
- coordinatesExtent[2] <= extent[2]) {
- return true;
- }
- if (coordinatesExtent[1] >= extent[1] &&
- coordinatesExtent[3] <= extent[3]) {
- return true;
- }
- return ol.geom.flat.segments.forEach(flatCoordinates, offset, end, stride,
- /**
- * @param {ol.Coordinate} point1 Start point.
- * @param {ol.Coordinate} point2 End point.
- * @return {boolean} `true` if the segment and the extent intersect,
- * `false` otherwise.
- */
- function(point1, point2) {
- return ol.extent.intersectsSegment(extent, point1, point2);
- });
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<number>} ends Ends.
- * @param {number} stride Stride.
- * @param {ol.Extent} extent Extent.
- * @return {boolean} True if the geometry and the extent intersect.
- */
- ol.geom.flat.intersectsextent.lineStrings = function(flatCoordinates, offset, ends, stride, extent) {
- var i, ii;
- for (i = 0, ii = ends.length; i < ii; ++i) {
- if (ol.geom.flat.intersectsextent.lineString(
- flatCoordinates, offset, ends[i], stride, extent)) {
- return true;
- }
- offset = ends[i];
- }
- return false;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {ol.Extent} extent Extent.
- * @return {boolean} True if the geometry and the extent intersect.
- */
- ol.geom.flat.intersectsextent.linearRing = function(flatCoordinates, offset, end, stride, extent) {
- if (ol.geom.flat.intersectsextent.lineString(
- flatCoordinates, offset, end, stride, extent)) {
- return true;
- }
- if (ol.geom.flat.contains.linearRingContainsXY(
- flatCoordinates, offset, end, stride, extent[0], extent[1])) {
- return true;
- }
- if (ol.geom.flat.contains.linearRingContainsXY(
- flatCoordinates, offset, end, stride, extent[0], extent[3])) {
- return true;
- }
- if (ol.geom.flat.contains.linearRingContainsXY(
- flatCoordinates, offset, end, stride, extent[2], extent[1])) {
- return true;
- }
- if (ol.geom.flat.contains.linearRingContainsXY(
- flatCoordinates, offset, end, stride, extent[2], extent[3])) {
- return true;
- }
- return false;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<number>} ends Ends.
- * @param {number} stride Stride.
- * @param {ol.Extent} extent Extent.
- * @return {boolean} True if the geometry and the extent intersect.
- */
- ol.geom.flat.intersectsextent.linearRings = function(flatCoordinates, offset, ends, stride, extent) {
- if (!ol.geom.flat.intersectsextent.linearRing(
- flatCoordinates, offset, ends[0], stride, extent)) {
- return false;
- }
- if (ends.length === 1) {
- return true;
- }
- var i, ii;
- for (i = 1, ii = ends.length; i < ii; ++i) {
- if (ol.geom.flat.contains.linearRingContainsExtent(
- flatCoordinates, ends[i - 1], ends[i], stride, extent)) {
- return false;
- }
- }
- return true;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<Array.<number>>} endss Endss.
- * @param {number} stride Stride.
- * @param {ol.Extent} extent Extent.
- * @return {boolean} True if the geometry and the extent intersect.
- */
- ol.geom.flat.intersectsextent.linearRingss = function(flatCoordinates, offset, endss, stride, extent) {
- var i, ii;
- for (i = 0, ii = endss.length; i < ii; ++i) {
- var ends = endss[i];
- if (ol.geom.flat.intersectsextent.linearRings(
- flatCoordinates, offset, ends, stride, extent)) {
- return true;
- }
- offset = ends[ends.length - 1];
- }
- return false;
- };
- goog.provide('ol.geom.flat.reverse');
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- */
- ol.geom.flat.reverse.coordinates = function(flatCoordinates, offset, end, stride) {
- while (offset < end - stride) {
- var i;
- for (i = 0; i < stride; ++i) {
- var tmp = flatCoordinates[offset + i];
- flatCoordinates[offset + i] = flatCoordinates[end - stride + i];
- flatCoordinates[end - stride + i] = tmp;
- }
- offset += stride;
- end -= stride;
- }
- };
- goog.provide('ol.geom.flat.orient');
- goog.require('ol.geom.flat.reverse');
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @return {boolean} Is clockwise.
- */
- ol.geom.flat.orient.linearRingIsClockwise = function(flatCoordinates, offset, end, stride) {
- // http://tinyurl.com/clockwise-method
- // https://github.com/OSGeo/gdal/blob/trunk/gdal/ogr/ogrlinearring.cpp
- var edge = 0;
- var x1 = flatCoordinates[end - stride];
- var y1 = flatCoordinates[end - stride + 1];
- for (; offset < end; offset += stride) {
- var x2 = flatCoordinates[offset];
- var y2 = flatCoordinates[offset + 1];
- edge += (x2 - x1) * (y2 + y1);
- x1 = x2;
- y1 = y2;
- }
- return edge > 0;
- };
- /**
- * Determines if linear rings are oriented. By default, left-hand orientation
- * is tested (first ring must be clockwise, remaining rings counter-clockwise).
- * To test for right-hand orientation, use the `opt_right` argument.
- *
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<number>} ends Array of end indexes.
- * @param {number} stride Stride.
- * @param {boolean=} opt_right Test for right-hand orientation
- * (counter-clockwise exterior ring and clockwise interior rings).
- * @return {boolean} Rings are correctly oriented.
- */
- ol.geom.flat.orient.linearRingsAreOriented = function(flatCoordinates, offset, ends, stride, opt_right) {
- var right = opt_right !== undefined ? opt_right : false;
- var i, ii;
- for (i = 0, ii = ends.length; i < ii; ++i) {
- var end = ends[i];
- var isClockwise = ol.geom.flat.orient.linearRingIsClockwise(
- flatCoordinates, offset, end, stride);
- if (i === 0) {
- if ((right && isClockwise) || (!right && !isClockwise)) {
- return false;
- }
- } else {
- if ((right && !isClockwise) || (!right && isClockwise)) {
- return false;
- }
- }
- offset = end;
- }
- return true;
- };
- /**
- * Determines if linear rings are oriented. By default, left-hand orientation
- * is tested (first ring must be clockwise, remaining rings counter-clockwise).
- * To test for right-hand orientation, use the `opt_right` argument.
- *
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<Array.<number>>} endss Array of array of end indexes.
- * @param {number} stride Stride.
- * @param {boolean=} opt_right Test for right-hand orientation
- * (counter-clockwise exterior ring and clockwise interior rings).
- * @return {boolean} Rings are correctly oriented.
- */
- ol.geom.flat.orient.linearRingssAreOriented = function(flatCoordinates, offset, endss, stride, opt_right) {
- var i, ii;
- for (i = 0, ii = endss.length; i < ii; ++i) {
- if (!ol.geom.flat.orient.linearRingsAreOriented(
- flatCoordinates, offset, endss[i], stride, opt_right)) {
- return false;
- }
- }
- return true;
- };
- /**
- * Orient coordinates in a flat array of linear rings. By default, rings
- * are oriented following the left-hand rule (clockwise for exterior and
- * counter-clockwise for interior rings). To orient according to the
- * right-hand rule, use the `opt_right` argument.
- *
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<number>} ends Ends.
- * @param {number} stride Stride.
- * @param {boolean=} opt_right Follow the right-hand rule for orientation.
- * @return {number} End.
- */
- ol.geom.flat.orient.orientLinearRings = function(flatCoordinates, offset, ends, stride, opt_right) {
- var right = opt_right !== undefined ? opt_right : false;
- var i, ii;
- for (i = 0, ii = ends.length; i < ii; ++i) {
- var end = ends[i];
- var isClockwise = ol.geom.flat.orient.linearRingIsClockwise(
- flatCoordinates, offset, end, stride);
- var reverse = i === 0 ?
- (right && isClockwise) || (!right && !isClockwise) :
- (right && !isClockwise) || (!right && isClockwise);
- if (reverse) {
- ol.geom.flat.reverse.coordinates(flatCoordinates, offset, end, stride);
- }
- offset = end;
- }
- return offset;
- };
- /**
- * Orient coordinates in a flat array of linear rings. By default, rings
- * are oriented following the left-hand rule (clockwise for exterior and
- * counter-clockwise for interior rings). To orient according to the
- * right-hand rule, use the `opt_right` argument.
- *
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<Array.<number>>} endss Array of array of end indexes.
- * @param {number} stride Stride.
- * @param {boolean=} opt_right Follow the right-hand rule for orientation.
- * @return {number} End.
- */
- ol.geom.flat.orient.orientLinearRingss = function(flatCoordinates, offset, endss, stride, opt_right) {
- var i, ii;
- for (i = 0, ii = endss.length; i < ii; ++i) {
- offset = ol.geom.flat.orient.orientLinearRings(
- flatCoordinates, offset, endss[i], stride, opt_right);
- }
- return offset;
- };
- goog.provide('ol.geom.Polygon');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.extent');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.LinearRing');
- goog.require('ol.geom.Point');
- goog.require('ol.geom.SimpleGeometry');
- goog.require('ol.geom.flat.area');
- goog.require('ol.geom.flat.closest');
- goog.require('ol.geom.flat.contains');
- goog.require('ol.geom.flat.deflate');
- goog.require('ol.geom.flat.inflate');
- goog.require('ol.geom.flat.interiorpoint');
- goog.require('ol.geom.flat.intersectsextent');
- goog.require('ol.geom.flat.orient');
- goog.require('ol.geom.flat.simplify');
- goog.require('ol.math');
- /**
- * @classdesc
- * Polygon geometry.
- *
- * @constructor
- * @extends {ol.geom.SimpleGeometry}
- * @param {Array.<Array.<ol.Coordinate>>} coordinates Array of linear
- * rings that define the polygon. The first linear ring of the array
- * defines the outer-boundary or surface of the polygon. Each subsequent
- * linear ring defines a hole in the surface of the polygon. A linear ring
- * is an array of vertices' coordinates where the first coordinate and the
- * last are equivalent.
- * @param {ol.geom.GeometryLayout=} opt_layout Layout.
- * @api
- */
- ol.geom.Polygon = function(coordinates, opt_layout) {
- ol.geom.SimpleGeometry.call(this);
- /**
- * @type {Array.<number>}
- * @private
- */
- this.ends_ = [];
- /**
- * @private
- * @type {number}
- */
- this.flatInteriorPointRevision_ = -1;
- /**
- * @private
- * @type {ol.Coordinate}
- */
- this.flatInteriorPoint_ = null;
- /**
- * @private
- * @type {number}
- */
- this.maxDelta_ = -1;
- /**
- * @private
- * @type {number}
- */
- this.maxDeltaRevision_ = -1;
- /**
- * @private
- * @type {number}
- */
- this.orientedRevision_ = -1;
- /**
- * @private
- * @type {Array.<number>}
- */
- this.orientedFlatCoordinates_ = null;
- this.setCoordinates(coordinates, opt_layout);
- };
- ol.inherits(ol.geom.Polygon, ol.geom.SimpleGeometry);
- /**
- * Append the passed linear ring to this polygon.
- * @param {ol.geom.LinearRing} linearRing Linear ring.
- * @api
- */
- ol.geom.Polygon.prototype.appendLinearRing = function(linearRing) {
- if (!this.flatCoordinates) {
- this.flatCoordinates = linearRing.getFlatCoordinates().slice();
- } else {
- ol.array.extend(this.flatCoordinates, linearRing.getFlatCoordinates());
- }
- this.ends_.push(this.flatCoordinates.length);
- this.changed();
- };
- /**
- * Make a complete copy of the geometry.
- * @return {!ol.geom.Polygon} Clone.
- * @override
- * @api
- */
- ol.geom.Polygon.prototype.clone = function() {
- var polygon = new ol.geom.Polygon(null);
- polygon.setFlatCoordinates(
- this.layout, this.flatCoordinates.slice(), this.ends_.slice());
- return polygon;
- };
- /**
- * @inheritDoc
- */
- ol.geom.Polygon.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) {
- if (minSquaredDistance <
- ol.extent.closestSquaredDistanceXY(this.getExtent(), x, y)) {
- return minSquaredDistance;
- }
- if (this.maxDeltaRevision_ != this.getRevision()) {
- this.maxDelta_ = Math.sqrt(ol.geom.flat.closest.getsMaxSquaredDelta(
- this.flatCoordinates, 0, this.ends_, this.stride, 0));
- this.maxDeltaRevision_ = this.getRevision();
- }
- return ol.geom.flat.closest.getsClosestPoint(
- this.flatCoordinates, 0, this.ends_, this.stride,
- this.maxDelta_, true, x, y, closestPoint, minSquaredDistance);
- };
- /**
- * @inheritDoc
- */
- ol.geom.Polygon.prototype.containsXY = function(x, y) {
- return ol.geom.flat.contains.linearRingsContainsXY(
- this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride, x, y);
- };
- /**
- * Return the area of the polygon on projected plane.
- * @return {number} Area (on projected plane).
- * @api
- */
- ol.geom.Polygon.prototype.getArea = function() {
- return ol.geom.flat.area.linearRings(
- this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride);
- };
- /**
- * Get the coordinate array for this geometry. This array has the structure
- * of a GeoJSON coordinate array for polygons.
- *
- * @param {boolean=} opt_right Orient coordinates according to the right-hand
- * rule (counter-clockwise for exterior and clockwise for interior rings).
- * If `false`, coordinates will be oriented according to the left-hand rule
- * (clockwise for exterior and counter-clockwise for interior rings).
- * By default, coordinate orientation will depend on how the geometry was
- * constructed.
- * @return {Array.<Array.<ol.Coordinate>>} Coordinates.
- * @override
- * @api
- */
- ol.geom.Polygon.prototype.getCoordinates = function(opt_right) {
- var flatCoordinates;
- if (opt_right !== undefined) {
- flatCoordinates = this.getOrientedFlatCoordinates().slice();
- ol.geom.flat.orient.orientLinearRings(
- flatCoordinates, 0, this.ends_, this.stride, opt_right);
- } else {
- flatCoordinates = this.flatCoordinates;
- }
- return ol.geom.flat.inflate.coordinatess(
- flatCoordinates, 0, this.ends_, this.stride);
- };
- /**
- * @return {Array.<number>} Ends.
- */
- ol.geom.Polygon.prototype.getEnds = function() {
- return this.ends_;
- };
- /**
- * @return {Array.<number>} Interior point.
- */
- ol.geom.Polygon.prototype.getFlatInteriorPoint = function() {
- if (this.flatInteriorPointRevision_ != this.getRevision()) {
- var flatCenter = ol.extent.getCenter(this.getExtent());
- this.flatInteriorPoint_ = ol.geom.flat.interiorpoint.linearRings(
- this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride,
- flatCenter, 0);
- this.flatInteriorPointRevision_ = this.getRevision();
- }
- return this.flatInteriorPoint_;
- };
- /**
- * Return an interior point of the polygon.
- * @return {ol.geom.Point} Interior point as XYM coordinate, where M is the
- * length of the horizontal intersection that the point belongs to.
- * @api
- */
- ol.geom.Polygon.prototype.getInteriorPoint = function() {
- return new ol.geom.Point(this.getFlatInteriorPoint(), ol.geom.GeometryLayout.XYM);
- };
- /**
- * Return the number of rings of the polygon, this includes the exterior
- * ring and any interior rings.
- *
- * @return {number} Number of rings.
- * @api
- */
- ol.geom.Polygon.prototype.getLinearRingCount = function() {
- return this.ends_.length;
- };
- /**
- * Return the Nth linear ring of the polygon geometry. Return `null` if the
- * given index is out of range.
- * The exterior linear ring is available at index `0` and the interior rings
- * at index `1` and beyond.
- *
- * @param {number} index Index.
- * @return {ol.geom.LinearRing} Linear ring.
- * @api
- */
- ol.geom.Polygon.prototype.getLinearRing = function(index) {
- if (index < 0 || this.ends_.length <= index) {
- return null;
- }
- var linearRing = new ol.geom.LinearRing(null);
- linearRing.setFlatCoordinates(this.layout, this.flatCoordinates.slice(
- index === 0 ? 0 : this.ends_[index - 1], this.ends_[index]));
- return linearRing;
- };
- /**
- * Return the linear rings of the polygon.
- * @return {Array.<ol.geom.LinearRing>} Linear rings.
- * @api
- */
- ol.geom.Polygon.prototype.getLinearRings = function() {
- var layout = this.layout;
- var flatCoordinates = this.flatCoordinates;
- var ends = this.ends_;
- var linearRings = [];
- var offset = 0;
- var i, ii;
- for (i = 0, ii = ends.length; i < ii; ++i) {
- var end = ends[i];
- var linearRing = new ol.geom.LinearRing(null);
- linearRing.setFlatCoordinates(layout, flatCoordinates.slice(offset, end));
- linearRings.push(linearRing);
- offset = end;
- }
- return linearRings;
- };
- /**
- * @return {Array.<number>} Oriented flat coordinates.
- */
- ol.geom.Polygon.prototype.getOrientedFlatCoordinates = function() {
- if (this.orientedRevision_ != this.getRevision()) {
- var flatCoordinates = this.flatCoordinates;
- if (ol.geom.flat.orient.linearRingsAreOriented(
- flatCoordinates, 0, this.ends_, this.stride)) {
- this.orientedFlatCoordinates_ = flatCoordinates;
- } else {
- this.orientedFlatCoordinates_ = flatCoordinates.slice();
- this.orientedFlatCoordinates_.length =
- ol.geom.flat.orient.orientLinearRings(
- this.orientedFlatCoordinates_, 0, this.ends_, this.stride);
- }
- this.orientedRevision_ = this.getRevision();
- }
- return this.orientedFlatCoordinates_;
- };
- /**
- * @inheritDoc
- */
- ol.geom.Polygon.prototype.getSimplifiedGeometryInternal = function(squaredTolerance) {
- var simplifiedFlatCoordinates = [];
- var simplifiedEnds = [];
- simplifiedFlatCoordinates.length = ol.geom.flat.simplify.quantizes(
- this.flatCoordinates, 0, this.ends_, this.stride,
- Math.sqrt(squaredTolerance),
- simplifiedFlatCoordinates, 0, simplifiedEnds);
- var simplifiedPolygon = new ol.geom.Polygon(null);
- simplifiedPolygon.setFlatCoordinates(
- ol.geom.GeometryLayout.XY, simplifiedFlatCoordinates, simplifiedEnds);
- return simplifiedPolygon;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.Polygon.prototype.getType = function() {
- return ol.geom.GeometryType.POLYGON;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.Polygon.prototype.intersectsExtent = function(extent) {
- return ol.geom.flat.intersectsextent.linearRings(
- this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride, extent);
- };
- /**
- * Set the coordinates of the polygon.
- * @param {Array.<Array.<ol.Coordinate>>} coordinates Coordinates.
- * @param {ol.geom.GeometryLayout=} opt_layout Layout.
- * @override
- * @api
- */
- ol.geom.Polygon.prototype.setCoordinates = function(coordinates, opt_layout) {
- if (!coordinates) {
- this.setFlatCoordinates(ol.geom.GeometryLayout.XY, null, this.ends_);
- } else {
- this.setLayout(opt_layout, coordinates, 2);
- if (!this.flatCoordinates) {
- this.flatCoordinates = [];
- }
- var ends = ol.geom.flat.deflate.coordinatess(
- this.flatCoordinates, 0, coordinates, this.stride, this.ends_);
- this.flatCoordinates.length = ends.length === 0 ? 0 : ends[ends.length - 1];
- this.changed();
- }
- };
- /**
- * @param {ol.geom.GeometryLayout} layout Layout.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {Array.<number>} ends Ends.
- */
- ol.geom.Polygon.prototype.setFlatCoordinates = function(layout, flatCoordinates, ends) {
- this.setFlatCoordinatesInternal(layout, flatCoordinates);
- this.ends_ = ends;
- this.changed();
- };
- /**
- * Create an approximation of a circle on the surface of a sphere.
- * @param {ol.Sphere} sphere The sphere.
- * @param {ol.Coordinate} center Center (`[lon, lat]` in degrees).
- * @param {number} radius The great-circle distance from the center to
- * the polygon vertices.
- * @param {number=} opt_n Optional number of vertices for the resulting
- * polygon. Default is `32`.
- * @return {ol.geom.Polygon} The "circular" polygon.
- * @api
- */
- ol.geom.Polygon.circular = function(sphere, center, radius, opt_n) {
- var n = opt_n ? opt_n : 32;
- /** @type {Array.<number>} */
- var flatCoordinates = [];
- var i;
- for (i = 0; i < n; ++i) {
- ol.array.extend(
- flatCoordinates, sphere.offset(center, radius, 2 * Math.PI * i / n));
- }
- flatCoordinates.push(flatCoordinates[0], flatCoordinates[1]);
- var polygon = new ol.geom.Polygon(null);
- polygon.setFlatCoordinates(
- ol.geom.GeometryLayout.XY, flatCoordinates, [flatCoordinates.length]);
- return polygon;
- };
- /**
- * Create a polygon from an extent. The layout used is `XY`.
- * @param {ol.Extent} extent The extent.
- * @return {ol.geom.Polygon} The polygon.
- * @api
- */
- ol.geom.Polygon.fromExtent = function(extent) {
- var minX = extent[0];
- var minY = extent[1];
- var maxX = extent[2];
- var maxY = extent[3];
- var flatCoordinates =
- [minX, minY, minX, maxY, maxX, maxY, maxX, minY, minX, minY];
- var polygon = new ol.geom.Polygon(null);
- polygon.setFlatCoordinates(
- ol.geom.GeometryLayout.XY, flatCoordinates, [flatCoordinates.length]);
- return polygon;
- };
- /**
- * Create a regular polygon from a circle.
- * @param {ol.geom.Circle} circle Circle geometry.
- * @param {number=} opt_sides Number of sides of the polygon. Default is 32.
- * @param {number=} opt_angle Start angle for the first vertex of the polygon in
- * radians. Default is 0.
- * @return {ol.geom.Polygon} Polygon geometry.
- * @api
- */
- ol.geom.Polygon.fromCircle = function(circle, opt_sides, opt_angle) {
- var sides = opt_sides ? opt_sides : 32;
- var stride = circle.getStride();
- var layout = circle.getLayout();
- var polygon = new ol.geom.Polygon(null, layout);
- var arrayLength = stride * (sides + 1);
- var flatCoordinates = new Array(arrayLength);
- for (var i = 0; i < arrayLength; i++) {
- flatCoordinates[i] = 0;
- }
- var ends = [flatCoordinates.length];
- polygon.setFlatCoordinates(layout, flatCoordinates, ends);
- ol.geom.Polygon.makeRegular(
- polygon, circle.getCenter(), circle.getRadius(), opt_angle);
- return polygon;
- };
- /**
- * Modify the coordinates of a polygon to make it a regular polygon.
- * @param {ol.geom.Polygon} polygon Polygon geometry.
- * @param {ol.Coordinate} center Center of the regular polygon.
- * @param {number} radius Radius of the regular polygon.
- * @param {number=} opt_angle Start angle for the first vertex of the polygon in
- * radians. Default is 0.
- */
- ol.geom.Polygon.makeRegular = function(polygon, center, radius, opt_angle) {
- var flatCoordinates = polygon.getFlatCoordinates();
- var layout = polygon.getLayout();
- var stride = polygon.getStride();
- var ends = polygon.getEnds();
- var sides = flatCoordinates.length / stride - 1;
- var startAngle = opt_angle ? opt_angle : 0;
- var angle, offset;
- for (var i = 0; i <= sides; ++i) {
- offset = i * stride;
- angle = startAngle + (ol.math.modulo(i, sides) * 2 * Math.PI / sides);
- flatCoordinates[offset] = center[0] + (radius * Math.cos(angle));
- flatCoordinates[offset + 1] = center[1] + (radius * Math.sin(angle));
- }
- polygon.setFlatCoordinates(layout, flatCoordinates, ends);
- };
- goog.provide('ol.View');
- goog.require('ol');
- goog.require('ol.CenterConstraint');
- goog.require('ol.Object');
- goog.require('ol.ResolutionConstraint');
- goog.require('ol.RotationConstraint');
- goog.require('ol.ViewHint');
- goog.require('ol.ViewProperty');
- goog.require('ol.array');
- goog.require('ol.asserts');
- goog.require('ol.coordinate');
- goog.require('ol.easing');
- goog.require('ol.extent');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.Polygon');
- goog.require('ol.geom.SimpleGeometry');
- goog.require('ol.math');
- goog.require('ol.obj');
- goog.require('ol.proj');
- goog.require('ol.proj.Units');
- /**
- * @classdesc
- * An ol.View object represents a simple 2D view of the map.
- *
- * This is the object to act upon to change the center, resolution,
- * and rotation of the map.
- *
- * ### The view states
- *
- * An `ol.View` is determined by three states: `center`, `resolution`,
- * and `rotation`. Each state has a corresponding getter and setter, e.g.
- * `getCenter` and `setCenter` for the `center` state.
- *
- * An `ol.View` has a `projection`. The projection determines the
- * coordinate system of the center, and its units determine the units of the
- * resolution (projection units per pixel). The default projection is
- * Spherical Mercator (EPSG:3857).
- *
- * ### The constraints
- *
- * `setCenter`, `setResolution` and `setRotation` can be used to change the
- * states of the view. Any value can be passed to the setters. And the value
- * that is passed to a setter will effectively be the value set in the view,
- * and returned by the corresponding getter.
- *
- * But an `ol.View` object also has a *resolution constraint*, a
- * *rotation constraint* and a *center constraint*.
- *
- * As said above, no constraints are applied when the setters are used to set
- * new states for the view. Applying constraints is done explicitly through
- * the use of the `constrain*` functions (`constrainResolution` and
- * `constrainRotation` and `constrainCenter`).
- *
- * The main users of the constraints are the interactions and the
- * controls. For example, double-clicking on the map changes the view to
- * the "next" resolution. And releasing the fingers after pinch-zooming
- * snaps to the closest resolution (with an animation).
- *
- * The *resolution constraint* snaps to specific resolutions. It is
- * determined by the following options: `resolutions`, `maxResolution`,
- * `maxZoom`, and `zoomFactor`. If `resolutions` is set, the other three
- * options are ignored. See documentation for each option for more
- * information.
- *
- * The *rotation constraint* snaps to specific angles. It is determined
- * by the following options: `enableRotation` and `constrainRotation`.
- * By default the rotation value is snapped to zero when approaching the
- * horizontal.
- *
- * The *center constraint* is determined by the `extent` option. By
- * default the center is not constrained at all.
- *
- * @constructor
- * @extends {ol.Object}
- * @param {olx.ViewOptions=} opt_options View options.
- * @api
- */
- ol.View = function(opt_options) {
- ol.Object.call(this);
- var options = ol.obj.assign({}, opt_options);
- /**
- * @private
- * @type {Array.<number>}
- */
- this.hints_ = [0, 0];
- /**
- * @private
- * @type {Array.<Array.<ol.ViewAnimation>>}
- */
- this.animations_ = [];
- /**
- * @private
- * @type {number|undefined}
- */
- this.updateAnimationKey_;
- this.updateAnimations_ = this.updateAnimations_.bind(this);
- /**
- * @private
- * @const
- * @type {ol.proj.Projection}
- */
- this.projection_ = ol.proj.createProjection(options.projection, 'EPSG:3857');
- this.applyOptions_(options);
- };
- ol.inherits(ol.View, ol.Object);
- /**
- * Set up the view with the given options.
- * @param {olx.ViewOptions} options View options.
- */
- ol.View.prototype.applyOptions_ = function(options) {
- /**
- * @type {Object.<string, *>}
- */
- var properties = {};
- properties[ol.ViewProperty.CENTER] = options.center !== undefined ?
- options.center : null;
- var resolutionConstraintInfo = ol.View.createResolutionConstraint_(
- options);
- /**
- * @private
- * @type {number}
- */
- this.maxResolution_ = resolutionConstraintInfo.maxResolution;
- /**
- * @private
- * @type {number}
- */
- this.minResolution_ = resolutionConstraintInfo.minResolution;
- /**
- * @private
- * @type {number}
- */
- this.zoomFactor_ = resolutionConstraintInfo.zoomFactor;
- /**
- * @private
- * @type {Array.<number>|undefined}
- */
- this.resolutions_ = options.resolutions;
- /**
- * @private
- * @type {number}
- */
- this.minZoom_ = resolutionConstraintInfo.minZoom;
- var centerConstraint = ol.View.createCenterConstraint_(options);
- var resolutionConstraint = resolutionConstraintInfo.constraint;
- var rotationConstraint = ol.View.createRotationConstraint_(options);
- /**
- * @private
- * @type {ol.Constraints}
- */
- this.constraints_ = {
- center: centerConstraint,
- resolution: resolutionConstraint,
- rotation: rotationConstraint
- };
- if (options.resolution !== undefined) {
- properties[ol.ViewProperty.RESOLUTION] = options.resolution;
- } else if (options.zoom !== undefined) {
- properties[ol.ViewProperty.RESOLUTION] = this.constrainResolution(
- this.maxResolution_, options.zoom - this.minZoom_);
- if (this.resolutions_) { // in case map zoom is out of min/max zoom range
- properties[ol.ViewProperty.RESOLUTION] = ol.math.clamp(
- Number(this.getResolution() || properties[ol.ViewProperty.RESOLUTION]),
- this.minResolution_, this.maxResolution_);
- }
- }
- properties[ol.ViewProperty.ROTATION] =
- options.rotation !== undefined ? options.rotation : 0;
- this.setProperties(properties);
- /**
- * @private
- * @type {olx.ViewOptions}
- */
- this.options_ = options;
- };
- /**
- * Get an updated version of the view options used to construct the view. The
- * current resolution (or zoom), center, and rotation are applied to any stored
- * options. The provided options can be uesd to apply new min/max zoom or
- * resolution limits.
- * @param {olx.ViewOptions} newOptions New options to be applied.
- * @return {olx.ViewOptions} New options updated with the current view state.
- */
- ol.View.prototype.getUpdatedOptions_ = function(newOptions) {
- var options = ol.obj.assign({}, this.options_);
- // preserve resolution (or zoom)
- if (options.resolution !== undefined) {
- options.resolution = this.getResolution();
- } else {
- options.zoom = this.getZoom();
- }
- // preserve center
- options.center = this.getCenter();
- // preserve rotation
- options.rotation = this.getRotation();
- return ol.obj.assign({}, options, newOptions);
- };
- /**
- * Animate the view. The view's center, zoom (or resolution), and rotation
- * can be animated for smooth transitions between view states. For example,
- * to animate the view to a new zoom level:
- *
- * view.animate({zoom: view.getZoom() + 1});
- *
- * By default, the animation lasts one second and uses in-and-out easing. You
- * can customize this behavior by including `duration` (in milliseconds) and
- * `easing` options (see {@link ol.easing}).
- *
- * To chain together multiple animations, call the method with multiple
- * animation objects. For example, to first zoom and then pan:
- *
- * view.animate({zoom: 10}, {center: [0, 0]});
- *
- * If you provide a function as the last argument to the animate method, it
- * will get called at the end of an animation series. The callback will be
- * called with `true` if the animation series completed on its own or `false`
- * if it was cancelled.
- *
- * Animations are cancelled by user interactions (e.g. dragging the map) or by
- * calling `view.setCenter()`, `view.setResolution()`, or `view.setRotation()`
- * (or another method that calls one of these).
- *
- * @param {...(olx.AnimationOptions|function(boolean))} var_args Animation
- * options. Multiple animations can be run in series by passing multiple
- * options objects. To run multiple animations in parallel, call the method
- * multiple times. An optional callback can be provided as a final
- * argument. The callback will be called with a boolean indicating whether
- * the animation completed without being cancelled.
- * @api
- */
- ol.View.prototype.animate = function(var_args) {
- var animationCount = arguments.length;
- var callback;
- if (animationCount > 1 && typeof arguments[animationCount - 1] === 'function') {
- callback = arguments[animationCount - 1];
- --animationCount;
- }
- if (!this.isDef()) {
- // if view properties are not yet set, shortcut to the final state
- var state = arguments[animationCount - 1];
- if (state.center) {
- this.setCenter(state.center);
- }
- if (state.zoom !== undefined) {
- this.setZoom(state.zoom);
- }
- if (state.rotation !== undefined) {
- this.setRotation(state.rotation);
- }
- if (callback) {
- callback(true);
- }
- return;
- }
- var start = Date.now();
- var center = this.getCenter().slice();
- var resolution = this.getResolution();
- var rotation = this.getRotation();
- var series = [];
- for (var i = 0; i < animationCount; ++i) {
- var options = /** @type {olx.AnimationOptions} */ (arguments[i]);
- var animation = /** @type {ol.ViewAnimation} */ ({
- start: start,
- complete: false,
- anchor: options.anchor,
- duration: options.duration !== undefined ? options.duration : 1000,
- easing: options.easing || ol.easing.inAndOut
- });
- if (options.center) {
- animation.sourceCenter = center;
- animation.targetCenter = options.center;
- center = animation.targetCenter;
- }
- if (options.zoom !== undefined) {
- animation.sourceResolution = resolution;
- animation.targetResolution = this.constrainResolution(
- this.maxResolution_, options.zoom - this.minZoom_, 0);
- resolution = animation.targetResolution;
- } else if (options.resolution) {
- animation.sourceResolution = resolution;
- animation.targetResolution = options.resolution;
- resolution = animation.targetResolution;
- }
- if (options.rotation !== undefined) {
- animation.sourceRotation = rotation;
- var delta = ol.math.modulo(options.rotation - rotation + Math.PI, 2 * Math.PI) - Math.PI;
- animation.targetRotation = rotation + delta;
- rotation = animation.targetRotation;
- }
- animation.callback = callback;
- // check if animation is a no-op
- if (ol.View.isNoopAnimation(animation)) {
- animation.complete = true;
- // we still push it onto the series for callback handling
- } else {
- start += animation.duration;
- }
- series.push(animation);
- }
- this.animations_.push(series);
- this.setHint(ol.ViewHint.ANIMATING, 1);
- this.updateAnimations_();
- };
- /**
- * Determine if the view is being animated.
- * @return {boolean} The view is being animated.
- * @api
- */
- ol.View.prototype.getAnimating = function() {
- return this.hints_[ol.ViewHint.ANIMATING] > 0;
- };
- /**
- * Determine if the user is interacting with the view, such as panning or zooming.
- * @return {boolean} The view is being interacted with.
- * @api
- */
- ol.View.prototype.getInteracting = function() {
- return this.hints_[ol.ViewHint.INTERACTING] > 0;
- };
- /**
- * Cancel any ongoing animations.
- * @api
- */
- ol.View.prototype.cancelAnimations = function() {
- this.setHint(ol.ViewHint.ANIMATING, -this.hints_[ol.ViewHint.ANIMATING]);
- for (var i = 0, ii = this.animations_.length; i < ii; ++i) {
- var series = this.animations_[i];
- if (series[0].callback) {
- series[0].callback(false);
- }
- }
- this.animations_.length = 0;
- };
- /**
- * Update all animations.
- */
- ol.View.prototype.updateAnimations_ = function() {
- if (this.updateAnimationKey_ !== undefined) {
- cancelAnimationFrame(this.updateAnimationKey_);
- this.updateAnimationKey_ = undefined;
- }
- if (!this.getAnimating()) {
- return;
- }
- var now = Date.now();
- var more = false;
- for (var i = this.animations_.length - 1; i >= 0; --i) {
- var series = this.animations_[i];
- var seriesComplete = true;
- for (var j = 0, jj = series.length; j < jj; ++j) {
- var animation = series[j];
- if (animation.complete) {
- continue;
- }
- var elapsed = now - animation.start;
- var fraction = animation.duration > 0 ? elapsed / animation.duration : 1;
- if (fraction >= 1) {
- animation.complete = true;
- fraction = 1;
- } else {
- seriesComplete = false;
- }
- var progress = animation.easing(fraction);
- if (animation.sourceCenter) {
- var x0 = animation.sourceCenter[0];
- var y0 = animation.sourceCenter[1];
- var x1 = animation.targetCenter[0];
- var y1 = animation.targetCenter[1];
- var x = x0 + progress * (x1 - x0);
- var y = y0 + progress * (y1 - y0);
- this.set(ol.ViewProperty.CENTER, [x, y]);
- }
- if (animation.sourceResolution && animation.targetResolution) {
- var resolution = progress === 1 ?
- animation.targetResolution :
- animation.sourceResolution + progress * (animation.targetResolution - animation.sourceResolution);
- if (animation.anchor) {
- this.set(ol.ViewProperty.CENTER,
- this.calculateCenterZoom(resolution, animation.anchor));
- }
- this.set(ol.ViewProperty.RESOLUTION, resolution);
- }
- if (animation.sourceRotation !== undefined && animation.targetRotation !== undefined) {
- var rotation = progress === 1 ?
- ol.math.modulo(animation.targetRotation + Math.PI, 2 * Math.PI) - Math.PI :
- animation.sourceRotation + progress * (animation.targetRotation - animation.sourceRotation);
- if (animation.anchor) {
- this.set(ol.ViewProperty.CENTER,
- this.calculateCenterRotate(rotation, animation.anchor));
- }
- this.set(ol.ViewProperty.ROTATION, rotation);
- }
- more = true;
- if (!animation.complete) {
- break;
- }
- }
- if (seriesComplete) {
- this.animations_[i] = null;
- this.setHint(ol.ViewHint.ANIMATING, -1);
- var callback = series[0].callback;
- if (callback) {
- callback(true);
- }
- }
- }
- // prune completed series
- this.animations_ = this.animations_.filter(Boolean);
- if (more && this.updateAnimationKey_ === undefined) {
- this.updateAnimationKey_ = requestAnimationFrame(this.updateAnimations_);
- }
- };
- /**
- * @param {number} rotation Target rotation.
- * @param {ol.Coordinate} anchor Rotation anchor.
- * @return {ol.Coordinate|undefined} Center for rotation and anchor.
- */
- ol.View.prototype.calculateCenterRotate = function(rotation, anchor) {
- var center;
- var currentCenter = this.getCenter();
- if (currentCenter !== undefined) {
- center = [currentCenter[0] - anchor[0], currentCenter[1] - anchor[1]];
- ol.coordinate.rotate(center, rotation - this.getRotation());
- ol.coordinate.add(center, anchor);
- }
- return center;
- };
- /**
- * @param {number} resolution Target resolution.
- * @param {ol.Coordinate} anchor Zoom anchor.
- * @return {ol.Coordinate|undefined} Center for resolution and anchor.
- */
- ol.View.prototype.calculateCenterZoom = function(resolution, anchor) {
- var center;
- var currentCenter = this.getCenter();
- var currentResolution = this.getResolution();
- if (currentCenter !== undefined && currentResolution !== undefined) {
- var x = anchor[0] -
- resolution * (anchor[0] - currentCenter[0]) / currentResolution;
- var y = anchor[1] -
- resolution * (anchor[1] - currentCenter[1]) / currentResolution;
- center = [x, y];
- }
- return center;
- };
- /**
- * @private
- * @return {ol.Size} Viewport size or `[100, 100]` when no viewport is found.
- */
- ol.View.prototype.getSizeFromViewport_ = function() {
- var size = [100, 100];
- var selector = '.ol-viewport[data-view="' + ol.getUid(this) + '"]';
- var element = document.querySelector(selector);
- if (element) {
- var metrics = getComputedStyle(element);
- size[0] = parseInt(metrics.width, 10);
- size[1] = parseInt(metrics.height, 10);
- }
- return size;
- };
- /**
- * Get the constrained center of this view.
- * @param {ol.Coordinate|undefined} center Center.
- * @return {ol.Coordinate|undefined} Constrained center.
- * @api
- */
- ol.View.prototype.constrainCenter = function(center) {
- return this.constraints_.center(center);
- };
- /**
- * Get the constrained resolution of this view.
- * @param {number|undefined} resolution Resolution.
- * @param {number=} opt_delta Delta. Default is `0`.
- * @param {number=} opt_direction Direction. Default is `0`.
- * @return {number|undefined} Constrained resolution.
- * @api
- */
- ol.View.prototype.constrainResolution = function(
- resolution, opt_delta, opt_direction) {
- var delta = opt_delta || 0;
- var direction = opt_direction || 0;
- return this.constraints_.resolution(resolution, delta, direction);
- };
- /**
- * Get the constrained rotation of this view.
- * @param {number|undefined} rotation Rotation.
- * @param {number=} opt_delta Delta. Default is `0`.
- * @return {number|undefined} Constrained rotation.
- * @api
- */
- ol.View.prototype.constrainRotation = function(rotation, opt_delta) {
- var delta = opt_delta || 0;
- return this.constraints_.rotation(rotation, delta);
- };
- /**
- * Get the view center.
- * @return {ol.Coordinate|undefined} The center of the view.
- * @observable
- * @api
- */
- ol.View.prototype.getCenter = function() {
- return /** @type {ol.Coordinate|undefined} */ (
- this.get(ol.ViewProperty.CENTER));
- };
- /**
- * @return {ol.Constraints} Constraints.
- */
- ol.View.prototype.getConstraints = function() {
- return this.constraints_;
- };
- /**
- * @param {Array.<number>=} opt_hints Destination array.
- * @return {Array.<number>} Hint.
- */
- ol.View.prototype.getHints = function(opt_hints) {
- if (opt_hints !== undefined) {
- opt_hints[0] = this.hints_[0];
- opt_hints[1] = this.hints_[1];
- return opt_hints;
- } else {
- return this.hints_.slice();
- }
- };
- /**
- * Calculate the extent for the current view state and the passed size.
- * The size is the pixel dimensions of the box into which the calculated extent
- * should fit. In most cases you want to get the extent of the entire map,
- * that is `map.getSize()`.
- * @param {ol.Size=} opt_size Box pixel size. If not provided, the size of the
- * first map that uses this view will be used.
- * @return {ol.Extent} Extent.
- * @api
- */
- ol.View.prototype.calculateExtent = function(opt_size) {
- var size = opt_size || this.getSizeFromViewport_();
- var center = /** @type {!ol.Coordinate} */ (this.getCenter());
- ol.asserts.assert(center, 1); // The view center is not defined
- var resolution = /** @type {!number} */ (this.getResolution());
- ol.asserts.assert(resolution !== undefined, 2); // The view resolution is not defined
- var rotation = /** @type {!number} */ (this.getRotation());
- ol.asserts.assert(rotation !== undefined, 3); // The view rotation is not defined
- return ol.extent.getForViewAndSize(center, resolution, rotation, size);
- };
- /**
- * Get the maximum resolution of the view.
- * @return {number} The maximum resolution of the view.
- * @api
- */
- ol.View.prototype.getMaxResolution = function() {
- return this.maxResolution_;
- };
- /**
- * Get the minimum resolution of the view.
- * @return {number} The minimum resolution of the view.
- * @api
- */
- ol.View.prototype.getMinResolution = function() {
- return this.minResolution_;
- };
- /**
- * Get the maximum zoom level for the view.
- * @return {number} The maximum zoom level.
- * @api
- */
- ol.View.prototype.getMaxZoom = function() {
- return /** @type {number} */ (this.getZoomForResolution(this.minResolution_));
- };
- /**
- * Set a new maximum zoom level for the view.
- * @param {number} zoom The maximum zoom level.
- * @api
- */
- ol.View.prototype.setMaxZoom = function(zoom) {
- this.applyOptions_(this.getUpdatedOptions_({maxZoom: zoom}));
- };
- /**
- * Get the minimum zoom level for the view.
- * @return {number} The minimum zoom level.
- * @api
- */
- ol.View.prototype.getMinZoom = function() {
- return /** @type {number} */ (this.getZoomForResolution(this.maxResolution_));
- };
- /**
- * Set a new minimum zoom level for the view.
- * @param {number} zoom The minimum zoom level.
- * @api
- */
- ol.View.prototype.setMinZoom = function(zoom) {
- this.applyOptions_(this.getUpdatedOptions_({minZoom: zoom}));
- };
- /**
- * Get the view projection.
- * @return {ol.proj.Projection} The projection of the view.
- * @api
- */
- ol.View.prototype.getProjection = function() {
- return this.projection_;
- };
- /**
- * Get the view resolution.
- * @return {number|undefined} The resolution of the view.
- * @observable
- * @api
- */
- ol.View.prototype.getResolution = function() {
- return /** @type {number|undefined} */ (
- this.get(ol.ViewProperty.RESOLUTION));
- };
- /**
- * Get the resolutions for the view. This returns the array of resolutions
- * passed to the constructor of the {ol.View}, or undefined if none were given.
- * @return {Array.<number>|undefined} The resolutions of the view.
- * @api
- */
- ol.View.prototype.getResolutions = function() {
- return this.resolutions_;
- };
- /**
- * Get the resolution for a provided extent (in map units) and size (in pixels).
- * @param {ol.Extent} extent Extent.
- * @param {ol.Size=} opt_size Box pixel size.
- * @return {number} The resolution at which the provided extent will render at
- * the given size.
- * @api
- */
- ol.View.prototype.getResolutionForExtent = function(extent, opt_size) {
- var size = opt_size || this.getSizeFromViewport_();
- var xResolution = ol.extent.getWidth(extent) / size[0];
- var yResolution = ol.extent.getHeight(extent) / size[1];
- return Math.max(xResolution, yResolution);
- };
- /**
- * Return a function that returns a value between 0 and 1 for a
- * resolution. Exponential scaling is assumed.
- * @param {number=} opt_power Power.
- * @return {function(number): number} Resolution for value function.
- */
- ol.View.prototype.getResolutionForValueFunction = function(opt_power) {
- var power = opt_power || 2;
- var maxResolution = this.maxResolution_;
- var minResolution = this.minResolution_;
- var max = Math.log(maxResolution / minResolution) / Math.log(power);
- return (
- /**
- * @param {number} value Value.
- * @return {number} Resolution.
- */
- function(value) {
- var resolution = maxResolution / Math.pow(power, value * max);
- return resolution;
- });
- };
- /**
- * Get the view rotation.
- * @return {number} The rotation of the view in radians.
- * @observable
- * @api
- */
- ol.View.prototype.getRotation = function() {
- return /** @type {number} */ (this.get(ol.ViewProperty.ROTATION));
- };
- /**
- * Return a function that returns a resolution for a value between
- * 0 and 1. Exponential scaling is assumed.
- * @param {number=} opt_power Power.
- * @return {function(number): number} Value for resolution function.
- */
- ol.View.prototype.getValueForResolutionFunction = function(opt_power) {
- var power = opt_power || 2;
- var maxResolution = this.maxResolution_;
- var minResolution = this.minResolution_;
- var max = Math.log(maxResolution / minResolution) / Math.log(power);
- return (
- /**
- * @param {number} resolution Resolution.
- * @return {number} Value.
- */
- function(resolution) {
- var value =
- (Math.log(maxResolution / resolution) / Math.log(power)) / max;
- return value;
- });
- };
- /**
- * @return {olx.ViewState} View state.
- */
- ol.View.prototype.getState = function() {
- var center = /** @type {ol.Coordinate} */ (this.getCenter());
- var projection = this.getProjection();
- var resolution = /** @type {number} */ (this.getResolution());
- var rotation = this.getRotation();
- return /** @type {olx.ViewState} */ ({
- center: center.slice(),
- projection: projection !== undefined ? projection : null,
- resolution: resolution,
- rotation: rotation,
- zoom: this.getZoom()
- });
- };
- /**
- * Get the current zoom level. If you configured your view with a resolutions
- * array (this is rare), this method may return non-integer zoom levels (so
- * the zoom level is not safe to use as an index into a resolutions array).
- * @return {number|undefined} Zoom.
- * @api
- */
- ol.View.prototype.getZoom = function() {
- var zoom;
- var resolution = this.getResolution();
- if (resolution !== undefined) {
- zoom = this.getZoomForResolution(resolution);
- }
- return zoom;
- };
- /**
- * Get the zoom level for a resolution.
- * @param {number} resolution The resolution.
- * @return {number|undefined} The zoom level for the provided resolution.
- * @api
- */
- ol.View.prototype.getZoomForResolution = function(resolution) {
- var offset = this.minZoom_ || 0;
- var max, zoomFactor;
- if (this.resolutions_) {
- var nearest = ol.array.linearFindNearest(this.resolutions_, resolution, 1);
- offset = nearest;
- max = this.resolutions_[nearest];
- if (nearest == this.resolutions_.length - 1) {
- zoomFactor = 2;
- } else {
- zoomFactor = max / this.resolutions_[nearest + 1];
- }
- } else {
- max = this.maxResolution_;
- zoomFactor = this.zoomFactor_;
- }
- return offset + Math.log(max / resolution) / Math.log(zoomFactor);
- };
- /**
- * Get the resolution for a zoom level.
- * @param {number} zoom Zoom level.
- * @return {number} The view resolution for the provided zoom level.
- * @api
- */
- ol.View.prototype.getResolutionForZoom = function(zoom) {
- return /** @type {number} */ (this.constrainResolution(
- this.maxResolution_, zoom - this.minZoom_, 0));
- };
- /**
- * Fit the given geometry or extent based on the given map size and border.
- * The size is pixel dimensions of the box to fit the extent into.
- * In most cases you will want to use the map size, that is `map.getSize()`.
- * Takes care of the map angle.
- * @param {ol.geom.SimpleGeometry|ol.Extent} geometryOrExtent The geometry or
- * extent to fit the view to.
- * @param {olx.view.FitOptions=} opt_options Options.
- * @api
- */
- ol.View.prototype.fit = function(geometryOrExtent, opt_options) {
- var options = opt_options || {};
- var size = options.size;
- if (!size) {
- size = this.getSizeFromViewport_();
- }
- /** @type {ol.geom.SimpleGeometry} */
- var geometry;
- if (!(geometryOrExtent instanceof ol.geom.SimpleGeometry)) {
- ol.asserts.assert(Array.isArray(geometryOrExtent),
- 24); // Invalid extent or geometry provided as `geometry`
- ol.asserts.assert(!ol.extent.isEmpty(geometryOrExtent),
- 25); // Cannot fit empty extent provided as `geometry`
- geometry = ol.geom.Polygon.fromExtent(geometryOrExtent);
- } else if (geometryOrExtent.getType() === ol.geom.GeometryType.CIRCLE) {
- geometryOrExtent = geometryOrExtent.getExtent();
- geometry = ol.geom.Polygon.fromExtent(geometryOrExtent);
- geometry.rotate(this.getRotation(), ol.extent.getCenter(geometryOrExtent));
- } else {
- geometry = geometryOrExtent;
- }
- var padding = options.padding !== undefined ? options.padding : [0, 0, 0, 0];
- var constrainResolution = options.constrainResolution !== undefined ?
- options.constrainResolution : true;
- var nearest = options.nearest !== undefined ? options.nearest : false;
- var minResolution;
- if (options.minResolution !== undefined) {
- minResolution = options.minResolution;
- } else if (options.maxZoom !== undefined) {
- minResolution = this.constrainResolution(
- this.maxResolution_, options.maxZoom - this.minZoom_, 0);
- } else {
- minResolution = 0;
- }
- var coords = geometry.getFlatCoordinates();
- // calculate rotated extent
- var rotation = this.getRotation();
- var cosAngle = Math.cos(-rotation);
- var sinAngle = Math.sin(-rotation);
- var minRotX = +Infinity;
- var minRotY = +Infinity;
- var maxRotX = -Infinity;
- var maxRotY = -Infinity;
- var stride = geometry.getStride();
- for (var i = 0, ii = coords.length; i < ii; i += stride) {
- var rotX = coords[i] * cosAngle - coords[i + 1] * sinAngle;
- var rotY = coords[i] * sinAngle + coords[i + 1] * cosAngle;
- minRotX = Math.min(minRotX, rotX);
- minRotY = Math.min(minRotY, rotY);
- maxRotX = Math.max(maxRotX, rotX);
- maxRotY = Math.max(maxRotY, rotY);
- }
- // calculate resolution
- var resolution = this.getResolutionForExtent(
- [minRotX, minRotY, maxRotX, maxRotY],
- [size[0] - padding[1] - padding[3], size[1] - padding[0] - padding[2]]);
- resolution = isNaN(resolution) ? minResolution :
- Math.max(resolution, minResolution);
- if (constrainResolution) {
- var constrainedResolution = this.constrainResolution(resolution, 0, 0);
- if (!nearest && constrainedResolution < resolution) {
- constrainedResolution = this.constrainResolution(
- constrainedResolution, -1, 0);
- }
- resolution = constrainedResolution;
- }
- // calculate center
- sinAngle = -sinAngle; // go back to original rotation
- var centerRotX = (minRotX + maxRotX) / 2;
- var centerRotY = (minRotY + maxRotY) / 2;
- centerRotX += (padding[1] - padding[3]) / 2 * resolution;
- centerRotY += (padding[0] - padding[2]) / 2 * resolution;
- var centerX = centerRotX * cosAngle - centerRotY * sinAngle;
- var centerY = centerRotY * cosAngle + centerRotX * sinAngle;
- var center = [centerX, centerY];
- var callback = options.callback ? options.callback : ol.nullFunction;
- if (options.duration !== undefined) {
- this.animate({
- resolution: resolution,
- center: center,
- duration: options.duration,
- easing: options.easing
- }, callback);
- } else {
- this.setResolution(resolution);
- this.setCenter(center);
- setTimeout(callback.bind(undefined, true), 0);
- }
- };
- /**
- * Center on coordinate and view position.
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {ol.Size} size Box pixel size.
- * @param {ol.Pixel} position Position on the view to center on.
- * @api
- */
- ol.View.prototype.centerOn = function(coordinate, size, position) {
- // calculate rotated position
- var rotation = this.getRotation();
- var cosAngle = Math.cos(-rotation);
- var sinAngle = Math.sin(-rotation);
- var rotX = coordinate[0] * cosAngle - coordinate[1] * sinAngle;
- var rotY = coordinate[1] * cosAngle + coordinate[0] * sinAngle;
- var resolution = this.getResolution();
- rotX += (size[0] / 2 - position[0]) * resolution;
- rotY += (position[1] - size[1] / 2) * resolution;
- // go back to original angle
- sinAngle = -sinAngle; // go back to original rotation
- var centerX = rotX * cosAngle - rotY * sinAngle;
- var centerY = rotY * cosAngle + rotX * sinAngle;
- this.setCenter([centerX, centerY]);
- };
- /**
- * @return {boolean} Is defined.
- */
- ol.View.prototype.isDef = function() {
- return !!this.getCenter() && this.getResolution() !== undefined;
- };
- /**
- * Rotate the view around a given coordinate.
- * @param {number} rotation New rotation value for the view.
- * @param {ol.Coordinate=} opt_anchor The rotation center.
- * @api
- */
- ol.View.prototype.rotate = function(rotation, opt_anchor) {
- if (opt_anchor !== undefined) {
- var center = this.calculateCenterRotate(rotation, opt_anchor);
- this.setCenter(center);
- }
- this.setRotation(rotation);
- };
- /**
- * Set the center of the current view.
- * @param {ol.Coordinate|undefined} center The center of the view.
- * @observable
- * @api
- */
- ol.View.prototype.setCenter = function(center) {
- this.set(ol.ViewProperty.CENTER, center);
- if (this.getAnimating()) {
- this.cancelAnimations();
- }
- };
- /**
- * @param {ol.ViewHint} hint Hint.
- * @param {number} delta Delta.
- * @return {number} New value.
- */
- ol.View.prototype.setHint = function(hint, delta) {
- this.hints_[hint] += delta;
- this.changed();
- return this.hints_[hint];
- };
- /**
- * Set the resolution for this view.
- * @param {number|undefined} resolution The resolution of the view.
- * @observable
- * @api
- */
- ol.View.prototype.setResolution = function(resolution) {
- this.set(ol.ViewProperty.RESOLUTION, resolution);
- if (this.getAnimating()) {
- this.cancelAnimations();
- }
- };
- /**
- * Set the rotation for this view.
- * @param {number} rotation The rotation of the view in radians.
- * @observable
- * @api
- */
- ol.View.prototype.setRotation = function(rotation) {
- this.set(ol.ViewProperty.ROTATION, rotation);
- if (this.getAnimating()) {
- this.cancelAnimations();
- }
- };
- /**
- * Zoom to a specific zoom level.
- * @param {number} zoom Zoom level.
- * @api
- */
- ol.View.prototype.setZoom = function(zoom) {
- this.setResolution(this.getResolutionForZoom(zoom));
- };
- /**
- * @param {olx.ViewOptions} options View options.
- * @private
- * @return {ol.CenterConstraintType} The constraint.
- */
- ol.View.createCenterConstraint_ = function(options) {
- if (options.extent !== undefined) {
- return ol.CenterConstraint.createExtent(options.extent);
- } else {
- return ol.CenterConstraint.none;
- }
- };
- /**
- * @private
- * @param {olx.ViewOptions} options View options.
- * @return {{constraint: ol.ResolutionConstraintType, maxResolution: number,
- * minResolution: number, zoomFactor: number}} The constraint.
- */
- ol.View.createResolutionConstraint_ = function(options) {
- var resolutionConstraint;
- var maxResolution;
- var minResolution;
- // TODO: move these to be ol constants
- // see https://github.com/openlayers/openlayers/issues/2076
- var defaultMaxZoom = 28;
- var defaultZoomFactor = 2;
- var minZoom = options.minZoom !== undefined ?
- options.minZoom : ol.DEFAULT_MIN_ZOOM;
- var maxZoom = options.maxZoom !== undefined ?
- options.maxZoom : defaultMaxZoom;
- var zoomFactor = options.zoomFactor !== undefined ?
- options.zoomFactor : defaultZoomFactor;
- if (options.resolutions !== undefined) {
- var resolutions = options.resolutions;
- maxResolution = resolutions[minZoom];
- minResolution = resolutions[maxZoom] !== undefined ?
- resolutions[maxZoom] : resolutions[resolutions.length - 1];
- resolutionConstraint = ol.ResolutionConstraint.createSnapToResolutions(
- resolutions);
- } else {
- // calculate the default min and max resolution
- var projection = ol.proj.createProjection(options.projection, 'EPSG:3857');
- var extent = projection.getExtent();
- var size = !extent ?
- // use an extent that can fit the whole world if need be
- 360 * ol.proj.METERS_PER_UNIT[ol.proj.Units.DEGREES] /
- projection.getMetersPerUnit() :
- Math.max(ol.extent.getWidth(extent), ol.extent.getHeight(extent));
- var defaultMaxResolution = size / ol.DEFAULT_TILE_SIZE / Math.pow(
- defaultZoomFactor, ol.DEFAULT_MIN_ZOOM);
- var defaultMinResolution = defaultMaxResolution / Math.pow(
- defaultZoomFactor, defaultMaxZoom - ol.DEFAULT_MIN_ZOOM);
- // user provided maxResolution takes precedence
- maxResolution = options.maxResolution;
- if (maxResolution !== undefined) {
- minZoom = 0;
- } else {
- maxResolution = defaultMaxResolution / Math.pow(zoomFactor, minZoom);
- }
- // user provided minResolution takes precedence
- minResolution = options.minResolution;
- if (minResolution === undefined) {
- if (options.maxZoom !== undefined) {
- if (options.maxResolution !== undefined) {
- minResolution = maxResolution / Math.pow(zoomFactor, maxZoom);
- } else {
- minResolution = defaultMaxResolution / Math.pow(zoomFactor, maxZoom);
- }
- } else {
- minResolution = defaultMinResolution;
- }
- }
- // given discrete zoom levels, minResolution may be different than provided
- maxZoom = minZoom + Math.floor(
- Math.log(maxResolution / minResolution) / Math.log(zoomFactor));
- minResolution = maxResolution / Math.pow(zoomFactor, maxZoom - minZoom);
- resolutionConstraint = ol.ResolutionConstraint.createSnapToPower(
- zoomFactor, maxResolution, maxZoom - minZoom);
- }
- return {constraint: resolutionConstraint, maxResolution: maxResolution,
- minResolution: minResolution, minZoom: minZoom, zoomFactor: zoomFactor};
- };
- /**
- * @private
- * @param {olx.ViewOptions} options View options.
- * @return {ol.RotationConstraintType} Rotation constraint.
- */
- ol.View.createRotationConstraint_ = function(options) {
- var enableRotation = options.enableRotation !== undefined ?
- options.enableRotation : true;
- if (enableRotation) {
- var constrainRotation = options.constrainRotation;
- if (constrainRotation === undefined || constrainRotation === true) {
- return ol.RotationConstraint.createSnapToZero();
- } else if (constrainRotation === false) {
- return ol.RotationConstraint.none;
- } else if (typeof constrainRotation === 'number') {
- return ol.RotationConstraint.createSnapToN(constrainRotation);
- } else {
- return ol.RotationConstraint.none;
- }
- } else {
- return ol.RotationConstraint.disable;
- }
- };
- /**
- * Determine if an animation involves no view change.
- * @param {ol.ViewAnimation} animation The animation.
- * @return {boolean} The animation involves no view change.
- */
- ol.View.isNoopAnimation = function(animation) {
- if (animation.sourceCenter && animation.targetCenter) {
- if (!ol.coordinate.equals(animation.sourceCenter, animation.targetCenter)) {
- return false;
- }
- }
- if (animation.sourceResolution !== animation.targetResolution) {
- return false;
- }
- if (animation.sourceRotation !== animation.targetRotation) {
- return false;
- }
- return true;
- };
- goog.provide('ol.dom');
- /**
- * Create an html canvas element and returns its 2d context.
- * @param {number=} opt_width Canvas width.
- * @param {number=} opt_height Canvas height.
- * @return {CanvasRenderingContext2D} The context.
- */
- ol.dom.createCanvasContext2D = function(opt_width, opt_height) {
- var canvas = document.createElement('CANVAS');
- if (opt_width) {
- canvas.width = opt_width;
- }
- if (opt_height) {
- canvas.height = opt_height;
- }
- return canvas.getContext('2d');
- };
- /**
- * Get the current computed width for the given element including margin,
- * padding and border.
- * Equivalent to jQuery's `$(el).outerWidth(true)`.
- * @param {!Element} element Element.
- * @return {number} The width.
- */
- ol.dom.outerWidth = function(element) {
- var width = element.offsetWidth;
- var style = getComputedStyle(element);
- width += parseInt(style.marginLeft, 10) + parseInt(style.marginRight, 10);
- return width;
- };
- /**
- * Get the current computed height for the given element including margin,
- * padding and border.
- * Equivalent to jQuery's `$(el).outerHeight(true)`.
- * @param {!Element} element Element.
- * @return {number} The height.
- */
- ol.dom.outerHeight = function(element) {
- var height = element.offsetHeight;
- var style = getComputedStyle(element);
- height += parseInt(style.marginTop, 10) + parseInt(style.marginBottom, 10);
- return height;
- };
- /**
- * @param {Node} newNode Node to replace old node
- * @param {Node} oldNode The node to be replaced
- */
- ol.dom.replaceNode = function(newNode, oldNode) {
- var parent = oldNode.parentNode;
- if (parent) {
- parent.replaceChild(newNode, oldNode);
- }
- };
- /**
- * @param {Node} node The node to remove.
- * @returns {Node} The node that was removed or null.
- */
- ol.dom.removeNode = function(node) {
- return node && node.parentNode ? node.parentNode.removeChild(node) : null;
- };
- /**
- * @param {Node} node The node to remove the children from.
- */
- ol.dom.removeChildren = function(node) {
- while (node.lastChild) {
- node.removeChild(node.lastChild);
- }
- };
- goog.provide('ol.layer.Property');
- /**
- * @enum {string}
- */
- ol.layer.Property = {
- OPACITY: 'opacity',
- VISIBLE: 'visible',
- EXTENT: 'extent',
- Z_INDEX: 'zIndex',
- MAX_RESOLUTION: 'maxResolution',
- MIN_RESOLUTION: 'minResolution',
- SOURCE: 'source'
- };
- goog.provide('ol.layer.Base');
- goog.require('ol');
- goog.require('ol.Object');
- goog.require('ol.layer.Property');
- goog.require('ol.math');
- goog.require('ol.obj');
- /**
- * @classdesc
- * Abstract base class; normally only used for creating subclasses and not
- * instantiated in apps.
- * Note that with `ol.layer.Base` and all its subclasses, any property set in
- * the options is set as a {@link ol.Object} property on the layer object, so
- * is observable, and has get/set accessors.
- *
- * @constructor
- * @abstract
- * @extends {ol.Object}
- * @param {olx.layer.BaseOptions} options Layer options.
- * @api
- */
- ol.layer.Base = function(options) {
- ol.Object.call(this);
- /**
- * @type {Object.<string, *>}
- */
- var properties = ol.obj.assign({}, options);
- properties[ol.layer.Property.OPACITY] =
- options.opacity !== undefined ? options.opacity : 1;
- properties[ol.layer.Property.VISIBLE] =
- options.visible !== undefined ? options.visible : true;
- properties[ol.layer.Property.Z_INDEX] =
- options.zIndex !== undefined ? options.zIndex : 0;
- properties[ol.layer.Property.MAX_RESOLUTION] =
- options.maxResolution !== undefined ? options.maxResolution : Infinity;
- properties[ol.layer.Property.MIN_RESOLUTION] =
- options.minResolution !== undefined ? options.minResolution : 0;
- this.setProperties(properties);
- /**
- * @type {ol.LayerState}
- * @private
- */
- this.state_ = /** @type {ol.LayerState} */ ({
- layer: /** @type {ol.layer.Layer} */ (this),
- managed: true
- });
- /**
- * The layer type.
- * @type {ol.LayerType}
- * @protected;
- */
- this.type;
- };
- ol.inherits(ol.layer.Base, ol.Object);
- /**
- * Get the layer type (used when creating a layer renderer).
- * @return {ol.LayerType} The layer type.
- */
- ol.layer.Base.prototype.getType = function() {
- return this.type;
- };
- /**
- * @return {ol.LayerState} Layer state.
- */
- ol.layer.Base.prototype.getLayerState = function() {
- this.state_.opacity = ol.math.clamp(this.getOpacity(), 0, 1);
- this.state_.sourceState = this.getSourceState();
- this.state_.visible = this.getVisible();
- this.state_.extent = this.getExtent();
- this.state_.zIndex = this.getZIndex();
- this.state_.maxResolution = this.getMaxResolution();
- this.state_.minResolution = Math.max(this.getMinResolution(), 0);
- return this.state_;
- };
- /**
- * @abstract
- * @param {Array.<ol.layer.Layer>=} opt_array Array of layers (to be
- * modified in place).
- * @return {Array.<ol.layer.Layer>} Array of layers.
- */
- ol.layer.Base.prototype.getLayersArray = function(opt_array) {};
- /**
- * @abstract
- * @param {Array.<ol.LayerState>=} opt_states Optional list of layer
- * states (to be modified in place).
- * @return {Array.<ol.LayerState>} List of layer states.
- */
- ol.layer.Base.prototype.getLayerStatesArray = function(opt_states) {};
- /**
- * Return the {@link ol.Extent extent} of the layer or `undefined` if it
- * will be visible regardless of extent.
- * @return {ol.Extent|undefined} The layer extent.
- * @observable
- * @api
- */
- ol.layer.Base.prototype.getExtent = function() {
- return /** @type {ol.Extent|undefined} */ (
- this.get(ol.layer.Property.EXTENT));
- };
- /**
- * Return the maximum resolution of the layer.
- * @return {number} The maximum resolution of the layer.
- * @observable
- * @api
- */
- ol.layer.Base.prototype.getMaxResolution = function() {
- return /** @type {number} */ (
- this.get(ol.layer.Property.MAX_RESOLUTION));
- };
- /**
- * Return the minimum resolution of the layer.
- * @return {number} The minimum resolution of the layer.
- * @observable
- * @api
- */
- ol.layer.Base.prototype.getMinResolution = function() {
- return /** @type {number} */ (
- this.get(ol.layer.Property.MIN_RESOLUTION));
- };
- /**
- * Return the opacity of the layer (between 0 and 1).
- * @return {number} The opacity of the layer.
- * @observable
- * @api
- */
- ol.layer.Base.prototype.getOpacity = function() {
- return /** @type {number} */ (this.get(ol.layer.Property.OPACITY));
- };
- /**
- * @abstract
- * @return {ol.source.State} Source state.
- */
- ol.layer.Base.prototype.getSourceState = function() {};
- /**
- * Return the visibility of the layer (`true` or `false`).
- * @return {boolean} The visibility of the layer.
- * @observable
- * @api
- */
- ol.layer.Base.prototype.getVisible = function() {
- return /** @type {boolean} */ (this.get(ol.layer.Property.VISIBLE));
- };
- /**
- * Return the Z-index of the layer, which is used to order layers before
- * rendering. The default Z-index is 0.
- * @return {number} The Z-index of the layer.
- * @observable
- * @api
- */
- ol.layer.Base.prototype.getZIndex = function() {
- return /** @type {number} */ (this.get(ol.layer.Property.Z_INDEX));
- };
- /**
- * Set the extent at which the layer is visible. If `undefined`, the layer
- * will be visible at all extents.
- * @param {ol.Extent|undefined} extent The extent of the layer.
- * @observable
- * @api
- */
- ol.layer.Base.prototype.setExtent = function(extent) {
- this.set(ol.layer.Property.EXTENT, extent);
- };
- /**
- * Set the maximum resolution at which the layer is visible.
- * @param {number} maxResolution The maximum resolution of the layer.
- * @observable
- * @api
- */
- ol.layer.Base.prototype.setMaxResolution = function(maxResolution) {
- this.set(ol.layer.Property.MAX_RESOLUTION, maxResolution);
- };
- /**
- * Set the minimum resolution at which the layer is visible.
- * @param {number} minResolution The minimum resolution of the layer.
- * @observable
- * @api
- */
- ol.layer.Base.prototype.setMinResolution = function(minResolution) {
- this.set(ol.layer.Property.MIN_RESOLUTION, minResolution);
- };
- /**
- * Set the opacity of the layer, allowed values range from 0 to 1.
- * @param {number} opacity The opacity of the layer.
- * @observable
- * @api
- */
- ol.layer.Base.prototype.setOpacity = function(opacity) {
- this.set(ol.layer.Property.OPACITY, opacity);
- };
- /**
- * Set the visibility of the layer (`true` or `false`).
- * @param {boolean} visible The visibility of the layer.
- * @observable
- * @api
- */
- ol.layer.Base.prototype.setVisible = function(visible) {
- this.set(ol.layer.Property.VISIBLE, visible);
- };
- /**
- * Set Z-index of the layer, which is used to order layers before rendering.
- * The default Z-index is 0.
- * @param {number} zindex The z-index of the layer.
- * @observable
- * @api
- */
- ol.layer.Base.prototype.setZIndex = function(zindex) {
- this.set(ol.layer.Property.Z_INDEX, zindex);
- };
- goog.provide('ol.source.State');
- /**
- * State of the source, one of 'undefined', 'loading', 'ready' or 'error'.
- * @enum {string}
- */
- ol.source.State = {
- UNDEFINED: 'undefined',
- LOADING: 'loading',
- READY: 'ready',
- ERROR: 'error'
- };
- goog.provide('ol.layer.Group');
- goog.require('ol');
- goog.require('ol.Collection');
- goog.require('ol.CollectionEventType');
- goog.require('ol.Object');
- goog.require('ol.ObjectEventType');
- goog.require('ol.asserts');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.extent');
- goog.require('ol.layer.Base');
- goog.require('ol.obj');
- goog.require('ol.source.State');
- /**
- * @classdesc
- * A {@link ol.Collection} of layers that are handled together.
- *
- * A generic `change` event is triggered when the group/Collection changes.
- *
- * @constructor
- * @extends {ol.layer.Base}
- * @param {olx.layer.GroupOptions=} opt_options Layer options.
- * @api
- */
- ol.layer.Group = function(opt_options) {
- var options = opt_options || {};
- var baseOptions = /** @type {olx.layer.GroupOptions} */
- (ol.obj.assign({}, options));
- delete baseOptions.layers;
- var layers = options.layers;
- ol.layer.Base.call(this, baseOptions);
- /**
- * @private
- * @type {Array.<ol.EventsKey>}
- */
- this.layersListenerKeys_ = [];
- /**
- * @private
- * @type {Object.<string, Array.<ol.EventsKey>>}
- */
- this.listenerKeys_ = {};
- ol.events.listen(this,
- ol.Object.getChangeEventType(ol.layer.Group.Property_.LAYERS),
- this.handleLayersChanged_, this);
- if (layers) {
- if (Array.isArray(layers)) {
- layers = new ol.Collection(layers.slice(), {unique: true});
- } else {
- ol.asserts.assert(layers instanceof ol.Collection,
- 43); // Expected `layers` to be an array or an `ol.Collection`
- layers = layers;
- }
- } else {
- layers = new ol.Collection(undefined, {unique: true});
- }
- this.setLayers(layers);
- };
- ol.inherits(ol.layer.Group, ol.layer.Base);
- /**
- * @private
- */
- ol.layer.Group.prototype.handleLayerChange_ = function() {
- this.changed();
- };
- /**
- * @param {ol.events.Event} event Event.
- * @private
- */
- ol.layer.Group.prototype.handleLayersChanged_ = function(event) {
- this.layersListenerKeys_.forEach(ol.events.unlistenByKey);
- this.layersListenerKeys_.length = 0;
- var layers = this.getLayers();
- this.layersListenerKeys_.push(
- ol.events.listen(layers, ol.CollectionEventType.ADD,
- this.handleLayersAdd_, this),
- ol.events.listen(layers, ol.CollectionEventType.REMOVE,
- this.handleLayersRemove_, this));
- for (var id in this.listenerKeys_) {
- this.listenerKeys_[id].forEach(ol.events.unlistenByKey);
- }
- ol.obj.clear(this.listenerKeys_);
- var layersArray = layers.getArray();
- var i, ii, layer;
- for (i = 0, ii = layersArray.length; i < ii; i++) {
- layer = layersArray[i];
- this.listenerKeys_[ol.getUid(layer).toString()] = [
- ol.events.listen(layer, ol.ObjectEventType.PROPERTYCHANGE,
- this.handleLayerChange_, this),
- ol.events.listen(layer, ol.events.EventType.CHANGE,
- this.handleLayerChange_, this)
- ];
- }
- this.changed();
- };
- /**
- * @param {ol.Collection.Event} collectionEvent Collection event.
- * @private
- */
- ol.layer.Group.prototype.handleLayersAdd_ = function(collectionEvent) {
- var layer = /** @type {ol.layer.Base} */ (collectionEvent.element);
- var key = ol.getUid(layer).toString();
- this.listenerKeys_[key] = [
- ol.events.listen(layer, ol.ObjectEventType.PROPERTYCHANGE,
- this.handleLayerChange_, this),
- ol.events.listen(layer, ol.events.EventType.CHANGE,
- this.handleLayerChange_, this)
- ];
- this.changed();
- };
- /**
- * @param {ol.Collection.Event} collectionEvent Collection event.
- * @private
- */
- ol.layer.Group.prototype.handleLayersRemove_ = function(collectionEvent) {
- var layer = /** @type {ol.layer.Base} */ (collectionEvent.element);
- var key = ol.getUid(layer).toString();
- this.listenerKeys_[key].forEach(ol.events.unlistenByKey);
- delete this.listenerKeys_[key];
- this.changed();
- };
- /**
- * Returns the {@link ol.Collection collection} of {@link ol.layer.Layer layers}
- * in this group.
- * @return {!ol.Collection.<ol.layer.Base>} Collection of
- * {@link ol.layer.Base layers} that are part of this group.
- * @observable
- * @api
- */
- ol.layer.Group.prototype.getLayers = function() {
- return /** @type {!ol.Collection.<ol.layer.Base>} */ (this.get(
- ol.layer.Group.Property_.LAYERS));
- };
- /**
- * Set the {@link ol.Collection collection} of {@link ol.layer.Layer layers}
- * in this group.
- * @param {!ol.Collection.<ol.layer.Base>} layers Collection of
- * {@link ol.layer.Base layers} that are part of this group.
- * @observable
- * @api
- */
- ol.layer.Group.prototype.setLayers = function(layers) {
- this.set(ol.layer.Group.Property_.LAYERS, layers);
- };
- /**
- * @inheritDoc
- */
- ol.layer.Group.prototype.getLayersArray = function(opt_array) {
- var array = opt_array !== undefined ? opt_array : [];
- this.getLayers().forEach(function(layer) {
- layer.getLayersArray(array);
- });
- return array;
- };
- /**
- * @inheritDoc
- */
- ol.layer.Group.prototype.getLayerStatesArray = function(opt_states) {
- var states = opt_states !== undefined ? opt_states : [];
- var pos = states.length;
- this.getLayers().forEach(function(layer) {
- layer.getLayerStatesArray(states);
- });
- var ownLayerState = this.getLayerState();
- var i, ii, layerState;
- for (i = pos, ii = states.length; i < ii; i++) {
- layerState = states[i];
- layerState.opacity *= ownLayerState.opacity;
- layerState.visible = layerState.visible && ownLayerState.visible;
- layerState.maxResolution = Math.min(
- layerState.maxResolution, ownLayerState.maxResolution);
- layerState.minResolution = Math.max(
- layerState.minResolution, ownLayerState.minResolution);
- if (ownLayerState.extent !== undefined) {
- if (layerState.extent !== undefined) {
- layerState.extent = ol.extent.getIntersection(
- layerState.extent, ownLayerState.extent);
- } else {
- layerState.extent = ownLayerState.extent;
- }
- }
- }
- return states;
- };
- /**
- * @inheritDoc
- */
- ol.layer.Group.prototype.getSourceState = function() {
- return ol.source.State.READY;
- };
- /**
- * @enum {string}
- * @private
- */
- ol.layer.Group.Property_ = {
- LAYERS: 'layers'
- };
- goog.provide('ol.PluginType');
- /**
- * A plugin type used when registering a plugin. The supported plugin types are
- * 'MAP_RENDERER', and 'LAYER_RENDERER'.
- * @enum {string}
- */
- ol.PluginType = {
- MAP_RENDERER: 'MAP_RENDERER',
- LAYER_RENDERER: 'LAYER_RENDERER'
- };
- goog.provide('ol.plugins');
- goog.require('ol.PluginType');
- /**
- * The registry of map renderer plugins.
- * @type {Array<olx.MapRendererPlugin>}
- * @private
- */
- ol.plugins.mapRendererPlugins_ = [];
- /**
- * Get all registered map renderer plugins.
- * @return {Array<olx.MapRendererPlugin>} The registered map renderer plugins.
- */
- ol.plugins.getMapRendererPlugins = function() {
- return ol.plugins.mapRendererPlugins_;
- };
- /**
- * The registry of layer renderer plugins.
- * @type {Array<olx.LayerRendererPlugin>}
- * @private
- */
- ol.plugins.layerRendererPlugins_ = [];
- /**
- * Get all registered layer renderer plugins.
- * @return {Array<olx.LayerRendererPlugin>} The registered layer renderer plugins.
- */
- ol.plugins.getLayerRendererPlugins = function() {
- return ol.plugins.layerRendererPlugins_;
- };
- /**
- * Register a plugin.
- * @param {ol.PluginType} type The plugin type.
- * @param {*} plugin The plugin.
- */
- ol.plugins.register = function(type, plugin) {
- var plugins;
- switch (type) {
- case ol.PluginType.MAP_RENDERER: {
- plugins = ol.plugins.mapRendererPlugins_;
- plugins.push(/** @type {olx.MapRendererPlugin} */ (plugin));
- break;
- }
- case ol.PluginType.LAYER_RENDERER: {
- plugins = ol.plugins.layerRendererPlugins_;
- plugins.push(/** @type {olx.LayerRendererPlugin} */ (plugin));
- break;
- }
- default: {
- throw new Error('Unsupported plugin type: ' + type);
- }
- }
- };
- /**
- * Register multiple plugins.
- * @param {ol.PluginType} type The plugin type.
- * @param {Array} plugins The plugins.
- */
- ol.plugins.registerMultiple = function(type, plugins) {
- for (var i = 0, ii = plugins.length; i < ii; ++i) {
- ol.plugins.register(type, plugins[i]);
- }
- };
- goog.provide('ol.renderer.Type');
- /**
- * Available renderers: `'canvas'` or `'webgl'`.
- * @enum {string}
- */
- ol.renderer.Type = {
- CANVAS: 'canvas',
- WEBGL: 'webgl'
- };
- goog.provide('ol.PluggableMap');
- goog.require('ol');
- goog.require('ol.Collection');
- goog.require('ol.CollectionEventType');
- goog.require('ol.MapBrowserEvent');
- goog.require('ol.MapBrowserEventHandler');
- goog.require('ol.MapBrowserEventType');
- goog.require('ol.MapEvent');
- goog.require('ol.MapEventType');
- goog.require('ol.MapProperty');
- goog.require('ol.Object');
- goog.require('ol.ObjectEventType');
- goog.require('ol.TileQueue');
- goog.require('ol.View');
- goog.require('ol.ViewHint');
- goog.require('ol.asserts');
- goog.require('ol.dom');
- goog.require('ol.events');
- goog.require('ol.events.Event');
- goog.require('ol.events.EventType');
- goog.require('ol.extent');
- goog.require('ol.functions');
- goog.require('ol.has');
- goog.require('ol.layer.Group');
- goog.require('ol.obj');
- goog.require('ol.plugins');
- goog.require('ol.renderer.Type');
- goog.require('ol.size');
- goog.require('ol.structs.PriorityQueue');
- goog.require('ol.transform');
- /**
- * @constructor
- * @extends {ol.Object}
- * @param {olx.MapOptions} options Map options.
- * @fires ol.MapBrowserEvent
- * @fires ol.MapEvent
- * @fires ol.render.Event#postcompose
- * @fires ol.render.Event#precompose
- * @api
- */
- ol.PluggableMap = function(options) {
- ol.Object.call(this);
- var optionsInternal = ol.PluggableMap.createOptionsInternal(options);
- /**
- * @type {boolean}
- * @private
- */
- this.loadTilesWhileAnimating_ =
- options.loadTilesWhileAnimating !== undefined ?
- options.loadTilesWhileAnimating : false;
- /**
- * @type {boolean}
- * @private
- */
- this.loadTilesWhileInteracting_ =
- options.loadTilesWhileInteracting !== undefined ?
- options.loadTilesWhileInteracting : false;
- /**
- * @private
- * @type {number}
- */
- this.pixelRatio_ = options.pixelRatio !== undefined ?
- options.pixelRatio : ol.has.DEVICE_PIXEL_RATIO;
- /**
- * @private
- * @type {Object.<string, string>}
- */
- this.logos_ = optionsInternal.logos;
- /**
- * @private
- * @type {number|undefined}
- */
- this.animationDelayKey_;
- /**
- * @private
- */
- this.animationDelay_ = function() {
- this.animationDelayKey_ = undefined;
- this.renderFrame_.call(this, Date.now());
- }.bind(this);
- /**
- * @private
- * @type {ol.Transform}
- */
- this.coordinateToPixelTransform_ = ol.transform.create();
- /**
- * @private
- * @type {ol.Transform}
- */
- this.pixelToCoordinateTransform_ = ol.transform.create();
- /**
- * @private
- * @type {number}
- */
- this.frameIndex_ = 0;
- /**
- * @private
- * @type {?olx.FrameState}
- */
- this.frameState_ = null;
- /**
- * The extent at the previous 'moveend' event.
- * @private
- * @type {ol.Extent}
- */
- this.previousExtent_ = null;
- /**
- * @private
- * @type {?ol.EventsKey}
- */
- this.viewPropertyListenerKey_ = null;
- /**
- * @private
- * @type {?ol.EventsKey}
- */
- this.viewChangeListenerKey_ = null;
- /**
- * @private
- * @type {Array.<ol.EventsKey>}
- */
- this.layerGroupPropertyListenerKeys_ = null;
- /**
- * @private
- * @type {Element}
- */
- this.viewport_ = document.createElement('DIV');
- this.viewport_.className = 'ol-viewport' + (ol.has.TOUCH ? ' ol-touch' : '');
- this.viewport_.style.position = 'relative';
- this.viewport_.style.overflow = 'hidden';
- this.viewport_.style.width = '100%';
- this.viewport_.style.height = '100%';
- // prevent page zoom on IE >= 10 browsers
- this.viewport_.style.msTouchAction = 'none';
- this.viewport_.style.touchAction = 'none';
- /**
- * @private
- * @type {!Element}
- */
- this.overlayContainer_ = document.createElement('DIV');
- this.overlayContainer_.className = 'ol-overlaycontainer';
- this.viewport_.appendChild(this.overlayContainer_);
- /**
- * @private
- * @type {!Element}
- */
- this.overlayContainerStopEvent_ = document.createElement('DIV');
- this.overlayContainerStopEvent_.className = 'ol-overlaycontainer-stopevent';
- var overlayEvents = [
- ol.events.EventType.CLICK,
- ol.events.EventType.DBLCLICK,
- ol.events.EventType.MOUSEDOWN,
- ol.events.EventType.TOUCHSTART,
- ol.events.EventType.MSPOINTERDOWN,
- ol.MapBrowserEventType.POINTERDOWN,
- ol.events.EventType.MOUSEWHEEL,
- ol.events.EventType.WHEEL
- ];
- for (var i = 0, ii = overlayEvents.length; i < ii; ++i) {
- ol.events.listen(this.overlayContainerStopEvent_, overlayEvents[i],
- ol.events.Event.stopPropagation);
- }
- this.viewport_.appendChild(this.overlayContainerStopEvent_);
- /**
- * @private
- * @type {ol.MapBrowserEventHandler}
- */
- this.mapBrowserEventHandler_ = new ol.MapBrowserEventHandler(this, options.moveTolerance);
- for (var key in ol.MapBrowserEventType) {
- ol.events.listen(this.mapBrowserEventHandler_, ol.MapBrowserEventType[key],
- this.handleMapBrowserEvent, this);
- }
- /**
- * @private
- * @type {Element|Document}
- */
- this.keyboardEventTarget_ = optionsInternal.keyboardEventTarget;
- /**
- * @private
- * @type {Array.<ol.EventsKey>}
- */
- this.keyHandlerKeys_ = null;
- ol.events.listen(this.viewport_, ol.events.EventType.WHEEL,
- this.handleBrowserEvent, this);
- ol.events.listen(this.viewport_, ol.events.EventType.MOUSEWHEEL,
- this.handleBrowserEvent, this);
- /**
- * @type {ol.Collection.<ol.control.Control>}
- * @protected
- */
- this.controls = optionsInternal.controls || new ol.Collection();
- /**
- * @type {ol.Collection.<ol.interaction.Interaction>}
- * @protected
- */
- this.interactions = optionsInternal.interactions || new ol.Collection();
- /**
- * @type {ol.Collection.<ol.Overlay>}
- * @private
- */
- this.overlays_ = optionsInternal.overlays;
- /**
- * A lookup of overlays by id.
- * @private
- * @type {Object.<string, ol.Overlay>}
- */
- this.overlayIdIndex_ = {};
- /**
- * @type {ol.renderer.Map}
- * @private
- */
- this.renderer_ = optionsInternal.mapRendererPlugin['create'](this.viewport_, this);
- /**
- * @type {function(Event)|undefined}
- * @private
- */
- this.handleResize_;
- /**
- * @private
- * @type {ol.Coordinate}
- */
- this.focus_ = null;
- /**
- * @private
- * @type {Array.<ol.PostRenderFunction>}
- */
- this.postRenderFunctions_ = [];
- /**
- * @private
- * @type {ol.TileQueue}
- */
- this.tileQueue_ = new ol.TileQueue(
- this.getTilePriority.bind(this),
- this.handleTileChange_.bind(this));
- /**
- * Uids of features to skip at rendering time.
- * @type {Object.<string, boolean>}
- * @private
- */
- this.skippedFeatureUids_ = {};
- ol.events.listen(
- this, ol.Object.getChangeEventType(ol.MapProperty.LAYERGROUP),
- this.handleLayerGroupChanged_, this);
- ol.events.listen(this, ol.Object.getChangeEventType(ol.MapProperty.VIEW),
- this.handleViewChanged_, this);
- ol.events.listen(this, ol.Object.getChangeEventType(ol.MapProperty.SIZE),
- this.handleSizeChanged_, this);
- ol.events.listen(this, ol.Object.getChangeEventType(ol.MapProperty.TARGET),
- this.handleTargetChanged_, this);
- // setProperties will trigger the rendering of the map if the map
- // is "defined" already.
- this.setProperties(optionsInternal.values);
- this.controls.forEach(
- /**
- * @param {ol.control.Control} control Control.
- * @this {ol.PluggableMap}
- */
- function(control) {
- control.setMap(this);
- }, this);
- ol.events.listen(this.controls, ol.CollectionEventType.ADD,
- /**
- * @param {ol.Collection.Event} event Collection event.
- */
- function(event) {
- event.element.setMap(this);
- }, this);
- ol.events.listen(this.controls, ol.CollectionEventType.REMOVE,
- /**
- * @param {ol.Collection.Event} event Collection event.
- */
- function(event) {
- event.element.setMap(null);
- }, this);
- this.interactions.forEach(
- /**
- * @param {ol.interaction.Interaction} interaction Interaction.
- * @this {ol.PluggableMap}
- */
- function(interaction) {
- interaction.setMap(this);
- }, this);
- ol.events.listen(this.interactions, ol.CollectionEventType.ADD,
- /**
- * @param {ol.Collection.Event} event Collection event.
- */
- function(event) {
- event.element.setMap(this);
- }, this);
- ol.events.listen(this.interactions, ol.CollectionEventType.REMOVE,
- /**
- * @param {ol.Collection.Event} event Collection event.
- */
- function(event) {
- event.element.setMap(null);
- }, this);
- this.overlays_.forEach(this.addOverlayInternal_, this);
- ol.events.listen(this.overlays_, ol.CollectionEventType.ADD,
- /**
- * @param {ol.Collection.Event} event Collection event.
- */
- function(event) {
- this.addOverlayInternal_(/** @type {ol.Overlay} */ (event.element));
- }, this);
- ol.events.listen(this.overlays_, ol.CollectionEventType.REMOVE,
- /**
- * @param {ol.Collection.Event} event Collection event.
- */
- function(event) {
- var overlay = /** @type {ol.Overlay} */ (event.element);
- var id = overlay.getId();
- if (id !== undefined) {
- delete this.overlayIdIndex_[id.toString()];
- }
- event.element.setMap(null);
- }, this);
- };
- ol.inherits(ol.PluggableMap, ol.Object);
- /**
- * Add the given control to the map.
- * @param {ol.control.Control} control Control.
- * @api
- */
- ol.PluggableMap.prototype.addControl = function(control) {
- this.getControls().push(control);
- };
- /**
- * Add the given interaction to the map.
- * @param {ol.interaction.Interaction} interaction Interaction to add.
- * @api
- */
- ol.PluggableMap.prototype.addInteraction = function(interaction) {
- this.getInteractions().push(interaction);
- };
- /**
- * Adds the given layer to the top of this map. If you want to add a layer
- * elsewhere in the stack, use `getLayers()` and the methods available on
- * {@link ol.Collection}.
- * @param {ol.layer.Base} layer Layer.
- * @api
- */
- ol.PluggableMap.prototype.addLayer = function(layer) {
- var layers = this.getLayerGroup().getLayers();
- layers.push(layer);
- };
- /**
- * Add the given overlay to the map.
- * @param {ol.Overlay} overlay Overlay.
- * @api
- */
- ol.PluggableMap.prototype.addOverlay = function(overlay) {
- this.getOverlays().push(overlay);
- };
- /**
- * This deals with map's overlay collection changes.
- * @param {ol.Overlay} overlay Overlay.
- * @private
- */
- ol.PluggableMap.prototype.addOverlayInternal_ = function(overlay) {
- var id = overlay.getId();
- if (id !== undefined) {
- this.overlayIdIndex_[id.toString()] = overlay;
- }
- overlay.setMap(this);
- };
- /**
- *
- * @inheritDoc
- */
- ol.PluggableMap.prototype.disposeInternal = function() {
- this.mapBrowserEventHandler_.dispose();
- ol.events.unlisten(this.viewport_, ol.events.EventType.WHEEL,
- this.handleBrowserEvent, this);
- ol.events.unlisten(this.viewport_, ol.events.EventType.MOUSEWHEEL,
- this.handleBrowserEvent, this);
- if (this.handleResize_ !== undefined) {
- window.removeEventListener(ol.events.EventType.RESIZE,
- this.handleResize_, false);
- this.handleResize_ = undefined;
- }
- if (this.animationDelayKey_) {
- cancelAnimationFrame(this.animationDelayKey_);
- this.animationDelayKey_ = undefined;
- }
- this.setTarget(null);
- ol.Object.prototype.disposeInternal.call(this);
- };
- /**
- * Detect features that intersect a pixel on the viewport, and execute a
- * callback with each intersecting feature. Layers included in the detection can
- * be configured through the `layerFilter` option in `opt_options`.
- * @param {ol.Pixel} pixel Pixel.
- * @param {function(this: S, (ol.Feature|ol.render.Feature),
- * ol.layer.Layer): T} callback Feature callback. The callback will be
- * called with two arguments. The first argument is one
- * {@link ol.Feature feature} or
- * {@link ol.render.Feature render feature} at the pixel, the second is
- * the {@link ol.layer.Layer layer} of the feature and will be null for
- * unmanaged layers. To stop detection, callback functions can return a
- * truthy value.
- * @param {olx.AtPixelOptions=} opt_options Optional options.
- * @return {T|undefined} Callback result, i.e. the return value of last
- * callback execution, or the first truthy callback return value.
- * @template S,T
- * @api
- */
- ol.PluggableMap.prototype.forEachFeatureAtPixel = function(pixel, callback, opt_options) {
- if (!this.frameState_) {
- return;
- }
- var coordinate = this.getCoordinateFromPixel(pixel);
- opt_options = opt_options !== undefined ? opt_options : {};
- var hitTolerance = opt_options.hitTolerance !== undefined ?
- opt_options.hitTolerance * this.frameState_.pixelRatio : 0;
- var layerFilter = opt_options.layerFilter !== undefined ?
- opt_options.layerFilter : ol.functions.TRUE;
- return this.renderer_.forEachFeatureAtCoordinate(
- coordinate, this.frameState_, hitTolerance, callback, null,
- layerFilter, null);
- };
- /**
- * Get all features that intersect a pixel on the viewport.
- * @param {ol.Pixel} pixel Pixel.
- * @param {olx.AtPixelOptions=} opt_options Optional options.
- * @return {Array.<ol.Feature|ol.render.Feature>} The detected features or
- * `null` if none were found.
- * @api
- */
- ol.PluggableMap.prototype.getFeaturesAtPixel = function(pixel, opt_options) {
- var features = null;
- this.forEachFeatureAtPixel(pixel, function(feature) {
- if (!features) {
- features = [];
- }
- features.push(feature);
- }, opt_options);
- return features;
- };
- /**
- * Detect layers that have a color value at a pixel on the viewport, and
- * execute a callback with each matching layer. Layers included in the
- * detection can be configured through `opt_layerFilter`.
- * @param {ol.Pixel} pixel Pixel.
- * @param {function(this: S, ol.layer.Layer, (Uint8ClampedArray|Uint8Array)): T} callback
- * Layer callback. This callback will receive two arguments: first is the
- * {@link ol.layer.Layer layer}, second argument is an array representing
- * [R, G, B, A] pixel values (0 - 255) and will be `null` for layer types
- * that do not currently support this argument. To stop detection, callback
- * functions can return a truthy value.
- * @param {S=} opt_this Value to use as `this` when executing `callback`.
- * @param {(function(this: U, ol.layer.Layer): boolean)=} opt_layerFilter Layer
- * filter function. The filter function will receive one argument, the
- * {@link ol.layer.Layer layer-candidate} and it should return a boolean
- * value. Only layers which are visible and for which this function returns
- * `true` will be tested for features. By default, all visible layers will
- * be tested.
- * @param {U=} opt_this2 Value to use as `this` when executing `layerFilter`.
- * @return {T|undefined} Callback result, i.e. the return value of last
- * callback execution, or the first truthy callback return value.
- * @template S,T,U
- * @api
- */
- ol.PluggableMap.prototype.forEachLayerAtPixel = function(pixel, callback, opt_this, opt_layerFilter, opt_this2) {
- if (!this.frameState_) {
- return;
- }
- var thisArg = opt_this !== undefined ? opt_this : null;
- var layerFilter = opt_layerFilter !== undefined ?
- opt_layerFilter : ol.functions.TRUE;
- var thisArg2 = opt_this2 !== undefined ? opt_this2 : null;
- return this.renderer_.forEachLayerAtPixel(
- pixel, this.frameState_, callback, thisArg,
- layerFilter, thisArg2);
- };
- /**
- * Detect if features intersect a pixel on the viewport. Layers included in the
- * detection can be configured through `opt_layerFilter`.
- * @param {ol.Pixel} pixel Pixel.
- * @param {olx.AtPixelOptions=} opt_options Optional options.
- * @return {boolean} Is there a feature at the given pixel?
- * @template U
- * @api
- */
- ol.PluggableMap.prototype.hasFeatureAtPixel = function(pixel, opt_options) {
- if (!this.frameState_) {
- return false;
- }
- var coordinate = this.getCoordinateFromPixel(pixel);
- opt_options = opt_options !== undefined ? opt_options : {};
- var layerFilter = opt_options.layerFilter !== undefined ?
- opt_options.layerFilter : ol.functions.TRUE;
- var hitTolerance = opt_options.hitTolerance !== undefined ?
- opt_options.hitTolerance * this.frameState_.pixelRatio : 0;
- return this.renderer_.hasFeatureAtCoordinate(
- coordinate, this.frameState_, hitTolerance, layerFilter, null);
- };
- /**
- * Returns the coordinate in view projection for a browser event.
- * @param {Event} event Event.
- * @return {ol.Coordinate} Coordinate.
- * @api
- */
- ol.PluggableMap.prototype.getEventCoordinate = function(event) {
- return this.getCoordinateFromPixel(this.getEventPixel(event));
- };
- /**
- * Returns the map pixel position for a browser event relative to the viewport.
- * @param {Event} event Event.
- * @return {ol.Pixel} Pixel.
- * @api
- */
- ol.PluggableMap.prototype.getEventPixel = function(event) {
- var viewportPosition = this.viewport_.getBoundingClientRect();
- var eventPosition = event.changedTouches ? event.changedTouches[0] : event;
- return [
- eventPosition.clientX - viewportPosition.left,
- eventPosition.clientY - viewportPosition.top
- ];
- };
- /**
- * Get the target in which this map is rendered.
- * Note that this returns what is entered as an option or in setTarget:
- * if that was an element, it returns an element; if a string, it returns that.
- * @return {Element|string|undefined} The Element or id of the Element that the
- * map is rendered in.
- * @observable
- * @api
- */
- ol.PluggableMap.prototype.getTarget = function() {
- return /** @type {Element|string|undefined} */ (
- this.get(ol.MapProperty.TARGET));
- };
- /**
- * Get the DOM element into which this map is rendered. In contrast to
- * `getTarget` this method always return an `Element`, or `null` if the
- * map has no target.
- * @return {Element} The element that the map is rendered in.
- * @api
- */
- ol.PluggableMap.prototype.getTargetElement = function() {
- var target = this.getTarget();
- if (target !== undefined) {
- return typeof target === 'string' ?
- document.getElementById(target) :
- target;
- } else {
- return null;
- }
- };
- /**
- * Get the coordinate for a given pixel. This returns a coordinate in the
- * map view projection.
- * @param {ol.Pixel} pixel Pixel position in the map viewport.
- * @return {ol.Coordinate} The coordinate for the pixel position.
- * @api
- */
- ol.PluggableMap.prototype.getCoordinateFromPixel = function(pixel) {
- var frameState = this.frameState_;
- if (!frameState) {
- return null;
- } else {
- return ol.transform.apply(frameState.pixelToCoordinateTransform, pixel.slice());
- }
- };
- /**
- * Get the map controls. Modifying this collection changes the controls
- * associated with the map.
- * @return {ol.Collection.<ol.control.Control>} Controls.
- * @api
- */
- ol.PluggableMap.prototype.getControls = function() {
- return this.controls;
- };
- /**
- * Get the map overlays. Modifying this collection changes the overlays
- * associated with the map.
- * @return {ol.Collection.<ol.Overlay>} Overlays.
- * @api
- */
- ol.PluggableMap.prototype.getOverlays = function() {
- return this.overlays_;
- };
- /**
- * Get an overlay by its identifier (the value returned by overlay.getId()).
- * Note that the index treats string and numeric identifiers as the same. So
- * `map.getOverlayById(2)` will return an overlay with id `'2'` or `2`.
- * @param {string|number} id Overlay identifier.
- * @return {ol.Overlay} Overlay.
- * @api
- */
- ol.PluggableMap.prototype.getOverlayById = function(id) {
- var overlay = this.overlayIdIndex_[id.toString()];
- return overlay !== undefined ? overlay : null;
- };
- /**
- * Get the map interactions. Modifying this collection changes the interactions
- * associated with the map.
- *
- * Interactions are used for e.g. pan, zoom and rotate.
- * @return {ol.Collection.<ol.interaction.Interaction>} Interactions.
- * @api
- */
- ol.PluggableMap.prototype.getInteractions = function() {
- return this.interactions;
- };
- /**
- * Get the layergroup associated with this map.
- * @return {ol.layer.Group} A layer group containing the layers in this map.
- * @observable
- * @api
- */
- ol.PluggableMap.prototype.getLayerGroup = function() {
- return /** @type {ol.layer.Group} */ (this.get(ol.MapProperty.LAYERGROUP));
- };
- /**
- * Get the collection of layers associated with this map.
- * @return {!ol.Collection.<ol.layer.Base>} Layers.
- * @api
- */
- ol.PluggableMap.prototype.getLayers = function() {
- var layers = this.getLayerGroup().getLayers();
- return layers;
- };
- /**
- * Get the pixel for a coordinate. This takes a coordinate in the map view
- * projection and returns the corresponding pixel.
- * @param {ol.Coordinate} coordinate A map coordinate.
- * @return {ol.Pixel} A pixel position in the map viewport.
- * @api
- */
- ol.PluggableMap.prototype.getPixelFromCoordinate = function(coordinate) {
- var frameState = this.frameState_;
- if (!frameState) {
- return null;
- } else {
- return ol.transform.apply(frameState.coordinateToPixelTransform,
- coordinate.slice(0, 2));
- }
- };
- /**
- * Get the map renderer.
- * @return {ol.renderer.Map} Renderer
- */
- ol.PluggableMap.prototype.getRenderer = function() {
- return this.renderer_;
- };
- /**
- * Get the size of this map.
- * @return {ol.Size|undefined} The size in pixels of the map in the DOM.
- * @observable
- * @api
- */
- ol.PluggableMap.prototype.getSize = function() {
- return /** @type {ol.Size|undefined} */ (this.get(ol.MapProperty.SIZE));
- };
- /**
- * Get the view associated with this map. A view manages properties such as
- * center and resolution.
- * @return {ol.View} The view that controls this map.
- * @observable
- * @api
- */
- ol.PluggableMap.prototype.getView = function() {
- return /** @type {ol.View} */ (this.get(ol.MapProperty.VIEW));
- };
- /**
- * Get the element that serves as the map viewport.
- * @return {Element} Viewport.
- * @api
- */
- ol.PluggableMap.prototype.getViewport = function() {
- return this.viewport_;
- };
- /**
- * Get the element that serves as the container for overlays. Elements added to
- * this container will let mousedown and touchstart events through to the map,
- * so clicks and gestures on an overlay will trigger {@link ol.MapBrowserEvent}
- * events.
- * @return {!Element} The map's overlay container.
- */
- ol.PluggableMap.prototype.getOverlayContainer = function() {
- return this.overlayContainer_;
- };
- /**
- * Get the element that serves as a container for overlays that don't allow
- * event propagation. Elements added to this container won't let mousedown and
- * touchstart events through to the map, so clicks and gestures on an overlay
- * don't trigger any {@link ol.MapBrowserEvent}.
- * @return {!Element} The map's overlay container that stops events.
- */
- ol.PluggableMap.prototype.getOverlayContainerStopEvent = function() {
- return this.overlayContainerStopEvent_;
- };
- /**
- * @param {ol.Tile} tile Tile.
- * @param {string} tileSourceKey Tile source key.
- * @param {ol.Coordinate} tileCenter Tile center.
- * @param {number} tileResolution Tile resolution.
- * @return {number} Tile priority.
- */
- ol.PluggableMap.prototype.getTilePriority = function(tile, tileSourceKey, tileCenter, tileResolution) {
- // Filter out tiles at higher zoom levels than the current zoom level, or that
- // are outside the visible extent.
- var frameState = this.frameState_;
- if (!frameState || !(tileSourceKey in frameState.wantedTiles)) {
- return ol.structs.PriorityQueue.DROP;
- }
- if (!frameState.wantedTiles[tileSourceKey][tile.getKey()]) {
- return ol.structs.PriorityQueue.DROP;
- }
- // Prioritize the highest zoom level tiles closest to the focus.
- // Tiles at higher zoom levels are prioritized using Math.log(tileResolution).
- // Within a zoom level, tiles are prioritized by the distance in pixels
- // between the center of the tile and the focus. The factor of 65536 means
- // that the prioritization should behave as desired for tiles up to
- // 65536 * Math.log(2) = 45426 pixels from the focus.
- var deltaX = tileCenter[0] - frameState.focus[0];
- var deltaY = tileCenter[1] - frameState.focus[1];
- return 65536 * Math.log(tileResolution) +
- Math.sqrt(deltaX * deltaX + deltaY * deltaY) / tileResolution;
- };
- /**
- * @param {Event} browserEvent Browser event.
- * @param {string=} opt_type Type.
- */
- ol.PluggableMap.prototype.handleBrowserEvent = function(browserEvent, opt_type) {
- var type = opt_type || browserEvent.type;
- var mapBrowserEvent = new ol.MapBrowserEvent(type, this, browserEvent);
- this.handleMapBrowserEvent(mapBrowserEvent);
- };
- /**
- * @param {ol.MapBrowserEvent} mapBrowserEvent The event to handle.
- */
- ol.PluggableMap.prototype.handleMapBrowserEvent = function(mapBrowserEvent) {
- if (!this.frameState_) {
- // With no view defined, we cannot translate pixels into geographical
- // coordinates so interactions cannot be used.
- return;
- }
- this.focus_ = mapBrowserEvent.coordinate;
- mapBrowserEvent.frameState = this.frameState_;
- var interactionsArray = this.getInteractions().getArray();
- var i;
- if (this.dispatchEvent(mapBrowserEvent) !== false) {
- for (i = interactionsArray.length - 1; i >= 0; i--) {
- var interaction = interactionsArray[i];
- if (!interaction.getActive()) {
- continue;
- }
- var cont = interaction.handleEvent(mapBrowserEvent);
- if (!cont) {
- break;
- }
- }
- }
- };
- /**
- * @protected
- */
- ol.PluggableMap.prototype.handlePostRender = function() {
- var frameState = this.frameState_;
- // Manage the tile queue
- // Image loads are expensive and a limited resource, so try to use them
- // efficiently:
- // * When the view is static we allow a large number of parallel tile loads
- // to complete the frame as quickly as possible.
- // * When animating or interacting, image loads can cause janks, so we reduce
- // the maximum number of loads per frame and limit the number of parallel
- // tile loads to remain reactive to view changes and to reduce the chance of
- // loading tiles that will quickly disappear from view.
- var tileQueue = this.tileQueue_;
- if (!tileQueue.isEmpty()) {
- var maxTotalLoading = 16;
- var maxNewLoads = maxTotalLoading;
- if (frameState) {
- var hints = frameState.viewHints;
- if (hints[ol.ViewHint.ANIMATING]) {
- maxTotalLoading = this.loadTilesWhileAnimating_ ? 8 : 0;
- maxNewLoads = 2;
- }
- if (hints[ol.ViewHint.INTERACTING]) {
- maxTotalLoading = this.loadTilesWhileInteracting_ ? 8 : 0;
- maxNewLoads = 2;
- }
- }
- if (tileQueue.getTilesLoading() < maxTotalLoading) {
- tileQueue.reprioritize(); // FIXME only call if view has changed
- tileQueue.loadMoreTiles(maxTotalLoading, maxNewLoads);
- }
- }
- var postRenderFunctions = this.postRenderFunctions_;
- var i, ii;
- for (i = 0, ii = postRenderFunctions.length; i < ii; ++i) {
- postRenderFunctions[i](this, frameState);
- }
- postRenderFunctions.length = 0;
- };
- /**
- * @private
- */
- ol.PluggableMap.prototype.handleSizeChanged_ = function() {
- this.render();
- };
- /**
- * @private
- */
- ol.PluggableMap.prototype.handleTargetChanged_ = function() {
- // target may be undefined, null, a string or an Element.
- // If it's a string we convert it to an Element before proceeding.
- // If it's not now an Element we remove the viewport from the DOM.
- // If it's an Element we append the viewport element to it.
- var targetElement;
- if (this.getTarget()) {
- targetElement = this.getTargetElement();
- }
- if (this.keyHandlerKeys_) {
- for (var i = 0, ii = this.keyHandlerKeys_.length; i < ii; ++i) {
- ol.events.unlistenByKey(this.keyHandlerKeys_[i]);
- }
- this.keyHandlerKeys_ = null;
- }
- if (!targetElement) {
- this.renderer_.removeLayerRenderers();
- ol.dom.removeNode(this.viewport_);
- if (this.handleResize_ !== undefined) {
- window.removeEventListener(ol.events.EventType.RESIZE,
- this.handleResize_, false);
- this.handleResize_ = undefined;
- }
- } else {
- targetElement.appendChild(this.viewport_);
- var keyboardEventTarget = !this.keyboardEventTarget_ ?
- targetElement : this.keyboardEventTarget_;
- this.keyHandlerKeys_ = [
- ol.events.listen(keyboardEventTarget, ol.events.EventType.KEYDOWN,
- this.handleBrowserEvent, this),
- ol.events.listen(keyboardEventTarget, ol.events.EventType.KEYPRESS,
- this.handleBrowserEvent, this)
- ];
- if (!this.handleResize_) {
- this.handleResize_ = this.updateSize.bind(this);
- window.addEventListener(ol.events.EventType.RESIZE,
- this.handleResize_, false);
- }
- }
- this.updateSize();
- // updateSize calls setSize, so no need to call this.render
- // ourselves here.
- };
- /**
- * @private
- */
- ol.PluggableMap.prototype.handleTileChange_ = function() {
- this.render();
- };
- /**
- * @private
- */
- ol.PluggableMap.prototype.handleViewPropertyChanged_ = function() {
- this.render();
- };
- /**
- * @private
- */
- ol.PluggableMap.prototype.handleViewChanged_ = function() {
- if (this.viewPropertyListenerKey_) {
- ol.events.unlistenByKey(this.viewPropertyListenerKey_);
- this.viewPropertyListenerKey_ = null;
- }
- if (this.viewChangeListenerKey_) {
- ol.events.unlistenByKey(this.viewChangeListenerKey_);
- this.viewChangeListenerKey_ = null;
- }
- var view = this.getView();
- if (view) {
- this.viewport_.setAttribute('data-view', ol.getUid(view));
- this.viewPropertyListenerKey_ = ol.events.listen(
- view, ol.ObjectEventType.PROPERTYCHANGE,
- this.handleViewPropertyChanged_, this);
- this.viewChangeListenerKey_ = ol.events.listen(
- view, ol.events.EventType.CHANGE,
- this.handleViewPropertyChanged_, this);
- }
- this.render();
- };
- /**
- * @private
- */
- ol.PluggableMap.prototype.handleLayerGroupChanged_ = function() {
- if (this.layerGroupPropertyListenerKeys_) {
- this.layerGroupPropertyListenerKeys_.forEach(ol.events.unlistenByKey);
- this.layerGroupPropertyListenerKeys_ = null;
- }
- var layerGroup = this.getLayerGroup();
- if (layerGroup) {
- this.layerGroupPropertyListenerKeys_ = [
- ol.events.listen(
- layerGroup, ol.ObjectEventType.PROPERTYCHANGE,
- this.render, this),
- ol.events.listen(
- layerGroup, ol.events.EventType.CHANGE,
- this.render, this)
- ];
- }
- this.render();
- };
- /**
- * @return {boolean} Is rendered.
- */
- ol.PluggableMap.prototype.isRendered = function() {
- return !!this.frameState_;
- };
- /**
- * Requests an immediate render in a synchronous manner.
- * @api
- */
- ol.PluggableMap.prototype.renderSync = function() {
- if (this.animationDelayKey_) {
- cancelAnimationFrame(this.animationDelayKey_);
- }
- this.animationDelay_();
- };
- /**
- * Request a map rendering (at the next animation frame).
- * @api
- */
- ol.PluggableMap.prototype.render = function() {
- if (this.animationDelayKey_ === undefined) {
- this.animationDelayKey_ = requestAnimationFrame(
- this.animationDelay_);
- }
- };
- /**
- * Remove the given control from the map.
- * @param {ol.control.Control} control Control.
- * @return {ol.control.Control|undefined} The removed control (or undefined
- * if the control was not found).
- * @api
- */
- ol.PluggableMap.prototype.removeControl = function(control) {
- return this.getControls().remove(control);
- };
- /**
- * Remove the given interaction from the map.
- * @param {ol.interaction.Interaction} interaction Interaction to remove.
- * @return {ol.interaction.Interaction|undefined} The removed interaction (or
- * undefined if the interaction was not found).
- * @api
- */
- ol.PluggableMap.prototype.removeInteraction = function(interaction) {
- return this.getInteractions().remove(interaction);
- };
- /**
- * Removes the given layer from the map.
- * @param {ol.layer.Base} layer Layer.
- * @return {ol.layer.Base|undefined} The removed layer (or undefined if the
- * layer was not found).
- * @api
- */
- ol.PluggableMap.prototype.removeLayer = function(layer) {
- var layers = this.getLayerGroup().getLayers();
- return layers.remove(layer);
- };
- /**
- * Remove the given overlay from the map.
- * @param {ol.Overlay} overlay Overlay.
- * @return {ol.Overlay|undefined} The removed overlay (or undefined
- * if the overlay was not found).
- * @api
- */
- ol.PluggableMap.prototype.removeOverlay = function(overlay) {
- return this.getOverlays().remove(overlay);
- };
- /**
- * @param {number} time Time.
- * @private
- */
- ol.PluggableMap.prototype.renderFrame_ = function(time) {
- var i, ii, viewState;
- var size = this.getSize();
- var view = this.getView();
- var extent = ol.extent.createEmpty();
- var previousFrameState = this.frameState_;
- /** @type {?olx.FrameState} */
- var frameState = null;
- if (size !== undefined && ol.size.hasArea(size) && view && view.isDef()) {
- var viewHints = view.getHints(this.frameState_ ? this.frameState_.viewHints : undefined);
- var layerStatesArray = this.getLayerGroup().getLayerStatesArray();
- var layerStates = {};
- for (i = 0, ii = layerStatesArray.length; i < ii; ++i) {
- layerStates[ol.getUid(layerStatesArray[i].layer)] = layerStatesArray[i];
- }
- viewState = view.getState();
- var center = viewState.center;
- var pixelResolution = viewState.resolution / this.pixelRatio_;
- center[0] = Math.round(center[0] / pixelResolution) * pixelResolution;
- center[1] = Math.round(center[1] / pixelResolution) * pixelResolution;
- frameState = /** @type {olx.FrameState} */ ({
- animate: false,
- coordinateToPixelTransform: this.coordinateToPixelTransform_,
- extent: extent,
- focus: !this.focus_ ? center : this.focus_,
- index: this.frameIndex_++,
- layerStates: layerStates,
- layerStatesArray: layerStatesArray,
- logos: ol.obj.assign({}, this.logos_),
- pixelRatio: this.pixelRatio_,
- pixelToCoordinateTransform: this.pixelToCoordinateTransform_,
- postRenderFunctions: [],
- size: size,
- skippedFeatureUids: this.skippedFeatureUids_,
- tileQueue: this.tileQueue_,
- time: time,
- usedTiles: {},
- viewState: viewState,
- viewHints: viewHints,
- wantedTiles: {}
- });
- }
- if (frameState) {
- frameState.extent = ol.extent.getForViewAndSize(viewState.center,
- viewState.resolution, viewState.rotation, frameState.size, extent);
- }
- this.frameState_ = frameState;
- this.renderer_.renderFrame(frameState);
- if (frameState) {
- if (frameState.animate) {
- this.render();
- }
- Array.prototype.push.apply(
- this.postRenderFunctions_, frameState.postRenderFunctions);
- if (previousFrameState) {
- var moveStart = !this.previousExtent_ ||
- (!ol.extent.isEmpty(this.previousExtent_) &&
- !ol.extent.equals(frameState.extent, this.previousExtent_));
- if (moveStart) {
- this.dispatchEvent(
- new ol.MapEvent(ol.MapEventType.MOVESTART, this, previousFrameState));
- this.previousExtent_ = ol.extent.createOrUpdateEmpty(this.previousExtent_);
- }
- }
- var idle = this.previousExtent_ &&
- !frameState.viewHints[ol.ViewHint.ANIMATING] &&
- !frameState.viewHints[ol.ViewHint.INTERACTING] &&
- !ol.extent.equals(frameState.extent, this.previousExtent_);
- if (idle) {
- this.dispatchEvent(
- new ol.MapEvent(ol.MapEventType.MOVEEND, this, frameState));
- ol.extent.clone(frameState.extent, this.previousExtent_);
- }
- }
- this.dispatchEvent(
- new ol.MapEvent(ol.MapEventType.POSTRENDER, this, frameState));
- setTimeout(this.handlePostRender.bind(this), 0);
- };
- /**
- * Sets the layergroup of this map.
- * @param {ol.layer.Group} layerGroup A layer group containing the layers in
- * this map.
- * @observable
- * @api
- */
- ol.PluggableMap.prototype.setLayerGroup = function(layerGroup) {
- this.set(ol.MapProperty.LAYERGROUP, layerGroup);
- };
- /**
- * Set the size of this map.
- * @param {ol.Size|undefined} size The size in pixels of the map in the DOM.
- * @observable
- * @api
- */
- ol.PluggableMap.prototype.setSize = function(size) {
- this.set(ol.MapProperty.SIZE, size);
- };
- /**
- * Set the target element to render this map into.
- * @param {Element|string|undefined} target The Element or id of the Element
- * that the map is rendered in.
- * @observable
- * @api
- */
- ol.PluggableMap.prototype.setTarget = function(target) {
- this.set(ol.MapProperty.TARGET, target);
- };
- /**
- * Set the view for this map.
- * @param {ol.View} view The view that controls this map.
- * @observable
- * @api
- */
- ol.PluggableMap.prototype.setView = function(view) {
- this.set(ol.MapProperty.VIEW, view);
- };
- /**
- * @param {ol.Feature} feature Feature.
- */
- ol.PluggableMap.prototype.skipFeature = function(feature) {
- var featureUid = ol.getUid(feature).toString();
- this.skippedFeatureUids_[featureUid] = true;
- this.render();
- };
- /**
- * Force a recalculation of the map viewport size. This should be called when
- * third-party code changes the size of the map viewport.
- * @api
- */
- ol.PluggableMap.prototype.updateSize = function() {
- var targetElement = this.getTargetElement();
- if (!targetElement) {
- this.setSize(undefined);
- } else {
- var computedStyle = getComputedStyle(targetElement);
- this.setSize([
- targetElement.offsetWidth -
- parseFloat(computedStyle['borderLeftWidth']) -
- parseFloat(computedStyle['paddingLeft']) -
- parseFloat(computedStyle['paddingRight']) -
- parseFloat(computedStyle['borderRightWidth']),
- targetElement.offsetHeight -
- parseFloat(computedStyle['borderTopWidth']) -
- parseFloat(computedStyle['paddingTop']) -
- parseFloat(computedStyle['paddingBottom']) -
- parseFloat(computedStyle['borderBottomWidth'])
- ]);
- }
- };
- /**
- * @param {ol.Feature} feature Feature.
- */
- ol.PluggableMap.prototype.unskipFeature = function(feature) {
- var featureUid = ol.getUid(feature).toString();
- delete this.skippedFeatureUids_[featureUid];
- this.render();
- };
- /**
- * @type {Array.<ol.renderer.Type>}
- * @const
- */
- ol.PluggableMap.DEFAULT_RENDERER_TYPES = [
- ol.renderer.Type.CANVAS,
- ol.renderer.Type.WEBGL
- ];
- /**
- * @const
- * @type {string}
- */
- ol.PluggableMap.LOGO_URL = 'data:image/png;base64,' +
- 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBI' +
- 'WXMAAAHGAAABxgEXwfpGAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAA' +
- 'AhNQTFRF////AP//AICAgP//AFVVQECA////K1VVSbbbYL/fJ05idsTYJFtbbcjbJllmZszW' +
- 'WMTOIFhoHlNiZszTa9DdUcHNHlNlV8XRIVdiasrUHlZjIVZjaMnVH1RlIFRkH1RkH1ZlasvY' +
- 'asvXVsPQH1VkacnVa8vWIVZjIFRjVMPQa8rXIVVkXsXRsNveIFVkIFZlIVVj3eDeh6GmbMvX' +
- 'H1ZkIFRka8rWbMvXIFVkIFVjIFVkbMvWH1VjbMvWIFVlbcvWIFVla8vVIFVkbMvWbMvVH1Vk' +
- 'bMvWIFVlbcvWIFVkbcvVbMvWjNPbIFVkU8LPwMzNIFVkbczWIFVkbsvWbMvXIFVkRnB8bcvW' +
- '2+TkW8XRIFVkIlZlJVloJlpoKlxrLl9tMmJwOWd0Omh1RXF8TneCT3iDUHiDU8LPVMLPVcLP' +
- 'VcPQVsPPVsPQV8PQWMTQWsTQW8TQXMXSXsXRX4SNX8bSYMfTYcfTYsfTY8jUZcfSZsnUaIqT' +
- 'acrVasrVa8jTa8rWbI2VbMvWbcvWdJObdcvUdszUd8vVeJaee87Yfc3WgJyjhqGnitDYjaar' +
- 'ldPZnrK2oNbborW5o9bbo9fbpLa6q9ndrL3ArtndscDDutzfu8fJwN7gwt7gxc/QyuHhy+Hi' +
- 'zeHi0NfX0+Pj19zb1+Tj2uXk29/e3uLg3+Lh3+bl4uXj4ufl4+fl5Ofl5ufl5ujm5+jmySDn' +
- 'BAAAAFp0Uk5TAAECAgMEBAYHCA0NDg4UGRogIiMmKSssLzU7PkJJT1JTVFliY2hrdHZ3foSF' +
- 'hYeJjY2QkpugqbG1tre5w8zQ09XY3uXn6+zx8vT09vf4+Pj5+fr6/P39/f3+gz7SsAAAAVVJ' +
- 'REFUOMtjYKA7EBDnwCPLrObS1BRiLoJLnte6CQy8FLHLCzs2QUG4FjZ5GbcmBDDjxJBXDWxC' +
- 'Brb8aM4zbkIDzpLYnAcE9VXlJSWlZRU13koIeW57mGx5XjoMZEUqwxWYQaQbSzLSkYGfKFSe' +
- '0QMsX5WbjgY0YS4MBplemI4BdGBW+DQ11eZiymfqQuXZIjqwyadPNoSZ4L+0FVM6e+oGI6g8' +
- 'a9iKNT3o8kVzNkzRg5lgl7p4wyRUL9Yt2jAxVh6mQCogae6GmflI8p0r13VFWTHBQ0rWPW7a' +
- 'hgWVcPm+9cuLoyy4kCJDzCm6d8PSFoh0zvQNC5OjDJhQopPPJqph1doJBUD5tnkbZiUEqaCn' +
- 'B3bTqLTFG1bPn71kw4b+GFdpLElKIzRxxgYgWNYc5SCENVHKeUaltHdXx0dZ8uBI1hJ2UUDg' +
- 'q82CM2MwKeibqAvSO7MCABq0wXEPiqWEAAAAAElFTkSuQmCC';
- /**
- * @param {olx.MapOptions} options Map options.
- * @return {ol.MapOptionsInternal} Internal map options.
- */
- ol.PluggableMap.createOptionsInternal = function(options) {
- /**
- * @type {Element|Document}
- */
- var keyboardEventTarget = null;
- if (options.keyboardEventTarget !== undefined) {
- keyboardEventTarget = typeof options.keyboardEventTarget === 'string' ?
- document.getElementById(options.keyboardEventTarget) :
- options.keyboardEventTarget;
- }
- /**
- * @type {Object.<string, *>}
- */
- var values = {};
- var logos = {};
- if (options.logo === undefined ||
- (typeof options.logo === 'boolean' && options.logo)) {
- logos[ol.PluggableMap.LOGO_URL] = 'https://openlayers.org/';
- } else {
- var logo = options.logo;
- if (typeof logo === 'string') {
- logos[logo] = '';
- } else if (logo instanceof HTMLElement) {
- logos[ol.getUid(logo).toString()] = logo;
- } else if (logo) {
- ol.asserts.assert(typeof logo.href == 'string', 44); // `logo.href` should be a string.
- ol.asserts.assert(typeof logo.src == 'string', 45); // `logo.src` should be a string.
- logos[logo.src] = logo.href;
- }
- }
- var layerGroup = (options.layers instanceof ol.layer.Group) ?
- options.layers : new ol.layer.Group({layers: options.layers});
- values[ol.MapProperty.LAYERGROUP] = layerGroup;
- values[ol.MapProperty.TARGET] = options.target;
- values[ol.MapProperty.VIEW] = options.view !== undefined ?
- options.view : new ol.View();
- /**
- * @type {Array.<ol.renderer.Type>}
- */
- var rendererTypes;
- if (options.renderer !== undefined) {
- if (Array.isArray(options.renderer)) {
- rendererTypes = options.renderer;
- } else if (typeof options.renderer === 'string') {
- rendererTypes = [options.renderer];
- } else {
- ol.asserts.assert(false, 46); // Incorrect format for `renderer` option
- }
- if (rendererTypes.indexOf(/** @type {ol.renderer.Type} */ ('dom')) >= 0) {
- rendererTypes = rendererTypes.concat(ol.PluggableMap.DEFAULT_RENDERER_TYPES);
- }
- } else {
- rendererTypes = ol.PluggableMap.DEFAULT_RENDERER_TYPES;
- }
- /**
- * @type {olx.MapRendererPlugin}
- */
- var mapRendererPlugin;
- var mapRendererPlugins = ol.plugins.getMapRendererPlugins();
- outer: for (var i = 0, ii = rendererTypes.length; i < ii; ++i) {
- var rendererType = rendererTypes[i];
- for (var j = 0, jj = mapRendererPlugins.length; j < jj; ++j) {
- var candidate = mapRendererPlugins[j];
- if (candidate['handles'](rendererType)) {
- mapRendererPlugin = candidate;
- break outer;
- }
- }
- }
- if (!mapRendererPlugin) {
- throw new Error('Unable to create a map renderer for types: ' + rendererTypes.join(', '));
- }
- var controls;
- if (options.controls !== undefined) {
- if (Array.isArray(options.controls)) {
- controls = new ol.Collection(options.controls.slice());
- } else {
- ol.asserts.assert(options.controls instanceof ol.Collection,
- 47); // Expected `controls` to be an array or an `ol.Collection`
- controls = options.controls;
- }
- }
- var interactions;
- if (options.interactions !== undefined) {
- if (Array.isArray(options.interactions)) {
- interactions = new ol.Collection(options.interactions.slice());
- } else {
- ol.asserts.assert(options.interactions instanceof ol.Collection,
- 48); // Expected `interactions` to be an array or an `ol.Collection`
- interactions = options.interactions;
- }
- }
- var overlays;
- if (options.overlays !== undefined) {
- if (Array.isArray(options.overlays)) {
- overlays = new ol.Collection(options.overlays.slice());
- } else {
- ol.asserts.assert(options.overlays instanceof ol.Collection,
- 49); // Expected `overlays` to be an array or an `ol.Collection`
- overlays = options.overlays;
- }
- } else {
- overlays = new ol.Collection();
- }
- return {
- controls: controls,
- interactions: interactions,
- keyboardEventTarget: keyboardEventTarget,
- logos: logos,
- overlays: overlays,
- mapRendererPlugin: mapRendererPlugin,
- values: values
- };
- };
- goog.provide('ol.control.Control');
- goog.require('ol');
- goog.require('ol.MapEventType');
- goog.require('ol.Object');
- goog.require('ol.dom');
- goog.require('ol.events');
- /**
- * @classdesc
- * A control is a visible widget with a DOM element in a fixed position on the
- * screen. They can involve user input (buttons), or be informational only;
- * the position is determined using CSS. By default these are placed in the
- * container with CSS class name `ol-overlaycontainer-stopevent`, but can use
- * any outside DOM element.
- *
- * This is the base class for controls. You can use it for simple custom
- * controls by creating the element with listeners, creating an instance:
- * ```js
- * var myControl = new ol.control.Control({element: myElement});
- * ```
- * and then adding this to the map.
- *
- * The main advantage of having this as a control rather than a simple separate
- * DOM element is that preventing propagation is handled for you. Controls
- * will also be `ol.Object`s in a `ol.Collection`, so you can use their
- * methods.
- *
- * You can also extend this base for your own control class. See
- * examples/custom-controls for an example of how to do this.
- *
- * @constructor
- * @extends {ol.Object}
- * @implements {oli.control.Control}
- * @param {olx.control.ControlOptions} options Control options.
- * @api
- */
- ol.control.Control = function(options) {
- ol.Object.call(this);
- /**
- * @protected
- * @type {Element}
- */
- this.element = options.element ? options.element : null;
- /**
- * @private
- * @type {Element}
- */
- this.target_ = null;
- /**
- * @private
- * @type {ol.PluggableMap}
- */
- this.map_ = null;
- /**
- * @protected
- * @type {!Array.<ol.EventsKey>}
- */
- this.listenerKeys = [];
- /**
- * @type {function(ol.MapEvent)}
- */
- this.render = options.render ? options.render : ol.nullFunction;
- if (options.target) {
- this.setTarget(options.target);
- }
- };
- ol.inherits(ol.control.Control, ol.Object);
- /**
- * @inheritDoc
- */
- ol.control.Control.prototype.disposeInternal = function() {
- ol.dom.removeNode(this.element);
- ol.Object.prototype.disposeInternal.call(this);
- };
- /**
- * Get the map associated with this control.
- * @return {ol.PluggableMap} Map.
- * @api
- */
- ol.control.Control.prototype.getMap = function() {
- return this.map_;
- };
- /**
- * Remove the control from its current map and attach it to the new map.
- * Subclasses may set up event handlers to get notified about changes to
- * the map here.
- * @param {ol.PluggableMap} map Map.
- * @override
- * @api
- */
- ol.control.Control.prototype.setMap = function(map) {
- if (this.map_) {
- ol.dom.removeNode(this.element);
- }
- for (var i = 0, ii = this.listenerKeys.length; i < ii; ++i) {
- ol.events.unlistenByKey(this.listenerKeys[i]);
- }
- this.listenerKeys.length = 0;
- this.map_ = map;
- if (this.map_) {
- var target = this.target_ ?
- this.target_ : map.getOverlayContainerStopEvent();
- target.appendChild(this.element);
- if (this.render !== ol.nullFunction) {
- this.listenerKeys.push(ol.events.listen(map,
- ol.MapEventType.POSTRENDER, this.render, this));
- }
- map.render();
- }
- };
- /**
- * This function is used to set a target element for the control. It has no
- * effect if it is called after the control has been added to the map (i.e.
- * after `setMap` is called on the control). If no `target` is set in the
- * options passed to the control constructor and if `setTarget` is not called
- * then the control is added to the map's overlay container.
- * @param {Element|string} target Target.
- * @api
- */
- ol.control.Control.prototype.setTarget = function(target) {
- this.target_ = typeof target === 'string' ?
- document.getElementById(target) :
- target;
- };
- goog.provide('ol.css');
- /**
- * The CSS class for hidden feature.
- *
- * @const
- * @type {string}
- */
- ol.css.CLASS_HIDDEN = 'ol-hidden';
- /**
- * The CSS class that we'll give the DOM elements to have them selectable.
- *
- * @const
- * @type {string}
- */
- ol.css.CLASS_SELECTABLE = 'ol-selectable';
- /**
- * The CSS class that we'll give the DOM elements to have them unselectable.
- *
- * @const
- * @type {string}
- */
- ol.css.CLASS_UNSELECTABLE = 'ol-unselectable';
- /**
- * The CSS class for unsupported feature.
- *
- * @const
- * @type {string}
- */
- ol.css.CLASS_UNSUPPORTED = 'ol-unsupported';
- /**
- * The CSS class for controls.
- *
- * @const
- * @type {string}
- */
- ol.css.CLASS_CONTROL = 'ol-control';
- /**
- * Get the list of font families from a font spec. Note that this doesn't work
- * for font families that have commas in them.
- * @param {string} The CSS font property.
- * @return {Object.<string>} The font families (or null if the input spec is invalid).
- */
- ol.css.getFontFamilies = (function() {
- var style;
- var cache = {};
- return function(font) {
- if (!style) {
- style = document.createElement('div').style;
- }
- if (!(font in cache)) {
- style.font = font;
- var family = style.fontFamily;
- style.font = '';
- if (!family) {
- return null;
- }
- cache[font] = family.split(/,\s?/);
- }
- return cache[font];
- };
- })();
- goog.provide('ol.render.EventType');
- /**
- * @enum {string}
- */
- ol.render.EventType = {
- /**
- * @event ol.render.Event#postcompose
- * @api
- */
- POSTCOMPOSE: 'postcompose',
- /**
- * @event ol.render.Event#precompose
- * @api
- */
- PRECOMPOSE: 'precompose',
- /**
- * @event ol.render.Event#render
- * @api
- */
- RENDER: 'render'
- };
- goog.provide('ol.layer.Layer');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol');
- goog.require('ol.Object');
- goog.require('ol.layer.Base');
- goog.require('ol.layer.Property');
- goog.require('ol.obj');
- goog.require('ol.render.EventType');
- goog.require('ol.source.State');
- /**
- * @classdesc
- * Abstract base class; normally only used for creating subclasses and not
- * instantiated in apps.
- * A visual representation of raster or vector map data.
- * Layers group together those properties that pertain to how the data is to be
- * displayed, irrespective of the source of that data.
- *
- * Layers are usually added to a map with {@link ol.Map#addLayer}. Components
- * like {@link ol.interaction.Select} use unmanaged layers internally. These
- * unmanaged layers are associated with the map using
- * {@link ol.layer.Layer#setMap} instead.
- *
- * A generic `change` event is fired when the state of the source changes.
- *
- * @constructor
- * @abstract
- * @extends {ol.layer.Base}
- * @fires ol.render.Event
- * @param {olx.layer.LayerOptions} options Layer options.
- * @api
- */
- ol.layer.Layer = function(options) {
- var baseOptions = ol.obj.assign({}, options);
- delete baseOptions.source;
- ol.layer.Base.call(this, /** @type {olx.layer.BaseOptions} */ (baseOptions));
- /**
- * @private
- * @type {?ol.EventsKey}
- */
- this.mapPrecomposeKey_ = null;
- /**
- * @private
- * @type {?ol.EventsKey}
- */
- this.mapRenderKey_ = null;
- /**
- * @private
- * @type {?ol.EventsKey}
- */
- this.sourceChangeKey_ = null;
- if (options.map) {
- this.setMap(options.map);
- }
- ol.events.listen(this,
- ol.Object.getChangeEventType(ol.layer.Property.SOURCE),
- this.handleSourcePropertyChange_, this);
- var source = options.source ? options.source : null;
- this.setSource(source);
- };
- ol.inherits(ol.layer.Layer, ol.layer.Base);
- /**
- * Return `true` if the layer is visible, and if the passed resolution is
- * between the layer's minResolution and maxResolution. The comparison is
- * inclusive for `minResolution` and exclusive for `maxResolution`.
- * @param {ol.LayerState} layerState Layer state.
- * @param {number} resolution Resolution.
- * @return {boolean} The layer is visible at the given resolution.
- */
- ol.layer.Layer.visibleAtResolution = function(layerState, resolution) {
- return layerState.visible && resolution >= layerState.minResolution &&
- resolution < layerState.maxResolution;
- };
- /**
- * @inheritDoc
- */
- ol.layer.Layer.prototype.getLayersArray = function(opt_array) {
- var array = opt_array ? opt_array : [];
- array.push(this);
- return array;
- };
- /**
- * @inheritDoc
- */
- ol.layer.Layer.prototype.getLayerStatesArray = function(opt_states) {
- var states = opt_states ? opt_states : [];
- states.push(this.getLayerState());
- return states;
- };
- /**
- * Get the layer source.
- * @return {ol.source.Source} The layer source (or `null` if not yet set).
- * @observable
- * @api
- */
- ol.layer.Layer.prototype.getSource = function() {
- var source = this.get(ol.layer.Property.SOURCE);
- return /** @type {ol.source.Source} */ (source) || null;
- };
- /**
- * @inheritDoc
- */
- ol.layer.Layer.prototype.getSourceState = function() {
- var source = this.getSource();
- return !source ? ol.source.State.UNDEFINED : source.getState();
- };
- /**
- * @private
- */
- ol.layer.Layer.prototype.handleSourceChange_ = function() {
- this.changed();
- };
- /**
- * @private
- */
- ol.layer.Layer.prototype.handleSourcePropertyChange_ = function() {
- if (this.sourceChangeKey_) {
- ol.events.unlistenByKey(this.sourceChangeKey_);
- this.sourceChangeKey_ = null;
- }
- var source = this.getSource();
- if (source) {
- this.sourceChangeKey_ = ol.events.listen(source,
- ol.events.EventType.CHANGE, this.handleSourceChange_, this);
- }
- this.changed();
- };
- /**
- * Sets the layer to be rendered on top of other layers on a map. The map will
- * not manage this layer in its layers collection, and the callback in
- * {@link ol.Map#forEachLayerAtPixel} will receive `null` as layer. This
- * is useful for temporary layers. To remove an unmanaged layer from the map,
- * use `#setMap(null)`.
- *
- * To add the layer to a map and have it managed by the map, use
- * {@link ol.Map#addLayer} instead.
- * @param {ol.PluggableMap} map Map.
- * @api
- */
- ol.layer.Layer.prototype.setMap = function(map) {
- if (this.mapPrecomposeKey_) {
- ol.events.unlistenByKey(this.mapPrecomposeKey_);
- this.mapPrecomposeKey_ = null;
- }
- if (!map) {
- this.changed();
- }
- if (this.mapRenderKey_) {
- ol.events.unlistenByKey(this.mapRenderKey_);
- this.mapRenderKey_ = null;
- }
- if (map) {
- this.mapPrecomposeKey_ = ol.events.listen(
- map, ol.render.EventType.PRECOMPOSE, function(evt) {
- var layerState = this.getLayerState();
- layerState.managed = false;
- layerState.zIndex = Infinity;
- evt.frameState.layerStatesArray.push(layerState);
- evt.frameState.layerStates[ol.getUid(this)] = layerState;
- }, this);
- this.mapRenderKey_ = ol.events.listen(
- this, ol.events.EventType.CHANGE, map.render, map);
- this.changed();
- }
- };
- /**
- * Set the layer source.
- * @param {ol.source.Source} source The layer source.
- * @observable
- * @api
- */
- ol.layer.Layer.prototype.setSource = function(source) {
- this.set(ol.layer.Property.SOURCE, source);
- };
- // FIXME handle date line wrap
- goog.provide('ol.control.Attribution');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.control.Control');
- goog.require('ol.css');
- goog.require('ol.dom');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.layer.Layer');
- goog.require('ol.obj');
- /**
- * @classdesc
- * Control to show all the attributions associated with the layer sources
- * in the map. This control is one of the default controls included in maps.
- * By default it will show in the bottom right portion of the map, but this can
- * be changed by using a css selector for `.ol-attribution`.
- *
- * @constructor
- * @extends {ol.control.Control}
- * @param {olx.control.AttributionOptions=} opt_options Attribution options.
- * @api
- */
- ol.control.Attribution = function(opt_options) {
- var options = opt_options ? opt_options : {};
- /**
- * @private
- * @type {Element}
- */
- this.ulElement_ = document.createElement('UL');
- /**
- * @private
- * @type {Element}
- */
- this.logoLi_ = document.createElement('LI');
- this.ulElement_.appendChild(this.logoLi_);
- this.logoLi_.style.display = 'none';
- /**
- * @private
- * @type {boolean}
- */
- this.collapsed_ = options.collapsed !== undefined ? options.collapsed : true;
- /**
- * @private
- * @type {boolean}
- */
- this.collapsible_ = options.collapsible !== undefined ?
- options.collapsible : true;
- if (!this.collapsible_) {
- this.collapsed_ = false;
- }
- var className = options.className !== undefined ? options.className : 'ol-attribution';
- var tipLabel = options.tipLabel !== undefined ? options.tipLabel : 'Attributions';
- var collapseLabel = options.collapseLabel !== undefined ? options.collapseLabel : '\u00BB';
- if (typeof collapseLabel === 'string') {
- /**
- * @private
- * @type {Node}
- */
- this.collapseLabel_ = document.createElement('span');
- this.collapseLabel_.textContent = collapseLabel;
- } else {
- this.collapseLabel_ = collapseLabel;
- }
- var label = options.label !== undefined ? options.label : 'i';
- if (typeof label === 'string') {
- /**
- * @private
- * @type {Node}
- */
- this.label_ = document.createElement('span');
- this.label_.textContent = label;
- } else {
- this.label_ = label;
- }
- var activeLabel = (this.collapsible_ && !this.collapsed_) ?
- this.collapseLabel_ : this.label_;
- var button = document.createElement('button');
- button.setAttribute('type', 'button');
- button.title = tipLabel;
- button.appendChild(activeLabel);
- ol.events.listen(button, ol.events.EventType.CLICK, this.handleClick_, this);
- var cssClasses = className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' +
- ol.css.CLASS_CONTROL +
- (this.collapsed_ && this.collapsible_ ? ' ol-collapsed' : '') +
- (this.collapsible_ ? '' : ' ol-uncollapsible');
- var element = document.createElement('div');
- element.className = cssClasses;
- element.appendChild(this.ulElement_);
- element.appendChild(button);
- var render = options.render ? options.render : ol.control.Attribution.render;
- ol.control.Control.call(this, {
- element: element,
- render: render,
- target: options.target
- });
- /**
- * A list of currently rendered resolutions.
- * @type {Array.<string>}
- * @private
- */
- this.renderedAttributions_ = [];
- /**
- * @private
- * @type {boolean}
- */
- this.renderedVisible_ = true;
- /**
- * @private
- * @type {Object.<string, Element>}
- */
- this.logoElements_ = {};
- };
- ol.inherits(ol.control.Attribution, ol.control.Control);
- /**
- * Get a list of visible attributions.
- * @param {olx.FrameState} frameState Frame state.
- * @return {Array.<string>} Attributions.
- * @private
- */
- ol.control.Attribution.prototype.getSourceAttributions_ = function(frameState) {
- /**
- * Used to determine if an attribution already exists.
- * @type {Object.<string, boolean>}
- */
- var lookup = {};
- /**
- * A list of visible attributions.
- * @type {Array.<string>}
- */
- var visibleAttributions = [];
- var layerStatesArray = frameState.layerStatesArray;
- var resolution = frameState.viewState.resolution;
- for (var i = 0, ii = layerStatesArray.length; i < ii; ++i) {
- var layerState = layerStatesArray[i];
- if (!ol.layer.Layer.visibleAtResolution(layerState, resolution)) {
- continue;
- }
- var source = layerState.layer.getSource();
- if (!source) {
- continue;
- }
- var attributionGetter = source.getAttributions2();
- if (!attributionGetter) {
- continue;
- }
- var attributions = attributionGetter(frameState);
- if (!attributions) {
- continue;
- }
- if (Array.isArray(attributions)) {
- for (var j = 0, jj = attributions.length; j < jj; ++j) {
- if (!(attributions[j] in lookup)) {
- visibleAttributions.push(attributions[j]);
- lookup[attributions[j]] = true;
- }
- }
- } else {
- if (!(attributions in lookup)) {
- visibleAttributions.push(attributions);
- lookup[attributions] = true;
- }
- }
- }
- return visibleAttributions;
- };
- /**
- * Update the attribution element.
- * @param {ol.MapEvent} mapEvent Map event.
- * @this {ol.control.Attribution}
- * @api
- */
- ol.control.Attribution.render = function(mapEvent) {
- this.updateElement_(mapEvent.frameState);
- };
- /**
- * @private
- * @param {?olx.FrameState} frameState Frame state.
- */
- ol.control.Attribution.prototype.updateElement_ = function(frameState) {
- if (!frameState) {
- if (this.renderedVisible_) {
- this.element.style.display = 'none';
- this.renderedVisible_ = false;
- }
- return;
- }
- var attributions = this.getSourceAttributions_(frameState);
- if (ol.array.equals(attributions, this.renderedAttributions_)) {
- return;
- }
- // remove everything but the logo
- while (this.ulElement_.lastChild !== this.logoLi_) {
- this.ulElement_.removeChild(this.ulElement_.lastChild);
- }
- // append the attributions
- for (var i = 0, ii = attributions.length; i < ii; ++i) {
- var element = document.createElement('LI');
- element.innerHTML = attributions[i];
- this.ulElement_.appendChild(element);
- }
- if (attributions.length === 0 && this.renderedAttributions_.length > 0) {
- this.element.classList.add('ol-logo-only');
- } else if (this.renderedAttributions_.length === 0 && attributions.length > 0) {
- this.element.classList.remove('ol-logo-only');
- }
- var visible = attributions.length > 0 || !ol.obj.isEmpty(frameState.logos);
- if (this.renderedVisible_ != visible) {
- this.element.style.display = visible ? '' : 'none';
- this.renderedVisible_ = visible;
- }
- this.renderedAttributions_ = attributions;
- this.insertLogos_(frameState);
- };
- /**
- * @param {?olx.FrameState} frameState Frame state.
- * @private
- */
- ol.control.Attribution.prototype.insertLogos_ = function(frameState) {
- var logo;
- var logos = frameState.logos;
- var logoElements = this.logoElements_;
- for (logo in logoElements) {
- if (!(logo in logos)) {
- ol.dom.removeNode(logoElements[logo]);
- delete logoElements[logo];
- }
- }
- var image, logoElement, logoKey;
- for (logoKey in logos) {
- var logoValue = logos[logoKey];
- if (logoValue instanceof HTMLElement) {
- this.logoLi_.appendChild(logoValue);
- logoElements[logoKey] = logoValue;
- }
- if (!(logoKey in logoElements)) {
- image = new Image();
- image.src = logoKey;
- if (logoValue === '') {
- logoElement = image;
- } else {
- logoElement = document.createElement('a');
- logoElement.href = logoValue;
- logoElement.appendChild(image);
- }
- this.logoLi_.appendChild(logoElement);
- logoElements[logoKey] = logoElement;
- }
- }
- this.logoLi_.style.display = !ol.obj.isEmpty(logos) ? '' : 'none';
- };
- /**
- * @param {Event} event The event to handle
- * @private
- */
- ol.control.Attribution.prototype.handleClick_ = function(event) {
- event.preventDefault();
- this.handleToggle_();
- };
- /**
- * @private
- */
- ol.control.Attribution.prototype.handleToggle_ = function() {
- this.element.classList.toggle('ol-collapsed');
- if (this.collapsed_) {
- ol.dom.replaceNode(this.collapseLabel_, this.label_);
- } else {
- ol.dom.replaceNode(this.label_, this.collapseLabel_);
- }
- this.collapsed_ = !this.collapsed_;
- };
- /**
- * Return `true` if the attribution is collapsible, `false` otherwise.
- * @return {boolean} True if the widget is collapsible.
- * @api
- */
- ol.control.Attribution.prototype.getCollapsible = function() {
- return this.collapsible_;
- };
- /**
- * Set whether the attribution should be collapsible.
- * @param {boolean} collapsible True if the widget is collapsible.
- * @api
- */
- ol.control.Attribution.prototype.setCollapsible = function(collapsible) {
- if (this.collapsible_ === collapsible) {
- return;
- }
- this.collapsible_ = collapsible;
- this.element.classList.toggle('ol-uncollapsible');
- if (!collapsible && this.collapsed_) {
- this.handleToggle_();
- }
- };
- /**
- * Collapse or expand the attribution according to the passed parameter. Will
- * not do anything if the attribution isn't collapsible or if the current
- * collapsed state is already the one requested.
- * @param {boolean} collapsed True if the widget is collapsed.
- * @api
- */
- ol.control.Attribution.prototype.setCollapsed = function(collapsed) {
- if (!this.collapsible_ || this.collapsed_ === collapsed) {
- return;
- }
- this.handleToggle_();
- };
- /**
- * Return `true` when the attribution is currently collapsed or `false`
- * otherwise.
- * @return {boolean} True if the widget is collapsed.
- * @api
- */
- ol.control.Attribution.prototype.getCollapsed = function() {
- return this.collapsed_;
- };
- goog.provide('ol.control.Rotate');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol');
- goog.require('ol.control.Control');
- goog.require('ol.css');
- goog.require('ol.easing');
- /**
- * @classdesc
- * A button control to reset rotation to 0.
- * To style this control use css selector `.ol-rotate`. A `.ol-hidden` css
- * selector is added to the button when the rotation is 0.
- *
- * @constructor
- * @extends {ol.control.Control}
- * @param {olx.control.RotateOptions=} opt_options Rotate options.
- * @api
- */
- ol.control.Rotate = function(opt_options) {
- var options = opt_options ? opt_options : {};
- var className = options.className !== undefined ? options.className : 'ol-rotate';
- var label = options.label !== undefined ? options.label : '\u21E7';
- /**
- * @type {Element}
- * @private
- */
- this.label_ = null;
- if (typeof label === 'string') {
- this.label_ = document.createElement('span');
- this.label_.className = 'ol-compass';
- this.label_.textContent = label;
- } else {
- this.label_ = label;
- this.label_.classList.add('ol-compass');
- }
- var tipLabel = options.tipLabel ? options.tipLabel : 'Reset rotation';
- var button = document.createElement('button');
- button.className = className + '-reset';
- button.setAttribute('type', 'button');
- button.title = tipLabel;
- button.appendChild(this.label_);
- ol.events.listen(button, ol.events.EventType.CLICK,
- ol.control.Rotate.prototype.handleClick_, this);
- var cssClasses = className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' +
- ol.css.CLASS_CONTROL;
- var element = document.createElement('div');
- element.className = cssClasses;
- element.appendChild(button);
- var render = options.render ? options.render : ol.control.Rotate.render;
- this.callResetNorth_ = options.resetNorth ? options.resetNorth : undefined;
- ol.control.Control.call(this, {
- element: element,
- render: render,
- target: options.target
- });
- /**
- * @type {number}
- * @private
- */
- this.duration_ = options.duration !== undefined ? options.duration : 250;
- /**
- * @type {boolean}
- * @private
- */
- this.autoHide_ = options.autoHide !== undefined ? options.autoHide : true;
- /**
- * @private
- * @type {number|undefined}
- */
- this.rotation_ = undefined;
- if (this.autoHide_) {
- this.element.classList.add(ol.css.CLASS_HIDDEN);
- }
- };
- ol.inherits(ol.control.Rotate, ol.control.Control);
- /**
- * @param {Event} event The event to handle
- * @private
- */
- ol.control.Rotate.prototype.handleClick_ = function(event) {
- event.preventDefault();
- if (this.callResetNorth_ !== undefined) {
- this.callResetNorth_();
- } else {
- this.resetNorth_();
- }
- };
- /**
- * @private
- */
- ol.control.Rotate.prototype.resetNorth_ = function() {
- var map = this.getMap();
- var view = map.getView();
- if (!view) {
- // the map does not have a view, so we can't act
- // upon it
- return;
- }
- if (view.getRotation() !== undefined) {
- if (this.duration_ > 0) {
- view.animate({
- rotation: 0,
- duration: this.duration_,
- easing: ol.easing.easeOut
- });
- } else {
- view.setRotation(0);
- }
- }
- };
- /**
- * Update the rotate control element.
- * @param {ol.MapEvent} mapEvent Map event.
- * @this {ol.control.Rotate}
- * @api
- */
- ol.control.Rotate.render = function(mapEvent) {
- var frameState = mapEvent.frameState;
- if (!frameState) {
- return;
- }
- var rotation = frameState.viewState.rotation;
- if (rotation != this.rotation_) {
- var transform = 'rotate(' + rotation + 'rad)';
- if (this.autoHide_) {
- var contains = this.element.classList.contains(ol.css.CLASS_HIDDEN);
- if (!contains && rotation === 0) {
- this.element.classList.add(ol.css.CLASS_HIDDEN);
- } else if (contains && rotation !== 0) {
- this.element.classList.remove(ol.css.CLASS_HIDDEN);
- }
- }
- this.label_.style.msTransform = transform;
- this.label_.style.webkitTransform = transform;
- this.label_.style.transform = transform;
- }
- this.rotation_ = rotation;
- };
- goog.provide('ol.control.Zoom');
- goog.require('ol');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.control.Control');
- goog.require('ol.css');
- goog.require('ol.easing');
- /**
- * @classdesc
- * A control with 2 buttons, one for zoom in and one for zoom out.
- * This control is one of the default controls of a map. To style this control
- * use css selectors `.ol-zoom-in` and `.ol-zoom-out`.
- *
- * @constructor
- * @extends {ol.control.Control}
- * @param {olx.control.ZoomOptions=} opt_options Zoom options.
- * @api
- */
- ol.control.Zoom = function(opt_options) {
- var options = opt_options ? opt_options : {};
- var className = options.className !== undefined ? options.className : 'ol-zoom';
- var delta = options.delta !== undefined ? options.delta : 1;
- var zoomInLabel = options.zoomInLabel !== undefined ? options.zoomInLabel : '+';
- var zoomOutLabel = options.zoomOutLabel !== undefined ? options.zoomOutLabel : '\u2212';
- var zoomInTipLabel = options.zoomInTipLabel !== undefined ?
- options.zoomInTipLabel : 'Zoom in';
- var zoomOutTipLabel = options.zoomOutTipLabel !== undefined ?
- options.zoomOutTipLabel : 'Zoom out';
- var inElement = document.createElement('button');
- inElement.className = className + '-in';
- inElement.setAttribute('type', 'button');
- inElement.title = zoomInTipLabel;
- inElement.appendChild(
- typeof zoomInLabel === 'string' ? document.createTextNode(zoomInLabel) : zoomInLabel
- );
- ol.events.listen(inElement, ol.events.EventType.CLICK,
- ol.control.Zoom.prototype.handleClick_.bind(this, delta));
- var outElement = document.createElement('button');
- outElement.className = className + '-out';
- outElement.setAttribute('type', 'button');
- outElement.title = zoomOutTipLabel;
- outElement.appendChild(
- typeof zoomOutLabel === 'string' ? document.createTextNode(zoomOutLabel) : zoomOutLabel
- );
- ol.events.listen(outElement, ol.events.EventType.CLICK,
- ol.control.Zoom.prototype.handleClick_.bind(this, -delta));
- var cssClasses = className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' +
- ol.css.CLASS_CONTROL;
- var element = document.createElement('div');
- element.className = cssClasses;
- element.appendChild(inElement);
- element.appendChild(outElement);
- ol.control.Control.call(this, {
- element: element,
- target: options.target
- });
- /**
- * @type {number}
- * @private
- */
- this.duration_ = options.duration !== undefined ? options.duration : 250;
- };
- ol.inherits(ol.control.Zoom, ol.control.Control);
- /**
- * @param {number} delta Zoom delta.
- * @param {Event} event The event to handle
- * @private
- */
- ol.control.Zoom.prototype.handleClick_ = function(delta, event) {
- event.preventDefault();
- this.zoomByDelta_(delta);
- };
- /**
- * @param {number} delta Zoom delta.
- * @private
- */
- ol.control.Zoom.prototype.zoomByDelta_ = function(delta) {
- var map = this.getMap();
- var view = map.getView();
- if (!view) {
- // the map does not have a view, so we can't act
- // upon it
- return;
- }
- var currentResolution = view.getResolution();
- if (currentResolution) {
- var newResolution = view.constrainResolution(currentResolution, delta);
- if (this.duration_ > 0) {
- if (view.getAnimating()) {
- view.cancelAnimations();
- }
- view.animate({
- resolution: newResolution,
- duration: this.duration_,
- easing: ol.easing.easeOut
- });
- } else {
- view.setResolution(newResolution);
- }
- }
- };
- goog.provide('ol.control');
- goog.require('ol.Collection');
- goog.require('ol.control.Attribution');
- goog.require('ol.control.Rotate');
- goog.require('ol.control.Zoom');
- /**
- * Set of controls included in maps by default. Unless configured otherwise,
- * this returns a collection containing an instance of each of the following
- * controls:
- * * {@link ol.control.Zoom}
- * * {@link ol.control.Rotate}
- * * {@link ol.control.Attribution}
- *
- * @param {olx.control.DefaultsOptions=} opt_options Defaults options.
- * @return {ol.Collection.<ol.control.Control>} Controls.
- * @api
- */
- ol.control.defaults = function(opt_options) {
- var options = opt_options ? opt_options : {};
- var controls = new ol.Collection();
- var zoomControl = options.zoom !== undefined ? options.zoom : true;
- if (zoomControl) {
- controls.push(new ol.control.Zoom(options.zoomOptions));
- }
- var rotateControl = options.rotate !== undefined ? options.rotate : true;
- if (rotateControl) {
- controls.push(new ol.control.Rotate(options.rotateOptions));
- }
- var attributionControl = options.attribution !== undefined ?
- options.attribution : true;
- if (attributionControl) {
- controls.push(new ol.control.Attribution(options.attributionOptions));
- }
- return controls;
- };
- goog.provide('ol.Kinetic');
- /**
- * @classdesc
- * Implementation of inertial deceleration for map movement.
- *
- * @constructor
- * @param {number} decay Rate of decay (must be negative).
- * @param {number} minVelocity Minimum velocity (pixels/millisecond).
- * @param {number} delay Delay to consider to calculate the kinetic
- * initial values (milliseconds).
- * @struct
- * @api
- */
- ol.Kinetic = function(decay, minVelocity, delay) {
- /**
- * @private
- * @type {number}
- */
- this.decay_ = decay;
- /**
- * @private
- * @type {number}
- */
- this.minVelocity_ = minVelocity;
- /**
- * @private
- * @type {number}
- */
- this.delay_ = delay;
- /**
- * @private
- * @type {Array.<number>}
- */
- this.points_ = [];
- /**
- * @private
- * @type {number}
- */
- this.angle_ = 0;
- /**
- * @private
- * @type {number}
- */
- this.initialVelocity_ = 0;
- };
- /**
- * FIXME empty description for jsdoc
- */
- ol.Kinetic.prototype.begin = function() {
- this.points_.length = 0;
- this.angle_ = 0;
- this.initialVelocity_ = 0;
- };
- /**
- * @param {number} x X.
- * @param {number} y Y.
- */
- ol.Kinetic.prototype.update = function(x, y) {
- this.points_.push(x, y, Date.now());
- };
- /**
- * @return {boolean} Whether we should do kinetic animation.
- */
- ol.Kinetic.prototype.end = function() {
- if (this.points_.length < 6) {
- // at least 2 points are required (i.e. there must be at least 6 elements
- // in the array)
- return false;
- }
- var delay = Date.now() - this.delay_;
- var lastIndex = this.points_.length - 3;
- if (this.points_[lastIndex + 2] < delay) {
- // the last tracked point is too old, which means that the user stopped
- // panning before releasing the map
- return false;
- }
- // get the first point which still falls into the delay time
- var firstIndex = lastIndex - 3;
- while (firstIndex > 0 && this.points_[firstIndex + 2] > delay) {
- firstIndex -= 3;
- }
- var duration = this.points_[lastIndex + 2] - this.points_[firstIndex + 2];
- // we don't want a duration of 0 (divide by zero)
- // we also make sure the user panned for a duration of at least one frame
- // (1/60s) to compute sane displacement values
- if (duration < 1000 / 60) {
- return false;
- }
- var dx = this.points_[lastIndex] - this.points_[firstIndex];
- var dy = this.points_[lastIndex + 1] - this.points_[firstIndex + 1];
- this.angle_ = Math.atan2(dy, dx);
- this.initialVelocity_ = Math.sqrt(dx * dx + dy * dy) / duration;
- return this.initialVelocity_ > this.minVelocity_;
- };
- /**
- * @return {number} Total distance travelled (pixels).
- */
- ol.Kinetic.prototype.getDistance = function() {
- return (this.minVelocity_ - this.initialVelocity_) / this.decay_;
- };
- /**
- * @return {number} Angle of the kinetic panning animation (radians).
- */
- ol.Kinetic.prototype.getAngle = function() {
- return this.angle_;
- };
- goog.provide('ol.interaction.Property');
- /**
- * @enum {string}
- */
- ol.interaction.Property = {
- ACTIVE: 'active'
- };
- // FIXME factor out key precondition (shift et. al)
- goog.provide('ol.interaction.Interaction');
- goog.require('ol');
- goog.require('ol.Object');
- goog.require('ol.easing');
- goog.require('ol.interaction.Property');
- goog.require('ol.math');
- /**
- * @classdesc
- * Abstract base class; normally only used for creating subclasses and not
- * instantiated in apps.
- * User actions that change the state of the map. Some are similar to controls,
- * but are not associated with a DOM element.
- * For example, {@link ol.interaction.KeyboardZoom} is functionally the same as
- * {@link ol.control.Zoom}, but triggered by a keyboard event not a button
- * element event.
- * Although interactions do not have a DOM element, some of them do render
- * vectors and so are visible on the screen.
- *
- * @constructor
- * @param {olx.interaction.InteractionOptions} options Options.
- * @extends {ol.Object}
- * @api
- */
- ol.interaction.Interaction = function(options) {
- ol.Object.call(this);
- /**
- * @private
- * @type {ol.PluggableMap}
- */
- this.map_ = null;
- this.setActive(true);
- /**
- * @type {function(ol.MapBrowserEvent):boolean}
- */
- this.handleEvent = options.handleEvent;
- };
- ol.inherits(ol.interaction.Interaction, ol.Object);
- /**
- * Return whether the interaction is currently active.
- * @return {boolean} `true` if the interaction is active, `false` otherwise.
- * @observable
- * @api
- */
- ol.interaction.Interaction.prototype.getActive = function() {
- return /** @type {boolean} */ (
- this.get(ol.interaction.Property.ACTIVE));
- };
- /**
- * Get the map associated with this interaction.
- * @return {ol.PluggableMap} Map.
- * @api
- */
- ol.interaction.Interaction.prototype.getMap = function() {
- return this.map_;
- };
- /**
- * Activate or deactivate the interaction.
- * @param {boolean} active Active.
- * @observable
- * @api
- */
- ol.interaction.Interaction.prototype.setActive = function(active) {
- this.set(ol.interaction.Property.ACTIVE, active);
- };
- /**
- * Remove the interaction from its current map and attach it to the new map.
- * Subclasses may set up event handlers to get notified about changes to
- * the map here.
- * @param {ol.PluggableMap} map Map.
- */
- ol.interaction.Interaction.prototype.setMap = function(map) {
- this.map_ = map;
- };
- /**
- * @param {ol.View} view View.
- * @param {ol.Coordinate} delta Delta.
- * @param {number=} opt_duration Duration.
- */
- ol.interaction.Interaction.pan = function(view, delta, opt_duration) {
- var currentCenter = view.getCenter();
- if (currentCenter) {
- var center = view.constrainCenter(
- [currentCenter[0] + delta[0], currentCenter[1] + delta[1]]);
- if (opt_duration) {
- view.animate({
- duration: opt_duration,
- easing: ol.easing.linear,
- center: center
- });
- } else {
- view.setCenter(center);
- }
- }
- };
- /**
- * @param {ol.View} view View.
- * @param {number|undefined} rotation Rotation.
- * @param {ol.Coordinate=} opt_anchor Anchor coordinate.
- * @param {number=} opt_duration Duration.
- */
- ol.interaction.Interaction.rotate = function(view, rotation, opt_anchor, opt_duration) {
- rotation = view.constrainRotation(rotation, 0);
- ol.interaction.Interaction.rotateWithoutConstraints(
- view, rotation, opt_anchor, opt_duration);
- };
- /**
- * @param {ol.View} view View.
- * @param {number|undefined} rotation Rotation.
- * @param {ol.Coordinate=} opt_anchor Anchor coordinate.
- * @param {number=} opt_duration Duration.
- */
- ol.interaction.Interaction.rotateWithoutConstraints = function(view, rotation, opt_anchor, opt_duration) {
- if (rotation !== undefined) {
- var currentRotation = view.getRotation();
- var currentCenter = view.getCenter();
- if (currentRotation !== undefined && currentCenter && opt_duration > 0) {
- view.animate({
- rotation: rotation,
- anchor: opt_anchor,
- duration: opt_duration,
- easing: ol.easing.easeOut
- });
- } else {
- view.rotate(rotation, opt_anchor);
- }
- }
- };
- /**
- * @param {ol.View} view View.
- * @param {number|undefined} resolution Resolution to go to.
- * @param {ol.Coordinate=} opt_anchor Anchor coordinate.
- * @param {number=} opt_duration Duration.
- * @param {number=} opt_direction Zooming direction; > 0 indicates
- * zooming out, in which case the constraints system will select
- * the largest nearest resolution; < 0 indicates zooming in, in
- * which case the constraints system will select the smallest
- * nearest resolution; == 0 indicates that the zooming direction
- * is unknown/not relevant, in which case the constraints system
- * will select the nearest resolution. If not defined 0 is
- * assumed.
- */
- ol.interaction.Interaction.zoom = function(view, resolution, opt_anchor, opt_duration, opt_direction) {
- resolution = view.constrainResolution(resolution, 0, opt_direction);
- ol.interaction.Interaction.zoomWithoutConstraints(
- view, resolution, opt_anchor, opt_duration);
- };
- /**
- * @param {ol.View} view View.
- * @param {number} delta Delta from previous zoom level.
- * @param {ol.Coordinate=} opt_anchor Anchor coordinate.
- * @param {number=} opt_duration Duration.
- */
- ol.interaction.Interaction.zoomByDelta = function(view, delta, opt_anchor, opt_duration) {
- var currentResolution = view.getResolution();
- var resolution = view.constrainResolution(currentResolution, delta, 0);
- if (resolution !== undefined) {
- var resolutions = view.getResolutions();
- resolution = ol.math.clamp(
- resolution,
- view.getMinResolution() || resolutions[resolutions.length - 1],
- view.getMaxResolution() || resolutions[0]);
- }
- // If we have a constraint on center, we need to change the anchor so that the
- // new center is within the extent. We first calculate the new center, apply
- // the constraint to it, and then calculate back the anchor
- if (opt_anchor && resolution !== undefined && resolution !== currentResolution) {
- var currentCenter = view.getCenter();
- var center = view.calculateCenterZoom(resolution, opt_anchor);
- center = view.constrainCenter(center);
- opt_anchor = [
- (resolution * currentCenter[0] - currentResolution * center[0]) /
- (resolution - currentResolution),
- (resolution * currentCenter[1] - currentResolution * center[1]) /
- (resolution - currentResolution)
- ];
- }
- ol.interaction.Interaction.zoomWithoutConstraints(
- view, resolution, opt_anchor, opt_duration);
- };
- /**
- * @param {ol.View} view View.
- * @param {number|undefined} resolution Resolution to go to.
- * @param {ol.Coordinate=} opt_anchor Anchor coordinate.
- * @param {number=} opt_duration Duration.
- */
- ol.interaction.Interaction.zoomWithoutConstraints = function(view, resolution, opt_anchor, opt_duration) {
- if (resolution) {
- var currentResolution = view.getResolution();
- var currentCenter = view.getCenter();
- if (currentResolution !== undefined && currentCenter &&
- resolution !== currentResolution && opt_duration) {
- view.animate({
- resolution: resolution,
- anchor: opt_anchor,
- duration: opt_duration,
- easing: ol.easing.easeOut
- });
- } else {
- if (opt_anchor) {
- var center = view.calculateCenterZoom(resolution, opt_anchor);
- view.setCenter(center);
- }
- view.setResolution(resolution);
- }
- }
- };
- goog.provide('ol.interaction.DoubleClickZoom');
- goog.require('ol');
- goog.require('ol.MapBrowserEventType');
- goog.require('ol.interaction.Interaction');
- /**
- * @classdesc
- * Allows the user to zoom by double-clicking on the map.
- *
- * @constructor
- * @extends {ol.interaction.Interaction}
- * @param {olx.interaction.DoubleClickZoomOptions=} opt_options Options.
- * @api
- */
- ol.interaction.DoubleClickZoom = function(opt_options) {
- var options = opt_options ? opt_options : {};
- /**
- * @private
- * @type {number}
- */
- this.delta_ = options.delta ? options.delta : 1;
- ol.interaction.Interaction.call(this, {
- handleEvent: ol.interaction.DoubleClickZoom.handleEvent
- });
- /**
- * @private
- * @type {number}
- */
- this.duration_ = options.duration !== undefined ? options.duration : 250;
- };
- ol.inherits(ol.interaction.DoubleClickZoom, ol.interaction.Interaction);
- /**
- * Handles the {@link ol.MapBrowserEvent map browser event} (if it was a
- * doubleclick) and eventually zooms the map.
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} `false` to stop event propagation.
- * @this {ol.interaction.DoubleClickZoom}
- * @api
- */
- ol.interaction.DoubleClickZoom.handleEvent = function(mapBrowserEvent) {
- var stopEvent = false;
- var browserEvent = mapBrowserEvent.originalEvent;
- if (mapBrowserEvent.type == ol.MapBrowserEventType.DBLCLICK) {
- var map = mapBrowserEvent.map;
- var anchor = mapBrowserEvent.coordinate;
- var delta = browserEvent.shiftKey ? -this.delta_ : this.delta_;
- var view = map.getView();
- ol.interaction.Interaction.zoomByDelta(
- view, delta, anchor, this.duration_);
- mapBrowserEvent.preventDefault();
- stopEvent = true;
- }
- return !stopEvent;
- };
- goog.provide('ol.events.condition');
- goog.require('ol.MapBrowserEventType');
- goog.require('ol.asserts');
- goog.require('ol.functions');
- goog.require('ol.has');
- /**
- * Return `true` if only the alt-key is pressed, `false` otherwise (e.g. when
- * additionally the shift-key is pressed).
- *
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} True if only the alt key is pressed.
- * @api
- */
- ol.events.condition.altKeyOnly = function(mapBrowserEvent) {
- var originalEvent = mapBrowserEvent.originalEvent;
- return (
- originalEvent.altKey &&
- !(originalEvent.metaKey || originalEvent.ctrlKey) &&
- !originalEvent.shiftKey);
- };
- /**
- * Return `true` if only the alt-key and shift-key is pressed, `false` otherwise
- * (e.g. when additionally the platform-modifier-key is pressed).
- *
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} True if only the alt and shift keys are pressed.
- * @api
- */
- ol.events.condition.altShiftKeysOnly = function(mapBrowserEvent) {
- var originalEvent = mapBrowserEvent.originalEvent;
- return (
- originalEvent.altKey &&
- !(originalEvent.metaKey || originalEvent.ctrlKey) &&
- originalEvent.shiftKey);
- };
- /**
- * Return always true.
- *
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} True.
- * @function
- * @api
- */
- ol.events.condition.always = ol.functions.TRUE;
- /**
- * Return `true` if the event is a `click` event, `false` otherwise.
- *
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} True if the event is a map `click` event.
- * @api
- */
- ol.events.condition.click = function(mapBrowserEvent) {
- return mapBrowserEvent.type == ol.MapBrowserEventType.CLICK;
- };
- /**
- * Return `true` if the event has an "action"-producing mouse button.
- *
- * By definition, this includes left-click on windows/linux, and left-click
- * without the ctrl key on Macs.
- *
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} The result.
- */
- ol.events.condition.mouseActionButton = function(mapBrowserEvent) {
- var originalEvent = mapBrowserEvent.originalEvent;
- return originalEvent.button == 0 &&
- !(ol.has.WEBKIT && ol.has.MAC && originalEvent.ctrlKey);
- };
- /**
- * Return always false.
- *
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} False.
- * @function
- * @api
- */
- ol.events.condition.never = ol.functions.FALSE;
- /**
- * Return `true` if the browser event is a `pointermove` event, `false`
- * otherwise.
- *
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} True if the browser event is a `pointermove` event.
- * @api
- */
- ol.events.condition.pointerMove = function(mapBrowserEvent) {
- return mapBrowserEvent.type == 'pointermove';
- };
- /**
- * Return `true` if the event is a map `singleclick` event, `false` otherwise.
- *
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} True if the event is a map `singleclick` event.
- * @api
- */
- ol.events.condition.singleClick = function(mapBrowserEvent) {
- return mapBrowserEvent.type == ol.MapBrowserEventType.SINGLECLICK;
- };
- /**
- * Return `true` if the event is a map `dblclick` event, `false` otherwise.
- *
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} True if the event is a map `dblclick` event.
- * @api
- */
- ol.events.condition.doubleClick = function(mapBrowserEvent) {
- return mapBrowserEvent.type == ol.MapBrowserEventType.DBLCLICK;
- };
- /**
- * Return `true` if no modifier key (alt-, shift- or platform-modifier-key) is
- * pressed.
- *
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} True only if there no modifier keys are pressed.
- * @api
- */
- ol.events.condition.noModifierKeys = function(mapBrowserEvent) {
- var originalEvent = mapBrowserEvent.originalEvent;
- return (
- !originalEvent.altKey &&
- !(originalEvent.metaKey || originalEvent.ctrlKey) &&
- !originalEvent.shiftKey);
- };
- /**
- * Return `true` if only the platform-modifier-key (the meta-key on Mac,
- * ctrl-key otherwise) is pressed, `false` otherwise (e.g. when additionally
- * the shift-key is pressed).
- *
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} True if only the platform modifier key is pressed.
- * @api
- */
- ol.events.condition.platformModifierKeyOnly = function(mapBrowserEvent) {
- var originalEvent = mapBrowserEvent.originalEvent;
- return (
- !originalEvent.altKey &&
- (ol.has.MAC ? originalEvent.metaKey : originalEvent.ctrlKey) &&
- !originalEvent.shiftKey);
- };
- /**
- * Return `true` if only the shift-key is pressed, `false` otherwise (e.g. when
- * additionally the alt-key is pressed).
- *
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} True if only the shift key is pressed.
- * @api
- */
- ol.events.condition.shiftKeyOnly = function(mapBrowserEvent) {
- var originalEvent = mapBrowserEvent.originalEvent;
- return (
- !originalEvent.altKey &&
- !(originalEvent.metaKey || originalEvent.ctrlKey) &&
- originalEvent.shiftKey);
- };
- /**
- * Return `true` if the target element is not editable, i.e. not a `<input>`-,
- * `<select>`- or `<textarea>`-element, `false` otherwise.
- *
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} True only if the target element is not editable.
- * @api
- */
- ol.events.condition.targetNotEditable = function(mapBrowserEvent) {
- var target = mapBrowserEvent.originalEvent.target;
- var tagName = target.tagName;
- return (
- tagName !== 'INPUT' &&
- tagName !== 'SELECT' &&
- tagName !== 'TEXTAREA');
- };
- /**
- * Return `true` if the event originates from a mouse device.
- *
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} True if the event originates from a mouse device.
- * @api
- */
- ol.events.condition.mouseOnly = function(mapBrowserEvent) {
- ol.asserts.assert(mapBrowserEvent.pointerEvent, 56); // mapBrowserEvent must originate from a pointer event
- // see http://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType
- return /** @type {ol.MapBrowserEvent} */ (mapBrowserEvent).pointerEvent.pointerType == 'mouse';
- };
- /**
- * Return `true` if the event originates from a primary pointer in
- * contact with the surface or if the left mouse button is pressed.
- * @see http://www.w3.org/TR/pointerevents/#button-states
- *
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} True if the event originates from a primary pointer.
- * @api
- */
- ol.events.condition.primaryAction = function(mapBrowserEvent) {
- var pointerEvent = mapBrowserEvent.pointerEvent;
- return pointerEvent.isPrimary && pointerEvent.button === 0;
- };
- goog.provide('ol.interaction.Pointer');
- goog.require('ol');
- goog.require('ol.functions');
- goog.require('ol.MapBrowserEventType');
- goog.require('ol.MapBrowserPointerEvent');
- goog.require('ol.interaction.Interaction');
- goog.require('ol.obj');
- /**
- * @classdesc
- * Base class that calls user-defined functions on `down`, `move` and `up`
- * events. This class also manages "drag sequences".
- *
- * When the `handleDownEvent` user function returns `true` a drag sequence is
- * started. During a drag sequence the `handleDragEvent` user function is
- * called on `move` events. The drag sequence ends when the `handleUpEvent`
- * user function is called and returns `false`.
- *
- * @constructor
- * @param {olx.interaction.PointerOptions=} opt_options Options.
- * @extends {ol.interaction.Interaction}
- * @api
- */
- ol.interaction.Pointer = function(opt_options) {
- var options = opt_options ? opt_options : {};
- var handleEvent = options.handleEvent ?
- options.handleEvent : ol.interaction.Pointer.handleEvent;
- ol.interaction.Interaction.call(this, {
- handleEvent: handleEvent
- });
- /**
- * @type {function(ol.MapBrowserPointerEvent):boolean}
- * @private
- */
- this.handleDownEvent_ = options.handleDownEvent ?
- options.handleDownEvent : ol.interaction.Pointer.handleDownEvent;
- /**
- * @type {function(ol.MapBrowserPointerEvent)}
- * @private
- */
- this.handleDragEvent_ = options.handleDragEvent ?
- options.handleDragEvent : ol.interaction.Pointer.handleDragEvent;
- /**
- * @type {function(ol.MapBrowserPointerEvent)}
- * @private
- */
- this.handleMoveEvent_ = options.handleMoveEvent ?
- options.handleMoveEvent : ol.interaction.Pointer.handleMoveEvent;
- /**
- * @type {function(ol.MapBrowserPointerEvent):boolean}
- * @private
- */
- this.handleUpEvent_ = options.handleUpEvent ?
- options.handleUpEvent : ol.interaction.Pointer.handleUpEvent;
- /**
- * @type {boolean}
- * @protected
- */
- this.handlingDownUpSequence = false;
- /**
- * @type {Object.<string, ol.pointer.PointerEvent>}
- * @private
- */
- this.trackedPointers_ = {};
- /**
- * @type {Array.<ol.pointer.PointerEvent>}
- * @protected
- */
- this.targetPointers = [];
- };
- ol.inherits(ol.interaction.Pointer, ol.interaction.Interaction);
- /**
- * @param {Array.<ol.pointer.PointerEvent>} pointerEvents List of events.
- * @return {ol.Pixel} Centroid pixel.
- */
- ol.interaction.Pointer.centroid = function(pointerEvents) {
- var length = pointerEvents.length;
- var clientX = 0;
- var clientY = 0;
- for (var i = 0; i < length; i++) {
- clientX += pointerEvents[i].clientX;
- clientY += pointerEvents[i].clientY;
- }
- return [clientX / length, clientY / length];
- };
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @return {boolean} Whether the event is a pointerdown, pointerdrag
- * or pointerup event.
- * @private
- */
- ol.interaction.Pointer.prototype.isPointerDraggingEvent_ = function(mapBrowserEvent) {
- var type = mapBrowserEvent.type;
- return (
- type === ol.MapBrowserEventType.POINTERDOWN ||
- type === ol.MapBrowserEventType.POINTERDRAG ||
- type === ol.MapBrowserEventType.POINTERUP);
- };
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @private
- */
- ol.interaction.Pointer.prototype.updateTrackedPointers_ = function(mapBrowserEvent) {
- if (this.isPointerDraggingEvent_(mapBrowserEvent)) {
- var event = mapBrowserEvent.pointerEvent;
- var id = event.pointerId.toString();
- if (mapBrowserEvent.type == ol.MapBrowserEventType.POINTERUP) {
- delete this.trackedPointers_[id];
- } else if (mapBrowserEvent.type ==
- ol.MapBrowserEventType.POINTERDOWN) {
- this.trackedPointers_[id] = event;
- } else if (id in this.trackedPointers_) {
- // update only when there was a pointerdown event for this pointer
- this.trackedPointers_[id] = event;
- }
- this.targetPointers = ol.obj.getValues(this.trackedPointers_);
- }
- };
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @this {ol.interaction.Pointer}
- */
- ol.interaction.Pointer.handleDragEvent = ol.nullFunction;
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @return {boolean} Capture dragging.
- * @this {ol.interaction.Pointer}
- */
- ol.interaction.Pointer.handleUpEvent = ol.functions.FALSE;
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @return {boolean} Capture dragging.
- * @this {ol.interaction.Pointer}
- */
- ol.interaction.Pointer.handleDownEvent = ol.functions.FALSE;
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @this {ol.interaction.Pointer}
- */
- ol.interaction.Pointer.handleMoveEvent = ol.nullFunction;
- /**
- * Handles the {@link ol.MapBrowserEvent map browser event} and may call into
- * other functions, if event sequences like e.g. 'drag' or 'down-up' etc. are
- * detected.
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} `false` to stop event propagation.
- * @this {ol.interaction.Pointer}
- * @api
- */
- ol.interaction.Pointer.handleEvent = function(mapBrowserEvent) {
- if (!(mapBrowserEvent instanceof ol.MapBrowserPointerEvent)) {
- return true;
- }
- var stopEvent = false;
- this.updateTrackedPointers_(mapBrowserEvent);
- if (this.handlingDownUpSequence) {
- if (mapBrowserEvent.type == ol.MapBrowserEventType.POINTERDRAG) {
- this.handleDragEvent_(mapBrowserEvent);
- } else if (mapBrowserEvent.type == ol.MapBrowserEventType.POINTERUP) {
- var handledUp = this.handleUpEvent_(mapBrowserEvent);
- this.handlingDownUpSequence = handledUp && this.targetPointers.length > 0;
- }
- } else {
- if (mapBrowserEvent.type == ol.MapBrowserEventType.POINTERDOWN) {
- var handled = this.handleDownEvent_(mapBrowserEvent);
- this.handlingDownUpSequence = handled;
- stopEvent = this.shouldStopEvent(handled);
- } else if (mapBrowserEvent.type == ol.MapBrowserEventType.POINTERMOVE) {
- this.handleMoveEvent_(mapBrowserEvent);
- }
- }
- return !stopEvent;
- };
- /**
- * This method is used to determine if "down" events should be propagated to
- * other interactions or should be stopped.
- *
- * The method receives the return code of the "handleDownEvent" function.
- *
- * By default this function is the "identity" function. It's overidden in
- * child classes.
- *
- * @param {boolean} handled Was the event handled by the interaction?
- * @return {boolean} Should the event be stopped?
- * @protected
- */
- ol.interaction.Pointer.prototype.shouldStopEvent = function(handled) {
- return handled;
- };
- goog.provide('ol.interaction.DragPan');
- goog.require('ol');
- goog.require('ol.ViewHint');
- goog.require('ol.coordinate');
- goog.require('ol.easing');
- goog.require('ol.events.condition');
- goog.require('ol.functions');
- goog.require('ol.interaction.Pointer');
- /**
- * @classdesc
- * Allows the user to pan the map by dragging the map.
- *
- * @constructor
- * @extends {ol.interaction.Pointer}
- * @param {olx.interaction.DragPanOptions=} opt_options Options.
- * @api
- */
- ol.interaction.DragPan = function(opt_options) {
- ol.interaction.Pointer.call(this, {
- handleDownEvent: ol.interaction.DragPan.handleDownEvent_,
- handleDragEvent: ol.interaction.DragPan.handleDragEvent_,
- handleUpEvent: ol.interaction.DragPan.handleUpEvent_
- });
- var options = opt_options ? opt_options : {};
- /**
- * @private
- * @type {ol.Kinetic|undefined}
- */
- this.kinetic_ = options.kinetic;
- /**
- * @type {ol.Pixel}
- */
- this.lastCentroid = null;
- /**
- * @type {number}
- */
- this.lastPointersCount_;
- /**
- * @private
- * @type {ol.EventsConditionType}
- */
- this.condition_ = options.condition ?
- options.condition : ol.events.condition.noModifierKeys;
- /**
- * @private
- * @type {boolean}
- */
- this.noKinetic_ = false;
- };
- ol.inherits(ol.interaction.DragPan, ol.interaction.Pointer);
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @this {ol.interaction.DragPan}
- * @private
- */
- ol.interaction.DragPan.handleDragEvent_ = function(mapBrowserEvent) {
- var targetPointers = this.targetPointers;
- var centroid =
- ol.interaction.Pointer.centroid(targetPointers);
- if (targetPointers.length == this.lastPointersCount_) {
- if (this.kinetic_) {
- this.kinetic_.update(centroid[0], centroid[1]);
- }
- if (this.lastCentroid) {
- var deltaX = this.lastCentroid[0] - centroid[0];
- var deltaY = centroid[1] - this.lastCentroid[1];
- var map = mapBrowserEvent.map;
- var view = map.getView();
- var viewState = view.getState();
- var center = [deltaX, deltaY];
- ol.coordinate.scale(center, viewState.resolution);
- ol.coordinate.rotate(center, viewState.rotation);
- ol.coordinate.add(center, viewState.center);
- center = view.constrainCenter(center);
- view.setCenter(center);
- }
- } else if (this.kinetic_) {
- // reset so we don't overestimate the kinetic energy after
- // after one finger down, tiny drag, second finger down
- this.kinetic_.begin();
- }
- this.lastCentroid = centroid;
- this.lastPointersCount_ = targetPointers.length;
- };
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @return {boolean} Stop drag sequence?
- * @this {ol.interaction.DragPan}
- * @private
- */
- ol.interaction.DragPan.handleUpEvent_ = function(mapBrowserEvent) {
- var map = mapBrowserEvent.map;
- var view = map.getView();
- if (this.targetPointers.length === 0) {
- if (!this.noKinetic_ && this.kinetic_ && this.kinetic_.end()) {
- var distance = this.kinetic_.getDistance();
- var angle = this.kinetic_.getAngle();
- var center = /** @type {!ol.Coordinate} */ (view.getCenter());
- var centerpx = map.getPixelFromCoordinate(center);
- var dest = map.getCoordinateFromPixel([
- centerpx[0] - distance * Math.cos(angle),
- centerpx[1] - distance * Math.sin(angle)
- ]);
- view.animate({
- center: view.constrainCenter(dest),
- duration: 500,
- easing: ol.easing.easeOut
- });
- }
- view.setHint(ol.ViewHint.INTERACTING, -1);
- return false;
- } else {
- if (this.kinetic_) {
- // reset so we don't overestimate the kinetic energy after
- // after one finger up, tiny drag, second finger up
- this.kinetic_.begin();
- }
- this.lastCentroid = null;
- return true;
- }
- };
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @return {boolean} Start drag sequence?
- * @this {ol.interaction.DragPan}
- * @private
- */
- ol.interaction.DragPan.handleDownEvent_ = function(mapBrowserEvent) {
- if (this.targetPointers.length > 0 && this.condition_(mapBrowserEvent)) {
- var map = mapBrowserEvent.map;
- var view = map.getView();
- this.lastCentroid = null;
- if (!this.handlingDownUpSequence) {
- view.setHint(ol.ViewHint.INTERACTING, 1);
- }
- // stop any current animation
- if (view.getAnimating()) {
- view.setCenter(mapBrowserEvent.frameState.viewState.center);
- }
- if (this.kinetic_) {
- this.kinetic_.begin();
- }
- // No kinetic as soon as more than one pointer on the screen is
- // detected. This is to prevent nasty pans after pinch.
- this.noKinetic_ = this.targetPointers.length > 1;
- return true;
- } else {
- return false;
- }
- };
- /**
- * @inheritDoc
- */
- ol.interaction.DragPan.prototype.shouldStopEvent = ol.functions.FALSE;
- goog.provide('ol.interaction.DragRotate');
- goog.require('ol');
- goog.require('ol.RotationConstraint');
- goog.require('ol.ViewHint');
- goog.require('ol.events.condition');
- goog.require('ol.functions');
- goog.require('ol.interaction.Interaction');
- goog.require('ol.interaction.Pointer');
- /**
- * @classdesc
- * Allows the user to rotate the map by clicking and dragging on the map,
- * normally combined with an {@link ol.events.condition} that limits
- * it to when the alt and shift keys are held down.
- *
- * This interaction is only supported for mouse devices.
- *
- * @constructor
- * @extends {ol.interaction.Pointer}
- * @param {olx.interaction.DragRotateOptions=} opt_options Options.
- * @api
- */
- ol.interaction.DragRotate = function(opt_options) {
- var options = opt_options ? opt_options : {};
- ol.interaction.Pointer.call(this, {
- handleDownEvent: ol.interaction.DragRotate.handleDownEvent_,
- handleDragEvent: ol.interaction.DragRotate.handleDragEvent_,
- handleUpEvent: ol.interaction.DragRotate.handleUpEvent_
- });
- /**
- * @private
- * @type {ol.EventsConditionType}
- */
- this.condition_ = options.condition ?
- options.condition : ol.events.condition.altShiftKeysOnly;
- /**
- * @private
- * @type {number|undefined}
- */
- this.lastAngle_ = undefined;
- /**
- * @private
- * @type {number}
- */
- this.duration_ = options.duration !== undefined ? options.duration : 250;
- };
- ol.inherits(ol.interaction.DragRotate, ol.interaction.Pointer);
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @this {ol.interaction.DragRotate}
- * @private
- */
- ol.interaction.DragRotate.handleDragEvent_ = function(mapBrowserEvent) {
- if (!ol.events.condition.mouseOnly(mapBrowserEvent)) {
- return;
- }
- var map = mapBrowserEvent.map;
- var view = map.getView();
- if (view.getConstraints().rotation === ol.RotationConstraint.disable) {
- return;
- }
- var size = map.getSize();
- var offset = mapBrowserEvent.pixel;
- var theta =
- Math.atan2(size[1] / 2 - offset[1], offset[0] - size[0] / 2);
- if (this.lastAngle_ !== undefined) {
- var delta = theta - this.lastAngle_;
- var rotation = view.getRotation();
- ol.interaction.Interaction.rotateWithoutConstraints(
- view, rotation - delta);
- }
- this.lastAngle_ = theta;
- };
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @return {boolean} Stop drag sequence?
- * @this {ol.interaction.DragRotate}
- * @private
- */
- ol.interaction.DragRotate.handleUpEvent_ = function(mapBrowserEvent) {
- if (!ol.events.condition.mouseOnly(mapBrowserEvent)) {
- return true;
- }
- var map = mapBrowserEvent.map;
- var view = map.getView();
- view.setHint(ol.ViewHint.INTERACTING, -1);
- var rotation = view.getRotation();
- ol.interaction.Interaction.rotate(view, rotation,
- undefined, this.duration_);
- return false;
- };
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @return {boolean} Start drag sequence?
- * @this {ol.interaction.DragRotate}
- * @private
- */
- ol.interaction.DragRotate.handleDownEvent_ = function(mapBrowserEvent) {
- if (!ol.events.condition.mouseOnly(mapBrowserEvent)) {
- return false;
- }
- if (ol.events.condition.mouseActionButton(mapBrowserEvent) &&
- this.condition_(mapBrowserEvent)) {
- var map = mapBrowserEvent.map;
- map.getView().setHint(ol.ViewHint.INTERACTING, 1);
- this.lastAngle_ = undefined;
- return true;
- } else {
- return false;
- }
- };
- /**
- * @inheritDoc
- */
- ol.interaction.DragRotate.prototype.shouldStopEvent = ol.functions.FALSE;
- // FIXME add rotation
- goog.provide('ol.render.Box');
- goog.require('ol');
- goog.require('ol.Disposable');
- goog.require('ol.geom.Polygon');
- /**
- * @constructor
- * @extends {ol.Disposable}
- * @param {string} className CSS class name.
- */
- ol.render.Box = function(className) {
- /**
- * @type {ol.geom.Polygon}
- * @private
- */
- this.geometry_ = null;
- /**
- * @type {HTMLDivElement}
- * @private
- */
- this.element_ = /** @type {HTMLDivElement} */ (document.createElement('div'));
- this.element_.style.position = 'absolute';
- this.element_.className = 'ol-box ' + className;
- /**
- * @private
- * @type {ol.PluggableMap}
- */
- this.map_ = null;
- /**
- * @private
- * @type {ol.Pixel}
- */
- this.startPixel_ = null;
- /**
- * @private
- * @type {ol.Pixel}
- */
- this.endPixel_ = null;
- };
- ol.inherits(ol.render.Box, ol.Disposable);
- /**
- * @inheritDoc
- */
- ol.render.Box.prototype.disposeInternal = function() {
- this.setMap(null);
- };
- /**
- * @private
- */
- ol.render.Box.prototype.render_ = function() {
- var startPixel = this.startPixel_;
- var endPixel = this.endPixel_;
- var px = 'px';
- var style = this.element_.style;
- style.left = Math.min(startPixel[0], endPixel[0]) + px;
- style.top = Math.min(startPixel[1], endPixel[1]) + px;
- style.width = Math.abs(endPixel[0] - startPixel[0]) + px;
- style.height = Math.abs(endPixel[1] - startPixel[1]) + px;
- };
- /**
- * @param {ol.PluggableMap} map Map.
- */
- ol.render.Box.prototype.setMap = function(map) {
- if (this.map_) {
- this.map_.getOverlayContainer().removeChild(this.element_);
- var style = this.element_.style;
- style.left = style.top = style.width = style.height = 'inherit';
- }
- this.map_ = map;
- if (this.map_) {
- this.map_.getOverlayContainer().appendChild(this.element_);
- }
- };
- /**
- * @param {ol.Pixel} startPixel Start pixel.
- * @param {ol.Pixel} endPixel End pixel.
- */
- ol.render.Box.prototype.setPixels = function(startPixel, endPixel) {
- this.startPixel_ = startPixel;
- this.endPixel_ = endPixel;
- this.createOrUpdateGeometry();
- this.render_();
- };
- /**
- * Creates or updates the cached geometry.
- */
- ol.render.Box.prototype.createOrUpdateGeometry = function() {
- var startPixel = this.startPixel_;
- var endPixel = this.endPixel_;
- var pixels = [
- startPixel,
- [startPixel[0], endPixel[1]],
- endPixel,
- [endPixel[0], startPixel[1]]
- ];
- var coordinates = pixels.map(this.map_.getCoordinateFromPixel, this.map_);
- // close the polygon
- coordinates[4] = coordinates[0].slice();
- if (!this.geometry_) {
- this.geometry_ = new ol.geom.Polygon([coordinates]);
- } else {
- this.geometry_.setCoordinates([coordinates]);
- }
- };
- /**
- * @return {ol.geom.Polygon} Geometry.
- */
- ol.render.Box.prototype.getGeometry = function() {
- return this.geometry_;
- };
- // FIXME draw drag box
- goog.provide('ol.interaction.DragBox');
- goog.require('ol.events.Event');
- goog.require('ol');
- goog.require('ol.events.condition');
- goog.require('ol.interaction.Pointer');
- goog.require('ol.render.Box');
- /**
- * @classdesc
- * Allows the user to draw a vector box by clicking and dragging on the map,
- * normally combined with an {@link ol.events.condition} that limits
- * it to when the shift or other key is held down. This is used, for example,
- * for zooming to a specific area of the map
- * (see {@link ol.interaction.DragZoom} and
- * {@link ol.interaction.DragRotateAndZoom}).
- *
- * This interaction is only supported for mouse devices.
- *
- * @constructor
- * @extends {ol.interaction.Pointer}
- * @fires ol.interaction.DragBox.Event
- * @param {olx.interaction.DragBoxOptions=} opt_options Options.
- * @api
- */
- ol.interaction.DragBox = function(opt_options) {
- ol.interaction.Pointer.call(this, {
- handleDownEvent: ol.interaction.DragBox.handleDownEvent_,
- handleDragEvent: ol.interaction.DragBox.handleDragEvent_,
- handleUpEvent: ol.interaction.DragBox.handleUpEvent_
- });
- var options = opt_options ? opt_options : {};
- /**
- * @type {ol.render.Box}
- * @private
- */
- this.box_ = new ol.render.Box(options.className || 'ol-dragbox');
- /**
- * @type {number}
- * @private
- */
- this.minArea_ = options.minArea !== undefined ? options.minArea : 64;
- /**
- * @type {ol.Pixel}
- * @private
- */
- this.startPixel_ = null;
- /**
- * @private
- * @type {ol.EventsConditionType}
- */
- this.condition_ = options.condition ?
- options.condition : ol.events.condition.always;
- /**
- * @private
- * @type {ol.DragBoxEndConditionType}
- */
- this.boxEndCondition_ = options.boxEndCondition ?
- options.boxEndCondition : ol.interaction.DragBox.defaultBoxEndCondition;
- };
- ol.inherits(ol.interaction.DragBox, ol.interaction.Pointer);
- /**
- * The default condition for determining whether the boxend event
- * should fire.
- * @param {ol.MapBrowserEvent} mapBrowserEvent The originating MapBrowserEvent
- * leading to the box end.
- * @param {ol.Pixel} startPixel The starting pixel of the box.
- * @param {ol.Pixel} endPixel The end pixel of the box.
- * @return {boolean} Whether or not the boxend condition should be fired.
- * @this {ol.interaction.DragBox}
- */
- ol.interaction.DragBox.defaultBoxEndCondition = function(mapBrowserEvent, startPixel, endPixel) {
- var width = endPixel[0] - startPixel[0];
- var height = endPixel[1] - startPixel[1];
- return width * width + height * height >= this.minArea_;
- };
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @this {ol.interaction.DragBox}
- * @private
- */
- ol.interaction.DragBox.handleDragEvent_ = function(mapBrowserEvent) {
- if (!ol.events.condition.mouseOnly(mapBrowserEvent)) {
- return;
- }
- this.box_.setPixels(this.startPixel_, mapBrowserEvent.pixel);
- this.dispatchEvent(new ol.interaction.DragBox.Event(ol.interaction.DragBox.EventType_.BOXDRAG,
- mapBrowserEvent.coordinate, mapBrowserEvent));
- };
- /**
- * Returns geometry of last drawn box.
- * @return {ol.geom.Polygon} Geometry.
- * @api
- */
- ol.interaction.DragBox.prototype.getGeometry = function() {
- return this.box_.getGeometry();
- };
- /**
- * To be overridden by child classes.
- * FIXME: use constructor option instead of relying on overriding.
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @protected
- */
- ol.interaction.DragBox.prototype.onBoxEnd = ol.nullFunction;
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @return {boolean} Stop drag sequence?
- * @this {ol.interaction.DragBox}
- * @private
- */
- ol.interaction.DragBox.handleUpEvent_ = function(mapBrowserEvent) {
- if (!ol.events.condition.mouseOnly(mapBrowserEvent)) {
- return true;
- }
- this.box_.setMap(null);
- if (this.boxEndCondition_(mapBrowserEvent,
- this.startPixel_, mapBrowserEvent.pixel)) {
- this.onBoxEnd(mapBrowserEvent);
- this.dispatchEvent(new ol.interaction.DragBox.Event(ol.interaction.DragBox.EventType_.BOXEND,
- mapBrowserEvent.coordinate, mapBrowserEvent));
- }
- return false;
- };
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @return {boolean} Start drag sequence?
- * @this {ol.interaction.DragBox}
- * @private
- */
- ol.interaction.DragBox.handleDownEvent_ = function(mapBrowserEvent) {
- if (!ol.events.condition.mouseOnly(mapBrowserEvent)) {
- return false;
- }
- if (ol.events.condition.mouseActionButton(mapBrowserEvent) &&
- this.condition_(mapBrowserEvent)) {
- this.startPixel_ = mapBrowserEvent.pixel;
- this.box_.setMap(mapBrowserEvent.map);
- this.box_.setPixels(this.startPixel_, this.startPixel_);
- this.dispatchEvent(new ol.interaction.DragBox.Event(ol.interaction.DragBox.EventType_.BOXSTART,
- mapBrowserEvent.coordinate, mapBrowserEvent));
- return true;
- } else {
- return false;
- }
- };
- /**
- * @enum {string}
- * @private
- */
- ol.interaction.DragBox.EventType_ = {
- /**
- * Triggered upon drag box start.
- * @event ol.interaction.DragBox.Event#boxstart
- * @api
- */
- BOXSTART: 'boxstart',
- /**
- * Triggered on drag when box is active.
- * @event ol.interaction.DragBox.Event#boxdrag
- * @api
- */
- BOXDRAG: 'boxdrag',
- /**
- * Triggered upon drag box end.
- * @event ol.interaction.DragBox.Event#boxend
- * @api
- */
- BOXEND: 'boxend'
- };
- /**
- * @classdesc
- * Events emitted by {@link ol.interaction.DragBox} instances are instances of
- * this type.
- *
- * @param {string} type The event type.
- * @param {ol.Coordinate} coordinate The event coordinate.
- * @param {ol.MapBrowserEvent} mapBrowserEvent Originating event.
- * @extends {ol.events.Event}
- * @constructor
- * @implements {oli.DragBoxEvent}
- */
- ol.interaction.DragBox.Event = function(type, coordinate, mapBrowserEvent) {
- ol.events.Event.call(this, type);
- /**
- * The coordinate of the drag event.
- * @const
- * @type {ol.Coordinate}
- * @api
- */
- this.coordinate = coordinate;
- /**
- * @const
- * @type {ol.MapBrowserEvent}
- * @api
- */
- this.mapBrowserEvent = mapBrowserEvent;
- };
- ol.inherits(ol.interaction.DragBox.Event, ol.events.Event);
- goog.provide('ol.interaction.DragZoom');
- goog.require('ol');
- goog.require('ol.easing');
- goog.require('ol.events.condition');
- goog.require('ol.extent');
- goog.require('ol.interaction.DragBox');
- /**
- * @classdesc
- * Allows the user to zoom the map by clicking and dragging on the map,
- * normally combined with an {@link ol.events.condition} that limits
- * it to when a key, shift by default, is held down.
- *
- * To change the style of the box, use CSS and the `.ol-dragzoom` selector, or
- * your custom one configured with `className`.
- *
- * @constructor
- * @extends {ol.interaction.DragBox}
- * @param {olx.interaction.DragZoomOptions=} opt_options Options.
- * @api
- */
- ol.interaction.DragZoom = function(opt_options) {
- var options = opt_options ? opt_options : {};
- var condition = options.condition ?
- options.condition : ol.events.condition.shiftKeyOnly;
- /**
- * @private
- * @type {number}
- */
- this.duration_ = options.duration !== undefined ? options.duration : 200;
- /**
- * @private
- * @type {boolean}
- */
- this.out_ = options.out !== undefined ? options.out : false;
- ol.interaction.DragBox.call(this, {
- condition: condition,
- className: options.className || 'ol-dragzoom'
- });
- };
- ol.inherits(ol.interaction.DragZoom, ol.interaction.DragBox);
- /**
- * @inheritDoc
- */
- ol.interaction.DragZoom.prototype.onBoxEnd = function() {
- var map = this.getMap();
- var view = /** @type {!ol.View} */ (map.getView());
- var size = /** @type {!ol.Size} */ (map.getSize());
- var extent = this.getGeometry().getExtent();
- if (this.out_) {
- var mapExtent = view.calculateExtent(size);
- var boxPixelExtent = ol.extent.createOrUpdateFromCoordinates([
- map.getPixelFromCoordinate(ol.extent.getBottomLeft(extent)),
- map.getPixelFromCoordinate(ol.extent.getTopRight(extent))]);
- var factor = view.getResolutionForExtent(boxPixelExtent, size);
- ol.extent.scaleFromCenter(mapExtent, 1 / factor);
- extent = mapExtent;
- }
- var resolution = view.constrainResolution(
- view.getResolutionForExtent(extent, size));
- var center = ol.extent.getCenter(extent);
- center = view.constrainCenter(center);
- view.animate({
- resolution: resolution,
- center: center,
- duration: this.duration_,
- easing: ol.easing.easeOut
- });
- };
- goog.provide('ol.events.KeyCode');
- /**
- * @enum {number}
- * @const
- */
- ol.events.KeyCode = {
- LEFT: 37,
- UP: 38,
- RIGHT: 39,
- DOWN: 40
- };
- goog.provide('ol.interaction.KeyboardPan');
- goog.require('ol');
- goog.require('ol.coordinate');
- goog.require('ol.events.EventType');
- goog.require('ol.events.KeyCode');
- goog.require('ol.events.condition');
- goog.require('ol.interaction.Interaction');
- /**
- * @classdesc
- * Allows the user to pan the map using keyboard arrows.
- * Note that, although this interaction is by default included in maps,
- * the keys can only be used when browser focus is on the element to which
- * the keyboard events are attached. By default, this is the map div,
- * though you can change this with the `keyboardEventTarget` in
- * {@link ol.Map}. `document` never loses focus but, for any other element,
- * focus will have to be on, and returned to, this element if the keys are to
- * function.
- * See also {@link ol.interaction.KeyboardZoom}.
- *
- * @constructor
- * @extends {ol.interaction.Interaction}
- * @param {olx.interaction.KeyboardPanOptions=} opt_options Options.
- * @api
- */
- ol.interaction.KeyboardPan = function(opt_options) {
- ol.interaction.Interaction.call(this, {
- handleEvent: ol.interaction.KeyboardPan.handleEvent
- });
- var options = opt_options || {};
- /**
- * @private
- * @param {ol.MapBrowserEvent} mapBrowserEvent Browser event.
- * @return {boolean} Combined condition result.
- */
- this.defaultCondition_ = function(mapBrowserEvent) {
- return ol.events.condition.noModifierKeys(mapBrowserEvent) &&
- ol.events.condition.targetNotEditable(mapBrowserEvent);
- };
- /**
- * @private
- * @type {ol.EventsConditionType}
- */
- this.condition_ = options.condition !== undefined ?
- options.condition : this.defaultCondition_;
- /**
- * @private
- * @type {number}
- */
- this.duration_ = options.duration !== undefined ? options.duration : 100;
- /**
- * @private
- * @type {number}
- */
- this.pixelDelta_ = options.pixelDelta !== undefined ?
- options.pixelDelta : 128;
- };
- ol.inherits(ol.interaction.KeyboardPan, ol.interaction.Interaction);
- /**
- * Handles the {@link ol.MapBrowserEvent map browser event} if it was a
- * `KeyEvent`, and decides the direction to pan to (if an arrow key was
- * pressed).
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} `false` to stop event propagation.
- * @this {ol.interaction.KeyboardPan}
- * @api
- */
- ol.interaction.KeyboardPan.handleEvent = function(mapBrowserEvent) {
- var stopEvent = false;
- if (mapBrowserEvent.type == ol.events.EventType.KEYDOWN) {
- var keyEvent = mapBrowserEvent.originalEvent;
- var keyCode = keyEvent.keyCode;
- if (this.condition_(mapBrowserEvent) &&
- (keyCode == ol.events.KeyCode.DOWN ||
- keyCode == ol.events.KeyCode.LEFT ||
- keyCode == ol.events.KeyCode.RIGHT ||
- keyCode == ol.events.KeyCode.UP)) {
- var map = mapBrowserEvent.map;
- var view = map.getView();
- var mapUnitsDelta = view.getResolution() * this.pixelDelta_;
- var deltaX = 0, deltaY = 0;
- if (keyCode == ol.events.KeyCode.DOWN) {
- deltaY = -mapUnitsDelta;
- } else if (keyCode == ol.events.KeyCode.LEFT) {
- deltaX = -mapUnitsDelta;
- } else if (keyCode == ol.events.KeyCode.RIGHT) {
- deltaX = mapUnitsDelta;
- } else {
- deltaY = mapUnitsDelta;
- }
- var delta = [deltaX, deltaY];
- ol.coordinate.rotate(delta, view.getRotation());
- ol.interaction.Interaction.pan(view, delta, this.duration_);
- mapBrowserEvent.preventDefault();
- stopEvent = true;
- }
- }
- return !stopEvent;
- };
- goog.provide('ol.interaction.KeyboardZoom');
- goog.require('ol');
- goog.require('ol.events.EventType');
- goog.require('ol.events.condition');
- goog.require('ol.interaction.Interaction');
- /**
- * @classdesc
- * Allows the user to zoom the map using keyboard + and -.
- * Note that, although this interaction is by default included in maps,
- * the keys can only be used when browser focus is on the element to which
- * the keyboard events are attached. By default, this is the map div,
- * though you can change this with the `keyboardEventTarget` in
- * {@link ol.Map}. `document` never loses focus but, for any other element,
- * focus will have to be on, and returned to, this element if the keys are to
- * function.
- * See also {@link ol.interaction.KeyboardPan}.
- *
- * @constructor
- * @param {olx.interaction.KeyboardZoomOptions=} opt_options Options.
- * @extends {ol.interaction.Interaction}
- * @api
- */
- ol.interaction.KeyboardZoom = function(opt_options) {
- ol.interaction.Interaction.call(this, {
- handleEvent: ol.interaction.KeyboardZoom.handleEvent
- });
- var options = opt_options ? opt_options : {};
- /**
- * @private
- * @type {ol.EventsConditionType}
- */
- this.condition_ = options.condition ? options.condition :
- ol.events.condition.targetNotEditable;
- /**
- * @private
- * @type {number}
- */
- this.delta_ = options.delta ? options.delta : 1;
- /**
- * @private
- * @type {number}
- */
- this.duration_ = options.duration !== undefined ? options.duration : 100;
- };
- ol.inherits(ol.interaction.KeyboardZoom, ol.interaction.Interaction);
- /**
- * Handles the {@link ol.MapBrowserEvent map browser event} if it was a
- * `KeyEvent`, and decides whether to zoom in or out (depending on whether the
- * key pressed was '+' or '-').
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} `false` to stop event propagation.
- * @this {ol.interaction.KeyboardZoom}
- * @api
- */
- ol.interaction.KeyboardZoom.handleEvent = function(mapBrowserEvent) {
- var stopEvent = false;
- if (mapBrowserEvent.type == ol.events.EventType.KEYDOWN ||
- mapBrowserEvent.type == ol.events.EventType.KEYPRESS) {
- var keyEvent = mapBrowserEvent.originalEvent;
- var charCode = keyEvent.charCode;
- if (this.condition_(mapBrowserEvent) &&
- (charCode == '+'.charCodeAt(0) || charCode == '-'.charCodeAt(0))) {
- var map = mapBrowserEvent.map;
- var delta = (charCode == '+'.charCodeAt(0)) ? this.delta_ : -this.delta_;
- var view = map.getView();
- ol.interaction.Interaction.zoomByDelta(
- view, delta, undefined, this.duration_);
- mapBrowserEvent.preventDefault();
- stopEvent = true;
- }
- }
- return !stopEvent;
- };
- goog.provide('ol.interaction.MouseWheelZoom');
- goog.require('ol');
- goog.require('ol.ViewHint');
- goog.require('ol.easing');
- goog.require('ol.events.EventType');
- goog.require('ol.has');
- goog.require('ol.interaction.Interaction');
- goog.require('ol.math');
- /**
- * @classdesc
- * Allows the user to zoom the map by scrolling the mouse wheel.
- *
- * @constructor
- * @extends {ol.interaction.Interaction}
- * @param {olx.interaction.MouseWheelZoomOptions=} opt_options Options.
- * @api
- */
- ol.interaction.MouseWheelZoom = function(opt_options) {
- ol.interaction.Interaction.call(this, {
- handleEvent: ol.interaction.MouseWheelZoom.handleEvent
- });
- var options = opt_options || {};
- /**
- * @private
- * @type {number}
- */
- this.delta_ = 0;
- /**
- * @private
- * @type {number}
- */
- this.duration_ = options.duration !== undefined ? options.duration : 250;
- /**
- * @private
- * @type {number}
- */
- this.timeout_ = options.timeout !== undefined ? options.timeout : 80;
- /**
- * @private
- * @type {boolean}
- */
- this.useAnchor_ = options.useAnchor !== undefined ? options.useAnchor : true;
- /**
- * @private
- * @type {boolean}
- */
- this.constrainResolution_ = options.constrainResolution || false;
- /**
- * @private
- * @type {?ol.Coordinate}
- */
- this.lastAnchor_ = null;
- /**
- * @private
- * @type {number|undefined}
- */
- this.startTime_ = undefined;
- /**
- * @private
- * @type {number|undefined}
- */
- this.timeoutId_ = undefined;
- /**
- * @private
- * @type {ol.interaction.MouseWheelZoom.Mode_|undefined}
- */
- this.mode_ = undefined;
- /**
- * Trackpad events separated by this delay will be considered separate
- * interactions.
- * @type {number}
- */
- this.trackpadEventGap_ = 400;
- /**
- * @type {number|undefined}
- */
- this.trackpadTimeoutId_ = undefined;
- /**
- * The number of delta values per zoom level
- * @private
- * @type {number}
- */
- this.trackpadDeltaPerZoom_ = 300;
- /**
- * The zoom factor by which scroll zooming is allowed to exceed the limits.
- * @private
- * @type {number}
- */
- this.trackpadZoomBuffer_ = 1.5;
- };
- ol.inherits(ol.interaction.MouseWheelZoom, ol.interaction.Interaction);
- /**
- * Handles the {@link ol.MapBrowserEvent map browser event} (if it was a
- * mousewheel-event) and eventually zooms the map.
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} Allow event propagation.
- * @this {ol.interaction.MouseWheelZoom}
- * @api
- */
- ol.interaction.MouseWheelZoom.handleEvent = function(mapBrowserEvent) {
- var type = mapBrowserEvent.type;
- if (type !== ol.events.EventType.WHEEL && type !== ol.events.EventType.MOUSEWHEEL) {
- return true;
- }
- mapBrowserEvent.preventDefault();
- var map = mapBrowserEvent.map;
- var wheelEvent = /** @type {WheelEvent} */ (mapBrowserEvent.originalEvent);
- if (this.useAnchor_) {
- this.lastAnchor_ = mapBrowserEvent.coordinate;
- }
- // Delta normalisation inspired by
- // https://github.com/mapbox/mapbox-gl-js/blob/001c7b9/js/ui/handler/scroll_zoom.js
- var delta;
- if (mapBrowserEvent.type == ol.events.EventType.WHEEL) {
- delta = wheelEvent.deltaY;
- if (ol.has.FIREFOX &&
- wheelEvent.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {
- delta /= ol.has.DEVICE_PIXEL_RATIO;
- }
- if (wheelEvent.deltaMode === WheelEvent.DOM_DELTA_LINE) {
- delta *= 40;
- }
- } else if (mapBrowserEvent.type == ol.events.EventType.MOUSEWHEEL) {
- delta = -wheelEvent.wheelDeltaY;
- if (ol.has.SAFARI) {
- delta /= 3;
- }
- }
- if (delta === 0) {
- return false;
- }
- var now = Date.now();
- if (this.startTime_ === undefined) {
- this.startTime_ = now;
- }
- if (!this.mode_ || now - this.startTime_ > this.trackpadEventGap_) {
- this.mode_ = Math.abs(delta) < 4 ?
- ol.interaction.MouseWheelZoom.Mode_.TRACKPAD :
- ol.interaction.MouseWheelZoom.Mode_.WHEEL;
- }
- if (this.mode_ === ol.interaction.MouseWheelZoom.Mode_.TRACKPAD) {
- var view = map.getView();
- if (this.trackpadTimeoutId_) {
- clearTimeout(this.trackpadTimeoutId_);
- } else {
- view.setHint(ol.ViewHint.INTERACTING, 1);
- }
- this.trackpadTimeoutId_ = setTimeout(this.decrementInteractingHint_.bind(this), this.trackpadEventGap_);
- var resolution = view.getResolution() * Math.pow(2, delta / this.trackpadDeltaPerZoom_);
- var minResolution = view.getMinResolution();
- var maxResolution = view.getMaxResolution();
- var rebound = 0;
- if (resolution < minResolution) {
- resolution = Math.max(resolution, minResolution / this.trackpadZoomBuffer_);
- rebound = 1;
- } else if (resolution > maxResolution) {
- resolution = Math.min(resolution, maxResolution * this.trackpadZoomBuffer_);
- rebound = -1;
- }
- if (this.lastAnchor_) {
- var center = view.calculateCenterZoom(resolution, this.lastAnchor_);
- view.setCenter(view.constrainCenter(center));
- }
- view.setResolution(resolution);
- if (rebound === 0 && this.constrainResolution_) {
- view.animate({
- resolution: view.constrainResolution(resolution, delta > 0 ? -1 : 1),
- easing: ol.easing.easeOut,
- anchor: this.lastAnchor_,
- duration: this.duration_
- });
- }
- if (rebound > 0) {
- view.animate({
- resolution: minResolution,
- easing: ol.easing.easeOut,
- anchor: this.lastAnchor_,
- duration: 500
- });
- } else if (rebound < 0) {
- view.animate({
- resolution: maxResolution,
- easing: ol.easing.easeOut,
- anchor: this.lastAnchor_,
- duration: 500
- });
- }
- this.startTime_ = now;
- return false;
- }
- this.delta_ += delta;
- var timeLeft = Math.max(this.timeout_ - (now - this.startTime_), 0);
- clearTimeout(this.timeoutId_);
- this.timeoutId_ = setTimeout(this.handleWheelZoom_.bind(this, map), timeLeft);
- return false;
- };
- /**
- * @private
- */
- ol.interaction.MouseWheelZoom.prototype.decrementInteractingHint_ = function() {
- this.trackpadTimeoutId_ = undefined;
- var view = this.getMap().getView();
- view.setHint(ol.ViewHint.INTERACTING, -1);
- };
- /**
- * @private
- * @param {ol.PluggableMap} map Map.
- */
- ol.interaction.MouseWheelZoom.prototype.handleWheelZoom_ = function(map) {
- var view = map.getView();
- if (view.getAnimating()) {
- view.cancelAnimations();
- }
- var maxDelta = ol.MOUSEWHEELZOOM_MAXDELTA;
- var delta = ol.math.clamp(this.delta_, -maxDelta, maxDelta);
- ol.interaction.Interaction.zoomByDelta(view, -delta, this.lastAnchor_,
- this.duration_);
- this.mode_ = undefined;
- this.delta_ = 0;
- this.lastAnchor_ = null;
- this.startTime_ = undefined;
- this.timeoutId_ = undefined;
- };
- /**
- * Enable or disable using the mouse's location as an anchor when zooming
- * @param {boolean} useAnchor true to zoom to the mouse's location, false
- * to zoom to the center of the map
- * @api
- */
- ol.interaction.MouseWheelZoom.prototype.setMouseAnchor = function(useAnchor) {
- this.useAnchor_ = useAnchor;
- if (!useAnchor) {
- this.lastAnchor_ = null;
- }
- };
- /**
- * @enum {string}
- * @private
- */
- ol.interaction.MouseWheelZoom.Mode_ = {
- TRACKPAD: 'trackpad',
- WHEEL: 'wheel'
- };
- goog.provide('ol.interaction.PinchRotate');
- goog.require('ol');
- goog.require('ol.ViewHint');
- goog.require('ol.functions');
- goog.require('ol.interaction.Interaction');
- goog.require('ol.interaction.Pointer');
- goog.require('ol.RotationConstraint');
- /**
- * @classdesc
- * Allows the user to rotate the map by twisting with two fingers
- * on a touch screen.
- *
- * @constructor
- * @extends {ol.interaction.Pointer}
- * @param {olx.interaction.PinchRotateOptions=} opt_options Options.
- * @api
- */
- ol.interaction.PinchRotate = function(opt_options) {
- ol.interaction.Pointer.call(this, {
- handleDownEvent: ol.interaction.PinchRotate.handleDownEvent_,
- handleDragEvent: ol.interaction.PinchRotate.handleDragEvent_,
- handleUpEvent: ol.interaction.PinchRotate.handleUpEvent_
- });
- var options = opt_options || {};
- /**
- * @private
- * @type {ol.Coordinate}
- */
- this.anchor_ = null;
- /**
- * @private
- * @type {number|undefined}
- */
- this.lastAngle_ = undefined;
- /**
- * @private
- * @type {boolean}
- */
- this.rotating_ = false;
- /**
- * @private
- * @type {number}
- */
- this.rotationDelta_ = 0.0;
- /**
- * @private
- * @type {number}
- */
- this.threshold_ = options.threshold !== undefined ? options.threshold : 0.3;
- /**
- * @private
- * @type {number}
- */
- this.duration_ = options.duration !== undefined ? options.duration : 250;
- };
- ol.inherits(ol.interaction.PinchRotate, ol.interaction.Pointer);
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @this {ol.interaction.PinchRotate}
- * @private
- */
- ol.interaction.PinchRotate.handleDragEvent_ = function(mapBrowserEvent) {
- var rotationDelta = 0.0;
- var touch0 = this.targetPointers[0];
- var touch1 = this.targetPointers[1];
- // angle between touches
- var angle = Math.atan2(
- touch1.clientY - touch0.clientY,
- touch1.clientX - touch0.clientX);
- if (this.lastAngle_ !== undefined) {
- var delta = angle - this.lastAngle_;
- this.rotationDelta_ += delta;
- if (!this.rotating_ &&
- Math.abs(this.rotationDelta_) > this.threshold_) {
- this.rotating_ = true;
- }
- rotationDelta = delta;
- }
- this.lastAngle_ = angle;
- var map = mapBrowserEvent.map;
- var view = map.getView();
- if (view.getConstraints().rotation === ol.RotationConstraint.disable) {
- return;
- }
- // rotate anchor point.
- // FIXME: should be the intersection point between the lines:
- // touch0,touch1 and previousTouch0,previousTouch1
- var viewportPosition = map.getViewport().getBoundingClientRect();
- var centroid = ol.interaction.Pointer.centroid(this.targetPointers);
- centroid[0] -= viewportPosition.left;
- centroid[1] -= viewportPosition.top;
- this.anchor_ = map.getCoordinateFromPixel(centroid);
- // rotate
- if (this.rotating_) {
- var rotation = view.getRotation();
- map.render();
- ol.interaction.Interaction.rotateWithoutConstraints(view,
- rotation + rotationDelta, this.anchor_);
- }
- };
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @return {boolean} Stop drag sequence?
- * @this {ol.interaction.PinchRotate}
- * @private
- */
- ol.interaction.PinchRotate.handleUpEvent_ = function(mapBrowserEvent) {
- if (this.targetPointers.length < 2) {
- var map = mapBrowserEvent.map;
- var view = map.getView();
- view.setHint(ol.ViewHint.INTERACTING, -1);
- if (this.rotating_) {
- var rotation = view.getRotation();
- ol.interaction.Interaction.rotate(
- view, rotation, this.anchor_, this.duration_);
- }
- return false;
- } else {
- return true;
- }
- };
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @return {boolean} Start drag sequence?
- * @this {ol.interaction.PinchRotate}
- * @private
- */
- ol.interaction.PinchRotate.handleDownEvent_ = function(mapBrowserEvent) {
- if (this.targetPointers.length >= 2) {
- var map = mapBrowserEvent.map;
- this.anchor_ = null;
- this.lastAngle_ = undefined;
- this.rotating_ = false;
- this.rotationDelta_ = 0.0;
- if (!this.handlingDownUpSequence) {
- map.getView().setHint(ol.ViewHint.INTERACTING, 1);
- }
- return true;
- } else {
- return false;
- }
- };
- /**
- * @inheritDoc
- */
- ol.interaction.PinchRotate.prototype.shouldStopEvent = ol.functions.FALSE;
- goog.provide('ol.interaction.PinchZoom');
- goog.require('ol');
- goog.require('ol.ViewHint');
- goog.require('ol.functions');
- goog.require('ol.interaction.Interaction');
- goog.require('ol.interaction.Pointer');
- /**
- * @classdesc
- * Allows the user to zoom the map by pinching with two fingers
- * on a touch screen.
- *
- * @constructor
- * @extends {ol.interaction.Pointer}
- * @param {olx.interaction.PinchZoomOptions=} opt_options Options.
- * @api
- */
- ol.interaction.PinchZoom = function(opt_options) {
- ol.interaction.Pointer.call(this, {
- handleDownEvent: ol.interaction.PinchZoom.handleDownEvent_,
- handleDragEvent: ol.interaction.PinchZoom.handleDragEvent_,
- handleUpEvent: ol.interaction.PinchZoom.handleUpEvent_
- });
- var options = opt_options ? opt_options : {};
- /**
- * @private
- * @type {boolean}
- */
- this.constrainResolution_ = options.constrainResolution || false;
- /**
- * @private
- * @type {ol.Coordinate}
- */
- this.anchor_ = null;
- /**
- * @private
- * @type {number}
- */
- this.duration_ = options.duration !== undefined ? options.duration : 400;
- /**
- * @private
- * @type {number|undefined}
- */
- this.lastDistance_ = undefined;
- /**
- * @private
- * @type {number}
- */
- this.lastScaleDelta_ = 1;
- };
- ol.inherits(ol.interaction.PinchZoom, ol.interaction.Pointer);
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @this {ol.interaction.PinchZoom}
- * @private
- */
- ol.interaction.PinchZoom.handleDragEvent_ = function(mapBrowserEvent) {
- var scaleDelta = 1.0;
- var touch0 = this.targetPointers[0];
- var touch1 = this.targetPointers[1];
- var dx = touch0.clientX - touch1.clientX;
- var dy = touch0.clientY - touch1.clientY;
- // distance between touches
- var distance = Math.sqrt(dx * dx + dy * dy);
- if (this.lastDistance_ !== undefined) {
- scaleDelta = this.lastDistance_ / distance;
- }
- this.lastDistance_ = distance;
- var map = mapBrowserEvent.map;
- var view = map.getView();
- var resolution = view.getResolution();
- var maxResolution = view.getMaxResolution();
- var minResolution = view.getMinResolution();
- var newResolution = resolution * scaleDelta;
- if (newResolution > maxResolution) {
- scaleDelta = maxResolution / resolution;
- newResolution = maxResolution;
- } else if (newResolution < minResolution) {
- scaleDelta = minResolution / resolution;
- newResolution = minResolution;
- }
- if (scaleDelta != 1.0) {
- this.lastScaleDelta_ = scaleDelta;
- }
- // scale anchor point.
- var viewportPosition = map.getViewport().getBoundingClientRect();
- var centroid = ol.interaction.Pointer.centroid(this.targetPointers);
- centroid[0] -= viewportPosition.left;
- centroid[1] -= viewportPosition.top;
- this.anchor_ = map.getCoordinateFromPixel(centroid);
- // scale, bypass the resolution constraint
- map.render();
- ol.interaction.Interaction.zoomWithoutConstraints(view, newResolution, this.anchor_);
- };
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @return {boolean} Stop drag sequence?
- * @this {ol.interaction.PinchZoom}
- * @private
- */
- ol.interaction.PinchZoom.handleUpEvent_ = function(mapBrowserEvent) {
- if (this.targetPointers.length < 2) {
- var map = mapBrowserEvent.map;
- var view = map.getView();
- view.setHint(ol.ViewHint.INTERACTING, -1);
- var resolution = view.getResolution();
- if (this.constrainResolution_ ||
- resolution < view.getMinResolution() ||
- resolution > view.getMaxResolution()) {
- // Zoom to final resolution, with an animation, and provide a
- // direction not to zoom out/in if user was pinching in/out.
- // Direction is > 0 if pinching out, and < 0 if pinching in.
- var direction = this.lastScaleDelta_ - 1;
- ol.interaction.Interaction.zoom(view, resolution,
- this.anchor_, this.duration_, direction);
- }
- return false;
- } else {
- return true;
- }
- };
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @return {boolean} Start drag sequence?
- * @this {ol.interaction.PinchZoom}
- * @private
- */
- ol.interaction.PinchZoom.handleDownEvent_ = function(mapBrowserEvent) {
- if (this.targetPointers.length >= 2) {
- var map = mapBrowserEvent.map;
- this.anchor_ = null;
- this.lastDistance_ = undefined;
- this.lastScaleDelta_ = 1;
- if (!this.handlingDownUpSequence) {
- map.getView().setHint(ol.ViewHint.INTERACTING, 1);
- }
- return true;
- } else {
- return false;
- }
- };
- /**
- * @inheritDoc
- */
- ol.interaction.PinchZoom.prototype.shouldStopEvent = ol.functions.FALSE;
- goog.provide('ol.interaction');
- goog.require('ol.Collection');
- goog.require('ol.Kinetic');
- goog.require('ol.interaction.DoubleClickZoom');
- goog.require('ol.interaction.DragPan');
- goog.require('ol.interaction.DragRotate');
- goog.require('ol.interaction.DragZoom');
- goog.require('ol.interaction.KeyboardPan');
- goog.require('ol.interaction.KeyboardZoom');
- goog.require('ol.interaction.MouseWheelZoom');
- goog.require('ol.interaction.PinchRotate');
- goog.require('ol.interaction.PinchZoom');
- /**
- * Set of interactions included in maps by default. Specific interactions can be
- * excluded by setting the appropriate option to false in the constructor
- * options, but the order of the interactions is fixed. If you want to specify
- * a different order for interactions, you will need to create your own
- * {@link ol.interaction.Interaction} instances and insert them into a
- * {@link ol.Collection} in the order you want before creating your
- * {@link ol.Map} instance. The default set of interactions, in sequence, is:
- * * {@link ol.interaction.DragRotate}
- * * {@link ol.interaction.DoubleClickZoom}
- * * {@link ol.interaction.DragPan}
- * * {@link ol.interaction.PinchRotate}
- * * {@link ol.interaction.PinchZoom}
- * * {@link ol.interaction.KeyboardPan}
- * * {@link ol.interaction.KeyboardZoom}
- * * {@link ol.interaction.MouseWheelZoom}
- * * {@link ol.interaction.DragZoom}
- *
- * @param {olx.interaction.DefaultsOptions=} opt_options Defaults options.
- * @return {ol.Collection.<ol.interaction.Interaction>} A collection of
- * interactions to be used with the ol.Map constructor's interactions option.
- * @api
- */
- ol.interaction.defaults = function(opt_options) {
- var options = opt_options ? opt_options : {};
- var interactions = new ol.Collection();
- var kinetic = new ol.Kinetic(-0.005, 0.05, 100);
- var altShiftDragRotate = options.altShiftDragRotate !== undefined ?
- options.altShiftDragRotate : true;
- if (altShiftDragRotate) {
- interactions.push(new ol.interaction.DragRotate());
- }
- var doubleClickZoom = options.doubleClickZoom !== undefined ?
- options.doubleClickZoom : true;
- if (doubleClickZoom) {
- interactions.push(new ol.interaction.DoubleClickZoom({
- delta: options.zoomDelta,
- duration: options.zoomDuration
- }));
- }
- var dragPan = options.dragPan !== undefined ? options.dragPan : true;
- if (dragPan) {
- interactions.push(new ol.interaction.DragPan({
- kinetic: kinetic
- }));
- }
- var pinchRotate = options.pinchRotate !== undefined ? options.pinchRotate :
- true;
- if (pinchRotate) {
- interactions.push(new ol.interaction.PinchRotate());
- }
- var pinchZoom = options.pinchZoom !== undefined ? options.pinchZoom : true;
- if (pinchZoom) {
- interactions.push(new ol.interaction.PinchZoom({
- constrainResolution: options.constrainResolution,
- duration: options.zoomDuration
- }));
- }
- var keyboard = options.keyboard !== undefined ? options.keyboard : true;
- if (keyboard) {
- interactions.push(new ol.interaction.KeyboardPan());
- interactions.push(new ol.interaction.KeyboardZoom({
- delta: options.zoomDelta,
- duration: options.zoomDuration
- }));
- }
- var mouseWheelZoom = options.mouseWheelZoom !== undefined ?
- options.mouseWheelZoom : true;
- if (mouseWheelZoom) {
- interactions.push(new ol.interaction.MouseWheelZoom({
- constrainResolution: options.constrainResolution,
- duration: options.zoomDuration
- }));
- }
- var shiftDragZoom = options.shiftDragZoom !== undefined ?
- options.shiftDragZoom : true;
- if (shiftDragZoom) {
- interactions.push(new ol.interaction.DragZoom({
- duration: options.zoomDuration
- }));
- }
- return interactions;
- };
- goog.provide('ol.ImageBase');
- goog.require('ol');
- goog.require('ol.events.EventTarget');
- goog.require('ol.events.EventType');
- /**
- * @constructor
- * @abstract
- * @extends {ol.events.EventTarget}
- * @param {ol.Extent} extent Extent.
- * @param {number|undefined} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.ImageState} state State.
- */
- ol.ImageBase = function(extent, resolution, pixelRatio, state) {
- ol.events.EventTarget.call(this);
- /**
- * @protected
- * @type {ol.Extent}
- */
- this.extent = extent;
- /**
- * @private
- * @type {number}
- */
- this.pixelRatio_ = pixelRatio;
- /**
- * @protected
- * @type {number|undefined}
- */
- this.resolution = resolution;
- /**
- * @protected
- * @type {ol.ImageState}
- */
- this.state = state;
- };
- ol.inherits(ol.ImageBase, ol.events.EventTarget);
- /**
- * @protected
- */
- ol.ImageBase.prototype.changed = function() {
- this.dispatchEvent(ol.events.EventType.CHANGE);
- };
- /**
- * @return {ol.Extent} Extent.
- */
- ol.ImageBase.prototype.getExtent = function() {
- return this.extent;
- };
- /**
- * @abstract
- * @return {HTMLCanvasElement|Image|HTMLVideoElement} Image.
- */
- ol.ImageBase.prototype.getImage = function() {};
- /**
- * @return {number} PixelRatio.
- */
- ol.ImageBase.prototype.getPixelRatio = function() {
- return this.pixelRatio_;
- };
- /**
- * @return {number} Resolution.
- */
- ol.ImageBase.prototype.getResolution = function() {
- return /** @type {number} */ (this.resolution);
- };
- /**
- * @return {ol.ImageState} State.
- */
- ol.ImageBase.prototype.getState = function() {
- return this.state;
- };
- /**
- * Load not yet loaded URI.
- * @abstract
- */
- ol.ImageBase.prototype.load = function() {};
- goog.provide('ol.ImageState');
- /**
- * @enum {number}
- */
- ol.ImageState = {
- IDLE: 0,
- LOADING: 1,
- LOADED: 2,
- ERROR: 3
- };
- goog.provide('ol.ImageCanvas');
- goog.require('ol');
- goog.require('ol.ImageBase');
- goog.require('ol.ImageState');
- /**
- * @constructor
- * @extends {ol.ImageBase}
- * @param {ol.Extent} extent Extent.
- * @param {number} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @param {HTMLCanvasElement} canvas Canvas.
- * @param {ol.ImageCanvasLoader=} opt_loader Optional loader function to
- * support asynchronous canvas drawing.
- */
- ol.ImageCanvas = function(extent, resolution, pixelRatio, canvas, opt_loader) {
- /**
- * Optional canvas loader function.
- * @type {?ol.ImageCanvasLoader}
- * @private
- */
- this.loader_ = opt_loader !== undefined ? opt_loader : null;
- var state = opt_loader !== undefined ?
- ol.ImageState.IDLE : ol.ImageState.LOADED;
- ol.ImageBase.call(this, extent, resolution, pixelRatio, state);
- /**
- * @private
- * @type {HTMLCanvasElement}
- */
- this.canvas_ = canvas;
- /**
- * @private
- * @type {Error}
- */
- this.error_ = null;
- };
- ol.inherits(ol.ImageCanvas, ol.ImageBase);
- /**
- * Get any error associated with asynchronous rendering.
- * @return {Error} Any error that occurred during rendering.
- */
- ol.ImageCanvas.prototype.getError = function() {
- return this.error_;
- };
- /**
- * Handle async drawing complete.
- * @param {Error} err Any error during drawing.
- * @private
- */
- ol.ImageCanvas.prototype.handleLoad_ = function(err) {
- if (err) {
- this.error_ = err;
- this.state = ol.ImageState.ERROR;
- } else {
- this.state = ol.ImageState.LOADED;
- }
- this.changed();
- };
- /**
- * @inheritDoc
- */
- ol.ImageCanvas.prototype.load = function() {
- if (this.state == ol.ImageState.IDLE) {
- this.state = ol.ImageState.LOADING;
- this.changed();
- this.loader_(this.handleLoad_.bind(this));
- }
- };
- /**
- * @inheritDoc
- */
- ol.ImageCanvas.prototype.getImage = function() {
- return this.canvas_;
- };
- goog.provide('ol.LayerType');
- /**
- * A layer type used when creating layer renderers.
- * @enum {string}
- */
- ol.LayerType = {
- IMAGE: 'IMAGE',
- TILE: 'TILE',
- VECTOR_TILE: 'VECTOR_TILE',
- VECTOR: 'VECTOR'
- };
- goog.provide('ol.layer.VectorRenderType');
- /**
- * @enum {string}
- * Render mode for vector layers:
- * * `'image'`: Vector layers are rendered as images. Great performance, but
- * point symbols and texts are always rotated with the view and pixels are
- * scaled during zoom animations.
- * * `'vector'`: Vector layers are rendered as vectors. Most accurate rendering
- * even during animations, but slower performance.
- * @api
- */
- ol.layer.VectorRenderType = {
- IMAGE: 'image',
- VECTOR: 'vector'
- };
- goog.provide('ol.render.Event');
- goog.require('ol');
- goog.require('ol.events.Event');
- /**
- * @constructor
- * @extends {ol.events.Event}
- * @implements {oli.render.Event}
- * @param {ol.render.EventType} type Type.
- * @param {ol.render.VectorContext=} opt_vectorContext Vector context.
- * @param {olx.FrameState=} opt_frameState Frame state.
- * @param {?CanvasRenderingContext2D=} opt_context Context.
- * @param {?ol.webgl.Context=} opt_glContext WebGL Context.
- */
- ol.render.Event = function(
- type, opt_vectorContext, opt_frameState, opt_context,
- opt_glContext) {
- ol.events.Event.call(this, type);
- /**
- * For canvas, this is an instance of {@link ol.render.canvas.Immediate}.
- * @type {ol.render.VectorContext|undefined}
- * @api
- */
- this.vectorContext = opt_vectorContext;
- /**
- * An object representing the current render frame state.
- * @type {olx.FrameState|undefined}
- * @api
- */
- this.frameState = opt_frameState;
- /**
- * Canvas context. Only available when a Canvas renderer is used, null
- * otherwise.
- * @type {CanvasRenderingContext2D|null|undefined}
- * @api
- */
- this.context = opt_context;
- /**
- * WebGL context. Only available when a WebGL renderer is used, null
- * otherwise.
- * @type {ol.webgl.Context|null|undefined}
- * @api
- */
- this.glContext = opt_glContext;
- };
- ol.inherits(ol.render.Event, ol.events.Event);
- goog.provide('ol.structs.LRUCache');
- goog.require('ol');
- goog.require('ol.asserts');
- goog.require('ol.events.EventTarget');
- goog.require('ol.events.EventType');
- /**
- * Implements a Least-Recently-Used cache where the keys do not conflict with
- * Object's properties (e.g. 'hasOwnProperty' is not allowed as a key). Expiring
- * items from the cache is the responsibility of the user.
- * @constructor
- * @extends {ol.events.EventTarget}
- * @fires ol.events.Event
- * @struct
- * @template T
- * @param {number=} opt_highWaterMark High water mark.
- */
- ol.structs.LRUCache = function(opt_highWaterMark) {
- ol.events.EventTarget.call(this);
- /**
- * @type {number}
- */
- this.highWaterMark = opt_highWaterMark !== undefined ? opt_highWaterMark : 2048;
- /**
- * @private
- * @type {number}
- */
- this.count_ = 0;
- /**
- * @private
- * @type {!Object.<string, ol.LRUCacheEntry>}
- */
- this.entries_ = {};
- /**
- * @private
- * @type {?ol.LRUCacheEntry}
- */
- this.oldest_ = null;
- /**
- * @private
- * @type {?ol.LRUCacheEntry}
- */
- this.newest_ = null;
- };
- ol.inherits(ol.structs.LRUCache, ol.events.EventTarget);
- /**
- * @return {boolean} Can expire cache.
- */
- ol.structs.LRUCache.prototype.canExpireCache = function() {
- return this.getCount() > this.highWaterMark;
- };
- /**
- * FIXME empty description for jsdoc
- */
- ol.structs.LRUCache.prototype.clear = function() {
- this.count_ = 0;
- this.entries_ = {};
- this.oldest_ = null;
- this.newest_ = null;
- this.dispatchEvent(ol.events.EventType.CLEAR);
- };
- /**
- * @param {string} key Key.
- * @return {boolean} Contains key.
- */
- ol.structs.LRUCache.prototype.containsKey = function(key) {
- return this.entries_.hasOwnProperty(key);
- };
- /**
- * @param {function(this: S, T, string, ol.structs.LRUCache): ?} f The function
- * to call for every entry from the oldest to the newer. This function takes
- * 3 arguments (the entry value, the entry key and the LRUCache object).
- * The return value is ignored.
- * @param {S=} opt_this The object to use as `this` in `f`.
- * @template S
- */
- ol.structs.LRUCache.prototype.forEach = function(f, opt_this) {
- var entry = this.oldest_;
- while (entry) {
- f.call(opt_this, entry.value_, entry.key_, this);
- entry = entry.newer;
- }
- };
- /**
- * @param {string} key Key.
- * @return {T} Value.
- */
- ol.structs.LRUCache.prototype.get = function(key) {
- var entry = this.entries_[key];
- ol.asserts.assert(entry !== undefined,
- 15); // Tried to get a value for a key that does not exist in the cache
- if (entry === this.newest_) {
- return entry.value_;
- } else if (entry === this.oldest_) {
- this.oldest_ = /** @type {ol.LRUCacheEntry} */ (this.oldest_.newer);
- this.oldest_.older = null;
- } else {
- entry.newer.older = entry.older;
- entry.older.newer = entry.newer;
- }
- entry.newer = null;
- entry.older = this.newest_;
- this.newest_.newer = entry;
- this.newest_ = entry;
- return entry.value_;
- };
- /**
- * Remove an entry from the cache.
- * @param {string} key The entry key.
- * @return {T} The removed entry.
- */
- ol.structs.LRUCache.prototype.remove = function(key) {
- var entry = this.entries_[key];
- ol.asserts.assert(entry !== undefined, 15); // Tried to get a value for a key that does not exist in the cache
- if (entry === this.newest_) {
- this.newest_ = /** @type {ol.LRUCacheEntry} */ (entry.older);
- if (this.newest_) {
- this.newest_.newer = null;
- }
- } else if (entry === this.oldest_) {
- this.oldest_ = /** @type {ol.LRUCacheEntry} */ (entry.newer);
- if (this.oldest_) {
- this.oldest_.older = null;
- }
- } else {
- entry.newer.older = entry.older;
- entry.older.newer = entry.newer;
- }
- delete this.entries_[key];
- --this.count_;
- return entry.value_;
- };
- /**
- * @return {number} Count.
- */
- ol.structs.LRUCache.prototype.getCount = function() {
- return this.count_;
- };
- /**
- * @return {Array.<string>} Keys.
- */
- ol.structs.LRUCache.prototype.getKeys = function() {
- var keys = new Array(this.count_);
- var i = 0;
- var entry;
- for (entry = this.newest_; entry; entry = entry.older) {
- keys[i++] = entry.key_;
- }
- return keys;
- };
- /**
- * @return {Array.<T>} Values.
- */
- ol.structs.LRUCache.prototype.getValues = function() {
- var values = new Array(this.count_);
- var i = 0;
- var entry;
- for (entry = this.newest_; entry; entry = entry.older) {
- values[i++] = entry.value_;
- }
- return values;
- };
- /**
- * @return {T} Last value.
- */
- ol.structs.LRUCache.prototype.peekLast = function() {
- return this.oldest_.value_;
- };
- /**
- * @return {string} Last key.
- */
- ol.structs.LRUCache.prototype.peekLastKey = function() {
- return this.oldest_.key_;
- };
- /**
- * Get the key of the newest item in the cache. Throws if the cache is empty.
- * @return {string} The newest key.
- */
- ol.structs.LRUCache.prototype.peekFirstKey = function() {
- return this.newest_.key_;
- };
- /**
- * @return {T} value Value.
- */
- ol.structs.LRUCache.prototype.pop = function() {
- var entry = this.oldest_;
- delete this.entries_[entry.key_];
- if (entry.newer) {
- entry.newer.older = null;
- }
- this.oldest_ = /** @type {ol.LRUCacheEntry} */ (entry.newer);
- if (!this.oldest_) {
- this.newest_ = null;
- }
- --this.count_;
- return entry.value_;
- };
- /**
- * @param {string} key Key.
- * @param {T} value Value.
- */
- ol.structs.LRUCache.prototype.replace = function(key, value) {
- this.get(key); // update `newest_`
- this.entries_[key].value_ = value;
- };
- /**
- * @param {string} key Key.
- * @param {T} value Value.
- */
- ol.structs.LRUCache.prototype.set = function(key, value) {
- ol.asserts.assert(!(key in this.entries_),
- 16); // Tried to set a value for a key that is used already
- var entry = /** @type {ol.LRUCacheEntry} */ ({
- key_: key,
- newer: null,
- older: this.newest_,
- value_: value
- });
- if (!this.newest_) {
- this.oldest_ = entry;
- } else {
- this.newest_.newer = entry;
- }
- this.newest_ = entry;
- this.entries_[key] = entry;
- ++this.count_;
- };
- /**
- * Prune the cache.
- */
- ol.structs.LRUCache.prototype.prune = function() {
- while (this.canExpireCache()) {
- this.pop();
- }
- };
- goog.provide('ol.render.canvas');
- goog.require('ol.css');
- goog.require('ol.dom');
- goog.require('ol.obj');
- goog.require('ol.structs.LRUCache');
- goog.require('ol.transform');
- /**
- * @const
- * @type {string}
- */
- ol.render.canvas.defaultFont = '10px sans-serif';
- /**
- * @const
- * @type {ol.Color}
- */
- ol.render.canvas.defaultFillStyle = [0, 0, 0, 1];
- /**
- * @const
- * @type {string}
- */
- ol.render.canvas.defaultLineCap = 'round';
- /**
- * @const
- * @type {Array.<number>}
- */
- ol.render.canvas.defaultLineDash = [];
- /**
- * @const
- * @type {number}
- */
- ol.render.canvas.defaultLineDashOffset = 0;
- /**
- * @const
- * @type {string}
- */
- ol.render.canvas.defaultLineJoin = 'round';
- /**
- * @const
- * @type {number}
- */
- ol.render.canvas.defaultMiterLimit = 10;
- /**
- * @const
- * @type {ol.Color}
- */
- ol.render.canvas.defaultStrokeStyle = [0, 0, 0, 1];
- /**
- * @const
- * @type {string}
- */
- ol.render.canvas.defaultTextAlign = 'center';
- /**
- * @const
- * @type {string}
- */
- ol.render.canvas.defaultTextBaseline = 'middle';
- /**
- * @const
- * @type {Array.<number>}
- */
- ol.render.canvas.defaultPadding = [0, 0, 0, 0];
- /**
- * @const
- * @type {number}
- */
- ol.render.canvas.defaultLineWidth = 1;
- /**
- * @type {ol.structs.LRUCache.<HTMLCanvasElement>}
- */
- ol.render.canvas.labelCache = new ol.structs.LRUCache();
- /**
- * @type {!Object.<string, number>}
- */
- ol.render.canvas.checkedFonts_ = {};
- /**
- * @type {CanvasRenderingContext2D}
- */
- ol.render.canvas.measureContext_ = null;
- /**
- * @type {!Object.<string, number>}
- */
- ol.render.canvas.textHeights_ = {};
- /**
- * Clears the label cache when a font becomes available.
- * @param {string} fontSpec CSS font spec.
- */
- ol.render.canvas.checkFont = (function() {
- var retries = 60;
- var checked = ol.render.canvas.checkedFonts_;
- var labelCache = ol.render.canvas.labelCache;
- var font = '32px monospace';
- var text = 'wmytzilWMYTZIL@#/&?$%10';
- var interval, referenceWidth;
- function isAvailable(fontFamily) {
- var context = ol.render.canvas.getMeasureContext();
- context.font = font;
- referenceWidth = context.measureText(text).width;
- var available = true;
- if (fontFamily != 'monospace') {
- context.font = '32px ' + fontFamily + ',monospace';
- var width = context.measureText(text).width;
- // If width and referenceWidth are the same, then the 'monospace'
- // fallback was used instead of the font we wanted, so the font is not
- // available.
- available = width != referenceWidth;
- }
- return available;
- }
- function check() {
- var done = true;
- for (var font in checked) {
- if (checked[font] < retries) {
- if (isAvailable(font)) {
- checked[font] = retries;
- ol.obj.clear(ol.render.canvas.textHeights_);
- // Make sure that loaded fonts are picked up by Safari
- ol.render.canvas.measureContext_ = null;
- labelCache.clear();
- } else {
- ++checked[font];
- done = false;
- }
- }
- }
- if (done) {
- window.clearInterval(interval);
- interval = undefined;
- }
- }
- return function(fontSpec) {
- var fontFamilies = ol.css.getFontFamilies(fontSpec);
- if (!fontFamilies) {
- return;
- }
- for (var i = 0, ii = fontFamilies.length; i < ii; ++i) {
- var fontFamily = fontFamilies[i];
- if (!(fontFamily in checked)) {
- checked[fontFamily] = retries;
- if (!isAvailable(fontFamily)) {
- checked[fontFamily] = 0;
- if (interval === undefined) {
- interval = window.setInterval(check, 32);
- }
- }
- }
- }
- };
- })();
- /**
- * @return {CanvasRenderingContext2D} Measure context.
- */
- ol.render.canvas.getMeasureContext = function() {
- var context = ol.render.canvas.measureContext_;
- if (!context) {
- context = ol.render.canvas.measureContext_ = ol.dom.createCanvasContext2D(1, 1);
- }
- return context;
- };
- /**
- * @param {string} font Font to use for measuring.
- * @return {ol.Size} Measurement.
- */
- ol.render.canvas.measureTextHeight = (function() {
- var span;
- var heights = ol.render.canvas.textHeights_;
- return function(font) {
- var height = heights[font];
- if (height == undefined) {
- if (!span) {
- span = document.createElement('span');
- span.textContent = 'M';
- span.style.margin = span.style.padding = '0 !important';
- span.style.position = 'absolute !important';
- span.style.left = '-99999px !important';
- }
- span.style.font = font;
- document.body.appendChild(span);
- height = heights[font] = span.offsetHeight;
- document.body.removeChild(span);
- }
- return height;
- };
- })();
- /**
- * @param {string} font Font.
- * @param {string} text Text.
- * @return {number} Width.
- */
- ol.render.canvas.measureTextWidth = function(font, text) {
- var measureContext = ol.render.canvas.getMeasureContext();
- if (font != measureContext.font) {
- measureContext.font = font;
- }
- return measureContext.measureText(text).width;
- };
- /**
- * @param {CanvasRenderingContext2D} context Context.
- * @param {number} rotation Rotation.
- * @param {number} offsetX X offset.
- * @param {number} offsetY Y offset.
- */
- ol.render.canvas.rotateAtOffset = function(context, rotation, offsetX, offsetY) {
- if (rotation !== 0) {
- context.translate(offsetX, offsetY);
- context.rotate(rotation);
- context.translate(-offsetX, -offsetY);
- }
- };
- ol.render.canvas.resetTransform_ = ol.transform.create();
- /**
- * @param {CanvasRenderingContext2D} context Context.
- * @param {ol.Transform|null} transform Transform.
- * @param {number} opacity Opacity.
- * @param {HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} image Image.
- * @param {number} originX Origin X.
- * @param {number} originY Origin Y.
- * @param {number} w Width.
- * @param {number} h Height.
- * @param {number} x X.
- * @param {number} y Y.
- * @param {number} scale Scale.
- */
- ol.render.canvas.drawImage = function(context,
- transform, opacity, image, originX, originY, w, h, x, y, scale) {
- var alpha;
- if (opacity != 1) {
- alpha = context.globalAlpha;
- context.globalAlpha = alpha * opacity;
- }
- if (transform) {
- context.setTransform.apply(context, transform);
- }
- context.drawImage(image, originX, originY, w, h, x, y, w * scale, h * scale);
- if (alpha) {
- context.globalAlpha = alpha;
- }
- if (transform) {
- context.setTransform.apply(context, ol.render.canvas.resetTransform_);
- }
- };
- goog.provide('ol.color');
- goog.require('ol.asserts');
- goog.require('ol.math');
- /**
- * This RegExp matches # followed by 3, 4, 6, or 8 hex digits.
- * @const
- * @type {RegExp}
- * @private
- */
- ol.color.HEX_COLOR_RE_ = /^#(?:[0-9a-f]{3,4}){1,2}$/i;
- /**
- * Regular expression for matching potential named color style strings.
- * @const
- * @type {RegExp}
- * @private
- */
- ol.color.NAMED_COLOR_RE_ = /^([a-z]*)$/i;
- /**
- * Return the color as an array. This function maintains a cache of calculated
- * arrays which means the result should not be modified.
- * @param {ol.Color|string} color Color.
- * @return {ol.Color} Color.
- * @api
- */
- ol.color.asArray = function(color) {
- if (Array.isArray(color)) {
- return color;
- } else {
- return ol.color.fromString(/** @type {string} */ (color));
- }
- };
- /**
- * Return the color as an rgba string.
- * @param {ol.Color|string} color Color.
- * @return {string} Rgba string.
- * @api
- */
- ol.color.asString = function(color) {
- if (typeof color === 'string') {
- return color;
- } else {
- return ol.color.toString(color);
- }
- };
- /**
- * Return named color as an rgba string.
- * @param {string} color Named color.
- * @return {string} Rgb string.
- */
- ol.color.fromNamed = function(color) {
- var el = document.createElement('div');
- el.style.color = color;
- document.body.appendChild(el);
- var rgb = getComputedStyle(el).color;
- document.body.removeChild(el);
- return rgb;
- };
- /**
- * @param {string} s String.
- * @return {ol.Color} Color.
- */
- ol.color.fromString = (
- function() {
- // We maintain a small cache of parsed strings. To provide cheap LRU-like
- // semantics, whenever the cache grows too large we simply delete an
- // arbitrary 25% of the entries.
- /**
- * @const
- * @type {number}
- */
- var MAX_CACHE_SIZE = 1024;
- /**
- * @type {Object.<string, ol.Color>}
- */
- var cache = {};
- /**
- * @type {number}
- */
- var cacheSize = 0;
- return (
- /**
- * @param {string} s String.
- * @return {ol.Color} Color.
- */
- function(s) {
- var color;
- if (cache.hasOwnProperty(s)) {
- color = cache[s];
- } else {
- if (cacheSize >= MAX_CACHE_SIZE) {
- var i = 0;
- var key;
- for (key in cache) {
- if ((i++ & 3) === 0) {
- delete cache[key];
- --cacheSize;
- }
- }
- }
- color = ol.color.fromStringInternal_(s);
- cache[s] = color;
- ++cacheSize;
- }
- return color;
- });
- })();
- /**
- * @param {string} s String.
- * @private
- * @return {ol.Color} Color.
- */
- ol.color.fromStringInternal_ = function(s) {
- var r, g, b, a, color, parts;
- if (ol.color.NAMED_COLOR_RE_.exec(s)) {
- s = ol.color.fromNamed(s);
- }
- if (ol.color.HEX_COLOR_RE_.exec(s)) { // hex
- var n = s.length - 1; // number of hex digits
- var d; // number of digits per channel
- if (n <= 4) {
- d = 1;
- } else {
- d = 2;
- }
- var hasAlpha = n === 4 || n === 8;
- r = parseInt(s.substr(1 + 0 * d, d), 16);
- g = parseInt(s.substr(1 + 1 * d, d), 16);
- b = parseInt(s.substr(1 + 2 * d, d), 16);
- if (hasAlpha) {
- a = parseInt(s.substr(1 + 3 * d, d), 16);
- } else {
- a = 255;
- }
- if (d == 1) {
- r = (r << 4) + r;
- g = (g << 4) + g;
- b = (b << 4) + b;
- if (hasAlpha) {
- a = (a << 4) + a;
- }
- }
- color = [r, g, b, a / 255];
- } else if (s.indexOf('rgba(') == 0) { // rgba()
- parts = s.slice(5, -1).split(',').map(Number);
- color = ol.color.normalize(parts);
- } else if (s.indexOf('rgb(') == 0) { // rgb()
- parts = s.slice(4, -1).split(',').map(Number);
- parts.push(1);
- color = ol.color.normalize(parts);
- } else {
- ol.asserts.assert(false, 14); // Invalid color
- }
- return /** @type {ol.Color} */ (color);
- };
- /**
- * @param {ol.Color} color Color.
- * @param {ol.Color=} opt_color Color.
- * @return {ol.Color} Clamped color.
- */
- ol.color.normalize = function(color, opt_color) {
- var result = opt_color || [];
- result[0] = ol.math.clamp((color[0] + 0.5) | 0, 0, 255);
- result[1] = ol.math.clamp((color[1] + 0.5) | 0, 0, 255);
- result[2] = ol.math.clamp((color[2] + 0.5) | 0, 0, 255);
- result[3] = ol.math.clamp(color[3], 0, 1);
- return result;
- };
- /**
- * @param {ol.Color} color Color.
- * @return {string} String.
- */
- ol.color.toString = function(color) {
- var r = color[0];
- if (r != (r | 0)) {
- r = (r + 0.5) | 0;
- }
- var g = color[1];
- if (g != (g | 0)) {
- g = (g + 0.5) | 0;
- }
- var b = color[2];
- if (b != (b | 0)) {
- b = (b + 0.5) | 0;
- }
- var a = color[3] === undefined ? 1 : color[3];
- return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
- };
- goog.provide('ol.colorlike');
- goog.require('ol.color');
- /**
- * @param {ol.Color|ol.ColorLike} color Color.
- * @return {ol.ColorLike} The color as an ol.ColorLike
- * @api
- */
- ol.colorlike.asColorLike = function(color) {
- if (ol.colorlike.isColorLike(color)) {
- return /** @type {string|CanvasPattern|CanvasGradient} */ (color);
- } else {
- return ol.color.asString(/** @type {ol.Color} */ (color));
- }
- };
- /**
- * @param {?} color The value that is potentially an ol.ColorLike
- * @return {boolean} Whether the color is an ol.ColorLike
- */
- ol.colorlike.isColorLike = function(color) {
- return (
- typeof color === 'string' ||
- color instanceof CanvasPattern ||
- color instanceof CanvasGradient
- );
- };
- goog.provide('ol.render.VectorContext');
- /**
- * Context for drawing geometries. A vector context is available on render
- * events and does not need to be constructed directly.
- * @constructor
- * @abstract
- * @struct
- * @api
- */
- ol.render.VectorContext = function() {
- };
- /**
- * Render a geometry with a custom renderer.
- *
- * @param {ol.geom.SimpleGeometry} geometry Geometry.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @param {Function} renderer Renderer.
- */
- ol.render.VectorContext.prototype.drawCustom = function(geometry, feature, renderer) {};
- /**
- * Render a geometry.
- *
- * @param {ol.geom.Geometry} geometry The geometry to render.
- */
- ol.render.VectorContext.prototype.drawGeometry = function(geometry) {};
- /**
- * Set the rendering style.
- *
- * @param {ol.style.Style} style The rendering style.
- */
- ol.render.VectorContext.prototype.setStyle = function(style) {};
- /**
- * @param {ol.geom.Circle} circleGeometry Circle geometry.
- * @param {ol.Feature} feature Feature.
- */
- ol.render.VectorContext.prototype.drawCircle = function(circleGeometry, feature) {};
- /**
- * @param {ol.Feature} feature Feature.
- * @param {ol.style.Style} style Style.
- */
- ol.render.VectorContext.prototype.drawFeature = function(feature, style) {};
- /**
- * @param {ol.geom.GeometryCollection} geometryCollectionGeometry Geometry
- * collection.
- * @param {ol.Feature} feature Feature.
- */
- ol.render.VectorContext.prototype.drawGeometryCollection = function(geometryCollectionGeometry, feature) {};
- /**
- * @param {ol.geom.LineString|ol.render.Feature} lineStringGeometry Line
- * string geometry.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- */
- ol.render.VectorContext.prototype.drawLineString = function(lineStringGeometry, feature) {};
- /**
- * @param {ol.geom.MultiLineString|ol.render.Feature} multiLineStringGeometry
- * MultiLineString geometry.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- */
- ol.render.VectorContext.prototype.drawMultiLineString = function(multiLineStringGeometry, feature) {};
- /**
- * @param {ol.geom.MultiPoint|ol.render.Feature} multiPointGeometry MultiPoint
- * geometry.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- */
- ol.render.VectorContext.prototype.drawMultiPoint = function(multiPointGeometry, feature) {};
- /**
- * @param {ol.geom.MultiPolygon} multiPolygonGeometry MultiPolygon geometry.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- */
- ol.render.VectorContext.prototype.drawMultiPolygon = function(multiPolygonGeometry, feature) {};
- /**
- * @param {ol.geom.Point|ol.render.Feature} pointGeometry Point geometry.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- */
- ol.render.VectorContext.prototype.drawPoint = function(pointGeometry, feature) {};
- /**
- * @param {ol.geom.Polygon|ol.render.Feature} polygonGeometry Polygon
- * geometry.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- */
- ol.render.VectorContext.prototype.drawPolygon = function(polygonGeometry, feature) {};
- /**
- * @param {ol.geom.Geometry|ol.render.Feature} geometry Geometry.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- */
- ol.render.VectorContext.prototype.drawText = function(geometry, feature) {};
- /**
- * @param {ol.style.Fill} fillStyle Fill style.
- * @param {ol.style.Stroke} strokeStyle Stroke style.
- */
- ol.render.VectorContext.prototype.setFillStrokeStyle = function(fillStyle, strokeStyle) {};
- /**
- * @param {ol.style.Image} imageStyle Image style.
- * @param {ol.DeclutterGroup=} opt_declutterGroup Declutter.
- */
- ol.render.VectorContext.prototype.setImageStyle = function(imageStyle, opt_declutterGroup) {};
- /**
- * @param {ol.style.Text} textStyle Text style.
- * @param {ol.DeclutterGroup=} opt_declutterGroup Declutter.
- */
- ol.render.VectorContext.prototype.setTextStyle = function(textStyle, opt_declutterGroup) {};
- // FIXME test, especially polygons with holes and multipolygons
- // FIXME need to handle large thick features (where pixel size matters)
- // FIXME add offset and end to ol.geom.flat.transform.transform2D?
- goog.provide('ol.render.canvas.Immediate');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.colorlike');
- goog.require('ol.extent');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.SimpleGeometry');
- goog.require('ol.geom.flat.transform');
- goog.require('ol.has');
- goog.require('ol.render.VectorContext');
- goog.require('ol.render.canvas');
- goog.require('ol.transform');
- /**
- * @classdesc
- * A concrete subclass of {@link ol.render.VectorContext} that implements
- * direct rendering of features and geometries to an HTML5 Canvas context.
- * Instances of this class are created internally by the library and
- * provided to application code as vectorContext member of the
- * {@link ol.render.Event} object associated with postcompose, precompose and
- * render events emitted by layers and maps.
- *
- * @constructor
- * @extends {ol.render.VectorContext}
- * @param {CanvasRenderingContext2D} context Context.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.Extent} extent Extent.
- * @param {ol.Transform} transform Transform.
- * @param {number} viewRotation View rotation.
- * @struct
- */
- ol.render.canvas.Immediate = function(context, pixelRatio, extent, transform, viewRotation) {
- ol.render.VectorContext.call(this);
- /**
- * @private
- * @type {CanvasRenderingContext2D}
- */
- this.context_ = context;
- /**
- * @private
- * @type {number}
- */
- this.pixelRatio_ = pixelRatio;
- /**
- * @private
- * @type {ol.Extent}
- */
- this.extent_ = extent;
- /**
- * @private
- * @type {ol.Transform}
- */
- this.transform_ = transform;
- /**
- * @private
- * @type {number}
- */
- this.viewRotation_ = viewRotation;
- /**
- * @private
- * @type {?ol.CanvasFillState}
- */
- this.contextFillState_ = null;
- /**
- * @private
- * @type {?ol.CanvasStrokeState}
- */
- this.contextStrokeState_ = null;
- /**
- * @private
- * @type {?ol.CanvasTextState}
- */
- this.contextTextState_ = null;
- /**
- * @private
- * @type {?ol.CanvasFillState}
- */
- this.fillState_ = null;
- /**
- * @private
- * @type {?ol.CanvasStrokeState}
- */
- this.strokeState_ = null;
- /**
- * @private
- * @type {HTMLCanvasElement|HTMLVideoElement|Image}
- */
- this.image_ = null;
- /**
- * @private
- * @type {number}
- */
- this.imageAnchorX_ = 0;
- /**
- * @private
- * @type {number}
- */
- this.imageAnchorY_ = 0;
- /**
- * @private
- * @type {number}
- */
- this.imageHeight_ = 0;
- /**
- * @private
- * @type {number}
- */
- this.imageOpacity_ = 0;
- /**
- * @private
- * @type {number}
- */
- this.imageOriginX_ = 0;
- /**
- * @private
- * @type {number}
- */
- this.imageOriginY_ = 0;
- /**
- * @private
- * @type {boolean}
- */
- this.imageRotateWithView_ = false;
- /**
- * @private
- * @type {number}
- */
- this.imageRotation_ = 0;
- /**
- * @private
- * @type {number}
- */
- this.imageScale_ = 0;
- /**
- * @private
- * @type {boolean}
- */
- this.imageSnapToPixel_ = false;
- /**
- * @private
- * @type {number}
- */
- this.imageWidth_ = 0;
- /**
- * @private
- * @type {string}
- */
- this.text_ = '';
- /**
- * @private
- * @type {number}
- */
- this.textOffsetX_ = 0;
- /**
- * @private
- * @type {number}
- */
- this.textOffsetY_ = 0;
- /**
- * @private
- * @type {boolean}
- */
- this.textRotateWithView_ = false;
- /**
- * @private
- * @type {number}
- */
- this.textRotation_ = 0;
- /**
- * @private
- * @type {number}
- */
- this.textScale_ = 0;
- /**
- * @private
- * @type {?ol.CanvasFillState}
- */
- this.textFillState_ = null;
- /**
- * @private
- * @type {?ol.CanvasStrokeState}
- */
- this.textStrokeState_ = null;
- /**
- * @private
- * @type {?ol.CanvasTextState}
- */
- this.textState_ = null;
- /**
- * @private
- * @type {Array.<number>}
- */
- this.pixelCoordinates_ = [];
- /**
- * @private
- * @type {ol.Transform}
- */
- this.tmpLocalTransform_ = ol.transform.create();
- };
- ol.inherits(ol.render.canvas.Immediate, ol.render.VectorContext);
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @private
- */
- ol.render.canvas.Immediate.prototype.drawImages_ = function(flatCoordinates, offset, end, stride) {
- if (!this.image_) {
- return;
- }
- var pixelCoordinates = ol.geom.flat.transform.transform2D(
- flatCoordinates, offset, end, 2, this.transform_,
- this.pixelCoordinates_);
- var context = this.context_;
- var localTransform = this.tmpLocalTransform_;
- var alpha = context.globalAlpha;
- if (this.imageOpacity_ != 1) {
- context.globalAlpha = alpha * this.imageOpacity_;
- }
- var rotation = this.imageRotation_;
- if (this.imageRotateWithView_) {
- rotation += this.viewRotation_;
- }
- var i, ii;
- for (i = 0, ii = pixelCoordinates.length; i < ii; i += 2) {
- var x = pixelCoordinates[i] - this.imageAnchorX_;
- var y = pixelCoordinates[i + 1] - this.imageAnchorY_;
- if (this.imageSnapToPixel_) {
- x = Math.round(x);
- y = Math.round(y);
- }
- if (rotation !== 0 || this.imageScale_ != 1) {
- var centerX = x + this.imageAnchorX_;
- var centerY = y + this.imageAnchorY_;
- ol.transform.compose(localTransform,
- centerX, centerY,
- this.imageScale_, this.imageScale_,
- rotation,
- -centerX, -centerY);
- context.setTransform.apply(context, localTransform);
- }
- context.drawImage(this.image_, this.imageOriginX_, this.imageOriginY_,
- this.imageWidth_, this.imageHeight_, x, y,
- this.imageWidth_, this.imageHeight_);
- }
- if (rotation !== 0 || this.imageScale_ != 1) {
- context.setTransform(1, 0, 0, 1, 0, 0);
- }
- if (this.imageOpacity_ != 1) {
- context.globalAlpha = alpha;
- }
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @private
- */
- ol.render.canvas.Immediate.prototype.drawText_ = function(flatCoordinates, offset, end, stride) {
- if (!this.textState_ || this.text_ === '') {
- return;
- }
- if (this.textFillState_) {
- this.setContextFillState_(this.textFillState_);
- }
- if (this.textStrokeState_) {
- this.setContextStrokeState_(this.textStrokeState_);
- }
- this.setContextTextState_(this.textState_);
- var pixelCoordinates = ol.geom.flat.transform.transform2D(
- flatCoordinates, offset, end, stride, this.transform_,
- this.pixelCoordinates_);
- var context = this.context_;
- var rotation = this.textRotation_;
- if (this.textRotateWithView_) {
- rotation += this.viewRotation_;
- }
- for (; offset < end; offset += stride) {
- var x = pixelCoordinates[offset] + this.textOffsetX_;
- var y = pixelCoordinates[offset + 1] + this.textOffsetY_;
- if (rotation !== 0 || this.textScale_ != 1) {
- var localTransform = ol.transform.compose(this.tmpLocalTransform_,
- x, y,
- this.textScale_, this.textScale_,
- rotation,
- -x, -y);
- context.setTransform.apply(context, localTransform);
- }
- if (this.textStrokeState_) {
- context.strokeText(this.text_, x, y);
- }
- if (this.textFillState_) {
- context.fillText(this.text_, x, y);
- }
- }
- if (rotation !== 0 || this.textScale_ != 1) {
- context.setTransform(1, 0, 0, 1, 0, 0);
- }
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {boolean} close Close.
- * @private
- * @return {number} end End.
- */
- ol.render.canvas.Immediate.prototype.moveToLineTo_ = function(flatCoordinates, offset, end, stride, close) {
- var context = this.context_;
- var pixelCoordinates = ol.geom.flat.transform.transform2D(
- flatCoordinates, offset, end, stride, this.transform_,
- this.pixelCoordinates_);
- context.moveTo(pixelCoordinates[0], pixelCoordinates[1]);
- var length = pixelCoordinates.length;
- if (close) {
- length -= 2;
- }
- for (var i = 2; i < length; i += 2) {
- context.lineTo(pixelCoordinates[i], pixelCoordinates[i + 1]);
- }
- if (close) {
- context.closePath();
- }
- return end;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<number>} ends Ends.
- * @param {number} stride Stride.
- * @private
- * @return {number} End.
- */
- ol.render.canvas.Immediate.prototype.drawRings_ = function(flatCoordinates, offset, ends, stride) {
- var i, ii;
- for (i = 0, ii = ends.length; i < ii; ++i) {
- offset = this.moveToLineTo_(
- flatCoordinates, offset, ends[i], stride, true);
- }
- return offset;
- };
- /**
- * Render a circle geometry into the canvas. Rendering is immediate and uses
- * the current fill and stroke styles.
- *
- * @param {ol.geom.Circle} geometry Circle geometry.
- * @override
- * @api
- */
- ol.render.canvas.Immediate.prototype.drawCircle = function(geometry) {
- if (!ol.extent.intersects(this.extent_, geometry.getExtent())) {
- return;
- }
- if (this.fillState_ || this.strokeState_) {
- if (this.fillState_) {
- this.setContextFillState_(this.fillState_);
- }
- if (this.strokeState_) {
- this.setContextStrokeState_(this.strokeState_);
- }
- var pixelCoordinates = ol.geom.SimpleGeometry.transform2D(
- geometry, this.transform_, this.pixelCoordinates_);
- var dx = pixelCoordinates[2] - pixelCoordinates[0];
- var dy = pixelCoordinates[3] - pixelCoordinates[1];
- var radius = Math.sqrt(dx * dx + dy * dy);
- var context = this.context_;
- context.beginPath();
- context.arc(
- pixelCoordinates[0], pixelCoordinates[1], radius, 0, 2 * Math.PI);
- if (this.fillState_) {
- context.fill();
- }
- if (this.strokeState_) {
- context.stroke();
- }
- }
- if (this.text_ !== '') {
- this.drawText_(geometry.getCenter(), 0, 2, 2);
- }
- };
- /**
- * Set the rendering style. Note that since this is an immediate rendering API,
- * any `zIndex` on the provided style will be ignored.
- *
- * @param {ol.style.Style} style The rendering style.
- * @override
- * @api
- */
- ol.render.canvas.Immediate.prototype.setStyle = function(style) {
- this.setFillStrokeStyle(style.getFill(), style.getStroke());
- this.setImageStyle(style.getImage());
- this.setTextStyle(style.getText());
- };
- /**
- * Render a geometry into the canvas. Call
- * {@link ol.render.canvas.Immediate#setStyle} first to set the rendering style.
- *
- * @param {ol.geom.Geometry|ol.render.Feature} geometry The geometry to render.
- * @override
- * @api
- */
- ol.render.canvas.Immediate.prototype.drawGeometry = function(geometry) {
- var type = geometry.getType();
- switch (type) {
- case ol.geom.GeometryType.POINT:
- this.drawPoint(/** @type {ol.geom.Point} */ (geometry));
- break;
- case ol.geom.GeometryType.LINE_STRING:
- this.drawLineString(/** @type {ol.geom.LineString} */ (geometry));
- break;
- case ol.geom.GeometryType.POLYGON:
- this.drawPolygon(/** @type {ol.geom.Polygon} */ (geometry));
- break;
- case ol.geom.GeometryType.MULTI_POINT:
- this.drawMultiPoint(/** @type {ol.geom.MultiPoint} */ (geometry));
- break;
- case ol.geom.GeometryType.MULTI_LINE_STRING:
- this.drawMultiLineString(/** @type {ol.geom.MultiLineString} */ (geometry));
- break;
- case ol.geom.GeometryType.MULTI_POLYGON:
- this.drawMultiPolygon(/** @type {ol.geom.MultiPolygon} */ (geometry));
- break;
- case ol.geom.GeometryType.GEOMETRY_COLLECTION:
- this.drawGeometryCollection(/** @type {ol.geom.GeometryCollection} */ (geometry));
- break;
- case ol.geom.GeometryType.CIRCLE:
- this.drawCircle(/** @type {ol.geom.Circle} */ (geometry));
- break;
- default:
- }
- };
- /**
- * Render a feature into the canvas. Note that any `zIndex` on the provided
- * style will be ignored - features are rendered immediately in the order that
- * this method is called. If you need `zIndex` support, you should be using an
- * {@link ol.layer.Vector} instead.
- *
- * @param {ol.Feature} feature Feature.
- * @param {ol.style.Style} style Style.
- * @override
- * @api
- */
- ol.render.canvas.Immediate.prototype.drawFeature = function(feature, style) {
- var geometry = style.getGeometryFunction()(feature);
- if (!geometry ||
- !ol.extent.intersects(this.extent_, geometry.getExtent())) {
- return;
- }
- this.setStyle(style);
- this.drawGeometry(geometry);
- };
- /**
- * Render a GeometryCollection to the canvas. Rendering is immediate and
- * uses the current styles appropriate for each geometry in the collection.
- *
- * @param {ol.geom.GeometryCollection} geometry Geometry collection.
- * @override
- */
- ol.render.canvas.Immediate.prototype.drawGeometryCollection = function(geometry) {
- var geometries = geometry.getGeometriesArray();
- var i, ii;
- for (i = 0, ii = geometries.length; i < ii; ++i) {
- this.drawGeometry(geometries[i]);
- }
- };
- /**
- * Render a Point geometry into the canvas. Rendering is immediate and uses
- * the current style.
- *
- * @param {ol.geom.Point|ol.render.Feature} geometry Point geometry.
- * @override
- */
- ol.render.canvas.Immediate.prototype.drawPoint = function(geometry) {
- var flatCoordinates = geometry.getFlatCoordinates();
- var stride = geometry.getStride();
- if (this.image_) {
- this.drawImages_(flatCoordinates, 0, flatCoordinates.length, stride);
- }
- if (this.text_ !== '') {
- this.drawText_(flatCoordinates, 0, flatCoordinates.length, stride);
- }
- };
- /**
- * Render a MultiPoint geometry into the canvas. Rendering is immediate and
- * uses the current style.
- *
- * @param {ol.geom.MultiPoint|ol.render.Feature} geometry MultiPoint geometry.
- * @override
- */
- ol.render.canvas.Immediate.prototype.drawMultiPoint = function(geometry) {
- var flatCoordinates = geometry.getFlatCoordinates();
- var stride = geometry.getStride();
- if (this.image_) {
- this.drawImages_(flatCoordinates, 0, flatCoordinates.length, stride);
- }
- if (this.text_ !== '') {
- this.drawText_(flatCoordinates, 0, flatCoordinates.length, stride);
- }
- };
- /**
- * Render a LineString into the canvas. Rendering is immediate and uses
- * the current style.
- *
- * @param {ol.geom.LineString|ol.render.Feature} geometry LineString geometry.
- * @override
- */
- ol.render.canvas.Immediate.prototype.drawLineString = function(geometry) {
- if (!ol.extent.intersects(this.extent_, geometry.getExtent())) {
- return;
- }
- if (this.strokeState_) {
- this.setContextStrokeState_(this.strokeState_);
- var context = this.context_;
- var flatCoordinates = geometry.getFlatCoordinates();
- context.beginPath();
- this.moveToLineTo_(flatCoordinates, 0, flatCoordinates.length,
- geometry.getStride(), false);
- context.stroke();
- }
- if (this.text_ !== '') {
- var flatMidpoint = geometry.getFlatMidpoint();
- this.drawText_(flatMidpoint, 0, 2, 2);
- }
- };
- /**
- * Render a MultiLineString geometry into the canvas. Rendering is immediate
- * and uses the current style.
- *
- * @param {ol.geom.MultiLineString|ol.render.Feature} geometry MultiLineString
- * geometry.
- * @override
- */
- ol.render.canvas.Immediate.prototype.drawMultiLineString = function(geometry) {
- var geometryExtent = geometry.getExtent();
- if (!ol.extent.intersects(this.extent_, geometryExtent)) {
- return;
- }
- if (this.strokeState_) {
- this.setContextStrokeState_(this.strokeState_);
- var context = this.context_;
- var flatCoordinates = geometry.getFlatCoordinates();
- var offset = 0;
- var ends = geometry.getEnds();
- var stride = geometry.getStride();
- context.beginPath();
- var i, ii;
- for (i = 0, ii = ends.length; i < ii; ++i) {
- offset = this.moveToLineTo_(
- flatCoordinates, offset, ends[i], stride, false);
- }
- context.stroke();
- }
- if (this.text_ !== '') {
- var flatMidpoints = geometry.getFlatMidpoints();
- this.drawText_(flatMidpoints, 0, flatMidpoints.length, 2);
- }
- };
- /**
- * Render a Polygon geometry into the canvas. Rendering is immediate and uses
- * the current style.
- *
- * @param {ol.geom.Polygon|ol.render.Feature} geometry Polygon geometry.
- * @override
- */
- ol.render.canvas.Immediate.prototype.drawPolygon = function(geometry) {
- if (!ol.extent.intersects(this.extent_, geometry.getExtent())) {
- return;
- }
- if (this.strokeState_ || this.fillState_) {
- if (this.fillState_) {
- this.setContextFillState_(this.fillState_);
- }
- if (this.strokeState_) {
- this.setContextStrokeState_(this.strokeState_);
- }
- var context = this.context_;
- context.beginPath();
- this.drawRings_(geometry.getOrientedFlatCoordinates(),
- 0, geometry.getEnds(), geometry.getStride());
- if (this.fillState_) {
- context.fill();
- }
- if (this.strokeState_) {
- context.stroke();
- }
- }
- if (this.text_ !== '') {
- var flatInteriorPoint = geometry.getFlatInteriorPoint();
- this.drawText_(flatInteriorPoint, 0, 2, 2);
- }
- };
- /**
- * Render MultiPolygon geometry into the canvas. Rendering is immediate and
- * uses the current style.
- * @param {ol.geom.MultiPolygon} geometry MultiPolygon geometry.
- * @override
- */
- ol.render.canvas.Immediate.prototype.drawMultiPolygon = function(geometry) {
- if (!ol.extent.intersects(this.extent_, geometry.getExtent())) {
- return;
- }
- if (this.strokeState_ || this.fillState_) {
- if (this.fillState_) {
- this.setContextFillState_(this.fillState_);
- }
- if (this.strokeState_) {
- this.setContextStrokeState_(this.strokeState_);
- }
- var context = this.context_;
- var flatCoordinates = geometry.getOrientedFlatCoordinates();
- var offset = 0;
- var endss = geometry.getEndss();
- var stride = geometry.getStride();
- var i, ii;
- context.beginPath();
- for (i = 0, ii = endss.length; i < ii; ++i) {
- var ends = endss[i];
- offset = this.drawRings_(flatCoordinates, offset, ends, stride);
- }
- if (this.fillState_) {
- context.fill();
- }
- if (this.strokeState_) {
- context.stroke();
- }
- }
- if (this.text_ !== '') {
- var flatInteriorPoints = geometry.getFlatInteriorPoints();
- this.drawText_(flatInteriorPoints, 0, flatInteriorPoints.length, 2);
- }
- };
- /**
- * @param {ol.CanvasFillState} fillState Fill state.
- * @private
- */
- ol.render.canvas.Immediate.prototype.setContextFillState_ = function(fillState) {
- var context = this.context_;
- var contextFillState = this.contextFillState_;
- if (!contextFillState) {
- context.fillStyle = fillState.fillStyle;
- this.contextFillState_ = {
- fillStyle: fillState.fillStyle
- };
- } else {
- if (contextFillState.fillStyle != fillState.fillStyle) {
- contextFillState.fillStyle = context.fillStyle = fillState.fillStyle;
- }
- }
- };
- /**
- * @param {ol.CanvasStrokeState} strokeState Stroke state.
- * @private
- */
- ol.render.canvas.Immediate.prototype.setContextStrokeState_ = function(strokeState) {
- var context = this.context_;
- var contextStrokeState = this.contextStrokeState_;
- if (!contextStrokeState) {
- context.lineCap = strokeState.lineCap;
- if (ol.has.CANVAS_LINE_DASH) {
- context.setLineDash(strokeState.lineDash);
- context.lineDashOffset = strokeState.lineDashOffset;
- }
- context.lineJoin = strokeState.lineJoin;
- context.lineWidth = strokeState.lineWidth;
- context.miterLimit = strokeState.miterLimit;
- context.strokeStyle = strokeState.strokeStyle;
- this.contextStrokeState_ = {
- lineCap: strokeState.lineCap,
- lineDash: strokeState.lineDash,
- lineDashOffset: strokeState.lineDashOffset,
- lineJoin: strokeState.lineJoin,
- lineWidth: strokeState.lineWidth,
- miterLimit: strokeState.miterLimit,
- strokeStyle: strokeState.strokeStyle
- };
- } else {
- if (contextStrokeState.lineCap != strokeState.lineCap) {
- contextStrokeState.lineCap = context.lineCap = strokeState.lineCap;
- }
- if (ol.has.CANVAS_LINE_DASH) {
- if (!ol.array.equals(
- contextStrokeState.lineDash, strokeState.lineDash)) {
- context.setLineDash(contextStrokeState.lineDash = strokeState.lineDash);
- }
- if (contextStrokeState.lineDashOffset != strokeState.lineDashOffset) {
- contextStrokeState.lineDashOffset = context.lineDashOffset =
- strokeState.lineDashOffset;
- }
- }
- if (contextStrokeState.lineJoin != strokeState.lineJoin) {
- contextStrokeState.lineJoin = context.lineJoin = strokeState.lineJoin;
- }
- if (contextStrokeState.lineWidth != strokeState.lineWidth) {
- contextStrokeState.lineWidth = context.lineWidth = strokeState.lineWidth;
- }
- if (contextStrokeState.miterLimit != strokeState.miterLimit) {
- contextStrokeState.miterLimit = context.miterLimit =
- strokeState.miterLimit;
- }
- if (contextStrokeState.strokeStyle != strokeState.strokeStyle) {
- contextStrokeState.strokeStyle = context.strokeStyle =
- strokeState.strokeStyle;
- }
- }
- };
- /**
- * @param {ol.CanvasTextState} textState Text state.
- * @private
- */
- ol.render.canvas.Immediate.prototype.setContextTextState_ = function(textState) {
- var context = this.context_;
- var contextTextState = this.contextTextState_;
- var textAlign = textState.textAlign ?
- textState.textAlign : ol.render.canvas.defaultTextAlign;
- if (!contextTextState) {
- context.font = textState.font;
- context.textAlign = textAlign;
- context.textBaseline = textState.textBaseline;
- this.contextTextState_ = {
- font: textState.font,
- textAlign: textAlign,
- textBaseline: textState.textBaseline
- };
- } else {
- if (contextTextState.font != textState.font) {
- contextTextState.font = context.font = textState.font;
- }
- if (contextTextState.textAlign != textAlign) {
- contextTextState.textAlign = textAlign;
- }
- if (contextTextState.textBaseline != textState.textBaseline) {
- contextTextState.textBaseline = context.textBaseline =
- textState.textBaseline;
- }
- }
- };
- /**
- * Set the fill and stroke style for subsequent draw operations. To clear
- * either fill or stroke styles, pass null for the appropriate parameter.
- *
- * @param {ol.style.Fill} fillStyle Fill style.
- * @param {ol.style.Stroke} strokeStyle Stroke style.
- * @override
- */
- ol.render.canvas.Immediate.prototype.setFillStrokeStyle = function(fillStyle, strokeStyle) {
- if (!fillStyle) {
- this.fillState_ = null;
- } else {
- var fillStyleColor = fillStyle.getColor();
- this.fillState_ = {
- fillStyle: ol.colorlike.asColorLike(fillStyleColor ?
- fillStyleColor : ol.render.canvas.defaultFillStyle)
- };
- }
- if (!strokeStyle) {
- this.strokeState_ = null;
- } else {
- var strokeStyleColor = strokeStyle.getColor();
- var strokeStyleLineCap = strokeStyle.getLineCap();
- var strokeStyleLineDash = strokeStyle.getLineDash();
- var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();
- var strokeStyleLineJoin = strokeStyle.getLineJoin();
- var strokeStyleWidth = strokeStyle.getWidth();
- var strokeStyleMiterLimit = strokeStyle.getMiterLimit();
- this.strokeState_ = {
- lineCap: strokeStyleLineCap !== undefined ?
- strokeStyleLineCap : ol.render.canvas.defaultLineCap,
- lineDash: strokeStyleLineDash ?
- strokeStyleLineDash : ol.render.canvas.defaultLineDash,
- lineDashOffset: strokeStyleLineDashOffset ?
- strokeStyleLineDashOffset : ol.render.canvas.defaultLineDashOffset,
- lineJoin: strokeStyleLineJoin !== undefined ?
- strokeStyleLineJoin : ol.render.canvas.defaultLineJoin,
- lineWidth: this.pixelRatio_ * (strokeStyleWidth !== undefined ?
- strokeStyleWidth : ol.render.canvas.defaultLineWidth),
- miterLimit: strokeStyleMiterLimit !== undefined ?
- strokeStyleMiterLimit : ol.render.canvas.defaultMiterLimit,
- strokeStyle: ol.colorlike.asColorLike(strokeStyleColor ?
- strokeStyleColor : ol.render.canvas.defaultStrokeStyle)
- };
- }
- };
- /**
- * Set the image style for subsequent draw operations. Pass null to remove
- * the image style.
- *
- * @param {ol.style.Image} imageStyle Image style.
- * @override
- */
- ol.render.canvas.Immediate.prototype.setImageStyle = function(imageStyle) {
- if (!imageStyle) {
- this.image_ = null;
- } else {
- var imageAnchor = imageStyle.getAnchor();
- // FIXME pixel ratio
- var imageImage = imageStyle.getImage(1);
- var imageOrigin = imageStyle.getOrigin();
- var imageSize = imageStyle.getSize();
- this.imageAnchorX_ = imageAnchor[0];
- this.imageAnchorY_ = imageAnchor[1];
- this.imageHeight_ = imageSize[1];
- this.image_ = imageImage;
- this.imageOpacity_ = imageStyle.getOpacity();
- this.imageOriginX_ = imageOrigin[0];
- this.imageOriginY_ = imageOrigin[1];
- this.imageRotateWithView_ = imageStyle.getRotateWithView();
- this.imageRotation_ = imageStyle.getRotation();
- this.imageScale_ = imageStyle.getScale() * this.pixelRatio_;
- this.imageSnapToPixel_ = imageStyle.getSnapToPixel();
- this.imageWidth_ = imageSize[0];
- }
- };
- /**
- * Set the text style for subsequent draw operations. Pass null to
- * remove the text style.
- *
- * @param {ol.style.Text} textStyle Text style.
- * @override
- */
- ol.render.canvas.Immediate.prototype.setTextStyle = function(textStyle) {
- if (!textStyle) {
- this.text_ = '';
- } else {
- var textFillStyle = textStyle.getFill();
- if (!textFillStyle) {
- this.textFillState_ = null;
- } else {
- var textFillStyleColor = textFillStyle.getColor();
- this.textFillState_ = {
- fillStyle: ol.colorlike.asColorLike(textFillStyleColor ?
- textFillStyleColor : ol.render.canvas.defaultFillStyle)
- };
- }
- var textStrokeStyle = textStyle.getStroke();
- if (!textStrokeStyle) {
- this.textStrokeState_ = null;
- } else {
- var textStrokeStyleColor = textStrokeStyle.getColor();
- var textStrokeStyleLineCap = textStrokeStyle.getLineCap();
- var textStrokeStyleLineDash = textStrokeStyle.getLineDash();
- var textStrokeStyleLineDashOffset = textStrokeStyle.getLineDashOffset();
- var textStrokeStyleLineJoin = textStrokeStyle.getLineJoin();
- var textStrokeStyleWidth = textStrokeStyle.getWidth();
- var textStrokeStyleMiterLimit = textStrokeStyle.getMiterLimit();
- this.textStrokeState_ = {
- lineCap: textStrokeStyleLineCap !== undefined ?
- textStrokeStyleLineCap : ol.render.canvas.defaultLineCap,
- lineDash: textStrokeStyleLineDash ?
- textStrokeStyleLineDash : ol.render.canvas.defaultLineDash,
- lineDashOffset: textStrokeStyleLineDashOffset ?
- textStrokeStyleLineDashOffset : ol.render.canvas.defaultLineDashOffset,
- lineJoin: textStrokeStyleLineJoin !== undefined ?
- textStrokeStyleLineJoin : ol.render.canvas.defaultLineJoin,
- lineWidth: textStrokeStyleWidth !== undefined ?
- textStrokeStyleWidth : ol.render.canvas.defaultLineWidth,
- miterLimit: textStrokeStyleMiterLimit !== undefined ?
- textStrokeStyleMiterLimit : ol.render.canvas.defaultMiterLimit,
- strokeStyle: ol.colorlike.asColorLike(textStrokeStyleColor ?
- textStrokeStyleColor : ol.render.canvas.defaultStrokeStyle)
- };
- }
- var textFont = textStyle.getFont();
- var textOffsetX = textStyle.getOffsetX();
- var textOffsetY = textStyle.getOffsetY();
- var textRotateWithView = textStyle.getRotateWithView();
- var textRotation = textStyle.getRotation();
- var textScale = textStyle.getScale();
- var textText = textStyle.getText();
- var textTextAlign = textStyle.getTextAlign();
- var textTextBaseline = textStyle.getTextBaseline();
- this.textState_ = {
- font: textFont !== undefined ?
- textFont : ol.render.canvas.defaultFont,
- textAlign: textTextAlign !== undefined ?
- textTextAlign : ol.render.canvas.defaultTextAlign,
- textBaseline: textTextBaseline !== undefined ?
- textTextBaseline : ol.render.canvas.defaultTextBaseline
- };
- this.text_ = textText !== undefined ? textText : '';
- this.textOffsetX_ =
- textOffsetX !== undefined ? (this.pixelRatio_ * textOffsetX) : 0;
- this.textOffsetY_ =
- textOffsetY !== undefined ? (this.pixelRatio_ * textOffsetY) : 0;
- this.textRotateWithView_ = textRotateWithView !== undefined ? textRotateWithView : false;
- this.textRotation_ = textRotation !== undefined ? textRotation : 0;
- this.textScale_ = this.pixelRatio_ * (textScale !== undefined ?
- textScale : 1);
- }
- };
- goog.provide('ol.renderer.Layer');
- goog.require('ol');
- goog.require('ol.ImageState');
- goog.require('ol.Observable');
- goog.require('ol.TileState');
- goog.require('ol.asserts');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.functions');
- goog.require('ol.source.State');
- /**
- * @constructor
- * @extends {ol.Observable}
- * @param {ol.layer.Layer} layer Layer.
- * @struct
- */
- ol.renderer.Layer = function(layer) {
- ol.Observable.call(this);
- /**
- * @private
- * @type {ol.layer.Layer}
- */
- this.layer_ = layer;
- };
- ol.inherits(ol.renderer.Layer, ol.Observable);
- /**
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {olx.FrameState} frameState Frame state.
- * @param {number} hitTolerance Hit tolerance in pixels.
- * @param {function(this: S, (ol.Feature|ol.render.Feature), ol.layer.Layer): T}
- * callback Feature callback.
- * @param {S} thisArg Value to use as `this` when executing `callback`.
- * @return {T|undefined} Callback result.
- * @template S,T
- */
- ol.renderer.Layer.prototype.forEachFeatureAtCoordinate = ol.nullFunction;
- /**
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {olx.FrameState} frameState Frame state.
- * @return {boolean} Is there a feature at the given coordinate?
- */
- ol.renderer.Layer.prototype.hasFeatureAtCoordinate = ol.functions.FALSE;
- /**
- * Create a function that adds loaded tiles to the tile lookup.
- * @param {ol.source.Tile} source Tile source.
- * @param {ol.proj.Projection} projection Projection of the tiles.
- * @param {Object.<number, Object.<string, ol.Tile>>} tiles Lookup of loaded
- * tiles by zoom level.
- * @return {function(number, ol.TileRange):boolean} A function that can be
- * called with a zoom level and a tile range to add loaded tiles to the
- * lookup.
- * @protected
- */
- ol.renderer.Layer.prototype.createLoadedTileFinder = function(source, projection, tiles) {
- return (
- /**
- * @param {number} zoom Zoom level.
- * @param {ol.TileRange} tileRange Tile range.
- * @return {boolean} The tile range is fully loaded.
- */
- function(zoom, tileRange) {
- function callback(tile) {
- if (!tiles[zoom]) {
- tiles[zoom] = {};
- }
- tiles[zoom][tile.tileCoord.toString()] = tile;
- }
- return source.forEachLoadedTile(projection, zoom, tileRange, callback);
- });
- };
- /**
- * @return {ol.layer.Layer} Layer.
- */
- ol.renderer.Layer.prototype.getLayer = function() {
- return this.layer_;
- };
- /**
- * Handle changes in image state.
- * @param {ol.events.Event} event Image change event.
- * @private
- */
- ol.renderer.Layer.prototype.handleImageChange_ = function(event) {
- var image = /** @type {ol.Image} */ (event.target);
- if (image.getState() === ol.ImageState.LOADED) {
- this.renderIfReadyAndVisible();
- }
- };
- /**
- * Load the image if not already loaded, and register the image change
- * listener if needed.
- * @param {ol.ImageBase} image Image.
- * @return {boolean} `true` if the image is already loaded, `false`
- * otherwise.
- * @protected
- */
- ol.renderer.Layer.prototype.loadImage = function(image) {
- var imageState = image.getState();
- if (imageState != ol.ImageState.LOADED &&
- imageState != ol.ImageState.ERROR) {
- ol.events.listen(image, ol.events.EventType.CHANGE,
- this.handleImageChange_, this);
- }
- if (imageState == ol.ImageState.IDLE) {
- image.load();
- imageState = image.getState();
- }
- return imageState == ol.ImageState.LOADED;
- };
- /**
- * @protected
- */
- ol.renderer.Layer.prototype.renderIfReadyAndVisible = function() {
- var layer = this.getLayer();
- if (layer.getVisible() && layer.getSourceState() == ol.source.State.READY) {
- this.changed();
- }
- };
- /**
- * @param {olx.FrameState} frameState Frame state.
- * @param {ol.source.Tile} tileSource Tile source.
- * @protected
- */
- ol.renderer.Layer.prototype.scheduleExpireCache = function(frameState, tileSource) {
- if (tileSource.canExpireCache()) {
- /**
- * @param {ol.source.Tile} tileSource Tile source.
- * @param {ol.PluggableMap} map Map.
- * @param {olx.FrameState} frameState Frame state.
- */
- var postRenderFunction = function(tileSource, map, frameState) {
- var tileSourceKey = ol.getUid(tileSource).toString();
- if (tileSourceKey in frameState.usedTiles) {
- tileSource.expireCache(frameState.viewState.projection,
- frameState.usedTiles[tileSourceKey]);
- }
- }.bind(null, tileSource);
- frameState.postRenderFunctions.push(
- /** @type {ol.PostRenderFunction} */ (postRenderFunction)
- );
- }
- };
- /**
- * @param {olx.FrameState} frameState Frame state.
- * @param {ol.source.Source} source Source.
- * @protected
- */
- ol.renderer.Layer.prototype.updateLogos = function(frameState, source) {
- var logo = source.getLogo();
- if (logo !== undefined) {
- if (typeof logo === 'string') {
- frameState.logos[logo] = '';
- } else if (logo) {
- ol.asserts.assert(typeof logo.href == 'string', 44); // `logo.href` should be a string.
- ol.asserts.assert(typeof logo.src == 'string', 45); // `logo.src` should be a string.
- frameState.logos[logo.src] = logo.href;
- }
- }
- };
- /**
- * @param {Object.<string, Object.<string, ol.TileRange>>} usedTiles Used tiles.
- * @param {ol.source.Tile} tileSource Tile source.
- * @param {number} z Z.
- * @param {ol.TileRange} tileRange Tile range.
- * @protected
- */
- ol.renderer.Layer.prototype.updateUsedTiles = function(usedTiles, tileSource, z, tileRange) {
- // FIXME should we use tilesToDrawByZ instead?
- var tileSourceKey = ol.getUid(tileSource).toString();
- var zKey = z.toString();
- if (tileSourceKey in usedTiles) {
- if (zKey in usedTiles[tileSourceKey]) {
- usedTiles[tileSourceKey][zKey].extend(tileRange);
- } else {
- usedTiles[tileSourceKey][zKey] = tileRange;
- }
- } else {
- usedTiles[tileSourceKey] = {};
- usedTiles[tileSourceKey][zKey] = tileRange;
- }
- };
- /**
- * Manage tile pyramid.
- * This function performs a number of functions related to the tiles at the
- * current zoom and lower zoom levels:
- * - registers idle tiles in frameState.wantedTiles so that they are not
- * discarded by the tile queue
- * - enqueues missing tiles
- * @param {olx.FrameState} frameState Frame state.
- * @param {ol.source.Tile} tileSource Tile source.
- * @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.proj.Projection} projection Projection.
- * @param {ol.Extent} extent Extent.
- * @param {number} currentZ Current Z.
- * @param {number} preload Load low resolution tiles up to 'preload' levels.
- * @param {function(this: T, ol.Tile)=} opt_tileCallback Tile callback.
- * @param {T=} opt_this Object to use as `this` in `opt_tileCallback`.
- * @protected
- * @template T
- */
- ol.renderer.Layer.prototype.manageTilePyramid = function(
- frameState, tileSource, tileGrid, pixelRatio, projection, extent,
- currentZ, preload, opt_tileCallback, opt_this) {
- var tileSourceKey = ol.getUid(tileSource).toString();
- if (!(tileSourceKey in frameState.wantedTiles)) {
- frameState.wantedTiles[tileSourceKey] = {};
- }
- var wantedTiles = frameState.wantedTiles[tileSourceKey];
- var tileQueue = frameState.tileQueue;
- var minZoom = tileGrid.getMinZoom();
- var tile, tileRange, tileResolution, x, y, z;
- for (z = minZoom; z <= currentZ; ++z) {
- tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z, tileRange);
- tileResolution = tileGrid.getResolution(z);
- for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
- for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
- if (currentZ - z <= preload) {
- tile = tileSource.getTile(z, x, y, pixelRatio, projection);
- if (tile.getState() == ol.TileState.IDLE) {
- wantedTiles[tile.getKey()] = true;
- if (!tileQueue.isKeyQueued(tile.getKey())) {
- tileQueue.enqueue([tile, tileSourceKey,
- tileGrid.getTileCoordCenter(tile.tileCoord), tileResolution]);
- }
- }
- if (opt_tileCallback !== undefined) {
- opt_tileCallback.call(opt_this, tile);
- }
- } else {
- tileSource.useTile(z, x, y, projection);
- }
- }
- }
- }
- };
- goog.provide('ol.renderer.canvas.Layer');
- goog.require('ol');
- goog.require('ol.extent');
- goog.require('ol.functions');
- goog.require('ol.render.Event');
- goog.require('ol.render.EventType');
- goog.require('ol.render.canvas');
- goog.require('ol.render.canvas.Immediate');
- goog.require('ol.renderer.Layer');
- goog.require('ol.transform');
- /**
- * @constructor
- * @abstract
- * @extends {ol.renderer.Layer}
- * @param {ol.layer.Layer} layer Layer.
- */
- ol.renderer.canvas.Layer = function(layer) {
- ol.renderer.Layer.call(this, layer);
- /**
- * @protected
- * @type {number}
- */
- this.renderedResolution;
- /**
- * @private
- * @type {ol.Transform}
- */
- this.transform_ = ol.transform.create();
- };
- ol.inherits(ol.renderer.canvas.Layer, ol.renderer.Layer);
- /**
- * @param {CanvasRenderingContext2D} context Context.
- * @param {olx.FrameState} frameState Frame state.
- * @param {ol.Extent} extent Clip extent.
- * @protected
- */
- ol.renderer.canvas.Layer.prototype.clip = function(context, frameState, extent) {
- var pixelRatio = frameState.pixelRatio;
- var width = frameState.size[0] * pixelRatio;
- var height = frameState.size[1] * pixelRatio;
- var rotation = frameState.viewState.rotation;
- var topLeft = ol.extent.getTopLeft(/** @type {ol.Extent} */ (extent));
- var topRight = ol.extent.getTopRight(/** @type {ol.Extent} */ (extent));
- var bottomRight = ol.extent.getBottomRight(/** @type {ol.Extent} */ (extent));
- var bottomLeft = ol.extent.getBottomLeft(/** @type {ol.Extent} */ (extent));
- ol.transform.apply(frameState.coordinateToPixelTransform, topLeft);
- ol.transform.apply(frameState.coordinateToPixelTransform, topRight);
- ol.transform.apply(frameState.coordinateToPixelTransform, bottomRight);
- ol.transform.apply(frameState.coordinateToPixelTransform, bottomLeft);
- context.save();
- ol.render.canvas.rotateAtOffset(context, -rotation, width / 2, height / 2);
- context.beginPath();
- context.moveTo(topLeft[0] * pixelRatio, topLeft[1] * pixelRatio);
- context.lineTo(topRight[0] * pixelRatio, topRight[1] * pixelRatio);
- context.lineTo(bottomRight[0] * pixelRatio, bottomRight[1] * pixelRatio);
- context.lineTo(bottomLeft[0] * pixelRatio, bottomLeft[1] * pixelRatio);
- context.clip();
- ol.render.canvas.rotateAtOffset(context, rotation, width / 2, height / 2);
- };
- /**
- * @param {ol.render.EventType} type Event type.
- * @param {CanvasRenderingContext2D} context Context.
- * @param {olx.FrameState} frameState Frame state.
- * @param {ol.Transform=} opt_transform Transform.
- * @private
- */
- ol.renderer.canvas.Layer.prototype.dispatchComposeEvent_ = function(type, context, frameState, opt_transform) {
- var layer = this.getLayer();
- if (layer.hasListener(type)) {
- var width = frameState.size[0] * frameState.pixelRatio;
- var height = frameState.size[1] * frameState.pixelRatio;
- var rotation = frameState.viewState.rotation;
- ol.render.canvas.rotateAtOffset(context, -rotation, width / 2, height / 2);
- var transform = opt_transform !== undefined ?
- opt_transform : this.getTransform(frameState, 0);
- var render = new ol.render.canvas.Immediate(
- context, frameState.pixelRatio, frameState.extent, transform,
- frameState.viewState.rotation);
- var composeEvent = new ol.render.Event(type, render, frameState,
- context, null);
- layer.dispatchEvent(composeEvent);
- ol.render.canvas.rotateAtOffset(context, rotation, width / 2, height / 2);
- }
- };
- /**
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {olx.FrameState} frameState FrameState.
- * @param {function(this: S, ol.layer.Layer, (Uint8ClampedArray|Uint8Array)): T} callback Layer
- * callback.
- * @param {S} thisArg Value to use as `this` when executing `callback`.
- * @return {T|undefined} Callback result.
- * @template S,T,U
- */
- ol.renderer.canvas.Layer.prototype.forEachLayerAtCoordinate = function(coordinate, frameState, callback, thisArg) {
- var hasFeature = this.forEachFeatureAtCoordinate(
- coordinate, frameState, 0, ol.functions.TRUE, this);
- if (hasFeature) {
- return callback.call(thisArg, this.getLayer(), null);
- } else {
- return undefined;
- }
- };
- /**
- * @param {CanvasRenderingContext2D} context Context.
- * @param {olx.FrameState} frameState Frame state.
- * @param {ol.LayerState} layerState Layer state.
- * @param {ol.Transform=} opt_transform Transform.
- * @protected
- */
- ol.renderer.canvas.Layer.prototype.postCompose = function(context, frameState, layerState, opt_transform) {
- this.dispatchComposeEvent_(ol.render.EventType.POSTCOMPOSE, context,
- frameState, opt_transform);
- };
- /**
- * @param {CanvasRenderingContext2D} context Context.
- * @param {olx.FrameState} frameState Frame state.
- * @param {ol.Transform=} opt_transform Transform.
- * @protected
- */
- ol.renderer.canvas.Layer.prototype.preCompose = function(context, frameState, opt_transform) {
- this.dispatchComposeEvent_(ol.render.EventType.PRECOMPOSE, context,
- frameState, opt_transform);
- };
- /**
- * @param {CanvasRenderingContext2D} context Context.
- * @param {olx.FrameState} frameState Frame state.
- * @param {ol.Transform=} opt_transform Transform.
- * @protected
- */
- ol.renderer.canvas.Layer.prototype.dispatchRenderEvent = function(context, frameState, opt_transform) {
- this.dispatchComposeEvent_(ol.render.EventType.RENDER, context,
- frameState, opt_transform);
- };
- /**
- * @param {olx.FrameState} frameState Frame state.
- * @param {number} offsetX Offset on the x-axis in view coordinates.
- * @protected
- * @return {!ol.Transform} Transform.
- */
- ol.renderer.canvas.Layer.prototype.getTransform = function(frameState, offsetX) {
- var viewState = frameState.viewState;
- var pixelRatio = frameState.pixelRatio;
- var dx1 = pixelRatio * frameState.size[0] / 2;
- var dy1 = pixelRatio * frameState.size[1] / 2;
- var sx = pixelRatio / viewState.resolution;
- var sy = -sx;
- var angle = -viewState.rotation;
- var dx2 = -viewState.center[0] + offsetX;
- var dy2 = -viewState.center[1];
- return ol.transform.compose(this.transform_, dx1, dy1, sx, sy, angle, dx2, dy2);
- };
- /**
- * @abstract
- * @param {olx.FrameState} frameState Frame state.
- * @param {ol.LayerState} layerState Layer state.
- * @param {CanvasRenderingContext2D} context Context.
- */
- ol.renderer.canvas.Layer.prototype.composeFrame = function(frameState, layerState, context) {};
- /**
- * @abstract
- * @param {olx.FrameState} frameState Frame state.
- * @param {ol.LayerState} layerState Layer state.
- * @return {boolean} whether composeFrame should be called.
- */
- ol.renderer.canvas.Layer.prototype.prepareFrame = function(frameState, layerState) {};
- goog.provide('ol.renderer.canvas.IntermediateCanvas');
- goog.require('ol');
- goog.require('ol.coordinate');
- goog.require('ol.dom');
- goog.require('ol.extent');
- goog.require('ol.renderer.canvas.Layer');
- goog.require('ol.transform');
- /**
- * @constructor
- * @abstract
- * @extends {ol.renderer.canvas.Layer}
- * @param {ol.layer.Layer} layer Layer.
- */
- ol.renderer.canvas.IntermediateCanvas = function(layer) {
- ol.renderer.canvas.Layer.call(this, layer);
- /**
- * @protected
- * @type {ol.Transform}
- */
- this.coordinateToCanvasPixelTransform = ol.transform.create();
- /**
- * @private
- * @type {CanvasRenderingContext2D}
- */
- this.hitCanvasContext_ = null;
- };
- ol.inherits(ol.renderer.canvas.IntermediateCanvas, ol.renderer.canvas.Layer);
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.IntermediateCanvas.prototype.composeFrame = function(frameState, layerState, context) {
- this.preCompose(context, frameState);
- var image = this.getImage();
- if (image) {
- // clipped rendering if layer extent is set
- var extent = layerState.extent;
- var clipped = extent !== undefined &&
- !ol.extent.containsExtent(extent, frameState.extent) &&
- ol.extent.intersects(extent, frameState.extent);
- if (clipped) {
- this.clip(context, frameState, /** @type {ol.Extent} */ (extent));
- }
- var imageTransform = this.getImageTransform();
- // for performance reasons, context.save / context.restore is not used
- // to save and restore the transformation matrix and the opacity.
- // see http://jsperf.com/context-save-restore-versus-variable
- var alpha = context.globalAlpha;
- context.globalAlpha = layerState.opacity;
- // for performance reasons, context.setTransform is only used
- // when the view is rotated. see http://jsperf.com/canvas-transform
- var dx = imageTransform[4];
- var dy = imageTransform[5];
- var dw = image.width * imageTransform[0];
- var dh = image.height * imageTransform[3];
- context.drawImage(image, 0, 0, +image.width, +image.height,
- Math.round(dx), Math.round(dy), Math.round(dw), Math.round(dh));
- context.globalAlpha = alpha;
- if (clipped) {
- context.restore();
- }
- }
- this.postCompose(context, frameState, layerState);
- };
- /**
- * @abstract
- * @return {HTMLCanvasElement|HTMLVideoElement|Image} Canvas.
- */
- ol.renderer.canvas.IntermediateCanvas.prototype.getImage = function() {};
- /**
- * @abstract
- * @return {!ol.Transform} Image transform.
- */
- ol.renderer.canvas.IntermediateCanvas.prototype.getImageTransform = function() {};
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.IntermediateCanvas.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, hitTolerance, callback, thisArg) {
- var layer = this.getLayer();
- var source = layer.getSource();
- var resolution = frameState.viewState.resolution;
- var rotation = frameState.viewState.rotation;
- var skippedFeatureUids = frameState.skippedFeatureUids;
- return source.forEachFeatureAtCoordinate(
- coordinate, resolution, rotation, hitTolerance, skippedFeatureUids,
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @return {?} Callback result.
- */
- function(feature) {
- return callback.call(thisArg, feature, layer);
- });
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.IntermediateCanvas.prototype.forEachLayerAtCoordinate = function(coordinate, frameState, callback, thisArg) {
- if (!this.getImage()) {
- return undefined;
- }
- if (this.getLayer().getSource().forEachFeatureAtCoordinate !== ol.nullFunction) {
- // for ImageCanvas sources use the original hit-detection logic,
- // so that for example also transparent polygons are detected
- return ol.renderer.canvas.Layer.prototype.forEachLayerAtCoordinate.apply(this, arguments);
- } else {
- var pixel = ol.transform.apply(this.coordinateToCanvasPixelTransform, coordinate.slice());
- ol.coordinate.scale(pixel, frameState.viewState.resolution / this.renderedResolution);
- if (!this.hitCanvasContext_) {
- this.hitCanvasContext_ = ol.dom.createCanvasContext2D(1, 1);
- }
- this.hitCanvasContext_.clearRect(0, 0, 1, 1);
- this.hitCanvasContext_.drawImage(this.getImage(), pixel[0], pixel[1], 1, 1, 0, 0, 1, 1);
- var imageData = this.hitCanvasContext_.getImageData(0, 0, 1, 1).data;
- if (imageData[3] > 0) {
- return callback.call(thisArg, this.getLayer(), imageData);
- } else {
- return undefined;
- }
- }
- };
- goog.provide('ol.renderer.canvas.ImageLayer');
- goog.require('ol');
- goog.require('ol.ImageCanvas');
- goog.require('ol.LayerType');
- goog.require('ol.ViewHint');
- goog.require('ol.array');
- goog.require('ol.extent');
- goog.require('ol.layer.VectorRenderType');
- goog.require('ol.obj');
- goog.require('ol.plugins');
- goog.require('ol.renderer.Type');
- goog.require('ol.renderer.canvas.IntermediateCanvas');
- goog.require('ol.transform');
- /**
- * @constructor
- * @extends {ol.renderer.canvas.IntermediateCanvas}
- * @param {ol.layer.Image} imageLayer Single image layer.
- * @api
- */
- ol.renderer.canvas.ImageLayer = function(imageLayer) {
- ol.renderer.canvas.IntermediateCanvas.call(this, imageLayer);
- /**
- * @private
- * @type {?ol.ImageBase}
- */
- this.image_ = null;
- /**
- * @private
- * @type {ol.Transform}
- */
- this.imageTransform_ = ol.transform.create();
- /**
- * @type {!Array.<string>}
- */
- this.skippedFeatures_ = [];
- /**
- * @private
- * @type {ol.renderer.canvas.VectorLayer}
- */
- this.vectorRenderer_ = null;
- };
- ol.inherits(ol.renderer.canvas.ImageLayer, ol.renderer.canvas.IntermediateCanvas);
- /**
- * Determine if this renderer handles the provided layer.
- * @param {ol.renderer.Type} type The renderer type.
- * @param {ol.layer.Layer} layer The candidate layer.
- * @return {boolean} The renderer can render the layer.
- */
- ol.renderer.canvas.ImageLayer['handles'] = function(type, layer) {
- return type === ol.renderer.Type.CANVAS && (layer.getType() === ol.LayerType.IMAGE ||
- layer.getType() === ol.LayerType.VECTOR &&
- /** @type {ol.layer.Vector} */ (layer).getRenderMode() === ol.layer.VectorRenderType.IMAGE);
- };
- /**
- * Create a layer renderer.
- * @param {ol.renderer.Map} mapRenderer The map renderer.
- * @param {ol.layer.Layer} layer The layer to be rendererd.
- * @return {ol.renderer.canvas.ImageLayer} The layer renderer.
- */
- ol.renderer.canvas.ImageLayer['create'] = function(mapRenderer, layer) {
- var renderer = new ol.renderer.canvas.ImageLayer(/** @type {ol.layer.Image} */ (layer));
- if (layer.getType() === ol.LayerType.VECTOR) {
- var candidates = ol.plugins.getLayerRendererPlugins();
- for (var i = 0, ii = candidates.length; i < ii; ++i) {
- var candidate = /** @type {Object.<string, Function>} */ (candidates[i]);
- if (candidate !== ol.renderer.canvas.ImageLayer && candidate['handles'](ol.renderer.Type.CANVAS, layer)) {
- renderer.setVectorRenderer(candidate['create'](mapRenderer, layer));
- }
- }
- }
- return renderer;
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.ImageLayer.prototype.getImage = function() {
- return !this.image_ ? null : this.image_.getImage();
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.ImageLayer.prototype.getImageTransform = function() {
- return this.imageTransform_;
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.ImageLayer.prototype.prepareFrame = function(frameState, layerState) {
- var pixelRatio = frameState.pixelRatio;
- var size = frameState.size;
- var viewState = frameState.viewState;
- var viewCenter = viewState.center;
- var viewResolution = viewState.resolution;
- var image;
- var imageLayer = /** @type {ol.layer.Image} */ (this.getLayer());
- var imageSource = imageLayer.getSource();
- var hints = frameState.viewHints;
- var renderedExtent = frameState.extent;
- if (layerState.extent !== undefined) {
- renderedExtent = ol.extent.getIntersection(
- renderedExtent, layerState.extent);
- }
- if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.INTERACTING] &&
- !ol.extent.isEmpty(renderedExtent)) {
- var projection = viewState.projection;
- if (!ol.ENABLE_RASTER_REPROJECTION) {
- var sourceProjection = imageSource.getProjection();
- if (sourceProjection) {
- projection = sourceProjection;
- }
- }
- var vectorRenderer = this.vectorRenderer_;
- if (vectorRenderer) {
- var context = vectorRenderer.context;
- var imageFrameState = /** @type {olx.FrameState} */ (ol.obj.assign({}, frameState, {
- size: [
- ol.extent.getWidth(renderedExtent) / viewResolution,
- ol.extent.getHeight(renderedExtent) / viewResolution
- ],
- viewState: /** @type {olx.ViewState} */ (ol.obj.assign({}, frameState.viewState, {
- rotation: 0
- }))
- }));
- var skippedFeatures = Object.keys(imageFrameState.skippedFeatureUids).sort();
- if (vectorRenderer.prepareFrame(imageFrameState, layerState) &&
- (vectorRenderer.replayGroupChanged ||
- !ol.array.equals(skippedFeatures, this.skippedFeatures_))) {
- context.canvas.width = imageFrameState.size[0] * pixelRatio;
- context.canvas.height = imageFrameState.size[1] * pixelRatio;
- vectorRenderer.composeFrame(imageFrameState, layerState, context);
- this.image_ = new ol.ImageCanvas(renderedExtent, viewResolution, pixelRatio, context.canvas);
- this.skippedFeatures_ = skippedFeatures;
- }
- } else {
- image = imageSource.getImage(
- renderedExtent, viewResolution, pixelRatio, projection);
- if (image) {
- var loaded = this.loadImage(image);
- if (loaded) {
- this.image_ = image;
- }
- }
- }
- }
- if (this.image_) {
- image = this.image_;
- var imageExtent = image.getExtent();
- var imageResolution = image.getResolution();
- var imagePixelRatio = image.getPixelRatio();
- var scale = pixelRatio * imageResolution /
- (viewResolution * imagePixelRatio);
- var transform = ol.transform.compose(this.imageTransform_,
- pixelRatio * size[0] / 2, pixelRatio * size[1] / 2,
- scale, scale,
- 0,
- imagePixelRatio * (imageExtent[0] - viewCenter[0]) / imageResolution,
- imagePixelRatio * (viewCenter[1] - imageExtent[3]) / imageResolution);
- ol.transform.compose(this.coordinateToCanvasPixelTransform,
- pixelRatio * size[0] / 2 - transform[4], pixelRatio * size[1] / 2 - transform[5],
- pixelRatio / viewResolution, -pixelRatio / viewResolution,
- 0,
- -viewCenter[0], -viewCenter[1]);
- this.updateLogos(frameState, imageSource);
- this.renderedResolution = imageResolution * pixelRatio / imagePixelRatio;
- }
- return !!this.image_;
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.ImageLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, hitTolerance, callback, thisArg) {
- if (this.vectorRenderer_) {
- return this.vectorRenderer_.forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback, thisArg);
- } else {
- return ol.renderer.canvas.IntermediateCanvas.prototype.forEachFeatureAtCoordinate.call(this, coordinate, frameState, hitTolerance, callback, thisArg);
- }
- };
- /**
- * @param {ol.renderer.canvas.VectorLayer} renderer Vector renderer.
- */
- ol.renderer.canvas.ImageLayer.prototype.setVectorRenderer = function(renderer) {
- this.vectorRenderer_ = renderer;
- };
- goog.provide('ol.style.IconImageCache');
- goog.require('ol.color');
- /**
- * Singleton class. Available through {@link ol.style.iconImageCache}.
- * @constructor
- */
- ol.style.IconImageCache = function() {
- /**
- * @type {Object.<string, ol.style.IconImage>}
- * @private
- */
- this.cache_ = {};
- /**
- * @type {number}
- * @private
- */
- this.cacheSize_ = 0;
- /**
- * @type {number}
- * @private
- */
- this.maxCacheSize_ = 32;
- };
- /**
- * @param {string} src Src.
- * @param {?string} crossOrigin Cross origin.
- * @param {ol.Color} color Color.
- * @return {string} Cache key.
- */
- ol.style.IconImageCache.getKey = function(src, crossOrigin, color) {
- var colorString = color ? ol.color.asString(color) : 'null';
- return crossOrigin + ':' + src + ':' + colorString;
- };
- /**
- * FIXME empty description for jsdoc
- */
- ol.style.IconImageCache.prototype.clear = function() {
- this.cache_ = {};
- this.cacheSize_ = 0;
- };
- /**
- * FIXME empty description for jsdoc
- */
- ol.style.IconImageCache.prototype.expire = function() {
- if (this.cacheSize_ > this.maxCacheSize_) {
- var i = 0;
- var key, iconImage;
- for (key in this.cache_) {
- iconImage = this.cache_[key];
- if ((i++ & 3) === 0 && !iconImage.hasListener()) {
- delete this.cache_[key];
- --this.cacheSize_;
- }
- }
- }
- };
- /**
- * @param {string} src Src.
- * @param {?string} crossOrigin Cross origin.
- * @param {ol.Color} color Color.
- * @return {ol.style.IconImage} Icon image.
- */
- ol.style.IconImageCache.prototype.get = function(src, crossOrigin, color) {
- var key = ol.style.IconImageCache.getKey(src, crossOrigin, color);
- return key in this.cache_ ? this.cache_[key] : null;
- };
- /**
- * @param {string} src Src.
- * @param {?string} crossOrigin Cross origin.
- * @param {ol.Color} color Color.
- * @param {ol.style.IconImage} iconImage Icon image.
- */
- ol.style.IconImageCache.prototype.set = function(src, crossOrigin, color, iconImage) {
- var key = ol.style.IconImageCache.getKey(src, crossOrigin, color);
- this.cache_[key] = iconImage;
- ++this.cacheSize_;
- };
- /**
- * Set the cache size of the icon cache. Default is `32`. Change this value when
- * your map uses more than 32 different icon images and you are not caching icon
- * styles on the application level.
- * @param {number} maxCacheSize Cache max size.
- * @api
- */
- ol.style.IconImageCache.prototype.setSize = function(maxCacheSize) {
- this.maxCacheSize_ = maxCacheSize;
- this.expire();
- };
- goog.provide('ol.style');
- goog.require('ol.style.IconImageCache');
- /**
- * The {@link ol.style.IconImageCache} for {@link ol.style.Icon} images.
- * @api
- */
- ol.style.iconImageCache = new ol.style.IconImageCache();
- goog.provide('ol.renderer.Map');
- goog.require('ol');
- goog.require('ol.Disposable');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.extent');
- goog.require('ol.functions');
- goog.require('ol.layer.Layer');
- goog.require('ol.plugins');
- goog.require('ol.style');
- goog.require('ol.transform');
- /**
- * @constructor
- * @abstract
- * @extends {ol.Disposable}
- * @param {Element} container Container.
- * @param {ol.PluggableMap} map Map.
- * @struct
- */
- ol.renderer.Map = function(container, map) {
- ol.Disposable.call(this);
- /**
- * @private
- * @type {ol.PluggableMap}
- */
- this.map_ = map;
- /**
- * @private
- * @type {Object.<string, ol.renderer.Layer>}
- */
- this.layerRenderers_ = {};
- /**
- * @private
- * @type {Object.<string, ol.EventsKey>}
- */
- this.layerRendererListeners_ = {};
- };
- ol.inherits(ol.renderer.Map, ol.Disposable);
- /**
- * @param {olx.FrameState} frameState FrameState.
- * @protected
- */
- ol.renderer.Map.prototype.calculateMatrices2D = function(frameState) {
- var viewState = frameState.viewState;
- var coordinateToPixelTransform = frameState.coordinateToPixelTransform;
- var pixelToCoordinateTransform = frameState.pixelToCoordinateTransform;
- ol.transform.compose(coordinateToPixelTransform,
- frameState.size[0] / 2, frameState.size[1] / 2,
- 1 / viewState.resolution, -1 / viewState.resolution,
- -viewState.rotation,
- -viewState.center[0], -viewState.center[1]);
- ol.transform.invert(
- ol.transform.setFromArray(pixelToCoordinateTransform, coordinateToPixelTransform));
- };
- /**
- * Removes all layer renderers.
- */
- ol.renderer.Map.prototype.removeLayerRenderers = function() {
- for (var key in this.layerRenderers_) {
- this.removeLayerRendererByKey_(key).dispose();
- }
- };
- /**
- * @param {ol.PluggableMap} map Map.
- * @param {olx.FrameState} frameState Frame state.
- * @private
- */
- ol.renderer.Map.expireIconCache_ = function(map, frameState) {
- var cache = ol.style.iconImageCache;
- cache.expire();
- };
- /**
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {olx.FrameState} frameState FrameState.
- * @param {number} hitTolerance Hit tolerance in pixels.
- * @param {function(this: S, (ol.Feature|ol.render.Feature),
- * ol.layer.Layer): T} callback Feature callback.
- * @param {S} thisArg Value to use as `this` when executing `callback`.
- * @param {function(this: U, ol.layer.Layer): boolean} layerFilter Layer filter
- * function, only layers which are visible and for which this function
- * returns `true` will be tested for features. By default, all visible
- * layers will be tested.
- * @param {U} thisArg2 Value to use as `this` when executing `layerFilter`.
- * @return {T|undefined} Callback result.
- * @template S,T,U
- */
- ol.renderer.Map.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, hitTolerance, callback, thisArg,
- layerFilter, thisArg2) {
- var result;
- var viewState = frameState.viewState;
- var viewResolution = viewState.resolution;
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @param {ol.layer.Layer} layer Layer.
- * @return {?} Callback result.
- */
- function forEachFeatureAtCoordinate(feature, layer) {
- var key = ol.getUid(feature).toString();
- var managed = frameState.layerStates[ol.getUid(layer)].managed;
- if (!(key in frameState.skippedFeatureUids && !managed)) {
- return callback.call(thisArg, feature, managed ? layer : null);
- }
- }
- var projection = viewState.projection;
- var translatedCoordinate = coordinate;
- if (projection.canWrapX()) {
- var projectionExtent = projection.getExtent();
- var worldWidth = ol.extent.getWidth(projectionExtent);
- var x = coordinate[0];
- if (x < projectionExtent[0] || x > projectionExtent[2]) {
- var worldsAway = Math.ceil((projectionExtent[0] - x) / worldWidth);
- translatedCoordinate = [x + worldWidth * worldsAway, coordinate[1]];
- }
- }
- var layerStates = frameState.layerStatesArray;
- var numLayers = layerStates.length;
- var i;
- for (i = numLayers - 1; i >= 0; --i) {
- var layerState = layerStates[i];
- var layer = layerState.layer;
- if (ol.layer.Layer.visibleAtResolution(layerState, viewResolution) &&
- layerFilter.call(thisArg2, layer)) {
- var layerRenderer = this.getLayerRenderer(layer);
- if (layer.getSource()) {
- result = layerRenderer.forEachFeatureAtCoordinate(
- layer.getSource().getWrapX() ? translatedCoordinate : coordinate,
- frameState, hitTolerance, forEachFeatureAtCoordinate, thisArg);
- }
- if (result) {
- return result;
- }
- }
- }
- return undefined;
- };
- /**
- * @abstract
- * @param {ol.Pixel} pixel Pixel.
- * @param {olx.FrameState} frameState FrameState.
- * @param {function(this: S, ol.layer.Layer, (Uint8ClampedArray|Uint8Array)): T} callback Layer
- * callback.
- * @param {S} thisArg Value to use as `this` when executing `callback`.
- * @param {function(this: U, ol.layer.Layer): boolean} layerFilter Layer filter
- * function, only layers which are visible and for which this function
- * returns `true` will be tested for features. By default, all visible
- * layers will be tested.
- * @param {U} thisArg2 Value to use as `this` when executing `layerFilter`.
- * @return {T|undefined} Callback result.
- * @template S,T,U
- */
- ol.renderer.Map.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg,
- layerFilter, thisArg2) {};
- /**
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {olx.FrameState} frameState FrameState.
- * @param {number} hitTolerance Hit tolerance in pixels.
- * @param {function(this: U, ol.layer.Layer): boolean} layerFilter Layer filter
- * function, only layers which are visible and for which this function
- * returns `true` will be tested for features. By default, all visible
- * layers will be tested.
- * @param {U} thisArg Value to use as `this` when executing `layerFilter`.
- * @return {boolean} Is there a feature at the given coordinate?
- * @template U
- */
- ol.renderer.Map.prototype.hasFeatureAtCoordinate = function(coordinate, frameState, hitTolerance, layerFilter, thisArg) {
- var hasFeature = this.forEachFeatureAtCoordinate(
- coordinate, frameState, hitTolerance, ol.functions.TRUE, this, layerFilter, thisArg);
- return hasFeature !== undefined;
- };
- /**
- * @param {ol.layer.Layer} layer Layer.
- * @protected
- * @return {ol.renderer.Layer} Layer renderer.
- */
- ol.renderer.Map.prototype.getLayerRenderer = function(layer) {
- var layerKey = ol.getUid(layer).toString();
- if (layerKey in this.layerRenderers_) {
- return this.layerRenderers_[layerKey];
- } else {
- var layerRendererPlugins = ol.plugins.getLayerRendererPlugins();
- var renderer;
- var type = this.getType();
- for (var i = 0, ii = layerRendererPlugins.length; i < ii; ++i) {
- var plugin = layerRendererPlugins[i];
- if (plugin['handles'](type, layer)) {
- renderer = plugin['create'](this, layer);
- break;
- }
- }
- if (renderer) {
- this.layerRenderers_[layerKey] = renderer;
- this.layerRendererListeners_[layerKey] = ol.events.listen(renderer,
- ol.events.EventType.CHANGE, this.handleLayerRendererChange_, this);
- } else {
- throw new Error('Unable to create renderer for layer: ' + layer.getType());
- }
- return renderer;
- }
- };
- /**
- * @param {string} layerKey Layer key.
- * @protected
- * @return {ol.renderer.Layer} Layer renderer.
- */
- ol.renderer.Map.prototype.getLayerRendererByKey = function(layerKey) {
- return this.layerRenderers_[layerKey];
- };
- /**
- * @protected
- * @return {Object.<string, ol.renderer.Layer>} Layer renderers.
- */
- ol.renderer.Map.prototype.getLayerRenderers = function() {
- return this.layerRenderers_;
- };
- /**
- * @return {ol.PluggableMap} Map.
- */
- ol.renderer.Map.prototype.getMap = function() {
- return this.map_;
- };
- /**
- * @abstract
- * @return {ol.renderer.Type} Type
- */
- ol.renderer.Map.prototype.getType = function() {};
- /**
- * Handle changes in a layer renderer.
- * @private
- */
- ol.renderer.Map.prototype.handleLayerRendererChange_ = function() {
- this.map_.render();
- };
- /**
- * @param {string} layerKey Layer key.
- * @return {ol.renderer.Layer} Layer renderer.
- * @private
- */
- ol.renderer.Map.prototype.removeLayerRendererByKey_ = function(layerKey) {
- var layerRenderer = this.layerRenderers_[layerKey];
- delete this.layerRenderers_[layerKey];
- ol.events.unlistenByKey(this.layerRendererListeners_[layerKey]);
- delete this.layerRendererListeners_[layerKey];
- return layerRenderer;
- };
- /**
- * Render.
- * @param {?olx.FrameState} frameState Frame state.
- */
- ol.renderer.Map.prototype.renderFrame = ol.nullFunction;
- /**
- * @param {ol.PluggableMap} map Map.
- * @param {olx.FrameState} frameState Frame state.
- * @private
- */
- ol.renderer.Map.prototype.removeUnusedLayerRenderers_ = function(map, frameState) {
- var layerKey;
- for (layerKey in this.layerRenderers_) {
- if (!frameState || !(layerKey in frameState.layerStates)) {
- this.removeLayerRendererByKey_(layerKey).dispose();
- }
- }
- };
- /**
- * @param {olx.FrameState} frameState Frame state.
- * @protected
- */
- ol.renderer.Map.prototype.scheduleExpireIconCache = function(frameState) {
- frameState.postRenderFunctions.push(
- /** @type {ol.PostRenderFunction} */ (ol.renderer.Map.expireIconCache_)
- );
- };
- /**
- * @param {!olx.FrameState} frameState Frame state.
- * @protected
- */
- ol.renderer.Map.prototype.scheduleRemoveUnusedLayerRenderers = function(frameState) {
- var layerKey;
- for (layerKey in this.layerRenderers_) {
- if (!(layerKey in frameState.layerStates)) {
- frameState.postRenderFunctions.push(
- /** @type {ol.PostRenderFunction} */ (this.removeUnusedLayerRenderers_.bind(this))
- );
- return;
- }
- }
- };
- /**
- * @param {ol.LayerState} state1 First layer state.
- * @param {ol.LayerState} state2 Second layer state.
- * @return {number} The zIndex difference.
- */
- ol.renderer.Map.sortByZIndex = function(state1, state2) {
- return state1.zIndex - state2.zIndex;
- };
- // FIXME offset panning
- goog.provide('ol.renderer.canvas.Map');
- goog.require('ol.transform');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.css');
- goog.require('ol.dom');
- goog.require('ol.layer.Layer');
- goog.require('ol.render.Event');
- goog.require('ol.render.EventType');
- goog.require('ol.render.canvas');
- goog.require('ol.render.canvas.Immediate');
- goog.require('ol.renderer.Map');
- goog.require('ol.renderer.Type');
- goog.require('ol.source.State');
- /**
- * @constructor
- * @extends {ol.renderer.Map}
- * @param {Element} container Container.
- * @param {ol.PluggableMap} map Map.
- * @api
- */
- ol.renderer.canvas.Map = function(container, map) {
- ol.renderer.Map.call(this, container, map);
- /**
- * @private
- * @type {CanvasRenderingContext2D}
- */
- this.context_ = ol.dom.createCanvasContext2D();
- /**
- * @private
- * @type {HTMLCanvasElement}
- */
- this.canvas_ = this.context_.canvas;
- this.canvas_.style.width = '100%';
- this.canvas_.style.height = '100%';
- this.canvas_.style.display = 'block';
- this.canvas_.className = ol.css.CLASS_UNSELECTABLE;
- container.insertBefore(this.canvas_, container.childNodes[0] || null);
- /**
- * @private
- * @type {boolean}
- */
- this.renderedVisible_ = true;
- /**
- * @private
- * @type {ol.Transform}
- */
- this.transform_ = ol.transform.create();
- };
- ol.inherits(ol.renderer.canvas.Map, ol.renderer.Map);
- /**
- * Determine if this renderer handles the provided layer.
- * @param {ol.renderer.Type} type The renderer type.
- * @return {boolean} The renderer can render the layer.
- */
- ol.renderer.canvas.Map['handles'] = function(type) {
- return type === ol.renderer.Type.CANVAS;
- };
- /**
- * Create the map renderer.
- * @param {Element} container Container.
- * @param {ol.PluggableMap} map Map.
- * @return {ol.renderer.canvas.Map} The map renderer.
- */
- ol.renderer.canvas.Map['create'] = function(container, map) {
- return new ol.renderer.canvas.Map(container, map);
- };
- /**
- * @param {ol.render.EventType} type Event type.
- * @param {olx.FrameState} frameState Frame state.
- * @private
- */
- ol.renderer.canvas.Map.prototype.dispatchComposeEvent_ = function(type, frameState) {
- var map = this.getMap();
- var context = this.context_;
- if (map.hasListener(type)) {
- var extent = frameState.extent;
- var pixelRatio = frameState.pixelRatio;
- var viewState = frameState.viewState;
- var rotation = viewState.rotation;
- var transform = this.getTransform(frameState);
- var vectorContext = new ol.render.canvas.Immediate(context, pixelRatio,
- extent, transform, rotation);
- var composeEvent = new ol.render.Event(type, vectorContext,
- frameState, context, null);
- map.dispatchEvent(composeEvent);
- }
- };
- /**
- * @param {olx.FrameState} frameState Frame state.
- * @protected
- * @return {!ol.Transform} Transform.
- */
- ol.renderer.canvas.Map.prototype.getTransform = function(frameState) {
- var viewState = frameState.viewState;
- var dx1 = this.canvas_.width / 2;
- var dy1 = this.canvas_.height / 2;
- var sx = frameState.pixelRatio / viewState.resolution;
- var sy = -sx;
- var angle = -viewState.rotation;
- var dx2 = -viewState.center[0];
- var dy2 = -viewState.center[1];
- return ol.transform.compose(this.transform_, dx1, dy1, sx, sy, angle, dx2, dy2);
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.Map.prototype.getType = function() {
- return ol.renderer.Type.CANVAS;
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.Map.prototype.renderFrame = function(frameState) {
- if (!frameState) {
- if (this.renderedVisible_) {
- this.canvas_.style.display = 'none';
- this.renderedVisible_ = false;
- }
- return;
- }
- var context = this.context_;
- var pixelRatio = frameState.pixelRatio;
- var width = Math.round(frameState.size[0] * pixelRatio);
- var height = Math.round(frameState.size[1] * pixelRatio);
- if (this.canvas_.width != width || this.canvas_.height != height) {
- this.canvas_.width = width;
- this.canvas_.height = height;
- } else {
- context.clearRect(0, 0, width, height);
- }
- var rotation = frameState.viewState.rotation;
- this.calculateMatrices2D(frameState);
- this.dispatchComposeEvent_(ol.render.EventType.PRECOMPOSE, frameState);
- var layerStatesArray = frameState.layerStatesArray;
- ol.array.stableSort(layerStatesArray, ol.renderer.Map.sortByZIndex);
- if (rotation) {
- context.save();
- ol.render.canvas.rotateAtOffset(context, rotation, width / 2, height / 2);
- }
- var viewResolution = frameState.viewState.resolution;
- var i, ii, layer, layerRenderer, layerState;
- for (i = 0, ii = layerStatesArray.length; i < ii; ++i) {
- layerState = layerStatesArray[i];
- layer = layerState.layer;
- layerRenderer = /** @type {ol.renderer.canvas.Layer} */ (this.getLayerRenderer(layer));
- if (!ol.layer.Layer.visibleAtResolution(layerState, viewResolution) ||
- layerState.sourceState != ol.source.State.READY) {
- continue;
- }
- if (layerRenderer.prepareFrame(frameState, layerState)) {
- layerRenderer.composeFrame(frameState, layerState, context);
- }
- }
- if (rotation) {
- context.restore();
- }
- this.dispatchComposeEvent_(
- ol.render.EventType.POSTCOMPOSE, frameState);
- if (!this.renderedVisible_) {
- this.canvas_.style.display = '';
- this.renderedVisible_ = true;
- }
- this.scheduleRemoveUnusedLayerRenderers(frameState);
- this.scheduleExpireIconCache(frameState);
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.Map.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg,
- layerFilter, thisArg2) {
- var result;
- var viewState = frameState.viewState;
- var viewResolution = viewState.resolution;
- var layerStates = frameState.layerStatesArray;
- var numLayers = layerStates.length;
- var coordinate = ol.transform.apply(
- frameState.pixelToCoordinateTransform, pixel.slice());
- var i;
- for (i = numLayers - 1; i >= 0; --i) {
- var layerState = layerStates[i];
- var layer = layerState.layer;
- if (ol.layer.Layer.visibleAtResolution(layerState, viewResolution) &&
- layerFilter.call(thisArg2, layer)) {
- var layerRenderer = /** @type {ol.renderer.canvas.Layer} */ (this.getLayerRenderer(layer));
- result = layerRenderer.forEachLayerAtCoordinate(
- coordinate, frameState, callback, thisArg);
- if (result) {
- return result;
- }
- }
- }
- return undefined;
- };
- goog.provide('ol.renderer.canvas.TileLayer');
- goog.require('ol');
- goog.require('ol.LayerType');
- goog.require('ol.TileRange');
- goog.require('ol.TileState');
- goog.require('ol.ViewHint');
- goog.require('ol.dom');
- goog.require('ol.extent');
- goog.require('ol.renderer.Type');
- goog.require('ol.renderer.canvas.IntermediateCanvas');
- goog.require('ol.transform');
- /**
- * @constructor
- * @extends {ol.renderer.canvas.IntermediateCanvas}
- * @param {ol.layer.Tile|ol.layer.VectorTile} tileLayer Tile layer.
- * @api
- */
- ol.renderer.canvas.TileLayer = function(tileLayer) {
- ol.renderer.canvas.IntermediateCanvas.call(this, tileLayer);
- /**
- * @protected
- * @type {CanvasRenderingContext2D}
- */
- this.context = this.context === null ? null : ol.dom.createCanvasContext2D();
- /**
- * @private
- * @type {number}
- */
- this.oversampling_;
- /**
- * @private
- * @type {ol.Extent}
- */
- this.renderedExtent_ = null;
- /**
- * @protected
- * @type {number}
- */
- this.renderedRevision;
- /**
- * @protected
- * @type {!Array.<ol.Tile>}
- */
- this.renderedTiles = [];
- /**
- * @protected
- * @type {ol.Extent}
- */
- this.tmpExtent = ol.extent.createEmpty();
- /**
- * @private
- * @type {ol.TileRange}
- */
- this.tmpTileRange_ = new ol.TileRange(0, 0, 0, 0);
- /**
- * @private
- * @type {ol.Transform}
- */
- this.imageTransform_ = ol.transform.create();
- /**
- * @protected
- * @type {number}
- */
- this.zDirection = 0;
- };
- ol.inherits(ol.renderer.canvas.TileLayer, ol.renderer.canvas.IntermediateCanvas);
- /**
- * Determine if this renderer handles the provided layer.
- * @param {ol.renderer.Type} type The renderer type.
- * @param {ol.layer.Layer} layer The candidate layer.
- * @return {boolean} The renderer can render the layer.
- */
- ol.renderer.canvas.TileLayer['handles'] = function(type, layer) {
- return type === ol.renderer.Type.CANVAS && layer.getType() === ol.LayerType.TILE;
- };
- /**
- * Create a layer renderer.
- * @param {ol.renderer.Map} mapRenderer The map renderer.
- * @param {ol.layer.Layer} layer The layer to be rendererd.
- * @return {ol.renderer.canvas.TileLayer} The layer renderer.
- */
- ol.renderer.canvas.TileLayer['create'] = function(mapRenderer, layer) {
- return new ol.renderer.canvas.TileLayer(/** @type {ol.layer.Tile} */ (layer));
- };
- /**
- * @private
- * @param {ol.Tile} tile Tile.
- * @return {boolean} Tile is drawable.
- */
- ol.renderer.canvas.TileLayer.prototype.isDrawableTile_ = function(tile) {
- var tileState = tile.getState();
- var useInterimTilesOnError = this.getLayer().getUseInterimTilesOnError();
- return tileState == ol.TileState.LOADED ||
- tileState == ol.TileState.EMPTY ||
- tileState == ol.TileState.ERROR && !useInterimTilesOnError;
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.TileLayer.prototype.prepareFrame = function(frameState, layerState) {
- var pixelRatio = frameState.pixelRatio;
- var size = frameState.size;
- var viewState = frameState.viewState;
- var projection = viewState.projection;
- var viewResolution = viewState.resolution;
- var viewCenter = viewState.center;
- var tileLayer = this.getLayer();
- var tileSource = /** @type {ol.source.Tile} */ (tileLayer.getSource());
- var sourceRevision = tileSource.getRevision();
- var tileGrid = tileSource.getTileGridForProjection(projection);
- var z = tileGrid.getZForResolution(viewResolution, this.zDirection);
- var tileResolution = tileGrid.getResolution(z);
- var oversampling = Math.round(viewResolution / tileResolution) || 1;
- var extent = frameState.extent;
- if (layerState.extent !== undefined) {
- extent = ol.extent.getIntersection(extent, layerState.extent);
- }
- if (ol.extent.isEmpty(extent)) {
- // Return false to prevent the rendering of the layer.
- return false;
- }
- var tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
- var imageExtent = tileGrid.getTileRangeExtent(z, tileRange);
- var tilePixelRatio = tileSource.getTilePixelRatio(pixelRatio);
- /**
- * @type {Object.<number, Object.<string, ol.Tile>>}
- */
- var tilesToDrawByZ = {};
- tilesToDrawByZ[z] = {};
- var findLoadedTiles = this.createLoadedTileFinder(
- tileSource, projection, tilesToDrawByZ);
- var tmpExtent = this.tmpExtent;
- var tmpTileRange = this.tmpTileRange_;
- var newTiles = false;
- var tile, x, y;
- for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
- for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
- tile = tileSource.getTile(z, x, y, pixelRatio, projection);
- if (tile.getState() == ol.TileState.ERROR) {
- if (!tileLayer.getUseInterimTilesOnError()) {
- // When useInterimTilesOnError is false, we consider the error tile as loaded.
- tile.setState(ol.TileState.LOADED);
- } else if (tileLayer.getPreload() > 0) {
- // Preloaded tiles for lower resolutions might have finished loading.
- newTiles = true;
- }
- }
- if (!this.isDrawableTile_(tile)) {
- tile = tile.getInterimTile();
- }
- if (this.isDrawableTile_(tile)) {
- var uid = ol.getUid(this);
- if (tile.getState() == ol.TileState.LOADED) {
- tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;
- var inTransition = tile.inTransition(uid);
- if (!newTiles && (inTransition || this.renderedTiles.indexOf(tile) === -1)) {
- newTiles = true;
- }
- }
- if (tile.getAlpha(uid, frameState.time) === 1) {
- // don't look for alt tiles if alpha is 1
- continue;
- }
- }
- var childTileRange = tileGrid.getTileCoordChildTileRange(
- tile.tileCoord, tmpTileRange, tmpExtent);
- var covered = false;
- if (childTileRange) {
- covered = findLoadedTiles(z + 1, childTileRange);
- }
- if (!covered) {
- tileGrid.forEachTileCoordParentTileRange(
- tile.tileCoord, findLoadedTiles, null, tmpTileRange, tmpExtent);
- }
- }
- }
- var renderedResolution = tileResolution * pixelRatio / tilePixelRatio * oversampling;
- var hints = frameState.viewHints;
- var animatingOrInteracting = hints[ol.ViewHint.ANIMATING] || hints[ol.ViewHint.INTERACTING];
- if (!(this.renderedResolution && Date.now() - frameState.time > 16 && animatingOrInteracting) && (
- newTiles ||
- !(this.renderedExtent_ && ol.extent.containsExtent(this.renderedExtent_, extent)) ||
- this.renderedRevision != sourceRevision ||
- oversampling != this.oversampling_ ||
- !animatingOrInteracting && renderedResolution != this.renderedResolution
- )) {
- var context = this.context;
- if (context) {
- var tilePixelSize = tileSource.getTilePixelSize(z, pixelRatio, projection);
- var width = Math.round(tileRange.getWidth() * tilePixelSize[0] / oversampling);
- var height = Math.round(tileRange.getHeight() * tilePixelSize[1] / oversampling);
- var canvas = context.canvas;
- if (canvas.width != width || canvas.height != height) {
- this.oversampling_ = oversampling;
- canvas.width = width;
- canvas.height = height;
- } else {
- if (this.renderedExtent_ && !ol.extent.equals(imageExtent, this.renderedExtent_)) {
- context.clearRect(0, 0, width, height);
- }
- oversampling = this.oversampling_;
- }
- }
- this.renderedTiles.length = 0;
- /** @type {Array.<number>} */
- var zs = Object.keys(tilesToDrawByZ).map(Number);
- zs.sort(function(a, b) {
- if (a === z) {
- return 1;
- } else if (b === z) {
- return -1;
- } else {
- return a > b ? 1 : a < b ? -1 : 0;
- }
- });
- var currentResolution, currentScale, currentTilePixelSize, currentZ, i, ii;
- var tileExtent, tileGutter, tilesToDraw, w, h;
- for (i = 0, ii = zs.length; i < ii; ++i) {
- currentZ = zs[i];
- currentTilePixelSize = tileSource.getTilePixelSize(currentZ, pixelRatio, projection);
- currentResolution = tileGrid.getResolution(currentZ);
- currentScale = currentResolution / tileResolution;
- tileGutter = tilePixelRatio * tileSource.getGutter(projection);
- tilesToDraw = tilesToDrawByZ[currentZ];
- for (var tileCoordKey in tilesToDraw) {
- tile = tilesToDraw[tileCoordKey];
- tileExtent = tileGrid.getTileCoordExtent(tile.getTileCoord(), tmpExtent);
- x = (tileExtent[0] - imageExtent[0]) / tileResolution * tilePixelRatio / oversampling;
- y = (imageExtent[3] - tileExtent[3]) / tileResolution * tilePixelRatio / oversampling;
- w = currentTilePixelSize[0] * currentScale / oversampling;
- h = currentTilePixelSize[1] * currentScale / oversampling;
- this.drawTileImage(tile, frameState, layerState, x, y, w, h, tileGutter, z === currentZ);
- this.renderedTiles.push(tile);
- }
- }
- this.renderedRevision = sourceRevision;
- this.renderedResolution = tileResolution * pixelRatio / tilePixelRatio * oversampling;
- this.renderedExtent_ = imageExtent;
- }
- var scale = this.renderedResolution / viewResolution;
- var transform = ol.transform.compose(this.imageTransform_,
- pixelRatio * size[0] / 2, pixelRatio * size[1] / 2,
- scale, scale,
- 0,
- (this.renderedExtent_[0] - viewCenter[0]) / this.renderedResolution * pixelRatio,
- (viewCenter[1] - this.renderedExtent_[3]) / this.renderedResolution * pixelRatio);
- ol.transform.compose(this.coordinateToCanvasPixelTransform,
- pixelRatio * size[0] / 2 - transform[4], pixelRatio * size[1] / 2 - transform[5],
- pixelRatio / viewResolution, -pixelRatio / viewResolution,
- 0,
- -viewCenter[0], -viewCenter[1]);
- this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
- this.manageTilePyramid(frameState, tileSource, tileGrid, pixelRatio,
- projection, extent, z, tileLayer.getPreload());
- this.scheduleExpireCache(frameState, tileSource);
- this.updateLogos(frameState, tileSource);
- return this.renderedTiles.length > 0;
- };
- /**
- * @param {ol.Tile} tile Tile.
- * @param {olx.FrameState} frameState Frame state.
- * @param {ol.LayerState} layerState Layer state.
- * @param {number} x Left of the tile.
- * @param {number} y Top of the tile.
- * @param {number} w Width of the tile.
- * @param {number} h Height of the tile.
- * @param {number} gutter Tile gutter.
- * @param {boolean} transition Apply an alpha transition.
- */
- ol.renderer.canvas.TileLayer.prototype.drawTileImage = function(tile, frameState, layerState, x, y, w, h, gutter, transition) {
- var image = tile.getImage(this.getLayer());
- if (!image) {
- return;
- }
- var uid = ol.getUid(this);
- var alpha = transition ? tile.getAlpha(uid, frameState.time) : 1;
- if (alpha === 1 && !this.getLayer().getSource().getOpaque(frameState.viewState.projection)) {
- this.context.clearRect(x, y, w, h);
- }
- var alphaChanged = alpha !== this.context.globalAlpha;
- if (alphaChanged) {
- this.context.save();
- this.context.globalAlpha = alpha;
- }
- this.context.drawImage(image, gutter, gutter,
- image.width - 2 * gutter, image.height - 2 * gutter, x, y, w, h);
- if (alphaChanged) {
- this.context.restore();
- }
- if (alpha !== 1) {
- frameState.animate = true;
- } else if (transition) {
- tile.endTransition(uid);
- }
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.TileLayer.prototype.getImage = function() {
- var context = this.context;
- return context ? context.canvas : null;
- };
- /**
- * @function
- * @return {ol.layer.Tile|ol.layer.VectorTile}
- */
- ol.renderer.canvas.TileLayer.prototype.getLayer;
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.TileLayer.prototype.getImageTransform = function() {
- return this.imageTransform_;
- };
- /**
- * @fileoverview
- * @suppress {accessControls, ambiguousFunctionDecl, checkDebuggerStatement, checkRegExp, checkTypes, checkVars, const, constantProperty, deprecated, duplicate, es5Strict, fileoverviewTags, missingProperties, nonStandardJsDocs, strictModuleDepCheck, suspiciousCode, undefinedNames, undefinedVars, unknownDefines, unusedLocalVariables, uselessCode, visibility}
- */
- goog.provide('ol.ext.rbush');
- /** @typedef {function(*)} */
- ol.ext.rbush = function() {};
- (function() {(function (exports) {
- 'use strict';
- var quickselect_1 = quickselect;
- var default_1 = quickselect;
- function quickselect(arr, k, left, right, compare) {
- quickselectStep(arr, k, left || 0, right || (arr.length - 1), compare || defaultCompare);
- }
- function quickselectStep(arr, k, left, right, compare) {
- while (right > left) {
- if (right - left > 600) {
- var n = right - left + 1;
- var m = k - left + 1;
- var z = Math.log(n);
- var s = 0.5 * Math.exp(2 * z / 3);
- var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
- var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
- var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
- quickselectStep(arr, k, newLeft, newRight, compare);
- }
- var t = arr[k];
- var i = left;
- var j = right;
- swap(arr, left, k);
- if (compare(arr[right], t) > 0) swap(arr, left, right);
- while (i < j) {
- swap(arr, i, j);
- i++;
- j--;
- while (compare(arr[i], t) < 0) i++;
- while (compare(arr[j], t) > 0) j--;
- }
- if (compare(arr[left], t) === 0) swap(arr, left, j);
- else {
- j++;
- swap(arr, j, right);
- }
- if (j <= k) left = j + 1;
- if (k <= j) right = j - 1;
- }
- }
- function swap(arr, i, j) {
- var tmp = arr[i];
- arr[i] = arr[j];
- arr[j] = tmp;
- }
- function defaultCompare(a, b) {
- return a < b ? -1 : a > b ? 1 : 0;
- }
- quickselect_1.default = default_1;
- var rbush_1 = rbush;
- function rbush(maxEntries, format) {
- if (!(this instanceof rbush)) return new rbush(maxEntries, format);
- this._maxEntries = Math.max(4, maxEntries || 9);
- this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));
- if (format) {
- this._initFormat(format);
- }
- this.clear();
- }
- rbush.prototype = {
- all: function () {
- return this._all(this.data, []);
- },
- search: function (bbox) {
- var node = this.data,
- result = [],
- toBBox = this.toBBox;
- if (!intersects(bbox, node)) return result;
- var nodesToSearch = [],
- i, len, child, childBBox;
- while (node) {
- for (i = 0, len = node.children.length; i < len; i++) {
- child = node.children[i];
- childBBox = node.leaf ? toBBox(child) : child;
- if (intersects(bbox, childBBox)) {
- if (node.leaf) result.push(child);
- else if (contains(bbox, childBBox)) this._all(child, result);
- else nodesToSearch.push(child);
- }
- }
- node = nodesToSearch.pop();
- }
- return result;
- },
- collides: function (bbox) {
- var node = this.data,
- toBBox = this.toBBox;
- if (!intersects(bbox, node)) return false;
- var nodesToSearch = [],
- i, len, child, childBBox;
- while (node) {
- for (i = 0, len = node.children.length; i < len; i++) {
- child = node.children[i];
- childBBox = node.leaf ? toBBox(child) : child;
- if (intersects(bbox, childBBox)) {
- if (node.leaf || contains(bbox, childBBox)) return true;
- nodesToSearch.push(child);
- }
- }
- node = nodesToSearch.pop();
- }
- return false;
- },
- load: function (data) {
- if (!(data && data.length)) return this;
- if (data.length < this._minEntries) {
- for (var i = 0, len = data.length; i < len; i++) {
- this.insert(data[i]);
- }
- return this;
- }
- var node = this._build(data.slice(), 0, data.length - 1, 0);
- if (!this.data.children.length) {
- this.data = node;
- } else if (this.data.height === node.height) {
- this._splitRoot(this.data, node);
- } else {
- if (this.data.height < node.height) {
- var tmpNode = this.data;
- this.data = node;
- node = tmpNode;
- }
- this._insert(node, this.data.height - node.height - 1, true);
- }
- return this;
- },
- insert: function (item) {
- if (item) this._insert(item, this.data.height - 1);
- return this;
- },
- clear: function () {
- this.data = createNode([]);
- return this;
- },
- remove: function (item, equalsFn) {
- if (!item) return this;
- var node = this.data,
- bbox = this.toBBox(item),
- path = [],
- indexes = [],
- i, parent, index, goingUp;
- while (node || path.length) {
- if (!node) {
- node = path.pop();
- parent = path[path.length - 1];
- i = indexes.pop();
- goingUp = true;
- }
- if (node.leaf) {
- index = findItem(item, node.children, equalsFn);
- if (index !== -1) {
- node.children.splice(index, 1);
- path.push(node);
- this._condense(path);
- return this;
- }
- }
- if (!goingUp && !node.leaf && contains(node, bbox)) {
- path.push(node);
- indexes.push(i);
- i = 0;
- parent = node;
- node = node.children[0];
- } else if (parent) {
- i++;
- node = parent.children[i];
- goingUp = false;
- } else node = null;
- }
- return this;
- },
- toBBox: function (item) { return item; },
- compareMinX: compareNodeMinX,
- compareMinY: compareNodeMinY,
- toJSON: function () { return this.data; },
- fromJSON: function (data) {
- this.data = data;
- return this;
- },
- _all: function (node, result) {
- var nodesToSearch = [];
- while (node) {
- if (node.leaf) result.push.apply(result, node.children);
- else nodesToSearch.push.apply(nodesToSearch, node.children);
- node = nodesToSearch.pop();
- }
- return result;
- },
- _build: function (items, left, right, height) {
- var N = right - left + 1,
- M = this._maxEntries,
- node;
- if (N <= M) {
- node = createNode(items.slice(left, right + 1));
- calcBBox(node, this.toBBox);
- return node;
- }
- if (!height) {
- height = Math.ceil(Math.log(N) / Math.log(M));
- M = Math.ceil(N / Math.pow(M, height - 1));
- }
- node = createNode([]);
- node.leaf = false;
- node.height = height;
- var N2 = Math.ceil(N / M),
- N1 = N2 * Math.ceil(Math.sqrt(M)),
- i, j, right2, right3;
- multiSelect(items, left, right, N1, this.compareMinX);
- for (i = left; i <= right; i += N1) {
- right2 = Math.min(i + N1 - 1, right);
- multiSelect(items, i, right2, N2, this.compareMinY);
- for (j = i; j <= right2; j += N2) {
- right3 = Math.min(j + N2 - 1, right2);
- node.children.push(this._build(items, j, right3, height - 1));
- }
- }
- calcBBox(node, this.toBBox);
- return node;
- },
- _chooseSubtree: function (bbox, node, level, path) {
- var i, len, child, targetNode, area, enlargement, minArea, minEnlargement;
- while (true) {
- path.push(node);
- if (node.leaf || path.length - 1 === level) break;
- minArea = minEnlargement = Infinity;
- for (i = 0, len = node.children.length; i < len; i++) {
- child = node.children[i];
- area = bboxArea(child);
- enlargement = enlargedArea(bbox, child) - area;
- if (enlargement < minEnlargement) {
- minEnlargement = enlargement;
- minArea = area < minArea ? area : minArea;
- targetNode = child;
- } else if (enlargement === minEnlargement) {
- if (area < minArea) {
- minArea = area;
- targetNode = child;
- }
- }
- }
- node = targetNode || node.children[0];
- }
- return node;
- },
- _insert: function (item, level, isNode) {
- var toBBox = this.toBBox,
- bbox = isNode ? item : toBBox(item),
- insertPath = [];
- var node = this._chooseSubtree(bbox, this.data, level, insertPath);
- node.children.push(item);
- extend(node, bbox);
- while (level >= 0) {
- if (insertPath[level].children.length > this._maxEntries) {
- this._split(insertPath, level);
- level--;
- } else break;
- }
- this._adjustParentBBoxes(bbox, insertPath, level);
- },
- _split: function (insertPath, level) {
- var node = insertPath[level],
- M = node.children.length,
- m = this._minEntries;
- this._chooseSplitAxis(node, m, M);
- var splitIndex = this._chooseSplitIndex(node, m, M);
- var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));
- newNode.height = node.height;
- newNode.leaf = node.leaf;
- calcBBox(node, this.toBBox);
- calcBBox(newNode, this.toBBox);
- if (level) insertPath[level - 1].children.push(newNode);
- else this._splitRoot(node, newNode);
- },
- _splitRoot: function (node, newNode) {
- this.data = createNode([node, newNode]);
- this.data.height = node.height + 1;
- this.data.leaf = false;
- calcBBox(this.data, this.toBBox);
- },
- _chooseSplitIndex: function (node, m, M) {
- var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index;
- minOverlap = minArea = Infinity;
- for (i = m; i <= M - m; i++) {
- bbox1 = distBBox(node, 0, i, this.toBBox);
- bbox2 = distBBox(node, i, M, this.toBBox);
- overlap = intersectionArea(bbox1, bbox2);
- area = bboxArea(bbox1) + bboxArea(bbox2);
- if (overlap < minOverlap) {
- minOverlap = overlap;
- index = i;
- minArea = area < minArea ? area : minArea;
- } else if (overlap === minOverlap) {
- if (area < minArea) {
- minArea = area;
- index = i;
- }
- }
- }
- return index;
- },
- _chooseSplitAxis: function (node, m, M) {
- var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX,
- compareMinY = node.leaf ? this.compareMinY : compareNodeMinY,
- xMargin = this._allDistMargin(node, m, M, compareMinX),
- yMargin = this._allDistMargin(node, m, M, compareMinY);
- if (xMargin < yMargin) node.children.sort(compareMinX);
- },
- _allDistMargin: function (node, m, M, compare) {
- node.children.sort(compare);
- var toBBox = this.toBBox,
- leftBBox = distBBox(node, 0, m, toBBox),
- rightBBox = distBBox(node, M - m, M, toBBox),
- margin = bboxMargin(leftBBox) + bboxMargin(rightBBox),
- i, child;
- for (i = m; i < M - m; i++) {
- child = node.children[i];
- extend(leftBBox, node.leaf ? toBBox(child) : child);
- margin += bboxMargin(leftBBox);
- }
- for (i = M - m - 1; i >= m; i--) {
- child = node.children[i];
- extend(rightBBox, node.leaf ? toBBox(child) : child);
- margin += bboxMargin(rightBBox);
- }
- return margin;
- },
- _adjustParentBBoxes: function (bbox, path, level) {
- for (var i = level; i >= 0; i--) {
- extend(path[i], bbox);
- }
- },
- _condense: function (path) {
- for (var i = path.length - 1, siblings; i >= 0; i--) {
- if (path[i].children.length === 0) {
- if (i > 0) {
- siblings = path[i - 1].children;
- siblings.splice(siblings.indexOf(path[i]), 1);
- } else this.clear();
- } else calcBBox(path[i], this.toBBox);
- }
- },
- _initFormat: function (format) {
- var compareArr = ['return a', ' - b', ';'];
- this.compareMinX = new Function('a', 'b', compareArr.join(format[0]));
- this.compareMinY = new Function('a', 'b', compareArr.join(format[1]));
- this.toBBox = new Function('a',
- 'return {minX: a' + format[0] +
- ', minY: a' + format[1] +
- ', maxX: a' + format[2] +
- ', maxY: a' + format[3] + '};');
- }
- };
- function findItem(item, items, equalsFn) {
- if (!equalsFn) return items.indexOf(item);
- for (var i = 0; i < items.length; i++) {
- if (equalsFn(item, items[i])) return i;
- }
- return -1;
- }
- function calcBBox(node, toBBox) {
- distBBox(node, 0, node.children.length, toBBox, node);
- }
- function distBBox(node, k, p, toBBox, destNode) {
- if (!destNode) destNode = createNode(null);
- destNode.minX = Infinity;
- destNode.minY = Infinity;
- destNode.maxX = -Infinity;
- destNode.maxY = -Infinity;
- for (var i = k, child; i < p; i++) {
- child = node.children[i];
- extend(destNode, node.leaf ? toBBox(child) : child);
- }
- return destNode;
- }
- function extend(a, b) {
- a.minX = Math.min(a.minX, b.minX);
- a.minY = Math.min(a.minY, b.minY);
- a.maxX = Math.max(a.maxX, b.maxX);
- a.maxY = Math.max(a.maxY, b.maxY);
- return a;
- }
- function compareNodeMinX(a, b) { return a.minX - b.minX; }
- function compareNodeMinY(a, b) { return a.minY - b.minY; }
- function bboxArea(a) { return (a.maxX - a.minX) * (a.maxY - a.minY); }
- function bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); }
- function enlargedArea(a, b) {
- return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *
- (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));
- }
- function intersectionArea(a, b) {
- var minX = Math.max(a.minX, b.minX),
- minY = Math.max(a.minY, b.minY),
- maxX = Math.min(a.maxX, b.maxX),
- maxY = Math.min(a.maxY, b.maxY);
- return Math.max(0, maxX - minX) *
- Math.max(0, maxY - minY);
- }
- function contains(a, b) {
- return a.minX <= b.minX &&
- a.minY <= b.minY &&
- b.maxX <= a.maxX &&
- b.maxY <= a.maxY;
- }
- function intersects(a, b) {
- return b.minX <= a.maxX &&
- b.minY <= a.maxY &&
- b.maxX >= a.minX &&
- b.maxY >= a.minY;
- }
- function createNode(children) {
- return {
- children: children,
- height: 1,
- leaf: true,
- minX: Infinity,
- minY: Infinity,
- maxX: -Infinity,
- maxY: -Infinity
- };
- }
- function multiSelect(arr, left, right, n, compare) {
- var stack = [left, right],
- mid;
- while (stack.length) {
- right = stack.pop();
- left = stack.pop();
- if (right - left <= n) continue;
- mid = left + Math.ceil((right - left) / n / 2) * n;
- quickselect_1(arr, mid, left, right, compare);
- stack.push(left, mid, mid, right);
- }
- }
- exports['default'] = rbush_1;
- }((this.rbush = this.rbush || {})));}).call(ol.ext);
- ol.ext.rbush = ol.ext.rbush.default;
- goog.provide('ol.render.ReplayGroup');
- /**
- * Base class for replay groups.
- * @constructor
- * @abstract
- */
- ol.render.ReplayGroup = function() {};
- /**
- * @abstract
- * @param {number|undefined} zIndex Z index.
- * @param {ol.render.ReplayType} replayType Replay type.
- * @return {ol.render.VectorContext} Replay.
- */
- ol.render.ReplayGroup.prototype.getReplay = function(zIndex, replayType) {};
- /**
- * @abstract
- * @return {boolean} Is empty.
- */
- ol.render.ReplayGroup.prototype.isEmpty = function() {};
- goog.provide('ol.render.ReplayType');
- /**
- * @enum {string}
- */
- ol.render.ReplayType = {
- CIRCLE: 'Circle',
- DEFAULT: 'Default',
- IMAGE: 'Image',
- LINE_STRING: 'LineString',
- POLYGON: 'Polygon',
- TEXT: 'Text'
- };
- goog.provide('ol.geom.flat.length');
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @return {number} Length.
- */
- ol.geom.flat.length.lineString = function(flatCoordinates, offset, end, stride) {
- var x1 = flatCoordinates[offset];
- var y1 = flatCoordinates[offset + 1];
- var length = 0;
- var i;
- for (i = offset + stride; i < end; i += stride) {
- var x2 = flatCoordinates[i];
- var y2 = flatCoordinates[i + 1];
- length += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
- x1 = x2;
- y1 = y2;
- }
- return length;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @return {number} Perimeter.
- */
- ol.geom.flat.length.linearRing = function(flatCoordinates, offset, end, stride) {
- var perimeter =
- ol.geom.flat.length.lineString(flatCoordinates, offset, end, stride);
- var dx = flatCoordinates[end - stride] - flatCoordinates[offset];
- var dy = flatCoordinates[end - stride + 1] - flatCoordinates[offset + 1];
- perimeter += Math.sqrt(dx * dx + dy * dy);
- return perimeter;
- };
- goog.provide('ol.geom.flat.textpath');
- goog.require('ol.math');
- /**
- * @param {Array.<number>} flatCoordinates Path to put text on.
- * @param {number} offset Start offset of the `flatCoordinates`.
- * @param {number} end End offset of the `flatCoordinates`.
- * @param {number} stride Stride.
- * @param {string} text Text to place on the path.
- * @param {function(string):number} measure Measure function returning the
- * width of the character passed as 1st argument.
- * @param {number} startM m along the path where the text starts.
- * @param {number} maxAngle Max angle between adjacent chars in radians.
- * @return {Array.<Array.<*>>} The result array of null if `maxAngle` was
- * exceeded. Entries of the array are x, y, anchorX, angle, chunk.
- */
- ol.geom.flat.textpath.lineString = function(
- flatCoordinates, offset, end, stride, text, measure, startM, maxAngle) {
- var result = [];
- // Keep text upright
- var reverse = flatCoordinates[offset] > flatCoordinates[end - stride];
- var numChars = text.length;
- var x1 = flatCoordinates[offset];
- var y1 = flatCoordinates[offset + 1];
- offset += stride;
- var x2 = flatCoordinates[offset];
- var y2 = flatCoordinates[offset + 1];
- var segmentM = 0;
- var segmentLength = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
- var chunk = '';
- var chunkLength = 0;
- var data, index, previousAngle;
- for (var i = 0; i < numChars; ++i) {
- index = reverse ? numChars - i - 1 : i;
- var char = text.charAt(index);
- chunk = reverse ? char + chunk : chunk + char;
- var charLength = measure(chunk) - chunkLength;
- chunkLength += charLength;
- var charM = startM + charLength / 2;
- while (offset < end - stride && segmentM + segmentLength < charM) {
- x1 = x2;
- y1 = y2;
- offset += stride;
- x2 = flatCoordinates[offset];
- y2 = flatCoordinates[offset + 1];
- segmentM += segmentLength;
- segmentLength = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
- }
- var segmentPos = charM - segmentM;
- var angle = Math.atan2(y2 - y1, x2 - x1);
- if (reverse) {
- angle += angle > 0 ? -Math.PI : Math.PI;
- }
- if (previousAngle !== undefined) {
- var delta = angle - previousAngle;
- delta += (delta > Math.PI) ? -2 * Math.PI : (delta < -Math.PI) ? 2 * Math.PI : 0;
- if (Math.abs(delta) > maxAngle) {
- return null;
- }
- }
- var interpolate = segmentPos / segmentLength;
- var x = ol.math.lerp(x1, x2, interpolate);
- var y = ol.math.lerp(y1, y2, interpolate);
- if (previousAngle == angle) {
- if (reverse) {
- data[0] = x;
- data[1] = y;
- data[2] = charLength / 2;
- }
- data[4] = chunk;
- } else {
- chunk = char;
- chunkLength = charLength;
- data = [x, y, charLength / 2, angle, chunk];
- if (reverse) {
- result.unshift(data);
- } else {
- result.push(data);
- }
- previousAngle = angle;
- }
- startM += charLength;
- }
- return result;
- };
- goog.provide('ol.render.canvas.Instruction');
- /**
- * @enum {number}
- */
- ol.render.canvas.Instruction = {
- BEGIN_GEOMETRY: 0,
- BEGIN_PATH: 1,
- CIRCLE: 2,
- CLOSE_PATH: 3,
- CUSTOM: 4,
- DRAW_CHARS: 5,
- DRAW_IMAGE: 6,
- END_GEOMETRY: 7,
- FILL: 8,
- MOVE_TO_LINE_TO: 9,
- SET_FILL_STYLE: 10,
- SET_STROKE_STYLE: 11,
- STROKE: 12
- };
- goog.provide('ol.render.replay');
- goog.require('ol.render.ReplayType');
- /**
- * @const
- * @type {Array.<ol.render.ReplayType>}
- */
- ol.render.replay.ORDER = [
- ol.render.ReplayType.POLYGON,
- ol.render.ReplayType.CIRCLE,
- ol.render.ReplayType.LINE_STRING,
- ol.render.ReplayType.IMAGE,
- ol.render.ReplayType.TEXT,
- ol.render.ReplayType.DEFAULT
- ];
- /**
- * @const
- * @enum {number}
- */
- ol.render.replay.TEXT_ALIGN = {};
- ol.render.replay.TEXT_ALIGN['left'] = 0;
- ol.render.replay.TEXT_ALIGN['end'] = 0;
- ol.render.replay.TEXT_ALIGN['center'] = 0.5;
- ol.render.replay.TEXT_ALIGN['right'] = 1;
- ol.render.replay.TEXT_ALIGN['start'] = 1;
- ol.render.replay.TEXT_ALIGN['top'] = 0;
- ol.render.replay.TEXT_ALIGN['middle'] = 0.5;
- ol.render.replay.TEXT_ALIGN['hanging'] = 0.2;
- ol.render.replay.TEXT_ALIGN['alphabetic'] = 0.8;
- ol.render.replay.TEXT_ALIGN['ideographic'] = 0.8;
- ol.render.replay.TEXT_ALIGN['bottom'] = 1;
- goog.provide('ol.render.canvas.Replay');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.colorlike');
- goog.require('ol.extent');
- goog.require('ol.extent.Relationship');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.flat.inflate');
- goog.require('ol.geom.flat.length');
- goog.require('ol.geom.flat.textpath');
- goog.require('ol.geom.flat.transform');
- goog.require('ol.has');
- goog.require('ol.obj');
- goog.require('ol.render.VectorContext');
- goog.require('ol.render.canvas');
- goog.require('ol.render.canvas.Instruction');
- goog.require('ol.render.replay');
- goog.require('ol.transform');
- /**
- * @constructor
- * @extends {ol.render.VectorContext}
- * @param {number} tolerance Tolerance.
- * @param {ol.Extent} maxExtent Maximum extent.
- * @param {number} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @param {boolean} overlaps The replay can have overlapping geometries.
- * @param {?} declutterTree Declutter tree.
- * @struct
- */
- ol.render.canvas.Replay = function(tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree) {
- ol.render.VectorContext.call(this);
- /**
- * @type {?}
- */
- this.declutterTree = declutterTree;
- /**
- * @private
- * @type {ol.Extent}
- */
- this.tmpExtent_ = ol.extent.createEmpty();
- /**
- * @protected
- * @type {number}
- */
- this.tolerance = tolerance;
- /**
- * @protected
- * @const
- * @type {ol.Extent}
- */
- this.maxExtent = maxExtent;
- /**
- * @protected
- * @type {boolean}
- */
- this.overlaps = overlaps;
- /**
- * @protected
- * @type {number}
- */
- this.pixelRatio = pixelRatio;
- /**
- * @protected
- * @type {number}
- */
- this.maxLineWidth = 0;
- /**
- * @protected
- * @const
- * @type {number}
- */
- this.resolution = resolution;
- /**
- * @private
- * @type {ol.Coordinate}
- */
- this.fillOrigin_;
- /**
- * @private
- * @type {Array.<*>}
- */
- this.beginGeometryInstruction1_ = null;
- /**
- * @private
- * @type {Array.<*>}
- */
- this.beginGeometryInstruction2_ = null;
- /**
- * @private
- * @type {ol.Extent}
- */
- this.bufferedMaxExtent_ = null;
- /**
- * @protected
- * @type {Array.<*>}
- */
- this.instructions = [];
- /**
- * @protected
- * @type {Array.<number>}
- */
- this.coordinates = [];
- /**
- * @private
- * @type {Object.<number,ol.Coordinate|Array.<ol.Coordinate>|Array.<Array.<ol.Coordinate>>>}
- */
- this.coordinateCache_ = {};
- /**
- * @private
- * @type {!ol.Transform}
- */
- this.renderedTransform_ = ol.transform.create();
- /**
- * @protected
- * @type {Array.<*>}
- */
- this.hitDetectionInstructions = [];
- /**
- * @private
- * @type {Array.<number>}
- */
- this.pixelCoordinates_ = null;
- /**
- * @protected
- * @type {ol.CanvasFillStrokeState}
- */
- this.state = /** @type {ol.CanvasFillStrokeState} */ ({});
- /**
- * @private
- * @type {number}
- */
- this.viewRotation_ = 0;
- /**
- * @private
- * @type {!ol.Transform}
- */
- this.tmpLocalTransform_ = ol.transform.create();
- /**
- * @private
- * @type {!ol.Transform}
- */
- this.resetTransform_ = ol.transform.create();
- };
- ol.inherits(ol.render.canvas.Replay, ol.render.VectorContext);
- /**
- * @param {CanvasRenderingContext2D} context Context.
- * @param {ol.Coordinate} p1 1st point of the background box.
- * @param {ol.Coordinate} p2 2nd point of the background box.
- * @param {ol.Coordinate} p3 3rd point of the background box.
- * @param {ol.Coordinate} p4 4th point of the background box.
- * @param {Array.<*>} fillInstruction Fill instruction.
- * @param {Array.<*>} strokeInstruction Stroke instruction.
- */
- ol.render.canvas.Replay.prototype.replayTextBackground_ = function(context, p1, p2, p3, p4,
- fillInstruction, strokeInstruction) {
- context.beginPath();
- context.moveTo.apply(context, p1);
- context.lineTo.apply(context, p2);
- context.lineTo.apply(context, p3);
- context.lineTo.apply(context, p4);
- context.lineTo.apply(context, p1);
- if (fillInstruction) {
- this.fillOrigin_ = /** @type {Array.<number>} */ (fillInstruction[2]);
- this.fill_(context);
- }
- if (strokeInstruction) {
- this.setStrokeStyle_(context, /** @type {Array.<*>} */ (strokeInstruction));
- context.stroke();
- }
- };
- /**
- * @param {CanvasRenderingContext2D} context Context.
- * @param {number} x X.
- * @param {number} y Y.
- * @param {HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} image Image.
- * @param {number} anchorX Anchor X.
- * @param {number} anchorY Anchor Y.
- * @param {ol.DeclutterGroup} declutterGroup Declutter group.
- * @param {number} height Height.
- * @param {number} opacity Opacity.
- * @param {number} originX Origin X.
- * @param {number} originY Origin Y.
- * @param {number} rotation Rotation.
- * @param {number} scale Scale.
- * @param {boolean} snapToPixel Snap to pixel.
- * @param {number} width Width.
- * @param {Array.<number>} padding Padding.
- * @param {Array.<*>} fillInstruction Fill instruction.
- * @param {Array.<*>} strokeInstruction Stroke instruction.
- */
- ol.render.canvas.Replay.prototype.replayImage_ = function(context, x, y, image,
- anchorX, anchorY, declutterGroup, height, opacity, originX, originY,
- rotation, scale, snapToPixel, width, padding, fillInstruction, strokeInstruction) {
- var fillStroke = fillInstruction || strokeInstruction;
- var localTransform = this.tmpLocalTransform_;
- anchorX *= scale;
- anchorY *= scale;
- x -= anchorX;
- y -= anchorY;
- if (snapToPixel) {
- x = Math.round(x);
- y = Math.round(y);
- }
- var w = (width + originX > image.width) ? image.width - originX : width;
- var h = (height + originY > image.height) ? image.height - originY : height;
- var box = this.tmpExtent_;
- var boxW = padding[3] + w * scale + padding[1];
- var boxH = padding[0] + h * scale + padding[2];
- var boxX = x - padding[3];
- var boxY = y - padding[0];
- /** @type {ol.Coordinate} */
- var p1;
- /** @type {ol.Coordinate} */
- var p2;
- /** @type {ol.Coordinate} */
- var p3;
- /** @type {ol.Coordinate} */
- var p4;
- if (fillStroke || rotation !== 0) {
- p1 = [boxX, boxY];
- p2 = [boxX + boxW, boxY];
- p3 = [boxX + boxW, boxY + boxH];
- p4 = [boxX, boxY + boxH];
- }
- var transform = null;
- if (rotation !== 0) {
- var centerX = x + anchorX;
- var centerY = y + anchorY;
- transform = ol.transform.compose(localTransform,
- centerX, centerY, 1, 1, rotation, -centerX, -centerY);
- ol.extent.createOrUpdateEmpty(box);
- ol.extent.extendCoordinate(box, ol.transform.apply(localTransform, p1));
- ol.extent.extendCoordinate(box, ol.transform.apply(localTransform, p2));
- ol.extent.extendCoordinate(box, ol.transform.apply(localTransform, p3));
- ol.extent.extendCoordinate(box, ol.transform.apply(localTransform, p4));
- } else {
- ol.extent.createOrUpdate(boxX, boxY, boxX + boxW, boxY + boxH, box);
- }
- var canvas = context.canvas;
- var intersects = box[0] <= canvas.width && box[2] >= 0 && box[1] <= canvas.height && box[3] >= 0;
- if (declutterGroup) {
- if (!intersects && declutterGroup[4] == 1) {
- return;
- }
- ol.extent.extend(declutterGroup, box);
- var declutterArgs = intersects ?
- [context, transform ? transform.slice(0) : null, opacity, image, originX, originY, w, h, x, y, scale] :
- null;
- if (declutterArgs && fillStroke) {
- declutterArgs.push(fillInstruction, strokeInstruction, p1, p2, p3, p4);
- }
- declutterGroup.push(declutterArgs);
- } else if (intersects) {
- if (fillStroke) {
- this.replayTextBackground_(context, p1, p2, p3, p4,
- /** @type {Array.<*>} */ (fillInstruction),
- /** @type {Array.<*>} */ (strokeInstruction));
- }
- ol.render.canvas.drawImage(context, transform, opacity, image, originX, originY, w, h, x, y, scale);
- }
- };
- /**
- * @protected
- * @param {Array.<number>} dashArray Dash array.
- * @return {Array.<number>} Dash array with pixel ratio applied
- */
- ol.render.canvas.Replay.prototype.applyPixelRatio = function(dashArray) {
- var pixelRatio = this.pixelRatio;
- return pixelRatio == 1 ? dashArray : dashArray.map(function(dash) {
- return dash * pixelRatio;
- });
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {boolean} closed Last input coordinate equals first.
- * @param {boolean} skipFirst Skip first coordinate.
- * @protected
- * @return {number} My end.
- */
- ol.render.canvas.Replay.prototype.appendFlatCoordinates = function(flatCoordinates, offset, end, stride, closed, skipFirst) {
- var myEnd = this.coordinates.length;
- var extent = this.getBufferedMaxExtent();
- if (skipFirst) {
- offset += stride;
- }
- var lastCoord = [flatCoordinates[offset], flatCoordinates[offset + 1]];
- var nextCoord = [NaN, NaN];
- var skipped = true;
- var i, lastRel, nextRel;
- for (i = offset + stride; i < end; i += stride) {
- nextCoord[0] = flatCoordinates[i];
- nextCoord[1] = flatCoordinates[i + 1];
- nextRel = ol.extent.coordinateRelationship(extent, nextCoord);
- if (nextRel !== lastRel) {
- if (skipped) {
- this.coordinates[myEnd++] = lastCoord[0];
- this.coordinates[myEnd++] = lastCoord[1];
- }
- this.coordinates[myEnd++] = nextCoord[0];
- this.coordinates[myEnd++] = nextCoord[1];
- skipped = false;
- } else if (nextRel === ol.extent.Relationship.INTERSECTING) {
- this.coordinates[myEnd++] = nextCoord[0];
- this.coordinates[myEnd++] = nextCoord[1];
- skipped = false;
- } else {
- skipped = true;
- }
- lastCoord[0] = nextCoord[0];
- lastCoord[1] = nextCoord[1];
- lastRel = nextRel;
- }
- // Last coordinate equals first or only one point to append:
- if ((closed && skipped) || i === offset + stride) {
- this.coordinates[myEnd++] = lastCoord[0];
- this.coordinates[myEnd++] = lastCoord[1];
- }
- return myEnd;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<number>} ends Ends.
- * @param {number} stride Stride.
- * @param {Array.<number>} replayEnds Replay ends.
- * @return {number} Offset.
- */
- ol.render.canvas.Replay.prototype.drawCustomCoordinates_ = function(flatCoordinates, offset, ends, stride, replayEnds) {
- for (var i = 0, ii = ends.length; i < ii; ++i) {
- var end = ends[i];
- var replayEnd = this.appendFlatCoordinates(flatCoordinates, offset, end, stride, false, false);
- replayEnds.push(replayEnd);
- offset = end;
- }
- return offset;
- };
- /**
- * @inheritDoc.
- */
- ol.render.canvas.Replay.prototype.drawCustom = function(geometry, feature, renderer) {
- this.beginGeometry(geometry, feature);
- var type = geometry.getType();
- var stride = geometry.getStride();
- var replayBegin = this.coordinates.length;
- var flatCoordinates, replayEnd, replayEnds, replayEndss;
- var offset;
- if (type == ol.geom.GeometryType.MULTI_POLYGON) {
- geometry = /** @type {ol.geom.MultiPolygon} */ (geometry);
- flatCoordinates = geometry.getOrientedFlatCoordinates();
- replayEndss = [];
- var endss = geometry.getEndss();
- offset = 0;
- for (var i = 0, ii = endss.length; i < ii; ++i) {
- var myEnds = [];
- offset = this.drawCustomCoordinates_(flatCoordinates, offset, endss[i], stride, myEnds);
- replayEndss.push(myEnds);
- }
- this.instructions.push([ol.render.canvas.Instruction.CUSTOM,
- replayBegin, replayEndss, geometry, renderer, ol.geom.flat.inflate.coordinatesss]);
- } else if (type == ol.geom.GeometryType.POLYGON || type == ol.geom.GeometryType.MULTI_LINE_STRING) {
- replayEnds = [];
- flatCoordinates = (type == ol.geom.GeometryType.POLYGON) ?
- /** @type {ol.geom.Polygon} */ (geometry).getOrientedFlatCoordinates() :
- geometry.getFlatCoordinates();
- offset = this.drawCustomCoordinates_(flatCoordinates, 0,
- /** @type {ol.geom.Polygon|ol.geom.MultiLineString} */ (geometry).getEnds(),
- stride, replayEnds);
- this.instructions.push([ol.render.canvas.Instruction.CUSTOM,
- replayBegin, replayEnds, geometry, renderer, ol.geom.flat.inflate.coordinatess]);
- } else if (type == ol.geom.GeometryType.LINE_STRING || type == ol.geom.GeometryType.MULTI_POINT) {
- flatCoordinates = geometry.getFlatCoordinates();
- replayEnd = this.appendFlatCoordinates(
- flatCoordinates, 0, flatCoordinates.length, stride, false, false);
- this.instructions.push([ol.render.canvas.Instruction.CUSTOM,
- replayBegin, replayEnd, geometry, renderer, ol.geom.flat.inflate.coordinates]);
- } else if (type == ol.geom.GeometryType.POINT) {
- flatCoordinates = geometry.getFlatCoordinates();
- this.coordinates.push(flatCoordinates[0], flatCoordinates[1]);
- replayEnd = this.coordinates.length;
- this.instructions.push([ol.render.canvas.Instruction.CUSTOM,
- replayBegin, replayEnd, geometry, renderer]);
- }
- this.endGeometry(geometry, feature);
- };
- /**
- * @protected
- * @param {ol.geom.Geometry|ol.render.Feature} geometry Geometry.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- */
- ol.render.canvas.Replay.prototype.beginGeometry = function(geometry, feature) {
- this.beginGeometryInstruction1_ =
- [ol.render.canvas.Instruction.BEGIN_GEOMETRY, feature, 0];
- this.instructions.push(this.beginGeometryInstruction1_);
- this.beginGeometryInstruction2_ =
- [ol.render.canvas.Instruction.BEGIN_GEOMETRY, feature, 0];
- this.hitDetectionInstructions.push(this.beginGeometryInstruction2_);
- };
- /**
- * @private
- * @param {CanvasRenderingContext2D} context Context.
- */
- ol.render.canvas.Replay.prototype.fill_ = function(context) {
- if (this.fillOrigin_) {
- var origin = ol.transform.apply(this.renderedTransform_, this.fillOrigin_.slice());
- context.translate(origin[0], origin[1]);
- context.rotate(this.viewRotation_);
- }
- context.fill();
- if (this.fillOrigin_) {
- context.setTransform.apply(context, ol.render.canvas.resetTransform_);
- }
- };
- /**
- * @private
- * @param {CanvasRenderingContext2D} context Context.
- * @param {Array.<*>} instruction Instruction.
- */
- ol.render.canvas.Replay.prototype.setStrokeStyle_ = function(context, instruction) {
- context.strokeStyle = /** @type {ol.ColorLike} */ (instruction[1]);
- context.lineWidth = /** @type {number} */ (instruction[2]);
- context.lineCap = /** @type {string} */ (instruction[3]);
- context.lineJoin = /** @type {string} */ (instruction[4]);
- context.miterLimit = /** @type {number} */ (instruction[5]);
- if (ol.has.CANVAS_LINE_DASH) {
- context.lineDashOffset = /** @type {number} */ (instruction[7]);
- context.setLineDash(/** @type {Array.<number>} */ (instruction[6]));
- }
- };
- /**
- * @param {ol.DeclutterGroup} declutterGroup Declutter group.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- */
- ol.render.canvas.Replay.prototype.renderDeclutter_ = function(declutterGroup, feature) {
- if (declutterGroup && declutterGroup.length > 5) {
- var groupCount = declutterGroup[4];
- if (groupCount == 1 || groupCount == declutterGroup.length - 5) {
- /** @type {ol.RBushEntry} */
- var box = {
- minX: /** @type {number} */ (declutterGroup[0]),
- minY: /** @type {number} */ (declutterGroup[1]),
- maxX: /** @type {number} */ (declutterGroup[2]),
- maxY: /** @type {number} */ (declutterGroup[3]),
- value: feature
- };
- if (!this.declutterTree.collides(box)) {
- this.declutterTree.insert(box);
- var drawImage = ol.render.canvas.drawImage;
- for (var j = 5, jj = declutterGroup.length; j < jj; ++j) {
- var declutterData = /** @type {Array} */ (declutterGroup[j]);
- if (declutterData) {
- if (declutterData.length > 11) {
- this.replayTextBackground_(declutterData[0],
- declutterData[13], declutterData[14], declutterData[15], declutterData[16],
- declutterData[11], declutterData[12]);
- }
- drawImage.apply(undefined, declutterData);
- }
- }
- }
- declutterGroup.length = 5;
- ol.extent.createOrUpdateEmpty(declutterGroup);
- }
- }
- };
- /**
- * @private
- * @param {CanvasRenderingContext2D} context Context.
- * @param {ol.Transform} transform Transform.
- * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
- * to skip.
- * @param {Array.<*>} instructions Instructions array.
- * @param {function((ol.Feature|ol.render.Feature)): T|undefined}
- * featureCallback Feature callback.
- * @param {ol.Extent=} opt_hitExtent Only check features that intersect this
- * extent.
- * @return {T|undefined} Callback result.
- * @template T
- */
- ol.render.canvas.Replay.prototype.replay_ = function(
- context, transform, skippedFeaturesHash,
- instructions, featureCallback, opt_hitExtent) {
- /** @type {Array.<number>} */
- var pixelCoordinates;
- if (this.pixelCoordinates_ && ol.array.equals(transform, this.renderedTransform_)) {
- pixelCoordinates = this.pixelCoordinates_;
- } else {
- if (!this.pixelCoordinates_) {
- this.pixelCoordinates_ = [];
- }
- pixelCoordinates = ol.geom.flat.transform.transform2D(
- this.coordinates, 0, this.coordinates.length, 2,
- transform, this.pixelCoordinates_);
- ol.transform.setFromArray(this.renderedTransform_, transform);
- }
- var skipFeatures = !ol.obj.isEmpty(skippedFeaturesHash);
- var i = 0; // instruction index
- var ii = instructions.length; // end of instructions
- var d = 0; // data index
- var dd; // end of per-instruction data
- var anchorX, anchorY, prevX, prevY, roundX, roundY, declutterGroup, image;
- var pendingFill = 0;
- var pendingStroke = 0;
- var lastFillInstruction = null;
- var lastStrokeInstruction = null;
- var coordinateCache = this.coordinateCache_;
- var viewRotation = this.viewRotation_;
- var state = /** @type {olx.render.State} */ ({
- context: context,
- pixelRatio: this.pixelRatio,
- resolution: this.resolution,
- rotation: viewRotation
- });
- // When the batch size gets too big, performance decreases. 200 is a good
- // balance between batch size and number of fill/stroke instructions.
- var batchSize =
- this.instructions != instructions || this.overlaps ? 0 : 200;
- while (i < ii) {
- var instruction = instructions[i];
- var type = /** @type {ol.render.canvas.Instruction} */ (instruction[0]);
- var /** @type {ol.Feature|ol.render.Feature} */ feature, x, y;
- switch (type) {
- case ol.render.canvas.Instruction.BEGIN_GEOMETRY:
- feature = /** @type {ol.Feature|ol.render.Feature} */ (instruction[1]);
- if ((skipFeatures &&
- skippedFeaturesHash[ol.getUid(feature).toString()]) ||
- !feature.getGeometry()) {
- i = /** @type {number} */ (instruction[2]);
- } else if (opt_hitExtent !== undefined && !ol.extent.intersects(
- opt_hitExtent, feature.getGeometry().getExtent())) {
- i = /** @type {number} */ (instruction[2]) + 1;
- } else {
- ++i;
- }
- break;
- case ol.render.canvas.Instruction.BEGIN_PATH:
- if (pendingFill > batchSize) {
- this.fill_(context);
- pendingFill = 0;
- }
- if (pendingStroke > batchSize) {
- context.stroke();
- pendingStroke = 0;
- }
- if (!pendingFill && !pendingStroke) {
- context.beginPath();
- prevX = prevY = NaN;
- }
- ++i;
- break;
- case ol.render.canvas.Instruction.CIRCLE:
- d = /** @type {number} */ (instruction[1]);
- var x1 = pixelCoordinates[d];
- var y1 = pixelCoordinates[d + 1];
- var x2 = pixelCoordinates[d + 2];
- var y2 = pixelCoordinates[d + 3];
- var dx = x2 - x1;
- var dy = y2 - y1;
- var r = Math.sqrt(dx * dx + dy * dy);
- context.moveTo(x1 + r, y1);
- context.arc(x1, y1, r, 0, 2 * Math.PI, true);
- ++i;
- break;
- case ol.render.canvas.Instruction.CLOSE_PATH:
- context.closePath();
- ++i;
- break;
- case ol.render.canvas.Instruction.CUSTOM:
- d = /** @type {number} */ (instruction[1]);
- dd = instruction[2];
- var geometry = /** @type {ol.geom.SimpleGeometry} */ (instruction[3]);
- var renderer = instruction[4];
- var fn = instruction.length == 6 ? instruction[5] : undefined;
- state.geometry = geometry;
- state.feature = feature;
- if (!(i in coordinateCache)) {
- coordinateCache[i] = [];
- }
- var coords = coordinateCache[i];
- if (fn) {
- fn(pixelCoordinates, d, dd, 2, coords);
- } else {
- coords[0] = pixelCoordinates[d];
- coords[1] = pixelCoordinates[d + 1];
- coords.length = 2;
- }
- renderer(coords, state);
- ++i;
- break;
- case ol.render.canvas.Instruction.DRAW_IMAGE:
- d = /** @type {number} */ (instruction[1]);
- dd = /** @type {number} */ (instruction[2]);
- image = /** @type {HTMLCanvasElement|HTMLVideoElement|Image} */
- (instruction[3]);
- // Remaining arguments in DRAW_IMAGE are in alphabetical order
- anchorX = /** @type {number} */ (instruction[4]);
- anchorY = /** @type {number} */ (instruction[5]);
- declutterGroup = featureCallback ? null : /** @type {ol.DeclutterGroup} */ (instruction[6]);
- var height = /** @type {number} */ (instruction[7]);
- var opacity = /** @type {number} */ (instruction[8]);
- var originX = /** @type {number} */ (instruction[9]);
- var originY = /** @type {number} */ (instruction[10]);
- var rotateWithView = /** @type {boolean} */ (instruction[11]);
- var rotation = /** @type {number} */ (instruction[12]);
- var scale = /** @type {number} */ (instruction[13]);
- var snapToPixel = /** @type {boolean} */ (instruction[14]);
- var width = /** @type {number} */ (instruction[15]);
- var padding, backgroundFill, backgroundStroke;
- if (instruction.length > 16) {
- padding = /** @type {Array.<number>} */ (instruction[16]);
- backgroundFill = /** @type {boolean} */ (instruction[17]);
- backgroundStroke = /** @type {boolean} */ (instruction[18]);
- } else {
- padding = ol.render.canvas.defaultPadding;
- backgroundFill = backgroundStroke = false;
- }
- if (rotateWithView) {
- rotation += viewRotation;
- }
- for (; d < dd; d += 2) {
- this.replayImage_(context,
- pixelCoordinates[d], pixelCoordinates[d + 1], image, anchorX, anchorY,
- declutterGroup, height, opacity, originX, originY, rotation, scale,
- snapToPixel, width, padding,
- backgroundFill ? /** @type {Array.<*>} */ (lastFillInstruction) : null,
- backgroundStroke ? /** @type {Array.<*>} */ (lastStrokeInstruction) : null);
- }
- this.renderDeclutter_(declutterGroup, feature);
- ++i;
- break;
- case ol.render.canvas.Instruction.DRAW_CHARS:
- var begin = /** @type {number} */ (instruction[1]);
- var end = /** @type {number} */ (instruction[2]);
- var baseline = /** @type {number} */ (instruction[3]);
- declutterGroup = featureCallback ? null : /** @type {ol.DeclutterGroup} */ (instruction[4]);
- var overflow = /** @type {number} */ (instruction[5]);
- var fillKey = /** @type {string} */ (instruction[6]);
- var maxAngle = /** @type {number} */ (instruction[7]);
- var measure = /** @type {function(string):number} */ (instruction[8]);
- var offsetY = /** @type {number} */ (instruction[9]);
- var strokeKey = /** @type {string} */ (instruction[10]);
- var strokeWidth = /** @type {number} */ (instruction[11]);
- var text = /** @type {string} */ (instruction[12]);
- var textKey = /** @type {string} */ (instruction[13]);
- var textScale = /** @type {number} */ (instruction[14]);
- var pathLength = ol.geom.flat.length.lineString(pixelCoordinates, begin, end, 2);
- var textLength = measure(text);
- if (overflow || textLength <= pathLength) {
- var textAlign = /** @type {ol.render.canvas.TextReplay} */ (this).textStates[textKey].textAlign;
- var startM = (pathLength - textLength) * ol.render.replay.TEXT_ALIGN[textAlign];
- var parts = ol.geom.flat.textpath.lineString(
- pixelCoordinates, begin, end, 2, text, measure, startM, maxAngle);
- if (parts) {
- var c, cc, chars, label, part;
- if (strokeKey) {
- for (c = 0, cc = parts.length; c < cc; ++c) {
- part = parts[c]; // x, y, anchorX, rotation, chunk
- chars = /** @type {string} */ (part[4]);
- label = /** @type {ol.render.canvas.TextReplay} */ (this).getImage(chars, textKey, '', strokeKey);
- anchorX = /** @type {number} */ (part[2]) + strokeWidth;
- anchorY = baseline * label.height + (0.5 - baseline) * 2 * strokeWidth - offsetY;
- this.replayImage_(context,
- /** @type {number} */ (part[0]), /** @type {number} */ (part[1]), label,
- anchorX, anchorY, declutterGroup, label.height, 1, 0, 0,
- /** @type {number} */ (part[3]), textScale, false, label.width,
- ol.render.canvas.defaultPadding, null, null);
- }
- }
- if (fillKey) {
- for (c = 0, cc = parts.length; c < cc; ++c) {
- part = parts[c]; // x, y, anchorX, rotation, chunk
- chars = /** @type {string} */ (part[4]);
- label = /** @type {ol.render.canvas.TextReplay} */ (this).getImage(chars, textKey, fillKey, '');
- anchorX = /** @type {number} */ (part[2]);
- anchorY = baseline * label.height - offsetY;
- this.replayImage_(context,
- /** @type {number} */ (part[0]), /** @type {number} */ (part[1]), label,
- anchorX, anchorY, declutterGroup, label.height, 1, 0, 0,
- /** @type {number} */ (part[3]), textScale, false, label.width,
- ol.render.canvas.defaultPadding, null, null);
- }
- }
- }
- }
- this.renderDeclutter_(declutterGroup, feature);
- ++i;
- break;
- case ol.render.canvas.Instruction.END_GEOMETRY:
- if (featureCallback !== undefined) {
- feature = /** @type {ol.Feature|ol.render.Feature} */ (instruction[1]);
- var result = featureCallback(feature);
- if (result) {
- return result;
- }
- }
- ++i;
- break;
- case ol.render.canvas.Instruction.FILL:
- if (batchSize) {
- pendingFill++;
- } else {
- this.fill_(context);
- }
- ++i;
- break;
- case ol.render.canvas.Instruction.MOVE_TO_LINE_TO:
- d = /** @type {number} */ (instruction[1]);
- dd = /** @type {number} */ (instruction[2]);
- x = pixelCoordinates[d];
- y = pixelCoordinates[d + 1];
- roundX = (x + 0.5) | 0;
- roundY = (y + 0.5) | 0;
- if (roundX !== prevX || roundY !== prevY) {
- context.moveTo(x, y);
- prevX = roundX;
- prevY = roundY;
- }
- for (d += 2; d < dd; d += 2) {
- x = pixelCoordinates[d];
- y = pixelCoordinates[d + 1];
- roundX = (x + 0.5) | 0;
- roundY = (y + 0.5) | 0;
- if (d == dd - 2 || roundX !== prevX || roundY !== prevY) {
- context.lineTo(x, y);
- prevX = roundX;
- prevY = roundY;
- }
- }
- ++i;
- break;
- case ol.render.canvas.Instruction.SET_FILL_STYLE:
- lastFillInstruction = instruction;
- this.fillOrigin_ = instruction[2];
- if (pendingFill) {
- this.fill_(context);
- pendingFill = 0;
- if (pendingStroke) {
- context.stroke();
- pendingStroke = 0;
- }
- }
- context.fillStyle = /** @type {ol.ColorLike} */ (instruction[1]);
- ++i;
- break;
- case ol.render.canvas.Instruction.SET_STROKE_STYLE:
- lastStrokeInstruction = instruction;
- if (pendingStroke) {
- context.stroke();
- pendingStroke = 0;
- }
- this.setStrokeStyle_(context, /** @type {Array.<*>} */ (instruction));
- ++i;
- break;
- case ol.render.canvas.Instruction.STROKE:
- if (batchSize) {
- pendingStroke++;
- } else {
- context.stroke();
- }
- ++i;
- break;
- default:
- ++i; // consume the instruction anyway, to avoid an infinite loop
- break;
- }
- }
- if (pendingFill) {
- this.fill_(context);
- }
- if (pendingStroke) {
- context.stroke();
- }
- return undefined;
- };
- /**
- * @param {CanvasRenderingContext2D} context Context.
- * @param {ol.Transform} transform Transform.
- * @param {number} viewRotation View rotation.
- * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
- * to skip.
- */
- ol.render.canvas.Replay.prototype.replay = function(
- context, transform, viewRotation, skippedFeaturesHash) {
- this.viewRotation_ = viewRotation;
- this.replay_(context, transform,
- skippedFeaturesHash, this.instructions, undefined, undefined);
- };
- /**
- * @param {CanvasRenderingContext2D} context Context.
- * @param {ol.Transform} transform Transform.
- * @param {number} viewRotation View rotation.
- * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
- * to skip.
- * @param {function((ol.Feature|ol.render.Feature)): T=} opt_featureCallback
- * Feature callback.
- * @param {ol.Extent=} opt_hitExtent Only check features that intersect this
- * extent.
- * @return {T|undefined} Callback result.
- * @template T
- */
- ol.render.canvas.Replay.prototype.replayHitDetection = function(
- context, transform, viewRotation, skippedFeaturesHash,
- opt_featureCallback, opt_hitExtent) {
- this.viewRotation_ = viewRotation;
- return this.replay_(context, transform, skippedFeaturesHash,
- this.hitDetectionInstructions, opt_featureCallback, opt_hitExtent);
- };
- /**
- * Reverse the hit detection instructions.
- */
- ol.render.canvas.Replay.prototype.reverseHitDetectionInstructions = function() {
- var hitDetectionInstructions = this.hitDetectionInstructions;
- // step 1 - reverse array
- hitDetectionInstructions.reverse();
- // step 2 - reverse instructions within geometry blocks
- var i;
- var n = hitDetectionInstructions.length;
- var instruction;
- var type;
- var begin = -1;
- for (i = 0; i < n; ++i) {
- instruction = hitDetectionInstructions[i];
- type = /** @type {ol.render.canvas.Instruction} */ (instruction[0]);
- if (type == ol.render.canvas.Instruction.END_GEOMETRY) {
- begin = i;
- } else if (type == ol.render.canvas.Instruction.BEGIN_GEOMETRY) {
- instruction[2] = i;
- ol.array.reverseSubArray(this.hitDetectionInstructions, begin, i);
- begin = -1;
- }
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.canvas.Replay.prototype.setFillStrokeStyle = function(fillStyle, strokeStyle) {
- var state = this.state;
- if (fillStyle) {
- var fillStyleColor = fillStyle.getColor();
- state.fillStyle = ol.colorlike.asColorLike(fillStyleColor ?
- fillStyleColor : ol.render.canvas.defaultFillStyle);
- } else {
- state.fillStyle = undefined;
- }
- if (strokeStyle) {
- var strokeStyleColor = strokeStyle.getColor();
- state.strokeStyle = ol.colorlike.asColorLike(strokeStyleColor ?
- strokeStyleColor : ol.render.canvas.defaultStrokeStyle);
- var strokeStyleLineCap = strokeStyle.getLineCap();
- state.lineCap = strokeStyleLineCap !== undefined ?
- strokeStyleLineCap : ol.render.canvas.defaultLineCap;
- var strokeStyleLineDash = strokeStyle.getLineDash();
- state.lineDash = strokeStyleLineDash ?
- strokeStyleLineDash.slice() : ol.render.canvas.defaultLineDash;
- var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();
- state.lineDashOffset = strokeStyleLineDashOffset ?
- strokeStyleLineDashOffset : ol.render.canvas.defaultLineDashOffset;
- var strokeStyleLineJoin = strokeStyle.getLineJoin();
- state.lineJoin = strokeStyleLineJoin !== undefined ?
- strokeStyleLineJoin : ol.render.canvas.defaultLineJoin;
- var strokeStyleWidth = strokeStyle.getWidth();
- state.lineWidth = strokeStyleWidth !== undefined ?
- strokeStyleWidth : ol.render.canvas.defaultLineWidth;
- var strokeStyleMiterLimit = strokeStyle.getMiterLimit();
- state.miterLimit = strokeStyleMiterLimit !== undefined ?
- strokeStyleMiterLimit : ol.render.canvas.defaultMiterLimit;
- if (state.lineWidth > this.maxLineWidth) {
- this.maxLineWidth = state.lineWidth;
- // invalidate the buffered max extent cache
- this.bufferedMaxExtent_ = null;
- }
- } else {
- state.strokeStyle = undefined;
- state.lineCap = undefined;
- state.lineDash = null;
- state.lineDashOffset = undefined;
- state.lineJoin = undefined;
- state.lineWidth = undefined;
- state.miterLimit = undefined;
- }
- };
- /**
- * @param {ol.CanvasFillStrokeState} state State.
- * @param {ol.geom.Geometry|ol.render.Feature} geometry Geometry.
- */
- ol.render.canvas.Replay.prototype.applyFill = function(state, geometry) {
- var fillStyle = state.fillStyle;
- var fillInstruction = [ol.render.canvas.Instruction.SET_FILL_STYLE, fillStyle];
- if (typeof fillStyle !== 'string') {
- var fillExtent = geometry.getExtent();
- fillInstruction.push([fillExtent[0], fillExtent[3]]);
- }
- this.instructions.push(fillInstruction);
- };
- /**
- * @param {ol.CanvasFillStrokeState} state State.
- */
- ol.render.canvas.Replay.prototype.applyStroke = function(state) {
- this.instructions.push([
- ol.render.canvas.Instruction.SET_STROKE_STYLE,
- state.strokeStyle, state.lineWidth * this.pixelRatio, state.lineCap,
- state.lineJoin, state.miterLimit,
- this.applyPixelRatio(state.lineDash), state.lineDashOffset * this.pixelRatio
- ]);
- };
- /**
- * @param {ol.CanvasFillStrokeState} state State.
- * @param {function(this:ol.render.canvas.Replay, ol.CanvasFillStrokeState, (ol.geom.Geometry|ol.render.Feature))} applyFill Apply fill.
- * @param {ol.geom.Geometry|ol.render.Feature} geometry Geometry.
- */
- ol.render.canvas.Replay.prototype.updateFillStyle = function(state, applyFill, geometry) {
- var fillStyle = state.fillStyle;
- if (typeof fillStyle !== 'string' || state.currentFillStyle != fillStyle) {
- applyFill.call(this, state, geometry);
- state.currentFillStyle = fillStyle;
- }
- };
- /**
- * @param {ol.CanvasFillStrokeState} state State.
- * @param {function(this:ol.render.canvas.Replay, ol.CanvasFillStrokeState)} applyStroke Apply stroke.
- */
- ol.render.canvas.Replay.prototype.updateStrokeStyle = function(state, applyStroke) {
- var strokeStyle = state.strokeStyle;
- var lineCap = state.lineCap;
- var lineDash = state.lineDash;
- var lineDashOffset = state.lineDashOffset;
- var lineJoin = state.lineJoin;
- var lineWidth = state.lineWidth;
- var miterLimit = state.miterLimit;
- if (state.currentStrokeStyle != strokeStyle ||
- state.currentLineCap != lineCap ||
- (lineDash != state.currentLineDash && !ol.array.equals(state.currentLineDash, lineDash)) ||
- state.currentLineDashOffset != lineDashOffset ||
- state.currentLineJoin != lineJoin ||
- state.currentLineWidth != lineWidth ||
- state.currentMiterLimit != miterLimit) {
- applyStroke.call(this, state);
- state.currentStrokeStyle = strokeStyle;
- state.currentLineCap = lineCap;
- state.currentLineDash = lineDash;
- state.currentLineDashOffset = lineDashOffset;
- state.currentLineJoin = lineJoin;
- state.currentLineWidth = lineWidth;
- state.currentMiterLimit = miterLimit;
- }
- };
- /**
- * @param {ol.geom.Geometry|ol.render.Feature} geometry Geometry.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- */
- ol.render.canvas.Replay.prototype.endGeometry = function(geometry, feature) {
- this.beginGeometryInstruction1_[2] = this.instructions.length;
- this.beginGeometryInstruction1_ = null;
- this.beginGeometryInstruction2_[2] = this.hitDetectionInstructions.length;
- this.beginGeometryInstruction2_ = null;
- var endGeometryInstruction =
- [ol.render.canvas.Instruction.END_GEOMETRY, feature];
- this.instructions.push(endGeometryInstruction);
- this.hitDetectionInstructions.push(endGeometryInstruction);
- };
- /**
- * FIXME empty description for jsdoc
- */
- ol.render.canvas.Replay.prototype.finish = ol.nullFunction;
- /**
- * Get the buffered rendering extent. Rendering will be clipped to the extent
- * provided to the constructor. To account for symbolizers that may intersect
- * this extent, we calculate a buffered extent (e.g. based on stroke width).
- * @return {ol.Extent} The buffered rendering extent.
- * @protected
- */
- ol.render.canvas.Replay.prototype.getBufferedMaxExtent = function() {
- if (!this.bufferedMaxExtent_) {
- this.bufferedMaxExtent_ = ol.extent.clone(this.maxExtent);
- if (this.maxLineWidth > 0) {
- var width = this.resolution * (this.maxLineWidth + 1) / 2;
- ol.extent.buffer(this.bufferedMaxExtent_, width, this.bufferedMaxExtent_);
- }
- }
- return this.bufferedMaxExtent_;
- };
- goog.provide('ol.render.canvas.ImageReplay');
- goog.require('ol');
- goog.require('ol.render.canvas.Instruction');
- goog.require('ol.render.canvas.Replay');
- /**
- * @constructor
- * @extends {ol.render.canvas.Replay}
- * @param {number} tolerance Tolerance.
- * @param {ol.Extent} maxExtent Maximum extent.
- * @param {number} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @param {boolean} overlaps The replay can have overlapping geometries.
- * @param {?} declutterTree Declutter tree.
- * @struct
- */
- ol.render.canvas.ImageReplay = function(
- tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree) {
- ol.render.canvas.Replay.call(this,
- tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree);
- /**
- * @private
- * @type {ol.DeclutterGroup}
- */
- this.declutterGroup_ = null;
- /**
- * @private
- * @type {HTMLCanvasElement|HTMLVideoElement|Image}
- */
- this.hitDetectionImage_ = null;
- /**
- * @private
- * @type {HTMLCanvasElement|HTMLVideoElement|Image}
- */
- this.image_ = null;
- /**
- * @private
- * @type {number|undefined}
- */
- this.anchorX_ = undefined;
- /**
- * @private
- * @type {number|undefined}
- */
- this.anchorY_ = undefined;
- /**
- * @private
- * @type {number|undefined}
- */
- this.height_ = undefined;
- /**
- * @private
- * @type {number|undefined}
- */
- this.opacity_ = undefined;
- /**
- * @private
- * @type {number|undefined}
- */
- this.originX_ = undefined;
- /**
- * @private
- * @type {number|undefined}
- */
- this.originY_ = undefined;
- /**
- * @private
- * @type {boolean|undefined}
- */
- this.rotateWithView_ = undefined;
- /**
- * @private
- * @type {number|undefined}
- */
- this.rotation_ = undefined;
- /**
- * @private
- * @type {number|undefined}
- */
- this.scale_ = undefined;
- /**
- * @private
- * @type {boolean|undefined}
- */
- this.snapToPixel_ = undefined;
- /**
- * @private
- * @type {number|undefined}
- */
- this.width_ = undefined;
- };
- ol.inherits(ol.render.canvas.ImageReplay, ol.render.canvas.Replay);
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @private
- * @return {number} My end.
- */
- ol.render.canvas.ImageReplay.prototype.drawCoordinates_ = function(flatCoordinates, offset, end, stride) {
- return this.appendFlatCoordinates(
- flatCoordinates, offset, end, stride, false, false);
- };
- /**
- * @inheritDoc
- */
- ol.render.canvas.ImageReplay.prototype.drawPoint = function(pointGeometry, feature) {
- if (!this.image_) {
- return;
- }
- this.beginGeometry(pointGeometry, feature);
- var flatCoordinates = pointGeometry.getFlatCoordinates();
- var stride = pointGeometry.getStride();
- var myBegin = this.coordinates.length;
- var myEnd = this.drawCoordinates_(
- flatCoordinates, 0, flatCoordinates.length, stride);
- this.instructions.push([
- ol.render.canvas.Instruction.DRAW_IMAGE, myBegin, myEnd, this.image_,
- // Remaining arguments to DRAW_IMAGE are in alphabetical order
- this.anchorX_, this.anchorY_, this.declutterGroup_, this.height_, this.opacity_,
- this.originX_, this.originY_, this.rotateWithView_, this.rotation_,
- this.scale_ * this.pixelRatio, this.snapToPixel_, this.width_
- ]);
- this.hitDetectionInstructions.push([
- ol.render.canvas.Instruction.DRAW_IMAGE, myBegin, myEnd,
- this.hitDetectionImage_,
- // Remaining arguments to DRAW_IMAGE are in alphabetical order
- this.anchorX_, this.anchorY_, this.declutterGroup_, this.height_, this.opacity_,
- this.originX_, this.originY_, this.rotateWithView_, this.rotation_,
- this.scale_, this.snapToPixel_, this.width_
- ]);
- this.endGeometry(pointGeometry, feature);
- };
- /**
- * @inheritDoc
- */
- ol.render.canvas.ImageReplay.prototype.drawMultiPoint = function(multiPointGeometry, feature) {
- if (!this.image_) {
- return;
- }
- this.beginGeometry(multiPointGeometry, feature);
- var flatCoordinates = multiPointGeometry.getFlatCoordinates();
- var stride = multiPointGeometry.getStride();
- var myBegin = this.coordinates.length;
- var myEnd = this.drawCoordinates_(
- flatCoordinates, 0, flatCoordinates.length, stride);
- this.instructions.push([
- ol.render.canvas.Instruction.DRAW_IMAGE, myBegin, myEnd, this.image_,
- // Remaining arguments to DRAW_IMAGE are in alphabetical order
- this.anchorX_, this.anchorY_, this.declutterGroup_, this.height_, this.opacity_,
- this.originX_, this.originY_, this.rotateWithView_, this.rotation_,
- this.scale_ * this.pixelRatio, this.snapToPixel_, this.width_
- ]);
- this.hitDetectionInstructions.push([
- ol.render.canvas.Instruction.DRAW_IMAGE, myBegin, myEnd,
- this.hitDetectionImage_,
- // Remaining arguments to DRAW_IMAGE are in alphabetical order
- this.anchorX_, this.anchorY_, this.declutterGroup_, this.height_, this.opacity_,
- this.originX_, this.originY_, this.rotateWithView_, this.rotation_,
- this.scale_, this.snapToPixel_, this.width_
- ]);
- this.endGeometry(multiPointGeometry, feature);
- };
- /**
- * @inheritDoc
- */
- ol.render.canvas.ImageReplay.prototype.finish = function() {
- this.reverseHitDetectionInstructions();
- // FIXME this doesn't really protect us against further calls to draw*Geometry
- this.anchorX_ = undefined;
- this.anchorY_ = undefined;
- this.hitDetectionImage_ = null;
- this.image_ = null;
- this.height_ = undefined;
- this.scale_ = undefined;
- this.opacity_ = undefined;
- this.originX_ = undefined;
- this.originY_ = undefined;
- this.rotateWithView_ = undefined;
- this.rotation_ = undefined;
- this.snapToPixel_ = undefined;
- this.width_ = undefined;
- };
- /**
- * @inheritDoc
- */
- ol.render.canvas.ImageReplay.prototype.setImageStyle = function(imageStyle, declutterGroup) {
- var anchor = imageStyle.getAnchor();
- var size = imageStyle.getSize();
- var hitDetectionImage = imageStyle.getHitDetectionImage(1);
- var image = imageStyle.getImage(1);
- var origin = imageStyle.getOrigin();
- this.anchorX_ = anchor[0];
- this.anchorY_ = anchor[1];
- this.declutterGroup_ = /** @type {ol.DeclutterGroup} */ (declutterGroup);
- this.hitDetectionImage_ = hitDetectionImage;
- this.image_ = image;
- this.height_ = size[1];
- this.opacity_ = imageStyle.getOpacity();
- this.originX_ = origin[0];
- this.originY_ = origin[1];
- this.rotateWithView_ = imageStyle.getRotateWithView();
- this.rotation_ = imageStyle.getRotation();
- this.scale_ = imageStyle.getScale();
- this.snapToPixel_ = imageStyle.getSnapToPixel();
- this.width_ = size[0];
- };
- goog.provide('ol.render.canvas.LineStringReplay');
- goog.require('ol');
- goog.require('ol.render.canvas.Instruction');
- goog.require('ol.render.canvas.Replay');
- /**
- * @constructor
- * @extends {ol.render.canvas.Replay}
- * @param {number} tolerance Tolerance.
- * @param {ol.Extent} maxExtent Maximum extent.
- * @param {number} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @param {boolean} overlaps The replay can have overlapping geometries.
- * @param {?} declutterTree Declutter tree.
- * @struct
- */
- ol.render.canvas.LineStringReplay = function(
- tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree) {
- ol.render.canvas.Replay.call(this,
- tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree);
- };
- ol.inherits(ol.render.canvas.LineStringReplay, ol.render.canvas.Replay);
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @private
- * @return {number} end.
- */
- ol.render.canvas.LineStringReplay.prototype.drawFlatCoordinates_ = function(flatCoordinates, offset, end, stride) {
- var myBegin = this.coordinates.length;
- var myEnd = this.appendFlatCoordinates(
- flatCoordinates, offset, end, stride, false, false);
- var moveToLineToInstruction =
- [ol.render.canvas.Instruction.MOVE_TO_LINE_TO, myBegin, myEnd];
- this.instructions.push(moveToLineToInstruction);
- this.hitDetectionInstructions.push(moveToLineToInstruction);
- return end;
- };
- /**
- * @inheritDoc
- */
- ol.render.canvas.LineStringReplay.prototype.drawLineString = function(lineStringGeometry, feature) {
- var state = this.state;
- var strokeStyle = state.strokeStyle;
- var lineWidth = state.lineWidth;
- if (strokeStyle === undefined || lineWidth === undefined) {
- return;
- }
- this.updateStrokeStyle(state, this.applyStroke);
- this.beginGeometry(lineStringGeometry, feature);
- this.hitDetectionInstructions.push([
- ol.render.canvas.Instruction.SET_STROKE_STYLE,
- state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
- state.miterLimit, state.lineDash, state.lineDashOffset
- ], [
- ol.render.canvas.Instruction.BEGIN_PATH
- ]);
- var flatCoordinates = lineStringGeometry.getFlatCoordinates();
- var stride = lineStringGeometry.getStride();
- this.drawFlatCoordinates_(flatCoordinates, 0, flatCoordinates.length, stride);
- this.hitDetectionInstructions.push([ol.render.canvas.Instruction.STROKE]);
- this.endGeometry(lineStringGeometry, feature);
- };
- /**
- * @inheritDoc
- */
- ol.render.canvas.LineStringReplay.prototype.drawMultiLineString = function(multiLineStringGeometry, feature) {
- var state = this.state;
- var strokeStyle = state.strokeStyle;
- var lineWidth = state.lineWidth;
- if (strokeStyle === undefined || lineWidth === undefined) {
- return;
- }
- this.updateStrokeStyle(state, this.applyStroke);
- this.beginGeometry(multiLineStringGeometry, feature);
- this.hitDetectionInstructions.push([
- ol.render.canvas.Instruction.SET_STROKE_STYLE,
- state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
- state.miterLimit, state.lineDash, state.lineDashOffset
- ], [
- ol.render.canvas.Instruction.BEGIN_PATH
- ]);
- var ends = multiLineStringGeometry.getEnds();
- var flatCoordinates = multiLineStringGeometry.getFlatCoordinates();
- var stride = multiLineStringGeometry.getStride();
- var offset = 0;
- var i, ii;
- for (i = 0, ii = ends.length; i < ii; ++i) {
- offset = this.drawFlatCoordinates_(
- flatCoordinates, offset, ends[i], stride);
- }
- this.hitDetectionInstructions.push([ol.render.canvas.Instruction.STROKE]);
- this.endGeometry(multiLineStringGeometry, feature);
- };
- /**
- * @inheritDoc
- */
- ol.render.canvas.LineStringReplay.prototype.finish = function() {
- var state = this.state;
- if (state.lastStroke != undefined && state.lastStroke != this.coordinates.length) {
- this.instructions.push([ol.render.canvas.Instruction.STROKE]);
- }
- this.reverseHitDetectionInstructions();
- this.state = null;
- };
- /**
- * @inheritDoc.
- */
- ol.render.canvas.LineStringReplay.prototype.applyStroke = function(state) {
- if (state.lastStroke != undefined && state.lastStroke != this.coordinates.length) {
- this.instructions.push([ol.render.canvas.Instruction.STROKE]);
- state.lastStroke = this.coordinates.length;
- }
- state.lastStroke = 0;
- ol.render.canvas.Replay.prototype.applyStroke.call(this, state);
- this.instructions.push([ol.render.canvas.Instruction.BEGIN_PATH]);
- };
- goog.provide('ol.render.canvas.PolygonReplay');
- goog.require('ol');
- goog.require('ol.color');
- goog.require('ol.geom.flat.simplify');
- goog.require('ol.render.canvas');
- goog.require('ol.render.canvas.Instruction');
- goog.require('ol.render.canvas.Replay');
- /**
- * @constructor
- * @extends {ol.render.canvas.Replay}
- * @param {number} tolerance Tolerance.
- * @param {ol.Extent} maxExtent Maximum extent.
- * @param {number} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @param {boolean} overlaps The replay can have overlapping geometries.
- * @param {?} declutterTree Declutter tree.
- * @struct
- */
- ol.render.canvas.PolygonReplay = function(
- tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree) {
- ol.render.canvas.Replay.call(this,
- tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree);
- };
- ol.inherits(ol.render.canvas.PolygonReplay, ol.render.canvas.Replay);
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<number>} ends Ends.
- * @param {number} stride Stride.
- * @private
- * @return {number} End.
- */
- ol.render.canvas.PolygonReplay.prototype.drawFlatCoordinatess_ = function(flatCoordinates, offset, ends, stride) {
- var state = this.state;
- var fill = state.fillStyle !== undefined;
- var stroke = state.strokeStyle != undefined;
- var numEnds = ends.length;
- var beginPathInstruction = [ol.render.canvas.Instruction.BEGIN_PATH];
- this.instructions.push(beginPathInstruction);
- this.hitDetectionInstructions.push(beginPathInstruction);
- for (var i = 0; i < numEnds; ++i) {
- var end = ends[i];
- var myBegin = this.coordinates.length;
- var myEnd = this.appendFlatCoordinates(
- flatCoordinates, offset, end, stride, true, !stroke);
- var moveToLineToInstruction =
- [ol.render.canvas.Instruction.MOVE_TO_LINE_TO, myBegin, myEnd];
- this.instructions.push(moveToLineToInstruction);
- this.hitDetectionInstructions.push(moveToLineToInstruction);
- if (stroke) {
- // Performance optimization: only call closePath() when we have a stroke.
- // Otherwise the ring is closed already (see appendFlatCoordinates above).
- var closePathInstruction = [ol.render.canvas.Instruction.CLOSE_PATH];
- this.instructions.push(closePathInstruction);
- this.hitDetectionInstructions.push(closePathInstruction);
- }
- offset = end;
- }
- var fillInstruction = [ol.render.canvas.Instruction.FILL];
- this.hitDetectionInstructions.push(fillInstruction);
- if (fill) {
- this.instructions.push(fillInstruction);
- }
- if (stroke) {
- var strokeInstruction = [ol.render.canvas.Instruction.STROKE];
- this.instructions.push(strokeInstruction);
- this.hitDetectionInstructions.push(strokeInstruction);
- }
- return offset;
- };
- /**
- * @inheritDoc
- */
- ol.render.canvas.PolygonReplay.prototype.drawCircle = function(circleGeometry, feature) {
- var state = this.state;
- var fillStyle = state.fillStyle;
- var strokeStyle = state.strokeStyle;
- if (fillStyle === undefined && strokeStyle === undefined) {
- return;
- }
- this.setFillStrokeStyles_(circleGeometry);
- this.beginGeometry(circleGeometry, feature);
- // always fill the circle for hit detection
- this.hitDetectionInstructions.push([
- ol.render.canvas.Instruction.SET_FILL_STYLE,
- ol.color.asString(ol.render.canvas.defaultFillStyle)
- ]);
- if (state.strokeStyle !== undefined) {
- this.hitDetectionInstructions.push([
- ol.render.canvas.Instruction.SET_STROKE_STYLE,
- state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
- state.miterLimit, state.lineDash, state.lineDashOffset
- ]);
- }
- var flatCoordinates = circleGeometry.getFlatCoordinates();
- var stride = circleGeometry.getStride();
- var myBegin = this.coordinates.length;
- this.appendFlatCoordinates(
- flatCoordinates, 0, flatCoordinates.length, stride, false, false);
- var beginPathInstruction = [ol.render.canvas.Instruction.BEGIN_PATH];
- var circleInstruction = [ol.render.canvas.Instruction.CIRCLE, myBegin];
- this.instructions.push(beginPathInstruction, circleInstruction);
- this.hitDetectionInstructions.push(beginPathInstruction, circleInstruction);
- var fillInstruction = [ol.render.canvas.Instruction.FILL];
- this.hitDetectionInstructions.push(fillInstruction);
- if (state.fillStyle !== undefined) {
- this.instructions.push(fillInstruction);
- }
- if (state.strokeStyle !== undefined) {
- var strokeInstruction = [ol.render.canvas.Instruction.STROKE];
- this.instructions.push(strokeInstruction);
- this.hitDetectionInstructions.push(strokeInstruction);
- }
- this.endGeometry(circleGeometry, feature);
- };
- /**
- * @inheritDoc
- */
- ol.render.canvas.PolygonReplay.prototype.drawPolygon = function(polygonGeometry, feature) {
- var state = this.state;
- this.setFillStrokeStyles_(polygonGeometry);
- this.beginGeometry(polygonGeometry, feature);
- // always fill the polygon for hit detection
- this.hitDetectionInstructions.push([
- ol.render.canvas.Instruction.SET_FILL_STYLE,
- ol.color.asString(ol.render.canvas.defaultFillStyle)]
- );
- if (state.strokeStyle !== undefined) {
- this.hitDetectionInstructions.push([
- ol.render.canvas.Instruction.SET_STROKE_STYLE,
- state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
- state.miterLimit, state.lineDash, state.lineDashOffset
- ]);
- }
- var ends = polygonGeometry.getEnds();
- var flatCoordinates = polygonGeometry.getOrientedFlatCoordinates();
- var stride = polygonGeometry.getStride();
- this.drawFlatCoordinatess_(flatCoordinates, 0, ends, stride);
- this.endGeometry(polygonGeometry, feature);
- };
- /**
- * @inheritDoc
- */
- ol.render.canvas.PolygonReplay.prototype.drawMultiPolygon = function(multiPolygonGeometry, feature) {
- var state = this.state;
- var fillStyle = state.fillStyle;
- var strokeStyle = state.strokeStyle;
- if (fillStyle === undefined && strokeStyle === undefined) {
- return;
- }
- this.setFillStrokeStyles_(multiPolygonGeometry);
- this.beginGeometry(multiPolygonGeometry, feature);
- // always fill the multi-polygon for hit detection
- this.hitDetectionInstructions.push([
- ol.render.canvas.Instruction.SET_FILL_STYLE,
- ol.color.asString(ol.render.canvas.defaultFillStyle)
- ]);
- if (state.strokeStyle !== undefined) {
- this.hitDetectionInstructions.push([
- ol.render.canvas.Instruction.SET_STROKE_STYLE,
- state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
- state.miterLimit, state.lineDash, state.lineDashOffset
- ]);
- }
- var endss = multiPolygonGeometry.getEndss();
- var flatCoordinates = multiPolygonGeometry.getOrientedFlatCoordinates();
- var stride = multiPolygonGeometry.getStride();
- var offset = 0;
- var i, ii;
- for (i = 0, ii = endss.length; i < ii; ++i) {
- offset = this.drawFlatCoordinatess_(
- flatCoordinates, offset, endss[i], stride);
- }
- this.endGeometry(multiPolygonGeometry, feature);
- };
- /**
- * @inheritDoc
- */
- ol.render.canvas.PolygonReplay.prototype.finish = function() {
- this.reverseHitDetectionInstructions();
- this.state = null;
- // We want to preserve topology when drawing polygons. Polygons are
- // simplified using quantization and point elimination. However, we might
- // have received a mix of quantized and non-quantized geometries, so ensure
- // that all are quantized by quantizing all coordinates in the batch.
- var tolerance = this.tolerance;
- if (tolerance !== 0) {
- var coordinates = this.coordinates;
- var i, ii;
- for (i = 0, ii = coordinates.length; i < ii; ++i) {
- coordinates[i] = ol.geom.flat.simplify.snap(coordinates[i], tolerance);
- }
- }
- };
- /**
- * @private
- * @param {ol.geom.Geometry|ol.render.Feature} geometry Geometry.
- */
- ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyles_ = function(geometry) {
- var state = this.state;
- var fillStyle = state.fillStyle;
- if (fillStyle !== undefined) {
- this.updateFillStyle(state, this.applyFill, geometry);
- }
- if (state.strokeStyle !== undefined) {
- this.updateStrokeStyle(state, this.applyStroke);
- }
- };
- goog.provide('ol.geom.flat.straightchunk');
- /**
- * @param {number} maxAngle Maximum acceptable angle delta between segments.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @return {Array.<number>} Start and end of the first suitable chunk of the
- * given `flatCoordinates`.
- */
- ol.geom.flat.straightchunk.lineString = function(maxAngle, flatCoordinates, offset, end, stride) {
- var chunkStart = offset;
- var chunkEnd = offset;
- var chunkM = 0;
- var m = 0;
- var start = offset;
- var acos, i, m12, m23, x1, y1, x12, y12, x23, y23;
- for (i = offset; i < end; i += stride) {
- var x2 = flatCoordinates[i];
- var y2 = flatCoordinates[i + 1];
- if (x1 !== undefined) {
- x23 = x2 - x1;
- y23 = y2 - y1;
- m23 = Math.sqrt(x23 * x23 + y23 * y23);
- if (x12 !== undefined) {
- m += m12;
- acos = Math.acos((x12 * x23 + y12 * y23) / (m12 * m23));
- if (acos > maxAngle) {
- if (m > chunkM) {
- chunkM = m;
- chunkStart = start;
- chunkEnd = i;
- }
- m = 0;
- start = i - stride;
- }
- }
- m12 = m23;
- x12 = x23;
- y12 = y23;
- }
- x1 = x2;
- y1 = y2;
- }
- m += m23;
- return m > chunkM ? [start, i] : [chunkStart, chunkEnd];
- };
- goog.provide('ol.style.TextPlacement');
- /**
- * Text placement. One of `'point'`, `'line'`. Default is `'point'`. Note that
- * `'line'` requires the underlying geometry to be a {@link ol.geom.LineString},
- * {@link ol.geom.Polygon}, {@link ol.geom.MultiLineString} or
- * {@link ol.geom.MultiPolygon}.
- * @enum {string}
- */
- ol.style.TextPlacement = {
- POINT: 'point',
- LINE: 'line'
- };
- goog.provide('ol.render.canvas.TextReplay');
- goog.require('ol');
- goog.require('ol.colorlike');
- goog.require('ol.dom');
- goog.require('ol.extent');
- goog.require('ol.geom.flat.straightchunk');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.has');
- goog.require('ol.render.canvas');
- goog.require('ol.render.canvas.Instruction');
- goog.require('ol.render.canvas.Replay');
- goog.require('ol.render.replay');
- goog.require('ol.style.TextPlacement');
- /**
- * @constructor
- * @extends {ol.render.canvas.Replay}
- * @param {number} tolerance Tolerance.
- * @param {ol.Extent} maxExtent Maximum extent.
- * @param {number} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @param {boolean} overlaps The replay can have overlapping geometries.
- * @param {?} declutterTree Declutter tree.
- * @struct
- */
- ol.render.canvas.TextReplay = function(
- tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree) {
- ol.render.canvas.Replay.call(this,
- tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree);
- /**
- * @private
- * @type {ol.DeclutterGroup}
- */
- this.declutterGroup_;
- /**
- * @private
- * @type {Array.<HTMLCanvasElement>}
- */
- this.labels_ = null;
- /**
- * @private
- * @type {string}
- */
- this.text_ = '';
- /**
- * @private
- * @type {number}
- */
- this.textOffsetX_ = 0;
- /**
- * @private
- * @type {number}
- */
- this.textOffsetY_ = 0;
- /**
- * @private
- * @type {boolean|undefined}
- */
- this.textRotateWithView_ = undefined;
- /**
- * @private
- * @type {number}
- */
- this.textRotation_ = 0;
- /**
- * @private
- * @type {?ol.CanvasFillState}
- */
- this.textFillState_ = null;
- /**
- * @type {Object.<string, ol.CanvasFillState>}
- */
- this.fillStates = {};
- /**
- * @private
- * @type {?ol.CanvasStrokeState}
- */
- this.textStrokeState_ = null;
- /**
- * @type {Object.<string, ol.CanvasStrokeState>}
- */
- this.strokeStates = {};
- /**
- * @private
- * @type {ol.CanvasTextState}
- */
- this.textState_ = /** @type {ol.CanvasTextState} */ ({});
- /**
- * @type {Object.<string, ol.CanvasTextState>}
- */
- this.textStates = {};
- /**
- * @private
- * @type {string}
- */
- this.textKey_ = '';
- /**
- * @private
- * @type {string}
- */
- this.fillKey_ = '';
- /**
- * @private
- * @type {string}
- */
- this.strokeKey_ = '';
- /**
- * @private
- * @type {Object.<string, Object.<string, number>>}
- */
- this.widths_ = {};
- var labelCache = ol.render.canvas.labelCache;
- labelCache.prune();
- };
- ol.inherits(ol.render.canvas.TextReplay, ol.render.canvas.Replay);
- /**
- * @param {string} font Font to use for measuring.
- * @param {Array.<string>} lines Lines to measure.
- * @param {Array.<number>} widths Array will be populated with the widths of
- * each line.
- * @return {number} Width of the whole text.
- */
- ol.render.canvas.TextReplay.measureTextWidths = function(font, lines, widths) {
- var numLines = lines.length;
- var width = 0;
- var currentWidth, i;
- for (i = 0; i < numLines; ++i) {
- currentWidth = ol.render.canvas.measureTextWidth(font, lines[i]);
- width = Math.max(width, currentWidth);
- widths.push(currentWidth);
- }
- return width;
- };
- /**
- * @inheritDoc
- */
- ol.render.canvas.TextReplay.prototype.drawText = function(geometry, feature) {
- var fillState = this.textFillState_;
- var strokeState = this.textStrokeState_;
- var textState = this.textState_;
- if (this.text_ === '' || !textState || (!fillState && !strokeState)) {
- return;
- }
- var begin = this.coordinates.length;
- var geometryType = geometry.getType();
- var flatCoordinates = null;
- var end = 2;
- var stride = 2;
- var i, ii;
- if (textState.placement === ol.style.TextPlacement.LINE) {
- if (!ol.extent.intersects(this.getBufferedMaxExtent(), geometry.getExtent())) {
- return;
- }
- var ends;
- flatCoordinates = geometry.getFlatCoordinates();
- stride = geometry.getStride();
- if (geometryType == ol.geom.GeometryType.LINE_STRING) {
- ends = [flatCoordinates.length];
- } else if (geometryType == ol.geom.GeometryType.MULTI_LINE_STRING) {
- ends = geometry.getEnds();
- } else if (geometryType == ol.geom.GeometryType.POLYGON) {
- ends = geometry.getEnds().slice(0, 1);
- } else if (geometryType == ol.geom.GeometryType.MULTI_POLYGON) {
- var endss = geometry.getEndss();
- ends = [];
- for (i = 0, ii = endss.length; i < ii; ++i) {
- ends.push(endss[i][0]);
- }
- }
- this.beginGeometry(geometry, feature);
- var textAlign = textState.textAlign;
- var flatOffset = 0;
- var flatEnd;
- for (var o = 0, oo = ends.length; o < oo; ++o) {
- if (textAlign == undefined) {
- var range = ol.geom.flat.straightchunk.lineString(
- textState.maxAngle, flatCoordinates, flatOffset, ends[o], stride);
- flatOffset = range[0];
- flatEnd = range[1];
- } else {
- flatEnd = ends[o];
- }
- for (i = flatOffset; i < flatEnd; i += stride) {
- this.coordinates.push(flatCoordinates[i], flatCoordinates[i + 1]);
- }
- end = this.coordinates.length;
- flatOffset = ends[o];
- this.drawChars_(begin, end, this.declutterGroup_);
- begin = end;
- }
- this.endGeometry(geometry, feature);
- } else {
- var label = this.getImage(this.text_, this.textKey_, this.fillKey_, this.strokeKey_);
- var width = label.width / this.pixelRatio;
- switch (geometryType) {
- case ol.geom.GeometryType.POINT:
- case ol.geom.GeometryType.MULTI_POINT:
- flatCoordinates = geometry.getFlatCoordinates();
- end = flatCoordinates.length;
- break;
- case ol.geom.GeometryType.LINE_STRING:
- flatCoordinates = /** @type {ol.geom.LineString} */ (geometry).getFlatMidpoint();
- break;
- case ol.geom.GeometryType.CIRCLE:
- flatCoordinates = /** @type {ol.geom.Circle} */ (geometry).getCenter();
- break;
- case ol.geom.GeometryType.MULTI_LINE_STRING:
- flatCoordinates = /** @type {ol.geom.MultiLineString} */ (geometry).getFlatMidpoints();
- end = flatCoordinates.length;
- break;
- case ol.geom.GeometryType.POLYGON:
- flatCoordinates = /** @type {ol.geom.Polygon} */ (geometry).getFlatInteriorPoint();
- if (!textState.overflow && flatCoordinates[2] / this.resolution < width) {
- return;
- }
- stride = 3;
- break;
- case ol.geom.GeometryType.MULTI_POLYGON:
- var interiorPoints = /** @type {ol.geom.MultiPolygon} */ (geometry).getFlatInteriorPoints();
- flatCoordinates = [];
- for (i = 0, ii = interiorPoints.length; i < ii; i += 3) {
- if (textState.overflow || interiorPoints[i + 2] / this.resolution >= width) {
- flatCoordinates.push(interiorPoints[i], interiorPoints[i + 1]);
- }
- }
- end = flatCoordinates.length;
- if (end == 0) {
- return;
- }
- break;
- default:
- }
- end = this.appendFlatCoordinates(flatCoordinates, 0, end, stride, false, false);
- this.beginGeometry(geometry, feature);
- if (textState.backgroundFill || textState.backgroundStroke) {
- this.setFillStrokeStyle(textState.backgroundFill, textState.backgroundStroke);
- this.updateFillStyle(this.state, this.applyFill, geometry);
- this.updateStrokeStyle(this.state, this.applyStroke);
- }
- this.drawTextImage_(label, begin, end);
- this.endGeometry(geometry, feature);
- }
- };
- /**
- * @param {string} text Text.
- * @param {string} textKey Text style key.
- * @param {string} fillKey Fill style key.
- * @param {string} strokeKey Stroke style key.
- * @return {HTMLCanvasElement} Image.
- */
- ol.render.canvas.TextReplay.prototype.getImage = function(text, textKey, fillKey, strokeKey) {
- var label;
- var key = strokeKey + textKey + text + fillKey + this.pixelRatio;
- var labelCache = ol.render.canvas.labelCache;
- if (!labelCache.containsKey(key)) {
- var strokeState = strokeKey ? this.strokeStates[strokeKey] || this.textStrokeState_ : null;
- var fillState = fillKey ? this.fillStates[fillKey] || this.textFillState_ : null;
- var textState = this.textStates[textKey] || this.textState_;
- var pixelRatio = this.pixelRatio;
- var scale = textState.scale * pixelRatio;
- var align = ol.render.replay.TEXT_ALIGN[textState.textAlign || ol.render.canvas.defaultTextAlign];
- var strokeWidth = strokeKey && strokeState.lineWidth ? strokeState.lineWidth : 0;
- var lines = text.split('\n');
- var numLines = lines.length;
- var widths = [];
- var width = ol.render.canvas.TextReplay.measureTextWidths(textState.font, lines, widths);
- var lineHeight = ol.render.canvas.measureTextHeight(textState.font);
- var height = lineHeight * numLines;
- var renderWidth = (width + strokeWidth);
- var context = ol.dom.createCanvasContext2D(
- Math.ceil(renderWidth * scale),
- Math.ceil((height + strokeWidth) * scale));
- label = context.canvas;
- labelCache.set(key, label);
- if (scale != 1) {
- context.scale(scale, scale);
- }
- context.font = textState.font;
- if (strokeKey) {
- context.strokeStyle = strokeState.strokeStyle;
- context.lineWidth = strokeWidth * (ol.has.SAFARI ? scale : 1);
- context.lineCap = strokeState.lineCap;
- context.lineJoin = strokeState.lineJoin;
- context.miterLimit = strokeState.miterLimit;
- if (ol.has.CANVAS_LINE_DASH && strokeState.lineDash.length) {
- context.setLineDash(strokeState.lineDash);
- context.lineDashOffset = strokeState.lineDashOffset;
- }
- }
- if (fillKey) {
- context.fillStyle = fillState.fillStyle;
- }
- context.textBaseline = 'middle';
- context.textAlign = 'center';
- var leftRight = (0.5 - align);
- var x = align * label.width / scale + leftRight * strokeWidth;
- var i;
- if (strokeKey) {
- for (i = 0; i < numLines; ++i) {
- context.strokeText(lines[i], x + leftRight * widths[i], 0.5 * (strokeWidth + lineHeight) + i * lineHeight);
- }
- }
- if (fillKey) {
- for (i = 0; i < numLines; ++i) {
- context.fillText(lines[i], x + leftRight * widths[i], 0.5 * (strokeWidth + lineHeight) + i * lineHeight);
- }
- }
- }
- return labelCache.get(key);
- };
- /**
- * @private
- * @param {HTMLCanvasElement} label Label.
- * @param {number} begin Begin.
- * @param {number} end End.
- */
- ol.render.canvas.TextReplay.prototype.drawTextImage_ = function(label, begin, end) {
- var textState = this.textState_;
- var strokeState = this.textStrokeState_;
- var pixelRatio = this.pixelRatio;
- var align = ol.render.replay.TEXT_ALIGN[textState.textAlign || ol.render.canvas.defaultTextAlign];
- var baseline = ol.render.replay.TEXT_ALIGN[textState.textBaseline];
- var strokeWidth = strokeState && strokeState.lineWidth ? strokeState.lineWidth : 0;
- var anchorX = align * label.width / pixelRatio + 2 * (0.5 - align) * strokeWidth;
- var anchorY = baseline * label.height / pixelRatio + 2 * (0.5 - baseline) * strokeWidth;
- this.instructions.push([ol.render.canvas.Instruction.DRAW_IMAGE, begin, end,
- label, (anchorX - this.textOffsetX_) * pixelRatio, (anchorY - this.textOffsetY_) * pixelRatio,
- this.declutterGroup_, label.height, 1, 0, 0, this.textRotateWithView_, this.textRotation_,
- 1, true, label.width,
- textState.padding == ol.render.canvas.defaultPadding ?
- ol.render.canvas.defaultPadding : textState.padding.map(function(p) {
- return p * pixelRatio;
- }),
- !!textState.backgroundFill, !!textState.backgroundStroke
- ]);
- this.hitDetectionInstructions.push([ol.render.canvas.Instruction.DRAW_IMAGE, begin, end,
- label, (anchorX - this.textOffsetX_) * pixelRatio, (anchorY - this.textOffsetY_) * pixelRatio,
- this.declutterGroup_, label.height, 1, 0, 0, this.textRotateWithView_, this.textRotation_,
- 1 / pixelRatio, true, label.width, textState.padding,
- !!textState.backgroundFill, !!textState.backgroundStroke
- ]);
- };
- /**
- * @private
- * @param {number} begin Begin.
- * @param {number} end End.
- * @param {ol.DeclutterGroup} declutterGroup Declutter group.
- */
- ol.render.canvas.TextReplay.prototype.drawChars_ = function(begin, end, declutterGroup) {
- var strokeState = this.textStrokeState_;
- var textState = this.textState_;
- var fillState = this.textFillState_;
- var strokeKey = this.strokeKey_;
- if (strokeState) {
- if (!(strokeKey in this.strokeStates)) {
- this.strokeStates[strokeKey] = /** @type {ol.CanvasStrokeState} */ ({
- strokeStyle: strokeState.strokeStyle,
- lineCap: strokeState.lineCap,
- lineDashOffset: strokeState.lineDashOffset,
- lineWidth: strokeState.lineWidth,
- lineJoin: strokeState.lineJoin,
- miterLimit: strokeState.miterLimit,
- lineDash: strokeState.lineDash
- });
- }
- }
- var textKey = this.textKey_;
- if (!(this.textKey_ in this.textStates)) {
- this.textStates[this.textKey_] = /** @type {ol.CanvasTextState} */ ({
- font: textState.font,
- textAlign: textState.textAlign || ol.render.canvas.defaultTextAlign,
- scale: textState.scale
- });
- }
- var fillKey = this.fillKey_;
- if (fillState) {
- if (!(fillKey in this.fillStates)) {
- this.fillStates[fillKey] = /** @type {ol.CanvasFillState} */ ({
- fillStyle: fillState.fillStyle
- });
- }
- }
- var pixelRatio = this.pixelRatio;
- var baseline = ol.render.replay.TEXT_ALIGN[textState.textBaseline];
- var offsetY = this.textOffsetY_ * pixelRatio;
- var text = this.text_;
- var font = textState.font;
- var textScale = textState.scale;
- var strokeWidth = strokeState ? strokeState.lineWidth * textScale / 2 : 0;
- var widths = this.widths_[font];
- if (!widths) {
- this.widths_[font] = widths = {};
- }
- this.instructions.push([ol.render.canvas.Instruction.DRAW_CHARS,
- begin, end, baseline, declutterGroup,
- textState.overflow, fillKey, textState.maxAngle,
- function(text) {
- var width = widths[text];
- if (!width) {
- width = widths[text] = ol.render.canvas.measureTextWidth(font, text);
- }
- return width * textScale * pixelRatio;
- },
- offsetY, strokeKey, strokeWidth * pixelRatio, text, textKey, 1
- ]);
- this.hitDetectionInstructions.push([ol.render.canvas.Instruction.DRAW_CHARS,
- begin, end, baseline, declutterGroup,
- textState.overflow, fillKey, textState.maxAngle,
- function(text) {
- var width = widths[text];
- if (!width) {
- width = widths[text] = ol.render.canvas.measureTextWidth(font, text);
- }
- return width * textScale;
- },
- offsetY, strokeKey, strokeWidth, text, textKey, 1 / pixelRatio
- ]);
- };
- /**
- * @inheritDoc
- */
- ol.render.canvas.TextReplay.prototype.setTextStyle = function(textStyle, declutterGroup) {
- var textState, fillState, strokeState;
- if (!textStyle) {
- this.text_ = '';
- } else {
- this.declutterGroup_ = /** @type {ol.DeclutterGroup} */ (declutterGroup);
- var textFillStyle = textStyle.getFill();
- if (!textFillStyle) {
- fillState = this.textFillState_ = null;
- } else {
- fillState = this.textFillState_;
- if (!fillState) {
- fillState = this.textFillState_ = /** @type {ol.CanvasFillState} */ ({});
- }
- fillState.fillStyle = ol.colorlike.asColorLike(
- textFillStyle.getColor() || ol.render.canvas.defaultFillStyle);
- }
- var textStrokeStyle = textStyle.getStroke();
- if (!textStrokeStyle) {
- strokeState = this.textStrokeState_ = null;
- } else {
- strokeState = this.textStrokeState_;
- if (!strokeState) {
- strokeState = this.textStrokeState_ = /** @type {ol.CanvasStrokeState} */ ({});
- }
- var lineDash = textStrokeStyle.getLineDash();
- var lineDashOffset = textStrokeStyle.getLineDashOffset();
- var lineWidth = textStrokeStyle.getWidth();
- var miterLimit = textStrokeStyle.getMiterLimit();
- strokeState.lineCap = textStrokeStyle.getLineCap() || ol.render.canvas.defaultLineCap;
- strokeState.lineDash = lineDash ? lineDash.slice() : ol.render.canvas.defaultLineDash;
- strokeState.lineDashOffset =
- lineDashOffset === undefined ? ol.render.canvas.defaultLineDashOffset : lineDashOffset;
- strokeState.lineJoin = textStrokeStyle.getLineJoin() || ol.render.canvas.defaultLineJoin;
- strokeState.lineWidth =
- lineWidth === undefined ? ol.render.canvas.defaultLineWidth : lineWidth;
- strokeState.miterLimit =
- miterLimit === undefined ? ol.render.canvas.defaultMiterLimit : miterLimit;
- strokeState.strokeStyle = ol.colorlike.asColorLike(
- textStrokeStyle.getColor() || ol.render.canvas.defaultStrokeStyle);
- }
- textState = this.textState_;
- var font = textStyle.getFont() || ol.render.canvas.defaultFont;
- ol.render.canvas.checkFont(font);
- var textScale = textStyle.getScale();
- textState.overflow = textStyle.getOverflow();
- textState.font = font;
- textState.maxAngle = textStyle.getMaxAngle();
- textState.placement = textStyle.getPlacement();
- textState.textAlign = textStyle.getTextAlign();
- textState.textBaseline = textStyle.getTextBaseline() || ol.render.canvas.defaultTextBaseline;
- textState.backgroundFill = textStyle.getBackgroundFill();
- textState.backgroundStroke = textStyle.getBackgroundStroke();
- textState.padding = textStyle.getPadding() || ol.render.canvas.defaultPadding;
- textState.scale = textScale === undefined ? 1 : textScale;
- var textOffsetX = textStyle.getOffsetX();
- var textOffsetY = textStyle.getOffsetY();
- var textRotateWithView = textStyle.getRotateWithView();
- var textRotation = textStyle.getRotation();
- this.text_ = textStyle.getText() || '';
- this.textOffsetX_ = textOffsetX === undefined ? 0 : textOffsetX;
- this.textOffsetY_ = textOffsetY === undefined ? 0 : textOffsetY;
- this.textRotateWithView_ = textRotateWithView === undefined ? false : textRotateWithView;
- this.textRotation_ = textRotation === undefined ? 0 : textRotation;
- this.strokeKey_ = strokeState ?
- (typeof strokeState.strokeStyle == 'string' ? strokeState.strokeStyle : ol.getUid(strokeState.strokeStyle)) +
- strokeState.lineCap + strokeState.lineDashOffset + '|' + strokeState.lineWidth +
- strokeState.lineJoin + strokeState.miterLimit + '[' + strokeState.lineDash.join() + ']' :
- '';
- this.textKey_ = textState.font + textState.scale + (textState.textAlign || '?');
- this.fillKey_ = fillState ?
- (typeof fillState.fillStyle == 'string' ? fillState.fillStyle : ('|' + ol.getUid(fillState.fillStyle))) :
- '';
- }
- };
- goog.provide('ol.render.canvas.ReplayGroup');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.dom');
- goog.require('ol.extent');
- goog.require('ol.geom.flat.transform');
- goog.require('ol.obj');
- goog.require('ol.render.ReplayGroup');
- goog.require('ol.render.ReplayType');
- goog.require('ol.render.canvas.Replay');
- goog.require('ol.render.canvas.ImageReplay');
- goog.require('ol.render.canvas.LineStringReplay');
- goog.require('ol.render.canvas.PolygonReplay');
- goog.require('ol.render.canvas.TextReplay');
- goog.require('ol.render.replay');
- goog.require('ol.transform');
- /**
- * @constructor
- * @extends {ol.render.ReplayGroup}
- * @param {number} tolerance Tolerance.
- * @param {ol.Extent} maxExtent Max extent.
- * @param {number} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @param {boolean} overlaps The replay group can have overlapping geometries.
- * @param {?} declutterTree Declutter tree
- * for declutter processing in postrender.
- * @param {number=} opt_renderBuffer Optional rendering buffer.
- * @struct
- */
- ol.render.canvas.ReplayGroup = function(
- tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree, opt_renderBuffer) {
- ol.render.ReplayGroup.call(this);
- /**
- * Declutter tree.
- * @private
- */
- this.declutterTree_ = declutterTree;
- /**
- * @type {ol.DeclutterGroup}
- * @private
- */
- this.declutterGroup_ = null;
- /**
- * @private
- * @type {number}
- */
- this.tolerance_ = tolerance;
- /**
- * @private
- * @type {ol.Extent}
- */
- this.maxExtent_ = maxExtent;
- /**
- * @private
- * @type {boolean}
- */
- this.overlaps_ = overlaps;
- /**
- * @private
- * @type {number}
- */
- this.pixelRatio_ = pixelRatio;
- /**
- * @private
- * @type {number}
- */
- this.resolution_ = resolution;
- /**
- * @private
- * @type {number|undefined}
- */
- this.renderBuffer_ = opt_renderBuffer;
- /**
- * @private
- * @type {!Object.<string,
- * Object.<ol.render.ReplayType, ol.render.canvas.Replay>>}
- */
- this.replaysByZIndex_ = {};
- /**
- * @private
- * @type {CanvasRenderingContext2D}
- */
- this.hitDetectionContext_ = ol.dom.createCanvasContext2D(1, 1);
- /**
- * @private
- * @type {ol.Transform}
- */
- this.hitDetectionTransform_ = ol.transform.create();
- };
- ol.inherits(ol.render.canvas.ReplayGroup, ol.render.ReplayGroup);
- /**
- * This cache is used for storing calculated pixel circles for increasing performance.
- * It is a static property to allow each Replaygroup to access it.
- * @type {Object.<number, Array.<Array.<(boolean|undefined)>>>}
- * @private
- */
- ol.render.canvas.ReplayGroup.circleArrayCache_ = {
- 0: [[true]]
- };
- /**
- * This method fills a row in the array from the given coordinate to the
- * middle with `true`.
- * @param {Array.<Array.<(boolean|undefined)>>} array The array that will be altered.
- * @param {number} x X coordinate.
- * @param {number} y Y coordinate.
- * @private
- */
- ol.render.canvas.ReplayGroup.fillCircleArrayRowToMiddle_ = function(array, x, y) {
- var i;
- var radius = Math.floor(array.length / 2);
- if (x >= radius) {
- for (i = radius; i < x; i++) {
- array[i][y] = true;
- }
- } else if (x < radius) {
- for (i = x + 1; i < radius; i++) {
- array[i][y] = true;
- }
- }
- };
- /**
- * This methods creates a circle inside a fitting array. Points inside the
- * circle are marked by true, points on the outside are undefined.
- * It uses the midpoint circle algorithm.
- * A cache is used to increase performance.
- * @param {number} radius Radius.
- * @returns {Array.<Array.<(boolean|undefined)>>} An array with marked circle points.
- * @private
- */
- ol.render.canvas.ReplayGroup.getCircleArray_ = function(radius) {
- if (ol.render.canvas.ReplayGroup.circleArrayCache_[radius] !== undefined) {
- return ol.render.canvas.ReplayGroup.circleArrayCache_[radius];
- }
- var arraySize = radius * 2 + 1;
- var arr = new Array(arraySize);
- for (var i = 0; i < arraySize; i++) {
- arr[i] = new Array(arraySize);
- }
- var x = radius;
- var y = 0;
- var error = 0;
- while (x >= y) {
- ol.render.canvas.ReplayGroup.fillCircleArrayRowToMiddle_(arr, radius + x, radius + y);
- ol.render.canvas.ReplayGroup.fillCircleArrayRowToMiddle_(arr, radius + y, radius + x);
- ol.render.canvas.ReplayGroup.fillCircleArrayRowToMiddle_(arr, radius - y, radius + x);
- ol.render.canvas.ReplayGroup.fillCircleArrayRowToMiddle_(arr, radius - x, radius + y);
- ol.render.canvas.ReplayGroup.fillCircleArrayRowToMiddle_(arr, radius - x, radius - y);
- ol.render.canvas.ReplayGroup.fillCircleArrayRowToMiddle_(arr, radius - y, radius - x);
- ol.render.canvas.ReplayGroup.fillCircleArrayRowToMiddle_(arr, radius + y, radius - x);
- ol.render.canvas.ReplayGroup.fillCircleArrayRowToMiddle_(arr, radius + x, radius - y);
- y++;
- error += 1 + 2 * y;
- if (2 * (error - x) + 1 > 0) {
- x -= 1;
- error += 1 - 2 * x;
- }
- }
- ol.render.canvas.ReplayGroup.circleArrayCache_[radius] = arr;
- return arr;
- };
- /**
- * @param {!Object.<string, Array.<*>>} declutterReplays Declutter replays.
- * @param {CanvasRenderingContext2D} context Context.
- * @param {number} rotation Rotation.
- */
- ol.render.canvas.ReplayGroup.replayDeclutter = function(declutterReplays, context, rotation) {
- var zs = Object.keys(declutterReplays).map(Number).sort(ol.array.numberSafeCompareFunction);
- var skippedFeatureUids = {};
- for (var z = 0, zz = zs.length; z < zz; ++z) {
- var replayData = declutterReplays[zs[z].toString()];
- for (var i = 0, ii = replayData.length; i < ii;) {
- var replay = replayData[i++];
- var transform = replayData[i++];
- replay.replay(context, transform, rotation, skippedFeatureUids);
- }
- }
- };
- /**
- * @param {boolean} group Group with previous replay.
- * @return {ol.DeclutterGroup} Declutter instruction group.
- */
- ol.render.canvas.ReplayGroup.prototype.addDeclutter = function(group) {
- var declutter = null;
- if (this.declutterTree_) {
- if (group) {
- declutter = this.declutterGroup_;
- /** @type {number} */ (declutter[4])++;
- } else {
- declutter = this.declutterGroup_ = ol.extent.createEmpty();
- declutter.push(1);
- }
- }
- return declutter;
- };
- /**
- * @param {CanvasRenderingContext2D} context Context.
- * @param {ol.Transform} transform Transform.
- */
- ol.render.canvas.ReplayGroup.prototype.clip = function(context, transform) {
- var flatClipCoords = this.getClipCoords(transform);
- context.beginPath();
- context.moveTo(flatClipCoords[0], flatClipCoords[1]);
- context.lineTo(flatClipCoords[2], flatClipCoords[3]);
- context.lineTo(flatClipCoords[4], flatClipCoords[5]);
- context.lineTo(flatClipCoords[6], flatClipCoords[7]);
- context.clip();
- };
- /**
- * @param {Array.<ol.render.ReplayType>} replays Replays.
- * @return {boolean} Has replays of the provided types.
- */
- ol.render.canvas.ReplayGroup.prototype.hasReplays = function(replays) {
- for (var zIndex in this.replaysByZIndex_) {
- var candidates = this.replaysByZIndex_[zIndex];
- for (var i = 0, ii = replays.length; i < ii; ++i) {
- if (replays[i] in candidates) {
- return true;
- }
- }
- }
- return false;
- };
- /**
- * FIXME empty description for jsdoc
- */
- ol.render.canvas.ReplayGroup.prototype.finish = function() {
- var zKey;
- for (zKey in this.replaysByZIndex_) {
- var replays = this.replaysByZIndex_[zKey];
- var replayKey;
- for (replayKey in replays) {
- replays[replayKey].finish();
- }
- }
- };
- /**
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {number} resolution Resolution.
- * @param {number} rotation Rotation.
- * @param {number} hitTolerance Hit tolerance in pixels.
- * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
- * to skip.
- * @param {function((ol.Feature|ol.render.Feature)): T} callback Feature
- * callback.
- * @param {Object.<string, ol.DeclutterGroup>} declutterReplays Declutter
- * replays.
- * @return {T|undefined} Callback result.
- * @template T
- */
- ol.render.canvas.ReplayGroup.prototype.forEachFeatureAtCoordinate = function(
- coordinate, resolution, rotation, hitTolerance, skippedFeaturesHash, callback, declutterReplays) {
- hitTolerance = Math.round(hitTolerance);
- var contextSize = hitTolerance * 2 + 1;
- var transform = ol.transform.compose(this.hitDetectionTransform_,
- hitTolerance + 0.5, hitTolerance + 0.5,
- 1 / resolution, -1 / resolution,
- -rotation,
- -coordinate[0], -coordinate[1]);
- var context = this.hitDetectionContext_;
- if (context.canvas.width !== contextSize || context.canvas.height !== contextSize) {
- context.canvas.width = contextSize;
- context.canvas.height = contextSize;
- } else {
- context.clearRect(0, 0, contextSize, contextSize);
- }
- /**
- * @type {ol.Extent}
- */
- var hitExtent;
- if (this.renderBuffer_ !== undefined) {
- hitExtent = ol.extent.createEmpty();
- ol.extent.extendCoordinate(hitExtent, coordinate);
- ol.extent.buffer(hitExtent, resolution * (this.renderBuffer_ + hitTolerance), hitExtent);
- }
- var mask = ol.render.canvas.ReplayGroup.getCircleArray_(hitTolerance);
- var declutteredFeatures;
- if (this.declutterTree_) {
- declutteredFeatures = this.declutterTree_.all().map(function(entry) {
- return entry.value;
- });
- }
- var replayType;
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @return {?} Callback result.
- */
- function featureCallback(feature) {
- var imageData = context.getImageData(0, 0, contextSize, contextSize).data;
- for (var i = 0; i < contextSize; i++) {
- for (var j = 0; j < contextSize; j++) {
- if (mask[i][j]) {
- if (imageData[(j * contextSize + i) * 4 + 3] > 0) {
- var result;
- if (!(declutteredFeatures && (replayType == ol.render.ReplayType.IMAGE || replayType == ol.render.ReplayType.TEXT)) ||
- declutteredFeatures.indexOf(feature) !== -1) {
- result = callback(feature);
- }
- if (result) {
- return result;
- } else {
- context.clearRect(0, 0, contextSize, contextSize);
- return undefined;
- }
- }
- }
- }
- }
- }
- /** @type {Array.<number>} */
- var zs = Object.keys(this.replaysByZIndex_).map(Number);
- zs.sort(ol.array.numberSafeCompareFunction);
- var i, j, replays, replay, result;
- for (i = zs.length - 1; i >= 0; --i) {
- var zIndexKey = zs[i].toString();
- replays = this.replaysByZIndex_[zIndexKey];
- for (j = ol.render.replay.ORDER.length - 1; j >= 0; --j) {
- replayType = ol.render.replay.ORDER[j];
- replay = replays[replayType];
- if (replay !== undefined) {
- if (declutterReplays &&
- (replayType == ol.render.ReplayType.IMAGE || replayType == ol.render.ReplayType.TEXT)) {
- var declutter = declutterReplays[zIndexKey];
- if (!declutter) {
- declutterReplays[zIndexKey] = [replay, transform.slice(0)];
- } else {
- declutter.push(replay, transform.slice(0));
- }
- } else {
- result = replay.replayHitDetection(context, transform, rotation,
- skippedFeaturesHash, featureCallback, hitExtent);
- if (result) {
- return result;
- }
- }
- }
- }
- }
- return undefined;
- };
- /**
- * @param {ol.Transform} transform Transform.
- * @return {Array.<number>} Clip coordinates.
- */
- ol.render.canvas.ReplayGroup.prototype.getClipCoords = function(transform) {
- var maxExtent = this.maxExtent_;
- var minX = maxExtent[0];
- var minY = maxExtent[1];
- var maxX = maxExtent[2];
- var maxY = maxExtent[3];
- var flatClipCoords = [minX, minY, minX, maxY, maxX, maxY, maxX, minY];
- ol.geom.flat.transform.transform2D(
- flatClipCoords, 0, 8, 2, transform, flatClipCoords);
- return flatClipCoords;
- };
- /**
- * @inheritDoc
- */
- ol.render.canvas.ReplayGroup.prototype.getReplay = function(zIndex, replayType) {
- var zIndexKey = zIndex !== undefined ? zIndex.toString() : '0';
- var replays = this.replaysByZIndex_[zIndexKey];
- if (replays === undefined) {
- replays = {};
- this.replaysByZIndex_[zIndexKey] = replays;
- }
- var replay = replays[replayType];
- if (replay === undefined) {
- var Constructor = ol.render.canvas.ReplayGroup.BATCH_CONSTRUCTORS_[replayType];
- replay = new Constructor(this.tolerance_, this.maxExtent_,
- this.resolution_, this.pixelRatio_, this.overlaps_, this.declutterTree_);
- replays[replayType] = replay;
- }
- return replay;
- };
- /**
- * @return {Object.<string, Object.<ol.render.ReplayType, ol.render.canvas.Replay>>} Replays.
- */
- ol.render.canvas.ReplayGroup.prototype.getReplays = function() {
- return this.replaysByZIndex_;
- };
- /**
- * @inheritDoc
- */
- ol.render.canvas.ReplayGroup.prototype.isEmpty = function() {
- return ol.obj.isEmpty(this.replaysByZIndex_);
- };
- /**
- * @param {CanvasRenderingContext2D} context Context.
- * @param {ol.Transform} transform Transform.
- * @param {number} viewRotation View rotation.
- * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
- * to skip.
- * @param {Array.<ol.render.ReplayType>=} opt_replayTypes Ordered replay types
- * to replay. Default is {@link ol.render.replay.ORDER}
- * @param {Object.<string, ol.DeclutterGroup>=} opt_declutterReplays Declutter
- * replays.
- */
- ol.render.canvas.ReplayGroup.prototype.replay = function(context,
- transform, viewRotation, skippedFeaturesHash, opt_replayTypes, opt_declutterReplays) {
- /** @type {Array.<number>} */
- var zs = Object.keys(this.replaysByZIndex_).map(Number);
- zs.sort(ol.array.numberSafeCompareFunction);
- // setup clipping so that the parts of over-simplified geometries are not
- // visible outside the current extent when panning
- context.save();
- this.clip(context, transform);
- var replayTypes = opt_replayTypes ? opt_replayTypes : ol.render.replay.ORDER;
- var i, ii, j, jj, replays, replay;
- for (i = 0, ii = zs.length; i < ii; ++i) {
- var zIndexKey = zs[i].toString();
- replays = this.replaysByZIndex_[zIndexKey];
- for (j = 0, jj = replayTypes.length; j < jj; ++j) {
- var replayType = replayTypes[j];
- replay = replays[replayType];
- if (replay !== undefined) {
- if (opt_declutterReplays &&
- (replayType == ol.render.ReplayType.IMAGE || replayType == ol.render.ReplayType.TEXT)) {
- var declutter = opt_declutterReplays[zIndexKey];
- if (!declutter) {
- opt_declutterReplays[zIndexKey] = [replay, transform.slice(0)];
- } else {
- declutter.push(replay, transform.slice(0));
- }
- } else {
- replay.replay(context, transform, viewRotation, skippedFeaturesHash);
- }
- }
- }
- }
- context.restore();
- };
- /**
- * @const
- * @private
- * @type {Object.<ol.render.ReplayType,
- * function(new: ol.render.canvas.Replay, number, ol.Extent,
- * number, number, boolean, Array.<ol.DeclutterGroup>)>}
- */
- ol.render.canvas.ReplayGroup.BATCH_CONSTRUCTORS_ = {
- 'Circle': ol.render.canvas.PolygonReplay,
- 'Default': ol.render.canvas.Replay,
- 'Image': ol.render.canvas.ImageReplay,
- 'LineString': ol.render.canvas.LineStringReplay,
- 'Polygon': ol.render.canvas.PolygonReplay,
- 'Text': ol.render.canvas.TextReplay
- };
- goog.provide('ol.renderer.vector');
- goog.require('ol');
- goog.require('ol.ImageState');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.render.ReplayType');
- /**
- * @param {ol.Feature|ol.render.Feature} feature1 Feature 1.
- * @param {ol.Feature|ol.render.Feature} feature2 Feature 2.
- * @return {number} Order.
- */
- ol.renderer.vector.defaultOrder = function(feature1, feature2) {
- return ol.getUid(feature1) - ol.getUid(feature2);
- };
- /**
- * @param {number} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @return {number} Squared pixel tolerance.
- */
- ol.renderer.vector.getSquaredTolerance = function(resolution, pixelRatio) {
- var tolerance = ol.renderer.vector.getTolerance(resolution, pixelRatio);
- return tolerance * tolerance;
- };
- /**
- * @param {number} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @return {number} Pixel tolerance.
- */
- ol.renderer.vector.getTolerance = function(resolution, pixelRatio) {
- return ol.SIMPLIFY_TOLERANCE * resolution / pixelRatio;
- };
- /**
- * @param {ol.render.ReplayGroup} replayGroup Replay group.
- * @param {ol.geom.Circle} geometry Geometry.
- * @param {ol.style.Style} style Style.
- * @param {ol.Feature} feature Feature.
- * @private
- */
- ol.renderer.vector.renderCircleGeometry_ = function(replayGroup, geometry, style, feature) {
- var fillStyle = style.getFill();
- var strokeStyle = style.getStroke();
- if (fillStyle || strokeStyle) {
- var circleReplay = replayGroup.getReplay(
- style.getZIndex(), ol.render.ReplayType.CIRCLE);
- circleReplay.setFillStrokeStyle(fillStyle, strokeStyle);
- circleReplay.drawCircle(geometry, feature);
- }
- var textStyle = style.getText();
- if (textStyle) {
- var textReplay = replayGroup.getReplay(
- style.getZIndex(), ol.render.ReplayType.TEXT);
- textReplay.setTextStyle(textStyle, replayGroup.addDeclutter(false));
- textReplay.drawText(geometry, feature);
- }
- };
- /**
- * @param {ol.render.ReplayGroup} replayGroup Replay group.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @param {ol.style.Style} style Style.
- * @param {number} squaredTolerance Squared tolerance.
- * @param {function(this: T, ol.events.Event)} listener Listener function.
- * @param {T} thisArg Value to use as `this` when executing `listener`.
- * @return {boolean} `true` if style is loading.
- * @template T
- */
- ol.renderer.vector.renderFeature = function(
- replayGroup, feature, style, squaredTolerance, listener, thisArg) {
- var loading = false;
- var imageStyle, imageState;
- imageStyle = style.getImage();
- if (imageStyle) {
- imageState = imageStyle.getImageState();
- if (imageState == ol.ImageState.LOADED ||
- imageState == ol.ImageState.ERROR) {
- imageStyle.unlistenImageChange(listener, thisArg);
- } else {
- if (imageState == ol.ImageState.IDLE) {
- imageStyle.load();
- }
- imageState = imageStyle.getImageState();
- imageStyle.listenImageChange(listener, thisArg);
- loading = true;
- }
- }
- ol.renderer.vector.renderFeature_(replayGroup, feature, style,
- squaredTolerance);
- return loading;
- };
- /**
- * @param {ol.render.ReplayGroup} replayGroup Replay group.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @param {ol.style.Style} style Style.
- * @param {number} squaredTolerance Squared tolerance.
- * @private
- */
- ol.renderer.vector.renderFeature_ = function(
- replayGroup, feature, style, squaredTolerance) {
- var geometry = style.getGeometryFunction()(feature);
- if (!geometry) {
- return;
- }
- var simplifiedGeometry = geometry.getSimplifiedGeometry(squaredTolerance);
- var renderer = style.getRenderer();
- if (renderer) {
- ol.renderer.vector.renderGeometry_(replayGroup, simplifiedGeometry, style, feature);
- } else {
- var geometryRenderer =
- ol.renderer.vector.GEOMETRY_RENDERERS_[simplifiedGeometry.getType()];
- geometryRenderer(replayGroup, simplifiedGeometry, style, feature);
- }
- };
- /**
- * @param {ol.render.ReplayGroup} replayGroup Replay group.
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {ol.style.Style} style Style.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @private
- */
- ol.renderer.vector.renderGeometry_ = function(replayGroup, geometry, style, feature) {
- if (geometry.getType() == ol.geom.GeometryType.GEOMETRY_COLLECTION) {
- var geometries = /** @type {ol.geom.GeometryCollection} */ (geometry).getGeometries();
- for (var i = 0, ii = geometries.length; i < ii; ++i) {
- ol.renderer.vector.renderGeometry_(replayGroup, geometries[i], style, feature);
- }
- return;
- }
- var replay = replayGroup.getReplay(style.getZIndex(), ol.render.ReplayType.DEFAULT);
- replay.drawCustom(/** @type {ol.geom.SimpleGeometry} */ (geometry), feature, style.getRenderer());
- };
- /**
- * @param {ol.render.ReplayGroup} replayGroup Replay group.
- * @param {ol.geom.GeometryCollection} geometry Geometry.
- * @param {ol.style.Style} style Style.
- * @param {ol.Feature} feature Feature.
- * @private
- */
- ol.renderer.vector.renderGeometryCollectionGeometry_ = function(replayGroup, geometry, style, feature) {
- var geometries = geometry.getGeometriesArray();
- var i, ii;
- for (i = 0, ii = geometries.length; i < ii; ++i) {
- var geometryRenderer =
- ol.renderer.vector.GEOMETRY_RENDERERS_[geometries[i].getType()];
- geometryRenderer(replayGroup, geometries[i], style, feature);
- }
- };
- /**
- * @param {ol.render.ReplayGroup} replayGroup Replay group.
- * @param {ol.geom.LineString|ol.render.Feature} geometry Geometry.
- * @param {ol.style.Style} style Style.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @private
- */
- ol.renderer.vector.renderLineStringGeometry_ = function(replayGroup, geometry, style, feature) {
- var strokeStyle = style.getStroke();
- if (strokeStyle) {
- var lineStringReplay = replayGroup.getReplay(
- style.getZIndex(), ol.render.ReplayType.LINE_STRING);
- lineStringReplay.setFillStrokeStyle(null, strokeStyle);
- lineStringReplay.drawLineString(geometry, feature);
- }
- var textStyle = style.getText();
- if (textStyle) {
- var textReplay = replayGroup.getReplay(
- style.getZIndex(), ol.render.ReplayType.TEXT);
- textReplay.setTextStyle(textStyle, replayGroup.addDeclutter(false));
- textReplay.drawText(geometry, feature);
- }
- };
- /**
- * @param {ol.render.ReplayGroup} replayGroup Replay group.
- * @param {ol.geom.MultiLineString|ol.render.Feature} geometry Geometry.
- * @param {ol.style.Style} style Style.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @private
- */
- ol.renderer.vector.renderMultiLineStringGeometry_ = function(replayGroup, geometry, style, feature) {
- var strokeStyle = style.getStroke();
- if (strokeStyle) {
- var lineStringReplay = replayGroup.getReplay(
- style.getZIndex(), ol.render.ReplayType.LINE_STRING);
- lineStringReplay.setFillStrokeStyle(null, strokeStyle);
- lineStringReplay.drawMultiLineString(geometry, feature);
- }
- var textStyle = style.getText();
- if (textStyle) {
- var textReplay = replayGroup.getReplay(
- style.getZIndex(), ol.render.ReplayType.TEXT);
- textReplay.setTextStyle(textStyle, replayGroup.addDeclutter(false));
- textReplay.drawText(geometry, feature);
- }
- };
- /**
- * @param {ol.render.ReplayGroup} replayGroup Replay group.
- * @param {ol.geom.MultiPolygon} geometry Geometry.
- * @param {ol.style.Style} style Style.
- * @param {ol.Feature} feature Feature.
- * @private
- */
- ol.renderer.vector.renderMultiPolygonGeometry_ = function(replayGroup, geometry, style, feature) {
- var fillStyle = style.getFill();
- var strokeStyle = style.getStroke();
- if (strokeStyle || fillStyle) {
- var polygonReplay = replayGroup.getReplay(
- style.getZIndex(), ol.render.ReplayType.POLYGON);
- polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle);
- polygonReplay.drawMultiPolygon(geometry, feature);
- }
- var textStyle = style.getText();
- if (textStyle) {
- var textReplay = replayGroup.getReplay(
- style.getZIndex(), ol.render.ReplayType.TEXT);
- textReplay.setTextStyle(textStyle, replayGroup.addDeclutter(false));
- textReplay.drawText(geometry, feature);
- }
- };
- /**
- * @param {ol.render.ReplayGroup} replayGroup Replay group.
- * @param {ol.geom.Point|ol.render.Feature} geometry Geometry.
- * @param {ol.style.Style} style Style.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @private
- */
- ol.renderer.vector.renderPointGeometry_ = function(replayGroup, geometry, style, feature) {
- var imageStyle = style.getImage();
- if (imageStyle) {
- if (imageStyle.getImageState() != ol.ImageState.LOADED) {
- return;
- }
- var imageReplay = replayGroup.getReplay(
- style.getZIndex(), ol.render.ReplayType.IMAGE);
- imageReplay.setImageStyle(imageStyle, replayGroup.addDeclutter(false));
- imageReplay.drawPoint(geometry, feature);
- }
- var textStyle = style.getText();
- if (textStyle) {
- var textReplay = replayGroup.getReplay(
- style.getZIndex(), ol.render.ReplayType.TEXT);
- textReplay.setTextStyle(textStyle, replayGroup.addDeclutter(!!imageStyle));
- textReplay.drawText(geometry, feature);
- }
- };
- /**
- * @param {ol.render.ReplayGroup} replayGroup Replay group.
- * @param {ol.geom.MultiPoint|ol.render.Feature} geometry Geometry.
- * @param {ol.style.Style} style Style.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @private
- */
- ol.renderer.vector.renderMultiPointGeometry_ = function(replayGroup, geometry, style, feature) {
- var imageStyle = style.getImage();
- if (imageStyle) {
- if (imageStyle.getImageState() != ol.ImageState.LOADED) {
- return;
- }
- var imageReplay = replayGroup.getReplay(
- style.getZIndex(), ol.render.ReplayType.IMAGE);
- imageReplay.setImageStyle(imageStyle, replayGroup.addDeclutter(false));
- imageReplay.drawMultiPoint(geometry, feature);
- }
- var textStyle = style.getText();
- if (textStyle) {
- var textReplay = replayGroup.getReplay(
- style.getZIndex(), ol.render.ReplayType.TEXT);
- textReplay.setTextStyle(textStyle, replayGroup.addDeclutter(!!imageStyle));
- textReplay.drawText(geometry, feature);
- }
- };
- /**
- * @param {ol.render.ReplayGroup} replayGroup Replay group.
- * @param {ol.geom.Polygon|ol.render.Feature} geometry Geometry.
- * @param {ol.style.Style} style Style.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @private
- */
- ol.renderer.vector.renderPolygonGeometry_ = function(replayGroup, geometry, style, feature) {
- var fillStyle = style.getFill();
- var strokeStyle = style.getStroke();
- if (fillStyle || strokeStyle) {
- var polygonReplay = replayGroup.getReplay(
- style.getZIndex(), ol.render.ReplayType.POLYGON);
- polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle);
- polygonReplay.drawPolygon(geometry, feature);
- }
- var textStyle = style.getText();
- if (textStyle) {
- var textReplay = replayGroup.getReplay(
- style.getZIndex(), ol.render.ReplayType.TEXT);
- textReplay.setTextStyle(textStyle, replayGroup.addDeclutter(false));
- textReplay.drawText(geometry, feature);
- }
- };
- /**
- * @const
- * @private
- * @type {Object.<ol.geom.GeometryType,
- * function(ol.render.ReplayGroup, ol.geom.Geometry,
- * ol.style.Style, Object)>}
- */
- ol.renderer.vector.GEOMETRY_RENDERERS_ = {
- 'Point': ol.renderer.vector.renderPointGeometry_,
- 'LineString': ol.renderer.vector.renderLineStringGeometry_,
- 'Polygon': ol.renderer.vector.renderPolygonGeometry_,
- 'MultiPoint': ol.renderer.vector.renderMultiPointGeometry_,
- 'MultiLineString': ol.renderer.vector.renderMultiLineStringGeometry_,
- 'MultiPolygon': ol.renderer.vector.renderMultiPolygonGeometry_,
- 'GeometryCollection': ol.renderer.vector.renderGeometryCollectionGeometry_,
- 'Circle': ol.renderer.vector.renderCircleGeometry_
- };
- goog.provide('ol.renderer.canvas.VectorLayer');
- goog.require('ol');
- goog.require('ol.LayerType');
- goog.require('ol.ViewHint');
- goog.require('ol.dom');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.ext.rbush');
- goog.require('ol.extent');
- goog.require('ol.render.EventType');
- goog.require('ol.render.canvas');
- goog.require('ol.render.canvas.ReplayGroup');
- goog.require('ol.renderer.Type');
- goog.require('ol.renderer.canvas.Layer');
- goog.require('ol.renderer.vector');
- /**
- * @constructor
- * @extends {ol.renderer.canvas.Layer}
- * @param {ol.layer.Vector} vectorLayer Vector layer.
- * @api
- */
- ol.renderer.canvas.VectorLayer = function(vectorLayer) {
- ol.renderer.canvas.Layer.call(this, vectorLayer);
- /**
- * Declutter tree.
- * @private
- */
- this.declutterTree_ = vectorLayer.getDeclutter() ?
- ol.ext.rbush(9) : null;
- /**
- * @private
- * @type {boolean}
- */
- this.dirty_ = false;
- /**
- * @private
- * @type {number}
- */
- this.renderedRevision_ = -1;
- /**
- * @private
- * @type {number}
- */
- this.renderedResolution_ = NaN;
- /**
- * @private
- * @type {ol.Extent}
- */
- this.renderedExtent_ = ol.extent.createEmpty();
- /**
- * @private
- * @type {function(ol.Feature, ol.Feature): number|null}
- */
- this.renderedRenderOrder_ = null;
- /**
- * @private
- * @type {ol.render.canvas.ReplayGroup}
- */
- this.replayGroup_ = null;
- /**
- * A new replay group had to be created by `prepareFrame()`
- * @type {boolean}
- */
- this.replayGroupChanged = true;
- /**
- * @type {CanvasRenderingContext2D}
- */
- this.context = ol.dom.createCanvasContext2D();
- ol.events.listen(ol.render.canvas.labelCache, ol.events.EventType.CLEAR, this.handleFontsChanged_, this);
- };
- ol.inherits(ol.renderer.canvas.VectorLayer, ol.renderer.canvas.Layer);
- /**
- * Determine if this renderer handles the provided layer.
- * @param {ol.renderer.Type} type The renderer type.
- * @param {ol.layer.Layer} layer The candidate layer.
- * @return {boolean} The renderer can render the layer.
- */
- ol.renderer.canvas.VectorLayer['handles'] = function(type, layer) {
- return type === ol.renderer.Type.CANVAS && layer.getType() === ol.LayerType.VECTOR;
- };
- /**
- * Create a layer renderer.
- * @param {ol.renderer.Map} mapRenderer The map renderer.
- * @param {ol.layer.Layer} layer The layer to be rendererd.
- * @return {ol.renderer.canvas.VectorLayer} The layer renderer.
- */
- ol.renderer.canvas.VectorLayer['create'] = function(mapRenderer, layer) {
- return new ol.renderer.canvas.VectorLayer(/** @type {ol.layer.Vector} */ (layer));
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.VectorLayer.prototype.disposeInternal = function() {
- ol.events.unlisten(ol.render.canvas.labelCache, ol.events.EventType.CLEAR, this.handleFontsChanged_, this);
- ol.renderer.canvas.Layer.prototype.disposeInternal.call(this);
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, layerState, context) {
- var extent = frameState.extent;
- var pixelRatio = frameState.pixelRatio;
- var skippedFeatureUids = layerState.managed ?
- frameState.skippedFeatureUids : {};
- var viewState = frameState.viewState;
- var projection = viewState.projection;
- var rotation = viewState.rotation;
- var projectionExtent = projection.getExtent();
- var vectorSource = /** @type {ol.source.Vector} */ (this.getLayer().getSource());
- var transform = this.getTransform(frameState, 0);
- this.preCompose(context, frameState, transform);
- // clipped rendering if layer extent is set
- var clipExtent = layerState.extent;
- var clipped = clipExtent !== undefined;
- if (clipped) {
- this.clip(context, frameState, /** @type {ol.Extent} */ (clipExtent));
- }
- var replayGroup = this.replayGroup_;
- if (replayGroup && !replayGroup.isEmpty()) {
- if (this.declutterTree_) {
- this.declutterTree_.clear();
- }
- var layer = /** @type {ol.layer.Vector} */ (this.getLayer());
- var drawOffsetX = 0;
- var drawOffsetY = 0;
- var replayContext;
- var transparentLayer = layerState.opacity !== 1;
- var hasRenderListeners = layer.hasListener(ol.render.EventType.RENDER);
- if (transparentLayer || hasRenderListeners) {
- var drawWidth = context.canvas.width;
- var drawHeight = context.canvas.height;
- if (rotation) {
- var drawSize = Math.round(Math.sqrt(drawWidth * drawWidth + drawHeight * drawHeight));
- drawOffsetX = (drawSize - drawWidth) / 2;
- drawOffsetY = (drawSize - drawHeight) / 2;
- drawWidth = drawHeight = drawSize;
- }
- // resize and clear
- this.context.canvas.width = drawWidth;
- this.context.canvas.height = drawHeight;
- replayContext = this.context;
- } else {
- replayContext = context;
- }
- var alpha = replayContext.globalAlpha;
- if (!transparentLayer) {
- // for performance reasons, context.save / context.restore is not used
- // to save and restore the transformation matrix and the opacity.
- // see http://jsperf.com/context-save-restore-versus-variable
- replayContext.globalAlpha = layerState.opacity;
- }
- if (replayContext != context) {
- replayContext.translate(drawOffsetX, drawOffsetY);
- }
- var width = frameState.size[0] * pixelRatio;
- var height = frameState.size[1] * pixelRatio;
- ol.render.canvas.rotateAtOffset(replayContext, -rotation,
- width / 2, height / 2);
- replayGroup.replay(replayContext, transform, rotation, skippedFeatureUids);
- if (vectorSource.getWrapX() && projection.canWrapX() &&
- !ol.extent.containsExtent(projectionExtent, extent)) {
- var startX = extent[0];
- var worldWidth = ol.extent.getWidth(projectionExtent);
- var world = 0;
- var offsetX;
- while (startX < projectionExtent[0]) {
- --world;
- offsetX = worldWidth * world;
- transform = this.getTransform(frameState, offsetX);
- replayGroup.replay(replayContext, transform, rotation, skippedFeatureUids);
- startX += worldWidth;
- }
- world = 0;
- startX = extent[2];
- while (startX > projectionExtent[2]) {
- ++world;
- offsetX = worldWidth * world;
- transform = this.getTransform(frameState, offsetX);
- replayGroup.replay(replayContext, transform, rotation, skippedFeatureUids);
- startX -= worldWidth;
- }
- // restore original transform for render and compose events
- transform = this.getTransform(frameState, 0);
- }
- ol.render.canvas.rotateAtOffset(replayContext, rotation,
- width / 2, height / 2);
- if (replayContext != context) {
- if (hasRenderListeners) {
- this.dispatchRenderEvent(replayContext, frameState, transform);
- }
- if (transparentLayer) {
- var mainContextAlpha = context.globalAlpha;
- context.globalAlpha = layerState.opacity;
- context.drawImage(replayContext.canvas, -drawOffsetX, -drawOffsetY);
- context.globalAlpha = mainContextAlpha;
- } else {
- context.drawImage(replayContext.canvas, -drawOffsetX, -drawOffsetY);
- }
- replayContext.translate(-drawOffsetX, -drawOffsetY);
- }
- if (!transparentLayer) {
- replayContext.globalAlpha = alpha;
- }
- }
- if (clipped) {
- context.restore();
- }
- this.postCompose(context, frameState, layerState, transform);
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.VectorLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, hitTolerance, callback, thisArg) {
- if (!this.replayGroup_) {
- return undefined;
- } else {
- var resolution = frameState.viewState.resolution;
- var rotation = frameState.viewState.rotation;
- var layer = /** @type {ol.layer.Vector} */ (this.getLayer());
- /** @type {Object.<string, boolean>} */
- var features = {};
- var result = this.replayGroup_.forEachFeatureAtCoordinate(coordinate, resolution,
- rotation, hitTolerance, {},
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @return {?} Callback result.
- */
- function(feature) {
- var key = ol.getUid(feature).toString();
- if (!(key in features)) {
- features[key] = true;
- return callback.call(thisArg, feature, layer);
- }
- }, null);
- return result;
- }
- };
- /**
- * @param {ol.events.Event} event Event.
- */
- ol.renderer.canvas.VectorLayer.prototype.handleFontsChanged_ = function(event) {
- var layer = this.getLayer();
- if (layer.getVisible() && this.replayGroup_) {
- layer.changed();
- }
- };
- /**
- * Handle changes in image style state.
- * @param {ol.events.Event} event Image style change event.
- * @private
- */
- ol.renderer.canvas.VectorLayer.prototype.handleStyleImageChange_ = function(event) {
- this.renderIfReadyAndVisible();
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.VectorLayer.prototype.prepareFrame = function(frameState, layerState) {
- var vectorLayer = /** @type {ol.layer.Vector} */ (this.getLayer());
- var vectorSource = vectorLayer.getSource();
- this.updateLogos(frameState, vectorSource);
- var animating = frameState.viewHints[ol.ViewHint.ANIMATING];
- var interacting = frameState.viewHints[ol.ViewHint.INTERACTING];
- var updateWhileAnimating = vectorLayer.getUpdateWhileAnimating();
- var updateWhileInteracting = vectorLayer.getUpdateWhileInteracting();
- if (!this.dirty_ && (!updateWhileAnimating && animating) ||
- (!updateWhileInteracting && interacting)) {
- return true;
- }
- var frameStateExtent = frameState.extent;
- var viewState = frameState.viewState;
- var projection = viewState.projection;
- var resolution = viewState.resolution;
- var pixelRatio = frameState.pixelRatio;
- var vectorLayerRevision = vectorLayer.getRevision();
- var vectorLayerRenderBuffer = vectorLayer.getRenderBuffer();
- var vectorLayerRenderOrder = vectorLayer.getRenderOrder();
- if (vectorLayerRenderOrder === undefined) {
- vectorLayerRenderOrder = ol.renderer.vector.defaultOrder;
- }
- var extent = ol.extent.buffer(frameStateExtent,
- vectorLayerRenderBuffer * resolution);
- var projectionExtent = viewState.projection.getExtent();
- if (vectorSource.getWrapX() && viewState.projection.canWrapX() &&
- !ol.extent.containsExtent(projectionExtent, frameState.extent)) {
- // For the replay group, we need an extent that intersects the real world
- // (-180° to +180°). To support geometries in a coordinate range from -540°
- // to +540°, we add at least 1 world width on each side of the projection
- // extent. If the viewport is wider than the world, we need to add half of
- // the viewport width to make sure we cover the whole viewport.
- var worldWidth = ol.extent.getWidth(projectionExtent);
- var buffer = Math.max(ol.extent.getWidth(extent) / 2, worldWidth);
- extent[0] = projectionExtent[0] - buffer;
- extent[2] = projectionExtent[2] + buffer;
- }
- if (!this.dirty_ &&
- this.renderedResolution_ == resolution &&
- this.renderedRevision_ == vectorLayerRevision &&
- this.renderedRenderOrder_ == vectorLayerRenderOrder &&
- ol.extent.containsExtent(this.renderedExtent_, extent)) {
- this.replayGroupChanged = false;
- return true;
- }
- this.replayGroup_ = null;
- this.dirty_ = false;
- var replayGroup = new ol.render.canvas.ReplayGroup(
- ol.renderer.vector.getTolerance(resolution, pixelRatio), extent, resolution,
- pixelRatio, vectorSource.getOverlaps(), this.declutterTree_, vectorLayer.getRenderBuffer());
- vectorSource.loadFeatures(extent, resolution, projection);
- /**
- * @param {ol.Feature} feature Feature.
- * @this {ol.renderer.canvas.VectorLayer}
- */
- var renderFeature = function(feature) {
- var styles;
- var styleFunction = feature.getStyleFunction();
- if (styleFunction) {
- styles = styleFunction.call(feature, resolution);
- } else {
- styleFunction = vectorLayer.getStyleFunction();
- if (styleFunction) {
- styles = styleFunction(feature, resolution);
- }
- }
- if (styles) {
- var dirty = this.renderFeature(
- feature, resolution, pixelRatio, styles, replayGroup);
- this.dirty_ = this.dirty_ || dirty;
- }
- }.bind(this);
- if (vectorLayerRenderOrder) {
- /** @type {Array.<ol.Feature>} */
- var features = [];
- vectorSource.forEachFeatureInExtent(extent,
- /**
- * @param {ol.Feature} feature Feature.
- */
- function(feature) {
- features.push(feature);
- }, this);
- features.sort(vectorLayerRenderOrder);
- for (var i = 0, ii = features.length; i < ii; ++i) {
- renderFeature(features[i]);
- }
- } else {
- vectorSource.forEachFeatureInExtent(extent, renderFeature, this);
- }
- replayGroup.finish();
- this.renderedResolution_ = resolution;
- this.renderedRevision_ = vectorLayerRevision;
- this.renderedRenderOrder_ = vectorLayerRenderOrder;
- this.renderedExtent_ = extent;
- this.replayGroup_ = replayGroup;
- this.replayGroupChanged = true;
- return true;
- };
- /**
- * @param {ol.Feature} feature Feature.
- * @param {number} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @param {(ol.style.Style|Array.<ol.style.Style>)} styles The style or array of
- * styles.
- * @param {ol.render.canvas.ReplayGroup} replayGroup Replay group.
- * @return {boolean} `true` if an image is loading.
- */
- ol.renderer.canvas.VectorLayer.prototype.renderFeature = function(feature, resolution, pixelRatio, styles, replayGroup) {
- if (!styles) {
- return false;
- }
- var loading = false;
- if (Array.isArray(styles)) {
- for (var i = 0, ii = styles.length; i < ii; ++i) {
- loading = ol.renderer.vector.renderFeature(
- replayGroup, feature, styles[i],
- ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
- this.handleStyleImageChange_, this) || loading;
- }
- } else {
- loading = ol.renderer.vector.renderFeature(
- replayGroup, feature, styles,
- ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
- this.handleStyleImageChange_, this);
- }
- return loading;
- };
- goog.provide('ol.layer.VectorTileRenderType');
- /**
- * @enum {string}
- * Render mode for vector tiles:
- * * `'image'`: Vector tiles are rendered as images. Great performance, but
- * point symbols and texts are always rotated with the view and pixels are
- * scaled during zoom animations.
- * * `'hybrid'`: Polygon and line elements are rendered as images, so pixels
- * are scaled during zoom animations. Point symbols and texts are accurately
- * rendered as vectors and can stay upright on rotated views.
- * * `'vector'`: Vector tiles are rendered as vectors. Most accurate rendering
- * even during animations, but slower performance than the other options.
- * @api
- */
- ol.layer.VectorTileRenderType = {
- IMAGE: 'image',
- HYBRID: 'hybrid',
- VECTOR: 'vector'
- };
- goog.provide('ol.renderer.canvas.VectorTileLayer');
- goog.require('ol');
- goog.require('ol.LayerType');
- goog.require('ol.TileState');
- goog.require('ol.dom');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.ext.rbush');
- goog.require('ol.extent');
- goog.require('ol.layer.VectorTileRenderType');
- goog.require('ol.proj');
- goog.require('ol.proj.Units');
- goog.require('ol.render.ReplayType');
- goog.require('ol.render.canvas');
- goog.require('ol.render.canvas.ReplayGroup');
- goog.require('ol.render.replay');
- goog.require('ol.renderer.Type');
- goog.require('ol.renderer.canvas.TileLayer');
- goog.require('ol.renderer.vector');
- goog.require('ol.transform');
- /**
- * @constructor
- * @extends {ol.renderer.canvas.TileLayer}
- * @param {ol.layer.VectorTile} layer VectorTile layer.
- * @api
- */
- ol.renderer.canvas.VectorTileLayer = function(layer) {
- /**
- * @type {CanvasRenderingContext2D}
- */
- this.context = null;
- ol.renderer.canvas.TileLayer.call(this, layer);
- /**
- * Declutter tree.
- * @private
- */
- this.declutterTree_ = layer.getDeclutter() ? ol.ext.rbush(9) : null;
- /**
- * @private
- * @type {boolean}
- */
- this.dirty_ = false;
- /**
- * @private
- * @type {number}
- */
- this.renderedLayerRevision_;
- /**
- * @private
- * @type {ol.Transform}
- */
- this.tmpTransform_ = ol.transform.create();
- // Use lower resolution for pure vector rendering. Closest resolution otherwise.
- this.zDirection =
- layer.getRenderMode() == ol.layer.VectorTileRenderType.VECTOR ? 1 : 0;
- ol.events.listen(ol.render.canvas.labelCache, ol.events.EventType.CLEAR, this.handleFontsChanged_, this);
- };
- ol.inherits(ol.renderer.canvas.VectorTileLayer, ol.renderer.canvas.TileLayer);
- /**
- * Determine if this renderer handles the provided layer.
- * @param {ol.renderer.Type} type The renderer type.
- * @param {ol.layer.Layer} layer The candidate layer.
- * @return {boolean} The renderer can render the layer.
- */
- ol.renderer.canvas.VectorTileLayer['handles'] = function(type, layer) {
- return type === ol.renderer.Type.CANVAS && layer.getType() === ol.LayerType.VECTOR_TILE;
- };
- /**
- * Create a layer renderer.
- * @param {ol.renderer.Map} mapRenderer The map renderer.
- * @param {ol.layer.Layer} layer The layer to be rendererd.
- * @return {ol.renderer.canvas.VectorTileLayer} The layer renderer.
- */
- ol.renderer.canvas.VectorTileLayer['create'] = function(mapRenderer, layer) {
- return new ol.renderer.canvas.VectorTileLayer(/** @type {ol.layer.VectorTile} */ (layer));
- };
- /**
- * @const
- * @type {!Object.<string, Array.<ol.render.ReplayType>>}
- */
- ol.renderer.canvas.VectorTileLayer.IMAGE_REPLAYS = {
- 'image': [ol.render.ReplayType.POLYGON, ol.render.ReplayType.CIRCLE,
- ol.render.ReplayType.LINE_STRING, ol.render.ReplayType.IMAGE, ol.render.ReplayType.TEXT],
- 'hybrid': [ol.render.ReplayType.POLYGON, ol.render.ReplayType.LINE_STRING]
- };
- /**
- * @const
- * @type {!Object.<string, Array.<ol.render.ReplayType>>}
- */
- ol.renderer.canvas.VectorTileLayer.VECTOR_REPLAYS = {
- 'image': [ol.render.ReplayType.DEFAULT],
- 'hybrid': [ol.render.ReplayType.IMAGE, ol.render.ReplayType.TEXT, ol.render.ReplayType.DEFAULT],
- 'vector': ol.render.replay.ORDER
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.VectorTileLayer.prototype.disposeInternal = function() {
- ol.events.unlisten(ol.render.canvas.labelCache, ol.events.EventType.CLEAR, this.handleFontsChanged_, this);
- ol.renderer.canvas.TileLayer.prototype.disposeInternal.call(this);
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.VectorTileLayer.prototype.prepareFrame = function(frameState, layerState) {
- var layer = this.getLayer();
- var layerRevision = layer.getRevision();
- if (this.renderedLayerRevision_ != layerRevision) {
- this.renderedTiles.length = 0;
- var renderMode = layer.getRenderMode();
- if (!this.context && renderMode != ol.layer.VectorTileRenderType.VECTOR) {
- this.context = ol.dom.createCanvasContext2D();
- }
- if (this.context && renderMode == ol.layer.VectorTileRenderType.VECTOR) {
- this.context = null;
- }
- }
- this.renderedLayerRevision_ = layerRevision;
- return ol.renderer.canvas.TileLayer.prototype.prepareFrame.apply(this, arguments);
- };
- /**
- * @param {ol.VectorImageTile} tile Tile.
- * @param {olx.FrameState} frameState Frame state.
- * @private
- */
- ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(
- tile, frameState) {
- var layer = this.getLayer();
- var pixelRatio = frameState.pixelRatio;
- var projection = frameState.viewState.projection;
- var revision = layer.getRevision();
- var renderOrder = /** @type {ol.RenderOrderFunction} */
- (layer.getRenderOrder()) || null;
- var replayState = tile.getReplayState(layer);
- if (!replayState.dirty && replayState.renderedRevision == revision &&
- replayState.renderedRenderOrder == renderOrder) {
- return;
- }
- var source = /** @type {ol.source.VectorTile} */ (layer.getSource());
- var sourceTileGrid = source.getTileGrid();
- var tileGrid = source.getTileGridForProjection(projection);
- var resolution = tileGrid.getResolution(tile.tileCoord[0]);
- var tileExtent = tileGrid.getTileCoordExtent(tile.wrappedTileCoord);
- var zIndexKeys = {};
- for (var t = 0, tt = tile.tileKeys.length; t < tt; ++t) {
- var sourceTile = tile.getTile(tile.tileKeys[t]);
- if (sourceTile.getState() == ol.TileState.ERROR) {
- continue;
- }
- var sourceTileCoord = sourceTile.tileCoord;
- var sourceTileExtent = sourceTileGrid.getTileCoordExtent(sourceTileCoord);
- var sharedExtent = ol.extent.getIntersection(tileExtent, sourceTileExtent);
- var bufferedExtent = ol.extent.equals(sourceTileExtent, sharedExtent) ? null :
- ol.extent.buffer(sharedExtent, layer.getRenderBuffer() * resolution);
- var tileProjection = sourceTile.getProjection();
- var reproject = false;
- if (!ol.proj.equivalent(projection, tileProjection)) {
- reproject = true;
- sourceTile.setProjection(projection);
- }
- replayState.dirty = false;
- var replayGroup = new ol.render.canvas.ReplayGroup(0, sharedExtent, resolution,
- pixelRatio, source.getOverlaps(), this.declutterTree_, layer.getRenderBuffer());
- var squaredTolerance = ol.renderer.vector.getSquaredTolerance(
- resolution, pixelRatio);
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @this {ol.renderer.canvas.VectorTileLayer}
- */
- var renderFeature = function(feature) {
- var styles;
- var styleFunction = feature.getStyleFunction();
- if (styleFunction) {
- styles = styleFunction.call(/** @type {ol.Feature} */ (feature), resolution);
- } else {
- styleFunction = layer.getStyleFunction();
- if (styleFunction) {
- styles = styleFunction(feature, resolution);
- }
- }
- if (styles) {
- var dirty = this.renderFeature(feature, squaredTolerance, styles,
- replayGroup);
- this.dirty_ = this.dirty_ || dirty;
- replayState.dirty = replayState.dirty || dirty;
- }
- };
- var features = sourceTile.getFeatures();
- if (renderOrder && renderOrder !== replayState.renderedRenderOrder) {
- features.sort(renderOrder);
- }
- var feature;
- for (var i = 0, ii = features.length; i < ii; ++i) {
- feature = features[i];
- if (reproject) {
- if (tileProjection.getUnits() == ol.proj.Units.TILE_PIXELS) {
- // projected tile extent
- tileProjection.setWorldExtent(sourceTileExtent);
- // tile extent in tile pixel space
- tileProjection.setExtent(sourceTile.getExtent());
- }
- feature.getGeometry().transform(tileProjection, projection);
- }
- if (!bufferedExtent || ol.extent.intersects(bufferedExtent, feature.getGeometry().getExtent())) {
- renderFeature.call(this, feature);
- }
- }
- replayGroup.finish();
- for (var r in replayGroup.getReplays()) {
- zIndexKeys[r] = true;
- }
- sourceTile.setReplayGroup(layer, tile.tileCoord.toString(), replayGroup);
- }
- replayState.renderedRevision = revision;
- replayState.renderedRenderOrder = renderOrder;
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.VectorTileLayer.prototype.drawTileImage = function(
- tile, frameState, layerState, x, y, w, h, gutter, transition) {
- var vectorImageTile = /** @type {ol.VectorImageTile} */ (tile);
- this.createReplayGroup_(vectorImageTile, frameState);
- if (this.context) {
- this.renderTileImage_(vectorImageTile, frameState, layerState);
- ol.renderer.canvas.TileLayer.prototype.drawTileImage.apply(this, arguments);
- }
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.VectorTileLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, hitTolerance, callback, thisArg) {
- var resolution = frameState.viewState.resolution;
- var rotation = frameState.viewState.rotation;
- hitTolerance = hitTolerance == undefined ? 0 : hitTolerance;
- var layer = this.getLayer();
- /** @type {Object.<string, boolean>} */
- var features = {};
- /** @type {Array.<ol.VectorImageTile>} */
- var renderedTiles = this.renderedTiles;
- var source = /** @type {ol.source.VectorTile} */ (layer.getSource());
- var tileGrid = source.getTileGridForProjection(frameState.viewState.projection);
- var bufferedExtent, found;
- var i, ii, replayGroup;
- var tile, tileCoord, tileExtent;
- for (i = 0, ii = renderedTiles.length; i < ii; ++i) {
- tile = renderedTiles[i];
- tileCoord = tile.wrappedTileCoord;
- tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent);
- bufferedExtent = ol.extent.buffer(tileExtent, hitTolerance * resolution, bufferedExtent);
- if (!ol.extent.containsCoordinate(bufferedExtent, coordinate)) {
- continue;
- }
- for (var t = 0, tt = tile.tileKeys.length; t < tt; ++t) {
- var sourceTile = tile.getTile(tile.tileKeys[t]);
- if (sourceTile.getState() == ol.TileState.ERROR) {
- continue;
- }
- replayGroup = sourceTile.getReplayGroup(layer, tile.tileCoord.toString());
- found = found || replayGroup.forEachFeatureAtCoordinate(
- coordinate, resolution, rotation, hitTolerance, {},
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @return {?} Callback result.
- */
- function(feature) {
- var key = ol.getUid(feature).toString();
- if (!(key in features)) {
- features[key] = true;
- return callback.call(thisArg, feature, layer);
- }
- }, null);
- }
- }
- return found;
- };
- /**
- * @param {ol.VectorTile} tile Tile.
- * @param {olx.FrameState} frameState Frame state.
- * @return {ol.Transform} transform Transform.
- * @private
- */
- ol.renderer.canvas.VectorTileLayer.prototype.getReplayTransform_ = function(tile, frameState) {
- var layer = this.getLayer();
- var source = /** @type {ol.source.VectorTile} */ (layer.getSource());
- var tileGrid = source.getTileGrid();
- var tileCoord = tile.tileCoord;
- var tileResolution = tileGrid.getResolution(tileCoord[0]);
- var viewState = frameState.viewState;
- var pixelRatio = frameState.pixelRatio;
- var renderResolution = viewState.resolution / pixelRatio;
- var tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent);
- var center = viewState.center;
- var origin = ol.extent.getTopLeft(tileExtent);
- var size = frameState.size;
- var offsetX = Math.round(pixelRatio * size[0] / 2);
- var offsetY = Math.round(pixelRatio * size[1] / 2);
- return ol.transform.compose(this.tmpTransform_,
- offsetX, offsetY,
- tileResolution / renderResolution, tileResolution / renderResolution,
- viewState.rotation,
- (origin[0] - center[0]) / tileResolution,
- (center[1] - origin[1]) / tileResolution);
- };
- /**
- * @param {ol.events.Event} event Event.
- */
- ol.renderer.canvas.VectorTileLayer.prototype.handleFontsChanged_ = function(event) {
- var layer = this.getLayer();
- if (layer.getVisible() && this.renderedLayerRevision_ !== undefined) {
- layer.changed();
- }
- };
- /**
- * Handle changes in image style state.
- * @param {ol.events.Event} event Image style change event.
- * @private
- */
- ol.renderer.canvas.VectorTileLayer.prototype.handleStyleImageChange_ = function(event) {
- this.renderIfReadyAndVisible();
- };
- /**
- * @inheritDoc
- */
- ol.renderer.canvas.VectorTileLayer.prototype.postCompose = function(context, frameState, layerState) {
- var layer = this.getLayer();
- var declutterReplays = layer.getDeclutter() ? {} : null;
- var source = /** @type {ol.source.VectorTile} */ (layer.getSource());
- var renderMode = layer.getRenderMode();
- var replayTypes = ol.renderer.canvas.VectorTileLayer.VECTOR_REPLAYS[renderMode];
- var pixelRatio = frameState.pixelRatio;
- var rotation = frameState.viewState.rotation;
- var size = frameState.size;
- var offsetX, offsetY;
- if (rotation) {
- offsetX = Math.round(pixelRatio * size[0] / 2);
- offsetY = Math.round(pixelRatio * size[1] / 2);
- ol.render.canvas.rotateAtOffset(context, -rotation, offsetX, offsetY);
- }
- if (declutterReplays) {
- this.declutterTree_.clear();
- }
- var tiles = this.renderedTiles;
- var tileGrid = source.getTileGridForProjection(frameState.viewState.projection);
- var clips = [];
- var zs = [];
- for (var i = tiles.length - 1; i >= 0; --i) {
- var tile = /** @type {ol.VectorImageTile} */ (tiles[i]);
- if (tile.getState() == ol.TileState.ABORT) {
- continue;
- }
- var tileCoord = tile.tileCoord;
- var worldOffset = tileGrid.getTileCoordExtent(tileCoord)[0] -
- tileGrid.getTileCoordExtent(tile.wrappedTileCoord)[0];
- var transform = undefined;
- for (var t = 0, tt = tile.tileKeys.length; t < tt; ++t) {
- var sourceTile = tile.getTile(tile.tileKeys[t]);
- if (sourceTile.getState() == ol.TileState.ERROR) {
- continue;
- }
- var replayGroup = sourceTile.getReplayGroup(layer, tileCoord.toString());
- if (renderMode != ol.layer.VectorTileRenderType.VECTOR && !replayGroup.hasReplays(replayTypes)) {
- continue;
- }
- if (!transform) {
- transform = this.getTransform(frameState, worldOffset);
- }
- var currentZ = sourceTile.tileCoord[0];
- var currentClip = replayGroup.getClipCoords(transform);
- context.save();
- context.globalAlpha = layerState.opacity;
- // Create a clip mask for regions in this low resolution tile that are
- // already filled by a higher resolution tile
- for (var j = 0, jj = clips.length; j < jj; ++j) {
- var clip = clips[j];
- if (currentZ < zs[j]) {
- context.beginPath();
- // counter-clockwise (outer ring) for current tile
- context.moveTo(currentClip[0], currentClip[1]);
- context.lineTo(currentClip[2], currentClip[3]);
- context.lineTo(currentClip[4], currentClip[5]);
- context.lineTo(currentClip[6], currentClip[7]);
- // clockwise (inner ring) for higher resolution tile
- context.moveTo(clip[6], clip[7]);
- context.lineTo(clip[4], clip[5]);
- context.lineTo(clip[2], clip[3]);
- context.lineTo(clip[0], clip[1]);
- context.clip();
- }
- }
- replayGroup.replay(context, transform, rotation, {}, replayTypes, declutterReplays);
- context.restore();
- clips.push(currentClip);
- zs.push(currentZ);
- }
- }
- if (declutterReplays) {
- ol.render.canvas.ReplayGroup.replayDeclutter(declutterReplays, context, rotation);
- }
- if (rotation) {
- ol.render.canvas.rotateAtOffset(context, rotation,
- /** @type {number} */ (offsetX), /** @type {number} */ (offsetY));
- }
- ol.renderer.canvas.TileLayer.prototype.postCompose.apply(this, arguments);
- };
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @param {number} squaredTolerance Squared tolerance.
- * @param {(ol.style.Style|Array.<ol.style.Style>)} styles The style or array of
- * styles.
- * @param {ol.render.canvas.ReplayGroup} replayGroup Replay group.
- * @return {boolean} `true` if an image is loading.
- */
- ol.renderer.canvas.VectorTileLayer.prototype.renderFeature = function(feature, squaredTolerance, styles, replayGroup) {
- if (!styles) {
- return false;
- }
- var loading = false;
- if (Array.isArray(styles)) {
- for (var i = 0, ii = styles.length; i < ii; ++i) {
- loading = ol.renderer.vector.renderFeature(
- replayGroup, feature, styles[i], squaredTolerance,
- this.handleStyleImageChange_, this) || loading;
- }
- } else {
- loading = ol.renderer.vector.renderFeature(
- replayGroup, feature, styles, squaredTolerance,
- this.handleStyleImageChange_, this);
- }
- return loading;
- };
- /**
- * @param {ol.VectorImageTile} tile Tile.
- * @param {olx.FrameState} frameState Frame state.
- * @param {ol.LayerState} layerState Layer state.
- * @private
- */
- ol.renderer.canvas.VectorTileLayer.prototype.renderTileImage_ = function(
- tile, frameState, layerState) {
- var layer = this.getLayer();
- var replayState = tile.getReplayState(layer);
- var revision = layer.getRevision();
- var replays = ol.renderer.canvas.VectorTileLayer.IMAGE_REPLAYS[layer.getRenderMode()];
- if (replays && replayState.renderedTileRevision !== revision) {
- replayState.renderedTileRevision = revision;
- var tileCoord = tile.wrappedTileCoord;
- var z = tileCoord[0];
- var pixelRatio = frameState.pixelRatio;
- var source = /** @type {ol.source.VectorTile} */ (layer.getSource());
- var tileGrid = source.getTileGridForProjection(frameState.viewState.projection);
- var resolution = tileGrid.getResolution(z);
- var context = tile.getContext(layer);
- var size = source.getTilePixelSize(z, pixelRatio, frameState.viewState.projection);
- context.canvas.width = size[0];
- context.canvas.height = size[1];
- var tileExtent = tileGrid.getTileCoordExtent(tileCoord);
- for (var i = 0, ii = tile.tileKeys.length; i < ii; ++i) {
- var sourceTile = tile.getTile(tile.tileKeys[i]);
- if (sourceTile.getState() == ol.TileState.ERROR) {
- continue;
- }
- var pixelScale = pixelRatio / resolution;
- var transform = ol.transform.reset(this.tmpTransform_);
- ol.transform.scale(transform, pixelScale, -pixelScale);
- ol.transform.translate(transform, -tileExtent[0], -tileExtent[3]);
- var replayGroup = sourceTile.getReplayGroup(layer, tile.tileCoord.toString());
- replayGroup.replay(context, transform, 0, {}, replays);
- }
- }
- };
- goog.provide('ol.CanvasMap');
- goog.require('ol');
- goog.require('ol.PluggableMap');
- goog.require('ol.PluginType');
- goog.require('ol.control');
- goog.require('ol.interaction');
- goog.require('ol.obj');
- goog.require('ol.plugins');
- goog.require('ol.renderer.canvas.ImageLayer');
- goog.require('ol.renderer.canvas.Map');
- goog.require('ol.renderer.canvas.TileLayer');
- goog.require('ol.renderer.canvas.VectorLayer');
- goog.require('ol.renderer.canvas.VectorTileLayer');
- ol.plugins.register(ol.PluginType.MAP_RENDERER, ol.renderer.canvas.Map);
- ol.plugins.registerMultiple(ol.PluginType.LAYER_RENDERER, [
- ol.renderer.canvas.ImageLayer,
- ol.renderer.canvas.TileLayer,
- ol.renderer.canvas.VectorLayer,
- ol.renderer.canvas.VectorTileLayer
- ]);
- /**
- * @classdesc
- * The map is the core component of OpenLayers. For a map to render, a view,
- * one or more layers, and a target container are needed:
- *
- * var map = new ol.CanvasMap({
- * view: new ol.View({
- * center: [0, 0],
- * zoom: 1
- * }),
- * layers: [
- * new ol.layer.Tile({
- * source: new ol.source.OSM()
- * })
- * ],
- * target: 'map'
- * });
- *
- * The above snippet creates a map using a {@link ol.layer.Tile} to display
- * {@link ol.source.OSM} OSM data and render it to a DOM element with the
- * id `map`.
- *
- * The constructor places a viewport container (with CSS class name
- * `ol-viewport`) in the target element (see `getViewport()`), and then two
- * further elements within the viewport: one with CSS class name
- * `ol-overlaycontainer-stopevent` for controls and some overlays, and one with
- * CSS class name `ol-overlaycontainer` for other overlays (see the `stopEvent`
- * option of {@link ol.Overlay} for the difference). The map itself is placed in
- * a further element within the viewport.
- *
- * Layers are stored as a `ol.Collection` in layerGroups. A top-level group is
- * provided by the library. This is what is accessed by `getLayerGroup` and
- * `setLayerGroup`. Layers entered in the options are added to this group, and
- * `addLayer` and `removeLayer` change the layer collection in the group.
- * `getLayers` is a convenience function for `getLayerGroup().getLayers()`.
- * Note that `ol.layer.Group` is a subclass of `ol.layer.Base`, so layers
- * entered in the options or added with `addLayer` can be groups, which can
- * contain further groups, and so on.
- *
- * @constructor
- * @extends {ol.PluggableMap}
- * @param {olx.MapOptions} options Map options.
- * @fires ol.MapBrowserEvent
- * @fires ol.MapEvent
- * @fires ol.render.Event#postcompose
- * @fires ol.render.Event#precompose
- * @api
- */
- ol.CanvasMap = function(options) {
- options = ol.obj.assign({}, options);
- delete options.renderer;
- if (!options.controls) {
- options.controls = ol.control.defaults();
- }
- if (!options.interactions) {
- options.interactions = ol.interaction.defaults();
- }
- ol.PluggableMap.call(this, options);
- };
- ol.inherits(ol.CanvasMap, ol.PluggableMap);
- goog.provide('ol.control.FullScreen');
- goog.require('ol');
- goog.require('ol.control.Control');
- goog.require('ol.css');
- goog.require('ol.dom');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- /**
- * @classdesc
- * Provides a button that when clicked fills up the full screen with the map.
- * The full screen source element is by default the element containing the map viewport unless
- * overridden by providing the `source` option. In which case, the dom
- * element introduced using this parameter will be displayed in full screen.
- *
- * When in full screen mode, a close button is shown to exit full screen mode.
- * The [Fullscreen API](http://www.w3.org/TR/fullscreen/) is used to
- * toggle the map in full screen mode.
- *
- *
- * @constructor
- * @extends {ol.control.Control}
- * @param {olx.control.FullScreenOptions=} opt_options Options.
- * @api
- */
- ol.control.FullScreen = function(opt_options) {
- var options = opt_options ? opt_options : {};
- /**
- * @private
- * @type {string}
- */
- this.cssClassName_ = options.className !== undefined ? options.className :
- 'ol-full-screen';
- var label = options.label !== undefined ? options.label : '\u2922';
- /**
- * @private
- * @type {Node}
- */
- this.labelNode_ = typeof label === 'string' ?
- document.createTextNode(label) : label;
- var labelActive = options.labelActive !== undefined ? options.labelActive : '\u00d7';
- /**
- * @private
- * @type {Node}
- */
- this.labelActiveNode_ = typeof labelActive === 'string' ?
- document.createTextNode(labelActive) : labelActive;
- var tipLabel = options.tipLabel ? options.tipLabel : 'Toggle full-screen';
- var button = document.createElement('button');
- button.className = this.cssClassName_ + '-' + ol.control.FullScreen.isFullScreen();
- button.setAttribute('type', 'button');
- button.title = tipLabel;
- button.appendChild(this.labelNode_);
- ol.events.listen(button, ol.events.EventType.CLICK,
- this.handleClick_, this);
- var cssClasses = this.cssClassName_ + ' ' + ol.css.CLASS_UNSELECTABLE +
- ' ' + ol.css.CLASS_CONTROL + ' ' +
- (!ol.control.FullScreen.isFullScreenSupported() ? ol.css.CLASS_UNSUPPORTED : '');
- var element = document.createElement('div');
- element.className = cssClasses;
- element.appendChild(button);
- ol.control.Control.call(this, {
- element: element,
- target: options.target
- });
- /**
- * @private
- * @type {boolean}
- */
- this.keys_ = options.keys !== undefined ? options.keys : false;
- /**
- * @private
- * @type {Element|string|undefined}
- */
- this.source_ = options.source;
- };
- ol.inherits(ol.control.FullScreen, ol.control.Control);
- /**
- * @param {Event} event The event to handle
- * @private
- */
- ol.control.FullScreen.prototype.handleClick_ = function(event) {
- event.preventDefault();
- this.handleFullScreen_();
- };
- /**
- * @private
- */
- ol.control.FullScreen.prototype.handleFullScreen_ = function() {
- if (!ol.control.FullScreen.isFullScreenSupported()) {
- return;
- }
- var map = this.getMap();
- if (!map) {
- return;
- }
- if (ol.control.FullScreen.isFullScreen()) {
- ol.control.FullScreen.exitFullScreen();
- } else {
- var element;
- if (this.source_) {
- element = typeof this.source_ === 'string' ?
- document.getElementById(this.source_) :
- this.source_;
- } else {
- element = map.getTargetElement();
- }
- if (this.keys_) {
- ol.control.FullScreen.requestFullScreenWithKeys(element);
- } else {
- ol.control.FullScreen.requestFullScreen(element);
- }
- }
- };
- /**
- * @private
- */
- ol.control.FullScreen.prototype.handleFullScreenChange_ = function() {
- var button = this.element.firstElementChild;
- var map = this.getMap();
- if (ol.control.FullScreen.isFullScreen()) {
- button.className = this.cssClassName_ + '-true';
- ol.dom.replaceNode(this.labelActiveNode_, this.labelNode_);
- } else {
- button.className = this.cssClassName_ + '-false';
- ol.dom.replaceNode(this.labelNode_, this.labelActiveNode_);
- }
- if (map) {
- map.updateSize();
- }
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.control.FullScreen.prototype.setMap = function(map) {
- ol.control.Control.prototype.setMap.call(this, map);
- if (map) {
- this.listenerKeys.push(ol.events.listen(document,
- ol.control.FullScreen.getChangeType_(),
- this.handleFullScreenChange_, this)
- );
- }
- };
- /**
- * @return {boolean} Fullscreen is supported by the current platform.
- */
- ol.control.FullScreen.isFullScreenSupported = function() {
- var body = document.body;
- return !!(
- body.webkitRequestFullscreen ||
- (body.mozRequestFullScreen && document.mozFullScreenEnabled) ||
- (body.msRequestFullscreen && document.msFullscreenEnabled) ||
- (body.requestFullscreen && document.fullscreenEnabled)
- );
- };
- /**
- * @return {boolean} Element is currently in fullscreen.
- */
- ol.control.FullScreen.isFullScreen = function() {
- return !!(
- document.webkitIsFullScreen || document.mozFullScreen ||
- document.msFullscreenElement || document.fullscreenElement
- );
- };
- /**
- * Request to fullscreen an element.
- * @param {Node} element Element to request fullscreen
- */
- ol.control.FullScreen.requestFullScreen = function(element) {
- if (element.requestFullscreen) {
- element.requestFullscreen();
- } else if (element.msRequestFullscreen) {
- element.msRequestFullscreen();
- } else if (element.mozRequestFullScreen) {
- element.mozRequestFullScreen();
- } else if (element.webkitRequestFullscreen) {
- element.webkitRequestFullscreen();
- }
- };
- /**
- * Request to fullscreen an element with keyboard input.
- * @param {Node} element Element to request fullscreen
- */
- ol.control.FullScreen.requestFullScreenWithKeys = function(element) {
- if (element.mozRequestFullScreenWithKeys) {
- element.mozRequestFullScreenWithKeys();
- } else if (element.webkitRequestFullscreen) {
- element.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
- } else {
- ol.control.FullScreen.requestFullScreen(element);
- }
- };
- /**
- * Exit fullscreen.
- */
- ol.control.FullScreen.exitFullScreen = function() {
- if (document.exitFullscreen) {
- document.exitFullscreen();
- } else if (document.msExitFullscreen) {
- document.msExitFullscreen();
- } else if (document.mozCancelFullScreen) {
- document.mozCancelFullScreen();
- } else if (document.webkitExitFullscreen) {
- document.webkitExitFullscreen();
- }
- };
- /**
- * @return {string} Change type.
- * @private
- */
- ol.control.FullScreen.getChangeType_ = (function() {
- var changeType;
- return function() {
- if (!changeType) {
- var body = document.body;
- if (body.webkitRequestFullscreen) {
- changeType = 'webkitfullscreenchange';
- } else if (body.mozRequestFullScreen) {
- changeType = 'mozfullscreenchange';
- } else if (body.msRequestFullscreen) {
- changeType = 'MSFullscreenChange';
- } else if (body.requestFullscreen) {
- changeType = 'fullscreenchange';
- }
- }
- return changeType;
- };
- })();
- // FIXME should listen on appropriate pane, once it is defined
- goog.provide('ol.control.MousePosition');
- goog.require('ol');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.Object');
- goog.require('ol.control.Control');
- goog.require('ol.proj');
- /**
- * @classdesc
- * A control to show the 2D coordinates of the mouse cursor. By default, these
- * are in the view projection, but can be in any supported projection.
- * By default the control is shown in the top right corner of the map, but this
- * can be changed by using the css selector `.ol-mouse-position`.
- *
- * @constructor
- * @extends {ol.control.Control}
- * @param {olx.control.MousePositionOptions=} opt_options Mouse position
- * options.
- * @api
- */
- ol.control.MousePosition = function(opt_options) {
- var options = opt_options ? opt_options : {};
- var element = document.createElement('DIV');
- element.className = options.className !== undefined ? options.className : 'ol-mouse-position';
- var render = options.render ?
- options.render : ol.control.MousePosition.render;
- ol.control.Control.call(this, {
- element: element,
- render: render,
- target: options.target
- });
- ol.events.listen(this,
- ol.Object.getChangeEventType(ol.control.MousePosition.Property_.PROJECTION),
- this.handleProjectionChanged_, this);
- if (options.coordinateFormat) {
- this.setCoordinateFormat(options.coordinateFormat);
- }
- if (options.projection) {
- this.setProjection(options.projection);
- }
- /**
- * @private
- * @type {string}
- */
- this.undefinedHTML_ = options.undefinedHTML !== undefined ? options.undefinedHTML : '';
- /**
- * @private
- * @type {string}
- */
- this.renderedHTML_ = element.innerHTML;
- /**
- * @private
- * @type {ol.proj.Projection}
- */
- this.mapProjection_ = null;
- /**
- * @private
- * @type {?ol.TransformFunction}
- */
- this.transform_ = null;
- /**
- * @private
- * @type {ol.Pixel}
- */
- this.lastMouseMovePixel_ = null;
- };
- ol.inherits(ol.control.MousePosition, ol.control.Control);
- /**
- * Update the mouseposition element.
- * @param {ol.MapEvent} mapEvent Map event.
- * @this {ol.control.MousePosition}
- * @api
- */
- ol.control.MousePosition.render = function(mapEvent) {
- var frameState = mapEvent.frameState;
- if (!frameState) {
- this.mapProjection_ = null;
- } else {
- if (this.mapProjection_ != frameState.viewState.projection) {
- this.mapProjection_ = frameState.viewState.projection;
- this.transform_ = null;
- }
- }
- this.updateHTML_(this.lastMouseMovePixel_);
- };
- /**
- * @private
- */
- ol.control.MousePosition.prototype.handleProjectionChanged_ = function() {
- this.transform_ = null;
- };
- /**
- * Return the coordinate format type used to render the current position or
- * undefined.
- * @return {ol.CoordinateFormatType|undefined} The format to render the current
- * position in.
- * @observable
- * @api
- */
- ol.control.MousePosition.prototype.getCoordinateFormat = function() {
- return /** @type {ol.CoordinateFormatType|undefined} */ (
- this.get(ol.control.MousePosition.Property_.COORDINATE_FORMAT));
- };
- /**
- * Return the projection that is used to report the mouse position.
- * @return {ol.proj.Projection|undefined} The projection to report mouse
- * position in.
- * @observable
- * @api
- */
- ol.control.MousePosition.prototype.getProjection = function() {
- return /** @type {ol.proj.Projection|undefined} */ (
- this.get(ol.control.MousePosition.Property_.PROJECTION));
- };
- /**
- * @param {Event} event Browser event.
- * @protected
- */
- ol.control.MousePosition.prototype.handleMouseMove = function(event) {
- var map = this.getMap();
- this.lastMouseMovePixel_ = map.getEventPixel(event);
- this.updateHTML_(this.lastMouseMovePixel_);
- };
- /**
- * @param {Event} event Browser event.
- * @protected
- */
- ol.control.MousePosition.prototype.handleMouseOut = function(event) {
- this.updateHTML_(null);
- this.lastMouseMovePixel_ = null;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.control.MousePosition.prototype.setMap = function(map) {
- ol.control.Control.prototype.setMap.call(this, map);
- if (map) {
- var viewport = map.getViewport();
- this.listenerKeys.push(
- ol.events.listen(viewport, ol.events.EventType.MOUSEMOVE,
- this.handleMouseMove, this),
- ol.events.listen(viewport, ol.events.EventType.MOUSEOUT,
- this.handleMouseOut, this)
- );
- }
- };
- /**
- * Set the coordinate format type used to render the current position.
- * @param {ol.CoordinateFormatType} format The format to render the current
- * position in.
- * @observable
- * @api
- */
- ol.control.MousePosition.prototype.setCoordinateFormat = function(format) {
- this.set(ol.control.MousePosition.Property_.COORDINATE_FORMAT, format);
- };
- /**
- * Set the projection that is used to report the mouse position.
- * @param {ol.ProjectionLike} projection The projection to report mouse
- * position in.
- * @observable
- * @api
- */
- ol.control.MousePosition.prototype.setProjection = function(projection) {
- this.set(ol.control.MousePosition.Property_.PROJECTION, ol.proj.get(projection));
- };
- /**
- * @param {?ol.Pixel} pixel Pixel.
- * @private
- */
- ol.control.MousePosition.prototype.updateHTML_ = function(pixel) {
- var html = this.undefinedHTML_;
- if (pixel && this.mapProjection_) {
- if (!this.transform_) {
- var projection = this.getProjection();
- if (projection) {
- this.transform_ = ol.proj.getTransformFromProjections(
- this.mapProjection_, projection);
- } else {
- this.transform_ = ol.proj.identityTransform;
- }
- }
- var map = this.getMap();
- var coordinate = map.getCoordinateFromPixel(pixel);
- if (coordinate) {
- this.transform_(coordinate, coordinate);
- var coordinateFormat = this.getCoordinateFormat();
- if (coordinateFormat) {
- html = coordinateFormat(coordinate);
- } else {
- html = coordinate.toString();
- }
- }
- }
- if (!this.renderedHTML_ || html != this.renderedHTML_) {
- this.element.innerHTML = html;
- this.renderedHTML_ = html;
- }
- };
- /**
- * @enum {string}
- * @private
- */
- ol.control.MousePosition.Property_ = {
- PROJECTION: 'projection',
- COORDINATE_FORMAT: 'coordinateFormat'
- };
- goog.provide('ol.OverlayPositioning');
- /**
- * Overlay position: `'bottom-left'`, `'bottom-center'`, `'bottom-right'`,
- * `'center-left'`, `'center-center'`, `'center-right'`, `'top-left'`,
- * `'top-center'`, `'top-right'`
- * @enum {string}
- */
- ol.OverlayPositioning = {
- BOTTOM_LEFT: 'bottom-left',
- BOTTOM_CENTER: 'bottom-center',
- BOTTOM_RIGHT: 'bottom-right',
- CENTER_LEFT: 'center-left',
- CENTER_CENTER: 'center-center',
- CENTER_RIGHT: 'center-right',
- TOP_LEFT: 'top-left',
- TOP_CENTER: 'top-center',
- TOP_RIGHT: 'top-right'
- };
- goog.provide('ol.Overlay');
- goog.require('ol');
- goog.require('ol.MapEventType');
- goog.require('ol.Object');
- goog.require('ol.OverlayPositioning');
- goog.require('ol.css');
- goog.require('ol.dom');
- goog.require('ol.events');
- goog.require('ol.extent');
- /**
- * @classdesc
- * An element to be displayed over the map and attached to a single map
- * location. Like {@link ol.control.Control}, Overlays are visible widgets.
- * Unlike Controls, they are not in a fixed position on the screen, but are tied
- * to a geographical coordinate, so panning the map will move an Overlay but not
- * a Control.
- *
- * Example:
- *
- * var popup = new ol.Overlay({
- * element: document.getElementById('popup')
- * });
- * popup.setPosition(coordinate);
- * map.addOverlay(popup);
- *
- * @constructor
- * @extends {ol.Object}
- * @param {olx.OverlayOptions} options Overlay options.
- * @api
- */
- ol.Overlay = function(options) {
- ol.Object.call(this);
- /**
- * @protected
- * @type {olx.OverlayOptions}
- */
- this.options = options;
- /**
- * @protected
- * @type {number|string|undefined}
- */
- this.id = options.id;
- /**
- * @protected
- * @type {boolean}
- */
- this.insertFirst = options.insertFirst !== undefined ?
- options.insertFirst : true;
- /**
- * @protected
- * @type {boolean}
- */
- this.stopEvent = options.stopEvent !== undefined ? options.stopEvent : true;
- /**
- * @protected
- * @type {Element}
- */
- this.element = document.createElement('DIV');
- this.element.className = options.className !== undefined ?
- options.className : 'ol-overlay-container ' + ol.css.CLASS_SELECTABLE;
- this.element.style.position = 'absolute';
- /**
- * @protected
- * @type {boolean}
- */
- this.autoPan = options.autoPan !== undefined ? options.autoPan : false;
- /**
- * @protected
- * @type {olx.OverlayPanOptions}
- */
- this.autoPanAnimation = options.autoPanAnimation ||
- /** @type {olx.OverlayPanOptions} */ ({});
- /**
- * @protected
- * @type {number}
- */
- this.autoPanMargin = options.autoPanMargin !== undefined ?
- options.autoPanMargin : 20;
- /**
- * @protected
- * @type {{bottom_: string,
- * left_: string,
- * right_: string,
- * top_: string,
- * visible: boolean}}
- */
- this.rendered = {
- bottom_: '',
- left_: '',
- right_: '',
- top_: '',
- visible: true
- };
- /**
- * @protected
- * @type {?ol.EventsKey}
- */
- this.mapPostrenderListenerKey = null;
- ol.events.listen(
- this, ol.Object.getChangeEventType(ol.Overlay.Property.ELEMENT),
- this.handleElementChanged, this);
- ol.events.listen(
- this, ol.Object.getChangeEventType(ol.Overlay.Property.MAP),
- this.handleMapChanged, this);
- ol.events.listen(
- this, ol.Object.getChangeEventType(ol.Overlay.Property.OFFSET),
- this.handleOffsetChanged, this);
- ol.events.listen(
- this, ol.Object.getChangeEventType(ol.Overlay.Property.POSITION),
- this.handlePositionChanged, this);
- ol.events.listen(
- this, ol.Object.getChangeEventType(ol.Overlay.Property.POSITIONING),
- this.handlePositioningChanged, this);
- if (options.element !== undefined) {
- this.setElement(options.element);
- }
- this.setOffset(options.offset !== undefined ? options.offset : [0, 0]);
- this.setPositioning(options.positioning !== undefined ?
- /** @type {ol.OverlayPositioning} */ (options.positioning) :
- ol.OverlayPositioning.TOP_LEFT);
- if (options.position !== undefined) {
- this.setPosition(options.position);
- }
- };
- ol.inherits(ol.Overlay, ol.Object);
- /**
- * Get the DOM element of this overlay.
- * @return {Element|undefined} The Element containing the overlay.
- * @observable
- * @api
- */
- ol.Overlay.prototype.getElement = function() {
- return /** @type {Element|undefined} */ (
- this.get(ol.Overlay.Property.ELEMENT));
- };
- /**
- * Get the overlay identifier which is set on constructor.
- * @return {number|string|undefined} Id.
- * @api
- */
- ol.Overlay.prototype.getId = function() {
- return this.id;
- };
- /**
- * Get the map associated with this overlay.
- * @return {ol.PluggableMap|undefined} The map that the overlay is part of.
- * @observable
- * @api
- */
- ol.Overlay.prototype.getMap = function() {
- return /** @type {ol.PluggableMap|undefined} */ (
- this.get(ol.Overlay.Property.MAP));
- };
- /**
- * Get the offset of this overlay.
- * @return {Array.<number>} The offset.
- * @observable
- * @api
- */
- ol.Overlay.prototype.getOffset = function() {
- return /** @type {Array.<number>} */ (
- this.get(ol.Overlay.Property.OFFSET));
- };
- /**
- * Get the current position of this overlay.
- * @return {ol.Coordinate|undefined} The spatial point that the overlay is
- * anchored at.
- * @observable
- * @api
- */
- ol.Overlay.prototype.getPosition = function() {
- return /** @type {ol.Coordinate|undefined} */ (
- this.get(ol.Overlay.Property.POSITION));
- };
- /**
- * Get the current positioning of this overlay.
- * @return {ol.OverlayPositioning} How the overlay is positioned
- * relative to its point on the map.
- * @observable
- * @api
- */
- ol.Overlay.prototype.getPositioning = function() {
- return /** @type {ol.OverlayPositioning} */ (
- this.get(ol.Overlay.Property.POSITIONING));
- };
- /**
- * @protected
- */
- ol.Overlay.prototype.handleElementChanged = function() {
- ol.dom.removeChildren(this.element);
- var element = this.getElement();
- if (element) {
- this.element.appendChild(element);
- }
- };
- /**
- * @protected
- */
- ol.Overlay.prototype.handleMapChanged = function() {
- if (this.mapPostrenderListenerKey) {
- ol.dom.removeNode(this.element);
- ol.events.unlistenByKey(this.mapPostrenderListenerKey);
- this.mapPostrenderListenerKey = null;
- }
- var map = this.getMap();
- if (map) {
- this.mapPostrenderListenerKey = ol.events.listen(map,
- ol.MapEventType.POSTRENDER, this.render, this);
- this.updatePixelPosition();
- var container = this.stopEvent ?
- map.getOverlayContainerStopEvent() : map.getOverlayContainer();
- if (this.insertFirst) {
- container.insertBefore(this.element, container.childNodes[0] || null);
- } else {
- container.appendChild(this.element);
- }
- }
- };
- /**
- * @protected
- */
- ol.Overlay.prototype.render = function() {
- this.updatePixelPosition();
- };
- /**
- * @protected
- */
- ol.Overlay.prototype.handleOffsetChanged = function() {
- this.updatePixelPosition();
- };
- /**
- * @protected
- */
- ol.Overlay.prototype.handlePositionChanged = function() {
- this.updatePixelPosition();
- if (this.get(ol.Overlay.Property.POSITION) && this.autoPan) {
- this.panIntoView();
- }
- };
- /**
- * @protected
- */
- ol.Overlay.prototype.handlePositioningChanged = function() {
- this.updatePixelPosition();
- };
- /**
- * Set the DOM element to be associated with this overlay.
- * @param {Element|undefined} element The Element containing the overlay.
- * @observable
- * @api
- */
- ol.Overlay.prototype.setElement = function(element) {
- this.set(ol.Overlay.Property.ELEMENT, element);
- };
- /**
- * Set the map to be associated with this overlay.
- * @param {ol.PluggableMap|undefined} map The map that the overlay is part of.
- * @observable
- * @api
- */
- ol.Overlay.prototype.setMap = function(map) {
- this.set(ol.Overlay.Property.MAP, map);
- };
- /**
- * Set the offset for this overlay.
- * @param {Array.<number>} offset Offset.
- * @observable
- * @api
- */
- ol.Overlay.prototype.setOffset = function(offset) {
- this.set(ol.Overlay.Property.OFFSET, offset);
- };
- /**
- * Set the position for this overlay. If the position is `undefined` the
- * overlay is hidden.
- * @param {ol.Coordinate|undefined} position The spatial point that the overlay
- * is anchored at.
- * @observable
- * @api
- */
- ol.Overlay.prototype.setPosition = function(position) {
- this.set(ol.Overlay.Property.POSITION, position);
- };
- /**
- * Pan the map so that the overlay is entirely visible in the current viewport
- * (if necessary).
- * @protected
- */
- ol.Overlay.prototype.panIntoView = function() {
- var map = this.getMap();
- if (!map || !map.getTargetElement()) {
- return;
- }
- var mapRect = this.getRect(map.getTargetElement(), map.getSize());
- var element = /** @type {!Element} */ (this.getElement());
- var overlayRect = this.getRect(element,
- [ol.dom.outerWidth(element), ol.dom.outerHeight(element)]);
- var margin = this.autoPanMargin;
- if (!ol.extent.containsExtent(mapRect, overlayRect)) {
- // the overlay is not completely inside the viewport, so pan the map
- var offsetLeft = overlayRect[0] - mapRect[0];
- var offsetRight = mapRect[2] - overlayRect[2];
- var offsetTop = overlayRect[1] - mapRect[1];
- var offsetBottom = mapRect[3] - overlayRect[3];
- var delta = [0, 0];
- if (offsetLeft < 0) {
- // move map to the left
- delta[0] = offsetLeft - margin;
- } else if (offsetRight < 0) {
- // move map to the right
- delta[0] = Math.abs(offsetRight) + margin;
- }
- if (offsetTop < 0) {
- // move map up
- delta[1] = offsetTop - margin;
- } else if (offsetBottom < 0) {
- // move map down
- delta[1] = Math.abs(offsetBottom) + margin;
- }
- if (delta[0] !== 0 || delta[1] !== 0) {
- var center = /** @type {ol.Coordinate} */ (map.getView().getCenter());
- var centerPx = map.getPixelFromCoordinate(center);
- var newCenterPx = [
- centerPx[0] + delta[0],
- centerPx[1] + delta[1]
- ];
- map.getView().animate({
- center: map.getCoordinateFromPixel(newCenterPx),
- duration: this.autoPanAnimation.duration,
- easing: this.autoPanAnimation.easing
- });
- }
- }
- };
- /**
- * Get the extent of an element relative to the document
- * @param {Element|undefined} element The element.
- * @param {ol.Size|undefined} size The size of the element.
- * @return {ol.Extent} The extent.
- * @protected
- */
- ol.Overlay.prototype.getRect = function(element, size) {
- var box = element.getBoundingClientRect();
- var offsetX = box.left + window.pageXOffset;
- var offsetY = box.top + window.pageYOffset;
- return [
- offsetX,
- offsetY,
- offsetX + size[0],
- offsetY + size[1]
- ];
- };
- /**
- * Set the positioning for this overlay.
- * @param {ol.OverlayPositioning} positioning how the overlay is
- * positioned relative to its point on the map.
- * @observable
- * @api
- */
- ol.Overlay.prototype.setPositioning = function(positioning) {
- this.set(ol.Overlay.Property.POSITIONING, positioning);
- };
- /**
- * Modify the visibility of the element.
- * @param {boolean} visible Element visibility.
- * @protected
- */
- ol.Overlay.prototype.setVisible = function(visible) {
- if (this.rendered.visible !== visible) {
- this.element.style.display = visible ? '' : 'none';
- this.rendered.visible = visible;
- }
- };
- /**
- * Update pixel position.
- * @protected
- */
- ol.Overlay.prototype.updatePixelPosition = function() {
- var map = this.getMap();
- var position = this.getPosition();
- if (!map || !map.isRendered() || !position) {
- this.setVisible(false);
- return;
- }
- var pixel = map.getPixelFromCoordinate(position);
- var mapSize = map.getSize();
- this.updateRenderedPosition(pixel, mapSize);
- };
- /**
- * @param {ol.Pixel} pixel The pixel location.
- * @param {ol.Size|undefined} mapSize The map size.
- * @protected
- */
- ol.Overlay.prototype.updateRenderedPosition = function(pixel, mapSize) {
- var style = this.element.style;
- var offset = this.getOffset();
- var positioning = this.getPositioning();
- this.setVisible(true);
- var offsetX = offset[0];
- var offsetY = offset[1];
- if (positioning == ol.OverlayPositioning.BOTTOM_RIGHT ||
- positioning == ol.OverlayPositioning.CENTER_RIGHT ||
- positioning == ol.OverlayPositioning.TOP_RIGHT) {
- if (this.rendered.left_ !== '') {
- this.rendered.left_ = style.left = '';
- }
- var right = Math.round(mapSize[0] - pixel[0] - offsetX) + 'px';
- if (this.rendered.right_ != right) {
- this.rendered.right_ = style.right = right;
- }
- } else {
- if (this.rendered.right_ !== '') {
- this.rendered.right_ = style.right = '';
- }
- if (positioning == ol.OverlayPositioning.BOTTOM_CENTER ||
- positioning == ol.OverlayPositioning.CENTER_CENTER ||
- positioning == ol.OverlayPositioning.TOP_CENTER) {
- offsetX -= this.element.offsetWidth / 2;
- }
- var left = Math.round(pixel[0] + offsetX) + 'px';
- if (this.rendered.left_ != left) {
- this.rendered.left_ = style.left = left;
- }
- }
- if (positioning == ol.OverlayPositioning.BOTTOM_LEFT ||
- positioning == ol.OverlayPositioning.BOTTOM_CENTER ||
- positioning == ol.OverlayPositioning.BOTTOM_RIGHT) {
- if (this.rendered.top_ !== '') {
- this.rendered.top_ = style.top = '';
- }
- var bottom = Math.round(mapSize[1] - pixel[1] - offsetY) + 'px';
- if (this.rendered.bottom_ != bottom) {
- this.rendered.bottom_ = style.bottom = bottom;
- }
- } else {
- if (this.rendered.bottom_ !== '') {
- this.rendered.bottom_ = style.bottom = '';
- }
- if (positioning == ol.OverlayPositioning.CENTER_LEFT ||
- positioning == ol.OverlayPositioning.CENTER_CENTER ||
- positioning == ol.OverlayPositioning.CENTER_RIGHT) {
- offsetY -= this.element.offsetHeight / 2;
- }
- var top = Math.round(pixel[1] + offsetY) + 'px';
- if (this.rendered.top_ != top) {
- this.rendered.top_ = style.top = top;
- }
- }
- };
- /**
- * returns the options this Overlay has been created with
- * @public
- * @return {olx.OverlayOptions} overlay options
- */
- ol.Overlay.prototype.getOptions = function() {
- return this.options;
- };
- /**
- * @enum {string}
- * @protected
- */
- ol.Overlay.Property = {
- ELEMENT: 'element',
- MAP: 'map',
- OFFSET: 'offset',
- POSITION: 'position',
- POSITIONING: 'positioning'
- };
- goog.provide('ol.control.OverviewMap');
- goog.require('ol');
- goog.require('ol.Collection');
- goog.require('ol.PluggableMap');
- goog.require('ol.MapEventType');
- goog.require('ol.MapProperty');
- goog.require('ol.Object');
- goog.require('ol.ObjectEventType');
- goog.require('ol.Overlay');
- goog.require('ol.OverlayPositioning');
- goog.require('ol.ViewProperty');
- goog.require('ol.control.Control');
- goog.require('ol.coordinate');
- goog.require('ol.css');
- goog.require('ol.dom');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.extent');
- /**
- * Create a new control with a map acting as an overview map for an other
- * defined map.
- * @constructor
- * @extends {ol.control.Control}
- * @param {olx.control.OverviewMapOptions=} opt_options OverviewMap options.
- * @api
- */
- ol.control.OverviewMap = function(opt_options) {
- var options = opt_options ? opt_options : {};
- /**
- * @type {boolean}
- * @private
- */
- this.collapsed_ = options.collapsed !== undefined ? options.collapsed : true;
- /**
- * @private
- * @type {boolean}
- */
- this.collapsible_ = options.collapsible !== undefined ?
- options.collapsible : true;
- if (!this.collapsible_) {
- this.collapsed_ = false;
- }
- var className = options.className !== undefined ? options.className : 'ol-overviewmap';
- var tipLabel = options.tipLabel !== undefined ? options.tipLabel : 'Overview map';
- var collapseLabel = options.collapseLabel !== undefined ? options.collapseLabel : '\u00AB';
- if (typeof collapseLabel === 'string') {
- /**
- * @private
- * @type {Node}
- */
- this.collapseLabel_ = document.createElement('span');
- this.collapseLabel_.textContent = collapseLabel;
- } else {
- this.collapseLabel_ = collapseLabel;
- }
- var label = options.label !== undefined ? options.label : '\u00BB';
- if (typeof label === 'string') {
- /**
- * @private
- * @type {Node}
- */
- this.label_ = document.createElement('span');
- this.label_.textContent = label;
- } else {
- this.label_ = label;
- }
- var activeLabel = (this.collapsible_ && !this.collapsed_) ?
- this.collapseLabel_ : this.label_;
- var button = document.createElement('button');
- button.setAttribute('type', 'button');
- button.title = tipLabel;
- button.appendChild(activeLabel);
- ol.events.listen(button, ol.events.EventType.CLICK,
- this.handleClick_, this);
- /**
- * @type {Element}
- * @private
- */
- this.ovmapDiv_ = document.createElement('DIV');
- this.ovmapDiv_.className = 'ol-overviewmap-map';
- /**
- * @type {ol.PluggableMap}
- * @private
- */
- this.ovmap_ = new ol.PluggableMap({
- controls: new ol.Collection(),
- interactions: new ol.Collection(),
- view: options.view
- });
- var ovmap = this.ovmap_;
- if (options.layers) {
- options.layers.forEach(
- /**
- * @param {ol.layer.Layer} layer Layer.
- */
- function(layer) {
- ovmap.addLayer(layer);
- }, this);
- }
- var box = document.createElement('DIV');
- box.className = 'ol-overviewmap-box';
- box.style.boxSizing = 'border-box';
- /**
- * @type {ol.Overlay}
- * @private
- */
- this.boxOverlay_ = new ol.Overlay({
- position: [0, 0],
- positioning: ol.OverlayPositioning.BOTTOM_LEFT,
- element: box
- });
- this.ovmap_.addOverlay(this.boxOverlay_);
- var cssClasses = className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' +
- ol.css.CLASS_CONTROL +
- (this.collapsed_ && this.collapsible_ ? ' ol-collapsed' : '') +
- (this.collapsible_ ? '' : ' ol-uncollapsible');
- var element = document.createElement('div');
- element.className = cssClasses;
- element.appendChild(this.ovmapDiv_);
- element.appendChild(button);
- var render = options.render ? options.render : ol.control.OverviewMap.render;
- ol.control.Control.call(this, {
- element: element,
- render: render,
- target: options.target
- });
- /* Interactive map */
- var scope = this;
- var overlay = this.boxOverlay_;
- var overlayBox = this.boxOverlay_.getElement();
- /* Functions definition */
- var computeDesiredMousePosition = function(mousePosition) {
- return {
- clientX: mousePosition.clientX - (overlayBox.offsetWidth / 2),
- clientY: mousePosition.clientY + (overlayBox.offsetHeight / 2)
- };
- };
- var move = function(event) {
- var coordinates = ovmap.getEventCoordinate(computeDesiredMousePosition(event));
- overlay.setPosition(coordinates);
- };
- var endMoving = function(event) {
- var coordinates = ovmap.getEventCoordinate(event);
- scope.getMap().getView().setCenter(coordinates);
- window.removeEventListener('mousemove', move);
- window.removeEventListener('mouseup', endMoving);
- };
- /* Binding */
- overlayBox.addEventListener('mousedown', function() {
- window.addEventListener('mousemove', move);
- window.addEventListener('mouseup', endMoving);
- });
- };
- ol.inherits(ol.control.OverviewMap, ol.control.Control);
- /**
- * @inheritDoc
- * @api
- */
- ol.control.OverviewMap.prototype.setMap = function(map) {
- var oldMap = this.getMap();
- if (map === oldMap) {
- return;
- }
- if (oldMap) {
- var oldView = oldMap.getView();
- if (oldView) {
- this.unbindView_(oldView);
- }
- this.ovmap_.setTarget(null);
- }
- ol.control.Control.prototype.setMap.call(this, map);
- if (map) {
- this.ovmap_.setTarget(this.ovmapDiv_);
- this.listenerKeys.push(ol.events.listen(
- map, ol.ObjectEventType.PROPERTYCHANGE,
- this.handleMapPropertyChange_, this));
- // TODO: to really support map switching, this would need to be reworked
- if (this.ovmap_.getLayers().getLength() === 0) {
- this.ovmap_.setLayerGroup(map.getLayerGroup());
- }
- var view = map.getView();
- if (view) {
- this.bindView_(view);
- if (view.isDef()) {
- this.ovmap_.updateSize();
- this.resetExtent_();
- }
- }
- }
- };
- /**
- * Handle map property changes. This only deals with changes to the map's view.
- * @param {ol.Object.Event} event The propertychange event.
- * @private
- */
- ol.control.OverviewMap.prototype.handleMapPropertyChange_ = function(event) {
- if (event.key === ol.MapProperty.VIEW) {
- var oldView = /** @type {ol.View} */ (event.oldValue);
- if (oldView) {
- this.unbindView_(oldView);
- }
- var newView = this.getMap().getView();
- this.bindView_(newView);
- }
- };
- /**
- * Register listeners for view property changes.
- * @param {ol.View} view The view.
- * @private
- */
- ol.control.OverviewMap.prototype.bindView_ = function(view) {
- ol.events.listen(view,
- ol.Object.getChangeEventType(ol.ViewProperty.ROTATION),
- this.handleRotationChanged_, this);
- };
- /**
- * Unregister listeners for view property changes.
- * @param {ol.View} view The view.
- * @private
- */
- ol.control.OverviewMap.prototype.unbindView_ = function(view) {
- ol.events.unlisten(view,
- ol.Object.getChangeEventType(ol.ViewProperty.ROTATION),
- this.handleRotationChanged_, this);
- };
- /**
- * Handle rotation changes to the main map.
- * TODO: This should rotate the extent rectrangle instead of the
- * overview map's view.
- * @private
- */
- ol.control.OverviewMap.prototype.handleRotationChanged_ = function() {
- this.ovmap_.getView().setRotation(this.getMap().getView().getRotation());
- };
- /**
- * Update the overview map element.
- * @param {ol.MapEvent} mapEvent Map event.
- * @this {ol.control.OverviewMap}
- * @api
- */
- ol.control.OverviewMap.render = function(mapEvent) {
- this.validateExtent_();
- this.updateBox_();
- };
- /**
- * Reset the overview map extent if the box size (width or
- * height) is less than the size of the overview map size times minRatio
- * or is greater than the size of the overview size times maxRatio.
- *
- * If the map extent was not reset, the box size can fits in the defined
- * ratio sizes. This method then checks if is contained inside the overview
- * map current extent. If not, recenter the overview map to the current
- * main map center location.
- * @private
- */
- ol.control.OverviewMap.prototype.validateExtent_ = function() {
- var map = this.getMap();
- var ovmap = this.ovmap_;
- if (!map.isRendered() || !ovmap.isRendered()) {
- return;
- }
- var mapSize = /** @type {ol.Size} */ (map.getSize());
- var view = map.getView();
- var extent = view.calculateExtent(mapSize);
- var ovmapSize = /** @type {ol.Size} */ (ovmap.getSize());
- var ovview = ovmap.getView();
- var ovextent = ovview.calculateExtent(ovmapSize);
- var topLeftPixel =
- ovmap.getPixelFromCoordinate(ol.extent.getTopLeft(extent));
- var bottomRightPixel =
- ovmap.getPixelFromCoordinate(ol.extent.getBottomRight(extent));
- var boxWidth = Math.abs(topLeftPixel[0] - bottomRightPixel[0]);
- var boxHeight = Math.abs(topLeftPixel[1] - bottomRightPixel[1]);
- var ovmapWidth = ovmapSize[0];
- var ovmapHeight = ovmapSize[1];
- if (boxWidth < ovmapWidth * ol.OVERVIEWMAP_MIN_RATIO ||
- boxHeight < ovmapHeight * ol.OVERVIEWMAP_MIN_RATIO ||
- boxWidth > ovmapWidth * ol.OVERVIEWMAP_MAX_RATIO ||
- boxHeight > ovmapHeight * ol.OVERVIEWMAP_MAX_RATIO) {
- this.resetExtent_();
- } else if (!ol.extent.containsExtent(ovextent, extent)) {
- this.recenter_();
- }
- };
- /**
- * Reset the overview map extent to half calculated min and max ratio times
- * the extent of the main map.
- * @private
- */
- ol.control.OverviewMap.prototype.resetExtent_ = function() {
- if (ol.OVERVIEWMAP_MAX_RATIO === 0 || ol.OVERVIEWMAP_MIN_RATIO === 0) {
- return;
- }
- var map = this.getMap();
- var ovmap = this.ovmap_;
- var mapSize = /** @type {ol.Size} */ (map.getSize());
- var view = map.getView();
- var extent = view.calculateExtent(mapSize);
- var ovview = ovmap.getView();
- // get how many times the current map overview could hold different
- // box sizes using the min and max ratio, pick the step in the middle used
- // to calculate the extent from the main map to set it to the overview map,
- var steps = Math.log(
- ol.OVERVIEWMAP_MAX_RATIO / ol.OVERVIEWMAP_MIN_RATIO) / Math.LN2;
- var ratio = 1 / (Math.pow(2, steps / 2) * ol.OVERVIEWMAP_MIN_RATIO);
- ol.extent.scaleFromCenter(extent, ratio);
- ovview.fit(extent);
- };
- /**
- * Set the center of the overview map to the map center without changing its
- * resolution.
- * @private
- */
- ol.control.OverviewMap.prototype.recenter_ = function() {
- var map = this.getMap();
- var ovmap = this.ovmap_;
- var view = map.getView();
- var ovview = ovmap.getView();
- ovview.setCenter(view.getCenter());
- };
- /**
- * Update the box using the main map extent
- * @private
- */
- ol.control.OverviewMap.prototype.updateBox_ = function() {
- var map = this.getMap();
- var ovmap = this.ovmap_;
- if (!map.isRendered() || !ovmap.isRendered()) {
- return;
- }
- var mapSize = /** @type {ol.Size} */ (map.getSize());
- var view = map.getView();
- var ovview = ovmap.getView();
- var rotation = view.getRotation();
- var overlay = this.boxOverlay_;
- var box = this.boxOverlay_.getElement();
- var extent = view.calculateExtent(mapSize);
- var ovresolution = ovview.getResolution();
- var bottomLeft = ol.extent.getBottomLeft(extent);
- var topRight = ol.extent.getTopRight(extent);
- // set position using bottom left coordinates
- var rotateBottomLeft = this.calculateCoordinateRotate_(rotation, bottomLeft);
- overlay.setPosition(rotateBottomLeft);
- // set box size calculated from map extent size and overview map resolution
- if (box) {
- box.style.width = Math.abs((bottomLeft[0] - topRight[0]) / ovresolution) + 'px';
- box.style.height = Math.abs((topRight[1] - bottomLeft[1]) / ovresolution) + 'px';
- }
- };
- /**
- * @param {number} rotation Target rotation.
- * @param {ol.Coordinate} coordinate Coordinate.
- * @return {ol.Coordinate|undefined} Coordinate for rotation and center anchor.
- * @private
- */
- ol.control.OverviewMap.prototype.calculateCoordinateRotate_ = function(
- rotation, coordinate) {
- var coordinateRotate;
- var map = this.getMap();
- var view = map.getView();
- var currentCenter = view.getCenter();
- if (currentCenter) {
- coordinateRotate = [
- coordinate[0] - currentCenter[0],
- coordinate[1] - currentCenter[1]
- ];
- ol.coordinate.rotate(coordinateRotate, rotation);
- ol.coordinate.add(coordinateRotate, currentCenter);
- }
- return coordinateRotate;
- };
- /**
- * @param {Event} event The event to handle
- * @private
- */
- ol.control.OverviewMap.prototype.handleClick_ = function(event) {
- event.preventDefault();
- this.handleToggle_();
- };
- /**
- * @private
- */
- ol.control.OverviewMap.prototype.handleToggle_ = function() {
- this.element.classList.toggle('ol-collapsed');
- if (this.collapsed_) {
- ol.dom.replaceNode(this.collapseLabel_, this.label_);
- } else {
- ol.dom.replaceNode(this.label_, this.collapseLabel_);
- }
- this.collapsed_ = !this.collapsed_;
- // manage overview map if it had not been rendered before and control
- // is expanded
- var ovmap = this.ovmap_;
- if (!this.collapsed_ && !ovmap.isRendered()) {
- ovmap.updateSize();
- this.resetExtent_();
- ol.events.listenOnce(ovmap, ol.MapEventType.POSTRENDER,
- function(event) {
- this.updateBox_();
- },
- this);
- }
- };
- /**
- * Return `true` if the overview map is collapsible, `false` otherwise.
- * @return {boolean} True if the widget is collapsible.
- * @api
- */
- ol.control.OverviewMap.prototype.getCollapsible = function() {
- return this.collapsible_;
- };
- /**
- * Set whether the overview map should be collapsible.
- * @param {boolean} collapsible True if the widget is collapsible.
- * @api
- */
- ol.control.OverviewMap.prototype.setCollapsible = function(collapsible) {
- if (this.collapsible_ === collapsible) {
- return;
- }
- this.collapsible_ = collapsible;
- this.element.classList.toggle('ol-uncollapsible');
- if (!collapsible && this.collapsed_) {
- this.handleToggle_();
- }
- };
- /**
- * Collapse or expand the overview map according to the passed parameter. Will
- * not do anything if the overview map isn't collapsible or if the current
- * collapsed state is already the one requested.
- * @param {boolean} collapsed True if the widget is collapsed.
- * @api
- */
- ol.control.OverviewMap.prototype.setCollapsed = function(collapsed) {
- if (!this.collapsible_ || this.collapsed_ === collapsed) {
- return;
- }
- this.handleToggle_();
- };
- /**
- * Determine if the overview map is collapsed.
- * @return {boolean} The overview map is collapsed.
- * @api
- */
- ol.control.OverviewMap.prototype.getCollapsed = function() {
- return this.collapsed_;
- };
- /**
- * Return the overview map.
- * @return {ol.PluggableMap} Overview map.
- * @api
- */
- ol.control.OverviewMap.prototype.getOverviewMap = function() {
- return this.ovmap_;
- };
- goog.provide('ol.control.ScaleLineUnits');
- /**
- * Units for the scale line. Supported values are `'degrees'`, `'imperial'`,
- * `'nautical'`, `'metric'`, `'us'`.
- * @enum {string}
- */
- ol.control.ScaleLineUnits = {
- DEGREES: 'degrees',
- IMPERIAL: 'imperial',
- NAUTICAL: 'nautical',
- METRIC: 'metric',
- US: 'us'
- };
- goog.provide('ol.control.ScaleLine');
- goog.require('ol');
- goog.require('ol.Object');
- goog.require('ol.asserts');
- goog.require('ol.control.Control');
- goog.require('ol.control.ScaleLineUnits');
- goog.require('ol.css');
- goog.require('ol.events');
- goog.require('ol.proj');
- goog.require('ol.proj.Units');
- /**
- * @classdesc
- * A control displaying rough y-axis distances, calculated for the center of the
- * viewport. For conformal projections (e.g. EPSG:3857, the default view
- * projection in OpenLayers), the scale is valid for all directions.
- * No scale line will be shown when the y-axis distance of a pixel at the
- * viewport center cannot be calculated in the view projection.
- * By default the scale line will show in the bottom left portion of the map,
- * but this can be changed by using the css selector `.ol-scale-line`.
- *
- * @constructor
- * @extends {ol.control.Control}
- * @param {olx.control.ScaleLineOptions=} opt_options Scale line options.
- * @api
- */
- ol.control.ScaleLine = function(opt_options) {
- var options = opt_options ? opt_options : {};
- var className = options.className !== undefined ? options.className : 'ol-scale-line';
- /**
- * @private
- * @type {Element}
- */
- this.innerElement_ = document.createElement('DIV');
- this.innerElement_.className = className + '-inner';
- /**
- * @private
- * @type {Element}
- */
- this.element_ = document.createElement('DIV');
- this.element_.className = className + ' ' + ol.css.CLASS_UNSELECTABLE;
- this.element_.appendChild(this.innerElement_);
- /**
- * @private
- * @type {?olx.ViewState}
- */
- this.viewState_ = null;
- /**
- * @private
- * @type {number}
- */
- this.minWidth_ = options.minWidth !== undefined ? options.minWidth : 64;
- /**
- * @private
- * @type {boolean}
- */
- this.renderedVisible_ = false;
- /**
- * @private
- * @type {number|undefined}
- */
- this.renderedWidth_ = undefined;
- /**
- * @private
- * @type {string}
- */
- this.renderedHTML_ = '';
- var render = options.render ? options.render : ol.control.ScaleLine.render;
- ol.control.Control.call(this, {
- element: this.element_,
- render: render,
- target: options.target
- });
- ol.events.listen(
- this, ol.Object.getChangeEventType(ol.control.ScaleLine.Property_.UNITS),
- this.handleUnitsChanged_, this);
- this.setUnits(/** @type {ol.control.ScaleLineUnits} */ (options.units) ||
- ol.control.ScaleLineUnits.METRIC);
- };
- ol.inherits(ol.control.ScaleLine, ol.control.Control);
- /**
- * @const
- * @type {Array.<number>}
- */
- ol.control.ScaleLine.LEADING_DIGITS = [1, 2, 5];
- /**
- * Return the units to use in the scale line.
- * @return {ol.control.ScaleLineUnits|undefined} The units to use in the scale
- * line.
- * @observable
- * @api
- */
- ol.control.ScaleLine.prototype.getUnits = function() {
- return /** @type {ol.control.ScaleLineUnits|undefined} */ (
- this.get(ol.control.ScaleLine.Property_.UNITS));
- };
- /**
- * Update the scale line element.
- * @param {ol.MapEvent} mapEvent Map event.
- * @this {ol.control.ScaleLine}
- * @api
- */
- ol.control.ScaleLine.render = function(mapEvent) {
- var frameState = mapEvent.frameState;
- if (!frameState) {
- this.viewState_ = null;
- } else {
- this.viewState_ = frameState.viewState;
- }
- this.updateElement_();
- };
- /**
- * @private
- */
- ol.control.ScaleLine.prototype.handleUnitsChanged_ = function() {
- this.updateElement_();
- };
- /**
- * Set the units to use in the scale line.
- * @param {ol.control.ScaleLineUnits} units The units to use in the scale line.
- * @observable
- * @api
- */
- ol.control.ScaleLine.prototype.setUnits = function(units) {
- this.set(ol.control.ScaleLine.Property_.UNITS, units);
- };
- /**
- * @private
- */
- ol.control.ScaleLine.prototype.updateElement_ = function() {
- var viewState = this.viewState_;
- if (!viewState) {
- if (this.renderedVisible_) {
- this.element_.style.display = 'none';
- this.renderedVisible_ = false;
- }
- return;
- }
- var center = viewState.center;
- var projection = viewState.projection;
- var units = this.getUnits();
- var pointResolutionUnits = units == ol.control.ScaleLineUnits.DEGREES ?
- ol.proj.Units.DEGREES :
- ol.proj.Units.METERS;
- var pointResolution =
- ol.proj.getPointResolution(projection, viewState.resolution, center, pointResolutionUnits);
- if (units != ol.control.ScaleLineUnits.DEGREES) {
- pointResolution *= projection.getMetersPerUnit();
- }
- var nominalCount = this.minWidth_ * pointResolution;
- var suffix = '';
- if (units == ol.control.ScaleLineUnits.DEGREES) {
- var metersPerDegree = ol.proj.METERS_PER_UNIT[ol.proj.Units.DEGREES];
- if (projection.getUnits() == ol.proj.Units.DEGREES) {
- nominalCount *= metersPerDegree;
- } else {
- pointResolution /= metersPerDegree;
- }
- if (nominalCount < metersPerDegree / 60) {
- suffix = '\u2033'; // seconds
- pointResolution *= 3600;
- } else if (nominalCount < metersPerDegree) {
- suffix = '\u2032'; // minutes
- pointResolution *= 60;
- } else {
- suffix = '\u00b0'; // degrees
- }
- } else if (units == ol.control.ScaleLineUnits.IMPERIAL) {
- if (nominalCount < 0.9144) {
- suffix = 'in';
- pointResolution /= 0.0254;
- } else if (nominalCount < 1609.344) {
- suffix = 'ft';
- pointResolution /= 0.3048;
- } else {
- suffix = 'mi';
- pointResolution /= 1609.344;
- }
- } else if (units == ol.control.ScaleLineUnits.NAUTICAL) {
- pointResolution /= 1852;
- suffix = 'nm';
- } else if (units == ol.control.ScaleLineUnits.METRIC) {
- if (nominalCount < 0.001) {
- suffix = 'μm';
- pointResolution *= 1000000;
- } else if (nominalCount < 1) {
- suffix = 'mm';
- pointResolution *= 1000;
- } else if (nominalCount < 1000) {
- suffix = 'm';
- } else {
- suffix = 'km';
- pointResolution /= 1000;
- }
- } else if (units == ol.control.ScaleLineUnits.US) {
- if (nominalCount < 0.9144) {
- suffix = 'in';
- pointResolution *= 39.37;
- } else if (nominalCount < 1609.344) {
- suffix = 'ft';
- pointResolution /= 0.30480061;
- } else {
- suffix = 'mi';
- pointResolution /= 1609.3472;
- }
- } else {
- ol.asserts.assert(false, 33); // Invalid units
- }
- var i = 3 * Math.floor(
- Math.log(this.minWidth_ * pointResolution) / Math.log(10));
- var count, width;
- while (true) {
- count = ol.control.ScaleLine.LEADING_DIGITS[((i % 3) + 3) % 3] *
- Math.pow(10, Math.floor(i / 3));
- width = Math.round(count / pointResolution);
- if (isNaN(width)) {
- this.element_.style.display = 'none';
- this.renderedVisible_ = false;
- return;
- } else if (width >= this.minWidth_) {
- break;
- }
- ++i;
- }
- var html = count + ' ' + suffix;
- if (this.renderedHTML_ != html) {
- this.innerElement_.innerHTML = html;
- this.renderedHTML_ = html;
- }
- if (this.renderedWidth_ != width) {
- this.innerElement_.style.width = width + 'px';
- this.renderedWidth_ = width;
- }
- if (!this.renderedVisible_) {
- this.element_.style.display = '';
- this.renderedVisible_ = true;
- }
- };
- /**
- * @enum {string}
- * @private
- */
- ol.control.ScaleLine.Property_ = {
- UNITS: 'units'
- };
- // FIXME should possibly show tooltip when dragging?
- goog.provide('ol.control.ZoomSlider');
- goog.require('ol');
- goog.require('ol.ViewHint');
- goog.require('ol.control.Control');
- goog.require('ol.css');
- goog.require('ol.easing');
- goog.require('ol.events');
- goog.require('ol.events.Event');
- goog.require('ol.events.EventType');
- goog.require('ol.math');
- goog.require('ol.pointer.EventType');
- goog.require('ol.pointer.PointerEventHandler');
- /**
- * @classdesc
- * A slider type of control for zooming.
- *
- * Example:
- *
- * map.addControl(new ol.control.ZoomSlider());
- *
- * @constructor
- * @extends {ol.control.Control}
- * @param {olx.control.ZoomSliderOptions=} opt_options Zoom slider options.
- * @api
- */
- ol.control.ZoomSlider = function(opt_options) {
- var options = opt_options ? opt_options : {};
- /**
- * Will hold the current resolution of the view.
- *
- * @type {number|undefined}
- * @private
- */
- this.currentResolution_ = undefined;
- /**
- * The direction of the slider. Will be determined from actual display of the
- * container and defaults to ol.control.ZoomSlider.Direction_.VERTICAL.
- *
- * @type {ol.control.ZoomSlider.Direction_}
- * @private
- */
- this.direction_ = ol.control.ZoomSlider.Direction_.VERTICAL;
- /**
- * @type {boolean}
- * @private
- */
- this.dragging_;
- /**
- * @type {number}
- * @private
- */
- this.heightLimit_ = 0;
- /**
- * @type {number}
- * @private
- */
- this.widthLimit_ = 0;
- /**
- * @type {number|undefined}
- * @private
- */
- this.previousX_;
- /**
- * @type {number|undefined}
- * @private
- */
- this.previousY_;
- /**
- * The calculated thumb size (border box plus margins). Set when initSlider_
- * is called.
- * @type {ol.Size}
- * @private
- */
- this.thumbSize_ = null;
- /**
- * Whether the slider is initialized.
- * @type {boolean}
- * @private
- */
- this.sliderInitialized_ = false;
- /**
- * @type {number}
- * @private
- */
- this.duration_ = options.duration !== undefined ? options.duration : 200;
- var className = options.className !== undefined ? options.className : 'ol-zoomslider';
- var thumbElement = document.createElement('button');
- thumbElement.setAttribute('type', 'button');
- thumbElement.className = className + '-thumb ' + ol.css.CLASS_UNSELECTABLE;
- var containerElement = document.createElement('div');
- containerElement.className = className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' + ol.css.CLASS_CONTROL;
- containerElement.appendChild(thumbElement);
- /**
- * @type {ol.pointer.PointerEventHandler}
- * @private
- */
- this.dragger_ = new ol.pointer.PointerEventHandler(containerElement);
- ol.events.listen(this.dragger_, ol.pointer.EventType.POINTERDOWN,
- this.handleDraggerStart_, this);
- ol.events.listen(this.dragger_, ol.pointer.EventType.POINTERMOVE,
- this.handleDraggerDrag_, this);
- ol.events.listen(this.dragger_, ol.pointer.EventType.POINTERUP,
- this.handleDraggerEnd_, this);
- ol.events.listen(containerElement, ol.events.EventType.CLICK,
- this.handleContainerClick_, this);
- ol.events.listen(thumbElement, ol.events.EventType.CLICK,
- ol.events.Event.stopPropagation);
- var render = options.render ? options.render : ol.control.ZoomSlider.render;
- ol.control.Control.call(this, {
- element: containerElement,
- render: render
- });
- };
- ol.inherits(ol.control.ZoomSlider, ol.control.Control);
- /**
- * @inheritDoc
- */
- ol.control.ZoomSlider.prototype.disposeInternal = function() {
- this.dragger_.dispose();
- ol.control.Control.prototype.disposeInternal.call(this);
- };
- /**
- * The enum for available directions.
- *
- * @enum {number}
- * @private
- */
- ol.control.ZoomSlider.Direction_ = {
- VERTICAL: 0,
- HORIZONTAL: 1
- };
- /**
- * @inheritDoc
- */
- ol.control.ZoomSlider.prototype.setMap = function(map) {
- ol.control.Control.prototype.setMap.call(this, map);
- if (map) {
- map.render();
- }
- };
- /**
- * Initializes the slider element. This will determine and set this controls
- * direction_ and also constrain the dragging of the thumb to always be within
- * the bounds of the container.
- *
- * @private
- */
- ol.control.ZoomSlider.prototype.initSlider_ = function() {
- var container = this.element;
- var containerSize = {
- width: container.offsetWidth, height: container.offsetHeight
- };
- var thumb = container.firstElementChild;
- var computedStyle = getComputedStyle(thumb);
- var thumbWidth = thumb.offsetWidth +
- parseFloat(computedStyle['marginRight']) +
- parseFloat(computedStyle['marginLeft']);
- var thumbHeight = thumb.offsetHeight +
- parseFloat(computedStyle['marginTop']) +
- parseFloat(computedStyle['marginBottom']);
- this.thumbSize_ = [thumbWidth, thumbHeight];
- if (containerSize.width > containerSize.height) {
- this.direction_ = ol.control.ZoomSlider.Direction_.HORIZONTAL;
- this.widthLimit_ = containerSize.width - thumbWidth;
- } else {
- this.direction_ = ol.control.ZoomSlider.Direction_.VERTICAL;
- this.heightLimit_ = containerSize.height - thumbHeight;
- }
- this.sliderInitialized_ = true;
- };
- /**
- * Update the zoomslider element.
- * @param {ol.MapEvent} mapEvent Map event.
- * @this {ol.control.ZoomSlider}
- * @api
- */
- ol.control.ZoomSlider.render = function(mapEvent) {
- if (!mapEvent.frameState) {
- return;
- }
- if (!this.sliderInitialized_) {
- this.initSlider_();
- }
- var res = mapEvent.frameState.viewState.resolution;
- if (res !== this.currentResolution_) {
- this.currentResolution_ = res;
- this.setThumbPosition_(res);
- }
- };
- /**
- * @param {Event} event The browser event to handle.
- * @private
- */
- ol.control.ZoomSlider.prototype.handleContainerClick_ = function(event) {
- var view = this.getMap().getView();
- var relativePosition = this.getRelativePosition_(
- event.offsetX - this.thumbSize_[0] / 2,
- event.offsetY - this.thumbSize_[1] / 2);
- var resolution = this.getResolutionForPosition_(relativePosition);
- view.animate({
- resolution: view.constrainResolution(resolution),
- duration: this.duration_,
- easing: ol.easing.easeOut
- });
- };
- /**
- * Handle dragger start events.
- * @param {ol.pointer.PointerEvent} event The drag event.
- * @private
- */
- ol.control.ZoomSlider.prototype.handleDraggerStart_ = function(event) {
- if (!this.dragging_ && event.originalEvent.target === this.element.firstElementChild) {
- this.getMap().getView().setHint(ol.ViewHint.INTERACTING, 1);
- this.previousX_ = event.clientX;
- this.previousY_ = event.clientY;
- this.dragging_ = true;
- }
- };
- /**
- * Handle dragger drag events.
- *
- * @param {ol.pointer.PointerEvent|Event} event The drag event.
- * @private
- */
- ol.control.ZoomSlider.prototype.handleDraggerDrag_ = function(event) {
- if (this.dragging_) {
- var element = this.element.firstElementChild;
- var deltaX = event.clientX - this.previousX_ + parseInt(element.style.left, 10);
- var deltaY = event.clientY - this.previousY_ + parseInt(element.style.top, 10);
- var relativePosition = this.getRelativePosition_(deltaX, deltaY);
- this.currentResolution_ = this.getResolutionForPosition_(relativePosition);
- this.getMap().getView().setResolution(this.currentResolution_);
- this.setThumbPosition_(this.currentResolution_);
- this.previousX_ = event.clientX;
- this.previousY_ = event.clientY;
- }
- };
- /**
- * Handle dragger end events.
- * @param {ol.pointer.PointerEvent|Event} event The drag event.
- * @private
- */
- ol.control.ZoomSlider.prototype.handleDraggerEnd_ = function(event) {
- if (this.dragging_) {
- var view = this.getMap().getView();
- view.setHint(ol.ViewHint.INTERACTING, -1);
- view.animate({
- resolution: view.constrainResolution(this.currentResolution_),
- duration: this.duration_,
- easing: ol.easing.easeOut
- });
- this.dragging_ = false;
- this.previousX_ = undefined;
- this.previousY_ = undefined;
- }
- };
- /**
- * Positions the thumb inside its container according to the given resolution.
- *
- * @param {number} res The res.
- * @private
- */
- ol.control.ZoomSlider.prototype.setThumbPosition_ = function(res) {
- var position = this.getPositionForResolution_(res);
- var thumb = this.element.firstElementChild;
- if (this.direction_ == ol.control.ZoomSlider.Direction_.HORIZONTAL) {
- thumb.style.left = this.widthLimit_ * position + 'px';
- } else {
- thumb.style.top = this.heightLimit_ * position + 'px';
- }
- };
- /**
- * Calculates the relative position of the thumb given x and y offsets. The
- * relative position scales from 0 to 1. The x and y offsets are assumed to be
- * in pixel units within the dragger limits.
- *
- * @param {number} x Pixel position relative to the left of the slider.
- * @param {number} y Pixel position relative to the top of the slider.
- * @return {number} The relative position of the thumb.
- * @private
- */
- ol.control.ZoomSlider.prototype.getRelativePosition_ = function(x, y) {
- var amount;
- if (this.direction_ === ol.control.ZoomSlider.Direction_.HORIZONTAL) {
- amount = x / this.widthLimit_;
- } else {
- amount = y / this.heightLimit_;
- }
- return ol.math.clamp(amount, 0, 1);
- };
- /**
- * Calculates the corresponding resolution of the thumb given its relative
- * position (where 0 is the minimum and 1 is the maximum).
- *
- * @param {number} position The relative position of the thumb.
- * @return {number} The corresponding resolution.
- * @private
- */
- ol.control.ZoomSlider.prototype.getResolutionForPosition_ = function(position) {
- var fn = this.getMap().getView().getResolutionForValueFunction();
- return fn(1 - position);
- };
- /**
- * Determines the relative position of the slider for the given resolution. A
- * relative position of 0 corresponds to the minimum view resolution. A
- * relative position of 1 corresponds to the maximum view resolution.
- *
- * @param {number} res The resolution.
- * @return {number} The relative position value (between 0 and 1).
- * @private
- */
- ol.control.ZoomSlider.prototype.getPositionForResolution_ = function(res) {
- var fn = this.getMap().getView().getValueForResolutionFunction();
- return 1 - fn(res);
- };
- goog.provide('ol.control.ZoomToExtent');
- goog.require('ol');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.control.Control');
- goog.require('ol.css');
- /**
- * @classdesc
- * A button control which, when pressed, changes the map view to a specific
- * extent. To style this control use the css selector `.ol-zoom-extent`.
- *
- * @constructor
- * @extends {ol.control.Control}
- * @param {olx.control.ZoomToExtentOptions=} opt_options Options.
- * @api
- */
- ol.control.ZoomToExtent = function(opt_options) {
- var options = opt_options ? opt_options : {};
- /**
- * @type {ol.Extent}
- * @protected
- */
- this.extent = options.extent ? options.extent : null;
- var className = options.className !== undefined ? options.className :
- 'ol-zoom-extent';
- var label = options.label !== undefined ? options.label : 'E';
- var tipLabel = options.tipLabel !== undefined ?
- options.tipLabel : 'Fit to extent';
- var button = document.createElement('button');
- button.setAttribute('type', 'button');
- button.title = tipLabel;
- button.appendChild(
- typeof label === 'string' ? document.createTextNode(label) : label
- );
- ol.events.listen(button, ol.events.EventType.CLICK,
- this.handleClick_, this);
- var cssClasses = className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' +
- ol.css.CLASS_CONTROL;
- var element = document.createElement('div');
- element.className = cssClasses;
- element.appendChild(button);
- ol.control.Control.call(this, {
- element: element,
- target: options.target
- });
- };
- ol.inherits(ol.control.ZoomToExtent, ol.control.Control);
- /**
- * @param {Event} event The event to handle
- * @private
- */
- ol.control.ZoomToExtent.prototype.handleClick_ = function(event) {
- event.preventDefault();
- this.handleZoomToExtent();
- };
- /**
- * @protected
- */
- ol.control.ZoomToExtent.prototype.handleZoomToExtent = function() {
- var map = this.getMap();
- var view = map.getView();
- var extent = !this.extent ? view.getProjection().getExtent() : this.extent;
- view.fit(extent);
- };
- goog.provide('ol.DeviceOrientation');
- goog.require('ol.events');
- goog.require('ol');
- goog.require('ol.Object');
- goog.require('ol.has');
- goog.require('ol.math');
- /**
- * @classdesc
- * The ol.DeviceOrientation class provides access to information from
- * DeviceOrientation events. See the [HTML 5 DeviceOrientation Specification](
- * http://www.w3.org/TR/orientation-event/) for more details.
- *
- * Many new computers, and especially mobile phones
- * and tablets, provide hardware support for device orientation. Web
- * developers targeting mobile devices will be especially interested in this
- * class.
- *
- * Device orientation data are relative to a common starting point. For mobile
- * devices, the starting point is to lay your phone face up on a table with the
- * top of the phone pointing north. This represents the zero state. All
- * angles are then relative to this state. For computers, it is the same except
- * the screen is open at 90 degrees.
- *
- * Device orientation is reported as three angles - `alpha`, `beta`, and
- * `gamma` - relative to the starting position along the three planar axes X, Y
- * and Z. The X axis runs from the left edge to the right edge through the
- * middle of the device. Similarly, the Y axis runs from the bottom to the top
- * of the device through the middle. The Z axis runs from the back to the front
- * through the middle. In the starting position, the X axis points to the
- * right, the Y axis points away from you and the Z axis points straight up
- * from the device lying flat.
- *
- * The three angles representing the device orientation are relative to the
- * three axes. `alpha` indicates how much the device has been rotated around the
- * Z axis, which is commonly interpreted as the compass heading (see note
- * below). `beta` indicates how much the device has been rotated around the X
- * axis, or how much it is tilted from front to back. `gamma` indicates how
- * much the device has been rotated around the Y axis, or how much it is tilted
- * from left to right.
- *
- * For most browsers, the `alpha` value returns the compass heading so if the
- * device points north, it will be 0. With Safari on iOS, the 0 value of
- * `alpha` is calculated from when device orientation was first requested.
- * ol.DeviceOrientation provides the `heading` property which normalizes this
- * behavior across all browsers for you.
- *
- * It is important to note that the HTML 5 DeviceOrientation specification
- * indicates that `alpha`, `beta` and `gamma` are in degrees while the
- * equivalent properties in ol.DeviceOrientation are in radians for consistency
- * with all other uses of angles throughout OpenLayers.
- *
- * To get notified of device orientation changes, register a listener for the
- * generic `change` event on your `ol.DeviceOrientation` instance.
- *
- * @see {@link http://www.w3.org/TR/orientation-event/}
- *
- * @deprecated This class is deprecated and will removed in the next major release.
- *
- * @constructor
- * @extends {ol.Object}
- * @param {olx.DeviceOrientationOptions=} opt_options Options.
- * @api
- */
- ol.DeviceOrientation = function(opt_options) {
- ol.Object.call(this);
- var options = opt_options ? opt_options : {};
- /**
- * @private
- * @type {?ol.EventsKey}
- */
- this.listenerKey_ = null;
- ol.events.listen(this,
- ol.Object.getChangeEventType(ol.DeviceOrientation.Property_.TRACKING),
- this.handleTrackingChanged_, this);
- this.setTracking(options.tracking !== undefined ? options.tracking : false);
- };
- ol.inherits(ol.DeviceOrientation, ol.Object);
- /**
- * @inheritDoc
- */
- ol.DeviceOrientation.prototype.disposeInternal = function() {
- this.setTracking(false);
- ol.Object.prototype.disposeInternal.call(this);
- };
- /**
- * @private
- * @param {Event} originalEvent Event.
- */
- ol.DeviceOrientation.prototype.orientationChange_ = function(originalEvent) {
- var event = /** @type {DeviceOrientationEvent} */ (originalEvent);
- if (event.alpha !== null) {
- var alpha = ol.math.toRadians(event.alpha);
- this.set(ol.DeviceOrientation.Property_.ALPHA, alpha);
- // event.absolute is undefined in iOS.
- if (typeof event.absolute === 'boolean' && event.absolute) {
- this.set(ol.DeviceOrientation.Property_.HEADING, alpha);
- } else if (typeof event.webkitCompassHeading === 'number' &&
- event.webkitCompassAccuracy != -1) {
- var heading = ol.math.toRadians(event.webkitCompassHeading);
- this.set(ol.DeviceOrientation.Property_.HEADING, heading);
- }
- }
- if (event.beta !== null) {
- this.set(ol.DeviceOrientation.Property_.BETA,
- ol.math.toRadians(event.beta));
- }
- if (event.gamma !== null) {
- this.set(ol.DeviceOrientation.Property_.GAMMA,
- ol.math.toRadians(event.gamma));
- }
- this.changed();
- };
- /**
- * Rotation around the device z-axis (in radians).
- * @return {number|undefined} The euler angle in radians of the device from the
- * standard Z axis.
- * @observable
- * @api
- */
- ol.DeviceOrientation.prototype.getAlpha = function() {
- return /** @type {number|undefined} */ (
- this.get(ol.DeviceOrientation.Property_.ALPHA));
- };
- /**
- * Rotation around the device x-axis (in radians).
- * @return {number|undefined} The euler angle in radians of the device from the
- * planar X axis.
- * @observable
- * @api
- */
- ol.DeviceOrientation.prototype.getBeta = function() {
- return /** @type {number|undefined} */ (
- this.get(ol.DeviceOrientation.Property_.BETA));
- };
- /**
- * Rotation around the device y-axis (in radians).
- * @return {number|undefined} The euler angle in radians of the device from the
- * planar Y axis.
- * @observable
- * @api
- */
- ol.DeviceOrientation.prototype.getGamma = function() {
- return /** @type {number|undefined} */ (
- this.get(ol.DeviceOrientation.Property_.GAMMA));
- };
- /**
- * The heading of the device relative to north (in radians).
- * @return {number|undefined} The heading of the device relative to north, in
- * radians, normalizing for different browser behavior.
- * @observable
- * @api
- */
- ol.DeviceOrientation.prototype.getHeading = function() {
- return /** @type {number|undefined} */ (
- this.get(ol.DeviceOrientation.Property_.HEADING));
- };
- /**
- * Determine if orientation is being tracked.
- * @return {boolean} Changes in device orientation are being tracked.
- * @observable
- * @api
- */
- ol.DeviceOrientation.prototype.getTracking = function() {
- return /** @type {boolean} */ (
- this.get(ol.DeviceOrientation.Property_.TRACKING));
- };
- /**
- * @private
- */
- ol.DeviceOrientation.prototype.handleTrackingChanged_ = function() {
- if (ol.has.DEVICE_ORIENTATION) {
- var tracking = this.getTracking();
- if (tracking && !this.listenerKey_) {
- this.listenerKey_ = ol.events.listen(window, 'deviceorientation',
- this.orientationChange_, this);
- } else if (!tracking && this.listenerKey_ !== null) {
- ol.events.unlistenByKey(this.listenerKey_);
- this.listenerKey_ = null;
- }
- }
- };
- /**
- * Enable or disable tracking of device orientation events.
- * @param {boolean} tracking The status of tracking changes to alpha, beta and
- * gamma. If true, changes are tracked and reported immediately.
- * @observable
- * @api
- */
- ol.DeviceOrientation.prototype.setTracking = function(tracking) {
- this.set(ol.DeviceOrientation.Property_.TRACKING, tracking);
- };
- /**
- * @enum {string}
- * @private
- */
- ol.DeviceOrientation.Property_ = {
- ALPHA: 'alpha',
- BETA: 'beta',
- GAMMA: 'gamma',
- HEADING: 'heading',
- TRACKING: 'tracking'
- };
- goog.provide('ol.style.Image');
- /**
- * @classdesc
- * A base class used for creating subclasses and not instantiated in
- * apps. Base class for {@link ol.style.Icon}, {@link ol.style.Circle} and
- * {@link ol.style.RegularShape}.
- *
- * @constructor
- * @abstract
- * @param {ol.StyleImageOptions} options Options.
- * @api
- */
- ol.style.Image = function(options) {
- /**
- * @private
- * @type {number}
- */
- this.opacity_ = options.opacity;
- /**
- * @private
- * @type {boolean}
- */
- this.rotateWithView_ = options.rotateWithView;
- /**
- * @private
- * @type {number}
- */
- this.rotation_ = options.rotation;
- /**
- * @private
- * @type {number}
- */
- this.scale_ = options.scale;
- /**
- * @private
- * @type {boolean}
- */
- this.snapToPixel_ = options.snapToPixel;
- };
- /**
- * Get the symbolizer opacity.
- * @return {number} Opacity.
- * @api
- */
- ol.style.Image.prototype.getOpacity = function() {
- return this.opacity_;
- };
- /**
- * Determine whether the symbolizer rotates with the map.
- * @return {boolean} Rotate with map.
- * @api
- */
- ol.style.Image.prototype.getRotateWithView = function() {
- return this.rotateWithView_;
- };
- /**
- * Get the symoblizer rotation.
- * @return {number} Rotation.
- * @api
- */
- ol.style.Image.prototype.getRotation = function() {
- return this.rotation_;
- };
- /**
- * Get the symbolizer scale.
- * @return {number} Scale.
- * @api
- */
- ol.style.Image.prototype.getScale = function() {
- return this.scale_;
- };
- /**
- * Determine whether the symbolizer should be snapped to a pixel.
- * @return {boolean} The symbolizer should snap to a pixel.
- * @api
- */
- ol.style.Image.prototype.getSnapToPixel = function() {
- return this.snapToPixel_;
- };
- /**
- * Get the anchor point in pixels. The anchor determines the center point for the
- * symbolizer.
- * @abstract
- * @return {Array.<number>} Anchor.
- */
- ol.style.Image.prototype.getAnchor = function() {};
- /**
- * Get the image element for the symbolizer.
- * @abstract
- * @param {number} pixelRatio Pixel ratio.
- * @return {HTMLCanvasElement|HTMLVideoElement|Image} Image element.
- */
- ol.style.Image.prototype.getImage = function(pixelRatio) {};
- /**
- * @abstract
- * @param {number} pixelRatio Pixel ratio.
- * @return {HTMLCanvasElement|HTMLVideoElement|Image} Image element.
- */
- ol.style.Image.prototype.getHitDetectionImage = function(pixelRatio) {};
- /**
- * @abstract
- * @return {ol.ImageState} Image state.
- */
- ol.style.Image.prototype.getImageState = function() {};
- /**
- * @abstract
- * @return {ol.Size} Image size.
- */
- ol.style.Image.prototype.getImageSize = function() {};
- /**
- * @abstract
- * @return {ol.Size} Size of the hit-detection image.
- */
- ol.style.Image.prototype.getHitDetectionImageSize = function() {};
- /**
- * Get the origin of the symbolizer.
- * @abstract
- * @return {Array.<number>} Origin.
- */
- ol.style.Image.prototype.getOrigin = function() {};
- /**
- * Get the size of the symbolizer (in pixels).
- * @abstract
- * @return {ol.Size} Size.
- */
- ol.style.Image.prototype.getSize = function() {};
- /**
- * Set the opacity.
- *
- * @param {number} opacity Opacity.
- * @api
- */
- ol.style.Image.prototype.setOpacity = function(opacity) {
- this.opacity_ = opacity;
- };
- /**
- * Set whether to rotate the style with the view.
- *
- * @param {boolean} rotateWithView Rotate with map.
- */
- ol.style.Image.prototype.setRotateWithView = function(rotateWithView) {
- this.rotateWithView_ = rotateWithView;
- };
- /**
- * Set the rotation.
- *
- * @param {number} rotation Rotation.
- * @api
- */
- ol.style.Image.prototype.setRotation = function(rotation) {
- this.rotation_ = rotation;
- };
- /**
- * Set the scale.
- *
- * @param {number} scale Scale.
- * @api
- */
- ol.style.Image.prototype.setScale = function(scale) {
- this.scale_ = scale;
- };
- /**
- * Set whether to snap the image to the closest pixel.
- *
- * @param {boolean} snapToPixel Snap to pixel?
- */
- ol.style.Image.prototype.setSnapToPixel = function(snapToPixel) {
- this.snapToPixel_ = snapToPixel;
- };
- /**
- * @abstract
- * @param {function(this: T, ol.events.Event)} listener Listener function.
- * @param {T} thisArg Value to use as `this` when executing `listener`.
- * @return {ol.EventsKey|undefined} Listener key.
- * @template T
- */
- ol.style.Image.prototype.listenImageChange = function(listener, thisArg) {};
- /**
- * Load not yet loaded URI.
- * @abstract
- */
- ol.style.Image.prototype.load = function() {};
- /**
- * @abstract
- * @param {function(this: T, ol.events.Event)} listener Listener function.
- * @param {T} thisArg Value to use as `this` when executing `listener`.
- * @template T
- */
- ol.style.Image.prototype.unlistenImageChange = function(listener, thisArg) {};
- goog.provide('ol.style.RegularShape');
- goog.require('ol');
- goog.require('ol.colorlike');
- goog.require('ol.dom');
- goog.require('ol.has');
- goog.require('ol.ImageState');
- goog.require('ol.render.canvas');
- goog.require('ol.style.Image');
- /**
- * @classdesc
- * Set regular shape style for vector features. The resulting shape will be
- * a regular polygon when `radius` is provided, or a star when `radius1` and
- * `radius2` are provided.
- *
- * @constructor
- * @param {olx.style.RegularShapeOptions} options Options.
- * @extends {ol.style.Image}
- * @api
- */
- ol.style.RegularShape = function(options) {
- /**
- * @private
- * @type {Array.<string>}
- */
- this.checksums_ = null;
- /**
- * @private
- * @type {HTMLCanvasElement}
- */
- this.canvas_ = null;
- /**
- * @private
- * @type {HTMLCanvasElement}
- */
- this.hitDetectionCanvas_ = null;
- /**
- * @private
- * @type {ol.style.Fill}
- */
- this.fill_ = options.fill !== undefined ? options.fill : null;
- /**
- * @private
- * @type {Array.<number>}
- */
- this.origin_ = [0, 0];
- /**
- * @private
- * @type {number}
- */
- this.points_ = options.points;
- /**
- * @protected
- * @type {number}
- */
- this.radius_ = /** @type {number} */ (options.radius !== undefined ?
- options.radius : options.radius1);
- /**
- * @private
- * @type {number|undefined}
- */
- this.radius2_ = options.radius2;
- /**
- * @private
- * @type {number}
- */
- this.angle_ = options.angle !== undefined ? options.angle : 0;
- /**
- * @private
- * @type {ol.style.Stroke}
- */
- this.stroke_ = options.stroke !== undefined ? options.stroke : null;
- /**
- * @private
- * @type {Array.<number>}
- */
- this.anchor_ = null;
- /**
- * @private
- * @type {ol.Size}
- */
- this.size_ = null;
- /**
- * @private
- * @type {ol.Size}
- */
- this.imageSize_ = null;
- /**
- * @private
- * @type {ol.Size}
- */
- this.hitDetectionImageSize_ = null;
- /**
- * @protected
- * @type {ol.style.AtlasManager|undefined}
- */
- this.atlasManager_ = options.atlasManager;
- this.render_(this.atlasManager_);
- /**
- * @type {boolean}
- */
- var snapToPixel = options.snapToPixel !== undefined ?
- options.snapToPixel : true;
- /**
- * @type {boolean}
- */
- var rotateWithView = options.rotateWithView !== undefined ?
- options.rotateWithView : false;
- ol.style.Image.call(this, {
- opacity: 1,
- rotateWithView: rotateWithView,
- rotation: options.rotation !== undefined ? options.rotation : 0,
- scale: 1,
- snapToPixel: snapToPixel
- });
- };
- ol.inherits(ol.style.RegularShape, ol.style.Image);
- /**
- * Clones the style. If an atlasmanager was provided to the original style it will be used in the cloned style, too.
- * @return {ol.style.RegularShape} The cloned style.
- * @api
- */
- ol.style.RegularShape.prototype.clone = function() {
- var style = new ol.style.RegularShape({
- fill: this.getFill() ? this.getFill().clone() : undefined,
- points: this.getPoints(),
- radius: this.getRadius(),
- radius2: this.getRadius2(),
- angle: this.getAngle(),
- snapToPixel: this.getSnapToPixel(),
- stroke: this.getStroke() ? this.getStroke().clone() : undefined,
- rotation: this.getRotation(),
- rotateWithView: this.getRotateWithView(),
- atlasManager: this.atlasManager_
- });
- style.setOpacity(this.getOpacity());
- style.setScale(this.getScale());
- return style;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.style.RegularShape.prototype.getAnchor = function() {
- return this.anchor_;
- };
- /**
- * Get the angle used in generating the shape.
- * @return {number} Shape's rotation in radians.
- * @api
- */
- ol.style.RegularShape.prototype.getAngle = function() {
- return this.angle_;
- };
- /**
- * Get the fill style for the shape.
- * @return {ol.style.Fill} Fill style.
- * @api
- */
- ol.style.RegularShape.prototype.getFill = function() {
- return this.fill_;
- };
- /**
- * @inheritDoc
- */
- ol.style.RegularShape.prototype.getHitDetectionImage = function(pixelRatio) {
- return this.hitDetectionCanvas_;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.style.RegularShape.prototype.getImage = function(pixelRatio) {
- return this.canvas_;
- };
- /**
- * @inheritDoc
- */
- ol.style.RegularShape.prototype.getImageSize = function() {
- return this.imageSize_;
- };
- /**
- * @inheritDoc
- */
- ol.style.RegularShape.prototype.getHitDetectionImageSize = function() {
- return this.hitDetectionImageSize_;
- };
- /**
- * @inheritDoc
- */
- ol.style.RegularShape.prototype.getImageState = function() {
- return ol.ImageState.LOADED;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.style.RegularShape.prototype.getOrigin = function() {
- return this.origin_;
- };
- /**
- * Get the number of points for generating the shape.
- * @return {number} Number of points for stars and regular polygons.
- * @api
- */
- ol.style.RegularShape.prototype.getPoints = function() {
- return this.points_;
- };
- /**
- * Get the (primary) radius for the shape.
- * @return {number} Radius.
- * @api
- */
- ol.style.RegularShape.prototype.getRadius = function() {
- return this.radius_;
- };
- /**
- * Get the secondary radius for the shape.
- * @return {number|undefined} Radius2.
- * @api
- */
- ol.style.RegularShape.prototype.getRadius2 = function() {
- return this.radius2_;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.style.RegularShape.prototype.getSize = function() {
- return this.size_;
- };
- /**
- * Get the stroke style for the shape.
- * @return {ol.style.Stroke} Stroke style.
- * @api
- */
- ol.style.RegularShape.prototype.getStroke = function() {
- return this.stroke_;
- };
- /**
- * @inheritDoc
- */
- ol.style.RegularShape.prototype.listenImageChange = function(listener, thisArg) {};
- /**
- * @inheritDoc
- */
- ol.style.RegularShape.prototype.load = function() {};
- /**
- * @inheritDoc
- */
- ol.style.RegularShape.prototype.unlistenImageChange = function(listener, thisArg) {};
- /**
- * @protected
- * @param {ol.style.AtlasManager|undefined} atlasManager An atlas manager.
- */
- ol.style.RegularShape.prototype.render_ = function(atlasManager) {
- var imageSize;
- var lineCap = '';
- var lineJoin = '';
- var miterLimit = 0;
- var lineDash = null;
- var lineDashOffset = 0;
- var strokeStyle;
- var strokeWidth = 0;
- if (this.stroke_) {
- strokeStyle = this.stroke_.getColor();
- if (strokeStyle === null) {
- strokeStyle = ol.render.canvas.defaultStrokeStyle;
- }
- strokeStyle = ol.colorlike.asColorLike(strokeStyle);
- strokeWidth = this.stroke_.getWidth();
- if (strokeWidth === undefined) {
- strokeWidth = ol.render.canvas.defaultLineWidth;
- }
- lineDash = this.stroke_.getLineDash();
- lineDashOffset = this.stroke_.getLineDashOffset();
- if (!ol.has.CANVAS_LINE_DASH) {
- lineDash = null;
- lineDashOffset = 0;
- }
- lineJoin = this.stroke_.getLineJoin();
- if (lineJoin === undefined) {
- lineJoin = ol.render.canvas.defaultLineJoin;
- }
- lineCap = this.stroke_.getLineCap();
- if (lineCap === undefined) {
- lineCap = ol.render.canvas.defaultLineCap;
- }
- miterLimit = this.stroke_.getMiterLimit();
- if (miterLimit === undefined) {
- miterLimit = ol.render.canvas.defaultMiterLimit;
- }
- }
- var size = 2 * (this.radius_ + strokeWidth) + 1;
- /** @type {ol.RegularShapeRenderOptions} */
- var renderOptions = {
- strokeStyle: strokeStyle,
- strokeWidth: strokeWidth,
- size: size,
- lineCap: lineCap,
- lineDash: lineDash,
- lineDashOffset: lineDashOffset,
- lineJoin: lineJoin,
- miterLimit: miterLimit
- };
- if (atlasManager === undefined) {
- // no atlas manager is used, create a new canvas
- var context = ol.dom.createCanvasContext2D(size, size);
- this.canvas_ = context.canvas;
- // canvas.width and height are rounded to the closest integer
- size = this.canvas_.width;
- imageSize = size;
- this.draw_(renderOptions, context, 0, 0);
- this.createHitDetectionCanvas_(renderOptions);
- } else {
- // an atlas manager is used, add the symbol to an atlas
- size = Math.round(size);
- var hasCustomHitDetectionImage = !this.fill_;
- var renderHitDetectionCallback;
- if (hasCustomHitDetectionImage) {
- // render the hit-detection image into a separate atlas image
- renderHitDetectionCallback =
- this.drawHitDetectionCanvas_.bind(this, renderOptions);
- }
- var id = this.getChecksum();
- var info = atlasManager.add(
- id, size, size, this.draw_.bind(this, renderOptions),
- renderHitDetectionCallback);
- this.canvas_ = info.image;
- this.origin_ = [info.offsetX, info.offsetY];
- imageSize = info.image.width;
- if (hasCustomHitDetectionImage) {
- this.hitDetectionCanvas_ = info.hitImage;
- this.hitDetectionImageSize_ =
- [info.hitImage.width, info.hitImage.height];
- } else {
- this.hitDetectionCanvas_ = this.canvas_;
- this.hitDetectionImageSize_ = [imageSize, imageSize];
- }
- }
- this.anchor_ = [size / 2, size / 2];
- this.size_ = [size, size];
- this.imageSize_ = [imageSize, imageSize];
- };
- /**
- * @private
- * @param {ol.RegularShapeRenderOptions} renderOptions Render options.
- * @param {CanvasRenderingContext2D} context The rendering context.
- * @param {number} x The origin for the symbol (x).
- * @param {number} y The origin for the symbol (y).
- */
- ol.style.RegularShape.prototype.draw_ = function(renderOptions, context, x, y) {
- var i, angle0, radiusC;
- // reset transform
- context.setTransform(1, 0, 0, 1, 0, 0);
- // then move to (x, y)
- context.translate(x, y);
- context.beginPath();
- var points = this.points_;
- if (points === Infinity) {
- context.arc(
- renderOptions.size / 2, renderOptions.size / 2,
- this.radius_, 0, 2 * Math.PI, true);
- } else {
- var radius2 = (this.radius2_ !== undefined) ? this.radius2_
- : this.radius_;
- if (radius2 !== this.radius_) {
- points = 2 * points;
- }
- for (i = 0; i <= points; i++) {
- angle0 = i * 2 * Math.PI / points - Math.PI / 2 + this.angle_;
- radiusC = i % 2 === 0 ? this.radius_ : radius2;
- context.lineTo(renderOptions.size / 2 + radiusC * Math.cos(angle0),
- renderOptions.size / 2 + radiusC * Math.sin(angle0));
- }
- }
- if (this.fill_) {
- var color = this.fill_.getColor();
- if (color === null) {
- color = ol.render.canvas.defaultFillStyle;
- }
- context.fillStyle = ol.colorlike.asColorLike(color);
- context.fill();
- }
- if (this.stroke_) {
- context.strokeStyle = renderOptions.strokeStyle;
- context.lineWidth = renderOptions.strokeWidth;
- if (renderOptions.lineDash) {
- context.setLineDash(renderOptions.lineDash);
- context.lineDashOffset = renderOptions.lineDashOffset;
- }
- context.lineCap = renderOptions.lineCap;
- context.lineJoin = renderOptions.lineJoin;
- context.miterLimit = renderOptions.miterLimit;
- context.stroke();
- }
- context.closePath();
- };
- /**
- * @private
- * @param {ol.RegularShapeRenderOptions} renderOptions Render options.
- */
- ol.style.RegularShape.prototype.createHitDetectionCanvas_ = function(renderOptions) {
- this.hitDetectionImageSize_ = [renderOptions.size, renderOptions.size];
- if (this.fill_) {
- this.hitDetectionCanvas_ = this.canvas_;
- return;
- }
- // if no fill style is set, create an extra hit-detection image with a
- // default fill style
- var context = ol.dom.createCanvasContext2D(renderOptions.size, renderOptions.size);
- this.hitDetectionCanvas_ = context.canvas;
- this.drawHitDetectionCanvas_(renderOptions, context, 0, 0);
- };
- /**
- * @private
- * @param {ol.RegularShapeRenderOptions} renderOptions Render options.
- * @param {CanvasRenderingContext2D} context The context.
- * @param {number} x The origin for the symbol (x).
- * @param {number} y The origin for the symbol (y).
- */
- ol.style.RegularShape.prototype.drawHitDetectionCanvas_ = function(renderOptions, context, x, y) {
- // reset transform
- context.setTransform(1, 0, 0, 1, 0, 0);
- // then move to (x, y)
- context.translate(x, y);
- context.beginPath();
- var points = this.points_;
- if (points === Infinity) {
- context.arc(
- renderOptions.size / 2, renderOptions.size / 2,
- this.radius_, 0, 2 * Math.PI, true);
- } else {
- var radius2 = (this.radius2_ !== undefined) ? this.radius2_
- : this.radius_;
- if (radius2 !== this.radius_) {
- points = 2 * points;
- }
- var i, radiusC, angle0;
- for (i = 0; i <= points; i++) {
- angle0 = i * 2 * Math.PI / points - Math.PI / 2 + this.angle_;
- radiusC = i % 2 === 0 ? this.radius_ : radius2;
- context.lineTo(renderOptions.size / 2 + radiusC * Math.cos(angle0),
- renderOptions.size / 2 + radiusC * Math.sin(angle0));
- }
- }
- context.fillStyle = ol.render.canvas.defaultFillStyle;
- context.fill();
- if (this.stroke_) {
- context.strokeStyle = renderOptions.strokeStyle;
- context.lineWidth = renderOptions.strokeWidth;
- if (renderOptions.lineDash) {
- context.setLineDash(renderOptions.lineDash);
- context.lineDashOffset = renderOptions.lineDashOffset;
- }
- context.stroke();
- }
- context.closePath();
- };
- /**
- * @return {string} The checksum.
- */
- ol.style.RegularShape.prototype.getChecksum = function() {
- var strokeChecksum = this.stroke_ ?
- this.stroke_.getChecksum() : '-';
- var fillChecksum = this.fill_ ?
- this.fill_.getChecksum() : '-';
- var recalculate = !this.checksums_ ||
- (strokeChecksum != this.checksums_[1] ||
- fillChecksum != this.checksums_[2] ||
- this.radius_ != this.checksums_[3] ||
- this.radius2_ != this.checksums_[4] ||
- this.angle_ != this.checksums_[5] ||
- this.points_ != this.checksums_[6]);
- if (recalculate) {
- var checksum = 'r' + strokeChecksum + fillChecksum +
- (this.radius_ !== undefined ? this.radius_.toString() : '-') +
- (this.radius2_ !== undefined ? this.radius2_.toString() : '-') +
- (this.angle_ !== undefined ? this.angle_.toString() : '-') +
- (this.points_ !== undefined ? this.points_.toString() : '-');
- this.checksums_ = [checksum, strokeChecksum, fillChecksum,
- this.radius_, this.radius2_, this.angle_, this.points_];
- }
- return this.checksums_[0];
- };
- goog.provide('ol.style.Circle');
- goog.require('ol');
- goog.require('ol.style.RegularShape');
- /**
- * @classdesc
- * Set circle style for vector features.
- *
- * @constructor
- * @param {olx.style.CircleOptions=} opt_options Options.
- * @extends {ol.style.RegularShape}
- * @api
- */
- ol.style.Circle = function(opt_options) {
- var options = opt_options || {};
- ol.style.RegularShape.call(this, {
- points: Infinity,
- fill: options.fill,
- radius: options.radius,
- snapToPixel: options.snapToPixel,
- stroke: options.stroke,
- atlasManager: options.atlasManager
- });
- };
- ol.inherits(ol.style.Circle, ol.style.RegularShape);
- /**
- * Clones the style. If an atlasmanager was provided to the original style it will be used in the cloned style, too.
- * @return {ol.style.Circle} The cloned style.
- * @override
- * @api
- */
- ol.style.Circle.prototype.clone = function() {
- var style = new ol.style.Circle({
- fill: this.getFill() ? this.getFill().clone() : undefined,
- stroke: this.getStroke() ? this.getStroke().clone() : undefined,
- radius: this.getRadius(),
- snapToPixel: this.getSnapToPixel(),
- atlasManager: this.atlasManager_
- });
- style.setOpacity(this.getOpacity());
- style.setScale(this.getScale());
- return style;
- };
- /**
- * Set the circle radius.
- *
- * @param {number} radius Circle radius.
- * @api
- */
- ol.style.Circle.prototype.setRadius = function(radius) {
- this.radius_ = radius;
- this.render_(this.atlasManager_);
- };
- goog.provide('ol.style.Fill');
- goog.require('ol');
- goog.require('ol.color');
- /**
- * @classdesc
- * Set fill style for vector features.
- *
- * @constructor
- * @param {olx.style.FillOptions=} opt_options Options.
- * @api
- */
- ol.style.Fill = function(opt_options) {
- var options = opt_options || {};
- /**
- * @private
- * @type {ol.Color|ol.ColorLike}
- */
- this.color_ = options.color !== undefined ? options.color : null;
- /**
- * @private
- * @type {string|undefined}
- */
- this.checksum_ = undefined;
- };
- /**
- * Clones the style. The color is not cloned if it is an {@link ol.ColorLike}.
- * @return {ol.style.Fill} The cloned style.
- * @api
- */
- ol.style.Fill.prototype.clone = function() {
- var color = this.getColor();
- return new ol.style.Fill({
- color: (color && color.slice) ? color.slice() : color || undefined
- });
- };
- /**
- * Get the fill color.
- * @return {ol.Color|ol.ColorLike} Color.
- * @api
- */
- ol.style.Fill.prototype.getColor = function() {
- return this.color_;
- };
- /**
- * Set the color.
- *
- * @param {ol.Color|ol.ColorLike} color Color.
- * @api
- */
- ol.style.Fill.prototype.setColor = function(color) {
- this.color_ = color;
- this.checksum_ = undefined;
- };
- /**
- * @return {string} The checksum.
- */
- ol.style.Fill.prototype.getChecksum = function() {
- if (this.checksum_ === undefined) {
- if (
- this.color_ instanceof CanvasPattern ||
- this.color_ instanceof CanvasGradient
- ) {
- this.checksum_ = ol.getUid(this.color_).toString();
- } else {
- this.checksum_ = 'f' + (this.color_ ?
- ol.color.asString(this.color_) : '-');
- }
- }
- return this.checksum_;
- };
- goog.provide('ol.style.Stroke');
- goog.require('ol');
- /**
- * @classdesc
- * Set stroke style for vector features.
- * Note that the defaults given are the Canvas defaults, which will be used if
- * option is not defined. The `get` functions return whatever was entered in
- * the options; they will not return the default.
- *
- * @constructor
- * @param {olx.style.StrokeOptions=} opt_options Options.
- * @api
- */
- ol.style.Stroke = function(opt_options) {
- var options = opt_options || {};
- /**
- * @private
- * @type {ol.Color|ol.ColorLike}
- */
- this.color_ = options.color !== undefined ? options.color : null;
- /**
- * @private
- * @type {string|undefined}
- */
- this.lineCap_ = options.lineCap;
- /**
- * @private
- * @type {Array.<number>}
- */
- this.lineDash_ = options.lineDash !== undefined ? options.lineDash : null;
- /**
- * @private
- * @type {number|undefined}
- */
- this.lineDashOffset_ = options.lineDashOffset;
- /**
- * @private
- * @type {string|undefined}
- */
- this.lineJoin_ = options.lineJoin;
- /**
- * @private
- * @type {number|undefined}
- */
- this.miterLimit_ = options.miterLimit;
- /**
- * @private
- * @type {number|undefined}
- */
- this.width_ = options.width;
- /**
- * @private
- * @type {string|undefined}
- */
- this.checksum_ = undefined;
- };
- /**
- * Clones the style.
- * @return {ol.style.Stroke} The cloned style.
- * @api
- */
- ol.style.Stroke.prototype.clone = function() {
- var color = this.getColor();
- return new ol.style.Stroke({
- color: (color && color.slice) ? color.slice() : color || undefined,
- lineCap: this.getLineCap(),
- lineDash: this.getLineDash() ? this.getLineDash().slice() : undefined,
- lineDashOffset: this.getLineDashOffset(),
- lineJoin: this.getLineJoin(),
- miterLimit: this.getMiterLimit(),
- width: this.getWidth()
- });
- };
- /**
- * Get the stroke color.
- * @return {ol.Color|ol.ColorLike} Color.
- * @api
- */
- ol.style.Stroke.prototype.getColor = function() {
- return this.color_;
- };
- /**
- * Get the line cap type for the stroke.
- * @return {string|undefined} Line cap.
- * @api
- */
- ol.style.Stroke.prototype.getLineCap = function() {
- return this.lineCap_;
- };
- /**
- * Get the line dash style for the stroke.
- * @return {Array.<number>} Line dash.
- * @api
- */
- ol.style.Stroke.prototype.getLineDash = function() {
- return this.lineDash_;
- };
- /**
- * Get the line dash offset for the stroke.
- * @return {number|undefined} Line dash offset.
- * @api
- */
- ol.style.Stroke.prototype.getLineDashOffset = function() {
- return this.lineDashOffset_;
- };
- /**
- * Get the line join type for the stroke.
- * @return {string|undefined} Line join.
- * @api
- */
- ol.style.Stroke.prototype.getLineJoin = function() {
- return this.lineJoin_;
- };
- /**
- * Get the miter limit for the stroke.
- * @return {number|undefined} Miter limit.
- * @api
- */
- ol.style.Stroke.prototype.getMiterLimit = function() {
- return this.miterLimit_;
- };
- /**
- * Get the stroke width.
- * @return {number|undefined} Width.
- * @api
- */
- ol.style.Stroke.prototype.getWidth = function() {
- return this.width_;
- };
- /**
- * Set the color.
- *
- * @param {ol.Color|ol.ColorLike} color Color.
- * @api
- */
- ol.style.Stroke.prototype.setColor = function(color) {
- this.color_ = color;
- this.checksum_ = undefined;
- };
- /**
- * Set the line cap.
- *
- * @param {string|undefined} lineCap Line cap.
- * @api
- */
- ol.style.Stroke.prototype.setLineCap = function(lineCap) {
- this.lineCap_ = lineCap;
- this.checksum_ = undefined;
- };
- /**
- * Set the line dash.
- *
- * Please note that Internet Explorer 10 and lower [do not support][mdn] the
- * `setLineDash` method on the `CanvasRenderingContext2D` and therefore this
- * property will have no visual effect in these browsers.
- *
- * [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash#Browser_compatibility
- *
- * @param {Array.<number>} lineDash Line dash.
- * @api
- */
- ol.style.Stroke.prototype.setLineDash = function(lineDash) {
- this.lineDash_ = lineDash;
- this.checksum_ = undefined;
- };
- /**
- * Set the line dash offset.
- *
- * @param {number|undefined} lineDashOffset Line dash offset.
- * @api
- */
- ol.style.Stroke.prototype.setLineDashOffset = function(lineDashOffset) {
- this.lineDashOffset_ = lineDashOffset;
- this.checksum_ = undefined;
- };
- /**
- * Set the line join.
- *
- * @param {string|undefined} lineJoin Line join.
- * @api
- */
- ol.style.Stroke.prototype.setLineJoin = function(lineJoin) {
- this.lineJoin_ = lineJoin;
- this.checksum_ = undefined;
- };
- /**
- * Set the miter limit.
- *
- * @param {number|undefined} miterLimit Miter limit.
- * @api
- */
- ol.style.Stroke.prototype.setMiterLimit = function(miterLimit) {
- this.miterLimit_ = miterLimit;
- this.checksum_ = undefined;
- };
- /**
- * Set the width.
- *
- * @param {number|undefined} width Width.
- * @api
- */
- ol.style.Stroke.prototype.setWidth = function(width) {
- this.width_ = width;
- this.checksum_ = undefined;
- };
- /**
- * @return {string} The checksum.
- */
- ol.style.Stroke.prototype.getChecksum = function() {
- if (this.checksum_ === undefined) {
- this.checksum_ = 's';
- if (this.color_) {
- if (typeof this.color_ === 'string') {
- this.checksum_ += this.color_;
- } else {
- this.checksum_ += ol.getUid(this.color_).toString();
- }
- } else {
- this.checksum_ += '-';
- }
- this.checksum_ += ',' +
- (this.lineCap_ !== undefined ?
- this.lineCap_.toString() : '-') + ',' +
- (this.lineDash_ ?
- this.lineDash_.toString() : '-') + ',' +
- (this.lineDashOffset_ !== undefined ?
- this.lineDashOffset_ : '-') + ',' +
- (this.lineJoin_ !== undefined ?
- this.lineJoin_ : '-') + ',' +
- (this.miterLimit_ !== undefined ?
- this.miterLimit_.toString() : '-') + ',' +
- (this.width_ !== undefined ?
- this.width_.toString() : '-');
- }
- return this.checksum_;
- };
- goog.provide('ol.style.Style');
- goog.require('ol.asserts');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.style.Circle');
- goog.require('ol.style.Fill');
- goog.require('ol.style.Stroke');
- /**
- * @classdesc
- * Container for vector feature rendering styles. Any changes made to the style
- * or its children through `set*()` methods will not take effect until the
- * feature or layer that uses the style is re-rendered.
- *
- * @constructor
- * @struct
- * @param {olx.style.StyleOptions=} opt_options Style options.
- * @api
- */
- ol.style.Style = function(opt_options) {
- var options = opt_options || {};
- /**
- * @private
- * @type {string|ol.geom.Geometry|ol.StyleGeometryFunction}
- */
- this.geometry_ = null;
- /**
- * @private
- * @type {!ol.StyleGeometryFunction}
- */
- this.geometryFunction_ = ol.style.Style.defaultGeometryFunction;
- if (options.geometry !== undefined) {
- this.setGeometry(options.geometry);
- }
- /**
- * @private
- * @type {ol.style.Fill}
- */
- this.fill_ = options.fill !== undefined ? options.fill : null;
- /**
- * @private
- * @type {ol.style.Image}
- */
- this.image_ = options.image !== undefined ? options.image : null;
- /**
- * @private
- * @type {ol.StyleRenderFunction|null}
- */
- this.renderer_ = options.renderer !== undefined ? options.renderer : null;
- /**
- * @private
- * @type {ol.style.Stroke}
- */
- this.stroke_ = options.stroke !== undefined ? options.stroke : null;
- /**
- * @private
- * @type {ol.style.Text}
- */
- this.text_ = options.text !== undefined ? options.text : null;
- /**
- * @private
- * @type {number|undefined}
- */
- this.zIndex_ = options.zIndex;
- };
- /**
- * Clones the style.
- * @return {ol.style.Style} The cloned style.
- * @api
- */
- ol.style.Style.prototype.clone = function() {
- var geometry = this.getGeometry();
- if (geometry && geometry.clone) {
- geometry = geometry.clone();
- }
- return new ol.style.Style({
- geometry: geometry,
- fill: this.getFill() ? this.getFill().clone() : undefined,
- image: this.getImage() ? this.getImage().clone() : undefined,
- stroke: this.getStroke() ? this.getStroke().clone() : undefined,
- text: this.getText() ? this.getText().clone() : undefined,
- zIndex: this.getZIndex()
- });
- };
- /**
- * Get the custom renderer function that was configured with
- * {@link #setRenderer} or the `renderer` constructor option.
- * @return {ol.StyleRenderFunction|null} Custom renderer function.
- * @api
- */
- ol.style.Style.prototype.getRenderer = function() {
- return this.renderer_;
- };
- /**
- * Sets a custom renderer function for this style. When set, `fill`, `stroke`
- * and `image` options of the style will be ignored.
- * @param {ol.StyleRenderFunction|null} renderer Custom renderer function.
- * @api
- */
- ol.style.Style.prototype.setRenderer = function(renderer) {
- this.renderer_ = renderer;
- };
- /**
- * Get the geometry to be rendered.
- * @return {string|ol.geom.Geometry|ol.StyleGeometryFunction}
- * Feature property or geometry or function that returns the geometry that will
- * be rendered with this style.
- * @api
- */
- ol.style.Style.prototype.getGeometry = function() {
- return this.geometry_;
- };
- /**
- * Get the function used to generate a geometry for rendering.
- * @return {!ol.StyleGeometryFunction} Function that is called with a feature
- * and returns the geometry to render instead of the feature's geometry.
- * @api
- */
- ol.style.Style.prototype.getGeometryFunction = function() {
- return this.geometryFunction_;
- };
- /**
- * Get the fill style.
- * @return {ol.style.Fill} Fill style.
- * @api
- */
- ol.style.Style.prototype.getFill = function() {
- return this.fill_;
- };
- /**
- * Set the fill style.
- * @param {ol.style.Fill} fill Fill style.
- * @api
- */
- ol.style.Style.prototype.setFill = function(fill) {
- this.fill_ = fill;
- };
- /**
- * Get the image style.
- * @return {ol.style.Image} Image style.
- * @api
- */
- ol.style.Style.prototype.getImage = function() {
- return this.image_;
- };
- /**
- * Set the image style.
- * @param {ol.style.Image} image Image style.
- * @api
- */
- ol.style.Style.prototype.setImage = function(image) {
- this.image_ = image;
- };
- /**
- * Get the stroke style.
- * @return {ol.style.Stroke} Stroke style.
- * @api
- */
- ol.style.Style.prototype.getStroke = function() {
- return this.stroke_;
- };
- /**
- * Set the stroke style.
- * @param {ol.style.Stroke} stroke Stroke style.
- * @api
- */
- ol.style.Style.prototype.setStroke = function(stroke) {
- this.stroke_ = stroke;
- };
- /**
- * Get the text style.
- * @return {ol.style.Text} Text style.
- * @api
- */
- ol.style.Style.prototype.getText = function() {
- return this.text_;
- };
- /**
- * Set the text style.
- * @param {ol.style.Text} text Text style.
- * @api
- */
- ol.style.Style.prototype.setText = function(text) {
- this.text_ = text;
- };
- /**
- * Get the z-index for the style.
- * @return {number|undefined} ZIndex.
- * @api
- */
- ol.style.Style.prototype.getZIndex = function() {
- return this.zIndex_;
- };
- /**
- * Set a geometry that is rendered instead of the feature's geometry.
- *
- * @param {string|ol.geom.Geometry|ol.StyleGeometryFunction} geometry
- * Feature property or geometry or function returning a geometry to render
- * for this style.
- * @api
- */
- ol.style.Style.prototype.setGeometry = function(geometry) {
- if (typeof geometry === 'function') {
- this.geometryFunction_ = geometry;
- } else if (typeof geometry === 'string') {
- this.geometryFunction_ = function(feature) {
- return /** @type {ol.geom.Geometry} */ (feature.get(geometry));
- };
- } else if (!geometry) {
- this.geometryFunction_ = ol.style.Style.defaultGeometryFunction;
- } else if (geometry !== undefined) {
- this.geometryFunction_ = function() {
- return /** @type {ol.geom.Geometry} */ (geometry);
- };
- }
- this.geometry_ = geometry;
- };
- /**
- * Set the z-index.
- *
- * @param {number|undefined} zIndex ZIndex.
- * @api
- */
- ol.style.Style.prototype.setZIndex = function(zIndex) {
- this.zIndex_ = zIndex;
- };
- /**
- * Convert the provided object into a style function. Functions passed through
- * unchanged. Arrays of ol.style.Style or single style objects wrapped in a
- * new style function.
- * @param {ol.StyleFunction|Array.<ol.style.Style>|ol.style.Style} obj
- * A style function, a single style, or an array of styles.
- * @return {ol.StyleFunction} A style function.
- */
- ol.style.Style.createFunction = function(obj) {
- var styleFunction;
- if (typeof obj === 'function') {
- styleFunction = obj;
- } else {
- /**
- * @type {Array.<ol.style.Style>}
- */
- var styles;
- if (Array.isArray(obj)) {
- styles = obj;
- } else {
- ol.asserts.assert(obj instanceof ol.style.Style,
- 41); // Expected an `ol.style.Style` or an array of `ol.style.Style`
- styles = [obj];
- }
- styleFunction = function() {
- return styles;
- };
- }
- return styleFunction;
- };
- /**
- * @type {Array.<ol.style.Style>}
- * @private
- */
- ol.style.Style.default_ = null;
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @param {number} resolution Resolution.
- * @return {Array.<ol.style.Style>} Style.
- */
- ol.style.Style.defaultFunction = function(feature, resolution) {
- // We don't use an immediately-invoked function
- // and a closure so we don't get an error at script evaluation time in
- // browsers that do not support Canvas. (ol.style.Circle does
- // canvas.getContext('2d') at construction time, which will cause an.error
- // in such browsers.)
- if (!ol.style.Style.default_) {
- var fill = new ol.style.Fill({
- color: 'rgba(255,255,255,0.4)'
- });
- var stroke = new ol.style.Stroke({
- color: '#3399CC',
- width: 1.25
- });
- ol.style.Style.default_ = [
- new ol.style.Style({
- image: new ol.style.Circle({
- fill: fill,
- stroke: stroke,
- radius: 5
- }),
- fill: fill,
- stroke: stroke
- })
- ];
- }
- return ol.style.Style.default_;
- };
- /**
- * Default styles for editing features.
- * @return {Object.<ol.geom.GeometryType, Array.<ol.style.Style>>} Styles
- */
- ol.style.Style.createDefaultEditing = function() {
- /** @type {Object.<ol.geom.GeometryType, Array.<ol.style.Style>>} */
- var styles = {};
- var white = [255, 255, 255, 1];
- var blue = [0, 153, 255, 1];
- var width = 3;
- styles[ol.geom.GeometryType.POLYGON] = [
- new ol.style.Style({
- fill: new ol.style.Fill({
- color: [255, 255, 255, 0.5]
- })
- })
- ];
- styles[ol.geom.GeometryType.MULTI_POLYGON] =
- styles[ol.geom.GeometryType.POLYGON];
- styles[ol.geom.GeometryType.LINE_STRING] = [
- new ol.style.Style({
- stroke: new ol.style.Stroke({
- color: white,
- width: width + 2
- })
- }),
- new ol.style.Style({
- stroke: new ol.style.Stroke({
- color: blue,
- width: width
- })
- })
- ];
- styles[ol.geom.GeometryType.MULTI_LINE_STRING] =
- styles[ol.geom.GeometryType.LINE_STRING];
- styles[ol.geom.GeometryType.CIRCLE] =
- styles[ol.geom.GeometryType.POLYGON].concat(
- styles[ol.geom.GeometryType.LINE_STRING]
- );
- styles[ol.geom.GeometryType.POINT] = [
- new ol.style.Style({
- image: new ol.style.Circle({
- radius: width * 2,
- fill: new ol.style.Fill({
- color: blue
- }),
- stroke: new ol.style.Stroke({
- color: white,
- width: width / 2
- })
- }),
- zIndex: Infinity
- })
- ];
- styles[ol.geom.GeometryType.MULTI_POINT] =
- styles[ol.geom.GeometryType.POINT];
- styles[ol.geom.GeometryType.GEOMETRY_COLLECTION] =
- styles[ol.geom.GeometryType.POLYGON].concat(
- styles[ol.geom.GeometryType.LINE_STRING],
- styles[ol.geom.GeometryType.POINT]
- );
- return styles;
- };
- /**
- * Function that is called with a feature and returns its default geometry.
- * @param {ol.Feature|ol.render.Feature} feature Feature to get the geometry
- * for.
- * @return {ol.geom.Geometry|ol.render.Feature|undefined} Geometry to render.
- */
- ol.style.Style.defaultGeometryFunction = function(feature) {
- return feature.getGeometry();
- };
- goog.provide('ol.Feature');
- goog.require('ol.asserts');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol');
- goog.require('ol.Object');
- goog.require('ol.geom.Geometry');
- goog.require('ol.style.Style');
- /**
- * @classdesc
- * A vector object for geographic features with a geometry and other
- * attribute properties, similar to the features in vector file formats like
- * GeoJSON.
- *
- * Features can be styled individually with `setStyle`; otherwise they use the
- * style of their vector layer.
- *
- * Note that attribute properties are set as {@link ol.Object} properties on
- * the feature object, so they are observable, and have get/set accessors.
- *
- * Typically, a feature has a single geometry property. You can set the
- * geometry using the `setGeometry` method and get it with `getGeometry`.
- * It is possible to store more than one geometry on a feature using attribute
- * properties. By default, the geometry used for rendering is identified by
- * the property name `geometry`. If you want to use another geometry property
- * for rendering, use the `setGeometryName` method to change the attribute
- * property associated with the geometry for the feature. For example:
- *
- * ```js
- * var feature = new ol.Feature({
- * geometry: new ol.geom.Polygon(polyCoords),
- * labelPoint: new ol.geom.Point(labelCoords),
- * name: 'My Polygon'
- * });
- *
- * // get the polygon geometry
- * var poly = feature.getGeometry();
- *
- * // Render the feature as a point using the coordinates from labelPoint
- * feature.setGeometryName('labelPoint');
- *
- * // get the point geometry
- * var point = feature.getGeometry();
- * ```
- *
- * @constructor
- * @extends {ol.Object}
- * @param {ol.geom.Geometry|Object.<string, *>=} opt_geometryOrProperties
- * You may pass a Geometry object directly, or an object literal
- * containing properties. If you pass an object literal, you may
- * include a Geometry associated with a `geometry` key.
- * @api
- */
- ol.Feature = function(opt_geometryOrProperties) {
- ol.Object.call(this);
- /**
- * @private
- * @type {number|string|undefined}
- */
- this.id_ = undefined;
- /**
- * @type {string}
- * @private
- */
- this.geometryName_ = 'geometry';
- /**
- * User provided style.
- * @private
- * @type {ol.style.Style|Array.<ol.style.Style>|
- * ol.FeatureStyleFunction}
- */
- this.style_ = null;
- /**
- * @private
- * @type {ol.FeatureStyleFunction|undefined}
- */
- this.styleFunction_ = undefined;
- /**
- * @private
- * @type {?ol.EventsKey}
- */
- this.geometryChangeKey_ = null;
- ol.events.listen(
- this, ol.Object.getChangeEventType(this.geometryName_),
- this.handleGeometryChanged_, this);
- if (opt_geometryOrProperties !== undefined) {
- if (opt_geometryOrProperties instanceof ol.geom.Geometry ||
- !opt_geometryOrProperties) {
- var geometry = opt_geometryOrProperties;
- this.setGeometry(geometry);
- } else {
- /** @type {Object.<string, *>} */
- var properties = opt_geometryOrProperties;
- this.setProperties(properties);
- }
- }
- };
- ol.inherits(ol.Feature, ol.Object);
- /**
- * Clone this feature. If the original feature has a geometry it
- * is also cloned. The feature id is not set in the clone.
- * @return {ol.Feature} The clone.
- * @api
- */
- ol.Feature.prototype.clone = function() {
- var clone = new ol.Feature(this.getProperties());
- clone.setGeometryName(this.getGeometryName());
- var geometry = this.getGeometry();
- if (geometry) {
- clone.setGeometry(geometry.clone());
- }
- var style = this.getStyle();
- if (style) {
- clone.setStyle(style);
- }
- return clone;
- };
- /**
- * Get the feature's default geometry. A feature may have any number of named
- * geometries. The "default" geometry (the one that is rendered by default) is
- * set when calling {@link ol.Feature#setGeometry}.
- * @return {ol.geom.Geometry|undefined} The default geometry for the feature.
- * @api
- * @observable
- */
- ol.Feature.prototype.getGeometry = function() {
- return /** @type {ol.geom.Geometry|undefined} */ (
- this.get(this.geometryName_));
- };
- /**
- * Get the feature identifier. This is a stable identifier for the feature and
- * is either set when reading data from a remote source or set explicitly by
- * calling {@link ol.Feature#setId}.
- * @return {number|string|undefined} Id.
- * @api
- */
- ol.Feature.prototype.getId = function() {
- return this.id_;
- };
- /**
- * Get the name of the feature's default geometry. By default, the default
- * geometry is named `geometry`.
- * @return {string} Get the property name associated with the default geometry
- * for this feature.
- * @api
- */
- ol.Feature.prototype.getGeometryName = function() {
- return this.geometryName_;
- };
- /**
- * Get the feature's style. Will return what was provided to the
- * {@link ol.Feature#setStyle} method.
- * @return {ol.style.Style|Array.<ol.style.Style>|
- * ol.FeatureStyleFunction|ol.StyleFunction} The feature style.
- * @api
- */
- ol.Feature.prototype.getStyle = function() {
- return this.style_;
- };
- /**
- * Get the feature's style function.
- * @return {ol.FeatureStyleFunction|undefined} Return a function
- * representing the current style of this feature.
- * @api
- */
- ol.Feature.prototype.getStyleFunction = function() {
- return this.styleFunction_;
- };
- /**
- * @private
- */
- ol.Feature.prototype.handleGeometryChange_ = function() {
- this.changed();
- };
- /**
- * @private
- */
- ol.Feature.prototype.handleGeometryChanged_ = function() {
- if (this.geometryChangeKey_) {
- ol.events.unlistenByKey(this.geometryChangeKey_);
- this.geometryChangeKey_ = null;
- }
- var geometry = this.getGeometry();
- if (geometry) {
- this.geometryChangeKey_ = ol.events.listen(geometry,
- ol.events.EventType.CHANGE, this.handleGeometryChange_, this);
- }
- this.changed();
- };
- /**
- * Set the default geometry for the feature. This will update the property
- * with the name returned by {@link ol.Feature#getGeometryName}.
- * @param {ol.geom.Geometry|undefined} geometry The new geometry.
- * @api
- * @observable
- */
- ol.Feature.prototype.setGeometry = function(geometry) {
- this.set(this.geometryName_, geometry);
- };
- /**
- * Set the style for the feature. This can be a single style object, an array
- * of styles, or a function that takes a resolution and returns an array of
- * styles. If it is `null` the feature has no style (a `null` style).
- * @param {ol.style.Style|Array.<ol.style.Style>|
- * ol.FeatureStyleFunction|ol.StyleFunction} style Style for this feature.
- * @api
- * @fires ol.events.Event#event:change
- */
- ol.Feature.prototype.setStyle = function(style) {
- this.style_ = style;
- this.styleFunction_ = !style ?
- undefined : ol.Feature.createStyleFunction(style);
- this.changed();
- };
- /**
- * Set the feature id. The feature id is considered stable and may be used when
- * requesting features or comparing identifiers returned from a remote source.
- * The feature id can be used with the {@link ol.source.Vector#getFeatureById}
- * method.
- * @param {number|string|undefined} id The feature id.
- * @api
- * @fires ol.events.Event#event:change
- */
- ol.Feature.prototype.setId = function(id) {
- this.id_ = id;
- this.changed();
- };
- /**
- * Set the property name to be used when getting the feature's default geometry.
- * When calling {@link ol.Feature#getGeometry}, the value of the property with
- * this name will be returned.
- * @param {string} name The property name of the default geometry.
- * @api
- */
- ol.Feature.prototype.setGeometryName = function(name) {
- ol.events.unlisten(
- this, ol.Object.getChangeEventType(this.geometryName_),
- this.handleGeometryChanged_, this);
- this.geometryName_ = name;
- ol.events.listen(
- this, ol.Object.getChangeEventType(this.geometryName_),
- this.handleGeometryChanged_, this);
- this.handleGeometryChanged_();
- };
- /**
- * Convert the provided object into a feature style function. Functions passed
- * through unchanged. Arrays of ol.style.Style or single style objects wrapped
- * in a new feature style function.
- * @param {ol.FeatureStyleFunction|!Array.<ol.style.Style>|!ol.style.Style} obj
- * A feature style function, a single style, or an array of styles.
- * @return {ol.FeatureStyleFunction} A style function.
- */
- ol.Feature.createStyleFunction = function(obj) {
- var styleFunction;
- if (typeof obj === 'function') {
- if (obj.length == 2) {
- styleFunction = function(resolution) {
- return /** @type {ol.StyleFunction} */ (obj)(this, resolution);
- };
- } else {
- styleFunction = obj;
- }
- } else {
- /**
- * @type {Array.<ol.style.Style>}
- */
- var styles;
- if (Array.isArray(obj)) {
- styles = obj;
- } else {
- ol.asserts.assert(obj instanceof ol.style.Style,
- 41); // Expected an `ol.style.Style` or an array of `ol.style.Style`
- styles = [obj];
- }
- styleFunction = function() {
- return styles;
- };
- }
- return styleFunction;
- };
- goog.provide('ol.format.FormatType');
- /**
- * @enum {string}
- */
- ol.format.FormatType = {
- ARRAY_BUFFER: 'arraybuffer',
- JSON: 'json',
- TEXT: 'text',
- XML: 'xml'
- };
- goog.provide('ol.xml');
- goog.require('ol.array');
- /**
- * This document should be used when creating nodes for XML serializations. This
- * document is also used by {@link ol.xml.createElementNS} and
- * {@link ol.xml.setAttributeNS}
- * @const
- * @type {Document}
- */
- ol.xml.DOCUMENT = document.implementation.createDocument('', '', null);
- /**
- * @param {string} namespaceURI Namespace URI.
- * @param {string} qualifiedName Qualified name.
- * @return {Node} Node.
- */
- ol.xml.createElementNS = function(namespaceURI, qualifiedName) {
- return ol.xml.DOCUMENT.createElementNS(namespaceURI, qualifiedName);
- };
- /**
- * Recursively grab all text content of child nodes into a single string.
- * @param {Node} node Node.
- * @param {boolean} normalizeWhitespace Normalize whitespace: remove all line
- * breaks.
- * @return {string} All text content.
- * @api
- */
- ol.xml.getAllTextContent = function(node, normalizeWhitespace) {
- return ol.xml.getAllTextContent_(node, normalizeWhitespace, []).join('');
- };
- /**
- * Recursively grab all text content of child nodes into a single string.
- * @param {Node} node Node.
- * @param {boolean} normalizeWhitespace Normalize whitespace: remove all line
- * breaks.
- * @param {Array.<string>} accumulator Accumulator.
- * @private
- * @return {Array.<string>} Accumulator.
- */
- ol.xml.getAllTextContent_ = function(node, normalizeWhitespace, accumulator) {
- if (node.nodeType == Node.CDATA_SECTION_NODE ||
- node.nodeType == Node.TEXT_NODE) {
- if (normalizeWhitespace) {
- accumulator.push(String(node.nodeValue).replace(/(\r\n|\r|\n)/g, ''));
- } else {
- accumulator.push(node.nodeValue);
- }
- } else {
- var n;
- for (n = node.firstChild; n; n = n.nextSibling) {
- ol.xml.getAllTextContent_(n, normalizeWhitespace, accumulator);
- }
- }
- return accumulator;
- };
- /**
- * @param {?} value Value.
- * @return {boolean} Is document.
- */
- ol.xml.isDocument = function(value) {
- return value instanceof Document;
- };
- /**
- * @param {?} value Value.
- * @return {boolean} Is node.
- */
- ol.xml.isNode = function(value) {
- return value instanceof Node;
- };
- /**
- * @param {Node} node Node.
- * @param {?string} namespaceURI Namespace URI.
- * @param {string} name Attribute name.
- * @return {string} Value
- */
- ol.xml.getAttributeNS = function(node, namespaceURI, name) {
- return node.getAttributeNS(namespaceURI, name) || '';
- };
- /**
- * @param {Node} node Node.
- * @param {?string} namespaceURI Namespace URI.
- * @param {string} name Attribute name.
- * @param {string|number} value Value.
- */
- ol.xml.setAttributeNS = function(node, namespaceURI, name, value) {
- node.setAttributeNS(namespaceURI, name, value);
- };
- /**
- * Parse an XML string to an XML Document.
- * @param {string} xml XML.
- * @return {Document} Document.
- * @api
- */
- ol.xml.parse = function(xml) {
- return new DOMParser().parseFromString(xml, 'application/xml');
- };
- /**
- * Make an array extender function for extending the array at the top of the
- * object stack.
- * @param {function(this: T, Node, Array.<*>): (Array.<*>|undefined)}
- * valueReader Value reader.
- * @param {T=} opt_this The object to use as `this` in `valueReader`.
- * @return {ol.XmlParser} Parser.
- * @template T
- */
- ol.xml.makeArrayExtender = function(valueReader, opt_this) {
- return (
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- */
- function(node, objectStack) {
- var value = valueReader.call(opt_this, node, objectStack);
- if (value !== undefined) {
- var array = /** @type {Array.<*>} */
- (objectStack[objectStack.length - 1]);
- ol.array.extend(array, value);
- }
- });
- };
- /**
- * Make an array pusher function for pushing to the array at the top of the
- * object stack.
- * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader.
- * @param {T=} opt_this The object to use as `this` in `valueReader`.
- * @return {ol.XmlParser} Parser.
- * @template T
- */
- ol.xml.makeArrayPusher = function(valueReader, opt_this) {
- return (
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- */
- function(node, objectStack) {
- var value = valueReader.call(opt_this !== undefined ? opt_this : this,
- node, objectStack);
- if (value !== undefined) {
- var array = objectStack[objectStack.length - 1];
- array.push(value);
- }
- });
- };
- /**
- * Make an object stack replacer function for replacing the object at the
- * top of the stack.
- * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader.
- * @param {T=} opt_this The object to use as `this` in `valueReader`.
- * @return {ol.XmlParser} Parser.
- * @template T
- */
- ol.xml.makeReplacer = function(valueReader, opt_this) {
- return (
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- */
- function(node, objectStack) {
- var value = valueReader.call(opt_this !== undefined ? opt_this : this,
- node, objectStack);
- if (value !== undefined) {
- objectStack[objectStack.length - 1] = value;
- }
- });
- };
- /**
- * Make an object property pusher function for adding a property to the
- * object at the top of the stack.
- * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader.
- * @param {string=} opt_property Property.
- * @param {T=} opt_this The object to use as `this` in `valueReader`.
- * @return {ol.XmlParser} Parser.
- * @template T
- */
- ol.xml.makeObjectPropertyPusher = function(valueReader, opt_property, opt_this) {
- return (
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- */
- function(node, objectStack) {
- var value = valueReader.call(opt_this !== undefined ? opt_this : this,
- node, objectStack);
- if (value !== undefined) {
- var object = /** @type {Object} */
- (objectStack[objectStack.length - 1]);
- var property = opt_property !== undefined ?
- opt_property : node.localName;
- var array;
- if (property in object) {
- array = object[property];
- } else {
- array = object[property] = [];
- }
- array.push(value);
- }
- });
- };
- /**
- * Make an object property setter function.
- * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader.
- * @param {string=} opt_property Property.
- * @param {T=} opt_this The object to use as `this` in `valueReader`.
- * @return {ol.XmlParser} Parser.
- * @template T
- */
- ol.xml.makeObjectPropertySetter = function(valueReader, opt_property, opt_this) {
- return (
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- */
- function(node, objectStack) {
- var value = valueReader.call(opt_this !== undefined ? opt_this : this,
- node, objectStack);
- if (value !== undefined) {
- var object = /** @type {Object} */
- (objectStack[objectStack.length - 1]);
- var property = opt_property !== undefined ?
- opt_property : node.localName;
- object[property] = value;
- }
- });
- };
- /**
- * Create a serializer that appends nodes written by its `nodeWriter` to its
- * designated parent. The parent is the `node` of the
- * {@link ol.XmlNodeStackItem} at the top of the `objectStack`.
- * @param {function(this: T, Node, V, Array.<*>)}
- * nodeWriter Node writer.
- * @param {T=} opt_this The object to use as `this` in `nodeWriter`.
- * @return {ol.XmlSerializer} Serializer.
- * @template T, V
- */
- ol.xml.makeChildAppender = function(nodeWriter, opt_this) {
- return function(node, value, objectStack) {
- nodeWriter.call(opt_this !== undefined ? opt_this : this,
- node, value, objectStack);
- var parent = objectStack[objectStack.length - 1];
- var parentNode = parent.node;
- parentNode.appendChild(node);
- };
- };
- /**
- * Create a serializer that calls the provided `nodeWriter` from
- * {@link ol.xml.serialize}. This can be used by the parent writer to have the
- * 'nodeWriter' called with an array of values when the `nodeWriter` was
- * designed to serialize a single item. An example would be a LineString
- * geometry writer, which could be reused for writing MultiLineString
- * geometries.
- * @param {function(this: T, Node, V, Array.<*>)}
- * nodeWriter Node writer.
- * @param {T=} opt_this The object to use as `this` in `nodeWriter`.
- * @return {ol.XmlSerializer} Serializer.
- * @template T, V
- */
- ol.xml.makeArraySerializer = function(nodeWriter, opt_this) {
- var serializersNS, nodeFactory;
- return function(node, value, objectStack) {
- if (serializersNS === undefined) {
- serializersNS = {};
- var serializers = {};
- serializers[node.localName] = nodeWriter;
- serializersNS[node.namespaceURI] = serializers;
- nodeFactory = ol.xml.makeSimpleNodeFactory(node.localName);
- }
- ol.xml.serialize(serializersNS, nodeFactory, value, objectStack);
- };
- };
- /**
- * Create a node factory which can use the `opt_keys` passed to
- * {@link ol.xml.serialize} or {@link ol.xml.pushSerializeAndPop} as node names,
- * or a fixed node name. The namespace of the created nodes can either be fixed,
- * or the parent namespace will be used.
- * @param {string=} opt_nodeName Fixed node name which will be used for all
- * created nodes. If not provided, the 3rd argument to the resulting node
- * factory needs to be provided and will be the nodeName.
- * @param {string=} opt_namespaceURI Fixed namespace URI which will be used for
- * all created nodes. If not provided, the namespace of the parent node will
- * be used.
- * @return {function(*, Array.<*>, string=): (Node|undefined)} Node factory.
- */
- ol.xml.makeSimpleNodeFactory = function(opt_nodeName, opt_namespaceURI) {
- var fixedNodeName = opt_nodeName;
- return (
- /**
- * @param {*} value Value.
- * @param {Array.<*>} objectStack Object stack.
- * @param {string=} opt_nodeName Node name.
- * @return {Node} Node.
- */
- function(value, objectStack, opt_nodeName) {
- var context = objectStack[objectStack.length - 1];
- var node = context.node;
- var nodeName = fixedNodeName;
- if (nodeName === undefined) {
- nodeName = opt_nodeName;
- }
- var namespaceURI = opt_namespaceURI;
- if (opt_namespaceURI === undefined) {
- namespaceURI = node.namespaceURI;
- }
- return ol.xml.createElementNS(namespaceURI, /** @type {string} */ (nodeName));
- }
- );
- };
- /**
- * A node factory that creates a node using the parent's `namespaceURI` and the
- * `nodeName` passed by {@link ol.xml.serialize} or
- * {@link ol.xml.pushSerializeAndPop} to the node factory.
- * @const
- * @type {function(*, Array.<*>, string=): (Node|undefined)}
- */
- ol.xml.OBJECT_PROPERTY_NODE_FACTORY = ol.xml.makeSimpleNodeFactory();
- /**
- * Create an array of `values` to be used with {@link ol.xml.serialize} or
- * {@link ol.xml.pushSerializeAndPop}, where `orderedKeys` has to be provided as
- * `opt_key` argument.
- * @param {Object.<string, V>} object Key-value pairs for the sequence. Keys can
- * be a subset of the `orderedKeys`.
- * @param {Array.<string>} orderedKeys Keys in the order of the sequence.
- * @return {Array.<V>} Values in the order of the sequence. The resulting array
- * has the same length as the `orderedKeys` array. Values that are not
- * present in `object` will be `undefined` in the resulting array.
- * @template V
- */
- ol.xml.makeSequence = function(object, orderedKeys) {
- var length = orderedKeys.length;
- var sequence = new Array(length);
- for (var i = 0; i < length; ++i) {
- sequence[i] = object[orderedKeys[i]];
- }
- return sequence;
- };
- /**
- * Create a namespaced structure, using the same values for each namespace.
- * This can be used as a starting point for versioned parsers, when only a few
- * values are version specific.
- * @param {Array.<string>} namespaceURIs Namespace URIs.
- * @param {T} structure Structure.
- * @param {Object.<string, T>=} opt_structureNS Namespaced structure to add to.
- * @return {Object.<string, T>} Namespaced structure.
- * @template T
- */
- ol.xml.makeStructureNS = function(namespaceURIs, structure, opt_structureNS) {
- /**
- * @type {Object.<string, *>}
- */
- var structureNS = opt_structureNS !== undefined ? opt_structureNS : {};
- var i, ii;
- for (i = 0, ii = namespaceURIs.length; i < ii; ++i) {
- structureNS[namespaceURIs[i]] = structure;
- }
- return structureNS;
- };
- /**
- * Parse a node using the parsers and object stack.
- * @param {Object.<string, Object.<string, ol.XmlParser>>} parsersNS
- * Parsers by namespace.
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @param {*=} opt_this The object to use as `this`.
- */
- ol.xml.parseNode = function(parsersNS, node, objectStack, opt_this) {
- var n;
- for (n = node.firstElementChild; n; n = n.nextElementSibling) {
- var parsers = parsersNS[n.namespaceURI];
- if (parsers !== undefined) {
- var parser = parsers[n.localName];
- if (parser !== undefined) {
- parser.call(opt_this, n, objectStack);
- }
- }
- }
- };
- /**
- * Push an object on top of the stack, parse and return the popped object.
- * @param {T} object Object.
- * @param {Object.<string, Object.<string, ol.XmlParser>>} parsersNS
- * Parsers by namespace.
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @param {*=} opt_this The object to use as `this`.
- * @return {T} Object.
- * @template T
- */
- ol.xml.pushParseAndPop = function(
- object, parsersNS, node, objectStack, opt_this) {
- objectStack.push(object);
- ol.xml.parseNode(parsersNS, node, objectStack, opt_this);
- return objectStack.pop();
- };
- /**
- * Walk through an array of `values` and call a serializer for each value.
- * @param {Object.<string, Object.<string, ol.XmlSerializer>>} serializersNS
- * Namespaced serializers.
- * @param {function(this: T, *, Array.<*>, (string|undefined)): (Node|undefined)} nodeFactory
- * Node factory. The `nodeFactory` creates the node whose namespace and name
- * will be used to choose a node writer from `serializersNS`. This
- * separation allows us to decide what kind of node to create, depending on
- * the value we want to serialize. An example for this would be different
- * geometry writers based on the geometry type.
- * @param {Array.<*>} values Values to serialize. An example would be an array
- * of {@link ol.Feature} instances.
- * @param {Array.<*>} objectStack Node stack.
- * @param {Array.<string>=} opt_keys Keys of the `values`. Will be passed to the
- * `nodeFactory`. This is used for serializing object literals where the
- * node name relates to the property key. The array length of `opt_keys` has
- * to match the length of `values`. For serializing a sequence, `opt_keys`
- * determines the order of the sequence.
- * @param {T=} opt_this The object to use as `this` for the node factory and
- * serializers.
- * @template T
- */
- ol.xml.serialize = function(
- serializersNS, nodeFactory, values, objectStack, opt_keys, opt_this) {
- var length = (opt_keys !== undefined ? opt_keys : values).length;
- var value, node;
- for (var i = 0; i < length; ++i) {
- value = values[i];
- if (value !== undefined) {
- node = nodeFactory.call(opt_this, value, objectStack,
- opt_keys !== undefined ? opt_keys[i] : undefined);
- if (node !== undefined) {
- serializersNS[node.namespaceURI][node.localName]
- .call(opt_this, node, value, objectStack);
- }
- }
- }
- };
- /**
- * @param {O} object Object.
- * @param {Object.<string, Object.<string, ol.XmlSerializer>>} serializersNS
- * Namespaced serializers.
- * @param {function(this: T, *, Array.<*>, (string|undefined)): (Node|undefined)} nodeFactory
- * Node factory. The `nodeFactory` creates the node whose namespace and name
- * will be used to choose a node writer from `serializersNS`. This
- * separation allows us to decide what kind of node to create, depending on
- * the value we want to serialize. An example for this would be different
- * geometry writers based on the geometry type.
- * @param {Array.<*>} values Values to serialize. An example would be an array
- * of {@link ol.Feature} instances.
- * @param {Array.<*>} objectStack Node stack.
- * @param {Array.<string>=} opt_keys Keys of the `values`. Will be passed to the
- * `nodeFactory`. This is used for serializing object literals where the
- * node name relates to the property key. The array length of `opt_keys` has
- * to match the length of `values`. For serializing a sequence, `opt_keys`
- * determines the order of the sequence.
- * @param {T=} opt_this The object to use as `this` for the node factory and
- * serializers.
- * @return {O|undefined} Object.
- * @template O, T
- */
- ol.xml.pushSerializeAndPop = function(object,
- serializersNS, nodeFactory, values, objectStack, opt_keys, opt_this) {
- objectStack.push(object);
- ol.xml.serialize(
- serializersNS, nodeFactory, values, objectStack, opt_keys, opt_this);
- return objectStack.pop();
- };
- goog.provide('ol.featureloader');
- goog.require('ol');
- goog.require('ol.format.FormatType');
- goog.require('ol.xml');
- /**
- * @param {string|ol.FeatureUrlFunction} url Feature URL service.
- * @param {ol.format.Feature} format Feature format.
- * @param {function(this:ol.VectorTile, Array.<ol.Feature>, ol.proj.Projection, ol.Extent)|function(this:ol.source.Vector, Array.<ol.Feature>)} success
- * Function called with the loaded features and optionally with the data
- * projection. Called with the vector tile or source as `this`.
- * @param {function(this:ol.VectorTile)|function(this:ol.source.Vector)} failure
- * Function called when loading failed. Called with the vector tile or
- * source as `this`.
- * @return {ol.FeatureLoader} The feature loader.
- */
- ol.featureloader.loadFeaturesXhr = function(url, format, success, failure) {
- return (
- /**
- * @param {ol.Extent} extent Extent.
- * @param {number} resolution Resolution.
- * @param {ol.proj.Projection} projection Projection.
- * @this {ol.source.Vector|ol.VectorTile}
- */
- function(extent, resolution, projection) {
- var xhr = new XMLHttpRequest();
- xhr.open('GET',
- typeof url === 'function' ? url(extent, resolution, projection) : url,
- true);
- if (format.getType() == ol.format.FormatType.ARRAY_BUFFER) {
- xhr.responseType = 'arraybuffer';
- }
- /**
- * @param {Event} event Event.
- * @private
- */
- xhr.onload = function(event) {
- // status will be 0 for file:// urls
- if (!xhr.status || xhr.status >= 200 && xhr.status < 300) {
- var type = format.getType();
- /** @type {Document|Node|Object|string|undefined} */
- var source;
- if (type == ol.format.FormatType.JSON ||
- type == ol.format.FormatType.TEXT) {
- source = xhr.responseText;
- } else if (type == ol.format.FormatType.XML) {
- source = xhr.responseXML;
- if (!source) {
- source = ol.xml.parse(xhr.responseText);
- }
- } else if (type == ol.format.FormatType.ARRAY_BUFFER) {
- source = /** @type {ArrayBuffer} */ (xhr.response);
- }
- if (source) {
- success.call(this, format.readFeatures(source,
- {featureProjection: projection}),
- format.readProjection(source), format.getLastExtent());
- } else {
- failure.call(this);
- }
- } else {
- failure.call(this);
- }
- }.bind(this);
- /**
- * @private
- */
- xhr.onerror = function() {
- failure.call(this);
- }.bind(this);
- xhr.send();
- });
- };
- /**
- * Create an XHR feature loader for a `url` and `format`. The feature loader
- * loads features (with XHR), parses the features, and adds them to the
- * vector source.
- * @param {string|ol.FeatureUrlFunction} url Feature URL service.
- * @param {ol.format.Feature} format Feature format.
- * @return {ol.FeatureLoader} The feature loader.
- * @api
- */
- ol.featureloader.xhr = function(url, format) {
- return ol.featureloader.loadFeaturesXhr(url, format,
- /**
- * @param {Array.<ol.Feature>} features The loaded features.
- * @param {ol.proj.Projection} dataProjection Data projection.
- * @this {ol.source.Vector}
- */
- function(features, dataProjection) {
- this.addFeatures(features);
- }, /* FIXME handle error */ ol.nullFunction);
- };
- goog.provide('ol.format.Feature');
- goog.require('ol.geom.Geometry');
- goog.require('ol.obj');
- goog.require('ol.proj');
- /**
- * @classdesc
- * Abstract base class; normally only used for creating subclasses and not
- * instantiated in apps.
- * Base class for feature formats.
- * {ol.format.Feature} subclasses provide the ability to decode and encode
- * {@link ol.Feature} objects from a variety of commonly used geospatial
- * file formats. See the documentation for each format for more details.
- *
- * @constructor
- * @abstract
- * @api
- */
- ol.format.Feature = function() {
- /**
- * @protected
- * @type {ol.proj.Projection}
- */
- this.defaultDataProjection = null;
- /**
- * @protected
- * @type {ol.proj.Projection}
- */
- this.defaultFeatureProjection = null;
- };
- /**
- * Adds the data projection to the read options.
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Options.
- * @return {olx.format.ReadOptions|undefined} Options.
- * @protected
- */
- ol.format.Feature.prototype.getReadOptions = function(source, opt_options) {
- var options;
- if (opt_options) {
- options = {
- dataProjection: opt_options.dataProjection ?
- opt_options.dataProjection : this.readProjection(source),
- featureProjection: opt_options.featureProjection
- };
- }
- return this.adaptOptions(options);
- };
- /**
- * Sets the `defaultDataProjection` on the options, if no `dataProjection`
- * is set.
- * @param {olx.format.WriteOptions|olx.format.ReadOptions|undefined} options
- * Options.
- * @protected
- * @return {olx.format.WriteOptions|olx.format.ReadOptions|undefined}
- * Updated options.
- */
- ol.format.Feature.prototype.adaptOptions = function(options) {
- return ol.obj.assign({
- dataProjection: this.defaultDataProjection,
- featureProjection: this.defaultFeatureProjection
- }, options);
- };
- /**
- * Get the extent from the source of the last {@link readFeatures} call.
- * @return {ol.Extent} Tile extent.
- */
- ol.format.Feature.prototype.getLastExtent = function() {
- return null;
- };
- /**
- * @abstract
- * @return {ol.format.FormatType} Format.
- */
- ol.format.Feature.prototype.getType = function() {};
- /**
- * Read a single feature from a source.
- *
- * @abstract
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {ol.Feature} Feature.
- */
- ol.format.Feature.prototype.readFeature = function(source, opt_options) {};
- /**
- * Read all features from a source.
- *
- * @abstract
- * @param {Document|Node|ArrayBuffer|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {Array.<ol.Feature>} Features.
- */
- ol.format.Feature.prototype.readFeatures = function(source, opt_options) {};
- /**
- * Read a single geometry from a source.
- *
- * @abstract
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {ol.geom.Geometry} Geometry.
- */
- ol.format.Feature.prototype.readGeometry = function(source, opt_options) {};
- /**
- * Read the projection from a source.
- *
- * @abstract
- * @param {Document|Node|Object|string} source Source.
- * @return {ol.proj.Projection} Projection.
- */
- ol.format.Feature.prototype.readProjection = function(source) {};
- /**
- * Encode a feature in this format.
- *
- * @abstract
- * @param {ol.Feature} feature Feature.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {string} Result.
- */
- ol.format.Feature.prototype.writeFeature = function(feature, opt_options) {};
- /**
- * Encode an array of features in this format.
- *
- * @abstract
- * @param {Array.<ol.Feature>} features Features.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {string} Result.
- */
- ol.format.Feature.prototype.writeFeatures = function(features, opt_options) {};
- /**
- * Write a single geometry in this format.
- *
- * @abstract
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {string} Result.
- */
- ol.format.Feature.prototype.writeGeometry = function(geometry, opt_options) {};
- /**
- * @param {ol.geom.Geometry|ol.Extent} geometry Geometry.
- * @param {boolean} write Set to true for writing, false for reading.
- * @param {(olx.format.WriteOptions|olx.format.ReadOptions)=} opt_options
- * Options.
- * @return {ol.geom.Geometry|ol.Extent} Transformed geometry.
- * @protected
- */
- ol.format.Feature.transformWithOptions = function(
- geometry, write, opt_options) {
- var featureProjection = opt_options ?
- ol.proj.get(opt_options.featureProjection) : null;
- var dataProjection = opt_options ?
- ol.proj.get(opt_options.dataProjection) : null;
- /**
- * @type {ol.geom.Geometry|ol.Extent}
- */
- var transformed;
- if (featureProjection && dataProjection &&
- !ol.proj.equivalent(featureProjection, dataProjection)) {
- if (geometry instanceof ol.geom.Geometry) {
- transformed = (write ? geometry.clone() : geometry).transform(
- write ? featureProjection : dataProjection,
- write ? dataProjection : featureProjection);
- } else {
- // FIXME this is necessary because ol.format.GML treats extents
- // as geometries
- transformed = ol.proj.transformExtent(
- geometry,
- dataProjection,
- featureProjection);
- }
- } else {
- transformed = geometry;
- }
- if (write && opt_options && opt_options.decimals !== undefined) {
- var power = Math.pow(10, opt_options.decimals);
- // if decimals option on write, round each coordinate appropriately
- /**
- * @param {Array.<number>} coordinates Coordinates.
- * @return {Array.<number>} Transformed coordinates.
- */
- var transform = function(coordinates) {
- for (var i = 0, ii = coordinates.length; i < ii; ++i) {
- coordinates[i] = Math.round(coordinates[i] * power) / power;
- }
- return coordinates;
- };
- if (transformed === geometry) {
- transformed = transformed.clone();
- }
- transformed.applyTransform(transform);
- }
- return transformed;
- };
- goog.provide('ol.format.JSONFeature');
- goog.require('ol');
- goog.require('ol.format.Feature');
- goog.require('ol.format.FormatType');
- /**
- * @classdesc
- * Abstract base class; normally only used for creating subclasses and not
- * instantiated in apps.
- * Base class for JSON feature formats.
- *
- * @constructor
- * @abstract
- * @extends {ol.format.Feature}
- */
- ol.format.JSONFeature = function() {
- ol.format.Feature.call(this);
- };
- ol.inherits(ol.format.JSONFeature, ol.format.Feature);
- /**
- * @param {Document|Node|Object|string} source Source.
- * @private
- * @return {Object} Object.
- */
- ol.format.JSONFeature.prototype.getObject_ = function(source) {
- if (typeof source === 'string') {
- var object = JSON.parse(source);
- return object ? /** @type {Object} */ (object) : null;
- } else if (source !== null) {
- return source;
- } else {
- return null;
- }
- };
- /**
- * @inheritDoc
- */
- ol.format.JSONFeature.prototype.getType = function() {
- return ol.format.FormatType.JSON;
- };
- /**
- * @inheritDoc
- */
- ol.format.JSONFeature.prototype.readFeature = function(source, opt_options) {
- return this.readFeatureFromObject(
- this.getObject_(source), this.getReadOptions(source, opt_options));
- };
- /**
- * @inheritDoc
- */
- ol.format.JSONFeature.prototype.readFeatures = function(source, opt_options) {
- return this.readFeaturesFromObject(
- this.getObject_(source), this.getReadOptions(source, opt_options));
- };
- /**
- * @abstract
- * @param {Object} object Object.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @protected
- * @return {ol.Feature} Feature.
- */
- ol.format.JSONFeature.prototype.readFeatureFromObject = function(object, opt_options) {};
- /**
- * @abstract
- * @param {Object} object Object.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @protected
- * @return {Array.<ol.Feature>} Features.
- */
- ol.format.JSONFeature.prototype.readFeaturesFromObject = function(object, opt_options) {};
- /**
- * @inheritDoc
- */
- ol.format.JSONFeature.prototype.readGeometry = function(source, opt_options) {
- return this.readGeometryFromObject(
- this.getObject_(source), this.getReadOptions(source, opt_options));
- };
- /**
- * @abstract
- * @param {Object} object Object.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @protected
- * @return {ol.geom.Geometry} Geometry.
- */
- ol.format.JSONFeature.prototype.readGeometryFromObject = function(object, opt_options) {};
- /**
- * @inheritDoc
- */
- ol.format.JSONFeature.prototype.readProjection = function(source) {
- return this.readProjectionFromObject(this.getObject_(source));
- };
- /**
- * @abstract
- * @param {Object} object Object.
- * @protected
- * @return {ol.proj.Projection} Projection.
- */
- ol.format.JSONFeature.prototype.readProjectionFromObject = function(object) {};
- /**
- * @inheritDoc
- */
- ol.format.JSONFeature.prototype.writeFeature = function(feature, opt_options) {
- return JSON.stringify(this.writeFeatureObject(feature, opt_options));
- };
- /**
- * @abstract
- * @param {ol.Feature} feature Feature.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {Object} Object.
- */
- ol.format.JSONFeature.prototype.writeFeatureObject = function(feature, opt_options) {};
- /**
- * @inheritDoc
- */
- ol.format.JSONFeature.prototype.writeFeatures = function(features, opt_options) {
- return JSON.stringify(this.writeFeaturesObject(features, opt_options));
- };
- /**
- * @abstract
- * @param {Array.<ol.Feature>} features Features.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {Object} Object.
- */
- ol.format.JSONFeature.prototype.writeFeaturesObject = function(features, opt_options) {};
- /**
- * @inheritDoc
- */
- ol.format.JSONFeature.prototype.writeGeometry = function(geometry, opt_options) {
- return JSON.stringify(this.writeGeometryObject(geometry, opt_options));
- };
- /**
- * @abstract
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {Object} Object.
- */
- ol.format.JSONFeature.prototype.writeGeometryObject = function(geometry, opt_options) {};
- goog.provide('ol.geom.flat.interpolate');
- goog.require('ol.array');
- goog.require('ol.math');
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {number} fraction Fraction.
- * @param {Array.<number>=} opt_dest Destination.
- * @return {Array.<number>} Destination.
- */
- ol.geom.flat.interpolate.lineString = function(flatCoordinates, offset, end, stride, fraction, opt_dest) {
- var pointX = NaN;
- var pointY = NaN;
- var n = (end - offset) / stride;
- if (n === 1) {
- pointX = flatCoordinates[offset];
- pointY = flatCoordinates[offset + 1];
- } else if (n == 2) {
- pointX = (1 - fraction) * flatCoordinates[offset] +
- fraction * flatCoordinates[offset + stride];
- pointY = (1 - fraction) * flatCoordinates[offset + 1] +
- fraction * flatCoordinates[offset + stride + 1];
- } else if (n !== 0) {
- var x1 = flatCoordinates[offset];
- var y1 = flatCoordinates[offset + 1];
- var length = 0;
- var cumulativeLengths = [0];
- var i;
- for (i = offset + stride; i < end; i += stride) {
- var x2 = flatCoordinates[i];
- var y2 = flatCoordinates[i + 1];
- length += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
- cumulativeLengths.push(length);
- x1 = x2;
- y1 = y2;
- }
- var target = fraction * length;
- var index = ol.array.binarySearch(cumulativeLengths, target);
- if (index < 0) {
- var t = (target - cumulativeLengths[-index - 2]) /
- (cumulativeLengths[-index - 1] - cumulativeLengths[-index - 2]);
- var o = offset + (-index - 2) * stride;
- pointX = ol.math.lerp(
- flatCoordinates[o], flatCoordinates[o + stride], t);
- pointY = ol.math.lerp(
- flatCoordinates[o + 1], flatCoordinates[o + stride + 1], t);
- } else {
- pointX = flatCoordinates[offset + index * stride];
- pointY = flatCoordinates[offset + index * stride + 1];
- }
- }
- if (opt_dest) {
- opt_dest[0] = pointX;
- opt_dest[1] = pointY;
- return opt_dest;
- } else {
- return [pointX, pointY];
- }
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {number} m M.
- * @param {boolean} extrapolate Extrapolate.
- * @return {ol.Coordinate} Coordinate.
- */
- ol.geom.flat.interpolate.lineStringCoordinateAtM = function(flatCoordinates, offset, end, stride, m, extrapolate) {
- if (end == offset) {
- return null;
- }
- var coordinate;
- if (m < flatCoordinates[offset + stride - 1]) {
- if (extrapolate) {
- coordinate = flatCoordinates.slice(offset, offset + stride);
- coordinate[stride - 1] = m;
- return coordinate;
- } else {
- return null;
- }
- } else if (flatCoordinates[end - 1] < m) {
- if (extrapolate) {
- coordinate = flatCoordinates.slice(end - stride, end);
- coordinate[stride - 1] = m;
- return coordinate;
- } else {
- return null;
- }
- }
- // FIXME use O(1) search
- if (m == flatCoordinates[offset + stride - 1]) {
- return flatCoordinates.slice(offset, offset + stride);
- }
- var lo = offset / stride;
- var hi = end / stride;
- while (lo < hi) {
- var mid = (lo + hi) >> 1;
- if (m < flatCoordinates[(mid + 1) * stride - 1]) {
- hi = mid;
- } else {
- lo = mid + 1;
- }
- }
- var m0 = flatCoordinates[lo * stride - 1];
- if (m == m0) {
- return flatCoordinates.slice((lo - 1) * stride, (lo - 1) * stride + stride);
- }
- var m1 = flatCoordinates[(lo + 1) * stride - 1];
- var t = (m - m0) / (m1 - m0);
- coordinate = [];
- var i;
- for (i = 0; i < stride - 1; ++i) {
- coordinate.push(ol.math.lerp(flatCoordinates[(lo - 1) * stride + i],
- flatCoordinates[lo * stride + i], t));
- }
- coordinate.push(m);
- return coordinate;
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<number>} ends Ends.
- * @param {number} stride Stride.
- * @param {number} m M.
- * @param {boolean} extrapolate Extrapolate.
- * @param {boolean} interpolate Interpolate.
- * @return {ol.Coordinate} Coordinate.
- */
- ol.geom.flat.interpolate.lineStringsCoordinateAtM = function(
- flatCoordinates, offset, ends, stride, m, extrapolate, interpolate) {
- if (interpolate) {
- return ol.geom.flat.interpolate.lineStringCoordinateAtM(
- flatCoordinates, offset, ends[ends.length - 1], stride, m, extrapolate);
- }
- var coordinate;
- if (m < flatCoordinates[stride - 1]) {
- if (extrapolate) {
- coordinate = flatCoordinates.slice(0, stride);
- coordinate[stride - 1] = m;
- return coordinate;
- } else {
- return null;
- }
- }
- if (flatCoordinates[flatCoordinates.length - 1] < m) {
- if (extrapolate) {
- coordinate = flatCoordinates.slice(flatCoordinates.length - stride);
- coordinate[stride - 1] = m;
- return coordinate;
- } else {
- return null;
- }
- }
- var i, ii;
- for (i = 0, ii = ends.length; i < ii; ++i) {
- var end = ends[i];
- if (offset == end) {
- continue;
- }
- if (m < flatCoordinates[offset + stride - 1]) {
- return null;
- } else if (m <= flatCoordinates[end - 1]) {
- return ol.geom.flat.interpolate.lineStringCoordinateAtM(
- flatCoordinates, offset, end, stride, m, false);
- }
- offset = end;
- }
- return null;
- };
- goog.provide('ol.geom.LineString');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.extent');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.SimpleGeometry');
- goog.require('ol.geom.flat.closest');
- goog.require('ol.geom.flat.deflate');
- goog.require('ol.geom.flat.inflate');
- goog.require('ol.geom.flat.interpolate');
- goog.require('ol.geom.flat.intersectsextent');
- goog.require('ol.geom.flat.length');
- goog.require('ol.geom.flat.segments');
- goog.require('ol.geom.flat.simplify');
- /**
- * @classdesc
- * Linestring geometry.
- *
- * @constructor
- * @extends {ol.geom.SimpleGeometry}
- * @param {Array.<ol.Coordinate>} coordinates Coordinates.
- * @param {ol.geom.GeometryLayout=} opt_layout Layout.
- * @api
- */
- ol.geom.LineString = function(coordinates, opt_layout) {
- ol.geom.SimpleGeometry.call(this);
- /**
- * @private
- * @type {ol.Coordinate}
- */
- this.flatMidpoint_ = null;
- /**
- * @private
- * @type {number}
- */
- this.flatMidpointRevision_ = -1;
- /**
- * @private
- * @type {number}
- */
- this.maxDelta_ = -1;
- /**
- * @private
- * @type {number}
- */
- this.maxDeltaRevision_ = -1;
- this.setCoordinates(coordinates, opt_layout);
- };
- ol.inherits(ol.geom.LineString, ol.geom.SimpleGeometry);
- /**
- * Append the passed coordinate to the coordinates of the linestring.
- * @param {ol.Coordinate} coordinate Coordinate.
- * @api
- */
- ol.geom.LineString.prototype.appendCoordinate = function(coordinate) {
- if (!this.flatCoordinates) {
- this.flatCoordinates = coordinate.slice();
- } else {
- ol.array.extend(this.flatCoordinates, coordinate);
- }
- this.changed();
- };
- /**
- * Make a complete copy of the geometry.
- * @return {!ol.geom.LineString} Clone.
- * @override
- * @api
- */
- ol.geom.LineString.prototype.clone = function() {
- var lineString = new ol.geom.LineString(null);
- lineString.setFlatCoordinates(this.layout, this.flatCoordinates.slice());
- return lineString;
- };
- /**
- * @inheritDoc
- */
- ol.geom.LineString.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) {
- if (minSquaredDistance <
- ol.extent.closestSquaredDistanceXY(this.getExtent(), x, y)) {
- return minSquaredDistance;
- }
- if (this.maxDeltaRevision_ != this.getRevision()) {
- this.maxDelta_ = Math.sqrt(ol.geom.flat.closest.getMaxSquaredDelta(
- this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, 0));
- this.maxDeltaRevision_ = this.getRevision();
- }
- return ol.geom.flat.closest.getClosestPoint(
- this.flatCoordinates, 0, this.flatCoordinates.length, this.stride,
- this.maxDelta_, false, x, y, closestPoint, minSquaredDistance);
- };
- /**
- * Iterate over each segment, calling the provided callback.
- * If the callback returns a truthy value the function returns that
- * value immediately. Otherwise the function returns `false`.
- *
- * @param {function(this: S, ol.Coordinate, ol.Coordinate): T} callback Function
- * called for each segment.
- * @param {S=} opt_this The object to be used as the value of 'this'
- * within callback.
- * @return {T|boolean} Value.
- * @template T,S
- * @api
- */
- ol.geom.LineString.prototype.forEachSegment = function(callback, opt_this) {
- return ol.geom.flat.segments.forEach(this.flatCoordinates, 0,
- this.flatCoordinates.length, this.stride, callback, opt_this);
- };
- /**
- * Returns the coordinate at `m` using linear interpolation, or `null` if no
- * such coordinate exists.
- *
- * `opt_extrapolate` controls extrapolation beyond the range of Ms in the
- * MultiLineString. If `opt_extrapolate` is `true` then Ms less than the first
- * M will return the first coordinate and Ms greater than the last M will
- * return the last coordinate.
- *
- * @param {number} m M.
- * @param {boolean=} opt_extrapolate Extrapolate. Default is `false`.
- * @return {ol.Coordinate} Coordinate.
- * @api
- */
- ol.geom.LineString.prototype.getCoordinateAtM = function(m, opt_extrapolate) {
- if (this.layout != ol.geom.GeometryLayout.XYM &&
- this.layout != ol.geom.GeometryLayout.XYZM) {
- return null;
- }
- var extrapolate = opt_extrapolate !== undefined ? opt_extrapolate : false;
- return ol.geom.flat.interpolate.lineStringCoordinateAtM(this.flatCoordinates, 0,
- this.flatCoordinates.length, this.stride, m, extrapolate);
- };
- /**
- * Return the coordinates of the linestring.
- * @return {Array.<ol.Coordinate>} Coordinates.
- * @override
- * @api
- */
- ol.geom.LineString.prototype.getCoordinates = function() {
- return ol.geom.flat.inflate.coordinates(
- this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);
- };
- /**
- * Return the coordinate at the provided fraction along the linestring.
- * The `fraction` is a number between 0 and 1, where 0 is the start of the
- * linestring and 1 is the end.
- * @param {number} fraction Fraction.
- * @param {ol.Coordinate=} opt_dest Optional coordinate whose values will
- * be modified. If not provided, a new coordinate will be returned.
- * @return {ol.Coordinate} Coordinate of the interpolated point.
- * @api
- */
- ol.geom.LineString.prototype.getCoordinateAt = function(fraction, opt_dest) {
- return ol.geom.flat.interpolate.lineString(
- this.flatCoordinates, 0, this.flatCoordinates.length, this.stride,
- fraction, opt_dest);
- };
- /**
- * Return the length of the linestring on projected plane.
- * @return {number} Length (on projected plane).
- * @api
- */
- ol.geom.LineString.prototype.getLength = function() {
- return ol.geom.flat.length.lineString(
- this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);
- };
- /**
- * @return {Array.<number>} Flat midpoint.
- */
- ol.geom.LineString.prototype.getFlatMidpoint = function() {
- if (this.flatMidpointRevision_ != this.getRevision()) {
- this.flatMidpoint_ = this.getCoordinateAt(0.5, this.flatMidpoint_);
- this.flatMidpointRevision_ = this.getRevision();
- }
- return this.flatMidpoint_;
- };
- /**
- * @inheritDoc
- */
- ol.geom.LineString.prototype.getSimplifiedGeometryInternal = function(squaredTolerance) {
- var simplifiedFlatCoordinates = [];
- simplifiedFlatCoordinates.length = ol.geom.flat.simplify.douglasPeucker(
- this.flatCoordinates, 0, this.flatCoordinates.length, this.stride,
- squaredTolerance, simplifiedFlatCoordinates, 0);
- var simplifiedLineString = new ol.geom.LineString(null);
- simplifiedLineString.setFlatCoordinates(
- ol.geom.GeometryLayout.XY, simplifiedFlatCoordinates);
- return simplifiedLineString;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.LineString.prototype.getType = function() {
- return ol.geom.GeometryType.LINE_STRING;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.LineString.prototype.intersectsExtent = function(extent) {
- return ol.geom.flat.intersectsextent.lineString(
- this.flatCoordinates, 0, this.flatCoordinates.length, this.stride,
- extent);
- };
- /**
- * Set the coordinates of the linestring.
- * @param {Array.<ol.Coordinate>} coordinates Coordinates.
- * @param {ol.geom.GeometryLayout=} opt_layout Layout.
- * @override
- * @api
- */
- ol.geom.LineString.prototype.setCoordinates = function(coordinates, opt_layout) {
- if (!coordinates) {
- this.setFlatCoordinates(ol.geom.GeometryLayout.XY, null);
- } else {
- this.setLayout(opt_layout, coordinates, 1);
- if (!this.flatCoordinates) {
- this.flatCoordinates = [];
- }
- this.flatCoordinates.length = ol.geom.flat.deflate.coordinates(
- this.flatCoordinates, 0, coordinates, this.stride);
- this.changed();
- }
- };
- /**
- * @param {ol.geom.GeometryLayout} layout Layout.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- */
- ol.geom.LineString.prototype.setFlatCoordinates = function(layout, flatCoordinates) {
- this.setFlatCoordinatesInternal(layout, flatCoordinates);
- this.changed();
- };
- goog.provide('ol.geom.MultiLineString');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.extent');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.LineString');
- goog.require('ol.geom.SimpleGeometry');
- goog.require('ol.geom.flat.closest');
- goog.require('ol.geom.flat.deflate');
- goog.require('ol.geom.flat.inflate');
- goog.require('ol.geom.flat.interpolate');
- goog.require('ol.geom.flat.intersectsextent');
- goog.require('ol.geom.flat.simplify');
- /**
- * @classdesc
- * Multi-linestring geometry.
- *
- * @constructor
- * @extends {ol.geom.SimpleGeometry}
- * @param {Array.<Array.<ol.Coordinate>>} coordinates Coordinates.
- * @param {ol.geom.GeometryLayout=} opt_layout Layout.
- * @api
- */
- ol.geom.MultiLineString = function(coordinates, opt_layout) {
- ol.geom.SimpleGeometry.call(this);
- /**
- * @type {Array.<number>}
- * @private
- */
- this.ends_ = [];
- /**
- * @private
- * @type {number}
- */
- this.maxDelta_ = -1;
- /**
- * @private
- * @type {number}
- */
- this.maxDeltaRevision_ = -1;
- this.setCoordinates(coordinates, opt_layout);
- };
- ol.inherits(ol.geom.MultiLineString, ol.geom.SimpleGeometry);
- /**
- * Append the passed linestring to the multilinestring.
- * @param {ol.geom.LineString} lineString LineString.
- * @api
- */
- ol.geom.MultiLineString.prototype.appendLineString = function(lineString) {
- if (!this.flatCoordinates) {
- this.flatCoordinates = lineString.getFlatCoordinates().slice();
- } else {
- ol.array.extend(
- this.flatCoordinates, lineString.getFlatCoordinates().slice());
- }
- this.ends_.push(this.flatCoordinates.length);
- this.changed();
- };
- /**
- * Make a complete copy of the geometry.
- * @return {!ol.geom.MultiLineString} Clone.
- * @override
- * @api
- */
- ol.geom.MultiLineString.prototype.clone = function() {
- var multiLineString = new ol.geom.MultiLineString(null);
- multiLineString.setFlatCoordinates(
- this.layout, this.flatCoordinates.slice(), this.ends_.slice());
- return multiLineString;
- };
- /**
- * @inheritDoc
- */
- ol.geom.MultiLineString.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) {
- if (minSquaredDistance <
- ol.extent.closestSquaredDistanceXY(this.getExtent(), x, y)) {
- return minSquaredDistance;
- }
- if (this.maxDeltaRevision_ != this.getRevision()) {
- this.maxDelta_ = Math.sqrt(ol.geom.flat.closest.getsMaxSquaredDelta(
- this.flatCoordinates, 0, this.ends_, this.stride, 0));
- this.maxDeltaRevision_ = this.getRevision();
- }
- return ol.geom.flat.closest.getsClosestPoint(
- this.flatCoordinates, 0, this.ends_, this.stride,
- this.maxDelta_, false, x, y, closestPoint, minSquaredDistance);
- };
- /**
- * Returns the coordinate at `m` using linear interpolation, or `null` if no
- * such coordinate exists.
- *
- * `opt_extrapolate` controls extrapolation beyond the range of Ms in the
- * MultiLineString. If `opt_extrapolate` is `true` then Ms less than the first
- * M will return the first coordinate and Ms greater than the last M will
- * return the last coordinate.
- *
- * `opt_interpolate` controls interpolation between consecutive LineStrings
- * within the MultiLineString. If `opt_interpolate` is `true` the coordinates
- * will be linearly interpolated between the last coordinate of one LineString
- * and the first coordinate of the next LineString. If `opt_interpolate` is
- * `false` then the function will return `null` for Ms falling between
- * LineStrings.
- *
- * @param {number} m M.
- * @param {boolean=} opt_extrapolate Extrapolate. Default is `false`.
- * @param {boolean=} opt_interpolate Interpolate. Default is `false`.
- * @return {ol.Coordinate} Coordinate.
- * @api
- */
- ol.geom.MultiLineString.prototype.getCoordinateAtM = function(m, opt_extrapolate, opt_interpolate) {
- if ((this.layout != ol.geom.GeometryLayout.XYM &&
- this.layout != ol.geom.GeometryLayout.XYZM) ||
- this.flatCoordinates.length === 0) {
- return null;
- }
- var extrapolate = opt_extrapolate !== undefined ? opt_extrapolate : false;
- var interpolate = opt_interpolate !== undefined ? opt_interpolate : false;
- return ol.geom.flat.interpolate.lineStringsCoordinateAtM(this.flatCoordinates, 0,
- this.ends_, this.stride, m, extrapolate, interpolate);
- };
- /**
- * Return the coordinates of the multilinestring.
- * @return {Array.<Array.<ol.Coordinate>>} Coordinates.
- * @override
- * @api
- */
- ol.geom.MultiLineString.prototype.getCoordinates = function() {
- return ol.geom.flat.inflate.coordinatess(
- this.flatCoordinates, 0, this.ends_, this.stride);
- };
- /**
- * @return {Array.<number>} Ends.
- */
- ol.geom.MultiLineString.prototype.getEnds = function() {
- return this.ends_;
- };
- /**
- * Return the linestring at the specified index.
- * @param {number} index Index.
- * @return {ol.geom.LineString} LineString.
- * @api
- */
- ol.geom.MultiLineString.prototype.getLineString = function(index) {
- if (index < 0 || this.ends_.length <= index) {
- return null;
- }
- var lineString = new ol.geom.LineString(null);
- lineString.setFlatCoordinates(this.layout, this.flatCoordinates.slice(
- index === 0 ? 0 : this.ends_[index - 1], this.ends_[index]));
- return lineString;
- };
- /**
- * Return the linestrings of this multilinestring.
- * @return {Array.<ol.geom.LineString>} LineStrings.
- * @api
- */
- ol.geom.MultiLineString.prototype.getLineStrings = function() {
- var flatCoordinates = this.flatCoordinates;
- var ends = this.ends_;
- var layout = this.layout;
- /** @type {Array.<ol.geom.LineString>} */
- var lineStrings = [];
- var offset = 0;
- var i, ii;
- for (i = 0, ii = ends.length; i < ii; ++i) {
- var end = ends[i];
- var lineString = new ol.geom.LineString(null);
- lineString.setFlatCoordinates(layout, flatCoordinates.slice(offset, end));
- lineStrings.push(lineString);
- offset = end;
- }
- return lineStrings;
- };
- /**
- * @return {Array.<number>} Flat midpoints.
- */
- ol.geom.MultiLineString.prototype.getFlatMidpoints = function() {
- var midpoints = [];
- var flatCoordinates = this.flatCoordinates;
- var offset = 0;
- var ends = this.ends_;
- var stride = this.stride;
- var i, ii;
- for (i = 0, ii = ends.length; i < ii; ++i) {
- var end = ends[i];
- var midpoint = ol.geom.flat.interpolate.lineString(
- flatCoordinates, offset, end, stride, 0.5);
- ol.array.extend(midpoints, midpoint);
- offset = end;
- }
- return midpoints;
- };
- /**
- * @inheritDoc
- */
- ol.geom.MultiLineString.prototype.getSimplifiedGeometryInternal = function(squaredTolerance) {
- var simplifiedFlatCoordinates = [];
- var simplifiedEnds = [];
- simplifiedFlatCoordinates.length = ol.geom.flat.simplify.douglasPeuckers(
- this.flatCoordinates, 0, this.ends_, this.stride, squaredTolerance,
- simplifiedFlatCoordinates, 0, simplifiedEnds);
- var simplifiedMultiLineString = new ol.geom.MultiLineString(null);
- simplifiedMultiLineString.setFlatCoordinates(
- ol.geom.GeometryLayout.XY, simplifiedFlatCoordinates, simplifiedEnds);
- return simplifiedMultiLineString;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.MultiLineString.prototype.getType = function() {
- return ol.geom.GeometryType.MULTI_LINE_STRING;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.MultiLineString.prototype.intersectsExtent = function(extent) {
- return ol.geom.flat.intersectsextent.lineStrings(
- this.flatCoordinates, 0, this.ends_, this.stride, extent);
- };
- /**
- * Set the coordinates of the multilinestring.
- * @param {Array.<Array.<ol.Coordinate>>} coordinates Coordinates.
- * @param {ol.geom.GeometryLayout=} opt_layout Layout.
- * @override
- * @api
- */
- ol.geom.MultiLineString.prototype.setCoordinates = function(coordinates, opt_layout) {
- if (!coordinates) {
- this.setFlatCoordinates(ol.geom.GeometryLayout.XY, null, this.ends_);
- } else {
- this.setLayout(opt_layout, coordinates, 2);
- if (!this.flatCoordinates) {
- this.flatCoordinates = [];
- }
- var ends = ol.geom.flat.deflate.coordinatess(
- this.flatCoordinates, 0, coordinates, this.stride, this.ends_);
- this.flatCoordinates.length = ends.length === 0 ? 0 : ends[ends.length - 1];
- this.changed();
- }
- };
- /**
- * @param {ol.geom.GeometryLayout} layout Layout.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {Array.<number>} ends Ends.
- */
- ol.geom.MultiLineString.prototype.setFlatCoordinates = function(layout, flatCoordinates, ends) {
- this.setFlatCoordinatesInternal(layout, flatCoordinates);
- this.ends_ = ends;
- this.changed();
- };
- /**
- * @param {Array.<ol.geom.LineString>} lineStrings LineStrings.
- */
- ol.geom.MultiLineString.prototype.setLineStrings = function(lineStrings) {
- var layout = this.getLayout();
- var flatCoordinates = [];
- var ends = [];
- var i, ii;
- for (i = 0, ii = lineStrings.length; i < ii; ++i) {
- var lineString = lineStrings[i];
- if (i === 0) {
- layout = lineString.getLayout();
- }
- ol.array.extend(flatCoordinates, lineString.getFlatCoordinates());
- ends.push(flatCoordinates.length);
- }
- this.setFlatCoordinates(layout, flatCoordinates, ends);
- };
- goog.provide('ol.geom.MultiPoint');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.extent');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.Point');
- goog.require('ol.geom.SimpleGeometry');
- goog.require('ol.geom.flat.deflate');
- goog.require('ol.geom.flat.inflate');
- goog.require('ol.math');
- /**
- * @classdesc
- * Multi-point geometry.
- *
- * @constructor
- * @extends {ol.geom.SimpleGeometry}
- * @param {Array.<ol.Coordinate>} coordinates Coordinates.
- * @param {ol.geom.GeometryLayout=} opt_layout Layout.
- * @api
- */
- ol.geom.MultiPoint = function(coordinates, opt_layout) {
- ol.geom.SimpleGeometry.call(this);
- this.setCoordinates(coordinates, opt_layout);
- };
- ol.inherits(ol.geom.MultiPoint, ol.geom.SimpleGeometry);
- /**
- * Append the passed point to this multipoint.
- * @param {ol.geom.Point} point Point.
- * @api
- */
- ol.geom.MultiPoint.prototype.appendPoint = function(point) {
- if (!this.flatCoordinates) {
- this.flatCoordinates = point.getFlatCoordinates().slice();
- } else {
- ol.array.extend(this.flatCoordinates, point.getFlatCoordinates());
- }
- this.changed();
- };
- /**
- * Make a complete copy of the geometry.
- * @return {!ol.geom.MultiPoint} Clone.
- * @override
- * @api
- */
- ol.geom.MultiPoint.prototype.clone = function() {
- var multiPoint = new ol.geom.MultiPoint(null);
- multiPoint.setFlatCoordinates(this.layout, this.flatCoordinates.slice());
- return multiPoint;
- };
- /**
- * @inheritDoc
- */
- ol.geom.MultiPoint.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) {
- if (minSquaredDistance <
- ol.extent.closestSquaredDistanceXY(this.getExtent(), x, y)) {
- return minSquaredDistance;
- }
- var flatCoordinates = this.flatCoordinates;
- var stride = this.stride;
- var i, ii, j;
- for (i = 0, ii = flatCoordinates.length; i < ii; i += stride) {
- var squaredDistance = ol.math.squaredDistance(
- x, y, flatCoordinates[i], flatCoordinates[i + 1]);
- if (squaredDistance < minSquaredDistance) {
- minSquaredDistance = squaredDistance;
- for (j = 0; j < stride; ++j) {
- closestPoint[j] = flatCoordinates[i + j];
- }
- closestPoint.length = stride;
- }
- }
- return minSquaredDistance;
- };
- /**
- * Return the coordinates of the multipoint.
- * @return {Array.<ol.Coordinate>} Coordinates.
- * @override
- * @api
- */
- ol.geom.MultiPoint.prototype.getCoordinates = function() {
- return ol.geom.flat.inflate.coordinates(
- this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);
- };
- /**
- * Return the point at the specified index.
- * @param {number} index Index.
- * @return {ol.geom.Point} Point.
- * @api
- */
- ol.geom.MultiPoint.prototype.getPoint = function(index) {
- var n = !this.flatCoordinates ?
- 0 : this.flatCoordinates.length / this.stride;
- if (index < 0 || n <= index) {
- return null;
- }
- var point = new ol.geom.Point(null);
- point.setFlatCoordinates(this.layout, this.flatCoordinates.slice(
- index * this.stride, (index + 1) * this.stride));
- return point;
- };
- /**
- * Return the points of this multipoint.
- * @return {Array.<ol.geom.Point>} Points.
- * @api
- */
- ol.geom.MultiPoint.prototype.getPoints = function() {
- var flatCoordinates = this.flatCoordinates;
- var layout = this.layout;
- var stride = this.stride;
- /** @type {Array.<ol.geom.Point>} */
- var points = [];
- var i, ii;
- for (i = 0, ii = flatCoordinates.length; i < ii; i += stride) {
- var point = new ol.geom.Point(null);
- point.setFlatCoordinates(layout, flatCoordinates.slice(i, i + stride));
- points.push(point);
- }
- return points;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.MultiPoint.prototype.getType = function() {
- return ol.geom.GeometryType.MULTI_POINT;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.MultiPoint.prototype.intersectsExtent = function(extent) {
- var flatCoordinates = this.flatCoordinates;
- var stride = this.stride;
- var i, ii, x, y;
- for (i = 0, ii = flatCoordinates.length; i < ii; i += stride) {
- x = flatCoordinates[i];
- y = flatCoordinates[i + 1];
- if (ol.extent.containsXY(extent, x, y)) {
- return true;
- }
- }
- return false;
- };
- /**
- * Set the coordinates of the multipoint.
- * @param {Array.<ol.Coordinate>} coordinates Coordinates.
- * @param {ol.geom.GeometryLayout=} opt_layout Layout.
- * @override
- * @api
- */
- ol.geom.MultiPoint.prototype.setCoordinates = function(coordinates, opt_layout) {
- if (!coordinates) {
- this.setFlatCoordinates(ol.geom.GeometryLayout.XY, null);
- } else {
- this.setLayout(opt_layout, coordinates, 1);
- if (!this.flatCoordinates) {
- this.flatCoordinates = [];
- }
- this.flatCoordinates.length = ol.geom.flat.deflate.coordinates(
- this.flatCoordinates, 0, coordinates, this.stride);
- this.changed();
- }
- };
- /**
- * @param {ol.geom.GeometryLayout} layout Layout.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- */
- ol.geom.MultiPoint.prototype.setFlatCoordinates = function(layout, flatCoordinates) {
- this.setFlatCoordinatesInternal(layout, flatCoordinates);
- this.changed();
- };
- goog.provide('ol.geom.flat.center');
- goog.require('ol.extent');
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {Array.<Array.<number>>} endss Endss.
- * @param {number} stride Stride.
- * @return {Array.<number>} Flat centers.
- */
- ol.geom.flat.center.linearRingss = function(flatCoordinates, offset, endss, stride) {
- var flatCenters = [];
- var i, ii;
- var extent = ol.extent.createEmpty();
- for (i = 0, ii = endss.length; i < ii; ++i) {
- var ends = endss[i];
- extent = ol.extent.createOrUpdateFromFlatCoordinates(
- flatCoordinates, offset, ends[0], stride);
- flatCenters.push((extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2);
- offset = ends[ends.length - 1];
- }
- return flatCenters;
- };
- goog.provide('ol.geom.MultiPolygon');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.extent');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.MultiPoint');
- goog.require('ol.geom.Polygon');
- goog.require('ol.geom.SimpleGeometry');
- goog.require('ol.geom.flat.area');
- goog.require('ol.geom.flat.center');
- goog.require('ol.geom.flat.closest');
- goog.require('ol.geom.flat.contains');
- goog.require('ol.geom.flat.deflate');
- goog.require('ol.geom.flat.inflate');
- goog.require('ol.geom.flat.interiorpoint');
- goog.require('ol.geom.flat.intersectsextent');
- goog.require('ol.geom.flat.orient');
- goog.require('ol.geom.flat.simplify');
- /**
- * @classdesc
- * Multi-polygon geometry.
- *
- * @constructor
- * @extends {ol.geom.SimpleGeometry}
- * @param {Array.<Array.<Array.<ol.Coordinate>>>} coordinates Coordinates.
- * @param {ol.geom.GeometryLayout=} opt_layout Layout.
- * @api
- */
- ol.geom.MultiPolygon = function(coordinates, opt_layout) {
- ol.geom.SimpleGeometry.call(this);
- /**
- * @type {Array.<Array.<number>>}
- * @private
- */
- this.endss_ = [];
- /**
- * @private
- * @type {number}
- */
- this.flatInteriorPointsRevision_ = -1;
- /**
- * @private
- * @type {Array.<number>}
- */
- this.flatInteriorPoints_ = null;
- /**
- * @private
- * @type {number}
- */
- this.maxDelta_ = -1;
- /**
- * @private
- * @type {number}
- */
- this.maxDeltaRevision_ = -1;
- /**
- * @private
- * @type {number}
- */
- this.orientedRevision_ = -1;
- /**
- * @private
- * @type {Array.<number>}
- */
- this.orientedFlatCoordinates_ = null;
- this.setCoordinates(coordinates, opt_layout);
- };
- ol.inherits(ol.geom.MultiPolygon, ol.geom.SimpleGeometry);
- /**
- * Append the passed polygon to this multipolygon.
- * @param {ol.geom.Polygon} polygon Polygon.
- * @api
- */
- ol.geom.MultiPolygon.prototype.appendPolygon = function(polygon) {
- /** @type {Array.<number>} */
- var ends;
- if (!this.flatCoordinates) {
- this.flatCoordinates = polygon.getFlatCoordinates().slice();
- ends = polygon.getEnds().slice();
- this.endss_.push();
- } else {
- var offset = this.flatCoordinates.length;
- ol.array.extend(this.flatCoordinates, polygon.getFlatCoordinates());
- ends = polygon.getEnds().slice();
- var i, ii;
- for (i = 0, ii = ends.length; i < ii; ++i) {
- ends[i] += offset;
- }
- }
- this.endss_.push(ends);
- this.changed();
- };
- /**
- * Make a complete copy of the geometry.
- * @return {!ol.geom.MultiPolygon} Clone.
- * @override
- * @api
- */
- ol.geom.MultiPolygon.prototype.clone = function() {
- var multiPolygon = new ol.geom.MultiPolygon(null);
- var len = this.endss_.length;
- var newEndss = new Array(len);
- for (var i = 0; i < len; ++i) {
- newEndss[i] = this.endss_[i].slice();
- }
- multiPolygon.setFlatCoordinates(
- this.layout, this.flatCoordinates.slice(), newEndss);
- return multiPolygon;
- };
- /**
- * @inheritDoc
- */
- ol.geom.MultiPolygon.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) {
- if (minSquaredDistance <
- ol.extent.closestSquaredDistanceXY(this.getExtent(), x, y)) {
- return minSquaredDistance;
- }
- if (this.maxDeltaRevision_ != this.getRevision()) {
- this.maxDelta_ = Math.sqrt(ol.geom.flat.closest.getssMaxSquaredDelta(
- this.flatCoordinates, 0, this.endss_, this.stride, 0));
- this.maxDeltaRevision_ = this.getRevision();
- }
- return ol.geom.flat.closest.getssClosestPoint(
- this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride,
- this.maxDelta_, true, x, y, closestPoint, minSquaredDistance);
- };
- /**
- * @inheritDoc
- */
- ol.geom.MultiPolygon.prototype.containsXY = function(x, y) {
- return ol.geom.flat.contains.linearRingssContainsXY(
- this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, x, y);
- };
- /**
- * Return the area of the multipolygon on projected plane.
- * @return {number} Area (on projected plane).
- * @api
- */
- ol.geom.MultiPolygon.prototype.getArea = function() {
- return ol.geom.flat.area.linearRingss(
- this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride);
- };
- /**
- * Get the coordinate array for this geometry. This array has the structure
- * of a GeoJSON coordinate array for multi-polygons.
- *
- * @param {boolean=} opt_right Orient coordinates according to the right-hand
- * rule (counter-clockwise for exterior and clockwise for interior rings).
- * If `false`, coordinates will be oriented according to the left-hand rule
- * (clockwise for exterior and counter-clockwise for interior rings).
- * By default, coordinate orientation will depend on how the geometry was
- * constructed.
- * @return {Array.<Array.<Array.<ol.Coordinate>>>} Coordinates.
- * @override
- * @api
- */
- ol.geom.MultiPolygon.prototype.getCoordinates = function(opt_right) {
- var flatCoordinates;
- if (opt_right !== undefined) {
- flatCoordinates = this.getOrientedFlatCoordinates().slice();
- ol.geom.flat.orient.orientLinearRingss(
- flatCoordinates, 0, this.endss_, this.stride, opt_right);
- } else {
- flatCoordinates = this.flatCoordinates;
- }
- return ol.geom.flat.inflate.coordinatesss(
- flatCoordinates, 0, this.endss_, this.stride);
- };
- /**
- * @return {Array.<Array.<number>>} Endss.
- */
- ol.geom.MultiPolygon.prototype.getEndss = function() {
- return this.endss_;
- };
- /**
- * @return {Array.<number>} Flat interior points.
- */
- ol.geom.MultiPolygon.prototype.getFlatInteriorPoints = function() {
- if (this.flatInteriorPointsRevision_ != this.getRevision()) {
- var flatCenters = ol.geom.flat.center.linearRingss(
- this.flatCoordinates, 0, this.endss_, this.stride);
- this.flatInteriorPoints_ = ol.geom.flat.interiorpoint.linearRingss(
- this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride,
- flatCenters);
- this.flatInteriorPointsRevision_ = this.getRevision();
- }
- return this.flatInteriorPoints_;
- };
- /**
- * Return the interior points as {@link ol.geom.MultiPoint multipoint}.
- * @return {ol.geom.MultiPoint} Interior points as XYM coordinates, where M is
- * the length of the horizontal intersection that the point belongs to.
- * @api
- */
- ol.geom.MultiPolygon.prototype.getInteriorPoints = function() {
- var interiorPoints = new ol.geom.MultiPoint(null);
- interiorPoints.setFlatCoordinates(ol.geom.GeometryLayout.XYM,
- this.getFlatInteriorPoints().slice());
- return interiorPoints;
- };
- /**
- * @return {Array.<number>} Oriented flat coordinates.
- */
- ol.geom.MultiPolygon.prototype.getOrientedFlatCoordinates = function() {
- if (this.orientedRevision_ != this.getRevision()) {
- var flatCoordinates = this.flatCoordinates;
- if (ol.geom.flat.orient.linearRingssAreOriented(
- flatCoordinates, 0, this.endss_, this.stride)) {
- this.orientedFlatCoordinates_ = flatCoordinates;
- } else {
- this.orientedFlatCoordinates_ = flatCoordinates.slice();
- this.orientedFlatCoordinates_.length =
- ol.geom.flat.orient.orientLinearRingss(
- this.orientedFlatCoordinates_, 0, this.endss_, this.stride);
- }
- this.orientedRevision_ = this.getRevision();
- }
- return this.orientedFlatCoordinates_;
- };
- /**
- * @inheritDoc
- */
- ol.geom.MultiPolygon.prototype.getSimplifiedGeometryInternal = function(squaredTolerance) {
- var simplifiedFlatCoordinates = [];
- var simplifiedEndss = [];
- simplifiedFlatCoordinates.length = ol.geom.flat.simplify.quantizess(
- this.flatCoordinates, 0, this.endss_, this.stride,
- Math.sqrt(squaredTolerance),
- simplifiedFlatCoordinates, 0, simplifiedEndss);
- var simplifiedMultiPolygon = new ol.geom.MultiPolygon(null);
- simplifiedMultiPolygon.setFlatCoordinates(
- ol.geom.GeometryLayout.XY, simplifiedFlatCoordinates, simplifiedEndss);
- return simplifiedMultiPolygon;
- };
- /**
- * Return the polygon at the specified index.
- * @param {number} index Index.
- * @return {ol.geom.Polygon} Polygon.
- * @api
- */
- ol.geom.MultiPolygon.prototype.getPolygon = function(index) {
- if (index < 0 || this.endss_.length <= index) {
- return null;
- }
- var offset;
- if (index === 0) {
- offset = 0;
- } else {
- var prevEnds = this.endss_[index - 1];
- offset = prevEnds[prevEnds.length - 1];
- }
- var ends = this.endss_[index].slice();
- var end = ends[ends.length - 1];
- if (offset !== 0) {
- var i, ii;
- for (i = 0, ii = ends.length; i < ii; ++i) {
- ends[i] -= offset;
- }
- }
- var polygon = new ol.geom.Polygon(null);
- polygon.setFlatCoordinates(
- this.layout, this.flatCoordinates.slice(offset, end), ends);
- return polygon;
- };
- /**
- * Return the polygons of this multipolygon.
- * @return {Array.<ol.geom.Polygon>} Polygons.
- * @api
- */
- ol.geom.MultiPolygon.prototype.getPolygons = function() {
- var layout = this.layout;
- var flatCoordinates = this.flatCoordinates;
- var endss = this.endss_;
- var polygons = [];
- var offset = 0;
- var i, ii, j, jj;
- for (i = 0, ii = endss.length; i < ii; ++i) {
- var ends = endss[i].slice();
- var end = ends[ends.length - 1];
- if (offset !== 0) {
- for (j = 0, jj = ends.length; j < jj; ++j) {
- ends[j] -= offset;
- }
- }
- var polygon = new ol.geom.Polygon(null);
- polygon.setFlatCoordinates(
- layout, flatCoordinates.slice(offset, end), ends);
- polygons.push(polygon);
- offset = end;
- }
- return polygons;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.MultiPolygon.prototype.getType = function() {
- return ol.geom.GeometryType.MULTI_POLYGON;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.MultiPolygon.prototype.intersectsExtent = function(extent) {
- return ol.geom.flat.intersectsextent.linearRingss(
- this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, extent);
- };
- /**
- * Set the coordinates of the multipolygon.
- * @param {Array.<Array.<Array.<ol.Coordinate>>>} coordinates Coordinates.
- * @param {ol.geom.GeometryLayout=} opt_layout Layout.
- * @override
- * @api
- */
- ol.geom.MultiPolygon.prototype.setCoordinates = function(coordinates, opt_layout) {
- if (!coordinates) {
- this.setFlatCoordinates(ol.geom.GeometryLayout.XY, null, this.endss_);
- } else {
- this.setLayout(opt_layout, coordinates, 3);
- if (!this.flatCoordinates) {
- this.flatCoordinates = [];
- }
- var endss = ol.geom.flat.deflate.coordinatesss(
- this.flatCoordinates, 0, coordinates, this.stride, this.endss_);
- if (endss.length === 0) {
- this.flatCoordinates.length = 0;
- } else {
- var lastEnds = endss[endss.length - 1];
- this.flatCoordinates.length = lastEnds.length === 0 ?
- 0 : lastEnds[lastEnds.length - 1];
- }
- this.changed();
- }
- };
- /**
- * @param {ol.geom.GeometryLayout} layout Layout.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {Array.<Array.<number>>} endss Endss.
- */
- ol.geom.MultiPolygon.prototype.setFlatCoordinates = function(layout, flatCoordinates, endss) {
- this.setFlatCoordinatesInternal(layout, flatCoordinates);
- this.endss_ = endss;
- this.changed();
- };
- /**
- * @param {Array.<ol.geom.Polygon>} polygons Polygons.
- */
- ol.geom.MultiPolygon.prototype.setPolygons = function(polygons) {
- var layout = this.getLayout();
- var flatCoordinates = [];
- var endss = [];
- var i, ii, ends;
- for (i = 0, ii = polygons.length; i < ii; ++i) {
- var polygon = polygons[i];
- if (i === 0) {
- layout = polygon.getLayout();
- }
- var offset = flatCoordinates.length;
- ends = polygon.getEnds();
- var j, jj;
- for (j = 0, jj = ends.length; j < jj; ++j) {
- ends[j] += offset;
- }
- ol.array.extend(flatCoordinates, polygon.getFlatCoordinates());
- endss.push(ends);
- }
- this.setFlatCoordinates(layout, flatCoordinates, endss);
- };
- goog.provide('ol.format.EsriJSON');
- goog.require('ol');
- goog.require('ol.Feature');
- goog.require('ol.asserts');
- goog.require('ol.extent');
- goog.require('ol.format.Feature');
- goog.require('ol.format.JSONFeature');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.LineString');
- goog.require('ol.geom.LinearRing');
- goog.require('ol.geom.MultiLineString');
- goog.require('ol.geom.MultiPoint');
- goog.require('ol.geom.MultiPolygon');
- goog.require('ol.geom.Point');
- goog.require('ol.geom.Polygon');
- goog.require('ol.geom.flat.deflate');
- goog.require('ol.geom.flat.orient');
- goog.require('ol.obj');
- goog.require('ol.proj');
- /**
- * @classdesc
- * Feature format for reading and writing data in the EsriJSON format.
- *
- * @constructor
- * @extends {ol.format.JSONFeature}
- * @param {olx.format.EsriJSONOptions=} opt_options Options.
- * @api
- */
- ol.format.EsriJSON = function(opt_options) {
- var options = opt_options ? opt_options : {};
- ol.format.JSONFeature.call(this);
- /**
- * Name of the geometry attribute for features.
- * @type {string|undefined}
- * @private
- */
- this.geometryName_ = options.geometryName;
- };
- ol.inherits(ol.format.EsriJSON, ol.format.JSONFeature);
- /**
- * @param {EsriJSONGeometry} object Object.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @private
- * @return {ol.geom.Geometry} Geometry.
- */
- ol.format.EsriJSON.readGeometry_ = function(object, opt_options) {
- if (!object) {
- return null;
- }
- /** @type {ol.geom.GeometryType} */
- var type;
- if (typeof object.x === 'number' && typeof object.y === 'number') {
- type = ol.geom.GeometryType.POINT;
- } else if (object.points) {
- type = ol.geom.GeometryType.MULTI_POINT;
- } else if (object.paths) {
- if (object.paths.length === 1) {
- type = ol.geom.GeometryType.LINE_STRING;
- } else {
- type = ol.geom.GeometryType.MULTI_LINE_STRING;
- }
- } else if (object.rings) {
- var layout = ol.format.EsriJSON.getGeometryLayout_(object);
- var rings = ol.format.EsriJSON.convertRings_(object.rings, layout);
- object = /** @type {EsriJSONGeometry} */(ol.obj.assign({}, object));
- if (rings.length === 1) {
- type = ol.geom.GeometryType.POLYGON;
- object.rings = rings[0];
- } else {
- type = ol.geom.GeometryType.MULTI_POLYGON;
- object.rings = rings;
- }
- }
- var geometryReader = ol.format.EsriJSON.GEOMETRY_READERS_[type];
- return /** @type {ol.geom.Geometry} */ (
- ol.format.Feature.transformWithOptions(
- geometryReader(object), false, opt_options));
- };
- /**
- * Determines inner and outer rings.
- * Checks if any polygons in this array contain any other polygons in this
- * array. It is used for checking for holes.
- * Logic inspired by: https://github.com/Esri/terraformer-arcgis-parser
- * @param {Array.<!Array.<!Array.<number>>>} rings Rings.
- * @param {ol.geom.GeometryLayout} layout Geometry layout.
- * @private
- * @return {Array.<!Array.<!Array.<number>>>} Transformed rings.
- */
- ol.format.EsriJSON.convertRings_ = function(rings, layout) {
- var flatRing = [];
- var outerRings = [];
- var holes = [];
- var i, ii;
- for (i = 0, ii = rings.length; i < ii; ++i) {
- flatRing.length = 0;
- ol.geom.flat.deflate.coordinates(flatRing, 0, rings[i], layout.length);
- // is this ring an outer ring? is it clockwise?
- var clockwise = ol.geom.flat.orient.linearRingIsClockwise(flatRing, 0,
- flatRing.length, layout.length);
- if (clockwise) {
- outerRings.push([rings[i]]);
- } else {
- holes.push(rings[i]);
- }
- }
- while (holes.length) {
- var hole = holes.shift();
- var matched = false;
- // loop over all outer rings and see if they contain our hole.
- for (i = outerRings.length - 1; i >= 0; i--) {
- var outerRing = outerRings[i][0];
- var containsHole = ol.extent.containsExtent(
- new ol.geom.LinearRing(outerRing).getExtent(),
- new ol.geom.LinearRing(hole).getExtent()
- );
- if (containsHole) {
- // the hole is contained push it into our polygon
- outerRings[i].push(hole);
- matched = true;
- break;
- }
- }
- if (!matched) {
- // no outer rings contain this hole turn it into and outer
- // ring (reverse it)
- outerRings.push([hole.reverse()]);
- }
- }
- return outerRings;
- };
- /**
- * @param {EsriJSONGeometry} object Object.
- * @private
- * @return {ol.geom.Geometry} Point.
- */
- ol.format.EsriJSON.readPointGeometry_ = function(object) {
- var point;
- if (object.m !== undefined && object.z !== undefined) {
- point = new ol.geom.Point([object.x, object.y, object.z, object.m],
- ol.geom.GeometryLayout.XYZM);
- } else if (object.z !== undefined) {
- point = new ol.geom.Point([object.x, object.y, object.z],
- ol.geom.GeometryLayout.XYZ);
- } else if (object.m !== undefined) {
- point = new ol.geom.Point([object.x, object.y, object.m],
- ol.geom.GeometryLayout.XYM);
- } else {
- point = new ol.geom.Point([object.x, object.y]);
- }
- return point;
- };
- /**
- * @param {EsriJSONGeometry} object Object.
- * @private
- * @return {ol.geom.Geometry} LineString.
- */
- ol.format.EsriJSON.readLineStringGeometry_ = function(object) {
- var layout = ol.format.EsriJSON.getGeometryLayout_(object);
- return new ol.geom.LineString(object.paths[0], layout);
- };
- /**
- * @param {EsriJSONGeometry} object Object.
- * @private
- * @return {ol.geom.Geometry} MultiLineString.
- */
- ol.format.EsriJSON.readMultiLineStringGeometry_ = function(object) {
- var layout = ol.format.EsriJSON.getGeometryLayout_(object);
- return new ol.geom.MultiLineString(object.paths, layout);
- };
- /**
- * @param {EsriJSONGeometry} object Object.
- * @private
- * @return {ol.geom.GeometryLayout} The geometry layout to use.
- */
- ol.format.EsriJSON.getGeometryLayout_ = function(object) {
- var layout = ol.geom.GeometryLayout.XY;
- if (object.hasZ === true && object.hasM === true) {
- layout = ol.geom.GeometryLayout.XYZM;
- } else if (object.hasZ === true) {
- layout = ol.geom.GeometryLayout.XYZ;
- } else if (object.hasM === true) {
- layout = ol.geom.GeometryLayout.XYM;
- }
- return layout;
- };
- /**
- * @param {EsriJSONGeometry} object Object.
- * @private
- * @return {ol.geom.Geometry} MultiPoint.
- */
- ol.format.EsriJSON.readMultiPointGeometry_ = function(object) {
- var layout = ol.format.EsriJSON.getGeometryLayout_(object);
- return new ol.geom.MultiPoint(object.points, layout);
- };
- /**
- * @param {EsriJSONGeometry} object Object.
- * @private
- * @return {ol.geom.Geometry} MultiPolygon.
- */
- ol.format.EsriJSON.readMultiPolygonGeometry_ = function(object) {
- var layout = ol.format.EsriJSON.getGeometryLayout_(object);
- return new ol.geom.MultiPolygon(
- /** @type {Array.<Array.<Array.<Array.<number>>>>} */(object.rings),
- layout);
- };
- /**
- * @param {EsriJSONGeometry} object Object.
- * @private
- * @return {ol.geom.Geometry} Polygon.
- */
- ol.format.EsriJSON.readPolygonGeometry_ = function(object) {
- var layout = ol.format.EsriJSON.getGeometryLayout_(object);
- return new ol.geom.Polygon(object.rings, layout);
- };
- /**
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @private
- * @return {EsriJSONGeometry} EsriJSON geometry.
- */
- ol.format.EsriJSON.writePointGeometry_ = function(geometry, opt_options) {
- var coordinates = /** @type {ol.geom.Point} */ (geometry).getCoordinates();
- var esriJSON;
- var layout = /** @type {ol.geom.Point} */ (geometry).getLayout();
- if (layout === ol.geom.GeometryLayout.XYZ) {
- esriJSON = /** @type {EsriJSONPoint} */ ({
- x: coordinates[0],
- y: coordinates[1],
- z: coordinates[2]
- });
- } else if (layout === ol.geom.GeometryLayout.XYM) {
- esriJSON = /** @type {EsriJSONPoint} */ ({
- x: coordinates[0],
- y: coordinates[1],
- m: coordinates[2]
- });
- } else if (layout === ol.geom.GeometryLayout.XYZM) {
- esriJSON = /** @type {EsriJSONPoint} */ ({
- x: coordinates[0],
- y: coordinates[1],
- z: coordinates[2],
- m: coordinates[3]
- });
- } else if (layout === ol.geom.GeometryLayout.XY) {
- esriJSON = /** @type {EsriJSONPoint} */ ({
- x: coordinates[0],
- y: coordinates[1]
- });
- } else {
- ol.asserts.assert(false, 34); // Invalid geometry layout
- }
- return /** @type {EsriJSONGeometry} */ (esriJSON);
- };
- /**
- * @param {ol.geom.SimpleGeometry} geometry Geometry.
- * @private
- * @return {Object} Object with boolean hasZ and hasM keys.
- */
- ol.format.EsriJSON.getHasZM_ = function(geometry) {
- var layout = geometry.getLayout();
- return {
- hasZ: (layout === ol.geom.GeometryLayout.XYZ ||
- layout === ol.geom.GeometryLayout.XYZM),
- hasM: (layout === ol.geom.GeometryLayout.XYM ||
- layout === ol.geom.GeometryLayout.XYZM)
- };
- };
- /**
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @private
- * @return {EsriJSONPolyline} EsriJSON geometry.
- */
- ol.format.EsriJSON.writeLineStringGeometry_ = function(geometry, opt_options) {
- var hasZM = ol.format.EsriJSON.getHasZM_(/** @type {ol.geom.LineString} */(geometry));
- return /** @type {EsriJSONPolyline} */ ({
- hasZ: hasZM.hasZ,
- hasM: hasZM.hasM,
- paths: [
- /** @type {ol.geom.LineString} */ (geometry).getCoordinates()
- ]
- });
- };
- /**
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @private
- * @return {EsriJSONPolygon} EsriJSON geometry.
- */
- ol.format.EsriJSON.writePolygonGeometry_ = function(geometry, opt_options) {
- // Esri geometries use the left-hand rule
- var hasZM = ol.format.EsriJSON.getHasZM_(/** @type {ol.geom.Polygon} */(geometry));
- return /** @type {EsriJSONPolygon} */ ({
- hasZ: hasZM.hasZ,
- hasM: hasZM.hasM,
- rings: /** @type {ol.geom.Polygon} */ (geometry).getCoordinates(false)
- });
- };
- /**
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @private
- * @return {EsriJSONPolyline} EsriJSON geometry.
- */
- ol.format.EsriJSON.writeMultiLineStringGeometry_ = function(geometry, opt_options) {
- var hasZM = ol.format.EsriJSON.getHasZM_(/** @type {ol.geom.MultiLineString} */(geometry));
- return /** @type {EsriJSONPolyline} */ ({
- hasZ: hasZM.hasZ,
- hasM: hasZM.hasM,
- paths: /** @type {ol.geom.MultiLineString} */ (geometry).getCoordinates()
- });
- };
- /**
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @private
- * @return {EsriJSONMultipoint} EsriJSON geometry.
- */
- ol.format.EsriJSON.writeMultiPointGeometry_ = function(geometry, opt_options) {
- var hasZM = ol.format.EsriJSON.getHasZM_(/** @type {ol.geom.MultiPoint} */(geometry));
- return /** @type {EsriJSONMultipoint} */ ({
- hasZ: hasZM.hasZ,
- hasM: hasZM.hasM,
- points: /** @type {ol.geom.MultiPoint} */ (geometry).getCoordinates()
- });
- };
- /**
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @private
- * @return {EsriJSONPolygon} EsriJSON geometry.
- */
- ol.format.EsriJSON.writeMultiPolygonGeometry_ = function(geometry,
- opt_options) {
- var hasZM = ol.format.EsriJSON.getHasZM_(/** @type {ol.geom.MultiPolygon} */(geometry));
- var coordinates = /** @type {ol.geom.MultiPolygon} */ (geometry).getCoordinates(false);
- var output = [];
- for (var i = 0; i < coordinates.length; i++) {
- for (var x = coordinates[i].length - 1; x >= 0; x--) {
- output.push(coordinates[i][x]);
- }
- }
- return /** @type {EsriJSONPolygon} */ ({
- hasZ: hasZM.hasZ,
- hasM: hasZM.hasM,
- rings: output
- });
- };
- /**
- * @const
- * @private
- * @type {Object.<ol.geom.GeometryType, function(EsriJSONGeometry): ol.geom.Geometry>}
- */
- ol.format.EsriJSON.GEOMETRY_READERS_ = {};
- ol.format.EsriJSON.GEOMETRY_READERS_[ol.geom.GeometryType.POINT] =
- ol.format.EsriJSON.readPointGeometry_;
- ol.format.EsriJSON.GEOMETRY_READERS_[ol.geom.GeometryType.LINE_STRING] =
- ol.format.EsriJSON.readLineStringGeometry_;
- ol.format.EsriJSON.GEOMETRY_READERS_[ol.geom.GeometryType.POLYGON] =
- ol.format.EsriJSON.readPolygonGeometry_;
- ol.format.EsriJSON.GEOMETRY_READERS_[ol.geom.GeometryType.MULTI_POINT] =
- ol.format.EsriJSON.readMultiPointGeometry_;
- ol.format.EsriJSON.GEOMETRY_READERS_[ol.geom.GeometryType.MULTI_LINE_STRING] =
- ol.format.EsriJSON.readMultiLineStringGeometry_;
- ol.format.EsriJSON.GEOMETRY_READERS_[ol.geom.GeometryType.MULTI_POLYGON] =
- ol.format.EsriJSON.readMultiPolygonGeometry_;
- /**
- * @const
- * @private
- * @type {Object.<string, function(ol.geom.Geometry, olx.format.WriteOptions=): (EsriJSONGeometry)>}
- */
- ol.format.EsriJSON.GEOMETRY_WRITERS_ = {};
- ol.format.EsriJSON.GEOMETRY_WRITERS_[ol.geom.GeometryType.POINT] =
- ol.format.EsriJSON.writePointGeometry_;
- ol.format.EsriJSON.GEOMETRY_WRITERS_[ol.geom.GeometryType.LINE_STRING] =
- ol.format.EsriJSON.writeLineStringGeometry_;
- ol.format.EsriJSON.GEOMETRY_WRITERS_[ol.geom.GeometryType.POLYGON] =
- ol.format.EsriJSON.writePolygonGeometry_;
- ol.format.EsriJSON.GEOMETRY_WRITERS_[ol.geom.GeometryType.MULTI_POINT] =
- ol.format.EsriJSON.writeMultiPointGeometry_;
- ol.format.EsriJSON.GEOMETRY_WRITERS_[ol.geom.GeometryType.MULTI_LINE_STRING] =
- ol.format.EsriJSON.writeMultiLineStringGeometry_;
- ol.format.EsriJSON.GEOMETRY_WRITERS_[ol.geom.GeometryType.MULTI_POLYGON] =
- ol.format.EsriJSON.writeMultiPolygonGeometry_;
- /**
- * Read a feature from a EsriJSON Feature source. Only works for Feature,
- * use `readFeatures` to read FeatureCollection source.
- *
- * @function
- * @param {ArrayBuffer|Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {ol.Feature} Feature.
- * @api
- */
- ol.format.EsriJSON.prototype.readFeature;
- /**
- * Read all features from a EsriJSON source. Works with both Feature and
- * FeatureCollection sources.
- *
- * @function
- * @param {ArrayBuffer|Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {Array.<ol.Feature>} Features.
- * @api
- */
- ol.format.EsriJSON.prototype.readFeatures;
- /**
- * @inheritDoc
- */
- ol.format.EsriJSON.prototype.readFeatureFromObject = function(
- object, opt_options) {
- var esriJSONFeature = /** @type {EsriJSONFeature} */ (object);
- var geometry = ol.format.EsriJSON.readGeometry_(esriJSONFeature.geometry,
- opt_options);
- var feature = new ol.Feature();
- if (this.geometryName_) {
- feature.setGeometryName(this.geometryName_);
- }
- feature.setGeometry(geometry);
- if (opt_options && opt_options.idField &&
- esriJSONFeature.attributes[opt_options.idField]) {
- feature.setId(/** @type {number} */(
- esriJSONFeature.attributes[opt_options.idField]));
- }
- if (esriJSONFeature.attributes) {
- feature.setProperties(esriJSONFeature.attributes);
- }
- return feature;
- };
- /**
- * @inheritDoc
- */
- ol.format.EsriJSON.prototype.readFeaturesFromObject = function(
- object, opt_options) {
- var esriJSONObject = /** @type {EsriJSONObject} */ (object);
- var options = opt_options ? opt_options : {};
- if (esriJSONObject.features) {
- var esriJSONFeatureCollection = /** @type {EsriJSONFeatureCollection} */
- (object);
- /** @type {Array.<ol.Feature>} */
- var features = [];
- var esriJSONFeatures = esriJSONFeatureCollection.features;
- var i, ii;
- options.idField = object.objectIdFieldName;
- for (i = 0, ii = esriJSONFeatures.length; i < ii; ++i) {
- features.push(this.readFeatureFromObject(esriJSONFeatures[i],
- options));
- }
- return features;
- } else {
- return [this.readFeatureFromObject(object, options)];
- }
- };
- /**
- * Read a geometry from a EsriJSON source.
- *
- * @function
- * @param {ArrayBuffer|Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {ol.geom.Geometry} Geometry.
- * @api
- */
- ol.format.EsriJSON.prototype.readGeometry;
- /**
- * @inheritDoc
- */
- ol.format.EsriJSON.prototype.readGeometryFromObject = function(
- object, opt_options) {
- return ol.format.EsriJSON.readGeometry_(
- /** @type {EsriJSONGeometry} */(object), opt_options);
- };
- /**
- * Read the projection from a EsriJSON source.
- *
- * @function
- * @param {ArrayBuffer|Document|Node|Object|string} source Source.
- * @return {ol.proj.Projection} Projection.
- * @api
- */
- ol.format.EsriJSON.prototype.readProjection;
- /**
- * @inheritDoc
- */
- ol.format.EsriJSON.prototype.readProjectionFromObject = function(object) {
- var esriJSONObject = /** @type {EsriJSONObject} */ (object);
- if (esriJSONObject.spatialReference && esriJSONObject.spatialReference.wkid) {
- var crs = esriJSONObject.spatialReference.wkid;
- return ol.proj.get('EPSG:' + crs);
- } else {
- return null;
- }
- };
- /**
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @private
- * @return {EsriJSONGeometry} EsriJSON geometry.
- */
- ol.format.EsriJSON.writeGeometry_ = function(geometry, opt_options) {
- var geometryWriter = ol.format.EsriJSON.GEOMETRY_WRITERS_[geometry.getType()];
- return geometryWriter(/** @type {ol.geom.Geometry} */(
- ol.format.Feature.transformWithOptions(geometry, true, opt_options)),
- opt_options);
- };
- /**
- * Encode a geometry as a EsriJSON string.
- *
- * @function
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {string} EsriJSON.
- * @api
- */
- ol.format.EsriJSON.prototype.writeGeometry;
- /**
- * Encode a geometry as a EsriJSON object.
- *
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {EsriJSONGeometry} Object.
- * @override
- * @api
- */
- ol.format.EsriJSON.prototype.writeGeometryObject = function(geometry,
- opt_options) {
- return ol.format.EsriJSON.writeGeometry_(geometry,
- this.adaptOptions(opt_options));
- };
- /**
- * Encode a feature as a EsriJSON Feature string.
- *
- * @function
- * @param {ol.Feature} feature Feature.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {string} EsriJSON.
- * @api
- */
- ol.format.EsriJSON.prototype.writeFeature;
- /**
- * Encode a feature as a esriJSON Feature object.
- *
- * @param {ol.Feature} feature Feature.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {Object} Object.
- * @override
- * @api
- */
- ol.format.EsriJSON.prototype.writeFeatureObject = function(
- feature, opt_options) {
- opt_options = this.adaptOptions(opt_options);
- var object = {};
- var geometry = feature.getGeometry();
- if (geometry) {
- object['geometry'] =
- ol.format.EsriJSON.writeGeometry_(geometry, opt_options);
- if (opt_options && opt_options.featureProjection) {
- object['geometry']['spatialReference'] = /** @type {EsriJSONCRS} */({
- wkid: ol.proj.get(
- opt_options.featureProjection).getCode().split(':').pop()
- });
- }
- }
- var properties = feature.getProperties();
- delete properties[feature.getGeometryName()];
- if (!ol.obj.isEmpty(properties)) {
- object['attributes'] = properties;
- } else {
- object['attributes'] = {};
- }
- return object;
- };
- /**
- * Encode an array of features as EsriJSON.
- *
- * @function
- * @param {Array.<ol.Feature>} features Features.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {string} EsriJSON.
- * @api
- */
- ol.format.EsriJSON.prototype.writeFeatures;
- /**
- * Encode an array of features as a EsriJSON object.
- *
- * @param {Array.<ol.Feature>} features Features.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {Object} EsriJSON Object.
- * @override
- * @api
- */
- ol.format.EsriJSON.prototype.writeFeaturesObject = function(features, opt_options) {
- opt_options = this.adaptOptions(opt_options);
- var objects = [];
- var i, ii;
- for (i = 0, ii = features.length; i < ii; ++i) {
- objects.push(this.writeFeatureObject(features[i], opt_options));
- }
- return /** @type {EsriJSONFeatureCollection} */ ({
- 'features': objects
- });
- };
- goog.provide('ol.format.filter.Filter');
- /**
- * @classdesc
- * Abstract class; normally only used for creating subclasses and not instantiated in apps.
- * Base class for WFS GetFeature filters.
- *
- * deprecated: This class will no longer be exported starting from the next major version.
- *
- * @constructor
- * @abstract
- * @param {!string} tagName The XML tag name for this filter.
- * @struct
- * @api
- */
- ol.format.filter.Filter = function(tagName) {
- /**
- * @private
- * @type {!string}
- */
- this.tagName_ = tagName;
- };
- /**
- * The XML tag name for a filter.
- * @returns {!string} Name.
- */
- ol.format.filter.Filter.prototype.getTagName = function() {
- return this.tagName_;
- };
- goog.provide('ol.format.filter.LogicalNary');
- goog.require('ol');
- goog.require('ol.asserts');
- goog.require('ol.format.filter.Filter');
- /**
- * @classdesc
- * Abstract class; normally only used for creating subclasses and not instantiated in apps.
- * Base class for WFS GetFeature n-ary logical filters.
- *
- * @constructor
- * @abstract
- * @param {!string} tagName The XML tag name for this filter.
- * @param {...ol.format.filter.Filter} conditions Conditions.
- * @extends {ol.format.filter.Filter}
- */
- ol.format.filter.LogicalNary = function(tagName, conditions) {
- ol.format.filter.Filter.call(this, tagName);
- /**
- * @public
- * @type {Array.<ol.format.filter.Filter>}
- */
- this.conditions = Array.prototype.slice.call(arguments, 1);
- ol.asserts.assert(this.conditions.length >= 2, 57); // At least 2 conditions are required.
- };
- ol.inherits(ol.format.filter.LogicalNary, ol.format.filter.Filter);
- goog.provide('ol.format.filter.And');
- goog.require('ol');
- goog.require('ol.format.filter.LogicalNary');
- /**
- * @classdesc
- * Represents a logical `<And>` operator between two or more filter conditions.
- *
- * deprecated: This class will no longer be exported starting from the next major version.
- *
- * @constructor
- * @abstract
- * @param {...ol.format.filter.Filter} conditions Conditions.
- * @extends {ol.format.filter.LogicalNary}
- * @api
- */
- ol.format.filter.And = function(conditions) {
- var params = ['And'].concat(Array.prototype.slice.call(arguments));
- ol.format.filter.LogicalNary.apply(this, params);
- };
- ol.inherits(ol.format.filter.And, ol.format.filter.LogicalNary);
- goog.provide('ol.format.filter.Bbox');
- goog.require('ol');
- goog.require('ol.format.filter.Filter');
- /**
- * @classdesc
- * Represents a `<BBOX>` operator to test whether a geometry-valued property
- * intersects a fixed bounding box
- *
- * @constructor
- * @param {!string} geometryName Geometry name to use.
- * @param {!ol.Extent} extent Extent.
- * @param {string=} opt_srsName SRS name. No srsName attribute will be
- * set on geometries when this is not provided.
- * @extends {ol.format.filter.Filter}
- * @api
- */
- ol.format.filter.Bbox = function(geometryName, extent, opt_srsName) {
- ol.format.filter.Filter.call(this, 'BBOX');
- /**
- * @public
- * @type {!string}
- */
- this.geometryName = geometryName;
- /**
- * @public
- * @type {ol.Extent}
- */
- this.extent = extent;
- /**
- * @public
- * @type {string|undefined}
- */
- this.srsName = opt_srsName;
- };
- ol.inherits(ol.format.filter.Bbox, ol.format.filter.Filter);
- goog.provide('ol.format.filter.Spatial');
- goog.require('ol');
- goog.require('ol.format.filter.Filter');
- /**
- * @classdesc
- * Abstract class; normally only used for creating subclasses and not instantiated in apps.
- * Represents a spatial operator to test whether a geometry-valued property
- * relates to a given geometry.
- *
- * deprecated: This class will no longer be exported starting from the next major version.
- *
- * @constructor
- * @abstract
- * @param {!string} tagName The XML tag name for this filter.
- * @param {!string} geometryName Geometry name to use.
- * @param {!ol.geom.Geometry} geometry Geometry.
- * @param {string=} opt_srsName SRS name. No srsName attribute will be
- * set on geometries when this is not provided.
- * @extends {ol.format.filter.Filter}
- * @api
- */
- ol.format.filter.Spatial = function(tagName, geometryName, geometry, opt_srsName) {
- ol.format.filter.Filter.call(this, tagName);
- /**
- * @public
- * @type {!string}
- */
- this.geometryName = geometryName || 'the_geom';
- /**
- * @public
- * @type {ol.geom.Geometry}
- */
- this.geometry = geometry;
- /**
- * @public
- * @type {string|undefined}
- */
- this.srsName = opt_srsName;
- };
- ol.inherits(ol.format.filter.Spatial, ol.format.filter.Filter);
- goog.provide('ol.format.filter.Contains');
- goog.require('ol');
- goog.require('ol.format.filter.Spatial');
- /**
- * @classdesc
- * Represents a `<Contains>` operator to test whether a geometry-valued property
- * contains a given geometry.
- *
- * @constructor
- * @param {!string} geometryName Geometry name to use.
- * @param {!ol.geom.Geometry} geometry Geometry.
- * @param {string=} opt_srsName SRS name. No srsName attribute will be
- * set on geometries when this is not provided.
- * @extends {ol.format.filter.Spatial}
- * @api
- */
- ol.format.filter.Contains = function(geometryName, geometry, opt_srsName) {
- ol.format.filter.Spatial.call(this, 'Contains', geometryName, geometry, opt_srsName);
- };
- ol.inherits(ol.format.filter.Contains, ol.format.filter.Spatial);
- goog.provide('ol.format.filter.Comparison');
- goog.require('ol');
- goog.require('ol.format.filter.Filter');
- /**
- * @classdesc
- * Abstract class; normally only used for creating subclasses and not instantiated in apps.
- * Base class for WFS GetFeature property comparison filters.
- *
- * deprecated: This class will no longer be exported starting from the next major version.
- *
- * @constructor
- * @abstract
- * @param {!string} tagName The XML tag name for this filter.
- * @param {!string} propertyName Name of the context property to compare.
- * @extends {ol.format.filter.Filter}
- * @api
- */
- ol.format.filter.Comparison = function(tagName, propertyName) {
- ol.format.filter.Filter.call(this, tagName);
- /**
- * @public
- * @type {!string}
- */
- this.propertyName = propertyName;
- };
- ol.inherits(ol.format.filter.Comparison, ol.format.filter.Filter);
- goog.provide('ol.format.filter.During');
- goog.require('ol');
- goog.require('ol.format.filter.Comparison');
- /**
- * @classdesc
- * Represents a `<During>` comparison operator.
- *
- * @constructor
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!string} begin The begin date in ISO-8601 format.
- * @param {!string} end The end date in ISO-8601 format.
- * @extends {ol.format.filter.Comparison}
- * @api
- */
- ol.format.filter.During = function(propertyName, begin, end) {
- ol.format.filter.Comparison.call(this, 'During', propertyName);
- /**
- * @public
- * @type {!string}
- */
- this.begin = begin;
- /**
- * @public
- * @type {!string}
- */
- this.end = end;
- };
- ol.inherits(ol.format.filter.During, ol.format.filter.Comparison);
- goog.provide('ol.format.filter.ComparisonBinary');
- goog.require('ol');
- goog.require('ol.format.filter.Comparison');
- /**
- * @classdesc
- * Abstract class; normally only used for creating subclasses and not instantiated in apps.
- * Base class for WFS GetFeature property binary comparison filters.
- *
- * deprecated: This class will no longer be exported starting from the next major version.
- *
- * @constructor
- * @abstract
- * @param {!string} tagName The XML tag name for this filter.
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!(string|number)} expression The value to compare.
- * @param {boolean=} opt_matchCase Case-sensitive?
- * @extends {ol.format.filter.Comparison}
- * @api
- */
- ol.format.filter.ComparisonBinary = function(
- tagName, propertyName, expression, opt_matchCase) {
- ol.format.filter.Comparison.call(this, tagName, propertyName);
- /**
- * @public
- * @type {!(string|number)}
- */
- this.expression = expression;
- /**
- * @public
- * @type {boolean|undefined}
- */
- this.matchCase = opt_matchCase;
- };
- ol.inherits(ol.format.filter.ComparisonBinary, ol.format.filter.Comparison);
- goog.provide('ol.format.filter.EqualTo');
- goog.require('ol');
- goog.require('ol.format.filter.ComparisonBinary');
- /**
- * @classdesc
- * Represents a `<PropertyIsEqualTo>` comparison operator.
- *
- * @constructor
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!(string|number)} expression The value to compare.
- * @param {boolean=} opt_matchCase Case-sensitive?
- * @extends {ol.format.filter.ComparisonBinary}
- * @api
- */
- ol.format.filter.EqualTo = function(propertyName, expression, opt_matchCase) {
- ol.format.filter.ComparisonBinary.call(this, 'PropertyIsEqualTo', propertyName, expression, opt_matchCase);
- };
- ol.inherits(ol.format.filter.EqualTo, ol.format.filter.ComparisonBinary);
- goog.provide('ol.format.filter.GreaterThan');
- goog.require('ol');
- goog.require('ol.format.filter.ComparisonBinary');
- /**
- * @classdesc
- * Represents a `<PropertyIsGreaterThan>` comparison operator.
- *
- * @constructor
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!number} expression The value to compare.
- * @extends {ol.format.filter.ComparisonBinary}
- * @api
- */
- ol.format.filter.GreaterThan = function(propertyName, expression) {
- ol.format.filter.ComparisonBinary.call(this, 'PropertyIsGreaterThan', propertyName, expression);
- };
- ol.inherits(ol.format.filter.GreaterThan, ol.format.filter.ComparisonBinary);
- goog.provide('ol.format.filter.GreaterThanOrEqualTo');
- goog.require('ol');
- goog.require('ol.format.filter.ComparisonBinary');
- /**
- * @classdesc
- * Represents a `<PropertyIsGreaterThanOrEqualTo>` comparison operator.
- *
- * @constructor
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!number} expression The value to compare.
- * @extends {ol.format.filter.ComparisonBinary}
- * @api
- */
- ol.format.filter.GreaterThanOrEqualTo = function(propertyName, expression) {
- ol.format.filter.ComparisonBinary.call(this, 'PropertyIsGreaterThanOrEqualTo', propertyName, expression);
- };
- ol.inherits(ol.format.filter.GreaterThanOrEqualTo, ol.format.filter.ComparisonBinary);
- goog.provide('ol.format.filter.Intersects');
- goog.require('ol');
- goog.require('ol.format.filter.Spatial');
- /**
- * @classdesc
- * Represents a `<Intersects>` operator to test whether a geometry-valued property
- * intersects a given geometry.
- *
- * @constructor
- * @param {!string} geometryName Geometry name to use.
- * @param {!ol.geom.Geometry} geometry Geometry.
- * @param {string=} opt_srsName SRS name. No srsName attribute will be
- * set on geometries when this is not provided.
- * @extends {ol.format.filter.Spatial}
- * @api
- */
- ol.format.filter.Intersects = function(geometryName, geometry, opt_srsName) {
- ol.format.filter.Spatial.call(this, 'Intersects', geometryName, geometry, opt_srsName);
- };
- ol.inherits(ol.format.filter.Intersects, ol.format.filter.Spatial);
- goog.provide('ol.format.filter.IsBetween');
- goog.require('ol');
- goog.require('ol.format.filter.Comparison');
- /**
- * @classdesc
- * Represents a `<PropertyIsBetween>` comparison operator.
- *
- * @constructor
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!number} lowerBoundary The lower bound of the range.
- * @param {!number} upperBoundary The upper bound of the range.
- * @extends {ol.format.filter.Comparison}
- * @api
- */
- ol.format.filter.IsBetween = function(propertyName, lowerBoundary, upperBoundary) {
- ol.format.filter.Comparison.call(this, 'PropertyIsBetween', propertyName);
- /**
- * @public
- * @type {!number}
- */
- this.lowerBoundary = lowerBoundary;
- /**
- * @public
- * @type {!number}
- */
- this.upperBoundary = upperBoundary;
- };
- ol.inherits(ol.format.filter.IsBetween, ol.format.filter.Comparison);
- goog.provide('ol.format.filter.IsLike');
- goog.require('ol');
- goog.require('ol.format.filter.Comparison');
- /**
- * @classdesc
- * Represents a `<PropertyIsLike>` comparison operator.
- *
- * @constructor
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!string} pattern Text pattern.
- * @param {string=} opt_wildCard Pattern character which matches any sequence of
- * zero or more string characters. Default is '*'.
- * @param {string=} opt_singleChar pattern character which matches any single
- * string character. Default is '.'.
- * @param {string=} opt_escapeChar Escape character which can be used to escape
- * the pattern characters. Default is '!'.
- * @param {boolean=} opt_matchCase Case-sensitive?
- * @extends {ol.format.filter.Comparison}
- * @api
- */
- ol.format.filter.IsLike = function(propertyName, pattern,
- opt_wildCard, opt_singleChar, opt_escapeChar, opt_matchCase) {
- ol.format.filter.Comparison.call(this, 'PropertyIsLike', propertyName);
- /**
- * @public
- * @type {!string}
- */
- this.pattern = pattern;
- /**
- * @public
- * @type {!string}
- */
- this.wildCard = (opt_wildCard !== undefined) ? opt_wildCard : '*';
- /**
- * @public
- * @type {!string}
- */
- this.singleChar = (opt_singleChar !== undefined) ? opt_singleChar : '.';
- /**
- * @public
- * @type {!string}
- */
- this.escapeChar = (opt_escapeChar !== undefined) ? opt_escapeChar : '!';
- /**
- * @public
- * @type {boolean|undefined}
- */
- this.matchCase = opt_matchCase;
- };
- ol.inherits(ol.format.filter.IsLike, ol.format.filter.Comparison);
- goog.provide('ol.format.filter.IsNull');
- goog.require('ol');
- goog.require('ol.format.filter.Comparison');
- /**
- * @classdesc
- * Represents a `<PropertyIsNull>` comparison operator.
- *
- * @constructor
- * @param {!string} propertyName Name of the context property to compare.
- * @extends {ol.format.filter.Comparison}
- * @api
- */
- ol.format.filter.IsNull = function(propertyName) {
- ol.format.filter.Comparison.call(this, 'PropertyIsNull', propertyName);
- };
- ol.inherits(ol.format.filter.IsNull, ol.format.filter.Comparison);
- goog.provide('ol.format.filter.LessThan');
- goog.require('ol');
- goog.require('ol.format.filter.ComparisonBinary');
- /**
- * @classdesc
- * Represents a `<PropertyIsLessThan>` comparison operator.
- *
- * @constructor
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!number} expression The value to compare.
- * @extends {ol.format.filter.ComparisonBinary}
- * @api
- */
- ol.format.filter.LessThan = function(propertyName, expression) {
- ol.format.filter.ComparisonBinary.call(this, 'PropertyIsLessThan', propertyName, expression);
- };
- ol.inherits(ol.format.filter.LessThan, ol.format.filter.ComparisonBinary);
- goog.provide('ol.format.filter.LessThanOrEqualTo');
- goog.require('ol');
- goog.require('ol.format.filter.ComparisonBinary');
- /**
- * @classdesc
- * Represents a `<PropertyIsLessThanOrEqualTo>` comparison operator.
- *
- * @constructor
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!number} expression The value to compare.
- * @extends {ol.format.filter.ComparisonBinary}
- * @api
- */
- ol.format.filter.LessThanOrEqualTo = function(propertyName, expression) {
- ol.format.filter.ComparisonBinary.call(this, 'PropertyIsLessThanOrEqualTo', propertyName, expression);
- };
- ol.inherits(ol.format.filter.LessThanOrEqualTo, ol.format.filter.ComparisonBinary);
- goog.provide('ol.format.filter.Not');
- goog.require('ol');
- goog.require('ol.format.filter.Filter');
- /**
- * @classdesc
- * Represents a logical `<Not>` operator for a filter condition.
- *
- * @constructor
- * @param {!ol.format.filter.Filter} condition Filter condition.
- * @extends {ol.format.filter.Filter}
- * @api
- */
- ol.format.filter.Not = function(condition) {
- ol.format.filter.Filter.call(this, 'Not');
- /**
- * @public
- * @type {!ol.format.filter.Filter}
- */
- this.condition = condition;
- };
- ol.inherits(ol.format.filter.Not, ol.format.filter.Filter);
- goog.provide('ol.format.filter.NotEqualTo');
- goog.require('ol');
- goog.require('ol.format.filter.ComparisonBinary');
- /**
- * @classdesc
- * Represents a `<PropertyIsNotEqualTo>` comparison operator.
- *
- * @constructor
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!(string|number)} expression The value to compare.
- * @param {boolean=} opt_matchCase Case-sensitive?
- * @extends {ol.format.filter.ComparisonBinary}
- * @api
- */
- ol.format.filter.NotEqualTo = function(propertyName, expression, opt_matchCase) {
- ol.format.filter.ComparisonBinary.call(this, 'PropertyIsNotEqualTo', propertyName, expression, opt_matchCase);
- };
- ol.inherits(ol.format.filter.NotEqualTo, ol.format.filter.ComparisonBinary);
- goog.provide('ol.format.filter.Or');
- goog.require('ol');
- goog.require('ol.format.filter.LogicalNary');
- /**
- * @classdesc
- * Represents a logical `<Or>` operator between two ore more filter conditions.
- *
- * @constructor
- * @param {...ol.format.filter.Filter} conditions Conditions.
- * @extends {ol.format.filter.LogicalNary}
- * @api
- */
- ol.format.filter.Or = function(conditions) {
- var params = ['Or'].concat(Array.prototype.slice.call(arguments));
- ol.format.filter.LogicalNary.apply(this, params);
- };
- ol.inherits(ol.format.filter.Or, ol.format.filter.LogicalNary);
- goog.provide('ol.format.filter.Within');
- goog.require('ol');
- goog.require('ol.format.filter.Spatial');
- /**
- * @classdesc
- * Represents a `<Within>` operator to test whether a geometry-valued property
- * is within a given geometry.
- *
- * @constructor
- * @param {!string} geometryName Geometry name to use.
- * @param {!ol.geom.Geometry} geometry Geometry.
- * @param {string=} opt_srsName SRS name. No srsName attribute will be
- * set on geometries when this is not provided.
- * @extends {ol.format.filter.Spatial}
- * @api
- */
- ol.format.filter.Within = function(geometryName, geometry, opt_srsName) {
- ol.format.filter.Spatial.call(this, 'Within', geometryName, geometry, opt_srsName);
- };
- ol.inherits(ol.format.filter.Within, ol.format.filter.Spatial);
- goog.provide('ol.format.filter');
- goog.require('ol.format.filter.And');
- goog.require('ol.format.filter.Bbox');
- goog.require('ol.format.filter.Contains');
- goog.require('ol.format.filter.During');
- goog.require('ol.format.filter.EqualTo');
- goog.require('ol.format.filter.GreaterThan');
- goog.require('ol.format.filter.GreaterThanOrEqualTo');
- goog.require('ol.format.filter.Intersects');
- goog.require('ol.format.filter.IsBetween');
- goog.require('ol.format.filter.IsLike');
- goog.require('ol.format.filter.IsNull');
- goog.require('ol.format.filter.LessThan');
- goog.require('ol.format.filter.LessThanOrEqualTo');
- goog.require('ol.format.filter.Not');
- goog.require('ol.format.filter.NotEqualTo');
- goog.require('ol.format.filter.Or');
- goog.require('ol.format.filter.Within');
- /**
- * Create a logical `<And>` operator between two or more filter conditions.
- *
- * @param {...ol.format.filter.Filter} conditions Filter conditions.
- * @returns {!ol.format.filter.And} `<And>` operator.
- * @api
- */
- ol.format.filter.and = function(conditions) {
- var params = [null].concat(Array.prototype.slice.call(arguments));
- return new (Function.prototype.bind.apply(ol.format.filter.And, params));
- };
- /**
- * Create a logical `<Or>` operator between two or more filter conditions.
- *
- * @param {...ol.format.filter.Filter} conditions Filter conditions.
- * @returns {!ol.format.filter.Or} `<Or>` operator.
- * @api
- */
- ol.format.filter.or = function(conditions) {
- var params = [null].concat(Array.prototype.slice.call(arguments));
- return new (Function.prototype.bind.apply(ol.format.filter.Or, params));
- };
- /**
- * Represents a logical `<Not>` operator for a filter condition.
- *
- * @param {!ol.format.filter.Filter} condition Filter condition.
- * @returns {!ol.format.filter.Not} `<Not>` operator.
- * @api
- */
- ol.format.filter.not = function(condition) {
- return new ol.format.filter.Not(condition);
- };
- /**
- * Create a `<BBOX>` operator to test whether a geometry-valued property
- * intersects a fixed bounding box
- *
- * @param {!string} geometryName Geometry name to use.
- * @param {!ol.Extent} extent Extent.
- * @param {string=} opt_srsName SRS name. No srsName attribute will be
- * set on geometries when this is not provided.
- * @returns {!ol.format.filter.Bbox} `<BBOX>` operator.
- * @api
- */
- ol.format.filter.bbox = function(geometryName, extent, opt_srsName) {
- return new ol.format.filter.Bbox(geometryName, extent, opt_srsName);
- };
- /**
- * Create a `<Contains>` operator to test whether a geometry-valued property
- * contains a given geometry.
- *
- * @param {!string} geometryName Geometry name to use.
- * @param {!ol.geom.Geometry} geometry Geometry.
- * @param {string=} opt_srsName SRS name. No srsName attribute will be
- * set on geometries when this is not provided.
- * @returns {!ol.format.filter.Contains} `<Contains>` operator.
- * @api
- */
- ol.format.filter.contains = function(geometryName, geometry, opt_srsName) {
- return new ol.format.filter.Contains(geometryName, geometry, opt_srsName);
- };
- /**
- * Create a `<Intersects>` operator to test whether a geometry-valued property
- * intersects a given geometry.
- *
- * @param {!string} geometryName Geometry name to use.
- * @param {!ol.geom.Geometry} geometry Geometry.
- * @param {string=} opt_srsName SRS name. No srsName attribute will be
- * set on geometries when this is not provided.
- * @returns {!ol.format.filter.Intersects} `<Intersects>` operator.
- * @api
- */
- ol.format.filter.intersects = function(geometryName, geometry, opt_srsName) {
- return new ol.format.filter.Intersects(geometryName, geometry, opt_srsName);
- };
- /**
- * Create a `<Within>` operator to test whether a geometry-valued property
- * is within a given geometry.
- *
- * @param {!string} geometryName Geometry name to use.
- * @param {!ol.geom.Geometry} geometry Geometry.
- * @param {string=} opt_srsName SRS name. No srsName attribute will be
- * set on geometries when this is not provided.
- * @returns {!ol.format.filter.Within} `<Within>` operator.
- * @api
- */
- ol.format.filter.within = function(geometryName, geometry, opt_srsName) {
- return new ol.format.filter.Within(geometryName, geometry, opt_srsName);
- };
- /**
- * Creates a `<PropertyIsEqualTo>` comparison operator.
- *
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!(string|number)} expression The value to compare.
- * @param {boolean=} opt_matchCase Case-sensitive?
- * @returns {!ol.format.filter.EqualTo} `<PropertyIsEqualTo>` operator.
- * @api
- */
- ol.format.filter.equalTo = function(propertyName, expression, opt_matchCase) {
- return new ol.format.filter.EqualTo(propertyName, expression, opt_matchCase);
- };
- /**
- * Creates a `<PropertyIsNotEqualTo>` comparison operator.
- *
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!(string|number)} expression The value to compare.
- * @param {boolean=} opt_matchCase Case-sensitive?
- * @returns {!ol.format.filter.NotEqualTo} `<PropertyIsNotEqualTo>` operator.
- * @api
- */
- ol.format.filter.notEqualTo = function(propertyName, expression, opt_matchCase) {
- return new ol.format.filter.NotEqualTo(propertyName, expression, opt_matchCase);
- };
- /**
- * Creates a `<PropertyIsLessThan>` comparison operator.
- *
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!number} expression The value to compare.
- * @returns {!ol.format.filter.LessThan} `<PropertyIsLessThan>` operator.
- * @api
- */
- ol.format.filter.lessThan = function(propertyName, expression) {
- return new ol.format.filter.LessThan(propertyName, expression);
- };
- /**
- * Creates a `<PropertyIsLessThanOrEqualTo>` comparison operator.
- *
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!number} expression The value to compare.
- * @returns {!ol.format.filter.LessThanOrEqualTo} `<PropertyIsLessThanOrEqualTo>` operator.
- * @api
- */
- ol.format.filter.lessThanOrEqualTo = function(propertyName, expression) {
- return new ol.format.filter.LessThanOrEqualTo(propertyName, expression);
- };
- /**
- * Creates a `<PropertyIsGreaterThan>` comparison operator.
- *
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!number} expression The value to compare.
- * @returns {!ol.format.filter.GreaterThan} `<PropertyIsGreaterThan>` operator.
- * @api
- */
- ol.format.filter.greaterThan = function(propertyName, expression) {
- return new ol.format.filter.GreaterThan(propertyName, expression);
- };
- /**
- * Creates a `<PropertyIsGreaterThanOrEqualTo>` comparison operator.
- *
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!number} expression The value to compare.
- * @returns {!ol.format.filter.GreaterThanOrEqualTo} `<PropertyIsGreaterThanOrEqualTo>` operator.
- * @api
- */
- ol.format.filter.greaterThanOrEqualTo = function(propertyName, expression) {
- return new ol.format.filter.GreaterThanOrEqualTo(propertyName, expression);
- };
- /**
- * Creates a `<PropertyIsNull>` comparison operator to test whether a property value
- * is null.
- *
- * @param {!string} propertyName Name of the context property to compare.
- * @returns {!ol.format.filter.IsNull} `<PropertyIsNull>` operator.
- * @api
- */
- ol.format.filter.isNull = function(propertyName) {
- return new ol.format.filter.IsNull(propertyName);
- };
- /**
- * Creates a `<PropertyIsBetween>` comparison operator to test whether an expression
- * value lies within a range given by a lower and upper bound (inclusive).
- *
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!number} lowerBoundary The lower bound of the range.
- * @param {!number} upperBoundary The upper bound of the range.
- * @returns {!ol.format.filter.IsBetween} `<PropertyIsBetween>` operator.
- * @api
- */
- ol.format.filter.between = function(propertyName, lowerBoundary, upperBoundary) {
- return new ol.format.filter.IsBetween(propertyName, lowerBoundary, upperBoundary);
- };
- /**
- * Represents a `<PropertyIsLike>` comparison operator that matches a string property
- * value against a text pattern.
- *
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!string} pattern Text pattern.
- * @param {string=} opt_wildCard Pattern character which matches any sequence of
- * zero or more string characters. Default is '*'.
- * @param {string=} opt_singleChar pattern character which matches any single
- * string character. Default is '.'.
- * @param {string=} opt_escapeChar Escape character which can be used to escape
- * the pattern characters. Default is '!'.
- * @param {boolean=} opt_matchCase Case-sensitive?
- * @returns {!ol.format.filter.IsLike} `<PropertyIsLike>` operator.
- * @api
- */
- ol.format.filter.like = function(propertyName, pattern,
- opt_wildCard, opt_singleChar, opt_escapeChar, opt_matchCase) {
- return new ol.format.filter.IsLike(propertyName, pattern,
- opt_wildCard, opt_singleChar, opt_escapeChar, opt_matchCase);
- };
- /**
- * Create a `<During>` temporal operator.
- *
- * @param {!string} propertyName Name of the context property to compare.
- * @param {!string} begin The begin date in ISO-8601 format.
- * @param {!string} end The end date in ISO-8601 format.
- * @returns {!ol.format.filter.During} `<During>` operator.
- * @api
- */
- ol.format.filter.during = function(propertyName, begin, end) {
- return new ol.format.filter.During(propertyName, begin, end);
- };
- goog.provide('ol.geom.GeometryCollection');
- goog.require('ol');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.extent');
- goog.require('ol.geom.Geometry');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.obj');
- /**
- * @classdesc
- * An array of {@link ol.geom.Geometry} objects.
- *
- * @constructor
- * @extends {ol.geom.Geometry}
- * @param {Array.<ol.geom.Geometry>=} opt_geometries Geometries.
- * @api
- */
- ol.geom.GeometryCollection = function(opt_geometries) {
- ol.geom.Geometry.call(this);
- /**
- * @private
- * @type {Array.<ol.geom.Geometry>}
- */
- this.geometries_ = opt_geometries ? opt_geometries : null;
- this.listenGeometriesChange_();
- };
- ol.inherits(ol.geom.GeometryCollection, ol.geom.Geometry);
- /**
- * @param {Array.<ol.geom.Geometry>} geometries Geometries.
- * @private
- * @return {Array.<ol.geom.Geometry>} Cloned geometries.
- */
- ol.geom.GeometryCollection.cloneGeometries_ = function(geometries) {
- var clonedGeometries = [];
- var i, ii;
- for (i = 0, ii = geometries.length; i < ii; ++i) {
- clonedGeometries.push(geometries[i].clone());
- }
- return clonedGeometries;
- };
- /**
- * @private
- */
- ol.geom.GeometryCollection.prototype.unlistenGeometriesChange_ = function() {
- var i, ii;
- if (!this.geometries_) {
- return;
- }
- for (i = 0, ii = this.geometries_.length; i < ii; ++i) {
- ol.events.unlisten(
- this.geometries_[i], ol.events.EventType.CHANGE,
- this.changed, this);
- }
- };
- /**
- * @private
- */
- ol.geom.GeometryCollection.prototype.listenGeometriesChange_ = function() {
- var i, ii;
- if (!this.geometries_) {
- return;
- }
- for (i = 0, ii = this.geometries_.length; i < ii; ++i) {
- ol.events.listen(
- this.geometries_[i], ol.events.EventType.CHANGE,
- this.changed, this);
- }
- };
- /**
- * Make a complete copy of the geometry.
- * @return {!ol.geom.GeometryCollection} Clone.
- * @override
- * @api
- */
- ol.geom.GeometryCollection.prototype.clone = function() {
- var geometryCollection = new ol.geom.GeometryCollection(null);
- geometryCollection.setGeometries(this.geometries_);
- return geometryCollection;
- };
- /**
- * @inheritDoc
- */
- ol.geom.GeometryCollection.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) {
- if (minSquaredDistance <
- ol.extent.closestSquaredDistanceXY(this.getExtent(), x, y)) {
- return minSquaredDistance;
- }
- var geometries = this.geometries_;
- var i, ii;
- for (i = 0, ii = geometries.length; i < ii; ++i) {
- minSquaredDistance = geometries[i].closestPointXY(
- x, y, closestPoint, minSquaredDistance);
- }
- return minSquaredDistance;
- };
- /**
- * @inheritDoc
- */
- ol.geom.GeometryCollection.prototype.containsXY = function(x, y) {
- var geometries = this.geometries_;
- var i, ii;
- for (i = 0, ii = geometries.length; i < ii; ++i) {
- if (geometries[i].containsXY(x, y)) {
- return true;
- }
- }
- return false;
- };
- /**
- * @inheritDoc
- */
- ol.geom.GeometryCollection.prototype.computeExtent = function(extent) {
- ol.extent.createOrUpdateEmpty(extent);
- var geometries = this.geometries_;
- for (var i = 0, ii = geometries.length; i < ii; ++i) {
- ol.extent.extend(extent, geometries[i].getExtent());
- }
- return extent;
- };
- /**
- * Return the geometries that make up this geometry collection.
- * @return {Array.<ol.geom.Geometry>} Geometries.
- * @api
- */
- ol.geom.GeometryCollection.prototype.getGeometries = function() {
- return ol.geom.GeometryCollection.cloneGeometries_(this.geometries_);
- };
- /**
- * @return {Array.<ol.geom.Geometry>} Geometries.
- */
- ol.geom.GeometryCollection.prototype.getGeometriesArray = function() {
- return this.geometries_;
- };
- /**
- * @inheritDoc
- */
- ol.geom.GeometryCollection.prototype.getSimplifiedGeometry = function(squaredTolerance) {
- if (this.simplifiedGeometryRevision != this.getRevision()) {
- ol.obj.clear(this.simplifiedGeometryCache);
- this.simplifiedGeometryMaxMinSquaredTolerance = 0;
- this.simplifiedGeometryRevision = this.getRevision();
- }
- if (squaredTolerance < 0 ||
- (this.simplifiedGeometryMaxMinSquaredTolerance !== 0 &&
- squaredTolerance < this.simplifiedGeometryMaxMinSquaredTolerance)) {
- return this;
- }
- var key = squaredTolerance.toString();
- if (this.simplifiedGeometryCache.hasOwnProperty(key)) {
- return this.simplifiedGeometryCache[key];
- } else {
- var simplifiedGeometries = [];
- var geometries = this.geometries_;
- var simplified = false;
- var i, ii;
- for (i = 0, ii = geometries.length; i < ii; ++i) {
- var geometry = geometries[i];
- var simplifiedGeometry = geometry.getSimplifiedGeometry(squaredTolerance);
- simplifiedGeometries.push(simplifiedGeometry);
- if (simplifiedGeometry !== geometry) {
- simplified = true;
- }
- }
- if (simplified) {
- var simplifiedGeometryCollection = new ol.geom.GeometryCollection(null);
- simplifiedGeometryCollection.setGeometriesArray(simplifiedGeometries);
- this.simplifiedGeometryCache[key] = simplifiedGeometryCollection;
- return simplifiedGeometryCollection;
- } else {
- this.simplifiedGeometryMaxMinSquaredTolerance = squaredTolerance;
- return this;
- }
- }
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.GeometryCollection.prototype.getType = function() {
- return ol.geom.GeometryType.GEOMETRY_COLLECTION;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.GeometryCollection.prototype.intersectsExtent = function(extent) {
- var geometries = this.geometries_;
- var i, ii;
- for (i = 0, ii = geometries.length; i < ii; ++i) {
- if (geometries[i].intersectsExtent(extent)) {
- return true;
- }
- }
- return false;
- };
- /**
- * @return {boolean} Is empty.
- */
- ol.geom.GeometryCollection.prototype.isEmpty = function() {
- return this.geometries_.length === 0;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.GeometryCollection.prototype.rotate = function(angle, anchor) {
- var geometries = this.geometries_;
- for (var i = 0, ii = geometries.length; i < ii; ++i) {
- geometries[i].rotate(angle, anchor);
- }
- this.changed();
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.GeometryCollection.prototype.scale = function(sx, opt_sy, opt_anchor) {
- var anchor = opt_anchor;
- if (!anchor) {
- anchor = ol.extent.getCenter(this.getExtent());
- }
- var geometries = this.geometries_;
- for (var i = 0, ii = geometries.length; i < ii; ++i) {
- geometries[i].scale(sx, opt_sy, anchor);
- }
- this.changed();
- };
- /**
- * Set the geometries that make up this geometry collection.
- * @param {Array.<ol.geom.Geometry>} geometries Geometries.
- * @api
- */
- ol.geom.GeometryCollection.prototype.setGeometries = function(geometries) {
- this.setGeometriesArray(
- ol.geom.GeometryCollection.cloneGeometries_(geometries));
- };
- /**
- * @param {Array.<ol.geom.Geometry>} geometries Geometries.
- */
- ol.geom.GeometryCollection.prototype.setGeometriesArray = function(geometries) {
- this.unlistenGeometriesChange_();
- this.geometries_ = geometries;
- this.listenGeometriesChange_();
- this.changed();
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.GeometryCollection.prototype.applyTransform = function(transformFn) {
- var geometries = this.geometries_;
- var i, ii;
- for (i = 0, ii = geometries.length; i < ii; ++i) {
- geometries[i].applyTransform(transformFn);
- }
- this.changed();
- };
- /**
- * Translate the geometry.
- * @param {number} deltaX Delta X.
- * @param {number} deltaY Delta Y.
- * @override
- * @api
- */
- ol.geom.GeometryCollection.prototype.translate = function(deltaX, deltaY) {
- var geometries = this.geometries_;
- var i, ii;
- for (i = 0, ii = geometries.length; i < ii; ++i) {
- geometries[i].translate(deltaX, deltaY);
- }
- this.changed();
- };
- /**
- * @inheritDoc
- */
- ol.geom.GeometryCollection.prototype.disposeInternal = function() {
- this.unlistenGeometriesChange_();
- ol.geom.Geometry.prototype.disposeInternal.call(this);
- };
- // TODO: serialize dataProjection as crs member when writing
- // see https://github.com/openlayers/openlayers/issues/2078
- goog.provide('ol.format.GeoJSON');
- goog.require('ol');
- goog.require('ol.asserts');
- goog.require('ol.Feature');
- goog.require('ol.format.Feature');
- goog.require('ol.format.JSONFeature');
- goog.require('ol.geom.GeometryCollection');
- goog.require('ol.geom.LineString');
- goog.require('ol.geom.MultiLineString');
- goog.require('ol.geom.MultiPoint');
- goog.require('ol.geom.MultiPolygon');
- goog.require('ol.geom.Point');
- goog.require('ol.geom.Polygon');
- goog.require('ol.obj');
- goog.require('ol.proj');
- /**
- * @classdesc
- * Feature format for reading and writing data in the GeoJSON format.
- *
- * @constructor
- * @extends {ol.format.JSONFeature}
- * @param {olx.format.GeoJSONOptions=} opt_options Options.
- * @api
- */
- ol.format.GeoJSON = function(opt_options) {
- var options = opt_options ? opt_options : {};
- ol.format.JSONFeature.call(this);
- /**
- * @inheritDoc
- */
- this.defaultDataProjection = ol.proj.get(
- options.defaultDataProjection ?
- options.defaultDataProjection : 'EPSG:4326');
- if (options.featureProjection) {
- this.defaultFeatureProjection = ol.proj.get(options.featureProjection);
- }
- /**
- * Name of the geometry attribute for features.
- * @type {string|undefined}
- * @private
- */
- this.geometryName_ = options.geometryName;
- /**
- * Look for the geometry name in the feature GeoJSON
- * @type {boolean|undefined}
- * @private
- */
- this.extractGeometryName_ = options.extractGeometryName;
- };
- ol.inherits(ol.format.GeoJSON, ol.format.JSONFeature);
- /**
- * @param {GeoJSONGeometry|GeoJSONGeometryCollection} object Object.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @private
- * @return {ol.geom.Geometry} Geometry.
- */
- ol.format.GeoJSON.readGeometry_ = function(object, opt_options) {
- if (!object) {
- return null;
- }
- var geometryReader = ol.format.GeoJSON.GEOMETRY_READERS_[object.type];
- return /** @type {ol.geom.Geometry} */ (
- ol.format.Feature.transformWithOptions(
- geometryReader(object), false, opt_options));
- };
- /**
- * @param {GeoJSONGeometryCollection} object Object.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @private
- * @return {ol.geom.GeometryCollection} Geometry collection.
- */
- ol.format.GeoJSON.readGeometryCollectionGeometry_ = function(
- object, opt_options) {
- var geometries = object.geometries.map(
- /**
- * @param {GeoJSONGeometry} geometry Geometry.
- * @return {ol.geom.Geometry} geometry Geometry.
- */
- function(geometry) {
- return ol.format.GeoJSON.readGeometry_(geometry, opt_options);
- });
- return new ol.geom.GeometryCollection(geometries);
- };
- /**
- * @param {GeoJSONGeometry} object Object.
- * @private
- * @return {ol.geom.Point} Point.
- */
- ol.format.GeoJSON.readPointGeometry_ = function(object) {
- return new ol.geom.Point(object.coordinates);
- };
- /**
- * @param {GeoJSONGeometry} object Object.
- * @private
- * @return {ol.geom.LineString} LineString.
- */
- ol.format.GeoJSON.readLineStringGeometry_ = function(object) {
- return new ol.geom.LineString(object.coordinates);
- };
- /**
- * @param {GeoJSONGeometry} object Object.
- * @private
- * @return {ol.geom.MultiLineString} MultiLineString.
- */
- ol.format.GeoJSON.readMultiLineStringGeometry_ = function(object) {
- return new ol.geom.MultiLineString(object.coordinates);
- };
- /**
- * @param {GeoJSONGeometry} object Object.
- * @private
- * @return {ol.geom.MultiPoint} MultiPoint.
- */
- ol.format.GeoJSON.readMultiPointGeometry_ = function(object) {
- return new ol.geom.MultiPoint(object.coordinates);
- };
- /**
- * @param {GeoJSONGeometry} object Object.
- * @private
- * @return {ol.geom.MultiPolygon} MultiPolygon.
- */
- ol.format.GeoJSON.readMultiPolygonGeometry_ = function(object) {
- return new ol.geom.MultiPolygon(object.coordinates);
- };
- /**
- * @param {GeoJSONGeometry} object Object.
- * @private
- * @return {ol.geom.Polygon} Polygon.
- */
- ol.format.GeoJSON.readPolygonGeometry_ = function(object) {
- return new ol.geom.Polygon(object.coordinates);
- };
- /**
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @private
- * @return {GeoJSONGeometry|GeoJSONGeometryCollection} GeoJSON geometry.
- */
- ol.format.GeoJSON.writeGeometry_ = function(geometry, opt_options) {
- var geometryWriter = ol.format.GeoJSON.GEOMETRY_WRITERS_[geometry.getType()];
- return geometryWriter(/** @type {ol.geom.Geometry} */ (
- ol.format.Feature.transformWithOptions(geometry, true, opt_options)),
- opt_options);
- };
- /**
- * @param {ol.geom.Geometry} geometry Geometry.
- * @private
- * @return {GeoJSONGeometryCollection} Empty GeoJSON geometry collection.
- */
- ol.format.GeoJSON.writeEmptyGeometryCollectionGeometry_ = function(geometry) {
- return /** @type {GeoJSONGeometryCollection} */ ({
- type: 'GeometryCollection',
- geometries: []
- });
- };
- /**
- * @param {ol.geom.GeometryCollection} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @private
- * @return {GeoJSONGeometryCollection} GeoJSON geometry collection.
- */
- ol.format.GeoJSON.writeGeometryCollectionGeometry_ = function(
- geometry, opt_options) {
- var geometries = geometry.getGeometriesArray().map(function(geometry) {
- var options = ol.obj.assign({}, opt_options);
- delete options.featureProjection;
- return ol.format.GeoJSON.writeGeometry_(geometry, options);
- });
- return /** @type {GeoJSONGeometryCollection} */ ({
- type: 'GeometryCollection',
- geometries: geometries
- });
- };
- /**
- * @param {ol.geom.LineString} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @private
- * @return {GeoJSONGeometry} GeoJSON geometry.
- */
- ol.format.GeoJSON.writeLineStringGeometry_ = function(geometry, opt_options) {
- return /** @type {GeoJSONGeometry} */ ({
- type: 'LineString',
- coordinates: geometry.getCoordinates()
- });
- };
- /**
- * @param {ol.geom.MultiLineString} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @private
- * @return {GeoJSONGeometry} GeoJSON geometry.
- */
- ol.format.GeoJSON.writeMultiLineStringGeometry_ = function(geometry, opt_options) {
- return /** @type {GeoJSONGeometry} */ ({
- type: 'MultiLineString',
- coordinates: geometry.getCoordinates()
- });
- };
- /**
- * @param {ol.geom.MultiPoint} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @private
- * @return {GeoJSONGeometry} GeoJSON geometry.
- */
- ol.format.GeoJSON.writeMultiPointGeometry_ = function(geometry, opt_options) {
- return /** @type {GeoJSONGeometry} */ ({
- type: 'MultiPoint',
- coordinates: geometry.getCoordinates()
- });
- };
- /**
- * @param {ol.geom.MultiPolygon} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @private
- * @return {GeoJSONGeometry} GeoJSON geometry.
- */
- ol.format.GeoJSON.writeMultiPolygonGeometry_ = function(geometry, opt_options) {
- var right;
- if (opt_options) {
- right = opt_options.rightHanded;
- }
- return /** @type {GeoJSONGeometry} */ ({
- type: 'MultiPolygon',
- coordinates: geometry.getCoordinates(right)
- });
- };
- /**
- * @param {ol.geom.Point} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @private
- * @return {GeoJSONGeometry} GeoJSON geometry.
- */
- ol.format.GeoJSON.writePointGeometry_ = function(geometry, opt_options) {
- return /** @type {GeoJSONGeometry} */ ({
- type: 'Point',
- coordinates: geometry.getCoordinates()
- });
- };
- /**
- * @param {ol.geom.Polygon} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @private
- * @return {GeoJSONGeometry} GeoJSON geometry.
- */
- ol.format.GeoJSON.writePolygonGeometry_ = function(geometry, opt_options) {
- var right;
- if (opt_options) {
- right = opt_options.rightHanded;
- }
- return /** @type {GeoJSONGeometry} */ ({
- type: 'Polygon',
- coordinates: geometry.getCoordinates(right)
- });
- };
- /**
- * @const
- * @private
- * @type {Object.<string, function(GeoJSONObject): ol.geom.Geometry>}
- */
- ol.format.GeoJSON.GEOMETRY_READERS_ = {
- 'Point': ol.format.GeoJSON.readPointGeometry_,
- 'LineString': ol.format.GeoJSON.readLineStringGeometry_,
- 'Polygon': ol.format.GeoJSON.readPolygonGeometry_,
- 'MultiPoint': ol.format.GeoJSON.readMultiPointGeometry_,
- 'MultiLineString': ol.format.GeoJSON.readMultiLineStringGeometry_,
- 'MultiPolygon': ol.format.GeoJSON.readMultiPolygonGeometry_,
- 'GeometryCollection': ol.format.GeoJSON.readGeometryCollectionGeometry_
- };
- /**
- * @const
- * @private
- * @type {Object.<string, function(ol.geom.Geometry, olx.format.WriteOptions=): (GeoJSONGeometry|GeoJSONGeometryCollection)>}
- */
- ol.format.GeoJSON.GEOMETRY_WRITERS_ = {
- 'Point': ol.format.GeoJSON.writePointGeometry_,
- 'LineString': ol.format.GeoJSON.writeLineStringGeometry_,
- 'Polygon': ol.format.GeoJSON.writePolygonGeometry_,
- 'MultiPoint': ol.format.GeoJSON.writeMultiPointGeometry_,
- 'MultiLineString': ol.format.GeoJSON.writeMultiLineStringGeometry_,
- 'MultiPolygon': ol.format.GeoJSON.writeMultiPolygonGeometry_,
- 'GeometryCollection': ol.format.GeoJSON.writeGeometryCollectionGeometry_,
- 'Circle': ol.format.GeoJSON.writeEmptyGeometryCollectionGeometry_
- };
- /**
- * Read a feature from a GeoJSON Feature source. Only works for Feature or
- * geometry types. Use {@link ol.format.GeoJSON#readFeatures} to read
- * FeatureCollection source. If feature at source has an id, it will be used
- * as Feature id by calling {@link ol.Feature#setId} internally.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {ol.Feature} Feature.
- * @api
- */
- ol.format.GeoJSON.prototype.readFeature;
- /**
- * Read all features from a GeoJSON source. Works for all GeoJSON types.
- * If the source includes only geometries, features will be created with those
- * geometries.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {Array.<ol.Feature>} Features.
- * @api
- */
- ol.format.GeoJSON.prototype.readFeatures;
- /**
- * @inheritDoc
- */
- ol.format.GeoJSON.prototype.readFeatureFromObject = function(
- object, opt_options) {
- /**
- * @type {GeoJSONFeature}
- */
- var geoJSONFeature = null;
- if (object.type === 'Feature') {
- geoJSONFeature = /** @type {GeoJSONFeature} */ (object);
- } else {
- geoJSONFeature = /** @type {GeoJSONFeature} */ ({
- type: 'Feature',
- geometry: /** @type {GeoJSONGeometry|GeoJSONGeometryCollection} */ (object)
- });
- }
- var geometry = ol.format.GeoJSON.readGeometry_(geoJSONFeature.geometry, opt_options);
- var feature = new ol.Feature();
- if (this.geometryName_) {
- feature.setGeometryName(this.geometryName_);
- } else if (this.extractGeometryName_ && geoJSONFeature.geometry_name !== undefined) {
- feature.setGeometryName(geoJSONFeature.geometry_name);
- }
- feature.setGeometry(geometry);
- if (geoJSONFeature.id !== undefined) {
- feature.setId(geoJSONFeature.id);
- }
- if (geoJSONFeature.properties) {
- feature.setProperties(geoJSONFeature.properties);
- }
- return feature;
- };
- /**
- * @inheritDoc
- */
- ol.format.GeoJSON.prototype.readFeaturesFromObject = function(
- object, opt_options) {
- var geoJSONObject = /** @type {GeoJSONObject} */ (object);
- /** @type {Array.<ol.Feature>} */
- var features = null;
- if (geoJSONObject.type === 'FeatureCollection') {
- var geoJSONFeatureCollection = /** @type {GeoJSONFeatureCollection} */
- (object);
- features = [];
- var geoJSONFeatures = geoJSONFeatureCollection.features;
- var i, ii;
- for (i = 0, ii = geoJSONFeatures.length; i < ii; ++i) {
- features.push(this.readFeatureFromObject(geoJSONFeatures[i],
- opt_options));
- }
- } else {
- features = [this.readFeatureFromObject(object, opt_options)];
- }
- return features;
- };
- /**
- * Read a geometry from a GeoJSON source.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {ol.geom.Geometry} Geometry.
- * @api
- */
- ol.format.GeoJSON.prototype.readGeometry;
- /**
- * @inheritDoc
- */
- ol.format.GeoJSON.prototype.readGeometryFromObject = function(
- object, opt_options) {
- return ol.format.GeoJSON.readGeometry_(
- /** @type {GeoJSONGeometry} */ (object), opt_options);
- };
- /**
- * Read the projection from a GeoJSON source.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @return {ol.proj.Projection} Projection.
- * @api
- */
- ol.format.GeoJSON.prototype.readProjection;
- /**
- * @inheritDoc
- */
- ol.format.GeoJSON.prototype.readProjectionFromObject = function(object) {
- var geoJSONObject = /** @type {GeoJSONObject} */ (object);
- var crs = geoJSONObject.crs;
- var projection;
- if (crs) {
- if (crs.type == 'name') {
- projection = ol.proj.get(crs.properties.name);
- } else {
- ol.asserts.assert(false, 36); // Unknown SRS type
- }
- } else {
- projection = this.defaultDataProjection;
- }
- return /** @type {ol.proj.Projection} */ (projection);
- };
- /**
- * Encode a feature as a GeoJSON Feature string.
- *
- * @function
- * @param {ol.Feature} feature Feature.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {string} GeoJSON.
- * @override
- * @api
- */
- ol.format.GeoJSON.prototype.writeFeature;
- /**
- * Encode a feature as a GeoJSON Feature object.
- *
- * @param {ol.Feature} feature Feature.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {GeoJSONFeature} Object.
- * @override
- * @api
- */
- ol.format.GeoJSON.prototype.writeFeatureObject = function(feature, opt_options) {
- opt_options = this.adaptOptions(opt_options);
- var object = /** @type {GeoJSONFeature} */ ({
- 'type': 'Feature'
- });
- var id = feature.getId();
- if (id !== undefined) {
- object.id = id;
- }
- var geometry = feature.getGeometry();
- if (geometry) {
- object.geometry =
- ol.format.GeoJSON.writeGeometry_(geometry, opt_options);
- } else {
- object.geometry = null;
- }
- var properties = feature.getProperties();
- delete properties[feature.getGeometryName()];
- if (!ol.obj.isEmpty(properties)) {
- object.properties = properties;
- } else {
- object.properties = null;
- }
- return object;
- };
- /**
- * Encode an array of features as GeoJSON.
- *
- * @function
- * @param {Array.<ol.Feature>} features Features.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {string} GeoJSON.
- * @api
- */
- ol.format.GeoJSON.prototype.writeFeatures;
- /**
- * Encode an array of features as a GeoJSON object.
- *
- * @param {Array.<ol.Feature>} features Features.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {GeoJSONFeatureCollection} GeoJSON Object.
- * @override
- * @api
- */
- ol.format.GeoJSON.prototype.writeFeaturesObject = function(features, opt_options) {
- opt_options = this.adaptOptions(opt_options);
- var objects = [];
- var i, ii;
- for (i = 0, ii = features.length; i < ii; ++i) {
- objects.push(this.writeFeatureObject(features[i], opt_options));
- }
- return /** @type {GeoJSONFeatureCollection} */ ({
- type: 'FeatureCollection',
- features: objects
- });
- };
- /**
- * Encode a geometry as a GeoJSON string.
- *
- * @function
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {string} GeoJSON.
- * @api
- */
- ol.format.GeoJSON.prototype.writeGeometry;
- /**
- * Encode a geometry as a GeoJSON object.
- *
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {GeoJSONGeometry|GeoJSONGeometryCollection} Object.
- * @override
- * @api
- */
- ol.format.GeoJSON.prototype.writeGeometryObject = function(geometry,
- opt_options) {
- return ol.format.GeoJSON.writeGeometry_(geometry,
- this.adaptOptions(opt_options));
- };
- goog.provide('ol.format.XMLFeature');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.format.Feature');
- goog.require('ol.format.FormatType');
- goog.require('ol.xml');
- /**
- * @classdesc
- * Abstract base class; normally only used for creating subclasses and not
- * instantiated in apps.
- * Base class for XML feature formats.
- *
- * @constructor
- * @abstract
- * @extends {ol.format.Feature}
- */
- ol.format.XMLFeature = function() {
- /**
- * @type {XMLSerializer}
- * @private
- */
- this.xmlSerializer_ = new XMLSerializer();
- ol.format.Feature.call(this);
- };
- ol.inherits(ol.format.XMLFeature, ol.format.Feature);
- /**
- * @inheritDoc
- */
- ol.format.XMLFeature.prototype.getType = function() {
- return ol.format.FormatType.XML;
- };
- /**
- * @inheritDoc
- */
- ol.format.XMLFeature.prototype.readFeature = function(source, opt_options) {
- if (ol.xml.isDocument(source)) {
- return this.readFeatureFromDocument(
- /** @type {Document} */ (source), opt_options);
- } else if (ol.xml.isNode(source)) {
- return this.readFeatureFromNode(/** @type {Node} */ (source), opt_options);
- } else if (typeof source === 'string') {
- var doc = ol.xml.parse(source);
- return this.readFeatureFromDocument(doc, opt_options);
- } else {
- return null;
- }
- };
- /**
- * @param {Document} doc Document.
- * @param {olx.format.ReadOptions=} opt_options Options.
- * @return {ol.Feature} Feature.
- */
- ol.format.XMLFeature.prototype.readFeatureFromDocument = function(
- doc, opt_options) {
- var features = this.readFeaturesFromDocument(doc, opt_options);
- if (features.length > 0) {
- return features[0];
- } else {
- return null;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {olx.format.ReadOptions=} opt_options Options.
- * @return {ol.Feature} Feature.
- */
- ol.format.XMLFeature.prototype.readFeatureFromNode = function(node, opt_options) {
- return null; // not implemented
- };
- /**
- * @inheritDoc
- */
- ol.format.XMLFeature.prototype.readFeatures = function(source, opt_options) {
- if (ol.xml.isDocument(source)) {
- return this.readFeaturesFromDocument(
- /** @type {Document} */ (source), opt_options);
- } else if (ol.xml.isNode(source)) {
- return this.readFeaturesFromNode(/** @type {Node} */ (source), opt_options);
- } else if (typeof source === 'string') {
- var doc = ol.xml.parse(source);
- return this.readFeaturesFromDocument(doc, opt_options);
- } else {
- return [];
- }
- };
- /**
- * @param {Document} doc Document.
- * @param {olx.format.ReadOptions=} opt_options Options.
- * @protected
- * @return {Array.<ol.Feature>} Features.
- */
- ol.format.XMLFeature.prototype.readFeaturesFromDocument = function(
- doc, opt_options) {
- /** @type {Array.<ol.Feature>} */
- var features = [];
- var n;
- for (n = doc.firstChild; n; n = n.nextSibling) {
- if (n.nodeType == Node.ELEMENT_NODE) {
- ol.array.extend(features, this.readFeaturesFromNode(n, opt_options));
- }
- }
- return features;
- };
- /**
- * @abstract
- * @param {Node} node Node.
- * @param {olx.format.ReadOptions=} opt_options Options.
- * @protected
- * @return {Array.<ol.Feature>} Features.
- */
- ol.format.XMLFeature.prototype.readFeaturesFromNode = function(node, opt_options) {};
- /**
- * @inheritDoc
- */
- ol.format.XMLFeature.prototype.readGeometry = function(source, opt_options) {
- if (ol.xml.isDocument(source)) {
- return this.readGeometryFromDocument(
- /** @type {Document} */ (source), opt_options);
- } else if (ol.xml.isNode(source)) {
- return this.readGeometryFromNode(/** @type {Node} */ (source), opt_options);
- } else if (typeof source === 'string') {
- var doc = ol.xml.parse(source);
- return this.readGeometryFromDocument(doc, opt_options);
- } else {
- return null;
- }
- };
- /**
- * @param {Document} doc Document.
- * @param {olx.format.ReadOptions=} opt_options Options.
- * @protected
- * @return {ol.geom.Geometry} Geometry.
- */
- ol.format.XMLFeature.prototype.readGeometryFromDocument = function(doc, opt_options) {
- return null; // not implemented
- };
- /**
- * @param {Node} node Node.
- * @param {olx.format.ReadOptions=} opt_options Options.
- * @protected
- * @return {ol.geom.Geometry} Geometry.
- */
- ol.format.XMLFeature.prototype.readGeometryFromNode = function(node, opt_options) {
- return null; // not implemented
- };
- /**
- * @inheritDoc
- */
- ol.format.XMLFeature.prototype.readProjection = function(source) {
- if (ol.xml.isDocument(source)) {
- return this.readProjectionFromDocument(/** @type {Document} */ (source));
- } else if (ol.xml.isNode(source)) {
- return this.readProjectionFromNode(/** @type {Node} */ (source));
- } else if (typeof source === 'string') {
- var doc = ol.xml.parse(source);
- return this.readProjectionFromDocument(doc);
- } else {
- return null;
- }
- };
- /**
- * @param {Document} doc Document.
- * @protected
- * @return {ol.proj.Projection} Projection.
- */
- ol.format.XMLFeature.prototype.readProjectionFromDocument = function(doc) {
- return this.defaultDataProjection;
- };
- /**
- * @param {Node} node Node.
- * @protected
- * @return {ol.proj.Projection} Projection.
- */
- ol.format.XMLFeature.prototype.readProjectionFromNode = function(node) {
- return this.defaultDataProjection;
- };
- /**
- * @inheritDoc
- */
- ol.format.XMLFeature.prototype.writeFeature = function(feature, opt_options) {
- var node = this.writeFeatureNode(feature, opt_options);
- return this.xmlSerializer_.serializeToString(node);
- };
- /**
- * @param {ol.Feature} feature Feature.
- * @param {olx.format.WriteOptions=} opt_options Options.
- * @protected
- * @return {Node} Node.
- */
- ol.format.XMLFeature.prototype.writeFeatureNode = function(feature, opt_options) {
- return null; // not implemented
- };
- /**
- * @inheritDoc
- */
- ol.format.XMLFeature.prototype.writeFeatures = function(features, opt_options) {
- var node = this.writeFeaturesNode(features, opt_options);
- return this.xmlSerializer_.serializeToString(node);
- };
- /**
- * @param {Array.<ol.Feature>} features Features.
- * @param {olx.format.WriteOptions=} opt_options Options.
- * @return {Node} Node.
- */
- ol.format.XMLFeature.prototype.writeFeaturesNode = function(features, opt_options) {
- return null; // not implemented
- };
- /**
- * @inheritDoc
- */
- ol.format.XMLFeature.prototype.writeGeometry = function(geometry, opt_options) {
- var node = this.writeGeometryNode(geometry, opt_options);
- return this.xmlSerializer_.serializeToString(node);
- };
- /**
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Options.
- * @return {Node} Node.
- */
- ol.format.XMLFeature.prototype.writeGeometryNode = function(geometry, opt_options) {
- return null; // not implemented
- };
- // FIXME Envelopes should not be treated as geometries! readEnvelope_ is part
- // of GEOMETRY_PARSERS_ and methods using GEOMETRY_PARSERS_ do not expect
- // envelopes/extents, only geometries!
- goog.provide('ol.format.GMLBase');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.Feature');
- goog.require('ol.format.Feature');
- goog.require('ol.format.XMLFeature');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.LineString');
- goog.require('ol.geom.LinearRing');
- goog.require('ol.geom.MultiLineString');
- goog.require('ol.geom.MultiPoint');
- goog.require('ol.geom.MultiPolygon');
- goog.require('ol.geom.Point');
- goog.require('ol.geom.Polygon');
- goog.require('ol.obj');
- goog.require('ol.proj');
- goog.require('ol.xml');
- /**
- * @classdesc
- * Abstract base class; normally only used for creating subclasses and not
- * instantiated in apps.
- * Feature base format for reading and writing data in the GML format.
- * This class cannot be instantiated, it contains only base content that
- * is shared with versioned format classes ol.format.GML2 and
- * ol.format.GML3.
- *
- * @constructor
- * @abstract
- * @param {olx.format.GMLOptions=} opt_options
- * Optional configuration object.
- * @extends {ol.format.XMLFeature}
- */
- ol.format.GMLBase = function(opt_options) {
- var options = /** @type {olx.format.GMLOptions} */
- (opt_options ? opt_options : {});
- /**
- * @protected
- * @type {Array.<string>|string|undefined}
- */
- this.featureType = options.featureType;
- /**
- * @protected
- * @type {Object.<string, string>|string|undefined}
- */
- this.featureNS = options.featureNS;
- /**
- * @protected
- * @type {string}
- */
- this.srsName = options.srsName;
- /**
- * @protected
- * @type {string}
- */
- this.schemaLocation = '';
- /**
- * @type {Object.<string, Object.<string, Object>>}
- */
- this.FEATURE_COLLECTION_PARSERS = {};
- this.FEATURE_COLLECTION_PARSERS[ol.format.GMLBase.GMLNS] = {
- 'featureMember': ol.xml.makeReplacer(
- ol.format.GMLBase.prototype.readFeaturesInternal),
- 'featureMembers': ol.xml.makeReplacer(
- ol.format.GMLBase.prototype.readFeaturesInternal)
- };
- ol.format.XMLFeature.call(this);
- };
- ol.inherits(ol.format.GMLBase, ol.format.XMLFeature);
- /**
- * @const
- * @type {string}
- */
- ol.format.GMLBase.GMLNS = 'http://www.opengis.net/gml';
- /**
- * A regular expression that matches if a string only contains whitespace
- * characters. It will e.g. match `''`, `' '`, `'\n'` etc. The non-breaking
- * space (0xa0) is explicitly included as IE doesn't include it in its
- * definition of `\s`.
- *
- * Information from `goog.string.isEmptyOrWhitespace`: https://github.com/google/closure-library/blob/e877b1e/closure/goog/string/string.js#L156-L160
- *
- * @const
- * @type {RegExp}
- * @private
- */
- ol.format.GMLBase.ONLY_WHITESPACE_RE_ = /^[\s\xa0]*$/;
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Array.<ol.Feature> | undefined} Features.
- */
- ol.format.GMLBase.prototype.readFeaturesInternal = function(node, objectStack) {
- var localName = node.localName;
- var features = null;
- if (localName == 'FeatureCollection') {
- if (node.namespaceURI === 'http://www.opengis.net/wfs') {
- features = ol.xml.pushParseAndPop([],
- this.FEATURE_COLLECTION_PARSERS, node,
- objectStack, this);
- } else {
- features = ol.xml.pushParseAndPop(null,
- this.FEATURE_COLLECTION_PARSERS, node,
- objectStack, this);
- }
- } else if (localName == 'featureMembers' || localName == 'featureMember') {
- var context = objectStack[0];
- var featureType = context['featureType'];
- var featureNS = context['featureNS'];
- var i, ii, prefix = 'p', defaultPrefix = 'p0';
- if (!featureType && node.childNodes) {
- featureType = [], featureNS = {};
- for (i = 0, ii = node.childNodes.length; i < ii; ++i) {
- var child = node.childNodes[i];
- if (child.nodeType === 1) {
- var ft = child.nodeName.split(':').pop();
- if (featureType.indexOf(ft) === -1) {
- var key = '';
- var count = 0;
- var uri = child.namespaceURI;
- for (var candidate in featureNS) {
- if (featureNS[candidate] === uri) {
- key = candidate;
- break;
- }
- ++count;
- }
- if (!key) {
- key = prefix + count;
- featureNS[key] = uri;
- }
- featureType.push(key + ':' + ft);
- }
- }
- }
- if (localName != 'featureMember') {
- // recheck featureType for each featureMember
- context['featureType'] = featureType;
- context['featureNS'] = featureNS;
- }
- }
- if (typeof featureNS === 'string') {
- var ns = featureNS;
- featureNS = {};
- featureNS[defaultPrefix] = ns;
- }
- var parsersNS = {};
- var featureTypes = Array.isArray(featureType) ? featureType : [featureType];
- for (var p in featureNS) {
- var parsers = {};
- for (i = 0, ii = featureTypes.length; i < ii; ++i) {
- var featurePrefix = featureTypes[i].indexOf(':') === -1 ?
- defaultPrefix : featureTypes[i].split(':')[0];
- if (featurePrefix === p) {
- parsers[featureTypes[i].split(':').pop()] =
- (localName == 'featureMembers') ?
- ol.xml.makeArrayPusher(this.readFeatureElement, this) :
- ol.xml.makeReplacer(this.readFeatureElement, this);
- }
- }
- parsersNS[featureNS[p]] = parsers;
- }
- if (localName == 'featureMember') {
- features = ol.xml.pushParseAndPop(undefined, parsersNS, node, objectStack);
- } else {
- features = ol.xml.pushParseAndPop([], parsersNS, node, objectStack);
- }
- }
- if (features === null) {
- features = [];
- }
- return features;
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {ol.geom.Geometry|undefined} Geometry.
- */
- ol.format.GMLBase.prototype.readGeometryElement = function(node, objectStack) {
- var context = /** @type {Object} */ (objectStack[0]);
- context['srsName'] = node.firstElementChild.getAttribute('srsName');
- context['srsDimension'] = node.firstElementChild.getAttribute('srsDimension');
- /** @type {ol.geom.Geometry} */
- var geometry = ol.xml.pushParseAndPop(null,
- this.GEOMETRY_PARSERS_, node, objectStack, this);
- if (geometry) {
- return /** @type {ol.geom.Geometry} */ (
- ol.format.Feature.transformWithOptions(geometry, false, context));
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {ol.Feature} Feature.
- */
- ol.format.GMLBase.prototype.readFeatureElement = function(node, objectStack) {
- var n;
- var fid = node.getAttribute('fid') ||
- ol.xml.getAttributeNS(node, ol.format.GMLBase.GMLNS, 'id');
- var values = {}, geometryName;
- for (n = node.firstElementChild; n; n = n.nextElementSibling) {
- var localName = n.localName;
- // Assume attribute elements have one child node and that the child
- // is a text or CDATA node (to be treated as text).
- // Otherwise assume it is a geometry node.
- if (n.childNodes.length === 0 ||
- (n.childNodes.length === 1 &&
- (n.firstChild.nodeType === 3 || n.firstChild.nodeType === 4))) {
- var value = ol.xml.getAllTextContent(n, false);
- if (ol.format.GMLBase.ONLY_WHITESPACE_RE_.test(value)) {
- value = undefined;
- }
- values[localName] = value;
- } else {
- // boundedBy is an extent and must not be considered as a geometry
- if (localName !== 'boundedBy') {
- geometryName = localName;
- }
- values[localName] = this.readGeometryElement(n, objectStack);
- }
- }
- var feature = new ol.Feature(values);
- if (geometryName) {
- feature.setGeometryName(geometryName);
- }
- if (fid) {
- feature.setId(fid);
- }
- return feature;
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {ol.geom.Point|undefined} Point.
- */
- ol.format.GMLBase.prototype.readPoint = function(node, objectStack) {
- var flatCoordinates =
- this.readFlatCoordinatesFromNode_(node, objectStack);
- if (flatCoordinates) {
- var point = new ol.geom.Point(null);
- point.setFlatCoordinates(ol.geom.GeometryLayout.XYZ, flatCoordinates);
- return point;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {ol.geom.MultiPoint|undefined} MultiPoint.
- */
- ol.format.GMLBase.prototype.readMultiPoint = function(node, objectStack) {
- /** @type {Array.<Array.<number>>} */
- var coordinates = ol.xml.pushParseAndPop([],
- this.MULTIPOINT_PARSERS_, node, objectStack, this);
- if (coordinates) {
- return new ol.geom.MultiPoint(coordinates);
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {ol.geom.MultiLineString|undefined} MultiLineString.
- */
- ol.format.GMLBase.prototype.readMultiLineString = function(node, objectStack) {
- /** @type {Array.<ol.geom.LineString>} */
- var lineStrings = ol.xml.pushParseAndPop([],
- this.MULTILINESTRING_PARSERS_, node, objectStack, this);
- if (lineStrings) {
- var multiLineString = new ol.geom.MultiLineString(null);
- multiLineString.setLineStrings(lineStrings);
- return multiLineString;
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {ol.geom.MultiPolygon|undefined} MultiPolygon.
- */
- ol.format.GMLBase.prototype.readMultiPolygon = function(node, objectStack) {
- /** @type {Array.<ol.geom.Polygon>} */
- var polygons = ol.xml.pushParseAndPop([],
- this.MULTIPOLYGON_PARSERS_, node, objectStack, this);
- if (polygons) {
- var multiPolygon = new ol.geom.MultiPolygon(null);
- multiPolygon.setPolygons(polygons);
- return multiPolygon;
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GMLBase.prototype.pointMemberParser_ = function(node, objectStack) {
- ol.xml.parseNode(this.POINTMEMBER_PARSERS_,
- node, objectStack, this);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GMLBase.prototype.lineStringMemberParser_ = function(node, objectStack) {
- ol.xml.parseNode(this.LINESTRINGMEMBER_PARSERS_,
- node, objectStack, this);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GMLBase.prototype.polygonMemberParser_ = function(node, objectStack) {
- ol.xml.parseNode(this.POLYGONMEMBER_PARSERS_, node,
- objectStack, this);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {ol.geom.LineString|undefined} LineString.
- */
- ol.format.GMLBase.prototype.readLineString = function(node, objectStack) {
- var flatCoordinates =
- this.readFlatCoordinatesFromNode_(node, objectStack);
- if (flatCoordinates) {
- var lineString = new ol.geom.LineString(null);
- lineString.setFlatCoordinates(ol.geom.GeometryLayout.XYZ, flatCoordinates);
- return lineString;
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Array.<number>|undefined} LinearRing flat coordinates.
- */
- ol.format.GMLBase.prototype.readFlatLinearRing_ = function(node, objectStack) {
- var ring = ol.xml.pushParseAndPop(null,
- this.GEOMETRY_FLAT_COORDINATES_PARSERS_, node,
- objectStack, this);
- if (ring) {
- return ring;
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {ol.geom.LinearRing|undefined} LinearRing.
- */
- ol.format.GMLBase.prototype.readLinearRing = function(node, objectStack) {
- var flatCoordinates =
- this.readFlatCoordinatesFromNode_(node, objectStack);
- if (flatCoordinates) {
- var ring = new ol.geom.LinearRing(null);
- ring.setFlatCoordinates(ol.geom.GeometryLayout.XYZ, flatCoordinates);
- return ring;
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {ol.geom.Polygon|undefined} Polygon.
- */
- ol.format.GMLBase.prototype.readPolygon = function(node, objectStack) {
- /** @type {Array.<Array.<number>>} */
- var flatLinearRings = ol.xml.pushParseAndPop([null],
- this.FLAT_LINEAR_RINGS_PARSERS_, node, objectStack, this);
- if (flatLinearRings && flatLinearRings[0]) {
- var polygon = new ol.geom.Polygon(null);
- var flatCoordinates = flatLinearRings[0];
- var ends = [flatCoordinates.length];
- var i, ii;
- for (i = 1, ii = flatLinearRings.length; i < ii; ++i) {
- ol.array.extend(flatCoordinates, flatLinearRings[i]);
- ends.push(flatCoordinates.length);
- }
- polygon.setFlatCoordinates(
- ol.geom.GeometryLayout.XYZ, flatCoordinates, ends);
- return polygon;
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Array.<number>} Flat coordinates.
- */
- ol.format.GMLBase.prototype.readFlatCoordinatesFromNode_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(null,
- this.GEOMETRY_FLAT_COORDINATES_PARSERS_, node,
- objectStack, this);
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GMLBase.prototype.MULTIPOINT_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'pointMember': ol.xml.makeArrayPusher(
- ol.format.GMLBase.prototype.pointMemberParser_),
- 'pointMembers': ol.xml.makeArrayPusher(
- ol.format.GMLBase.prototype.pointMemberParser_)
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GMLBase.prototype.MULTILINESTRING_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'lineStringMember': ol.xml.makeArrayPusher(
- ol.format.GMLBase.prototype.lineStringMemberParser_),
- 'lineStringMembers': ol.xml.makeArrayPusher(
- ol.format.GMLBase.prototype.lineStringMemberParser_)
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GMLBase.prototype.MULTIPOLYGON_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'polygonMember': ol.xml.makeArrayPusher(
- ol.format.GMLBase.prototype.polygonMemberParser_),
- 'polygonMembers': ol.xml.makeArrayPusher(
- ol.format.GMLBase.prototype.polygonMemberParser_)
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GMLBase.prototype.POINTMEMBER_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'Point': ol.xml.makeArrayPusher(
- ol.format.GMLBase.prototype.readFlatCoordinatesFromNode_)
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GMLBase.prototype.LINESTRINGMEMBER_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'LineString': ol.xml.makeArrayPusher(
- ol.format.GMLBase.prototype.readLineString)
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GMLBase.prototype.POLYGONMEMBER_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'Polygon': ol.xml.makeArrayPusher(
- ol.format.GMLBase.prototype.readPolygon)
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @protected
- */
- ol.format.GMLBase.prototype.RING_PARSERS = {
- 'http://www.opengis.net/gml': {
- 'LinearRing': ol.xml.makeReplacer(
- ol.format.GMLBase.prototype.readFlatLinearRing_)
- }
- };
- /**
- * @inheritDoc
- */
- ol.format.GMLBase.prototype.readGeometryFromNode = function(node, opt_options) {
- var geometry = this.readGeometryElement(node,
- [this.getReadOptions(node, opt_options ? opt_options : {})]);
- return geometry ? geometry : null;
- };
- /**
- * Read all features from a GML FeatureCollection.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Options.
- * @return {Array.<ol.Feature>} Features.
- * @api
- */
- ol.format.GMLBase.prototype.readFeatures;
- /**
- * @inheritDoc
- */
- ol.format.GMLBase.prototype.readFeaturesFromNode = function(node, opt_options) {
- var options = {
- featureType: this.featureType,
- featureNS: this.featureNS
- };
- if (opt_options) {
- ol.obj.assign(options, this.getReadOptions(node, opt_options));
- }
- var features = this.readFeaturesInternal(node, [options]);
- return features || [];
- };
- /**
- * @inheritDoc
- */
- ol.format.GMLBase.prototype.readProjectionFromNode = function(node) {
- return ol.proj.get(this.srsName ? this.srsName :
- node.firstElementChild.getAttribute('srsName'));
- };
- goog.provide('ol.format.XSD');
- goog.require('ol.xml');
- goog.require('ol.string');
- /**
- * @const
- * @type {string}
- */
- ol.format.XSD.NAMESPACE_URI = 'http://www.w3.org/2001/XMLSchema';
- /**
- * @param {Node} node Node.
- * @return {boolean|undefined} Boolean.
- */
- ol.format.XSD.readBoolean = function(node) {
- var s = ol.xml.getAllTextContent(node, false);
- return ol.format.XSD.readBooleanString(s);
- };
- /**
- * @param {string} string String.
- * @return {boolean|undefined} Boolean.
- */
- ol.format.XSD.readBooleanString = function(string) {
- var m = /^\s*(true|1)|(false|0)\s*$/.exec(string);
- if (m) {
- return m[1] !== undefined || false;
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @return {number|undefined} DateTime in seconds.
- */
- ol.format.XSD.readDateTime = function(node) {
- var s = ol.xml.getAllTextContent(node, false);
- var dateTime = Date.parse(s);
- return isNaN(dateTime) ? undefined : dateTime / 1000;
- };
- /**
- * @param {Node} node Node.
- * @return {number|undefined} Decimal.
- */
- ol.format.XSD.readDecimal = function(node) {
- var s = ol.xml.getAllTextContent(node, false);
- return ol.format.XSD.readDecimalString(s);
- };
- /**
- * @param {string} string String.
- * @return {number|undefined} Decimal.
- */
- ol.format.XSD.readDecimalString = function(string) {
- // FIXME check spec
- var m = /^\s*([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?)\s*$/i.exec(string);
- if (m) {
- return parseFloat(m[1]);
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @return {number|undefined} Non negative integer.
- */
- ol.format.XSD.readNonNegativeInteger = function(node) {
- var s = ol.xml.getAllTextContent(node, false);
- return ol.format.XSD.readNonNegativeIntegerString(s);
- };
- /**
- * @param {string} string String.
- * @return {number|undefined} Non negative integer.
- */
- ol.format.XSD.readNonNegativeIntegerString = function(string) {
- var m = /^\s*(\d+)\s*$/.exec(string);
- if (m) {
- return parseInt(m[1], 10);
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @return {string|undefined} String.
- */
- ol.format.XSD.readString = function(node) {
- return ol.xml.getAllTextContent(node, false).trim();
- };
- /**
- * @param {Node} node Node to append a TextNode with the boolean to.
- * @param {boolean} bool Boolean.
- */
- ol.format.XSD.writeBooleanTextNode = function(node, bool) {
- ol.format.XSD.writeStringTextNode(node, (bool) ? '1' : '0');
- };
- /**
- * @param {Node} node Node to append a CDATA Section with the string to.
- * @param {string} string String.
- */
- ol.format.XSD.writeCDATASection = function(node, string) {
- node.appendChild(ol.xml.DOCUMENT.createCDATASection(string));
- };
- /**
- * @param {Node} node Node to append a TextNode with the dateTime to.
- * @param {number} dateTime DateTime in seconds.
- */
- ol.format.XSD.writeDateTimeTextNode = function(node, dateTime) {
- var date = new Date(dateTime * 1000);
- var string = date.getUTCFullYear() + '-' +
- ol.string.padNumber(date.getUTCMonth() + 1, 2) + '-' +
- ol.string.padNumber(date.getUTCDate(), 2) + 'T' +
- ol.string.padNumber(date.getUTCHours(), 2) + ':' +
- ol.string.padNumber(date.getUTCMinutes(), 2) + ':' +
- ol.string.padNumber(date.getUTCSeconds(), 2) + 'Z';
- node.appendChild(ol.xml.DOCUMENT.createTextNode(string));
- };
- /**
- * @param {Node} node Node to append a TextNode with the decimal to.
- * @param {number} decimal Decimal.
- */
- ol.format.XSD.writeDecimalTextNode = function(node, decimal) {
- var string = decimal.toPrecision();
- node.appendChild(ol.xml.DOCUMENT.createTextNode(string));
- };
- /**
- * @param {Node} node Node to append a TextNode with the decimal to.
- * @param {number} nonNegativeInteger Non negative integer.
- */
- ol.format.XSD.writeNonNegativeIntegerTextNode = function(node, nonNegativeInteger) {
- var string = nonNegativeInteger.toString();
- node.appendChild(ol.xml.DOCUMENT.createTextNode(string));
- };
- /**
- * @param {Node} node Node to append a TextNode with the string to.
- * @param {string} string String.
- */
- ol.format.XSD.writeStringTextNode = function(node, string) {
- node.appendChild(ol.xml.DOCUMENT.createTextNode(string));
- };
- goog.provide('ol.format.GML3');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.extent');
- goog.require('ol.format.Feature');
- goog.require('ol.format.GMLBase');
- goog.require('ol.format.XSD');
- goog.require('ol.geom.Geometry');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.LineString');
- goog.require('ol.geom.MultiLineString');
- goog.require('ol.geom.MultiPolygon');
- goog.require('ol.geom.Polygon');
- goog.require('ol.obj');
- goog.require('ol.proj');
- goog.require('ol.xml');
- /**
- * @classdesc
- * Feature format for reading and writing data in the GML format
- * version 3.1.1.
- * Currently only supports GML 3.1.1 Simple Features profile.
- *
- * @constructor
- * @param {olx.format.GMLOptions=} opt_options
- * Optional configuration object.
- * @extends {ol.format.GMLBase}
- * @api
- */
- ol.format.GML3 = function(opt_options) {
- var options = /** @type {olx.format.GMLOptions} */
- (opt_options ? opt_options : {});
- ol.format.GMLBase.call(this, options);
- /**
- * @private
- * @type {boolean}
- */
- this.surface_ = options.surface !== undefined ? options.surface : false;
- /**
- * @private
- * @type {boolean}
- */
- this.curve_ = options.curve !== undefined ? options.curve : false;
- /**
- * @private
- * @type {boolean}
- */
- this.multiCurve_ = options.multiCurve !== undefined ?
- options.multiCurve : true;
- /**
- * @private
- * @type {boolean}
- */
- this.multiSurface_ = options.multiSurface !== undefined ?
- options.multiSurface : true;
- /**
- * @inheritDoc
- */
- this.schemaLocation = options.schemaLocation ?
- options.schemaLocation : ol.format.GML3.schemaLocation_;
- /**
- * @private
- * @type {boolean}
- */
- this.hasZ = options.hasZ !== undefined ?
- options.hasZ : false;
- };
- ol.inherits(ol.format.GML3, ol.format.GMLBase);
- /**
- * @const
- * @type {string}
- * @private
- */
- ol.format.GML3.schemaLocation_ = ol.format.GMLBase.GMLNS +
- ' http://schemas.opengis.net/gml/3.1.1/profiles/gmlsfProfile/' +
- '1.0.0/gmlsf.xsd';
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {ol.geom.MultiLineString|undefined} MultiLineString.
- */
- ol.format.GML3.prototype.readMultiCurve_ = function(node, objectStack) {
- /** @type {Array.<ol.geom.LineString>} */
- var lineStrings = ol.xml.pushParseAndPop([],
- this.MULTICURVE_PARSERS_, node, objectStack, this);
- if (lineStrings) {
- var multiLineString = new ol.geom.MultiLineString(null);
- multiLineString.setLineStrings(lineStrings);
- return multiLineString;
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {ol.geom.MultiPolygon|undefined} MultiPolygon.
- */
- ol.format.GML3.prototype.readMultiSurface_ = function(node, objectStack) {
- /** @type {Array.<ol.geom.Polygon>} */
- var polygons = ol.xml.pushParseAndPop([],
- this.MULTISURFACE_PARSERS_, node, objectStack, this);
- if (polygons) {
- var multiPolygon = new ol.geom.MultiPolygon(null);
- multiPolygon.setPolygons(polygons);
- return multiPolygon;
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GML3.prototype.curveMemberParser_ = function(node, objectStack) {
- ol.xml.parseNode(this.CURVEMEMBER_PARSERS_, node, objectStack, this);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GML3.prototype.surfaceMemberParser_ = function(node, objectStack) {
- ol.xml.parseNode(this.SURFACEMEMBER_PARSERS_,
- node, objectStack, this);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Array.<(Array.<number>)>|undefined} flat coordinates.
- */
- ol.format.GML3.prototype.readPatch_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop([null],
- this.PATCHES_PARSERS_, node, objectStack, this);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Array.<number>|undefined} flat coordinates.
- */
- ol.format.GML3.prototype.readSegment_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop([null],
- this.SEGMENTS_PARSERS_, node, objectStack, this);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Array.<(Array.<number>)>|undefined} flat coordinates.
- */
- ol.format.GML3.prototype.readPolygonPatch_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop([null],
- this.FLAT_LINEAR_RINGS_PARSERS_, node, objectStack, this);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Array.<number>|undefined} flat coordinates.
- */
- ol.format.GML3.prototype.readLineStringSegment_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop([null],
- this.GEOMETRY_FLAT_COORDINATES_PARSERS_,
- node, objectStack, this);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GML3.prototype.interiorParser_ = function(node, objectStack) {
- /** @type {Array.<number>|undefined} */
- var flatLinearRing = ol.xml.pushParseAndPop(undefined,
- this.RING_PARSERS, node, objectStack, this);
- if (flatLinearRing) {
- var flatLinearRings = /** @type {Array.<Array.<number>>} */
- (objectStack[objectStack.length - 1]);
- flatLinearRings.push(flatLinearRing);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GML3.prototype.exteriorParser_ = function(node, objectStack) {
- /** @type {Array.<number>|undefined} */
- var flatLinearRing = ol.xml.pushParseAndPop(undefined,
- this.RING_PARSERS, node, objectStack, this);
- if (flatLinearRing) {
- var flatLinearRings = /** @type {Array.<Array.<number>>} */
- (objectStack[objectStack.length - 1]);
- flatLinearRings[0] = flatLinearRing;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {ol.geom.Polygon|undefined} Polygon.
- */
- ol.format.GML3.prototype.readSurface_ = function(node, objectStack) {
- /** @type {Array.<Array.<number>>} */
- var flatLinearRings = ol.xml.pushParseAndPop([null],
- this.SURFACE_PARSERS_, node, objectStack, this);
- if (flatLinearRings && flatLinearRings[0]) {
- var polygon = new ol.geom.Polygon(null);
- var flatCoordinates = flatLinearRings[0];
- var ends = [flatCoordinates.length];
- var i, ii;
- for (i = 1, ii = flatLinearRings.length; i < ii; ++i) {
- ol.array.extend(flatCoordinates, flatLinearRings[i]);
- ends.push(flatCoordinates.length);
- }
- polygon.setFlatCoordinates(
- ol.geom.GeometryLayout.XYZ, flatCoordinates, ends);
- return polygon;
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {ol.geom.LineString|undefined} LineString.
- */
- ol.format.GML3.prototype.readCurve_ = function(node, objectStack) {
- /** @type {Array.<number>} */
- var flatCoordinates = ol.xml.pushParseAndPop([null],
- this.CURVE_PARSERS_, node, objectStack, this);
- if (flatCoordinates) {
- var lineString = new ol.geom.LineString(null);
- lineString.setFlatCoordinates(ol.geom.GeometryLayout.XYZ, flatCoordinates);
- return lineString;
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {ol.Extent|undefined} Envelope.
- */
- ol.format.GML3.prototype.readEnvelope_ = function(node, objectStack) {
- /** @type {Array.<number>} */
- var flatCoordinates = ol.xml.pushParseAndPop([null],
- this.ENVELOPE_PARSERS_, node, objectStack, this);
- return ol.extent.createOrUpdate(flatCoordinates[1][0],
- flatCoordinates[1][1], flatCoordinates[2][0],
- flatCoordinates[2][1]);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Array.<number>|undefined} Flat coordinates.
- */
- ol.format.GML3.prototype.readFlatPos_ = function(node, objectStack) {
- var s = ol.xml.getAllTextContent(node, false);
- var re = /^\s*([+\-]?\d*\.?\d+(?:[eE][+\-]?\d+)?)\s*/;
- /** @type {Array.<number>} */
- var flatCoordinates = [];
- var m;
- while ((m = re.exec(s))) {
- flatCoordinates.push(parseFloat(m[1]));
- s = s.substr(m[0].length);
- }
- if (s !== '') {
- return undefined;
- }
- var context = objectStack[0];
- var containerSrs = context['srsName'];
- var axisOrientation = 'enu';
- if (containerSrs) {
- var proj = ol.proj.get(containerSrs);
- axisOrientation = proj.getAxisOrientation();
- }
- if (axisOrientation === 'neu') {
- var i, ii;
- for (i = 0, ii = flatCoordinates.length; i < ii; i += 3) {
- var y = flatCoordinates[i];
- var x = flatCoordinates[i + 1];
- flatCoordinates[i] = x;
- flatCoordinates[i + 1] = y;
- }
- }
- var len = flatCoordinates.length;
- if (len == 2) {
- flatCoordinates.push(0);
- }
- if (len === 0) {
- return undefined;
- }
- return flatCoordinates;
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Array.<number>|undefined} Flat coordinates.
- */
- ol.format.GML3.prototype.readFlatPosList_ = function(node, objectStack) {
- var s = ol.xml.getAllTextContent(node, false).replace(/^\s*|\s*$/g, '');
- var context = objectStack[0];
- var containerSrs = context['srsName'];
- var contextDimension = context['srsDimension'];
- var axisOrientation = 'enu';
- if (containerSrs) {
- var proj = ol.proj.get(containerSrs);
- axisOrientation = proj.getAxisOrientation();
- }
- var coords = s.split(/\s+/);
- // The "dimension" attribute is from the GML 3.0.1 spec.
- var dim = 2;
- if (node.getAttribute('srsDimension')) {
- dim = ol.format.XSD.readNonNegativeIntegerString(
- node.getAttribute('srsDimension'));
- } else if (node.getAttribute('dimension')) {
- dim = ol.format.XSD.readNonNegativeIntegerString(
- node.getAttribute('dimension'));
- } else if (node.parentNode.getAttribute('srsDimension')) {
- dim = ol.format.XSD.readNonNegativeIntegerString(
- node.parentNode.getAttribute('srsDimension'));
- } else if (contextDimension) {
- dim = ol.format.XSD.readNonNegativeIntegerString(contextDimension);
- }
- var x, y, z;
- var flatCoordinates = [];
- for (var i = 0, ii = coords.length; i < ii; i += dim) {
- x = parseFloat(coords[i]);
- y = parseFloat(coords[i + 1]);
- z = (dim === 3) ? parseFloat(coords[i + 2]) : 0;
- if (axisOrientation.substr(0, 2) === 'en') {
- flatCoordinates.push(x, y, z);
- } else {
- flatCoordinates.push(y, x, z);
- }
- }
- return flatCoordinates;
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GML3.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'pos': ol.xml.makeReplacer(ol.format.GML3.prototype.readFlatPos_),
- 'posList': ol.xml.makeReplacer(ol.format.GML3.prototype.readFlatPosList_)
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GML3.prototype.FLAT_LINEAR_RINGS_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'interior': ol.format.GML3.prototype.interiorParser_,
- 'exterior': ol.format.GML3.prototype.exteriorParser_
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GML3.prototype.GEOMETRY_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'Point': ol.xml.makeReplacer(ol.format.GMLBase.prototype.readPoint),
- 'MultiPoint': ol.xml.makeReplacer(
- ol.format.GMLBase.prototype.readMultiPoint),
- 'LineString': ol.xml.makeReplacer(
- ol.format.GMLBase.prototype.readLineString),
- 'MultiLineString': ol.xml.makeReplacer(
- ol.format.GMLBase.prototype.readMultiLineString),
- 'LinearRing': ol.xml.makeReplacer(
- ol.format.GMLBase.prototype.readLinearRing),
- 'Polygon': ol.xml.makeReplacer(ol.format.GMLBase.prototype.readPolygon),
- 'MultiPolygon': ol.xml.makeReplacer(
- ol.format.GMLBase.prototype.readMultiPolygon),
- 'Surface': ol.xml.makeReplacer(ol.format.GML3.prototype.readSurface_),
- 'MultiSurface': ol.xml.makeReplacer(
- ol.format.GML3.prototype.readMultiSurface_),
- 'Curve': ol.xml.makeReplacer(ol.format.GML3.prototype.readCurve_),
- 'MultiCurve': ol.xml.makeReplacer(
- ol.format.GML3.prototype.readMultiCurve_),
- 'Envelope': ol.xml.makeReplacer(ol.format.GML3.prototype.readEnvelope_)
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GML3.prototype.MULTICURVE_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'curveMember': ol.xml.makeArrayPusher(
- ol.format.GML3.prototype.curveMemberParser_),
- 'curveMembers': ol.xml.makeArrayPusher(
- ol.format.GML3.prototype.curveMemberParser_)
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GML3.prototype.MULTISURFACE_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'surfaceMember': ol.xml.makeArrayPusher(
- ol.format.GML3.prototype.surfaceMemberParser_),
- 'surfaceMembers': ol.xml.makeArrayPusher(
- ol.format.GML3.prototype.surfaceMemberParser_)
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GML3.prototype.CURVEMEMBER_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'LineString': ol.xml.makeArrayPusher(
- ol.format.GMLBase.prototype.readLineString),
- 'Curve': ol.xml.makeArrayPusher(ol.format.GML3.prototype.readCurve_)
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GML3.prototype.SURFACEMEMBER_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'Polygon': ol.xml.makeArrayPusher(ol.format.GMLBase.prototype.readPolygon),
- 'Surface': ol.xml.makeArrayPusher(ol.format.GML3.prototype.readSurface_)
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GML3.prototype.SURFACE_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'patches': ol.xml.makeReplacer(ol.format.GML3.prototype.readPatch_)
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GML3.prototype.CURVE_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'segments': ol.xml.makeReplacer(ol.format.GML3.prototype.readSegment_)
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GML3.prototype.ENVELOPE_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'lowerCorner': ol.xml.makeArrayPusher(
- ol.format.GML3.prototype.readFlatPosList_),
- 'upperCorner': ol.xml.makeArrayPusher(
- ol.format.GML3.prototype.readFlatPosList_)
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GML3.prototype.PATCHES_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'PolygonPatch': ol.xml.makeReplacer(
- ol.format.GML3.prototype.readPolygonPatch_)
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GML3.prototype.SEGMENTS_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'LineStringSegment': ol.xml.makeReplacer(
- ol.format.GML3.prototype.readLineStringSegment_)
- }
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.Point} value Point geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML3.prototype.writePos_ = function(node, value, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var hasZ = context['hasZ'];
- var srsDimension = hasZ ? 3 : 2;
- node.setAttribute('srsDimension', srsDimension);
- var srsName = context['srsName'];
- var axisOrientation = 'enu';
- if (srsName) {
- axisOrientation = ol.proj.get(srsName).getAxisOrientation();
- }
- var point = value.getCoordinates();
- var coords;
- // only 2d for simple features profile
- if (axisOrientation.substr(0, 2) === 'en') {
- coords = (point[0] + ' ' + point[1]);
- } else {
- coords = (point[1] + ' ' + point[0]);
- }
- if (hasZ) {
- // For newly created points, Z can be undefined.
- var z = point[2] || 0;
- coords += ' ' + z;
- }
- ol.format.XSD.writeStringTextNode(node, coords);
- };
- /**
- * @param {Array.<number>} point Point geometry.
- * @param {string=} opt_srsName Optional srsName
- * @param {boolean=} opt_hasZ whether the geometry has a Z coordinate (is 3D) or not.
- * @return {string} The coords string.
- * @private
- */
- ol.format.GML3.prototype.getCoords_ = function(point, opt_srsName, opt_hasZ) {
- var axisOrientation = 'enu';
- if (opt_srsName) {
- axisOrientation = ol.proj.get(opt_srsName).getAxisOrientation();
- }
- var coords = ((axisOrientation.substr(0, 2) === 'en') ?
- point[0] + ' ' + point[1] :
- point[1] + ' ' + point[0]);
- if (opt_hasZ) {
- // For newly created points, Z can be undefined.
- var z = point[2] || 0;
- coords += ' ' + z;
- }
- return coords;
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.LineString|ol.geom.LinearRing} value Geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML3.prototype.writePosList_ = function(node, value, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var hasZ = context['hasZ'];
- var srsDimension = hasZ ? 3 : 2;
- node.setAttribute('srsDimension', srsDimension);
- var srsName = context['srsName'];
- // only 2d for simple features profile
- var points = value.getCoordinates();
- var len = points.length;
- var parts = new Array(len);
- var point;
- for (var i = 0; i < len; ++i) {
- point = points[i];
- parts[i] = this.getCoords_(point, srsName, hasZ);
- }
- ol.format.XSD.writeStringTextNode(node, parts.join(' '));
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.Point} geometry Point geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML3.prototype.writePoint_ = function(node, geometry, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var srsName = context['srsName'];
- if (srsName) {
- node.setAttribute('srsName', srsName);
- }
- var pos = ol.xml.createElementNS(node.namespaceURI, 'pos');
- node.appendChild(pos);
- this.writePos_(pos, geometry, objectStack);
- };
- /**
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.GML3.ENVELOPE_SERIALIZERS_ = {
- 'http://www.opengis.net/gml': {
- 'lowerCorner': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'upperCorner': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode)
- }
- };
- /**
- * @param {Node} node Node.
- * @param {ol.Extent} extent Extent.
- * @param {Array.<*>} objectStack Node stack.
- */
- ol.format.GML3.prototype.writeEnvelope = function(node, extent, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var srsName = context['srsName'];
- if (srsName) {
- node.setAttribute('srsName', srsName);
- }
- var keys = ['lowerCorner', 'upperCorner'];
- var values = [extent[0] + ' ' + extent[1], extent[2] + ' ' + extent[3]];
- ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */
- ({node: node}), ol.format.GML3.ENVELOPE_SERIALIZERS_,
- ol.xml.OBJECT_PROPERTY_NODE_FACTORY,
- values,
- objectStack, keys, this);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.LinearRing} geometry LinearRing geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML3.prototype.writeLinearRing_ = function(node, geometry, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var srsName = context['srsName'];
- if (srsName) {
- node.setAttribute('srsName', srsName);
- }
- var posList = ol.xml.createElementNS(node.namespaceURI, 'posList');
- node.appendChild(posList);
- this.writePosList_(posList, geometry, objectStack);
- };
- /**
- * @param {*} value Value.
- * @param {Array.<*>} objectStack Object stack.
- * @param {string=} opt_nodeName Node name.
- * @return {Node} Node.
- * @private
- */
- ol.format.GML3.prototype.RING_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) {
- var context = objectStack[objectStack.length - 1];
- var parentNode = context.node;
- var exteriorWritten = context['exteriorWritten'];
- if (exteriorWritten === undefined) {
- context['exteriorWritten'] = true;
- }
- return ol.xml.createElementNS(parentNode.namespaceURI,
- exteriorWritten !== undefined ? 'interior' : 'exterior');
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.Polygon} geometry Polygon geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML3.prototype.writeSurfaceOrPolygon_ = function(node, geometry, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var hasZ = context['hasZ'];
- var srsName = context['srsName'];
- if (node.nodeName !== 'PolygonPatch' && srsName) {
- node.setAttribute('srsName', srsName);
- }
- if (node.nodeName === 'Polygon' || node.nodeName === 'PolygonPatch') {
- var rings = geometry.getLinearRings();
- ol.xml.pushSerializeAndPop(
- {node: node, hasZ: hasZ, srsName: srsName},
- ol.format.GML3.RING_SERIALIZERS_,
- this.RING_NODE_FACTORY_,
- rings, objectStack, undefined, this);
- } else if (node.nodeName === 'Surface') {
- var patches = ol.xml.createElementNS(node.namespaceURI, 'patches');
- node.appendChild(patches);
- this.writeSurfacePatches_(
- patches, geometry, objectStack);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.LineString} geometry LineString geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML3.prototype.writeCurveOrLineString_ = function(node, geometry, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var srsName = context['srsName'];
- if (node.nodeName !== 'LineStringSegment' && srsName) {
- node.setAttribute('srsName', srsName);
- }
- if (node.nodeName === 'LineString' ||
- node.nodeName === 'LineStringSegment') {
- var posList = ol.xml.createElementNS(node.namespaceURI, 'posList');
- node.appendChild(posList);
- this.writePosList_(posList, geometry, objectStack);
- } else if (node.nodeName === 'Curve') {
- var segments = ol.xml.createElementNS(node.namespaceURI, 'segments');
- node.appendChild(segments);
- this.writeCurveSegments_(segments,
- geometry, objectStack);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.MultiPolygon} geometry MultiPolygon geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML3.prototype.writeMultiSurfaceOrPolygon_ = function(node, geometry, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var hasZ = context['hasZ'];
- var srsName = context['srsName'];
- var surface = context['surface'];
- if (srsName) {
- node.setAttribute('srsName', srsName);
- }
- var polygons = geometry.getPolygons();
- ol.xml.pushSerializeAndPop({node: node, hasZ: hasZ, srsName: srsName, surface: surface},
- ol.format.GML3.SURFACEORPOLYGONMEMBER_SERIALIZERS_,
- this.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, polygons,
- objectStack, undefined, this);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.MultiPoint} geometry MultiPoint geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML3.prototype.writeMultiPoint_ = function(node, geometry,
- objectStack) {
- var context = objectStack[objectStack.length - 1];
- var srsName = context['srsName'];
- var hasZ = context['hasZ'];
- if (srsName) {
- node.setAttribute('srsName', srsName);
- }
- var points = geometry.getPoints();
- ol.xml.pushSerializeAndPop({node: node, hasZ: hasZ, srsName: srsName},
- ol.format.GML3.POINTMEMBER_SERIALIZERS_,
- ol.xml.makeSimpleNodeFactory('pointMember'), points,
- objectStack, undefined, this);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.MultiLineString} geometry MultiLineString geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML3.prototype.writeMultiCurveOrLineString_ = function(node, geometry, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var hasZ = context['hasZ'];
- var srsName = context['srsName'];
- var curve = context['curve'];
- if (srsName) {
- node.setAttribute('srsName', srsName);
- }
- var lines = geometry.getLineStrings();
- ol.xml.pushSerializeAndPop({node: node, hasZ: hasZ, srsName: srsName, curve: curve},
- ol.format.GML3.LINESTRINGORCURVEMEMBER_SERIALIZERS_,
- this.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, lines,
- objectStack, undefined, this);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.LinearRing} ring LinearRing geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML3.prototype.writeRing_ = function(node, ring, objectStack) {
- var linearRing = ol.xml.createElementNS(node.namespaceURI, 'LinearRing');
- node.appendChild(linearRing);
- this.writeLinearRing_(linearRing, ring, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.Polygon} polygon Polygon geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML3.prototype.writeSurfaceOrPolygonMember_ = function(node, polygon, objectStack) {
- var child = this.GEOMETRY_NODE_FACTORY_(
- polygon, objectStack);
- if (child) {
- node.appendChild(child);
- this.writeSurfaceOrPolygon_(child, polygon, objectStack);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.Point} point Point geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML3.prototype.writePointMember_ = function(node, point, objectStack) {
- var child = ol.xml.createElementNS(node.namespaceURI, 'Point');
- node.appendChild(child);
- this.writePoint_(child, point, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.LineString} line LineString geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML3.prototype.writeLineStringOrCurveMember_ = function(node, line, objectStack) {
- var child = this.GEOMETRY_NODE_FACTORY_(line, objectStack);
- if (child) {
- node.appendChild(child);
- this.writeCurveOrLineString_(child, line, objectStack);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.Polygon} polygon Polygon geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML3.prototype.writeSurfacePatches_ = function(node, polygon, objectStack) {
- var child = ol.xml.createElementNS(node.namespaceURI, 'PolygonPatch');
- node.appendChild(child);
- this.writeSurfaceOrPolygon_(child, polygon, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.LineString} line LineString geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML3.prototype.writeCurveSegments_ = function(node, line, objectStack) {
- var child = ol.xml.createElementNS(node.namespaceURI,
- 'LineStringSegment');
- node.appendChild(child);
- this.writeCurveOrLineString_(child, line, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.Geometry|ol.Extent} geometry Geometry.
- * @param {Array.<*>} objectStack Node stack.
- */
- ol.format.GML3.prototype.writeGeometryElement = function(node, geometry, objectStack) {
- var context = /** @type {olx.format.WriteOptions} */ (objectStack[objectStack.length - 1]);
- var item = ol.obj.assign({}, context);
- item.node = node;
- var value;
- if (Array.isArray(geometry)) {
- if (context.dataProjection) {
- value = ol.proj.transformExtent(
- geometry, context.featureProjection, context.dataProjection);
- } else {
- value = geometry;
- }
- } else {
- value =
- ol.format.Feature.transformWithOptions(/** @type {ol.geom.Geometry} */ (geometry), true, context);
- }
- ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */
- (item), ol.format.GML3.GEOMETRY_SERIALIZERS_,
- this.GEOMETRY_NODE_FACTORY_, [value],
- objectStack, undefined, this);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.Feature} feature Feature.
- * @param {Array.<*>} objectStack Node stack.
- */
- ol.format.GML3.prototype.writeFeatureElement = function(node, feature, objectStack) {
- var fid = feature.getId();
- if (fid) {
- node.setAttribute('fid', fid);
- }
- var context = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- var featureNS = context['featureNS'];
- var geometryName = feature.getGeometryName();
- if (!context.serializers) {
- context.serializers = {};
- context.serializers[featureNS] = {};
- }
- var properties = feature.getProperties();
- var keys = [], values = [];
- for (var key in properties) {
- var value = properties[key];
- if (value !== null) {
- keys.push(key);
- values.push(value);
- if (key == geometryName || value instanceof ol.geom.Geometry) {
- if (!(key in context.serializers[featureNS])) {
- context.serializers[featureNS][key] = ol.xml.makeChildAppender(
- this.writeGeometryElement, this);
- }
- } else {
- if (!(key in context.serializers[featureNS])) {
- context.serializers[featureNS][key] = ol.xml.makeChildAppender(
- ol.format.XSD.writeStringTextNode);
- }
- }
- }
- }
- var item = ol.obj.assign({}, context);
- item.node = node;
- ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */
- (item), context.serializers,
- ol.xml.makeSimpleNodeFactory(undefined, featureNS),
- values,
- objectStack, keys);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<ol.Feature>} features Features.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML3.prototype.writeFeatureMembers_ = function(node, features, objectStack) {
- var context = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- var featureType = context['featureType'];
- var featureNS = context['featureNS'];
- var serializers = {};
- serializers[featureNS] = {};
- serializers[featureNS][featureType] = ol.xml.makeChildAppender(
- this.writeFeatureElement, this);
- var item = ol.obj.assign({}, context);
- item.node = node;
- ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */
- (item),
- serializers,
- ol.xml.makeSimpleNodeFactory(featureType, featureNS), features,
- objectStack);
- };
- /**
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.GML3.SURFACEORPOLYGONMEMBER_SERIALIZERS_ = {
- 'http://www.opengis.net/gml': {
- 'surfaceMember': ol.xml.makeChildAppender(
- ol.format.GML3.prototype.writeSurfaceOrPolygonMember_),
- 'polygonMember': ol.xml.makeChildAppender(
- ol.format.GML3.prototype.writeSurfaceOrPolygonMember_)
- }
- };
- /**
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.GML3.POINTMEMBER_SERIALIZERS_ = {
- 'http://www.opengis.net/gml': {
- 'pointMember': ol.xml.makeChildAppender(
- ol.format.GML3.prototype.writePointMember_)
- }
- };
- /**
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.GML3.LINESTRINGORCURVEMEMBER_SERIALIZERS_ = {
- 'http://www.opengis.net/gml': {
- 'lineStringMember': ol.xml.makeChildAppender(
- ol.format.GML3.prototype.writeLineStringOrCurveMember_),
- 'curveMember': ol.xml.makeChildAppender(
- ol.format.GML3.prototype.writeLineStringOrCurveMember_)
- }
- };
- /**
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.GML3.RING_SERIALIZERS_ = {
- 'http://www.opengis.net/gml': {
- 'exterior': ol.xml.makeChildAppender(ol.format.GML3.prototype.writeRing_),
- 'interior': ol.xml.makeChildAppender(ol.format.GML3.prototype.writeRing_)
- }
- };
- /**
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.GML3.GEOMETRY_SERIALIZERS_ = {
- 'http://www.opengis.net/gml': {
- 'Curve': ol.xml.makeChildAppender(
- ol.format.GML3.prototype.writeCurveOrLineString_),
- 'MultiCurve': ol.xml.makeChildAppender(
- ol.format.GML3.prototype.writeMultiCurveOrLineString_),
- 'Point': ol.xml.makeChildAppender(ol.format.GML3.prototype.writePoint_),
- 'MultiPoint': ol.xml.makeChildAppender(
- ol.format.GML3.prototype.writeMultiPoint_),
- 'LineString': ol.xml.makeChildAppender(
- ol.format.GML3.prototype.writeCurveOrLineString_),
- 'MultiLineString': ol.xml.makeChildAppender(
- ol.format.GML3.prototype.writeMultiCurveOrLineString_),
- 'LinearRing': ol.xml.makeChildAppender(
- ol.format.GML3.prototype.writeLinearRing_),
- 'Polygon': ol.xml.makeChildAppender(
- ol.format.GML3.prototype.writeSurfaceOrPolygon_),
- 'MultiPolygon': ol.xml.makeChildAppender(
- ol.format.GML3.prototype.writeMultiSurfaceOrPolygon_),
- 'Surface': ol.xml.makeChildAppender(
- ol.format.GML3.prototype.writeSurfaceOrPolygon_),
- 'MultiSurface': ol.xml.makeChildAppender(
- ol.format.GML3.prototype.writeMultiSurfaceOrPolygon_),
- 'Envelope': ol.xml.makeChildAppender(
- ol.format.GML3.prototype.writeEnvelope)
- }
- };
- /**
- * @const
- * @type {Object.<string, string>}
- * @private
- */
- ol.format.GML3.MULTIGEOMETRY_TO_MEMBER_NODENAME_ = {
- 'MultiLineString': 'lineStringMember',
- 'MultiCurve': 'curveMember',
- 'MultiPolygon': 'polygonMember',
- 'MultiSurface': 'surfaceMember'
- };
- /**
- * @const
- * @param {*} value Value.
- * @param {Array.<*>} objectStack Object stack.
- * @param {string=} opt_nodeName Node name.
- * @return {Node|undefined} Node.
- * @private
- */
- ol.format.GML3.prototype.MULTIGEOMETRY_MEMBER_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) {
- var parentNode = objectStack[objectStack.length - 1].node;
- return ol.xml.createElementNS('http://www.opengis.net/gml',
- ol.format.GML3.MULTIGEOMETRY_TO_MEMBER_NODENAME_[parentNode.nodeName]);
- };
- /**
- * @const
- * @param {*} value Value.
- * @param {Array.<*>} objectStack Object stack.
- * @param {string=} opt_nodeName Node name.
- * @return {Node|undefined} Node.
- * @private
- */
- ol.format.GML3.prototype.GEOMETRY_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) {
- var context = objectStack[objectStack.length - 1];
- var multiSurface = context['multiSurface'];
- var surface = context['surface'];
- var curve = context['curve'];
- var multiCurve = context['multiCurve'];
- var nodeName;
- if (!Array.isArray(value)) {
- nodeName = /** @type {ol.geom.Geometry} */ (value).getType();
- if (nodeName === 'MultiPolygon' && multiSurface === true) {
- nodeName = 'MultiSurface';
- } else if (nodeName === 'Polygon' && surface === true) {
- nodeName = 'Surface';
- } else if (nodeName === 'LineString' && curve === true) {
- nodeName = 'Curve';
- } else if (nodeName === 'MultiLineString' && multiCurve === true) {
- nodeName = 'MultiCurve';
- }
- } else {
- nodeName = 'Envelope';
- }
- return ol.xml.createElementNS('http://www.opengis.net/gml',
- nodeName);
- };
- /**
- * Encode a geometry in GML 3.1.1 Simple Features.
- *
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Options.
- * @return {Node} Node.
- * @override
- * @api
- */
- ol.format.GML3.prototype.writeGeometryNode = function(geometry, opt_options) {
- opt_options = this.adaptOptions(opt_options);
- var geom = ol.xml.createElementNS('http://www.opengis.net/gml', 'geom');
- var context = {node: geom, hasZ: this.hasZ, srsName: this.srsName,
- curve: this.curve_, surface: this.surface_,
- multiSurface: this.multiSurface_, multiCurve: this.multiCurve_};
- if (opt_options) {
- ol.obj.assign(context, opt_options);
- }
- this.writeGeometryElement(geom, geometry, [context]);
- return geom;
- };
- /**
- * Encode an array of features in GML 3.1.1 Simple Features.
- *
- * @function
- * @param {Array.<ol.Feature>} features Features.
- * @param {olx.format.WriteOptions=} opt_options Options.
- * @return {string} Result.
- * @api
- */
- ol.format.GML3.prototype.writeFeatures;
- /**
- * Encode an array of features in the GML 3.1.1 format as an XML node.
- *
- * @param {Array.<ol.Feature>} features Features.
- * @param {olx.format.WriteOptions=} opt_options Options.
- * @return {Node} Node.
- * @override
- * @api
- */
- ol.format.GML3.prototype.writeFeaturesNode = function(features, opt_options) {
- opt_options = this.adaptOptions(opt_options);
- var node = ol.xml.createElementNS('http://www.opengis.net/gml',
- 'featureMembers');
- ol.xml.setAttributeNS(node, 'http://www.w3.org/2001/XMLSchema-instance',
- 'xsi:schemaLocation', this.schemaLocation);
- var context = {
- srsName: this.srsName,
- hasZ: this.hasZ,
- curve: this.curve_,
- surface: this.surface_,
- multiSurface: this.multiSurface_,
- multiCurve: this.multiCurve_,
- featureNS: this.featureNS,
- featureType: this.featureType
- };
- if (opt_options) {
- ol.obj.assign(context, opt_options);
- }
- this.writeFeatureMembers_(node, features, [context]);
- return node;
- };
- goog.provide('ol.format.GML');
- goog.require('ol.format.GML3');
- /**
- * @classdesc
- * Feature format for reading and writing data in the GML format
- * version 3.1.1.
- * Currently only supports GML 3.1.1 Simple Features profile.
- *
- * @constructor
- * @param {olx.format.GMLOptions=} opt_options
- * Optional configuration object.
- * @extends {ol.format.GMLBase}
- * @api
- */
- ol.format.GML = ol.format.GML3;
- /**
- * Encode an array of features in GML 3.1.1 Simple Features.
- *
- * @function
- * @param {Array.<ol.Feature>} features Features.
- * @param {olx.format.WriteOptions=} opt_options Options.
- * @return {string} Result.
- * @api
- */
- ol.format.GML.prototype.writeFeatures;
- /**
- * Encode an array of features in the GML 3.1.1 format as an XML node.
- *
- * @function
- * @param {Array.<ol.Feature>} features Features.
- * @param {olx.format.WriteOptions=} opt_options Options.
- * @return {Node} Node.
- * @api
- */
- ol.format.GML.prototype.writeFeaturesNode;
- goog.provide('ol.format.GML2');
- goog.require('ol');
- goog.require('ol.extent');
- goog.require('ol.format.Feature');
- goog.require('ol.format.GMLBase');
- goog.require('ol.format.XSD');
- goog.require('ol.geom.Geometry');
- goog.require('ol.obj');
- goog.require('ol.proj');
- goog.require('ol.xml');
- /**
- * @classdesc
- * Feature format for reading and writing data in the GML format,
- * version 2.1.2.
- *
- * @constructor
- * @param {olx.format.GMLOptions=} opt_options Optional configuration object.
- * @extends {ol.format.GMLBase}
- * @api
- */
- ol.format.GML2 = function(opt_options) {
- var options = /** @type {olx.format.GMLOptions} */
- (opt_options ? opt_options : {});
- ol.format.GMLBase.call(this, options);
- this.FEATURE_COLLECTION_PARSERS[ol.format.GMLBase.GMLNS][
- 'featureMember'] =
- ol.xml.makeArrayPusher(ol.format.GMLBase.prototype.readFeaturesInternal);
- /**
- * @inheritDoc
- */
- this.schemaLocation = options.schemaLocation ?
- options.schemaLocation : ol.format.GML2.schemaLocation_;
- };
- ol.inherits(ol.format.GML2, ol.format.GMLBase);
- /**
- * @const
- * @type {string}
- * @private
- */
- ol.format.GML2.schemaLocation_ = ol.format.GMLBase.GMLNS +
- ' http://schemas.opengis.net/gml/2.1.2/feature.xsd';
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Array.<number>|undefined} Flat coordinates.
- */
- ol.format.GML2.prototype.readFlatCoordinates_ = function(node, objectStack) {
- var s = ol.xml.getAllTextContent(node, false).replace(/^\s*|\s*$/g, '');
- var context = /** @type {ol.XmlNodeStackItem} */ (objectStack[0]);
- var containerSrs = context['srsName'];
- var axisOrientation = 'enu';
- if (containerSrs) {
- var proj = ol.proj.get(containerSrs);
- if (proj) {
- axisOrientation = proj.getAxisOrientation();
- }
- }
- var coordsGroups = s.trim().split(/\s+/);
- var x, y, z;
- var flatCoordinates = [];
- for (var i = 0, ii = coordsGroups.length; i < ii; i++) {
- var coords = coordsGroups[i].split(/,+/);
- x = parseFloat(coords[0]);
- y = parseFloat(coords[1]);
- z = (coords.length === 3) ? parseFloat(coords[2]) : 0;
- if (axisOrientation.substr(0, 2) === 'en') {
- flatCoordinates.push(x, y, z);
- } else {
- flatCoordinates.push(y, x, z);
- }
- }
- return flatCoordinates;
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {ol.Extent|undefined} Envelope.
- */
- ol.format.GML2.prototype.readBox_ = function(node, objectStack) {
- /** @type {Array.<number>} */
- var flatCoordinates = ol.xml.pushParseAndPop([null],
- this.BOX_PARSERS_, node, objectStack, this);
- return ol.extent.createOrUpdate(flatCoordinates[1][0],
- flatCoordinates[1][1], flatCoordinates[1][3],
- flatCoordinates[1][4]);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GML2.prototype.innerBoundaryIsParser_ = function(node, objectStack) {
- /** @type {Array.<number>|undefined} */
- var flatLinearRing = ol.xml.pushParseAndPop(undefined,
- this.RING_PARSERS, node, objectStack, this);
- if (flatLinearRing) {
- var flatLinearRings = /** @type {Array.<Array.<number>>} */
- (objectStack[objectStack.length - 1]);
- flatLinearRings.push(flatLinearRing);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GML2.prototype.outerBoundaryIsParser_ = function(node, objectStack) {
- /** @type {Array.<number>|undefined} */
- var flatLinearRing = ol.xml.pushParseAndPop(undefined,
- this.RING_PARSERS, node, objectStack, this);
- if (flatLinearRing) {
- var flatLinearRings = /** @type {Array.<Array.<number>>} */
- (objectStack[objectStack.length - 1]);
- flatLinearRings[0] = flatLinearRing;
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GML2.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'coordinates': ol.xml.makeReplacer(
- ol.format.GML2.prototype.readFlatCoordinates_)
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GML2.prototype.FLAT_LINEAR_RINGS_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'innerBoundaryIs': ol.format.GML2.prototype.innerBoundaryIsParser_,
- 'outerBoundaryIs': ol.format.GML2.prototype.outerBoundaryIsParser_
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GML2.prototype.BOX_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'coordinates': ol.xml.makeArrayPusher(
- ol.format.GML2.prototype.readFlatCoordinates_)
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GML2.prototype.GEOMETRY_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'Point': ol.xml.makeReplacer(ol.format.GMLBase.prototype.readPoint),
- 'MultiPoint': ol.xml.makeReplacer(
- ol.format.GMLBase.prototype.readMultiPoint),
- 'LineString': ol.xml.makeReplacer(
- ol.format.GMLBase.prototype.readLineString),
- 'MultiLineString': ol.xml.makeReplacer(
- ol.format.GMLBase.prototype.readMultiLineString),
- 'LinearRing': ol.xml.makeReplacer(
- ol.format.GMLBase.prototype.readLinearRing),
- 'Polygon': ol.xml.makeReplacer(ol.format.GMLBase.prototype.readPolygon),
- 'MultiPolygon': ol.xml.makeReplacer(
- ol.format.GMLBase.prototype.readMultiPolygon),
- 'Box': ol.xml.makeReplacer(ol.format.GML2.prototype.readBox_)
- }
- };
- /**
- * @const
- * @param {*} value Value.
- * @param {Array.<*>} objectStack Object stack.
- * @param {string=} opt_nodeName Node name.
- * @return {Node|undefined} Node.
- * @private
- */
- ol.format.GML2.prototype.GEOMETRY_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) {
- var context = objectStack[objectStack.length - 1];
- var multiSurface = context['multiSurface'];
- var surface = context['surface'];
- var multiCurve = context['multiCurve'];
- var nodeName;
- if (!Array.isArray(value)) {
- nodeName = /** @type {ol.geom.Geometry} */ (value).getType();
- if (nodeName === 'MultiPolygon' && multiSurface === true) {
- nodeName = 'MultiSurface';
- } else if (nodeName === 'Polygon' && surface === true) {
- nodeName = 'Surface';
- } else if (nodeName === 'MultiLineString' && multiCurve === true) {
- nodeName = 'MultiCurve';
- }
- } else {
- nodeName = 'Envelope';
- }
- return ol.xml.createElementNS('http://www.opengis.net/gml',
- nodeName);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.Feature} feature Feature.
- * @param {Array.<*>} objectStack Node stack.
- */
- ol.format.GML2.prototype.writeFeatureElement = function(node, feature, objectStack) {
- var fid = feature.getId();
- if (fid) {
- node.setAttribute('fid', fid);
- }
- var context = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- var featureNS = context['featureNS'];
- var geometryName = feature.getGeometryName();
- if (!context.serializers) {
- context.serializers = {};
- context.serializers[featureNS] = {};
- }
- var properties = feature.getProperties();
- var keys = [], values = [];
- for (var key in properties) {
- var value = properties[key];
- if (value !== null) {
- keys.push(key);
- values.push(value);
- if (key == geometryName || value instanceof ol.geom.Geometry) {
- if (!(key in context.serializers[featureNS])) {
- context.serializers[featureNS][key] = ol.xml.makeChildAppender(
- this.writeGeometryElement, this);
- }
- } else {
- if (!(key in context.serializers[featureNS])) {
- context.serializers[featureNS][key] = ol.xml.makeChildAppender(
- ol.format.XSD.writeStringTextNode);
- }
- }
- }
- }
- var item = ol.obj.assign({}, context);
- item.node = node;
- ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */
- (item), context.serializers,
- ol.xml.makeSimpleNodeFactory(undefined, featureNS),
- values,
- objectStack, keys);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.Geometry|ol.Extent} geometry Geometry.
- * @param {Array.<*>} objectStack Node stack.
- */
- ol.format.GML2.prototype.writeGeometryElement = function(node, geometry, objectStack) {
- var context = /** @type {olx.format.WriteOptions} */ (objectStack[objectStack.length - 1]);
- var item = ol.obj.assign({}, context);
- item.node = node;
- var value;
- if (Array.isArray(geometry)) {
- if (context.dataProjection) {
- value = ol.proj.transformExtent(
- geometry, context.featureProjection, context.dataProjection);
- } else {
- value = geometry;
- }
- } else {
- value =
- ol.format.Feature.transformWithOptions(/** @type {ol.geom.Geometry} */ (geometry), true, context);
- }
- ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */
- (item), ol.format.GML2.GEOMETRY_SERIALIZERS_,
- this.GEOMETRY_NODE_FACTORY_, [value],
- objectStack, undefined, this);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.LineString} geometry LineString geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML2.prototype.writeCurveOrLineString_ = function(node, geometry, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var srsName = context['srsName'];
- if (node.nodeName !== 'LineStringSegment' && srsName) {
- node.setAttribute('srsName', srsName);
- }
- if (node.nodeName === 'LineString' ||
- node.nodeName === 'LineStringSegment') {
- var coordinates = this.createCoordinatesNode_(node.namespaceURI);
- node.appendChild(coordinates);
- this.writeCoordinates_(coordinates, geometry, objectStack);
- } else if (node.nodeName === 'Curve') {
- var segments = ol.xml.createElementNS(node.namespaceURI, 'segments');
- node.appendChild(segments);
- this.writeCurveSegments_(segments,
- geometry, objectStack);
- }
- };
- /**
- * @param {string} namespaceURI XML namespace.
- * @returns {Node} coordinates node.
- * @private
- */
- ol.format.GML2.prototype.createCoordinatesNode_ = function(namespaceURI) {
- var coordinates = ol.xml.createElementNS(namespaceURI, 'coordinates');
- coordinates.setAttribute('decimal', '.');
- coordinates.setAttribute('cs', ',');
- coordinates.setAttribute('ts', ' ');
- return coordinates;
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.LineString|ol.geom.LinearRing} value Geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML2.prototype.writeCoordinates_ = function(node, value, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var hasZ = context['hasZ'];
- var srsName = context['srsName'];
- // only 2d for simple features profile
- var points = value.getCoordinates();
- var len = points.length;
- var parts = new Array(len);
- var point;
- for (var i = 0; i < len; ++i) {
- point = points[i];
- parts[i] = this.getCoords_(point, srsName, hasZ);
- }
- ol.format.XSD.writeStringTextNode(node, parts.join(' '));
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.LineString} line LineString geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML2.prototype.writeCurveSegments_ = function(node, line, objectStack) {
- var child = ol.xml.createElementNS(node.namespaceURI,
- 'LineStringSegment');
- node.appendChild(child);
- this.writeCurveOrLineString_(child, line, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.Polygon} geometry Polygon geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML2.prototype.writeSurfaceOrPolygon_ = function(node, geometry, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var hasZ = context['hasZ'];
- var srsName = context['srsName'];
- if (node.nodeName !== 'PolygonPatch' && srsName) {
- node.setAttribute('srsName', srsName);
- }
- if (node.nodeName === 'Polygon' || node.nodeName === 'PolygonPatch') {
- var rings = geometry.getLinearRings();
- ol.xml.pushSerializeAndPop(
- {node: node, hasZ: hasZ, srsName: srsName},
- ol.format.GML2.RING_SERIALIZERS_,
- this.RING_NODE_FACTORY_,
- rings, objectStack, undefined, this);
- } else if (node.nodeName === 'Surface') {
- var patches = ol.xml.createElementNS(node.namespaceURI, 'patches');
- node.appendChild(patches);
- this.writeSurfacePatches_(
- patches, geometry, objectStack);
- }
- };
- /**
- * @param {*} value Value.
- * @param {Array.<*>} objectStack Object stack.
- * @param {string=} opt_nodeName Node name.
- * @return {Node} Node.
- * @private
- */
- ol.format.GML2.prototype.RING_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) {
- var context = objectStack[objectStack.length - 1];
- var parentNode = context.node;
- var exteriorWritten = context['exteriorWritten'];
- if (exteriorWritten === undefined) {
- context['exteriorWritten'] = true;
- }
- return ol.xml.createElementNS(parentNode.namespaceURI,
- exteriorWritten !== undefined ? 'innerBoundaryIs' : 'outerBoundaryIs');
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.Polygon} polygon Polygon geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML2.prototype.writeSurfacePatches_ = function(node, polygon, objectStack) {
- var child = ol.xml.createElementNS(node.namespaceURI, 'PolygonPatch');
- node.appendChild(child);
- this.writeSurfaceOrPolygon_(child, polygon, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.LinearRing} ring LinearRing geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML2.prototype.writeRing_ = function(node, ring, objectStack) {
- var linearRing = ol.xml.createElementNS(node.namespaceURI, 'LinearRing');
- node.appendChild(linearRing);
- this.writeLinearRing_(linearRing, ring, objectStack);
- };
- /**
- * @param {Array.<number>} point Point geometry.
- * @param {string=} opt_srsName Optional srsName
- * @param {boolean=} opt_hasZ whether the geometry has a Z coordinate (is 3D) or not.
- * @return {string} The coords string.
- * @private
- */
- ol.format.GML2.prototype.getCoords_ = function(point, opt_srsName, opt_hasZ) {
- var axisOrientation = 'enu';
- if (opt_srsName) {
- axisOrientation = ol.proj.get(opt_srsName).getAxisOrientation();
- }
- var coords = ((axisOrientation.substr(0, 2) === 'en') ?
- point[0] + ',' + point[1] :
- point[1] + ',' + point[0]);
- if (opt_hasZ) {
- // For newly created points, Z can be undefined.
- var z = point[2] || 0;
- coords += ',' + z;
- }
- return coords;
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.MultiLineString} geometry MultiLineString geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML2.prototype.writeMultiCurveOrLineString_ = function(node, geometry, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var hasZ = context['hasZ'];
- var srsName = context['srsName'];
- var curve = context['curve'];
- if (srsName) {
- node.setAttribute('srsName', srsName);
- }
- var lines = geometry.getLineStrings();
- ol.xml.pushSerializeAndPop({node: node, hasZ: hasZ, srsName: srsName, curve: curve},
- ol.format.GML2.LINESTRINGORCURVEMEMBER_SERIALIZERS_,
- this.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, lines,
- objectStack, undefined, this);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.Point} geometry Point geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML2.prototype.writePoint_ = function(node, geometry, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var hasZ = context['hasZ'];
- var srsName = context['srsName'];
- if (srsName) {
- node.setAttribute('srsName', srsName);
- }
- var coordinates = this.createCoordinatesNode_(node.namespaceURI);
- node.appendChild(coordinates);
- var point = geometry.getCoordinates();
- var coord = this.getCoords_(point, srsName, hasZ);
- ol.format.XSD.writeStringTextNode(coordinates, coord);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.MultiPoint} geometry MultiPoint geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML2.prototype.writeMultiPoint_ = function(node, geometry,
- objectStack) {
- var context = objectStack[objectStack.length - 1];
- var hasZ = context['hasZ'];
- var srsName = context['srsName'];
- if (srsName) {
- node.setAttribute('srsName', srsName);
- }
- var points = geometry.getPoints();
- ol.xml.pushSerializeAndPop({node: node, hasZ: hasZ, srsName: srsName},
- ol.format.GML2.POINTMEMBER_SERIALIZERS_,
- ol.xml.makeSimpleNodeFactory('pointMember'), points,
- objectStack, undefined, this);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.Point} point Point geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML2.prototype.writePointMember_ = function(node, point, objectStack) {
- var child = ol.xml.createElementNS(node.namespaceURI, 'Point');
- node.appendChild(child);
- this.writePoint_(child, point, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.LineString} line LineString geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML2.prototype.writeLineStringOrCurveMember_ = function(node, line, objectStack) {
- var child = this.GEOMETRY_NODE_FACTORY_(line, objectStack);
- if (child) {
- node.appendChild(child);
- this.writeCurveOrLineString_(child, line, objectStack);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.LinearRing} geometry LinearRing geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML2.prototype.writeLinearRing_ = function(node, geometry, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var srsName = context['srsName'];
- if (srsName) {
- node.setAttribute('srsName', srsName);
- }
- var coordinates = this.createCoordinatesNode_(node.namespaceURI);
- node.appendChild(coordinates);
- this.writeCoordinates_(coordinates, geometry, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.MultiPolygon} geometry MultiPolygon geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML2.prototype.writeMultiSurfaceOrPolygon_ = function(node, geometry, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var hasZ = context['hasZ'];
- var srsName = context['srsName'];
- var surface = context['surface'];
- if (srsName) {
- node.setAttribute('srsName', srsName);
- }
- var polygons = geometry.getPolygons();
- ol.xml.pushSerializeAndPop({node: node, hasZ: hasZ, srsName: srsName, surface: surface},
- ol.format.GML2.SURFACEORPOLYGONMEMBER_SERIALIZERS_,
- this.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, polygons,
- objectStack, undefined, this);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.Polygon} polygon Polygon geometry.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML2.prototype.writeSurfaceOrPolygonMember_ = function(node, polygon, objectStack) {
- var child = this.GEOMETRY_NODE_FACTORY_(
- polygon, objectStack);
- if (child) {
- node.appendChild(child);
- this.writeSurfaceOrPolygon_(child, polygon, objectStack);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {ol.Extent} extent Extent.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GML2.prototype.writeEnvelope = function(node, extent, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var srsName = context['srsName'];
- if (srsName) {
- node.setAttribute('srsName', srsName);
- }
- var keys = ['lowerCorner', 'upperCorner'];
- var values = [extent[0] + ' ' + extent[1], extent[2] + ' ' + extent[3]];
- ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */
- ({node: node}), ol.format.GML2.ENVELOPE_SERIALIZERS_,
- ol.xml.OBJECT_PROPERTY_NODE_FACTORY,
- values,
- objectStack, keys, this);
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.GML2.GEOMETRY_SERIALIZERS_ = {
- 'http://www.opengis.net/gml': {
- 'Curve': ol.xml.makeChildAppender(
- ol.format.GML2.prototype.writeCurveOrLineString_),
- 'MultiCurve': ol.xml.makeChildAppender(
- ol.format.GML2.prototype.writeMultiCurveOrLineString_),
- 'Point': ol.xml.makeChildAppender(ol.format.GML2.prototype.writePoint_),
- 'MultiPoint': ol.xml.makeChildAppender(
- ol.format.GML2.prototype.writeMultiPoint_),
- 'LineString': ol.xml.makeChildAppender(
- ol.format.GML2.prototype.writeCurveOrLineString_),
- 'MultiLineString': ol.xml.makeChildAppender(
- ol.format.GML2.prototype.writeMultiCurveOrLineString_),
- 'LinearRing': ol.xml.makeChildAppender(
- ol.format.GML2.prototype.writeLinearRing_),
- 'Polygon': ol.xml.makeChildAppender(
- ol.format.GML2.prototype.writeSurfaceOrPolygon_),
- 'MultiPolygon': ol.xml.makeChildAppender(
- ol.format.GML2.prototype.writeMultiSurfaceOrPolygon_),
- 'Surface': ol.xml.makeChildAppender(
- ol.format.GML2.prototype.writeSurfaceOrPolygon_),
- 'MultiSurface': ol.xml.makeChildAppender(
- ol.format.GML2.prototype.writeMultiSurfaceOrPolygon_),
- 'Envelope': ol.xml.makeChildAppender(
- ol.format.GML2.prototype.writeEnvelope)
- }
- };
- /**
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.GML2.RING_SERIALIZERS_ = {
- 'http://www.opengis.net/gml': {
- 'outerBoundaryIs': ol.xml.makeChildAppender(ol.format.GML2.prototype.writeRing_),
- 'innerBoundaryIs': ol.xml.makeChildAppender(ol.format.GML2.prototype.writeRing_)
- }
- };
- /**
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.GML2.POINTMEMBER_SERIALIZERS_ = {
- 'http://www.opengis.net/gml': {
- 'pointMember': ol.xml.makeChildAppender(
- ol.format.GML2.prototype.writePointMember_)
- }
- };
- /**
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.GML2.LINESTRINGORCURVEMEMBER_SERIALIZERS_ = {
- 'http://www.opengis.net/gml': {
- 'lineStringMember': ol.xml.makeChildAppender(
- ol.format.GML2.prototype.writeLineStringOrCurveMember_),
- 'curveMember': ol.xml.makeChildAppender(
- ol.format.GML2.prototype.writeLineStringOrCurveMember_)
- }
- };
- /**
- * @const
- * @param {*} value Value.
- * @param {Array.<*>} objectStack Object stack.
- * @param {string=} opt_nodeName Node name.
- * @return {Node|undefined} Node.
- * @private
- */
- ol.format.GML2.prototype.MULTIGEOMETRY_MEMBER_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) {
- var parentNode = objectStack[objectStack.length - 1].node;
- return ol.xml.createElementNS('http://www.opengis.net/gml',
- ol.format.GML2.MULTIGEOMETRY_TO_MEMBER_NODENAME_[parentNode.nodeName]);
- };
- /**
- * @const
- * @type {Object.<string, string>}
- * @private
- */
- ol.format.GML2.MULTIGEOMETRY_TO_MEMBER_NODENAME_ = {
- 'MultiLineString': 'lineStringMember',
- 'MultiCurve': 'curveMember',
- 'MultiPolygon': 'polygonMember',
- 'MultiSurface': 'surfaceMember'
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.GML2.SURFACEORPOLYGONMEMBER_SERIALIZERS_ = {
- 'http://www.opengis.net/gml': {
- 'surfaceMember': ol.xml.makeChildAppender(
- ol.format.GML2.prototype.writeSurfaceOrPolygonMember_),
- 'polygonMember': ol.xml.makeChildAppender(
- ol.format.GML2.prototype.writeSurfaceOrPolygonMember_)
- }
- };
- /**
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.GML2.ENVELOPE_SERIALIZERS_ = {
- 'http://www.opengis.net/gml': {
- 'lowerCorner': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'upperCorner': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode)
- }
- };
- goog.provide('ol.format.GPX');
- goog.require('ol');
- goog.require('ol.Feature');
- goog.require('ol.array');
- goog.require('ol.format.Feature');
- goog.require('ol.format.XMLFeature');
- goog.require('ol.format.XSD');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.LineString');
- goog.require('ol.geom.MultiLineString');
- goog.require('ol.geom.Point');
- goog.require('ol.proj');
- goog.require('ol.xml');
- /**
- * @classdesc
- * Feature format for reading and writing data in the GPX format.
- *
- * @constructor
- * @extends {ol.format.XMLFeature}
- * @param {olx.format.GPXOptions=} opt_options Options.
- * @api
- */
- ol.format.GPX = function(opt_options) {
- var options = opt_options ? opt_options : {};
- ol.format.XMLFeature.call(this);
- /**
- * @inheritDoc
- */
- this.defaultDataProjection = ol.proj.get('EPSG:4326');
- /**
- * @type {function(ol.Feature, Node)|undefined}
- * @private
- */
- this.readExtensions_ = options.readExtensions;
- };
- ol.inherits(ol.format.GPX, ol.format.XMLFeature);
- /**
- * @const
- * @private
- * @type {Array.<string>}
- */
- ol.format.GPX.NAMESPACE_URIS_ = [
- null,
- 'http://www.topografix.com/GPX/1/0',
- 'http://www.topografix.com/GPX/1/1'
- ];
- /**
- * @const
- * @type {string}
- * @private
- */
- ol.format.GPX.SCHEMA_LOCATION_ = 'http://www.topografix.com/GPX/1/1 ' +
- 'http://www.topografix.com/GPX/1/1/gpx.xsd';
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {ol.LayoutOptions} layoutOptions Layout options.
- * @param {Node} node Node.
- * @param {Object} values Values.
- * @private
- * @return {Array.<number>} Flat coordinates.
- */
- ol.format.GPX.appendCoordinate_ = function(flatCoordinates, layoutOptions, node, values) {
- flatCoordinates.push(
- parseFloat(node.getAttribute('lon')),
- parseFloat(node.getAttribute('lat')));
- if ('ele' in values) {
- flatCoordinates.push(/** @type {number} */ (values['ele']));
- delete values['ele'];
- layoutOptions.hasZ = true;
- } else {
- flatCoordinates.push(0);
- }
- if ('time' in values) {
- flatCoordinates.push(/** @type {number} */ (values['time']));
- delete values['time'];
- layoutOptions.hasM = true;
- } else {
- flatCoordinates.push(0);
- }
- return flatCoordinates;
- };
- /**
- * Choose GeometryLayout based on flags in layoutOptions and adjust flatCoordinates
- * and ends arrays by shrinking them accordingly (removing unused zero entries).
- *
- * @param {ol.LayoutOptions} layoutOptions Layout options.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {Array.<number>=} ends Ends.
- * @return {ol.geom.GeometryLayout} Layout.
- */
- ol.format.GPX.applyLayoutOptions_ = function(layoutOptions, flatCoordinates, ends) {
- var layout = ol.geom.GeometryLayout.XY;
- var stride = 2;
- if (layoutOptions.hasZ && layoutOptions.hasM) {
- layout = ol.geom.GeometryLayout.XYZM;
- stride = 4;
- } else if (layoutOptions.hasZ) {
- layout = ol.geom.GeometryLayout.XYZ;
- stride = 3;
- } else if (layoutOptions.hasM) {
- layout = ol.geom.GeometryLayout.XYM;
- stride = 3;
- }
- if (stride !== 4) {
- var i, ii;
- for (i = 0, ii = flatCoordinates.length / 4; i < ii; i++) {
- flatCoordinates[i * stride] = flatCoordinates[i * 4];
- flatCoordinates[i * stride + 1] = flatCoordinates[i * 4 + 1];
- if (layoutOptions.hasZ) {
- flatCoordinates[i * stride + 2] = flatCoordinates[i * 4 + 2];
- }
- if (layoutOptions.hasM) {
- flatCoordinates[i * stride + 2] = flatCoordinates[i * 4 + 3];
- }
- }
- flatCoordinates.length = flatCoordinates.length / 4 * stride;
- if (ends) {
- for (i = 0, ii = ends.length; i < ii; i++) {
- ends[i] = ends[i] / 4 * stride;
- }
- }
- }
- return layout;
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GPX.parseLink_ = function(node, objectStack) {
- var values = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- var href = node.getAttribute('href');
- if (href !== null) {
- values['link'] = href;
- }
- ol.xml.parseNode(ol.format.GPX.LINK_PARSERS_, node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GPX.parseExtensions_ = function(node, objectStack) {
- var values = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- values['extensionsNode_'] = node;
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GPX.parseRtePt_ = function(node, objectStack) {
- var values = ol.xml.pushParseAndPop(
- {}, ol.format.GPX.RTEPT_PARSERS_, node, objectStack);
- if (values) {
- var rteValues = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- var flatCoordinates = /** @type {Array.<number>} */
- (rteValues['flatCoordinates']);
- var layoutOptions = /** @type {ol.LayoutOptions} */
- (rteValues['layoutOptions']);
- ol.format.GPX.appendCoordinate_(flatCoordinates, layoutOptions, node, values);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GPX.parseTrkPt_ = function(node, objectStack) {
- var values = ol.xml.pushParseAndPop(
- {}, ol.format.GPX.TRKPT_PARSERS_, node, objectStack);
- if (values) {
- var trkValues = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- var flatCoordinates = /** @type {Array.<number>} */
- (trkValues['flatCoordinates']);
- var layoutOptions = /** @type {ol.LayoutOptions} */
- (trkValues['layoutOptions']);
- ol.format.GPX.appendCoordinate_(flatCoordinates, layoutOptions, node, values);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GPX.parseTrkSeg_ = function(node, objectStack) {
- var values = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- ol.xml.parseNode(ol.format.GPX.TRKSEG_PARSERS_, node, objectStack);
- var flatCoordinates = /** @type {Array.<number>} */
- (values['flatCoordinates']);
- var ends = /** @type {Array.<number>} */ (values['ends']);
- ends.push(flatCoordinates.length);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {ol.Feature|undefined} Track.
- */
- ol.format.GPX.readRte_ = function(node, objectStack) {
- var options = /** @type {olx.format.ReadOptions} */ (objectStack[0]);
- var values = ol.xml.pushParseAndPop({
- 'flatCoordinates': [],
- 'layoutOptions': {}
- }, ol.format.GPX.RTE_PARSERS_, node, objectStack);
- if (!values) {
- return undefined;
- }
- var flatCoordinates = /** @type {Array.<number>} */
- (values['flatCoordinates']);
- delete values['flatCoordinates'];
- var layoutOptions = /** @type {ol.LayoutOptions} */ (values['layoutOptions']);
- delete values['layoutOptions'];
- var layout = ol.format.GPX.applyLayoutOptions_(layoutOptions, flatCoordinates);
- var geometry = new ol.geom.LineString(null);
- geometry.setFlatCoordinates(layout, flatCoordinates);
- ol.format.Feature.transformWithOptions(geometry, false, options);
- var feature = new ol.Feature(geometry);
- feature.setProperties(values);
- return feature;
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {ol.Feature|undefined} Track.
- */
- ol.format.GPX.readTrk_ = function(node, objectStack) {
- var options = /** @type {olx.format.ReadOptions} */ (objectStack[0]);
- var values = ol.xml.pushParseAndPop({
- 'flatCoordinates': [],
- 'ends': [],
- 'layoutOptions': {}
- }, ol.format.GPX.TRK_PARSERS_, node, objectStack);
- if (!values) {
- return undefined;
- }
- var flatCoordinates = /** @type {Array.<number>} */
- (values['flatCoordinates']);
- delete values['flatCoordinates'];
- var ends = /** @type {Array.<number>} */ (values['ends']);
- delete values['ends'];
- var layoutOptions = /** @type {ol.LayoutOptions} */ (values['layoutOptions']);
- delete values['layoutOptions'];
- var layout = ol.format.GPX.applyLayoutOptions_(layoutOptions, flatCoordinates, ends);
- var geometry = new ol.geom.MultiLineString(null);
- geometry.setFlatCoordinates(layout, flatCoordinates, ends);
- ol.format.Feature.transformWithOptions(geometry, false, options);
- var feature = new ol.Feature(geometry);
- feature.setProperties(values);
- return feature;
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {ol.Feature|undefined} Waypoint.
- */
- ol.format.GPX.readWpt_ = function(node, objectStack) {
- var options = /** @type {olx.format.ReadOptions} */ (objectStack[0]);
- var values = ol.xml.pushParseAndPop(
- {}, ol.format.GPX.WPT_PARSERS_, node, objectStack);
- if (!values) {
- return undefined;
- }
- var layoutOptions = /** @type {ol.LayoutOptions} */ ({});
- var coordinates = ol.format.GPX.appendCoordinate_([], layoutOptions, node, values);
- var layout = ol.format.GPX.applyLayoutOptions_(layoutOptions, coordinates);
- var geometry = new ol.geom.Point(coordinates, layout);
- ol.format.Feature.transformWithOptions(geometry, false, options);
- var feature = new ol.Feature(geometry);
- feature.setProperties(values);
- return feature;
- };
- /**
- * @const
- * @type {Object.<string, function(Node, Array.<*>): (ol.Feature|undefined)>}
- * @private
- */
- ol.format.GPX.FEATURE_READER_ = {
- 'rte': ol.format.GPX.readRte_,
- 'trk': ol.format.GPX.readTrk_,
- 'wpt': ol.format.GPX.readWpt_
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GPX.GPX_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.GPX.NAMESPACE_URIS_, {
- 'rte': ol.xml.makeArrayPusher(ol.format.GPX.readRte_),
- 'trk': ol.xml.makeArrayPusher(ol.format.GPX.readTrk_),
- 'wpt': ol.xml.makeArrayPusher(ol.format.GPX.readWpt_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GPX.LINK_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.GPX.NAMESPACE_URIS_, {
- 'text':
- ol.xml.makeObjectPropertySetter(ol.format.XSD.readString, 'linkText'),
- 'type':
- ol.xml.makeObjectPropertySetter(ol.format.XSD.readString, 'linkType')
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GPX.RTE_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.GPX.NAMESPACE_URIS_, {
- 'name': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'cmt': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'desc': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'src': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'link': ol.format.GPX.parseLink_,
- 'number':
- ol.xml.makeObjectPropertySetter(ol.format.XSD.readNonNegativeInteger),
- 'extensions': ol.format.GPX.parseExtensions_,
- 'type': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'rtept': ol.format.GPX.parseRtePt_
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GPX.RTEPT_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.GPX.NAMESPACE_URIS_, {
- 'ele': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'time': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDateTime)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GPX.TRK_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.GPX.NAMESPACE_URIS_, {
- 'name': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'cmt': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'desc': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'src': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'link': ol.format.GPX.parseLink_,
- 'number':
- ol.xml.makeObjectPropertySetter(ol.format.XSD.readNonNegativeInteger),
- 'type': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'extensions': ol.format.GPX.parseExtensions_,
- 'trkseg': ol.format.GPX.parseTrkSeg_
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GPX.TRKSEG_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.GPX.NAMESPACE_URIS_, {
- 'trkpt': ol.format.GPX.parseTrkPt_
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GPX.TRKPT_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.GPX.NAMESPACE_URIS_, {
- 'ele': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'time': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDateTime)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.GPX.WPT_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.GPX.NAMESPACE_URIS_, {
- 'ele': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'time': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDateTime),
- 'magvar': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'geoidheight': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'name': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'cmt': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'desc': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'src': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'link': ol.format.GPX.parseLink_,
- 'sym': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'type': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'fix': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'sat': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readNonNegativeInteger),
- 'hdop': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'vdop': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'pdop': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'ageofdgpsdata':
- ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'dgpsid':
- ol.xml.makeObjectPropertySetter(ol.format.XSD.readNonNegativeInteger),
- 'extensions': ol.format.GPX.parseExtensions_
- });
- /**
- * @param {Array.<ol.Feature>} features List of features.
- * @private
- */
- ol.format.GPX.prototype.handleReadExtensions_ = function(features) {
- if (!features) {
- features = [];
- }
- for (var i = 0, ii = features.length; i < ii; ++i) {
- var feature = features[i];
- if (this.readExtensions_) {
- var extensionsNode = feature.get('extensionsNode_') || null;
- this.readExtensions_(feature, extensionsNode);
- }
- feature.set('extensionsNode_', undefined);
- }
- };
- /**
- * Read the first feature from a GPX source.
- * Routes (`<rte>`) are converted into LineString geometries, and tracks (`<trk>`)
- * into MultiLineString. Any properties on route and track waypoints are ignored.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {ol.Feature} Feature.
- * @api
- */
- ol.format.GPX.prototype.readFeature;
- /**
- * @inheritDoc
- */
- ol.format.GPX.prototype.readFeatureFromNode = function(node, opt_options) {
- if (!ol.array.includes(ol.format.GPX.NAMESPACE_URIS_, node.namespaceURI)) {
- return null;
- }
- var featureReader = ol.format.GPX.FEATURE_READER_[node.localName];
- if (!featureReader) {
- return null;
- }
- var feature = featureReader(node, [this.getReadOptions(node, opt_options)]);
- if (!feature) {
- return null;
- }
- this.handleReadExtensions_([feature]);
- return feature;
- };
- /**
- * Read all features from a GPX source.
- * Routes (`<rte>`) are converted into LineString geometries, and tracks (`<trk>`)
- * into MultiLineString. Any properties on route and track waypoints are ignored.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {Array.<ol.Feature>} Features.
- * @api
- */
- ol.format.GPX.prototype.readFeatures;
- /**
- * @inheritDoc
- */
- ol.format.GPX.prototype.readFeaturesFromNode = function(node, opt_options) {
- if (!ol.array.includes(ol.format.GPX.NAMESPACE_URIS_, node.namespaceURI)) {
- return [];
- }
- if (node.localName == 'gpx') {
- /** @type {Array.<ol.Feature>} */
- var features = ol.xml.pushParseAndPop([], ol.format.GPX.GPX_PARSERS_,
- node, [this.getReadOptions(node, opt_options)]);
- if (features) {
- this.handleReadExtensions_(features);
- return features;
- } else {
- return [];
- }
- }
- return [];
- };
- /**
- * Read the projection from a GPX source.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @return {ol.proj.Projection} Projection.
- * @api
- */
- ol.format.GPX.prototype.readProjection;
- /**
- * @param {Node} node Node.
- * @param {string} value Value for the link's `href` attribute.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.GPX.writeLink_ = function(node, value, objectStack) {
- node.setAttribute('href', value);
- var context = objectStack[objectStack.length - 1];
- var properties = context['properties'];
- var link = [
- properties['linkText'],
- properties['linkType']
- ];
- ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */ ({node: node}),
- ol.format.GPX.LINK_SERIALIZERS_, ol.xml.OBJECT_PROPERTY_NODE_FACTORY,
- link, objectStack, ol.format.GPX.LINK_SEQUENCE_);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GPX.writeWptType_ = function(node, coordinate, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var parentNode = context.node;
- var namespaceURI = parentNode.namespaceURI;
- var properties = context['properties'];
- //FIXME Projection handling
- ol.xml.setAttributeNS(node, null, 'lat', coordinate[1]);
- ol.xml.setAttributeNS(node, null, 'lon', coordinate[0]);
- var geometryLayout = context['geometryLayout'];
- switch (geometryLayout) {
- case ol.geom.GeometryLayout.XYZM:
- if (coordinate[3] !== 0) {
- properties['time'] = coordinate[3];
- }
- // fall through
- case ol.geom.GeometryLayout.XYZ:
- if (coordinate[2] !== 0) {
- properties['ele'] = coordinate[2];
- }
- break;
- case ol.geom.GeometryLayout.XYM:
- if (coordinate[2] !== 0) {
- properties['time'] = coordinate[2];
- }
- break;
- default:
- // pass
- }
- var orderedKeys = (node.nodeName == 'rtept') ?
- ol.format.GPX.RTEPT_TYPE_SEQUENCE_[namespaceURI] :
- ol.format.GPX.WPT_TYPE_SEQUENCE_[namespaceURI];
- var values = ol.xml.makeSequence(properties, orderedKeys);
- ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */
- ({node: node, 'properties': properties}),
- ol.format.GPX.WPT_TYPE_SERIALIZERS_, ol.xml.OBJECT_PROPERTY_NODE_FACTORY,
- values, objectStack, orderedKeys);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.Feature} feature Feature.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GPX.writeRte_ = function(node, feature, objectStack) {
- var options = /** @type {olx.format.WriteOptions} */ (objectStack[0]);
- var properties = feature.getProperties();
- var context = {node: node, 'properties': properties};
- var geometry = feature.getGeometry();
- if (geometry) {
- geometry = /** @type {ol.geom.LineString} */
- (ol.format.Feature.transformWithOptions(geometry, true, options));
- context['geometryLayout'] = geometry.getLayout();
- properties['rtept'] = geometry.getCoordinates();
- }
- var parentNode = objectStack[objectStack.length - 1].node;
- var orderedKeys = ol.format.GPX.RTE_SEQUENCE_[parentNode.namespaceURI];
- var values = ol.xml.makeSequence(properties, orderedKeys);
- ol.xml.pushSerializeAndPop(context,
- ol.format.GPX.RTE_SERIALIZERS_, ol.xml.OBJECT_PROPERTY_NODE_FACTORY,
- values, objectStack, orderedKeys);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.Feature} feature Feature.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GPX.writeTrk_ = function(node, feature, objectStack) {
- var options = /** @type {olx.format.WriteOptions} */ (objectStack[0]);
- var properties = feature.getProperties();
- /** @type {ol.XmlNodeStackItem} */
- var context = {node: node, 'properties': properties};
- var geometry = feature.getGeometry();
- if (geometry) {
- geometry = /** @type {ol.geom.MultiLineString} */
- (ol.format.Feature.transformWithOptions(geometry, true, options));
- properties['trkseg'] = geometry.getLineStrings();
- }
- var parentNode = objectStack[objectStack.length - 1].node;
- var orderedKeys = ol.format.GPX.TRK_SEQUENCE_[parentNode.namespaceURI];
- var values = ol.xml.makeSequence(properties, orderedKeys);
- ol.xml.pushSerializeAndPop(context,
- ol.format.GPX.TRK_SERIALIZERS_, ol.xml.OBJECT_PROPERTY_NODE_FACTORY,
- values, objectStack, orderedKeys);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.LineString} lineString LineString.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GPX.writeTrkSeg_ = function(node, lineString, objectStack) {
- /** @type {ol.XmlNodeStackItem} */
- var context = {node: node, 'geometryLayout': lineString.getLayout(),
- 'properties': {}};
- ol.xml.pushSerializeAndPop(context,
- ol.format.GPX.TRKSEG_SERIALIZERS_, ol.format.GPX.TRKSEG_NODE_FACTORY_,
- lineString.getCoordinates(), objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.Feature} feature Feature.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.GPX.writeWpt_ = function(node, feature, objectStack) {
- var options = /** @type {olx.format.WriteOptions} */ (objectStack[0]);
- var context = objectStack[objectStack.length - 1];
- context['properties'] = feature.getProperties();
- var geometry = feature.getGeometry();
- if (geometry) {
- geometry = /** @type {ol.geom.Point} */
- (ol.format.Feature.transformWithOptions(geometry, true, options));
- context['geometryLayout'] = geometry.getLayout();
- ol.format.GPX.writeWptType_(node, geometry.getCoordinates(), objectStack);
- }
- };
- /**
- * @const
- * @type {Array.<string>}
- * @private
- */
- ol.format.GPX.LINK_SEQUENCE_ = ['text', 'type'];
- /**
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.GPX.LINK_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.GPX.NAMESPACE_URIS_, {
- 'text': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'type': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode)
- });
- /**
- * @const
- * @type {Object.<string, Array.<string>>}
- * @private
- */
- ol.format.GPX.RTE_SEQUENCE_ = ol.xml.makeStructureNS(
- ol.format.GPX.NAMESPACE_URIS_, [
- 'name', 'cmt', 'desc', 'src', 'link', 'number', 'type', 'rtept'
- ]);
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.GPX.RTE_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.GPX.NAMESPACE_URIS_, {
- 'name': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'cmt': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'desc': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'src': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'link': ol.xml.makeChildAppender(ol.format.GPX.writeLink_),
- 'number': ol.xml.makeChildAppender(
- ol.format.XSD.writeNonNegativeIntegerTextNode),
- 'type': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'rtept': ol.xml.makeArraySerializer(ol.xml.makeChildAppender(
- ol.format.GPX.writeWptType_))
- });
- /**
- * @const
- * @type {Object.<string, Array.<string>>}
- * @private
- */
- ol.format.GPX.RTEPT_TYPE_SEQUENCE_ = ol.xml.makeStructureNS(
- ol.format.GPX.NAMESPACE_URIS_, [
- 'ele', 'time'
- ]);
- /**
- * @const
- * @type {Object.<string, Array.<string>>}
- * @private
- */
- ol.format.GPX.TRK_SEQUENCE_ = ol.xml.makeStructureNS(
- ol.format.GPX.NAMESPACE_URIS_, [
- 'name', 'cmt', 'desc', 'src', 'link', 'number', 'type', 'trkseg'
- ]);
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.GPX.TRK_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.GPX.NAMESPACE_URIS_, {
- 'name': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'cmt': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'desc': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'src': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'link': ol.xml.makeChildAppender(ol.format.GPX.writeLink_),
- 'number': ol.xml.makeChildAppender(
- ol.format.XSD.writeNonNegativeIntegerTextNode),
- 'type': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'trkseg': ol.xml.makeArraySerializer(ol.xml.makeChildAppender(
- ol.format.GPX.writeTrkSeg_))
- });
- /**
- * @const
- * @type {function(*, Array.<*>, string=): (Node|undefined)}
- * @private
- */
- ol.format.GPX.TRKSEG_NODE_FACTORY_ = ol.xml.makeSimpleNodeFactory('trkpt');
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.GPX.TRKSEG_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.GPX.NAMESPACE_URIS_, {
- 'trkpt': ol.xml.makeChildAppender(ol.format.GPX.writeWptType_)
- });
- /**
- * @const
- * @type {Object.<string, Array.<string>>}
- * @private
- */
- ol.format.GPX.WPT_TYPE_SEQUENCE_ = ol.xml.makeStructureNS(
- ol.format.GPX.NAMESPACE_URIS_, [
- 'ele', 'time', 'magvar', 'geoidheight', 'name', 'cmt', 'desc', 'src',
- 'link', 'sym', 'type', 'fix', 'sat', 'hdop', 'vdop', 'pdop',
- 'ageofdgpsdata', 'dgpsid'
- ]);
- /**
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.GPX.WPT_TYPE_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.GPX.NAMESPACE_URIS_, {
- 'ele': ol.xml.makeChildAppender(ol.format.XSD.writeDecimalTextNode),
- 'time': ol.xml.makeChildAppender(ol.format.XSD.writeDateTimeTextNode),
- 'magvar': ol.xml.makeChildAppender(ol.format.XSD.writeDecimalTextNode),
- 'geoidheight': ol.xml.makeChildAppender(
- ol.format.XSD.writeDecimalTextNode),
- 'name': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'cmt': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'desc': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'src': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'link': ol.xml.makeChildAppender(ol.format.GPX.writeLink_),
- 'sym': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'type': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'fix': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'sat': ol.xml.makeChildAppender(
- ol.format.XSD.writeNonNegativeIntegerTextNode),
- 'hdop': ol.xml.makeChildAppender(ol.format.XSD.writeDecimalTextNode),
- 'vdop': ol.xml.makeChildAppender(ol.format.XSD.writeDecimalTextNode),
- 'pdop': ol.xml.makeChildAppender(ol.format.XSD.writeDecimalTextNode),
- 'ageofdgpsdata': ol.xml.makeChildAppender(
- ol.format.XSD.writeDecimalTextNode),
- 'dgpsid': ol.xml.makeChildAppender(
- ol.format.XSD.writeNonNegativeIntegerTextNode)
- });
- /**
- * @const
- * @type {Object.<string, string>}
- * @private
- */
- ol.format.GPX.GEOMETRY_TYPE_TO_NODENAME_ = {
- 'Point': 'wpt',
- 'LineString': 'rte',
- 'MultiLineString': 'trk'
- };
- /**
- * @const
- * @param {*} value Value.
- * @param {Array.<*>} objectStack Object stack.
- * @param {string=} opt_nodeName Node name.
- * @return {Node|undefined} Node.
- * @private
- */
- ol.format.GPX.GPX_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) {
- var geometry = /** @type {ol.Feature} */ (value).getGeometry();
- if (geometry) {
- var nodeName = ol.format.GPX.GEOMETRY_TYPE_TO_NODENAME_[geometry.getType()];
- if (nodeName) {
- var parentNode = objectStack[objectStack.length - 1].node;
- return ol.xml.createElementNS(parentNode.namespaceURI, nodeName);
- }
- }
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.GPX.GPX_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.GPX.NAMESPACE_URIS_, {
- 'rte': ol.xml.makeChildAppender(ol.format.GPX.writeRte_),
- 'trk': ol.xml.makeChildAppender(ol.format.GPX.writeTrk_),
- 'wpt': ol.xml.makeChildAppender(ol.format.GPX.writeWpt_)
- });
- /**
- * Encode an array of features in the GPX format.
- * LineString geometries are output as routes (`<rte>`), and MultiLineString
- * as tracks (`<trk>`).
- *
- * @function
- * @param {Array.<ol.Feature>} features Features.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {string} Result.
- * @api
- */
- ol.format.GPX.prototype.writeFeatures;
- /**
- * Encode an array of features in the GPX format as an XML node.
- * LineString geometries are output as routes (`<rte>`), and MultiLineString
- * as tracks (`<trk>`).
- *
- * @param {Array.<ol.Feature>} features Features.
- * @param {olx.format.WriteOptions=} opt_options Options.
- * @return {Node} Node.
- * @override
- * @api
- */
- ol.format.GPX.prototype.writeFeaturesNode = function(features, opt_options) {
- opt_options = this.adaptOptions(opt_options);
- //FIXME Serialize metadata
- var gpx = ol.xml.createElementNS('http://www.topografix.com/GPX/1/1', 'gpx');
- var xmlnsUri = 'http://www.w3.org/2000/xmlns/';
- var xmlSchemaInstanceUri = 'http://www.w3.org/2001/XMLSchema-instance';
- ol.xml.setAttributeNS(gpx, xmlnsUri, 'xmlns:xsi', xmlSchemaInstanceUri);
- ol.xml.setAttributeNS(gpx, xmlSchemaInstanceUri, 'xsi:schemaLocation',
- ol.format.GPX.SCHEMA_LOCATION_);
- gpx.setAttribute('version', '1.1');
- gpx.setAttribute('creator', 'OpenLayers');
- ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */
- ({node: gpx}), ol.format.GPX.GPX_SERIALIZERS_,
- ol.format.GPX.GPX_NODE_FACTORY_, features, [opt_options]);
- return gpx;
- };
- goog.provide('ol.format.IGCZ');
- /**
- * IGC altitude/z. One of 'barometric', 'gps', 'none'.
- * @enum {string}
- */
- ol.format.IGCZ = {
- BAROMETRIC: 'barometric',
- GPS: 'gps',
- NONE: 'none'
- };
- goog.provide('ol.format.TextFeature');
- goog.require('ol');
- goog.require('ol.format.Feature');
- goog.require('ol.format.FormatType');
- /**
- * @classdesc
- * Abstract base class; normally only used for creating subclasses and not
- * instantiated in apps.
- * Base class for text feature formats.
- *
- * @constructor
- * @abstract
- * @extends {ol.format.Feature}
- */
- ol.format.TextFeature = function() {
- ol.format.Feature.call(this);
- };
- ol.inherits(ol.format.TextFeature, ol.format.Feature);
- /**
- * @param {Document|Node|Object|string} source Source.
- * @private
- * @return {string} Text.
- */
- ol.format.TextFeature.prototype.getText_ = function(source) {
- if (typeof source === 'string') {
- return source;
- } else {
- return '';
- }
- };
- /**
- * @inheritDoc
- */
- ol.format.TextFeature.prototype.getType = function() {
- return ol.format.FormatType.TEXT;
- };
- /**
- * @inheritDoc
- */
- ol.format.TextFeature.prototype.readFeature = function(source, opt_options) {
- return this.readFeatureFromText(
- this.getText_(source), this.adaptOptions(opt_options));
- };
- /**
- * @abstract
- * @param {string} text Text.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @protected
- * @return {ol.Feature} Feature.
- */
- ol.format.TextFeature.prototype.readFeatureFromText = function(text, opt_options) {};
- /**
- * @inheritDoc
- */
- ol.format.TextFeature.prototype.readFeatures = function(source, opt_options) {
- return this.readFeaturesFromText(
- this.getText_(source), this.adaptOptions(opt_options));
- };
- /**
- * @abstract
- * @param {string} text Text.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @protected
- * @return {Array.<ol.Feature>} Features.
- */
- ol.format.TextFeature.prototype.readFeaturesFromText = function(text, opt_options) {};
- /**
- * @inheritDoc
- */
- ol.format.TextFeature.prototype.readGeometry = function(source, opt_options) {
- return this.readGeometryFromText(
- this.getText_(source), this.adaptOptions(opt_options));
- };
- /**
- * @abstract
- * @param {string} text Text.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @protected
- * @return {ol.geom.Geometry} Geometry.
- */
- ol.format.TextFeature.prototype.readGeometryFromText = function(text, opt_options) {};
- /**
- * @inheritDoc
- */
- ol.format.TextFeature.prototype.readProjection = function(source) {
- return this.readProjectionFromText(this.getText_(source));
- };
- /**
- * @param {string} text Text.
- * @protected
- * @return {ol.proj.Projection} Projection.
- */
- ol.format.TextFeature.prototype.readProjectionFromText = function(text) {
- return this.defaultDataProjection;
- };
- /**
- * @inheritDoc
- */
- ol.format.TextFeature.prototype.writeFeature = function(feature, opt_options) {
- return this.writeFeatureText(feature, this.adaptOptions(opt_options));
- };
- /**
- * @abstract
- * @param {ol.Feature} feature Features.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @protected
- * @return {string} Text.
- */
- ol.format.TextFeature.prototype.writeFeatureText = function(feature, opt_options) {};
- /**
- * @inheritDoc
- */
- ol.format.TextFeature.prototype.writeFeatures = function(
- features, opt_options) {
- return this.writeFeaturesText(features, this.adaptOptions(opt_options));
- };
- /**
- * @abstract
- * @param {Array.<ol.Feature>} features Features.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @protected
- * @return {string} Text.
- */
- ol.format.TextFeature.prototype.writeFeaturesText = function(features, opt_options) {};
- /**
- * @inheritDoc
- */
- ol.format.TextFeature.prototype.writeGeometry = function(
- geometry, opt_options) {
- return this.writeGeometryText(geometry, this.adaptOptions(opt_options));
- };
- /**
- * @abstract
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @protected
- * @return {string} Text.
- */
- ol.format.TextFeature.prototype.writeGeometryText = function(geometry, opt_options) {};
- goog.provide('ol.format.IGC');
- goog.require('ol');
- goog.require('ol.Feature');
- goog.require('ol.format.Feature');
- goog.require('ol.format.IGCZ');
- goog.require('ol.format.TextFeature');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.LineString');
- goog.require('ol.proj');
- /**
- * @classdesc
- * Feature format for `*.igc` flight recording files.
- *
- * @constructor
- * @extends {ol.format.TextFeature}
- * @param {olx.format.IGCOptions=} opt_options Options.
- * @api
- */
- ol.format.IGC = function(opt_options) {
- var options = opt_options ? opt_options : {};
- ol.format.TextFeature.call(this);
- /**
- * @inheritDoc
- */
- this.defaultDataProjection = ol.proj.get('EPSG:4326');
- /**
- * @private
- * @type {ol.format.IGCZ}
- */
- this.altitudeMode_ = options.altitudeMode ?
- options.altitudeMode : ol.format.IGCZ.NONE;
- };
- ol.inherits(ol.format.IGC, ol.format.TextFeature);
- /**
- * @const
- * @type {RegExp}
- * @private
- */
- ol.format.IGC.B_RECORD_RE_ =
- /^B(\d{2})(\d{2})(\d{2})(\d{2})(\d{5})([NS])(\d{3})(\d{5})([EW])([AV])(\d{5})(\d{5})/;
- /**
- * @const
- * @type {RegExp}
- * @private
- */
- ol.format.IGC.H_RECORD_RE_ = /^H.([A-Z]{3}).*?:(.*)/;
- /**
- * @const
- * @type {RegExp}
- * @private
- */
- ol.format.IGC.HFDTE_RECORD_RE_ = /^HFDTE(\d{2})(\d{2})(\d{2})/;
- /**
- * A regular expression matching the newline characters `\r\n`, `\r` and `\n`.
- *
- * @const
- * @type {RegExp}
- * @private
- */
- ol.format.IGC.NEWLINE_RE_ = /\r\n|\r|\n/;
- /**
- * Read the feature from the IGC source.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {ol.Feature} Feature.
- * @api
- */
- ol.format.IGC.prototype.readFeature;
- /**
- * @inheritDoc
- */
- ol.format.IGC.prototype.readFeatureFromText = function(text, opt_options) {
- var altitudeMode = this.altitudeMode_;
- var lines = text.split(ol.format.IGC.NEWLINE_RE_);
- /** @type {Object.<string, string>} */
- var properties = {};
- var flatCoordinates = [];
- var year = 2000;
- var month = 0;
- var day = 1;
- var lastDateTime = -1;
- var i, ii;
- for (i = 0, ii = lines.length; i < ii; ++i) {
- var line = lines[i];
- var m;
- if (line.charAt(0) == 'B') {
- m = ol.format.IGC.B_RECORD_RE_.exec(line);
- if (m) {
- var hour = parseInt(m[1], 10);
- var minute = parseInt(m[2], 10);
- var second = parseInt(m[3], 10);
- var y = parseInt(m[4], 10) + parseInt(m[5], 10) / 60000;
- if (m[6] == 'S') {
- y = -y;
- }
- var x = parseInt(m[7], 10) + parseInt(m[8], 10) / 60000;
- if (m[9] == 'W') {
- x = -x;
- }
- flatCoordinates.push(x, y);
- if (altitudeMode != ol.format.IGCZ.NONE) {
- var z;
- if (altitudeMode == ol.format.IGCZ.GPS) {
- z = parseInt(m[11], 10);
- } else if (altitudeMode == ol.format.IGCZ.BAROMETRIC) {
- z = parseInt(m[12], 10);
- } else {
- z = 0;
- }
- flatCoordinates.push(z);
- }
- var dateTime = Date.UTC(year, month, day, hour, minute, second);
- // Detect UTC midnight wrap around.
- if (dateTime < lastDateTime) {
- dateTime = Date.UTC(year, month, day + 1, hour, minute, second);
- }
- flatCoordinates.push(dateTime / 1000);
- lastDateTime = dateTime;
- }
- } else if (line.charAt(0) == 'H') {
- m = ol.format.IGC.HFDTE_RECORD_RE_.exec(line);
- if (m) {
- day = parseInt(m[1], 10);
- month = parseInt(m[2], 10) - 1;
- year = 2000 + parseInt(m[3], 10);
- } else {
- m = ol.format.IGC.H_RECORD_RE_.exec(line);
- if (m) {
- properties[m[1]] = m[2].trim();
- }
- }
- }
- }
- if (flatCoordinates.length === 0) {
- return null;
- }
- var lineString = new ol.geom.LineString(null);
- var layout = altitudeMode == ol.format.IGCZ.NONE ?
- ol.geom.GeometryLayout.XYM : ol.geom.GeometryLayout.XYZM;
- lineString.setFlatCoordinates(layout, flatCoordinates);
- var feature = new ol.Feature(ol.format.Feature.transformWithOptions(
- lineString, false, opt_options));
- feature.setProperties(properties);
- return feature;
- };
- /**
- * Read the feature from the source. As IGC sources contain a single
- * feature, this will return the feature in an array.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {Array.<ol.Feature>} Features.
- * @api
- */
- ol.format.IGC.prototype.readFeatures;
- /**
- * @inheritDoc
- */
- ol.format.IGC.prototype.readFeaturesFromText = function(text, opt_options) {
- var feature = this.readFeatureFromText(text, opt_options);
- if (feature) {
- return [feature];
- } else {
- return [];
- }
- };
- /**
- * Read the projection from the IGC source.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @return {ol.proj.Projection} Projection.
- * @api
- */
- ol.format.IGC.prototype.readProjection;
- /**
- * Not implemented.
- * @inheritDoc
- */
- ol.format.IGC.prototype.writeFeatureText = function(feature, opt_options) {};
- /**
- * Not implemented.
- * @inheritDoc
- */
- ol.format.IGC.prototype.writeFeaturesText = function(features, opt_options) {};
- /**
- * Not implemented.
- * @inheritDoc
- */
- ol.format.IGC.prototype.writeGeometryText = function(geometry, opt_options) {};
- /**
- * Not implemented.
- * @inheritDoc
- */
- ol.format.IGC.prototype.readGeometryFromText = function(text, opt_options) {};
- goog.provide('ol.style.IconAnchorUnits');
- /**
- * Icon anchor units. One of 'fraction', 'pixels'.
- * @enum {string}
- */
- ol.style.IconAnchorUnits = {
- FRACTION: 'fraction',
- PIXELS: 'pixels'
- };
- goog.provide('ol.style.IconImage');
- goog.require('ol');
- goog.require('ol.dom');
- goog.require('ol.events');
- goog.require('ol.events.EventTarget');
- goog.require('ol.events.EventType');
- goog.require('ol.ImageState');
- goog.require('ol.style');
- /**
- * @constructor
- * @param {Image|HTMLCanvasElement} image Image.
- * @param {string|undefined} src Src.
- * @param {ol.Size} size Size.
- * @param {?string} crossOrigin Cross origin.
- * @param {ol.ImageState} imageState Image state.
- * @param {ol.Color} color Color.
- * @extends {ol.events.EventTarget}
- */
- ol.style.IconImage = function(image, src, size, crossOrigin, imageState,
- color) {
- ol.events.EventTarget.call(this);
- /**
- * @private
- * @type {Image|HTMLCanvasElement}
- */
- this.hitDetectionImage_ = null;
- /**
- * @private
- * @type {Image|HTMLCanvasElement}
- */
- this.image_ = !image ? new Image() : image;
- if (crossOrigin !== null) {
- this.image_.crossOrigin = crossOrigin;
- }
- /**
- * @private
- * @type {HTMLCanvasElement}
- */
- this.canvas_ = color ?
- /** @type {HTMLCanvasElement} */ (document.createElement('CANVAS')) :
- null;
- /**
- * @private
- * @type {ol.Color}
- */
- this.color_ = color;
- /**
- * @private
- * @type {Array.<ol.EventsKey>}
- */
- this.imageListenerKeys_ = null;
- /**
- * @private
- * @type {ol.ImageState}
- */
- this.imageState_ = imageState;
- /**
- * @private
- * @type {ol.Size}
- */
- this.size_ = size;
- /**
- * @private
- * @type {string|undefined}
- */
- this.src_ = src;
- /**
- * @private
- * @type {boolean}
- */
- this.tainting_ = false;
- if (this.imageState_ == ol.ImageState.LOADED) {
- this.determineTainting_();
- }
- };
- ol.inherits(ol.style.IconImage, ol.events.EventTarget);
- /**
- * @param {Image|HTMLCanvasElement} image Image.
- * @param {string} src Src.
- * @param {ol.Size} size Size.
- * @param {?string} crossOrigin Cross origin.
- * @param {ol.ImageState} imageState Image state.
- * @param {ol.Color} color Color.
- * @return {ol.style.IconImage} Icon image.
- */
- ol.style.IconImage.get = function(image, src, size, crossOrigin, imageState,
- color) {
- var iconImageCache = ol.style.iconImageCache;
- var iconImage = iconImageCache.get(src, crossOrigin, color);
- if (!iconImage) {
- iconImage = new ol.style.IconImage(
- image, src, size, crossOrigin, imageState, color);
- iconImageCache.set(src, crossOrigin, color, iconImage);
- }
- return iconImage;
- };
- /**
- * @private
- */
- ol.style.IconImage.prototype.determineTainting_ = function() {
- var context = ol.dom.createCanvasContext2D(1, 1);
- try {
- context.drawImage(this.image_, 0, 0);
- context.getImageData(0, 0, 1, 1);
- } catch (e) {
- this.tainting_ = true;
- }
- };
- /**
- * @private
- */
- ol.style.IconImage.prototype.dispatchChangeEvent_ = function() {
- this.dispatchEvent(ol.events.EventType.CHANGE);
- };
- /**
- * @private
- */
- ol.style.IconImage.prototype.handleImageError_ = function() {
- this.imageState_ = ol.ImageState.ERROR;
- this.unlistenImage_();
- this.dispatchChangeEvent_();
- };
- /**
- * @private
- */
- ol.style.IconImage.prototype.handleImageLoad_ = function() {
- this.imageState_ = ol.ImageState.LOADED;
- if (this.size_) {
- this.image_.width = this.size_[0];
- this.image_.height = this.size_[1];
- }
- this.size_ = [this.image_.width, this.image_.height];
- this.unlistenImage_();
- this.determineTainting_();
- this.replaceColor_();
- this.dispatchChangeEvent_();
- };
- /**
- * @param {number} pixelRatio Pixel ratio.
- * @return {Image|HTMLCanvasElement} Image or Canvas element.
- */
- ol.style.IconImage.prototype.getImage = function(pixelRatio) {
- return this.canvas_ ? this.canvas_ : this.image_;
- };
- /**
- * @return {ol.ImageState} Image state.
- */
- ol.style.IconImage.prototype.getImageState = function() {
- return this.imageState_;
- };
- /**
- * @param {number} pixelRatio Pixel ratio.
- * @return {Image|HTMLCanvasElement} Image element.
- */
- ol.style.IconImage.prototype.getHitDetectionImage = function(pixelRatio) {
- if (!this.hitDetectionImage_) {
- if (this.tainting_) {
- var width = this.size_[0];
- var height = this.size_[1];
- var context = ol.dom.createCanvasContext2D(width, height);
- context.fillRect(0, 0, width, height);
- this.hitDetectionImage_ = context.canvas;
- } else {
- this.hitDetectionImage_ = this.image_;
- }
- }
- return this.hitDetectionImage_;
- };
- /**
- * @return {ol.Size} Image size.
- */
- ol.style.IconImage.prototype.getSize = function() {
- return this.size_;
- };
- /**
- * @return {string|undefined} Image src.
- */
- ol.style.IconImage.prototype.getSrc = function() {
- return this.src_;
- };
- /**
- * Load not yet loaded URI.
- */
- ol.style.IconImage.prototype.load = function() {
- if (this.imageState_ == ol.ImageState.IDLE) {
- this.imageState_ = ol.ImageState.LOADING;
- this.imageListenerKeys_ = [
- ol.events.listenOnce(this.image_, ol.events.EventType.ERROR,
- this.handleImageError_, this),
- ol.events.listenOnce(this.image_, ol.events.EventType.LOAD,
- this.handleImageLoad_, this)
- ];
- try {
- this.image_.src = this.src_;
- } catch (e) {
- this.handleImageError_();
- }
- }
- };
- /**
- * @private
- */
- ol.style.IconImage.prototype.replaceColor_ = function() {
- if (this.tainting_ || this.color_ === null) {
- return;
- }
- this.canvas_.width = this.image_.width;
- this.canvas_.height = this.image_.height;
- var ctx = this.canvas_.getContext('2d');
- ctx.drawImage(this.image_, 0, 0);
- var imgData = ctx.getImageData(0, 0, this.image_.width, this.image_.height);
- var data = imgData.data;
- var r = this.color_[0] / 255.0;
- var g = this.color_[1] / 255.0;
- var b = this.color_[2] / 255.0;
- for (var i = 0, ii = data.length; i < ii; i += 4) {
- data[i] *= r;
- data[i + 1] *= g;
- data[i + 2] *= b;
- }
- ctx.putImageData(imgData, 0, 0);
- };
- /**
- * Discards event handlers which listen for load completion or errors.
- *
- * @private
- */
- ol.style.IconImage.prototype.unlistenImage_ = function() {
- this.imageListenerKeys_.forEach(ol.events.unlistenByKey);
- this.imageListenerKeys_ = null;
- };
- goog.provide('ol.style.IconOrigin');
- /**
- * Icon origin. One of 'bottom-left', 'bottom-right', 'top-left', 'top-right'.
- * @enum {string}
- */
- ol.style.IconOrigin = {
- BOTTOM_LEFT: 'bottom-left',
- BOTTOM_RIGHT: 'bottom-right',
- TOP_LEFT: 'top-left',
- TOP_RIGHT: 'top-right'
- };
- goog.provide('ol.style.Icon');
- goog.require('ol');
- goog.require('ol.ImageState');
- goog.require('ol.asserts');
- goog.require('ol.color');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.style.IconAnchorUnits');
- goog.require('ol.style.IconImage');
- goog.require('ol.style.IconOrigin');
- goog.require('ol.style.Image');
- /**
- * @classdesc
- * Set icon style for vector features.
- *
- * @constructor
- * @param {olx.style.IconOptions=} opt_options Options.
- * @extends {ol.style.Image}
- * @api
- */
- ol.style.Icon = function(opt_options) {
- var options = opt_options || {};
- /**
- * @private
- * @type {Array.<number>}
- */
- this.anchor_ = options.anchor !== undefined ? options.anchor : [0.5, 0.5];
- /**
- * @private
- * @type {Array.<number>}
- */
- this.normalizedAnchor_ = null;
- /**
- * @private
- * @type {ol.style.IconOrigin}
- */
- this.anchorOrigin_ = options.anchorOrigin !== undefined ?
- options.anchorOrigin : ol.style.IconOrigin.TOP_LEFT;
- /**
- * @private
- * @type {ol.style.IconAnchorUnits}
- */
- this.anchorXUnits_ = options.anchorXUnits !== undefined ?
- options.anchorXUnits : ol.style.IconAnchorUnits.FRACTION;
- /**
- * @private
- * @type {ol.style.IconAnchorUnits}
- */
- this.anchorYUnits_ = options.anchorYUnits !== undefined ?
- options.anchorYUnits : ol.style.IconAnchorUnits.FRACTION;
- /**
- * @private
- * @type {?string}
- */
- this.crossOrigin_ =
- options.crossOrigin !== undefined ? options.crossOrigin : null;
- /**
- * @type {Image|HTMLCanvasElement}
- */
- var image = options.img !== undefined ? options.img : null;
- /**
- * @type {ol.Size}
- */
- var imgSize = options.imgSize !== undefined ? options.imgSize : null;
- /**
- * @type {string|undefined}
- */
- var src = options.src;
- ol.asserts.assert(!(src !== undefined && image),
- 4); // `image` and `src` cannot be provided at the same time
- ol.asserts.assert(!image || (image && imgSize),
- 5); // `imgSize` must be set when `image` is provided
- if ((src === undefined || src.length === 0) && image) {
- src = image.src || ol.getUid(image).toString();
- }
- ol.asserts.assert(src !== undefined && src.length > 0,
- 6); // A defined and non-empty `src` or `image` must be provided
- /**
- * @type {ol.ImageState}
- */
- var imageState = options.src !== undefined ?
- ol.ImageState.IDLE : ol.ImageState.LOADED;
- /**
- * @private
- * @type {ol.Color}
- */
- this.color_ = options.color !== undefined ? ol.color.asArray(options.color) :
- null;
- /**
- * @private
- * @type {ol.style.IconImage}
- */
- this.iconImage_ = ol.style.IconImage.get(
- image, /** @type {string} */ (src), imgSize, this.crossOrigin_, imageState, this.color_);
- /**
- * @private
- * @type {Array.<number>}
- */
- this.offset_ = options.offset !== undefined ? options.offset : [0, 0];
- /**
- * @private
- * @type {ol.style.IconOrigin}
- */
- this.offsetOrigin_ = options.offsetOrigin !== undefined ?
- options.offsetOrigin : ol.style.IconOrigin.TOP_LEFT;
- /**
- * @private
- * @type {Array.<number>}
- */
- this.origin_ = null;
- /**
- * @private
- * @type {ol.Size}
- */
- this.size_ = options.size !== undefined ? options.size : null;
- /**
- * @type {number}
- */
- var opacity = options.opacity !== undefined ? options.opacity : 1;
- /**
- * @type {boolean}
- */
- var rotateWithView = options.rotateWithView !== undefined ?
- options.rotateWithView : false;
- /**
- * @type {number}
- */
- var rotation = options.rotation !== undefined ? options.rotation : 0;
- /**
- * @type {number}
- */
- var scale = options.scale !== undefined ? options.scale : 1;
- /**
- * @type {boolean}
- */
- var snapToPixel = options.snapToPixel !== undefined ?
- options.snapToPixel : true;
- ol.style.Image.call(this, {
- opacity: opacity,
- rotation: rotation,
- scale: scale,
- snapToPixel: snapToPixel,
- rotateWithView: rotateWithView
- });
- };
- ol.inherits(ol.style.Icon, ol.style.Image);
- /**
- * Clones the style. The underlying Image/HTMLCanvasElement is not cloned.
- * @return {ol.style.Icon} The cloned style.
- * @api
- */
- ol.style.Icon.prototype.clone = function() {
- return new ol.style.Icon({
- anchor: this.anchor_.slice(),
- anchorOrigin: this.anchorOrigin_,
- anchorXUnits: this.anchorXUnits_,
- anchorYUnits: this.anchorYUnits_,
- crossOrigin: this.crossOrigin_,
- color: (this.color_ && this.color_.slice) ? this.color_.slice() : this.color_ || undefined,
- src: this.getSrc(),
- offset: this.offset_.slice(),
- offsetOrigin: this.offsetOrigin_,
- size: this.size_ !== null ? this.size_.slice() : undefined,
- opacity: this.getOpacity(),
- scale: this.getScale(),
- snapToPixel: this.getSnapToPixel(),
- rotation: this.getRotation(),
- rotateWithView: this.getRotateWithView()
- });
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.style.Icon.prototype.getAnchor = function() {
- if (this.normalizedAnchor_) {
- return this.normalizedAnchor_;
- }
- var anchor = this.anchor_;
- var size = this.getSize();
- if (this.anchorXUnits_ == ol.style.IconAnchorUnits.FRACTION ||
- this.anchorYUnits_ == ol.style.IconAnchorUnits.FRACTION) {
- if (!size) {
- return null;
- }
- anchor = this.anchor_.slice();
- if (this.anchorXUnits_ == ol.style.IconAnchorUnits.FRACTION) {
- anchor[0] *= size[0];
- }
- if (this.anchorYUnits_ == ol.style.IconAnchorUnits.FRACTION) {
- anchor[1] *= size[1];
- }
- }
- if (this.anchorOrigin_ != ol.style.IconOrigin.TOP_LEFT) {
- if (!size) {
- return null;
- }
- if (anchor === this.anchor_) {
- anchor = this.anchor_.slice();
- }
- if (this.anchorOrigin_ == ol.style.IconOrigin.TOP_RIGHT ||
- this.anchorOrigin_ == ol.style.IconOrigin.BOTTOM_RIGHT) {
- anchor[0] = -anchor[0] + size[0];
- }
- if (this.anchorOrigin_ == ol.style.IconOrigin.BOTTOM_LEFT ||
- this.anchorOrigin_ == ol.style.IconOrigin.BOTTOM_RIGHT) {
- anchor[1] = -anchor[1] + size[1];
- }
- }
- this.normalizedAnchor_ = anchor;
- return this.normalizedAnchor_;
- };
- /**
- * Get the icon color.
- * @return {ol.Color} Color.
- * @api
- */
- ol.style.Icon.prototype.getColor = function() {
- return this.color_;
- };
- /**
- * Get the image icon.
- * @param {number} pixelRatio Pixel ratio.
- * @return {Image|HTMLCanvasElement} Image or Canvas element.
- * @override
- * @api
- */
- ol.style.Icon.prototype.getImage = function(pixelRatio) {
- return this.iconImage_.getImage(pixelRatio);
- };
- /**
- * @override
- */
- ol.style.Icon.prototype.getImageSize = function() {
- return this.iconImage_.getSize();
- };
- /**
- * @override
- */
- ol.style.Icon.prototype.getHitDetectionImageSize = function() {
- return this.getImageSize();
- };
- /**
- * @override
- */
- ol.style.Icon.prototype.getImageState = function() {
- return this.iconImage_.getImageState();
- };
- /**
- * @override
- */
- ol.style.Icon.prototype.getHitDetectionImage = function(pixelRatio) {
- return this.iconImage_.getHitDetectionImage(pixelRatio);
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.style.Icon.prototype.getOrigin = function() {
- if (this.origin_) {
- return this.origin_;
- }
- var offset = this.offset_;
- if (this.offsetOrigin_ != ol.style.IconOrigin.TOP_LEFT) {
- var size = this.getSize();
- var iconImageSize = this.iconImage_.getSize();
- if (!size || !iconImageSize) {
- return null;
- }
- offset = offset.slice();
- if (this.offsetOrigin_ == ol.style.IconOrigin.TOP_RIGHT ||
- this.offsetOrigin_ == ol.style.IconOrigin.BOTTOM_RIGHT) {
- offset[0] = iconImageSize[0] - size[0] - offset[0];
- }
- if (this.offsetOrigin_ == ol.style.IconOrigin.BOTTOM_LEFT ||
- this.offsetOrigin_ == ol.style.IconOrigin.BOTTOM_RIGHT) {
- offset[1] = iconImageSize[1] - size[1] - offset[1];
- }
- }
- this.origin_ = offset;
- return this.origin_;
- };
- /**
- * Get the image URL.
- * @return {string|undefined} Image src.
- * @api
- */
- ol.style.Icon.prototype.getSrc = function() {
- return this.iconImage_.getSrc();
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.style.Icon.prototype.getSize = function() {
- return !this.size_ ? this.iconImage_.getSize() : this.size_;
- };
- /**
- * @override
- */
- ol.style.Icon.prototype.listenImageChange = function(listener, thisArg) {
- return ol.events.listen(this.iconImage_, ol.events.EventType.CHANGE,
- listener, thisArg);
- };
- /**
- * Load not yet loaded URI.
- * When rendering a feature with an icon style, the vector renderer will
- * automatically call this method. However, you might want to call this
- * method yourself for preloading or other purposes.
- * @override
- * @api
- */
- ol.style.Icon.prototype.load = function() {
- this.iconImage_.load();
- };
- /**
- * @override
- */
- ol.style.Icon.prototype.unlistenImageChange = function(listener, thisArg) {
- ol.events.unlisten(this.iconImage_, ol.events.EventType.CHANGE,
- listener, thisArg);
- };
- goog.provide('ol.style.Text');
- goog.require('ol.style.Fill');
- goog.require('ol.style.TextPlacement');
- /**
- * @classdesc
- * Set text style for vector features.
- *
- * @constructor
- * @param {olx.style.TextOptions=} opt_options Options.
- * @api
- */
- ol.style.Text = function(opt_options) {
- var options = opt_options || {};
- /**
- * @private
- * @type {string|undefined}
- */
- this.font_ = options.font;
- /**
- * @private
- * @type {number|undefined}
- */
- this.rotation_ = options.rotation;
- /**
- * @private
- * @type {boolean|undefined}
- */
- this.rotateWithView_ = options.rotateWithView;
- /**
- * @private
- * @type {number|undefined}
- */
- this.scale_ = options.scale;
- /**
- * @private
- * @type {string|undefined}
- */
- this.text_ = options.text;
- /**
- * @private
- * @type {string|undefined}
- */
- this.textAlign_ = options.textAlign;
- /**
- * @private
- * @type {string|undefined}
- */
- this.textBaseline_ = options.textBaseline;
- /**
- * @private
- * @type {ol.style.Fill}
- */
- this.fill_ = options.fill !== undefined ? options.fill :
- new ol.style.Fill({color: ol.style.Text.DEFAULT_FILL_COLOR_});
- /**
- * @private
- * @type {number}
- */
- this.maxAngle_ = options.maxAngle !== undefined ? options.maxAngle : Math.PI / 4;
- /**
- * @private
- * @type {ol.style.TextPlacement|string}
- */
- this.placement_ = options.placement !== undefined ? options.placement : ol.style.TextPlacement.POINT;
- //TODO Use options.overflow directly after removing @deprecated exceedLength
- var overflow = options.overflow === undefined ? options.exceedLength : options.overflow;
- /**
- * @private
- * @type {boolean}
- */
- this.overflow_ = overflow !== undefined ? overflow : false;
- /**
- * @private
- * @type {ol.style.Stroke}
- */
- this.stroke_ = options.stroke !== undefined ? options.stroke : null;
- /**
- * @private
- * @type {number}
- */
- this.offsetX_ = options.offsetX !== undefined ? options.offsetX : 0;
- /**
- * @private
- * @type {number}
- */
- this.offsetY_ = options.offsetY !== undefined ? options.offsetY : 0;
- /**
- * @private
- * @type {ol.style.Fill}
- */
- this.backgroundFill_ = options.backgroundFill ? options.backgroundFill : null;
- /**
- * @private
- * @type {ol.style.Stroke}
- */
- this.backgroundStroke_ = options.backgroundStroke ? options.backgroundStroke : null;
- /**
- * @private
- * @type {Array.<number>}
- */
- this.padding_ = options.padding === undefined ? null : options.padding;
- };
- /**
- * The default fill color to use if no fill was set at construction time; a
- * blackish `#333`.
- *
- * @const {string}
- * @private
- */
- ol.style.Text.DEFAULT_FILL_COLOR_ = '#333';
- /**
- * Clones the style.
- * @return {ol.style.Text} The cloned style.
- * @api
- */
- ol.style.Text.prototype.clone = function() {
- return new ol.style.Text({
- font: this.getFont(),
- placement: this.getPlacement(),
- maxAngle: this.getMaxAngle(),
- overflow: this.getOverflow(),
- rotation: this.getRotation(),
- rotateWithView: this.getRotateWithView(),
- scale: this.getScale(),
- text: this.getText(),
- textAlign: this.getTextAlign(),
- textBaseline: this.getTextBaseline(),
- fill: this.getFill() ? this.getFill().clone() : undefined,
- stroke: this.getStroke() ? this.getStroke().clone() : undefined,
- offsetX: this.getOffsetX(),
- offsetY: this.getOffsetY()
- });
- };
- /**
- * Get the `overflow` configuration.
- * @return {boolean} Let text overflow the length of the path they follow.
- * @api
- */
- ol.style.Text.prototype.getOverflow = function() {
- return this.overflow_;
- };
- /**
- * Get the font name.
- * @return {string|undefined} Font.
- * @api
- */
- ol.style.Text.prototype.getFont = function() {
- return this.font_;
- };
- /**
- * Get the maximum angle between adjacent characters.
- * @return {number} Angle in radians.
- * @api
- */
- ol.style.Text.prototype.getMaxAngle = function() {
- return this.maxAngle_;
- };
- /**
- * Get the label placement.
- * @return {ol.style.TextPlacement|string} Text placement.
- * @api
- */
- ol.style.Text.prototype.getPlacement = function() {
- return this.placement_;
- };
- /**
- * Get the x-offset for the text.
- * @return {number} Horizontal text offset.
- * @api
- */
- ol.style.Text.prototype.getOffsetX = function() {
- return this.offsetX_;
- };
- /**
- * Get the y-offset for the text.
- * @return {number} Vertical text offset.
- * @api
- */
- ol.style.Text.prototype.getOffsetY = function() {
- return this.offsetY_;
- };
- /**
- * Get the fill style for the text.
- * @return {ol.style.Fill} Fill style.
- * @api
- */
- ol.style.Text.prototype.getFill = function() {
- return this.fill_;
- };
- /**
- * Determine whether the text rotates with the map.
- * @return {boolean|undefined} Rotate with map.
- * @api
- */
- ol.style.Text.prototype.getRotateWithView = function() {
- return this.rotateWithView_;
- };
- /**
- * Get the text rotation.
- * @return {number|undefined} Rotation.
- * @api
- */
- ol.style.Text.prototype.getRotation = function() {
- return this.rotation_;
- };
- /**
- * Get the text scale.
- * @return {number|undefined} Scale.
- * @api
- */
- ol.style.Text.prototype.getScale = function() {
- return this.scale_;
- };
- /**
- * Get the stroke style for the text.
- * @return {ol.style.Stroke} Stroke style.
- * @api
- */
- ol.style.Text.prototype.getStroke = function() {
- return this.stroke_;
- };
- /**
- * Get the text to be rendered.
- * @return {string|undefined} Text.
- * @api
- */
- ol.style.Text.prototype.getText = function() {
- return this.text_;
- };
- /**
- * Get the text alignment.
- * @return {string|undefined} Text align.
- * @api
- */
- ol.style.Text.prototype.getTextAlign = function() {
- return this.textAlign_;
- };
- /**
- * Get the text baseline.
- * @return {string|undefined} Text baseline.
- * @api
- */
- ol.style.Text.prototype.getTextBaseline = function() {
- return this.textBaseline_;
- };
- /**
- * Get the background fill style for the text.
- * @return {ol.style.Fill} Fill style.
- * @api
- */
- ol.style.Text.prototype.getBackgroundFill = function() {
- return this.backgroundFill_;
- };
- /**
- * Get the background stroke style for the text.
- * @return {ol.style.Stroke} Stroke style.
- * @api
- */
- ol.style.Text.prototype.getBackgroundStroke = function() {
- return this.backgroundStroke_;
- };
- /**
- * Get the padding for the text.
- * @return {Array.<number>} Padding.
- * @api
- */
- ol.style.Text.prototype.getPadding = function() {
- return this.padding_;
- };
- /**
- * Set the `overflow` property.
- *
- * @param {boolean} overflow Let text overflow the path that it follows.
- * @api
- */
- ol.style.Text.prototype.setOverflow = function(overflow) {
- this.overflow_ = overflow;
- };
- /**
- * Set the font.
- *
- * @param {string|undefined} font Font.
- * @api
- */
- ol.style.Text.prototype.setFont = function(font) {
- this.font_ = font;
- };
- /**
- * Set the maximum angle between adjacent characters.
- *
- * @param {number} maxAngle Angle in radians.
- * @api
- */
- ol.style.Text.prototype.setMaxAngle = function(maxAngle) {
- this.maxAngle_ = maxAngle;
- };
- /**
- * Set the x offset.
- *
- * @param {number} offsetX Horizontal text offset.
- * @api
- */
- ol.style.Text.prototype.setOffsetX = function(offsetX) {
- this.offsetX_ = offsetX;
- };
- /**
- * Set the y offset.
- *
- * @param {number} offsetY Vertical text offset.
- * @api
- */
- ol.style.Text.prototype.setOffsetY = function(offsetY) {
- this.offsetY_ = offsetY;
- };
- /**
- * Set the text placement.
- *
- * @param {ol.style.TextPlacement|string} placement Placement.
- * @api
- */
- ol.style.Text.prototype.setPlacement = function(placement) {
- this.placement_ = placement;
- };
- /**
- * Set the fill.
- *
- * @param {ol.style.Fill} fill Fill style.
- * @api
- */
- ol.style.Text.prototype.setFill = function(fill) {
- this.fill_ = fill;
- };
- /**
- * Set the rotation.
- *
- * @param {number|undefined} rotation Rotation.
- * @api
- */
- ol.style.Text.prototype.setRotation = function(rotation) {
- this.rotation_ = rotation;
- };
- /**
- * Set the scale.
- *
- * @param {number|undefined} scale Scale.
- * @api
- */
- ol.style.Text.prototype.setScale = function(scale) {
- this.scale_ = scale;
- };
- /**
- * Set the stroke.
- *
- * @param {ol.style.Stroke} stroke Stroke style.
- * @api
- */
- ol.style.Text.prototype.setStroke = function(stroke) {
- this.stroke_ = stroke;
- };
- /**
- * Set the text.
- *
- * @param {string|undefined} text Text.
- * @api
- */
- ol.style.Text.prototype.setText = function(text) {
- this.text_ = text;
- };
- /**
- * Set the text alignment.
- *
- * @param {string|undefined} textAlign Text align.
- * @api
- */
- ol.style.Text.prototype.setTextAlign = function(textAlign) {
- this.textAlign_ = textAlign;
- };
- /**
- * Set the text baseline.
- *
- * @param {string|undefined} textBaseline Text baseline.
- * @api
- */
- ol.style.Text.prototype.setTextBaseline = function(textBaseline) {
- this.textBaseline_ = textBaseline;
- };
- /**
- * Set the background fill.
- *
- * @param {ol.style.Fill} fill Fill style.
- * @api
- */
- ol.style.Text.prototype.setBackgroundFill = function(fill) {
- this.backgroundFill_ = fill;
- };
- /**
- * Set the background stroke.
- *
- * @param {ol.style.Stroke} stroke Stroke style.
- * @api
- */
- ol.style.Text.prototype.setBackgroundStroke = function(stroke) {
- this.backgroundStroke_ = stroke;
- };
- /**
- * Set the padding (`[top, right, bottom, left]`).
- *
- * @param {!Array.<number>} padding Padding.
- * @api
- */
- ol.style.Text.prototype.setPadding = function(padding) {
- this.padding_ = padding;
- };
- // FIXME http://earth.google.com/kml/1.0 namespace?
- // FIXME why does node.getAttribute return an unknown type?
- // FIXME serialize arbitrary feature properties
- // FIXME don't parse style if extractStyles is false
- goog.provide('ol.format.KML');
- goog.require('ol');
- goog.require('ol.Feature');
- goog.require('ol.array');
- goog.require('ol.asserts');
- goog.require('ol.color');
- goog.require('ol.format.Feature');
- goog.require('ol.format.XMLFeature');
- goog.require('ol.format.XSD');
- goog.require('ol.geom.GeometryCollection');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.LineString');
- goog.require('ol.geom.MultiLineString');
- goog.require('ol.geom.MultiPoint');
- goog.require('ol.geom.MultiPolygon');
- goog.require('ol.geom.Point');
- goog.require('ol.geom.Polygon');
- goog.require('ol.math');
- goog.require('ol.proj');
- goog.require('ol.style.Fill');
- goog.require('ol.style.Icon');
- goog.require('ol.style.IconAnchorUnits');
- goog.require('ol.style.IconOrigin');
- goog.require('ol.style.Stroke');
- goog.require('ol.style.Style');
- goog.require('ol.style.Text');
- goog.require('ol.xml');
- /**
- * @classdesc
- * Feature format for reading and writing data in the KML format.
- *
- * Note that the KML format uses the URL() constructor. Older browsers such as IE
- * which do not support this will need a URL polyfill to be loaded before use.
- *
- * @constructor
- * @extends {ol.format.XMLFeature}
- * @param {olx.format.KMLOptions=} opt_options Options.
- * @api
- */
- ol.format.KML = function(opt_options) {
- var options = opt_options ? opt_options : {};
- ol.format.XMLFeature.call(this);
- if (!ol.format.KML.DEFAULT_STYLE_ARRAY_) {
- ol.format.KML.createStyleDefaults_();
- }
- /**
- * @inheritDoc
- */
- this.defaultDataProjection = ol.proj.get('EPSG:4326');
- /**
- * @private
- * @type {Array.<ol.style.Style>}
- */
- this.defaultStyle_ = options.defaultStyle ?
- options.defaultStyle : ol.format.KML.DEFAULT_STYLE_ARRAY_;
- /**
- * @private
- * @type {boolean}
- */
- this.extractStyles_ = options.extractStyles !== undefined ?
- options.extractStyles : true;
- /**
- * @private
- * @type {boolean}
- */
- this.writeStyles_ = options.writeStyles !== undefined ?
- options.writeStyles : true;
- /**
- * @private
- * @type {Object.<string, (Array.<ol.style.Style>|string)>}
- */
- this.sharedStyles_ = {};
- /**
- * @private
- * @type {boolean}
- */
- this.showPointNames_ = options.showPointNames !== undefined ?
- options.showPointNames : true;
- };
- ol.inherits(ol.format.KML, ol.format.XMLFeature);
- /**
- * @const
- * @type {Array.<string>}
- * @private
- */
- ol.format.KML.GX_NAMESPACE_URIS_ = [
- 'http://www.google.com/kml/ext/2.2'
- ];
- /**
- * @const
- * @type {Array.<string>}
- * @private
- */
- ol.format.KML.NAMESPACE_URIS_ = [
- null,
- 'http://earth.google.com/kml/2.0',
- 'http://earth.google.com/kml/2.1',
- 'http://earth.google.com/kml/2.2',
- 'http://www.opengis.net/kml/2.2'
- ];
- /**
- * @const
- * @type {string}
- * @private
- */
- ol.format.KML.SCHEMA_LOCATION_ = 'http://www.opengis.net/kml/2.2 ' +
- 'https://developers.google.com/kml/schema/kml22gx.xsd';
- /**
- * @return {Array.<ol.style.Style>} Default style.
- * @private
- */
- ol.format.KML.createStyleDefaults_ = function() {
- /**
- * @const
- * @type {ol.Color}
- * @private
- */
- ol.format.KML.DEFAULT_COLOR_ = [255, 255, 255, 1];
- /**
- * @const
- * @type {ol.style.Fill}
- * @private
- */
- ol.format.KML.DEFAULT_FILL_STYLE_ = new ol.style.Fill({
- color: ol.format.KML.DEFAULT_COLOR_
- });
- /**
- * @const
- * @type {ol.Size}
- * @private
- */
- ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_ = [20, 2]; // FIXME maybe [8, 32] ?
- /**
- * @const
- * @type {ol.style.IconAnchorUnits}
- * @private
- */
- ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_X_UNITS_ =
- ol.style.IconAnchorUnits.PIXELS;
- /**
- * @const
- * @type {ol.style.IconAnchorUnits}
- * @private
- */
- ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_Y_UNITS_ =
- ol.style.IconAnchorUnits.PIXELS;
- /**
- * @const
- * @type {ol.Size}
- * @private
- */
- ol.format.KML.DEFAULT_IMAGE_STYLE_SIZE_ = [64, 64];
- /**
- * @const
- * @type {string}
- * @private
- */
- ol.format.KML.DEFAULT_IMAGE_STYLE_SRC_ =
- 'https://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png';
- /**
- * @const
- * @type {number}
- * @private
- */
- ol.format.KML.DEFAULT_IMAGE_SCALE_MULTIPLIER_ = 0.5;
- /**
- * @const
- * @type {ol.style.Image}
- * @private
- */
- ol.format.KML.DEFAULT_IMAGE_STYLE_ = new ol.style.Icon({
- anchor: ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_,
- anchorOrigin: ol.style.IconOrigin.BOTTOM_LEFT,
- anchorXUnits: ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_X_UNITS_,
- anchorYUnits: ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_Y_UNITS_,
- crossOrigin: 'anonymous',
- rotation: 0,
- scale: ol.format.KML.DEFAULT_IMAGE_SCALE_MULTIPLIER_,
- size: ol.format.KML.DEFAULT_IMAGE_STYLE_SIZE_,
- src: ol.format.KML.DEFAULT_IMAGE_STYLE_SRC_
- });
- /**
- * @const
- * @type {string}
- * @private
- */
- ol.format.KML.DEFAULT_NO_IMAGE_STYLE_ = 'NO_IMAGE';
- /**
- * @const
- * @type {ol.style.Stroke}
- * @private
- */
- ol.format.KML.DEFAULT_STROKE_STYLE_ = new ol.style.Stroke({
- color: ol.format.KML.DEFAULT_COLOR_,
- width: 1
- });
- /**
- * @const
- * @type {ol.style.Stroke}
- * @private
- */
- ol.format.KML.DEFAULT_TEXT_STROKE_STYLE_ = new ol.style.Stroke({
- color: [51, 51, 51, 1],
- width: 2
- });
- /**
- * @const
- * @type {ol.style.Text}
- * @private
- */
- ol.format.KML.DEFAULT_TEXT_STYLE_ = new ol.style.Text({
- font: 'bold 16px Helvetica',
- fill: ol.format.KML.DEFAULT_FILL_STYLE_,
- stroke: ol.format.KML.DEFAULT_TEXT_STROKE_STYLE_,
- scale: 0.8
- });
- /**
- * @const
- * @type {ol.style.Style}
- * @private
- */
- ol.format.KML.DEFAULT_STYLE_ = new ol.style.Style({
- fill: ol.format.KML.DEFAULT_FILL_STYLE_,
- image: ol.format.KML.DEFAULT_IMAGE_STYLE_,
- text: ol.format.KML.DEFAULT_TEXT_STYLE_,
- stroke: ol.format.KML.DEFAULT_STROKE_STYLE_,
- zIndex: 0
- });
- /**
- * @const
- * @type {Array.<ol.style.Style>}
- * @private
- */
- ol.format.KML.DEFAULT_STYLE_ARRAY_ = [ol.format.KML.DEFAULT_STYLE_];
- return ol.format.KML.DEFAULT_STYLE_ARRAY_;
- };
- /**
- * @const
- * @type {Object.<string, ol.style.IconAnchorUnits>}
- * @private
- */
- ol.format.KML.ICON_ANCHOR_UNITS_MAP_ = {
- 'fraction': ol.style.IconAnchorUnits.FRACTION,
- 'pixels': ol.style.IconAnchorUnits.PIXELS,
- 'insetPixels': ol.style.IconAnchorUnits.PIXELS
- };
- /**
- * @param {ol.style.Style|undefined} foundStyle Style.
- * @param {string} name Name.
- * @return {ol.style.Style} style Style.
- * @private
- */
- ol.format.KML.createNameStyleFunction_ = function(foundStyle, name) {
- var textStyle = null;
- var textOffset = [0, 0];
- var textAlign = 'start';
- if (foundStyle.getImage()) {
- var imageSize = foundStyle.getImage().getImageSize();
- if (imageSize === null) {
- imageSize = ol.format.KML.DEFAULT_IMAGE_STYLE_SIZE_;
- }
- if (imageSize.length == 2) {
- var imageScale = foundStyle.getImage().getScale();
- // Offset the label to be centered to the right of the icon, if there is
- // one.
- textOffset[0] = imageScale * imageSize[0] / 2;
- textOffset[1] = -imageScale * imageSize[1] / 2;
- textAlign = 'left';
- }
- }
- if (foundStyle.getText() !== null) {
- // clone the text style, customizing it with name, alignments and offset.
- // Note that kml does not support many text options that OpenLayers does (rotation, textBaseline).
- var foundText = foundStyle.getText();
- textStyle = foundText.clone();
- textStyle.setFont(foundText.getFont() || ol.format.KML.DEFAULT_TEXT_STYLE_.getFont());
- textStyle.setScale(foundText.getScale() || ol.format.KML.DEFAULT_TEXT_STYLE_.getScale());
- textStyle.setFill(foundText.getFill() || ol.format.KML.DEFAULT_TEXT_STYLE_.getFill());
- textStyle.setStroke(foundText.getStroke() || ol.format.KML.DEFAULT_TEXT_STROKE_STYLE_);
- } else {
- textStyle = ol.format.KML.DEFAULT_TEXT_STYLE_.clone();
- }
- textStyle.setText(name);
- textStyle.setOffsetX(textOffset[0]);
- textStyle.setOffsetY(textOffset[1]);
- textStyle.setTextAlign(textAlign);
- var nameStyle = new ol.style.Style({
- text: textStyle
- });
- return nameStyle;
- };
- /**
- * @param {Array.<ol.style.Style>|undefined} style Style.
- * @param {string} styleUrl Style URL.
- * @param {Array.<ol.style.Style>} defaultStyle Default style.
- * @param {Object.<string, (Array.<ol.style.Style>|string)>} sharedStyles Shared
- * styles.
- * @param {boolean|undefined} showPointNames true to show names for point
- * placemarks.
- * @return {ol.FeatureStyleFunction} Feature style function.
- * @private
- */
- ol.format.KML.createFeatureStyleFunction_ = function(style, styleUrl,
- defaultStyle, sharedStyles, showPointNames) {
- return (
- /**
- * @param {number} resolution Resolution.
- * @return {Array.<ol.style.Style>} Style.
- * @this {ol.Feature}
- */
- function(resolution) {
- var drawName = showPointNames;
- /** @type {ol.style.Style|undefined} */
- var nameStyle;
- var name = '';
- if (drawName) {
- if (this.getGeometry()) {
- drawName = (this.getGeometry().getType() ===
- ol.geom.GeometryType.POINT);
- }
- }
- if (drawName) {
- name = /** @type {string} */ (this.get('name'));
- drawName = drawName && name;
- }
- if (style) {
- if (drawName) {
- nameStyle = ol.format.KML.createNameStyleFunction_(style[0],
- name);
- return style.concat(nameStyle);
- }
- return style;
- }
- if (styleUrl) {
- var foundStyle = ol.format.KML.findStyle_(styleUrl, defaultStyle,
- sharedStyles);
- if (drawName) {
- nameStyle = ol.format.KML.createNameStyleFunction_(foundStyle[0],
- name);
- return foundStyle.concat(nameStyle);
- }
- return foundStyle;
- }
- if (drawName) {
- nameStyle = ol.format.KML.createNameStyleFunction_(defaultStyle[0],
- name);
- return defaultStyle.concat(nameStyle);
- }
- return defaultStyle;
- });
- };
- /**
- * @param {Array.<ol.style.Style>|string|undefined} styleValue Style value.
- * @param {Array.<ol.style.Style>} defaultStyle Default style.
- * @param {Object.<string, (Array.<ol.style.Style>|string)>} sharedStyles
- * Shared styles.
- * @return {Array.<ol.style.Style>} Style.
- * @private
- */
- ol.format.KML.findStyle_ = function(styleValue, defaultStyle, sharedStyles) {
- if (Array.isArray(styleValue)) {
- return styleValue;
- } else if (typeof styleValue === 'string') {
- // KML files in the wild occasionally forget the leading `#` on styleUrls
- // defined in the same document. Add a leading `#` if it enables to find
- // a style.
- if (!(styleValue in sharedStyles) && ('#' + styleValue in sharedStyles)) {
- styleValue = '#' + styleValue;
- }
- return ol.format.KML.findStyle_(
- sharedStyles[styleValue], defaultStyle, sharedStyles);
- } else {
- return defaultStyle;
- }
- };
- /**
- * @param {Node} node Node.
- * @private
- * @return {ol.Color|undefined} Color.
- */
- ol.format.KML.readColor_ = function(node) {
- var s = ol.xml.getAllTextContent(node, false);
- // The KML specification states that colors should not include a leading `#`
- // but we tolerate them.
- var m = /^\s*#?\s*([0-9A-Fa-f]{8})\s*$/.exec(s);
- if (m) {
- var hexColor = m[1];
- return [
- parseInt(hexColor.substr(6, 2), 16),
- parseInt(hexColor.substr(4, 2), 16),
- parseInt(hexColor.substr(2, 2), 16),
- parseInt(hexColor.substr(0, 2), 16) / 255
- ];
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @private
- * @return {Array.<number>|undefined} Flat coordinates.
- */
- ol.format.KML.readFlatCoordinates_ = function(node) {
- var s = ol.xml.getAllTextContent(node, false);
- var flatCoordinates = [];
- // The KML specification states that coordinate tuples should not include
- // spaces, but we tolerate them.
- var re =
- /^\s*([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?)\s*,\s*([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?)(?:\s*,\s*([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?))?\s*/i;
- var m;
- while ((m = re.exec(s))) {
- var x = parseFloat(m[1]);
- var y = parseFloat(m[2]);
- var z = m[3] ? parseFloat(m[3]) : 0;
- flatCoordinates.push(x, y, z);
- s = s.substr(m[0].length);
- }
- if (s !== '') {
- return undefined;
- }
- return flatCoordinates;
- };
- /**
- * @param {Node} node Node.
- * @private
- * @return {string} URI.
- */
- ol.format.KML.readURI_ = function(node) {
- var s = ol.xml.getAllTextContent(node, false).trim();
- var baseURI = node.baseURI;
- if (!baseURI || baseURI == 'about:blank') {
- baseURI = window.location.href;
- }
- if (baseURI) {
- var url = new URL(s, baseURI);
- return url.href;
- } else {
- return s;
- }
- };
- /**
- * @param {Node} node Node.
- * @private
- * @return {ol.KMLVec2_} Vec2.
- */
- ol.format.KML.readVec2_ = function(node) {
- var xunits = node.getAttribute('xunits');
- var yunits = node.getAttribute('yunits');
- var origin;
- if (xunits !== 'insetPixels') {
- if (yunits !== 'insetPixels') {
- origin = ol.style.IconOrigin.BOTTOM_LEFT;
- } else {
- origin = ol.style.IconOrigin.TOP_LEFT;
- }
- } else {
- if (yunits !== 'insetPixels') {
- origin = ol.style.IconOrigin.BOTTOM_RIGHT;
- } else {
- origin = ol.style.IconOrigin.TOP_RIGHT;
- }
- }
- return {
- x: parseFloat(node.getAttribute('x')),
- xunits: ol.format.KML.ICON_ANCHOR_UNITS_MAP_[xunits],
- y: parseFloat(node.getAttribute('y')),
- yunits: ol.format.KML.ICON_ANCHOR_UNITS_MAP_[yunits],
- origin: origin
- };
- };
- /**
- * @param {Node} node Node.
- * @private
- * @return {number|undefined} Scale.
- */
- ol.format.KML.readScale_ = function(node) {
- return ol.format.XSD.readDecimal(node);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Array.<ol.style.Style>|string|undefined} StyleMap.
- */
- ol.format.KML.readStyleMapValue_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(undefined,
- ol.format.KML.STYLE_MAP_PARSERS_, node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.IconStyleParser_ = function(node, objectStack) {
- // FIXME refreshMode
- // FIXME refreshInterval
- // FIXME viewRefreshTime
- // FIXME viewBoundScale
- // FIXME viewFormat
- // FIXME httpQuery
- var object = ol.xml.pushParseAndPop(
- {}, ol.format.KML.ICON_STYLE_PARSERS_, node, objectStack);
- if (!object) {
- return;
- }
- var styleObject = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- var IconObject = 'Icon' in object ? object['Icon'] : {};
- var drawIcon = (!('Icon' in object) || Object.keys(IconObject).length > 0);
- var src;
- var href = /** @type {string|undefined} */
- (IconObject['href']);
- if (href) {
- src = href;
- } else if (drawIcon) {
- src = ol.format.KML.DEFAULT_IMAGE_STYLE_SRC_;
- }
- var anchor, anchorXUnits, anchorYUnits;
- var anchorOrigin = ol.style.IconOrigin.BOTTOM_LEFT;
- var hotSpot = /** @type {ol.KMLVec2_|undefined} */
- (object['hotSpot']);
- if (hotSpot) {
- anchor = [hotSpot.x, hotSpot.y];
- anchorXUnits = hotSpot.xunits;
- anchorYUnits = hotSpot.yunits;
- anchorOrigin = hotSpot.origin;
- } else if (src === ol.format.KML.DEFAULT_IMAGE_STYLE_SRC_) {
- anchor = ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_;
- anchorXUnits = ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_X_UNITS_;
- anchorYUnits = ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_Y_UNITS_;
- } else if (/^http:\/\/maps\.(?:google|gstatic)\.com\//.test(src)) {
- anchor = [0.5, 0];
- anchorXUnits = ol.style.IconAnchorUnits.FRACTION;
- anchorYUnits = ol.style.IconAnchorUnits.FRACTION;
- }
- var offset;
- var x = /** @type {number|undefined} */
- (IconObject['x']);
- var y = /** @type {number|undefined} */
- (IconObject['y']);
- if (x !== undefined && y !== undefined) {
- offset = [x, y];
- }
- var size;
- var w = /** @type {number|undefined} */
- (IconObject['w']);
- var h = /** @type {number|undefined} */
- (IconObject['h']);
- if (w !== undefined && h !== undefined) {
- size = [w, h];
- }
- var rotation;
- var heading = /** @type {number} */
- (object['heading']);
- if (heading !== undefined) {
- rotation = ol.math.toRadians(heading);
- }
- var scale = /** @type {number|undefined} */
- (object['scale']);
- if (drawIcon) {
- if (src == ol.format.KML.DEFAULT_IMAGE_STYLE_SRC_) {
- size = ol.format.KML.DEFAULT_IMAGE_STYLE_SIZE_;
- if (scale === undefined) {
- scale = ol.format.KML.DEFAULT_IMAGE_SCALE_MULTIPLIER_;
- }
- }
- var imageStyle = new ol.style.Icon({
- anchor: anchor,
- anchorOrigin: anchorOrigin,
- anchorXUnits: anchorXUnits,
- anchorYUnits: anchorYUnits,
- crossOrigin: 'anonymous', // FIXME should this be configurable?
- offset: offset,
- offsetOrigin: ol.style.IconOrigin.BOTTOM_LEFT,
- rotation: rotation,
- scale: scale,
- size: size,
- src: src
- });
- styleObject['imageStyle'] = imageStyle;
- } else {
- // handle the case when we explicitly want to draw no icon.
- styleObject['imageStyle'] = ol.format.KML.DEFAULT_NO_IMAGE_STYLE_;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.LabelStyleParser_ = function(node, objectStack) {
- // FIXME colorMode
- var object = ol.xml.pushParseAndPop(
- {}, ol.format.KML.LABEL_STYLE_PARSERS_, node, objectStack);
- if (!object) {
- return;
- }
- var styleObject = objectStack[objectStack.length - 1];
- var textStyle = new ol.style.Text({
- fill: new ol.style.Fill({
- color: /** @type {ol.Color} */
- ('color' in object ? object['color'] : ol.format.KML.DEFAULT_COLOR_)
- }),
- scale: /** @type {number|undefined} */
- (object['scale'])
- });
- styleObject['textStyle'] = textStyle;
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.LineStyleParser_ = function(node, objectStack) {
- // FIXME colorMode
- // FIXME gx:outerColor
- // FIXME gx:outerWidth
- // FIXME gx:physicalWidth
- // FIXME gx:labelVisibility
- var object = ol.xml.pushParseAndPop(
- {}, ol.format.KML.LINE_STYLE_PARSERS_, node, objectStack);
- if (!object) {
- return;
- }
- var styleObject = objectStack[objectStack.length - 1];
- var strokeStyle = new ol.style.Stroke({
- color: /** @type {ol.Color} */
- ('color' in object ? object['color'] : ol.format.KML.DEFAULT_COLOR_),
- width: /** @type {number} */ ('width' in object ? object['width'] : 1)
- });
- styleObject['strokeStyle'] = strokeStyle;
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.PolyStyleParser_ = function(node, objectStack) {
- // FIXME colorMode
- var object = ol.xml.pushParseAndPop(
- {}, ol.format.KML.POLY_STYLE_PARSERS_, node, objectStack);
- if (!object) {
- return;
- }
- var styleObject = objectStack[objectStack.length - 1];
- var fillStyle = new ol.style.Fill({
- color: /** @type {ol.Color} */
- ('color' in object ? object['color'] : ol.format.KML.DEFAULT_COLOR_)
- });
- styleObject['fillStyle'] = fillStyle;
- var fill = /** @type {boolean|undefined} */ (object['fill']);
- if (fill !== undefined) {
- styleObject['fill'] = fill;
- }
- var outline =
- /** @type {boolean|undefined} */ (object['outline']);
- if (outline !== undefined) {
- styleObject['outline'] = outline;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Array.<number>} LinearRing flat coordinates.
- */
- ol.format.KML.readFlatLinearRing_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(null,
- ol.format.KML.FLAT_LINEAR_RING_PARSERS_, node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.gxCoordParser_ = function(node, objectStack) {
- var gxTrackObject = /** @type {ol.KMLGxTrackObject_} */
- (objectStack[objectStack.length - 1]);
- var flatCoordinates = gxTrackObject.flatCoordinates;
- var s = ol.xml.getAllTextContent(node, false);
- var re =
- /^\s*([+\-]?\d+(?:\.\d*)?(?:e[+\-]?\d*)?)\s+([+\-]?\d+(?:\.\d*)?(?:e[+\-]?\d*)?)\s+([+\-]?\d+(?:\.\d*)?(?:e[+\-]?\d*)?)\s*$/i;
- var m = re.exec(s);
- if (m) {
- var x = parseFloat(m[1]);
- var y = parseFloat(m[2]);
- var z = parseFloat(m[3]);
- flatCoordinates.push(x, y, z, 0);
- } else {
- flatCoordinates.push(0, 0, 0, 0);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {ol.geom.MultiLineString|undefined} MultiLineString.
- */
- ol.format.KML.readGxMultiTrack_ = function(node, objectStack) {
- var lineStrings = ol.xml.pushParseAndPop([],
- ol.format.KML.GX_MULTITRACK_GEOMETRY_PARSERS_, node, objectStack);
- if (!lineStrings) {
- return undefined;
- }
- var multiLineString = new ol.geom.MultiLineString(null);
- multiLineString.setLineStrings(lineStrings);
- return multiLineString;
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {ol.geom.LineString|undefined} LineString.
- */
- ol.format.KML.readGxTrack_ = function(node, objectStack) {
- var gxTrackObject = ol.xml.pushParseAndPop(
- /** @type {ol.KMLGxTrackObject_} */ ({
- flatCoordinates: [],
- whens: []
- }), ol.format.KML.GX_TRACK_PARSERS_, node, objectStack);
- if (!gxTrackObject) {
- return undefined;
- }
- var flatCoordinates = gxTrackObject.flatCoordinates;
- var whens = gxTrackObject.whens;
- var i, ii;
- for (i = 0, ii = Math.min(flatCoordinates.length, whens.length); i < ii;
- ++i) {
- flatCoordinates[4 * i + 3] = whens[i];
- }
- var lineString = new ol.geom.LineString(null);
- lineString.setFlatCoordinates(ol.geom.GeometryLayout.XYZM, flatCoordinates);
- return lineString;
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object} Icon object.
- */
- ol.format.KML.readIcon_ = function(node, objectStack) {
- var iconObject = ol.xml.pushParseAndPop(
- {}, ol.format.KML.ICON_PARSERS_, node, objectStack);
- if (iconObject) {
- return iconObject;
- } else {
- return null;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Array.<number>} Flat coordinates.
- */
- ol.format.KML.readFlatCoordinatesFromNode_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(null,
- ol.format.KML.GEOMETRY_FLAT_COORDINATES_PARSERS_, node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {ol.geom.LineString|undefined} LineString.
- */
- ol.format.KML.readLineString_ = function(node, objectStack) {
- var properties = ol.xml.pushParseAndPop({},
- ol.format.KML.EXTRUDE_AND_ALTITUDE_MODE_PARSERS_, node,
- objectStack);
- var flatCoordinates =
- ol.format.KML.readFlatCoordinatesFromNode_(node, objectStack);
- if (flatCoordinates) {
- var lineString = new ol.geom.LineString(null);
- lineString.setFlatCoordinates(ol.geom.GeometryLayout.XYZ, flatCoordinates);
- lineString.setProperties(properties);
- return lineString;
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {ol.geom.Polygon|undefined} Polygon.
- */
- ol.format.KML.readLinearRing_ = function(node, objectStack) {
- var properties = ol.xml.pushParseAndPop({},
- ol.format.KML.EXTRUDE_AND_ALTITUDE_MODE_PARSERS_, node,
- objectStack);
- var flatCoordinates =
- ol.format.KML.readFlatCoordinatesFromNode_(node, objectStack);
- if (flatCoordinates) {
- var polygon = new ol.geom.Polygon(null);
- polygon.setFlatCoordinates(ol.geom.GeometryLayout.XYZ, flatCoordinates,
- [flatCoordinates.length]);
- polygon.setProperties(properties);
- return polygon;
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {ol.geom.Geometry} Geometry.
- */
- ol.format.KML.readMultiGeometry_ = function(node, objectStack) {
- var geometries = ol.xml.pushParseAndPop([],
- ol.format.KML.MULTI_GEOMETRY_PARSERS_, node, objectStack);
- if (!geometries) {
- return null;
- }
- if (geometries.length === 0) {
- return new ol.geom.GeometryCollection(geometries);
- }
- /** @type {ol.geom.Geometry} */
- var multiGeometry;
- var homogeneous = true;
- var type = geometries[0].getType();
- var geometry, i, ii;
- for (i = 1, ii = geometries.length; i < ii; ++i) {
- geometry = geometries[i];
- if (geometry.getType() != type) {
- homogeneous = false;
- break;
- }
- }
- if (homogeneous) {
- var layout;
- var flatCoordinates;
- if (type == ol.geom.GeometryType.POINT) {
- var point = geometries[0];
- layout = point.getLayout();
- flatCoordinates = point.getFlatCoordinates();
- for (i = 1, ii = geometries.length; i < ii; ++i) {
- geometry = geometries[i];
- ol.array.extend(flatCoordinates, geometry.getFlatCoordinates());
- }
- multiGeometry = new ol.geom.MultiPoint(null);
- multiGeometry.setFlatCoordinates(layout, flatCoordinates);
- ol.format.KML.setCommonGeometryProperties_(multiGeometry, geometries);
- } else if (type == ol.geom.GeometryType.LINE_STRING) {
- multiGeometry = new ol.geom.MultiLineString(null);
- multiGeometry.setLineStrings(geometries);
- ol.format.KML.setCommonGeometryProperties_(multiGeometry, geometries);
- } else if (type == ol.geom.GeometryType.POLYGON) {
- multiGeometry = new ol.geom.MultiPolygon(null);
- multiGeometry.setPolygons(geometries);
- ol.format.KML.setCommonGeometryProperties_(multiGeometry, geometries);
- } else if (type == ol.geom.GeometryType.GEOMETRY_COLLECTION) {
- multiGeometry = new ol.geom.GeometryCollection(geometries);
- } else {
- ol.asserts.assert(false, 37); // Unknown geometry type found
- }
- } else {
- multiGeometry = new ol.geom.GeometryCollection(geometries);
- }
- return /** @type {ol.geom.Geometry} */ (multiGeometry);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {ol.geom.Point|undefined} Point.
- */
- ol.format.KML.readPoint_ = function(node, objectStack) {
- var properties = ol.xml.pushParseAndPop({},
- ol.format.KML.EXTRUDE_AND_ALTITUDE_MODE_PARSERS_, node,
- objectStack);
- var flatCoordinates =
- ol.format.KML.readFlatCoordinatesFromNode_(node, objectStack);
- if (flatCoordinates) {
- var point = new ol.geom.Point(null);
- point.setFlatCoordinates(ol.geom.GeometryLayout.XYZ, flatCoordinates);
- point.setProperties(properties);
- return point;
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {ol.geom.Polygon|undefined} Polygon.
- */
- ol.format.KML.readPolygon_ = function(node, objectStack) {
- var properties = ol.xml.pushParseAndPop(/** @type {Object<string,*>} */ ({}),
- ol.format.KML.EXTRUDE_AND_ALTITUDE_MODE_PARSERS_, node,
- objectStack);
- var flatLinearRings = ol.xml.pushParseAndPop([null],
- ol.format.KML.FLAT_LINEAR_RINGS_PARSERS_, node, objectStack);
- if (flatLinearRings && flatLinearRings[0]) {
- var polygon = new ol.geom.Polygon(null);
- var flatCoordinates = flatLinearRings[0];
- var ends = [flatCoordinates.length];
- var i, ii;
- for (i = 1, ii = flatLinearRings.length; i < ii; ++i) {
- ol.array.extend(flatCoordinates, flatLinearRings[i]);
- ends.push(flatCoordinates.length);
- }
- polygon.setFlatCoordinates(
- ol.geom.GeometryLayout.XYZ, flatCoordinates, ends);
- polygon.setProperties(properties);
- return polygon;
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Array.<ol.style.Style>} Style.
- */
- ol.format.KML.readStyle_ = function(node, objectStack) {
- var styleObject = ol.xml.pushParseAndPop(
- {}, ol.format.KML.STYLE_PARSERS_, node, objectStack);
- if (!styleObject) {
- return null;
- }
- var fillStyle = /** @type {ol.style.Fill} */
- ('fillStyle' in styleObject ?
- styleObject['fillStyle'] : ol.format.KML.DEFAULT_FILL_STYLE_);
- var fill = /** @type {boolean|undefined} */ (styleObject['fill']);
- if (fill !== undefined && !fill) {
- fillStyle = null;
- }
- var imageStyle = /** @type {ol.style.Image} */
- ('imageStyle' in styleObject ?
- styleObject['imageStyle'] : ol.format.KML.DEFAULT_IMAGE_STYLE_);
- if (imageStyle == ol.format.KML.DEFAULT_NO_IMAGE_STYLE_) {
- imageStyle = undefined;
- }
- var textStyle = /** @type {ol.style.Text} */
- ('textStyle' in styleObject ?
- styleObject['textStyle'] : ol.format.KML.DEFAULT_TEXT_STYLE_);
- var strokeStyle = /** @type {ol.style.Stroke} */
- ('strokeStyle' in styleObject ?
- styleObject['strokeStyle'] : ol.format.KML.DEFAULT_STROKE_STYLE_);
- var outline = /** @type {boolean|undefined} */
- (styleObject['outline']);
- if (outline !== undefined && !outline) {
- strokeStyle = null;
- }
- return [new ol.style.Style({
- fill: fillStyle,
- image: imageStyle,
- stroke: strokeStyle,
- text: textStyle,
- zIndex: undefined // FIXME
- })];
- };
- /**
- * Reads an array of geometries and creates arrays for common geometry
- * properties. Then sets them to the multi geometry.
- * @param {ol.geom.MultiPoint|ol.geom.MultiLineString|ol.geom.MultiPolygon}
- * multiGeometry A multi-geometry.
- * @param {Array.<ol.geom.Geometry>} geometries List of geometries.
- * @private
- */
- ol.format.KML.setCommonGeometryProperties_ = function(multiGeometry,
- geometries) {
- var ii = geometries.length;
- var extrudes = new Array(geometries.length);
- var tessellates = new Array(geometries.length);
- var altitudeModes = new Array(geometries.length);
- var geometry, i, hasExtrude, hasTessellate, hasAltitudeMode;
- hasExtrude = hasTessellate = hasAltitudeMode = false;
- for (i = 0; i < ii; ++i) {
- geometry = geometries[i];
- extrudes[i] = geometry.get('extrude');
- tessellates[i] = geometry.get('tessellate');
- altitudeModes[i] = geometry.get('altitudeMode');
- hasExtrude = hasExtrude || extrudes[i] !== undefined;
- hasTessellate = hasTessellate || tessellates[i] !== undefined;
- hasAltitudeMode = hasAltitudeMode || altitudeModes[i];
- }
- if (hasExtrude) {
- multiGeometry.set('extrude', extrudes);
- }
- if (hasTessellate) {
- multiGeometry.set('tessellate', tessellates);
- }
- if (hasAltitudeMode) {
- multiGeometry.set('altitudeMode', altitudeModes);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.DataParser_ = function(node, objectStack) {
- var name = node.getAttribute('name');
- ol.xml.parseNode(ol.format.KML.DATA_PARSERS_, node, objectStack);
- var featureObject = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- if (name !== null) {
- featureObject[name] = featureObject.value;
- } else if (featureObject.displayName !== null) {
- featureObject[featureObject.displayName] = featureObject.value;
- }
- delete featureObject['value'];
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.ExtendedDataParser_ = function(node, objectStack) {
- ol.xml.parseNode(ol.format.KML.EXTENDED_DATA_PARSERS_, node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.RegionParser_ = function(node, objectStack) {
- ol.xml.parseNode(ol.format.KML.REGION_PARSERS_, node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.PairDataParser_ = function(node, objectStack) {
- var pairObject = ol.xml.pushParseAndPop(
- {}, ol.format.KML.PAIR_PARSERS_, node, objectStack);
- if (!pairObject) {
- return;
- }
- var key = /** @type {string|undefined} */
- (pairObject['key']);
- if (key && key == 'normal') {
- var styleUrl = /** @type {string|undefined} */
- (pairObject['styleUrl']);
- if (styleUrl) {
- objectStack[objectStack.length - 1] = styleUrl;
- }
- var Style = /** @type {ol.style.Style} */
- (pairObject['Style']);
- if (Style) {
- objectStack[objectStack.length - 1] = Style;
- }
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.PlacemarkStyleMapParser_ = function(node, objectStack) {
- var styleMapValue = ol.format.KML.readStyleMapValue_(node, objectStack);
- if (!styleMapValue) {
- return;
- }
- var placemarkObject = objectStack[objectStack.length - 1];
- if (Array.isArray(styleMapValue)) {
- placemarkObject['Style'] = styleMapValue;
- } else if (typeof styleMapValue === 'string') {
- placemarkObject['styleUrl'] = styleMapValue;
- } else {
- ol.asserts.assert(false, 38); // `styleMapValue` has an unknown type
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.SchemaDataParser_ = function(node, objectStack) {
- ol.xml.parseNode(ol.format.KML.SCHEMA_DATA_PARSERS_, node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.SimpleDataParser_ = function(node, objectStack) {
- var name = node.getAttribute('name');
- if (name !== null) {
- var data = ol.format.XSD.readString(node);
- var featureObject =
- /** @type {Object} */ (objectStack[objectStack.length - 1]);
- featureObject[name] = data;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.LatLonAltBoxParser_ = function(node, objectStack) {
- var object = ol.xml.pushParseAndPop({}, ol.format.KML.LAT_LON_ALT_BOX_PARSERS_, node, objectStack);
- if (!object) {
- return;
- }
- var regionObject = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- var extent = [
- parseFloat(object['west']),
- parseFloat(object['south']),
- parseFloat(object['east']),
- parseFloat(object['north'])
- ];
- regionObject['extent'] = extent;
- regionObject['altitudeMode'] = object['altitudeMode'];
- regionObject['minAltitude'] = parseFloat(object['minAltitude']);
- regionObject['maxAltitude'] = parseFloat(object['maxAltitude']);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.LodParser_ = function(node, objectStack) {
- var object = ol.xml.pushParseAndPop({}, ol.format.KML.LOD_PARSERS_, node, objectStack);
- if (!object) {
- return;
- }
- var lodObject = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- lodObject['minLodPixels'] = parseFloat(object['minLodPixels']);
- lodObject['maxLodPixels'] = parseFloat(object['maxLodPixels']);
- lodObject['minFadeExtent'] = parseFloat(object['minFadeExtent']);
- lodObject['maxFadeExtent'] = parseFloat(object['maxFadeExtent']);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.innerBoundaryIsParser_ = function(node, objectStack) {
- /** @type {Array.<number>|undefined} */
- var flatLinearRing = ol.xml.pushParseAndPop(undefined,
- ol.format.KML.INNER_BOUNDARY_IS_PARSERS_, node, objectStack);
- if (flatLinearRing) {
- var flatLinearRings = /** @type {Array.<Array.<number>>} */
- (objectStack[objectStack.length - 1]);
- flatLinearRings.push(flatLinearRing);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.outerBoundaryIsParser_ = function(node, objectStack) {
- /** @type {Array.<number>|undefined} */
- var flatLinearRing = ol.xml.pushParseAndPop(undefined,
- ol.format.KML.OUTER_BOUNDARY_IS_PARSERS_, node, objectStack);
- if (flatLinearRing) {
- var flatLinearRings = /** @type {Array.<Array.<number>>} */
- (objectStack[objectStack.length - 1]);
- flatLinearRings[0] = flatLinearRing;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.LinkParser_ = function(node, objectStack) {
- ol.xml.parseNode(ol.format.KML.LINK_PARSERS_, node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.whenParser_ = function(node, objectStack) {
- var gxTrackObject = /** @type {ol.KMLGxTrackObject_} */
- (objectStack[objectStack.length - 1]);
- var whens = gxTrackObject.whens;
- var s = ol.xml.getAllTextContent(node, false);
- var when = Date.parse(s);
- whens.push(isNaN(when) ? 0 : when);
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.DATA_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'displayName': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'value': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.EXTENDED_DATA_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'Data': ol.format.KML.DataParser_,
- 'SchemaData': ol.format.KML.SchemaDataParser_
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.REGION_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'LatLonAltBox': ol.format.KML.LatLonAltBoxParser_,
- 'Lod': ol.format.KML.LodParser_
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.LAT_LON_ALT_BOX_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'altitudeMode': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'minAltitude': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'maxAltitude': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'north': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'south': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'east': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'west': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.LOD_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'minLodPixels': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'maxLodPixels': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'minFadeExtent': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'maxFadeExtent': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.EXTRUDE_AND_ALTITUDE_MODE_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'extrude': ol.xml.makeObjectPropertySetter(ol.format.XSD.readBoolean),
- 'tessellate': ol.xml.makeObjectPropertySetter(ol.format.XSD.readBoolean),
- 'altitudeMode': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.FLAT_LINEAR_RING_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'coordinates': ol.xml.makeReplacer(ol.format.KML.readFlatCoordinates_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.FLAT_LINEAR_RINGS_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'innerBoundaryIs': ol.format.KML.innerBoundaryIsParser_,
- 'outerBoundaryIs': ol.format.KML.outerBoundaryIsParser_
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.GX_TRACK_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'when': ol.format.KML.whenParser_
- }, ol.xml.makeStructureNS(
- ol.format.KML.GX_NAMESPACE_URIS_, {
- 'coord': ol.format.KML.gxCoordParser_
- }));
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.GEOMETRY_FLAT_COORDINATES_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'coordinates': ol.xml.makeReplacer(ol.format.KML.readFlatCoordinates_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.ICON_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'href': ol.xml.makeObjectPropertySetter(ol.format.KML.readURI_)
- }, ol.xml.makeStructureNS(
- ol.format.KML.GX_NAMESPACE_URIS_, {
- 'x': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'y': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'w': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'h': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal)
- }));
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.ICON_STYLE_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'Icon': ol.xml.makeObjectPropertySetter(ol.format.KML.readIcon_),
- 'heading': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
- 'hotSpot': ol.xml.makeObjectPropertySetter(ol.format.KML.readVec2_),
- 'scale': ol.xml.makeObjectPropertySetter(ol.format.KML.readScale_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.INNER_BOUNDARY_IS_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'LinearRing': ol.xml.makeReplacer(ol.format.KML.readFlatLinearRing_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.LABEL_STYLE_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'color': ol.xml.makeObjectPropertySetter(ol.format.KML.readColor_),
- 'scale': ol.xml.makeObjectPropertySetter(ol.format.KML.readScale_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.LINE_STYLE_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'color': ol.xml.makeObjectPropertySetter(ol.format.KML.readColor_),
- 'width': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.MULTI_GEOMETRY_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'LineString': ol.xml.makeArrayPusher(ol.format.KML.readLineString_),
- 'LinearRing': ol.xml.makeArrayPusher(ol.format.KML.readLinearRing_),
- 'MultiGeometry': ol.xml.makeArrayPusher(ol.format.KML.readMultiGeometry_),
- 'Point': ol.xml.makeArrayPusher(ol.format.KML.readPoint_),
- 'Polygon': ol.xml.makeArrayPusher(ol.format.KML.readPolygon_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.GX_MULTITRACK_GEOMETRY_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.GX_NAMESPACE_URIS_, {
- 'Track': ol.xml.makeArrayPusher(ol.format.KML.readGxTrack_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.NETWORK_LINK_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'ExtendedData': ol.format.KML.ExtendedDataParser_,
- 'Region': ol.format.KML.RegionParser_,
- 'Link': ol.format.KML.LinkParser_,
- 'address': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'description': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'name': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'open': ol.xml.makeObjectPropertySetter(ol.format.XSD.readBoolean),
- 'phoneNumber': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'visibility': ol.xml.makeObjectPropertySetter(ol.format.XSD.readBoolean)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.LINK_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'href': ol.xml.makeObjectPropertySetter(ol.format.KML.readURI_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.OUTER_BOUNDARY_IS_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'LinearRing': ol.xml.makeReplacer(ol.format.KML.readFlatLinearRing_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.PAIR_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'Style': ol.xml.makeObjectPropertySetter(ol.format.KML.readStyle_),
- 'key': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'styleUrl': ol.xml.makeObjectPropertySetter(ol.format.KML.readURI_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.PLACEMARK_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'ExtendedData': ol.format.KML.ExtendedDataParser_,
- 'Region': ol.format.KML.RegionParser_,
- 'MultiGeometry': ol.xml.makeObjectPropertySetter(
- ol.format.KML.readMultiGeometry_, 'geometry'),
- 'LineString': ol.xml.makeObjectPropertySetter(
- ol.format.KML.readLineString_, 'geometry'),
- 'LinearRing': ol.xml.makeObjectPropertySetter(
- ol.format.KML.readLinearRing_, 'geometry'),
- 'Point': ol.xml.makeObjectPropertySetter(
- ol.format.KML.readPoint_, 'geometry'),
- 'Polygon': ol.xml.makeObjectPropertySetter(
- ol.format.KML.readPolygon_, 'geometry'),
- 'Style': ol.xml.makeObjectPropertySetter(ol.format.KML.readStyle_),
- 'StyleMap': ol.format.KML.PlacemarkStyleMapParser_,
- 'address': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'description': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'name': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'open': ol.xml.makeObjectPropertySetter(ol.format.XSD.readBoolean),
- 'phoneNumber': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'styleUrl': ol.xml.makeObjectPropertySetter(ol.format.KML.readURI_),
- 'visibility': ol.xml.makeObjectPropertySetter(ol.format.XSD.readBoolean)
- }, ol.xml.makeStructureNS(
- ol.format.KML.GX_NAMESPACE_URIS_, {
- 'MultiTrack': ol.xml.makeObjectPropertySetter(
- ol.format.KML.readGxMultiTrack_, 'geometry'),
- 'Track': ol.xml.makeObjectPropertySetter(
- ol.format.KML.readGxTrack_, 'geometry')
- }
- ));
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.POLY_STYLE_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'color': ol.xml.makeObjectPropertySetter(ol.format.KML.readColor_),
- 'fill': ol.xml.makeObjectPropertySetter(ol.format.XSD.readBoolean),
- 'outline': ol.xml.makeObjectPropertySetter(ol.format.XSD.readBoolean)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.SCHEMA_DATA_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'SimpleData': ol.format.KML.SimpleDataParser_
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.STYLE_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'IconStyle': ol.format.KML.IconStyleParser_,
- 'LabelStyle': ol.format.KML.LabelStyleParser_,
- 'LineStyle': ol.format.KML.LineStyleParser_,
- 'PolyStyle': ol.format.KML.PolyStyleParser_
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.KML.STYLE_MAP_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'Pair': ol.format.KML.PairDataParser_
- });
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Array.<ol.Feature>|undefined} Features.
- */
- ol.format.KML.prototype.readDocumentOrFolder_ = function(node, objectStack) {
- // FIXME use scope somehow
- var parsersNS = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'Document': ol.xml.makeArrayExtender(this.readDocumentOrFolder_, this),
- 'Folder': ol.xml.makeArrayExtender(this.readDocumentOrFolder_, this),
- 'Placemark': ol.xml.makeArrayPusher(this.readPlacemark_, this),
- 'Style': this.readSharedStyle_.bind(this),
- 'StyleMap': this.readSharedStyleMap_.bind(this)
- });
- /** @type {Array.<ol.Feature>} */
- var features = ol.xml.pushParseAndPop([], parsersNS, node, objectStack, this);
- if (features) {
- return features;
- } else {
- return undefined;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {ol.Feature|undefined} Feature.
- */
- ol.format.KML.prototype.readPlacemark_ = function(node, objectStack) {
- var object = ol.xml.pushParseAndPop({'geometry': null},
- ol.format.KML.PLACEMARK_PARSERS_, node, objectStack);
- if (!object) {
- return undefined;
- }
- var feature = new ol.Feature();
- var id = node.getAttribute('id');
- if (id !== null) {
- feature.setId(id);
- }
- var options = /** @type {olx.format.ReadOptions} */ (objectStack[0]);
- var geometry = object['geometry'];
- if (geometry) {
- ol.format.Feature.transformWithOptions(geometry, false, options);
- }
- feature.setGeometry(geometry);
- delete object['geometry'];
- if (this.extractStyles_) {
- var style = object['Style'];
- var styleUrl = object['styleUrl'];
- var styleFunction = ol.format.KML.createFeatureStyleFunction_(
- style, styleUrl, this.defaultStyle_, this.sharedStyles_,
- this.showPointNames_);
- feature.setStyle(styleFunction);
- }
- delete object['Style'];
- // we do not remove the styleUrl property from the object, so it
- // gets stored on feature when setProperties is called
- feature.setProperties(object);
- return feature;
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.prototype.readSharedStyle_ = function(node, objectStack) {
- var id = node.getAttribute('id');
- if (id !== null) {
- var style = ol.format.KML.readStyle_(node, objectStack);
- if (style) {
- var styleUri;
- var baseURI = node.baseURI;
- if (!baseURI || baseURI == 'about:blank') {
- baseURI = window.location.href;
- }
- if (baseURI) {
- var url = new URL('#' + id, baseURI);
- styleUri = url.href;
- } else {
- styleUri = '#' + id;
- }
- this.sharedStyles_[styleUri] = style;
- }
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.prototype.readSharedStyleMap_ = function(node, objectStack) {
- var id = node.getAttribute('id');
- if (id === null) {
- return;
- }
- var styleMapValue = ol.format.KML.readStyleMapValue_(node, objectStack);
- if (!styleMapValue) {
- return;
- }
- var styleUri;
- var baseURI = node.baseURI;
- if (!baseURI || baseURI == 'about:blank') {
- baseURI = window.location.href;
- }
- if (baseURI) {
- var url = new URL('#' + id, baseURI);
- styleUri = url.href;
- } else {
- styleUri = '#' + id;
- }
- this.sharedStyles_[styleUri] = styleMapValue;
- };
- /**
- * Read the first feature from a KML source. MultiGeometries are converted into
- * GeometryCollections if they are a mix of geometry types, and into MultiPoint/
- * MultiLineString/MultiPolygon if they are all of the same type.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {ol.Feature} Feature.
- * @api
- */
- ol.format.KML.prototype.readFeature;
- /**
- * @inheritDoc
- */
- ol.format.KML.prototype.readFeatureFromNode = function(node, opt_options) {
- if (!ol.array.includes(ol.format.KML.NAMESPACE_URIS_, node.namespaceURI)) {
- return null;
- }
- var feature = this.readPlacemark_(
- node, [this.getReadOptions(node, opt_options)]);
- if (feature) {
- return feature;
- } else {
- return null;
- }
- };
- /**
- * Read all features from a KML source. MultiGeometries are converted into
- * GeometryCollections if they are a mix of geometry types, and into MultiPoint/
- * MultiLineString/MultiPolygon if they are all of the same type.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {Array.<ol.Feature>} Features.
- * @api
- */
- ol.format.KML.prototype.readFeatures;
- /**
- * @inheritDoc
- */
- ol.format.KML.prototype.readFeaturesFromNode = function(node, opt_options) {
- if (!ol.array.includes(ol.format.KML.NAMESPACE_URIS_, node.namespaceURI)) {
- return [];
- }
- var features;
- var localName = node.localName;
- if (localName == 'Document' || localName == 'Folder') {
- features = this.readDocumentOrFolder_(
- node, [this.getReadOptions(node, opt_options)]);
- if (features) {
- return features;
- } else {
- return [];
- }
- } else if (localName == 'Placemark') {
- var feature = this.readPlacemark_(
- node, [this.getReadOptions(node, opt_options)]);
- if (feature) {
- return [feature];
- } else {
- return [];
- }
- } else if (localName == 'kml') {
- features = [];
- var n;
- for (n = node.firstElementChild; n; n = n.nextElementSibling) {
- var fs = this.readFeaturesFromNode(n, opt_options);
- if (fs) {
- ol.array.extend(features, fs);
- }
- }
- return features;
- } else {
- return [];
- }
- };
- /**
- * Read the name of the KML.
- *
- * @param {Document|Node|string} source Souce.
- * @return {string|undefined} Name.
- * @api
- */
- ol.format.KML.prototype.readName = function(source) {
- if (ol.xml.isDocument(source)) {
- return this.readNameFromDocument(/** @type {Document} */ (source));
- } else if (ol.xml.isNode(source)) {
- return this.readNameFromNode(/** @type {Node} */ (source));
- } else if (typeof source === 'string') {
- var doc = ol.xml.parse(source);
- return this.readNameFromDocument(doc);
- } else {
- return undefined;
- }
- };
- /**
- * @param {Document} doc Document.
- * @return {string|undefined} Name.
- */
- ol.format.KML.prototype.readNameFromDocument = function(doc) {
- var n;
- for (n = doc.firstChild; n; n = n.nextSibling) {
- if (n.nodeType == Node.ELEMENT_NODE) {
- var name = this.readNameFromNode(n);
- if (name) {
- return name;
- }
- }
- }
- return undefined;
- };
- /**
- * @param {Node} node Node.
- * @return {string|undefined} Name.
- */
- ol.format.KML.prototype.readNameFromNode = function(node) {
- var n;
- for (n = node.firstElementChild; n; n = n.nextElementSibling) {
- if (ol.array.includes(ol.format.KML.NAMESPACE_URIS_, n.namespaceURI) &&
- n.localName == 'name') {
- return ol.format.XSD.readString(n);
- }
- }
- for (n = node.firstElementChild; n; n = n.nextElementSibling) {
- var localName = n.localName;
- if (ol.array.includes(ol.format.KML.NAMESPACE_URIS_, n.namespaceURI) &&
- (localName == 'Document' ||
- localName == 'Folder' ||
- localName == 'Placemark' ||
- localName == 'kml')) {
- var name = this.readNameFromNode(n);
- if (name) {
- return name;
- }
- }
- }
- return undefined;
- };
- /**
- * Read the network links of the KML.
- *
- * @param {Document|Node|string} source Source.
- * @return {Array.<Object>} Network links.
- * @api
- */
- ol.format.KML.prototype.readNetworkLinks = function(source) {
- var networkLinks = [];
- if (ol.xml.isDocument(source)) {
- ol.array.extend(networkLinks, this.readNetworkLinksFromDocument(
- /** @type {Document} */ (source)));
- } else if (ol.xml.isNode(source)) {
- ol.array.extend(networkLinks, this.readNetworkLinksFromNode(
- /** @type {Node} */ (source)));
- } else if (typeof source === 'string') {
- var doc = ol.xml.parse(source);
- ol.array.extend(networkLinks, this.readNetworkLinksFromDocument(doc));
- }
- return networkLinks;
- };
- /**
- * @param {Document} doc Document.
- * @return {Array.<Object>} Network links.
- */
- ol.format.KML.prototype.readNetworkLinksFromDocument = function(doc) {
- var n, networkLinks = [];
- for (n = doc.firstChild; n; n = n.nextSibling) {
- if (n.nodeType == Node.ELEMENT_NODE) {
- ol.array.extend(networkLinks, this.readNetworkLinksFromNode(n));
- }
- }
- return networkLinks;
- };
- /**
- * @param {Node} node Node.
- * @return {Array.<Object>} Network links.
- */
- ol.format.KML.prototype.readNetworkLinksFromNode = function(node) {
- var n, networkLinks = [];
- for (n = node.firstElementChild; n; n = n.nextElementSibling) {
- if (ol.array.includes(ol.format.KML.NAMESPACE_URIS_, n.namespaceURI) &&
- n.localName == 'NetworkLink') {
- var obj = ol.xml.pushParseAndPop({}, ol.format.KML.NETWORK_LINK_PARSERS_,
- n, []);
- networkLinks.push(obj);
- }
- }
- for (n = node.firstElementChild; n; n = n.nextElementSibling) {
- var localName = n.localName;
- if (ol.array.includes(ol.format.KML.NAMESPACE_URIS_, n.namespaceURI) &&
- (localName == 'Document' ||
- localName == 'Folder' ||
- localName == 'kml')) {
- ol.array.extend(networkLinks, this.readNetworkLinksFromNode(n));
- }
- }
- return networkLinks;
- };
- /**
- * Read the regions of the KML.
- *
- * @param {Document|Node|string} source Source.
- * @return {Array.<Object>} Regions.
- * @api
- */
- ol.format.KML.prototype.readRegion = function(source) {
- var regions = [];
- if (ol.xml.isDocument(source)) {
- ol.array.extend(regions, this.readRegionFromDocument(
- /** @type {Document} */ (source)));
- } else if (ol.xml.isNode(source)) {
- ol.array.extend(regions, this.readRegionFromNode(
- /** @type {Node} */ (source)));
- } else if (typeof source === 'string') {
- var doc = ol.xml.parse(source);
- ol.array.extend(regions, this.readRegionFromDocument(doc));
- }
- return regions;
- };
- /**
- * @param {Document} doc Document.
- * @return {Array.<Object>} Region.
- */
- ol.format.KML.prototype.readRegionFromDocument = function(doc) {
- var n, regions = [];
- for (n = doc.firstChild; n; n = n.nextSibling) {
- if (n.nodeType == Node.ELEMENT_NODE) {
- ol.array.extend(regions, this.readRegionFromNode(n));
- }
- }
- return regions;
- };
- /**
- * @param {Node} node Node.
- * @return {Array.<Object>} Region.
- * @api
- */
- ol.format.KML.prototype.readRegionFromNode = function(node) {
- var n, regions = [];
- for (n = node.firstElementChild; n; n = n.nextElementSibling) {
- if (ol.array.includes(ol.format.KML.NAMESPACE_URIS_, n.namespaceURI) &&
- n.localName == 'Region') {
- var obj = ol.xml.pushParseAndPop({}, ol.format.KML.REGION_PARSERS_,
- n, []);
- regions.push(obj);
- }
- }
- for (n = node.firstElementChild; n; n = n.nextElementSibling) {
- var localName = n.localName;
- if (ol.array.includes(ol.format.KML.NAMESPACE_URIS_, n.namespaceURI) &&
- (localName == 'Document' ||
- localName == 'Folder' ||
- localName == 'kml')) {
- ol.array.extend(regions, this.readRegionFromNode(n));
- }
- }
- return regions;
- };
- /**
- * Read the projection from a KML source.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @return {ol.proj.Projection} Projection.
- * @api
- */
- ol.format.KML.prototype.readProjection;
- /**
- * @param {Node} node Node to append a TextNode with the color to.
- * @param {ol.Color|string} color Color.
- * @private
- */
- ol.format.KML.writeColorTextNode_ = function(node, color) {
- var rgba = ol.color.asArray(color);
- var opacity = (rgba.length == 4) ? rgba[3] : 1;
- var abgr = [opacity * 255, rgba[2], rgba[1], rgba[0]];
- var i;
- for (i = 0; i < 4; ++i) {
- var hex = parseInt(abgr[i], 10).toString(16);
- abgr[i] = (hex.length == 1) ? '0' + hex : hex;
- }
- ol.format.XSD.writeStringTextNode(node, abgr.join(''));
- };
- /**
- * @param {Node} node Node to append a TextNode with the coordinates to.
- * @param {Array.<number>} coordinates Coordinates.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.writeCoordinatesTextNode_ = function(node, coordinates, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var layout = context['layout'];
- var stride = context['stride'];
- var dimension;
- if (layout == ol.geom.GeometryLayout.XY ||
- layout == ol.geom.GeometryLayout.XYM) {
- dimension = 2;
- } else if (layout == ol.geom.GeometryLayout.XYZ ||
- layout == ol.geom.GeometryLayout.XYZM) {
- dimension = 3;
- } else {
- ol.asserts.assert(false, 34); // Invalid geometry layout
- }
- var d, i;
- var ii = coordinates.length;
- var text = '';
- if (ii > 0) {
- text += coordinates[0];
- for (d = 1; d < dimension; ++d) {
- text += ',' + coordinates[d];
- }
- for (i = stride; i < ii; i += stride) {
- text += ' ' + coordinates[i];
- for (d = 1; d < dimension; ++d) {
- text += ',' + coordinates[i + d];
- }
- }
- }
- ol.format.XSD.writeStringTextNode(node, text);
- };
- /**
- * @param {Node} node Node.
- * @param {{name: *, value: *}} pair Name value pair.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.writeDataNode_ = function(node, pair, objectStack) {
- node.setAttribute('name', pair.name);
- var /** @type {ol.XmlNodeStackItem} */ context = {node: node};
- var value = pair.value;
- if (typeof value == 'object') {
- if (value !== null && value.displayName) {
- ol.xml.pushSerializeAndPop(context, ol.format.KML.EXTENDEDDATA_NODE_SERIALIZERS_,
- ol.xml.OBJECT_PROPERTY_NODE_FACTORY, [value.displayName], objectStack, ['displayName']);
- }
- if (value !== null && value.value) {
- ol.xml.pushSerializeAndPop(context, ol.format.KML.EXTENDEDDATA_NODE_SERIALIZERS_,
- ol.xml.OBJECT_PROPERTY_NODE_FACTORY, [value.value], objectStack, ['value']);
- }
- } else {
- ol.xml.pushSerializeAndPop(context, ol.format.KML.EXTENDEDDATA_NODE_SERIALIZERS_,
- ol.xml.OBJECT_PROPERTY_NODE_FACTORY, [value], objectStack, ['value']);
- }
- };
- /**
- * @param {Node} node Node to append a TextNode with the name to.
- * @param {string} name DisplayName.
- * @private
- */
- ol.format.KML.writeDataNodeName_ = function(node, name) {
- ol.format.XSD.writeCDATASection(node, name);
- };
- /**
- * @param {Node} node Node to append a CDATA Section with the value to.
- * @param {string} value Value.
- * @private
- */
- ol.format.KML.writeDataNodeValue_ = function(node, value) {
- ol.format.XSD.writeStringTextNode(node, value);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<ol.Feature>} features Features.
- * @param {Array.<*>} objectStack Object stack.
- * @this {ol.format.KML}
- * @private
- */
- ol.format.KML.writeDocument_ = function(node, features, objectStack) {
- var /** @type {ol.XmlNodeStackItem} */ context = {node: node};
- ol.xml.pushSerializeAndPop(context, ol.format.KML.DOCUMENT_SERIALIZERS_,
- ol.format.KML.DOCUMENT_NODE_FACTORY_, features, objectStack, undefined,
- this);
- };
- /**
- * @param {Node} node Node.
- * @param {{names: Array<string>, values: (Array<*>)}} namesAndValues Names and values.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.writeExtendedData_ = function(node, namesAndValues, objectStack) {
- var /** @type {ol.XmlNodeStackItem} */ context = {node: node};
- var names = namesAndValues.names, values = namesAndValues.values;
- var length = names.length;
- for (var i = 0; i < length; i++) {
- ol.xml.pushSerializeAndPop(context, ol.format.KML.EXTENDEDDATA_NODE_SERIALIZERS_,
- ol.format.KML.DATA_NODE_FACTORY_, [{name: names[i], value: values[i]}], objectStack);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Object} icon Icon object.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.writeIcon_ = function(node, icon, objectStack) {
- var /** @type {ol.XmlNodeStackItem} */ context = {node: node};
- var parentNode = objectStack[objectStack.length - 1].node;
- var orderedKeys = ol.format.KML.ICON_SEQUENCE_[parentNode.namespaceURI];
- var values = ol.xml.makeSequence(icon, orderedKeys);
- ol.xml.pushSerializeAndPop(context,
- ol.format.KML.ICON_SERIALIZERS_, ol.xml.OBJECT_PROPERTY_NODE_FACTORY,
- values, objectStack, orderedKeys);
- orderedKeys =
- ol.format.KML.ICON_SEQUENCE_[ol.format.KML.GX_NAMESPACE_URIS_[0]];
- values = ol.xml.makeSequence(icon, orderedKeys);
- ol.xml.pushSerializeAndPop(context, ol.format.KML.ICON_SERIALIZERS_,
- ol.format.KML.GX_NODE_FACTORY_, values, objectStack, orderedKeys);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.style.Icon} style Icon style.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.writeIconStyle_ = function(node, style, objectStack) {
- var /** @type {ol.XmlNodeStackItem} */ context = {node: node};
- var properties = {};
- var src = style.getSrc();
- var size = style.getSize();
- var iconImageSize = style.getImageSize();
- var iconProperties = {
- 'href': src
- };
- if (size) {
- iconProperties['w'] = size[0];
- iconProperties['h'] = size[1];
- var anchor = style.getAnchor(); // top-left
- var origin = style.getOrigin(); // top-left
- if (origin && iconImageSize && origin[0] !== 0 && origin[1] !== size[1]) {
- iconProperties['x'] = origin[0];
- iconProperties['y'] = iconImageSize[1] - (origin[1] + size[1]);
- }
- if (anchor && (anchor[0] !== size[0] / 2 || anchor[1] !== size[1] / 2)) {
- var /** @type {ol.KMLVec2_} */ hotSpot = {
- x: anchor[0],
- xunits: ol.style.IconAnchorUnits.PIXELS,
- y: size[1] - anchor[1],
- yunits: ol.style.IconAnchorUnits.PIXELS
- };
- properties['hotSpot'] = hotSpot;
- }
- }
- properties['Icon'] = iconProperties;
- var scale = style.getScale();
- if (scale !== 1) {
- properties['scale'] = scale;
- }
- var rotation = style.getRotation();
- if (rotation !== 0) {
- properties['heading'] = rotation; // 0-360
- }
- var parentNode = objectStack[objectStack.length - 1].node;
- var orderedKeys = ol.format.KML.ICON_STYLE_SEQUENCE_[parentNode.namespaceURI];
- var values = ol.xml.makeSequence(properties, orderedKeys);
- ol.xml.pushSerializeAndPop(context, ol.format.KML.ICON_STYLE_SERIALIZERS_,
- ol.xml.OBJECT_PROPERTY_NODE_FACTORY, values, objectStack, orderedKeys);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.style.Text} style style.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.writeLabelStyle_ = function(node, style, objectStack) {
- var /** @type {ol.XmlNodeStackItem} */ context = {node: node};
- var properties = {};
- var fill = style.getFill();
- if (fill) {
- properties['color'] = fill.getColor();
- }
- var scale = style.getScale();
- if (scale && scale !== 1) {
- properties['scale'] = scale;
- }
- var parentNode = objectStack[objectStack.length - 1].node;
- var orderedKeys =
- ol.format.KML.LABEL_STYLE_SEQUENCE_[parentNode.namespaceURI];
- var values = ol.xml.makeSequence(properties, orderedKeys);
- ol.xml.pushSerializeAndPop(context, ol.format.KML.LABEL_STYLE_SERIALIZERS_,
- ol.xml.OBJECT_PROPERTY_NODE_FACTORY, values, objectStack, orderedKeys);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.style.Stroke} style style.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.writeLineStyle_ = function(node, style, objectStack) {
- var /** @type {ol.XmlNodeStackItem} */ context = {node: node};
- var properties = {
- 'color': style.getColor(),
- 'width': style.getWidth()
- };
- var parentNode = objectStack[objectStack.length - 1].node;
- var orderedKeys = ol.format.KML.LINE_STYLE_SEQUENCE_[parentNode.namespaceURI];
- var values = ol.xml.makeSequence(properties, orderedKeys);
- ol.xml.pushSerializeAndPop(context, ol.format.KML.LINE_STYLE_SERIALIZERS_,
- ol.xml.OBJECT_PROPERTY_NODE_FACTORY, values, objectStack, orderedKeys);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.writeMultiGeometry_ = function(node, geometry, objectStack) {
- /** @type {ol.XmlNodeStackItem} */
- var context = {node: node};
- var type = geometry.getType();
- /** @type {Array.<ol.geom.Geometry>} */
- var geometries;
- /** @type {function(*, Array.<*>, string=): (Node|undefined)} */
- var factory;
- if (type == ol.geom.GeometryType.GEOMETRY_COLLECTION) {
- geometries = /** @type {ol.geom.GeometryCollection} */ (geometry).getGeometries();
- factory = ol.format.KML.GEOMETRY_NODE_FACTORY_;
- } else if (type == ol.geom.GeometryType.MULTI_POINT) {
- geometries = /** @type {ol.geom.MultiPoint} */ (geometry).getPoints();
- factory = ol.format.KML.POINT_NODE_FACTORY_;
- } else if (type == ol.geom.GeometryType.MULTI_LINE_STRING) {
- geometries =
- (/** @type {ol.geom.MultiLineString} */ (geometry)).getLineStrings();
- factory = ol.format.KML.LINE_STRING_NODE_FACTORY_;
- } else if (type == ol.geom.GeometryType.MULTI_POLYGON) {
- geometries =
- (/** @type {ol.geom.MultiPolygon} */ (geometry)).getPolygons();
- factory = ol.format.KML.POLYGON_NODE_FACTORY_;
- } else {
- ol.asserts.assert(false, 39); // Unknown geometry type
- }
- ol.xml.pushSerializeAndPop(context,
- ol.format.KML.MULTI_GEOMETRY_SERIALIZERS_, factory,
- geometries, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.LinearRing} linearRing Linear ring.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.writeBoundaryIs_ = function(node, linearRing, objectStack) {
- var /** @type {ol.XmlNodeStackItem} */ context = {node: node};
- ol.xml.pushSerializeAndPop(context,
- ol.format.KML.BOUNDARY_IS_SERIALIZERS_,
- ol.format.KML.LINEAR_RING_NODE_FACTORY_, [linearRing], objectStack);
- };
- /**
- * FIXME currently we do serialize arbitrary/custom feature properties
- * (ExtendedData).
- * @param {Node} node Node.
- * @param {ol.Feature} feature Feature.
- * @param {Array.<*>} objectStack Object stack.
- * @this {ol.format.KML}
- * @private
- */
- ol.format.KML.writePlacemark_ = function(node, feature, objectStack) {
- var /** @type {ol.XmlNodeStackItem} */ context = {node: node};
- // set id
- if (feature.getId()) {
- node.setAttribute('id', feature.getId());
- }
- // serialize properties (properties unknown to KML are not serialized)
- var properties = feature.getProperties();
- // don't export these to ExtendedData
- var filter = {'address': 1, 'description': 1, 'name': 1, 'open': 1,
- 'phoneNumber': 1, 'styleUrl': 1, 'visibility': 1};
- filter[feature.getGeometryName()] = 1;
- var keys = Object.keys(properties || {}).sort().filter(function(v) {
- return !filter[v];
- });
- if (keys.length > 0) {
- var sequence = ol.xml.makeSequence(properties, keys);
- var namesAndValues = {names: keys, values: sequence};
- ol.xml.pushSerializeAndPop(context, ol.format.KML.PLACEMARK_SERIALIZERS_,
- ol.format.KML.EXTENDEDDATA_NODE_FACTORY_, [namesAndValues], objectStack);
- }
- var styleFunction = feature.getStyleFunction();
- if (styleFunction) {
- // FIXME the styles returned by the style function are supposed to be
- // resolution-independent here
- var styles = styleFunction.call(feature, 0);
- if (styles) {
- var style = Array.isArray(styles) ? styles[0] : styles;
- if (this.writeStyles_) {
- properties['Style'] = style;
- }
- var textStyle = style.getText();
- if (textStyle) {
- properties['name'] = textStyle.getText();
- }
- }
- }
- var parentNode = objectStack[objectStack.length - 1].node;
- var orderedKeys = ol.format.KML.PLACEMARK_SEQUENCE_[parentNode.namespaceURI];
- var values = ol.xml.makeSequence(properties, orderedKeys);
- ol.xml.pushSerializeAndPop(context, ol.format.KML.PLACEMARK_SERIALIZERS_,
- ol.xml.OBJECT_PROPERTY_NODE_FACTORY, values, objectStack, orderedKeys);
- // serialize geometry
- var options = /** @type {olx.format.WriteOptions} */ (objectStack[0]);
- var geometry = feature.getGeometry();
- if (geometry) {
- geometry =
- ol.format.Feature.transformWithOptions(geometry, true, options);
- }
- ol.xml.pushSerializeAndPop(context, ol.format.KML.PLACEMARK_SERIALIZERS_,
- ol.format.KML.GEOMETRY_NODE_FACTORY_, [geometry], objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.SimpleGeometry} geometry Geometry.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.writePrimitiveGeometry_ = function(node, geometry, objectStack) {
- var flatCoordinates = geometry.getFlatCoordinates();
- var /** @type {ol.XmlNodeStackItem} */ context = {node: node};
- context['layout'] = geometry.getLayout();
- context['stride'] = geometry.getStride();
- // serialize properties (properties unknown to KML are not serialized)
- var properties = geometry.getProperties();
- properties.coordinates = flatCoordinates;
- var parentNode = objectStack[objectStack.length - 1].node;
- var orderedKeys = ol.format.KML.PRIMITIVE_GEOMETRY_SEQUENCE_[parentNode.namespaceURI];
- var values = ol.xml.makeSequence(properties, orderedKeys);
- ol.xml.pushSerializeAndPop(context, ol.format.KML.PRIMITIVE_GEOMETRY_SERIALIZERS_,
- ol.xml.OBJECT_PROPERTY_NODE_FACTORY, values, objectStack, orderedKeys);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.geom.Polygon} polygon Polygon.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.writePolygon_ = function(node, polygon, objectStack) {
- var linearRings = polygon.getLinearRings();
- var outerRing = linearRings.shift();
- var /** @type {ol.XmlNodeStackItem} */ context = {node: node};
- // inner rings
- ol.xml.pushSerializeAndPop(context,
- ol.format.KML.POLYGON_SERIALIZERS_,
- ol.format.KML.INNER_BOUNDARY_NODE_FACTORY_,
- linearRings, objectStack);
- // outer ring
- ol.xml.pushSerializeAndPop(context,
- ol.format.KML.POLYGON_SERIALIZERS_,
- ol.format.KML.OUTER_BOUNDARY_NODE_FACTORY_,
- [outerRing], objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.style.Fill} style Style.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.writePolyStyle_ = function(node, style, objectStack) {
- var /** @type {ol.XmlNodeStackItem} */ context = {node: node};
- ol.xml.pushSerializeAndPop(context, ol.format.KML.POLY_STYLE_SERIALIZERS_,
- ol.format.KML.COLOR_NODE_FACTORY_, [style.getColor()], objectStack);
- };
- /**
- * @param {Node} node Node to append a TextNode with the scale to.
- * @param {number|undefined} scale Scale.
- * @private
- */
- ol.format.KML.writeScaleTextNode_ = function(node, scale) {
- // the Math is to remove any excess decimals created by float arithmetic
- ol.format.XSD.writeDecimalTextNode(node,
- Math.round(scale * 1e6) / 1e6);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.style.Style} style Style.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.KML.writeStyle_ = function(node, style, objectStack) {
- var /** @type {ol.XmlNodeStackItem} */ context = {node: node};
- var properties = {};
- var fillStyle = style.getFill();
- var strokeStyle = style.getStroke();
- var imageStyle = style.getImage();
- var textStyle = style.getText();
- if (imageStyle instanceof ol.style.Icon) {
- properties['IconStyle'] = imageStyle;
- }
- if (textStyle) {
- properties['LabelStyle'] = textStyle;
- }
- if (strokeStyle) {
- properties['LineStyle'] = strokeStyle;
- }
- if (fillStyle) {
- properties['PolyStyle'] = fillStyle;
- }
- var parentNode = objectStack[objectStack.length - 1].node;
- var orderedKeys = ol.format.KML.STYLE_SEQUENCE_[parentNode.namespaceURI];
- var values = ol.xml.makeSequence(properties, orderedKeys);
- ol.xml.pushSerializeAndPop(context, ol.format.KML.STYLE_SERIALIZERS_,
- ol.xml.OBJECT_PROPERTY_NODE_FACTORY, values, objectStack, orderedKeys);
- };
- /**
- * @param {Node} node Node to append a TextNode with the Vec2 to.
- * @param {ol.KMLVec2_} vec2 Vec2.
- * @private
- */
- ol.format.KML.writeVec2_ = function(node, vec2) {
- node.setAttribute('x', vec2.x);
- node.setAttribute('y', vec2.y);
- node.setAttribute('xunits', vec2.xunits);
- node.setAttribute('yunits', vec2.yunits);
- };
- /**
- * @const
- * @type {Object.<string, Array.<string>>}
- * @private
- */
- ol.format.KML.KML_SEQUENCE_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, [
- 'Document', 'Placemark'
- ]);
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.KML.KML_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'Document': ol.xml.makeChildAppender(ol.format.KML.writeDocument_),
- 'Placemark': ol.xml.makeChildAppender(ol.format.KML.writePlacemark_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.KML.DOCUMENT_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'Placemark': ol.xml.makeChildAppender(ol.format.KML.writePlacemark_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.KML.EXTENDEDDATA_NODE_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'Data': ol.xml.makeChildAppender(ol.format.KML.writeDataNode_),
- 'value': ol.xml.makeChildAppender(ol.format.KML.writeDataNodeValue_),
- 'displayName': ol.xml.makeChildAppender(ol.format.KML.writeDataNodeName_)
- });
- /**
- * @const
- * @type {Object.<string, string>}
- * @private
- */
- ol.format.KML.GEOMETRY_TYPE_TO_NODENAME_ = {
- 'Point': 'Point',
- 'LineString': 'LineString',
- 'LinearRing': 'LinearRing',
- 'Polygon': 'Polygon',
- 'MultiPoint': 'MultiGeometry',
- 'MultiLineString': 'MultiGeometry',
- 'MultiPolygon': 'MultiGeometry',
- 'GeometryCollection': 'MultiGeometry'
- };
- /**
- * @const
- * @type {Object.<string, Array.<string>>}
- * @private
- */
- ol.format.KML.ICON_SEQUENCE_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, [
- 'href'
- ],
- ol.xml.makeStructureNS(ol.format.KML.GX_NAMESPACE_URIS_, [
- 'x', 'y', 'w', 'h'
- ]));
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.KML.ICON_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'href': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode)
- }, ol.xml.makeStructureNS(
- ol.format.KML.GX_NAMESPACE_URIS_, {
- 'x': ol.xml.makeChildAppender(ol.format.XSD.writeDecimalTextNode),
- 'y': ol.xml.makeChildAppender(ol.format.XSD.writeDecimalTextNode),
- 'w': ol.xml.makeChildAppender(ol.format.XSD.writeDecimalTextNode),
- 'h': ol.xml.makeChildAppender(ol.format.XSD.writeDecimalTextNode)
- }));
- /**
- * @const
- * @type {Object.<string, Array.<string>>}
- * @private
- */
- ol.format.KML.ICON_STYLE_SEQUENCE_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, [
- 'scale', 'heading', 'Icon', 'hotSpot'
- ]);
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.KML.ICON_STYLE_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'Icon': ol.xml.makeChildAppender(ol.format.KML.writeIcon_),
- 'heading': ol.xml.makeChildAppender(ol.format.XSD.writeDecimalTextNode),
- 'hotSpot': ol.xml.makeChildAppender(ol.format.KML.writeVec2_),
- 'scale': ol.xml.makeChildAppender(ol.format.KML.writeScaleTextNode_)
- });
- /**
- * @const
- * @type {Object.<string, Array.<string>>}
- * @private
- */
- ol.format.KML.LABEL_STYLE_SEQUENCE_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, [
- 'color', 'scale'
- ]);
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.KML.LABEL_STYLE_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'color': ol.xml.makeChildAppender(ol.format.KML.writeColorTextNode_),
- 'scale': ol.xml.makeChildAppender(ol.format.KML.writeScaleTextNode_)
- });
- /**
- * @const
- * @type {Object.<string, Array.<string>>}
- * @private
- */
- ol.format.KML.LINE_STYLE_SEQUENCE_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, [
- 'color', 'width'
- ]);
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.KML.LINE_STYLE_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'color': ol.xml.makeChildAppender(ol.format.KML.writeColorTextNode_),
- 'width': ol.xml.makeChildAppender(ol.format.XSD.writeDecimalTextNode)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.KML.BOUNDARY_IS_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'LinearRing': ol.xml.makeChildAppender(
- ol.format.KML.writePrimitiveGeometry_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.KML.MULTI_GEOMETRY_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'LineString': ol.xml.makeChildAppender(
- ol.format.KML.writePrimitiveGeometry_),
- 'Point': ol.xml.makeChildAppender(
- ol.format.KML.writePrimitiveGeometry_),
- 'Polygon': ol.xml.makeChildAppender(ol.format.KML.writePolygon_),
- 'GeometryCollection': ol.xml.makeChildAppender(
- ol.format.KML.writeMultiGeometry_)
- });
- /**
- * @const
- * @type {Object.<string, Array.<string>>}
- * @private
- */
- ol.format.KML.PLACEMARK_SEQUENCE_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, [
- 'name', 'open', 'visibility', 'address', 'phoneNumber', 'description',
- 'styleUrl', 'Style'
- ]);
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.KML.PLACEMARK_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'ExtendedData': ol.xml.makeChildAppender(
- ol.format.KML.writeExtendedData_),
- 'MultiGeometry': ol.xml.makeChildAppender(
- ol.format.KML.writeMultiGeometry_),
- 'LineString': ol.xml.makeChildAppender(
- ol.format.KML.writePrimitiveGeometry_),
- 'LinearRing': ol.xml.makeChildAppender(
- ol.format.KML.writePrimitiveGeometry_),
- 'Point': ol.xml.makeChildAppender(
- ol.format.KML.writePrimitiveGeometry_),
- 'Polygon': ol.xml.makeChildAppender(ol.format.KML.writePolygon_),
- 'Style': ol.xml.makeChildAppender(ol.format.KML.writeStyle_),
- 'address': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'description': ol.xml.makeChildAppender(
- ol.format.XSD.writeStringTextNode),
- 'name': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'open': ol.xml.makeChildAppender(ol.format.XSD.writeBooleanTextNode),
- 'phoneNumber': ol.xml.makeChildAppender(
- ol.format.XSD.writeStringTextNode),
- 'styleUrl': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'visibility': ol.xml.makeChildAppender(
- ol.format.XSD.writeBooleanTextNode)
- });
- /**
- * @const
- * @type {Object.<string, Array.<string>>}
- * @private
- */
- ol.format.KML.PRIMITIVE_GEOMETRY_SEQUENCE_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, [
- 'extrude', 'tessellate', 'altitudeMode', 'coordinates'
- ]);
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.KML.PRIMITIVE_GEOMETRY_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'extrude': ol.xml.makeChildAppender(ol.format.XSD.writeBooleanTextNode),
- 'tessellate': ol.xml.makeChildAppender(ol.format.XSD.writeBooleanTextNode),
- 'altitudeMode': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
- 'coordinates': ol.xml.makeChildAppender(
- ol.format.KML.writeCoordinatesTextNode_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.KML.POLYGON_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'outerBoundaryIs': ol.xml.makeChildAppender(
- ol.format.KML.writeBoundaryIs_),
- 'innerBoundaryIs': ol.xml.makeChildAppender(
- ol.format.KML.writeBoundaryIs_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.KML.POLY_STYLE_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'color': ol.xml.makeChildAppender(ol.format.KML.writeColorTextNode_)
- });
- /**
- * @const
- * @type {Object.<string, Array.<string>>}
- * @private
- */
- ol.format.KML.STYLE_SEQUENCE_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, [
- 'IconStyle', 'LabelStyle', 'LineStyle', 'PolyStyle'
- ]);
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.KML.STYLE_SERIALIZERS_ = ol.xml.makeStructureNS(
- ol.format.KML.NAMESPACE_URIS_, {
- 'IconStyle': ol.xml.makeChildAppender(ol.format.KML.writeIconStyle_),
- 'LabelStyle': ol.xml.makeChildAppender(ol.format.KML.writeLabelStyle_),
- 'LineStyle': ol.xml.makeChildAppender(ol.format.KML.writeLineStyle_),
- 'PolyStyle': ol.xml.makeChildAppender(ol.format.KML.writePolyStyle_)
- });
- /**
- * @const
- * @param {*} value Value.
- * @param {Array.<*>} objectStack Object stack.
- * @param {string=} opt_nodeName Node name.
- * @return {Node|undefined} Node.
- * @private
- */
- ol.format.KML.GX_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) {
- return ol.xml.createElementNS(ol.format.KML.GX_NAMESPACE_URIS_[0],
- 'gx:' + opt_nodeName);
- };
- /**
- * @const
- * @param {*} value Value.
- * @param {Array.<*>} objectStack Object stack.
- * @param {string=} opt_nodeName Node name.
- * @return {Node|undefined} Node.
- * @private
- */
- ol.format.KML.DOCUMENT_NODE_FACTORY_ = function(value, objectStack,
- opt_nodeName) {
- var parentNode = objectStack[objectStack.length - 1].node;
- return ol.xml.createElementNS(parentNode.namespaceURI, 'Placemark');
- };
- /**
- * @const
- * @param {*} value Value.
- * @param {Array.<*>} objectStack Object stack.
- * @param {string=} opt_nodeName Node name.
- * @return {Node|undefined} Node.
- * @private
- */
- ol.format.KML.GEOMETRY_NODE_FACTORY_ = function(value, objectStack,
- opt_nodeName) {
- if (value) {
- var parentNode = objectStack[objectStack.length - 1].node;
- return ol.xml.createElementNS(parentNode.namespaceURI,
- ol.format.KML.GEOMETRY_TYPE_TO_NODENAME_[/** @type {ol.geom.Geometry} */ (value).getType()]);
- }
- };
- /**
- * A factory for creating coordinates nodes.
- * @const
- * @type {function(*, Array.<*>, string=): (Node|undefined)}
- * @private
- */
- ol.format.KML.COLOR_NODE_FACTORY_ = ol.xml.makeSimpleNodeFactory('color');
- /**
- * A factory for creating Data nodes.
- * @const
- * @type {function(*, Array.<*>): (Node|undefined)}
- * @private
- */
- ol.format.KML.DATA_NODE_FACTORY_ =
- ol.xml.makeSimpleNodeFactory('Data');
- /**
- * A factory for creating ExtendedData nodes.
- * @const
- * @type {function(*, Array.<*>): (Node|undefined)}
- * @private
- */
- ol.format.KML.EXTENDEDDATA_NODE_FACTORY_ =
- ol.xml.makeSimpleNodeFactory('ExtendedData');
- /**
- * A factory for creating innerBoundaryIs nodes.
- * @const
- * @type {function(*, Array.<*>, string=): (Node|undefined)}
- * @private
- */
- ol.format.KML.INNER_BOUNDARY_NODE_FACTORY_ =
- ol.xml.makeSimpleNodeFactory('innerBoundaryIs');
- /**
- * A factory for creating Point nodes.
- * @const
- * @type {function(*, Array.<*>, string=): (Node|undefined)}
- * @private
- */
- ol.format.KML.POINT_NODE_FACTORY_ =
- ol.xml.makeSimpleNodeFactory('Point');
- /**
- * A factory for creating LineString nodes.
- * @const
- * @type {function(*, Array.<*>, string=): (Node|undefined)}
- * @private
- */
- ol.format.KML.LINE_STRING_NODE_FACTORY_ =
- ol.xml.makeSimpleNodeFactory('LineString');
- /**
- * A factory for creating LinearRing nodes.
- * @const
- * @type {function(*, Array.<*>, string=): (Node|undefined)}
- * @private
- */
- ol.format.KML.LINEAR_RING_NODE_FACTORY_ =
- ol.xml.makeSimpleNodeFactory('LinearRing');
- /**
- * A factory for creating Polygon nodes.
- * @const
- * @type {function(*, Array.<*>, string=): (Node|undefined)}
- * @private
- */
- ol.format.KML.POLYGON_NODE_FACTORY_ =
- ol.xml.makeSimpleNodeFactory('Polygon');
- /**
- * A factory for creating outerBoundaryIs nodes.
- * @const
- * @type {function(*, Array.<*>, string=): (Node|undefined)}
- * @private
- */
- ol.format.KML.OUTER_BOUNDARY_NODE_FACTORY_ =
- ol.xml.makeSimpleNodeFactory('outerBoundaryIs');
- /**
- * Encode an array of features in the KML format. GeometryCollections, MultiPoints,
- * MultiLineStrings, and MultiPolygons are output as MultiGeometries.
- *
- * @function
- * @param {Array.<ol.Feature>} features Features.
- * @param {olx.format.WriteOptions=} opt_options Options.
- * @return {string} Result.
- * @api
- */
- ol.format.KML.prototype.writeFeatures;
- /**
- * Encode an array of features in the KML format as an XML node. GeometryCollections,
- * MultiPoints, MultiLineStrings, and MultiPolygons are output as MultiGeometries.
- *
- * @param {Array.<ol.Feature>} features Features.
- * @param {olx.format.WriteOptions=} opt_options Options.
- * @return {Node} Node.
- * @override
- * @api
- */
- ol.format.KML.prototype.writeFeaturesNode = function(features, opt_options) {
- opt_options = this.adaptOptions(opt_options);
- var kml = ol.xml.createElementNS(ol.format.KML.NAMESPACE_URIS_[4], 'kml');
- var xmlnsUri = 'http://www.w3.org/2000/xmlns/';
- var xmlSchemaInstanceUri = 'http://www.w3.org/2001/XMLSchema-instance';
- ol.xml.setAttributeNS(kml, xmlnsUri, 'xmlns:gx',
- ol.format.KML.GX_NAMESPACE_URIS_[0]);
- ol.xml.setAttributeNS(kml, xmlnsUri, 'xmlns:xsi', xmlSchemaInstanceUri);
- ol.xml.setAttributeNS(kml, xmlSchemaInstanceUri, 'xsi:schemaLocation',
- ol.format.KML.SCHEMA_LOCATION_);
- var /** @type {ol.XmlNodeStackItem} */ context = {node: kml};
- var properties = {};
- if (features.length > 1) {
- properties['Document'] = features;
- } else if (features.length == 1) {
- properties['Placemark'] = features[0];
- }
- var orderedKeys = ol.format.KML.KML_SEQUENCE_[kml.namespaceURI];
- var values = ol.xml.makeSequence(properties, orderedKeys);
- ol.xml.pushSerializeAndPop(context, ol.format.KML.KML_SERIALIZERS_,
- ol.xml.OBJECT_PROPERTY_NODE_FACTORY, values, [opt_options], orderedKeys,
- this);
- return kml;
- };
- /**
- * @fileoverview
- * @suppress {accessControls, ambiguousFunctionDecl, checkDebuggerStatement, checkRegExp, checkTypes, checkVars, const, constantProperty, deprecated, duplicate, es5Strict, fileoverviewTags, missingProperties, nonStandardJsDocs, strictModuleDepCheck, suspiciousCode, undefinedNames, undefinedVars, unknownDefines, unusedLocalVariables, uselessCode, visibility}
- */
- goog.provide('ol.ext.PBF');
- /** @typedef {function(*)} */
- ol.ext.PBF = function() {};
- (function() {(function (exports) {
- 'use strict';
- var read = function (buffer, offset, isLE, mLen, nBytes) {
- var e, m;
- var eLen = (nBytes * 8) - mLen - 1;
- var eMax = (1 << eLen) - 1;
- var eBias = eMax >> 1;
- var nBits = -7;
- var i = isLE ? (nBytes - 1) : 0;
- var d = isLE ? -1 : 1;
- var s = buffer[offset + i];
- i += d;
- e = s & ((1 << (-nBits)) - 1);
- s >>= (-nBits);
- nBits += eLen;
- for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}
- m = e & ((1 << (-nBits)) - 1);
- e >>= (-nBits);
- nBits += mLen;
- for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}
- if (e === 0) {
- e = 1 - eBias;
- } else if (e === eMax) {
- return m ? NaN : ((s ? -1 : 1) * Infinity)
- } else {
- m = m + Math.pow(2, mLen);
- e = e - eBias;
- }
- return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
- };
- var write = function (buffer, value, offset, isLE, mLen, nBytes) {
- var e, m, c;
- var eLen = (nBytes * 8) - mLen - 1;
- var eMax = (1 << eLen) - 1;
- var eBias = eMax >> 1;
- var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0);
- var i = isLE ? 0 : (nBytes - 1);
- var d = isLE ? 1 : -1;
- var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
- value = Math.abs(value);
- if (isNaN(value) || value === Infinity) {
- m = isNaN(value) ? 1 : 0;
- e = eMax;
- } else {
- e = Math.floor(Math.log(value) / Math.LN2);
- if (value * (c = Math.pow(2, -e)) < 1) {
- e--;
- c *= 2;
- }
- if (e + eBias >= 1) {
- value += rt / c;
- } else {
- value += rt * Math.pow(2, 1 - eBias);
- }
- if (value * c >= 2) {
- e++;
- c /= 2;
- }
- if (e + eBias >= eMax) {
- m = 0;
- e = eMax;
- } else if (e + eBias >= 1) {
- m = ((value * c) - 1) * Math.pow(2, mLen);
- e = e + eBias;
- } else {
- m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
- e = 0;
- }
- }
- for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
- e = (e << mLen) | m;
- eLen += mLen;
- for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
- buffer[offset + i - d] |= s * 128;
- };
- var ieee754 = {
- read: read,
- write: write
- };
- var pbf = Pbf;
- function Pbf(buf) {
- this.buf = ArrayBuffer.isView && ArrayBuffer.isView(buf) ? buf : new Uint8Array(buf || 0);
- this.pos = 0;
- this.type = 0;
- this.length = this.buf.length;
- }
- Pbf.Varint = 0;
- Pbf.Fixed64 = 1;
- Pbf.Bytes = 2;
- Pbf.Fixed32 = 5;
- var SHIFT_LEFT_32 = (1 << 16) * (1 << 16);
- var SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32;
- Pbf.prototype = {
- destroy: function() {
- this.buf = null;
- },
- readFields: function(readField, result, end) {
- end = end || this.length;
- while (this.pos < end) {
- var val = this.readVarint(),
- tag = val >> 3,
- startPos = this.pos;
- this.type = val & 0x7;
- readField(tag, result, this);
- if (this.pos === startPos) this.skip(val);
- }
- return result;
- },
- readMessage: function(readField, result) {
- return this.readFields(readField, result, this.readVarint() + this.pos);
- },
- readFixed32: function() {
- var val = readUInt32(this.buf, this.pos);
- this.pos += 4;
- return val;
- },
- readSFixed32: function() {
- var val = readInt32(this.buf, this.pos);
- this.pos += 4;
- return val;
- },
- readFixed64: function() {
- var val = readUInt32(this.buf, this.pos) + readUInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32;
- this.pos += 8;
- return val;
- },
- readSFixed64: function() {
- var val = readUInt32(this.buf, this.pos) + readInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32;
- this.pos += 8;
- return val;
- },
- readFloat: function() {
- var val = ieee754.read(this.buf, this.pos, true, 23, 4);
- this.pos += 4;
- return val;
- },
- readDouble: function() {
- var val = ieee754.read(this.buf, this.pos, true, 52, 8);
- this.pos += 8;
- return val;
- },
- readVarint: function(isSigned) {
- var buf = this.buf,
- val, b;
- b = buf[this.pos++]; val = b & 0x7f; if (b < 0x80) return val;
- b = buf[this.pos++]; val |= (b & 0x7f) << 7; if (b < 0x80) return val;
- b = buf[this.pos++]; val |= (b & 0x7f) << 14; if (b < 0x80) return val;
- b = buf[this.pos++]; val |= (b & 0x7f) << 21; if (b < 0x80) return val;
- b = buf[this.pos]; val |= (b & 0x0f) << 28;
- return readVarintRemainder(val, isSigned, this);
- },
- readVarint64: function() {
- return this.readVarint(true);
- },
- readSVarint: function() {
- var num = this.readVarint();
- return num % 2 === 1 ? (num + 1) / -2 : num / 2;
- },
- readBoolean: function() {
- return Boolean(this.readVarint());
- },
- readString: function() {
- var end = this.readVarint() + this.pos,
- str = readUtf8(this.buf, this.pos, end);
- this.pos = end;
- return str;
- },
- readBytes: function() {
- var end = this.readVarint() + this.pos,
- buffer = this.buf.subarray(this.pos, end);
- this.pos = end;
- return buffer;
- },
- readPackedVarint: function(arr, isSigned) {
- var end = readPackedEnd(this);
- arr = arr || [];
- while (this.pos < end) arr.push(this.readVarint(isSigned));
- return arr;
- },
- readPackedSVarint: function(arr) {
- var end = readPackedEnd(this);
- arr = arr || [];
- while (this.pos < end) arr.push(this.readSVarint());
- return arr;
- },
- readPackedBoolean: function(arr) {
- var end = readPackedEnd(this);
- arr = arr || [];
- while (this.pos < end) arr.push(this.readBoolean());
- return arr;
- },
- readPackedFloat: function(arr) {
- var end = readPackedEnd(this);
- arr = arr || [];
- while (this.pos < end) arr.push(this.readFloat());
- return arr;
- },
- readPackedDouble: function(arr) {
- var end = readPackedEnd(this);
- arr = arr || [];
- while (this.pos < end) arr.push(this.readDouble());
- return arr;
- },
- readPackedFixed32: function(arr) {
- var end = readPackedEnd(this);
- arr = arr || [];
- while (this.pos < end) arr.push(this.readFixed32());
- return arr;
- },
- readPackedSFixed32: function(arr) {
- var end = readPackedEnd(this);
- arr = arr || [];
- while (this.pos < end) arr.push(this.readSFixed32());
- return arr;
- },
- readPackedFixed64: function(arr) {
- var end = readPackedEnd(this);
- arr = arr || [];
- while (this.pos < end) arr.push(this.readFixed64());
- return arr;
- },
- readPackedSFixed64: function(arr) {
- var end = readPackedEnd(this);
- arr = arr || [];
- while (this.pos < end) arr.push(this.readSFixed64());
- return arr;
- },
- skip: function(val) {
- var type = val & 0x7;
- if (type === Pbf.Varint) while (this.buf[this.pos++] > 0x7f) {}
- else if (type === Pbf.Bytes) this.pos = this.readVarint() + this.pos;
- else if (type === Pbf.Fixed32) this.pos += 4;
- else if (type === Pbf.Fixed64) this.pos += 8;
- else throw new Error('Unimplemented type: ' + type);
- },
- writeTag: function(tag, type) {
- this.writeVarint((tag << 3) | type);
- },
- realloc: function(min) {
- var length = this.length || 16;
- while (length < this.pos + min) length *= 2;
- if (length !== this.length) {
- var buf = new Uint8Array(length);
- buf.set(this.buf);
- this.buf = buf;
- this.length = length;
- }
- },
- finish: function() {
- this.length = this.pos;
- this.pos = 0;
- return this.buf.subarray(0, this.length);
- },
- writeFixed32: function(val) {
- this.realloc(4);
- writeInt32(this.buf, val, this.pos);
- this.pos += 4;
- },
- writeSFixed32: function(val) {
- this.realloc(4);
- writeInt32(this.buf, val, this.pos);
- this.pos += 4;
- },
- writeFixed64: function(val) {
- this.realloc(8);
- writeInt32(this.buf, val & -1, this.pos);
- writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4);
- this.pos += 8;
- },
- writeSFixed64: function(val) {
- this.realloc(8);
- writeInt32(this.buf, val & -1, this.pos);
- writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4);
- this.pos += 8;
- },
- writeVarint: function(val) {
- val = +val || 0;
- if (val > 0xfffffff || val < 0) {
- writeBigVarint(val, this);
- return;
- }
- this.realloc(4);
- this.buf[this.pos++] = val & 0x7f | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return;
- this.buf[this.pos++] = ((val >>>= 7) & 0x7f) | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return;
- this.buf[this.pos++] = ((val >>>= 7) & 0x7f) | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return;
- this.buf[this.pos++] = (val >>> 7) & 0x7f;
- },
- writeSVarint: function(val) {
- this.writeVarint(val < 0 ? -val * 2 - 1 : val * 2);
- },
- writeBoolean: function(val) {
- this.writeVarint(Boolean(val));
- },
- writeString: function(str) {
- str = String(str);
- this.realloc(str.length * 4);
- this.pos++;
- var startPos = this.pos;
- this.pos = writeUtf8(this.buf, str, this.pos);
- var len = this.pos - startPos;
- if (len >= 0x80) makeRoomForExtraLength(startPos, len, this);
- this.pos = startPos - 1;
- this.writeVarint(len);
- this.pos += len;
- },
- writeFloat: function(val) {
- this.realloc(4);
- ieee754.write(this.buf, val, this.pos, true, 23, 4);
- this.pos += 4;
- },
- writeDouble: function(val) {
- this.realloc(8);
- ieee754.write(this.buf, val, this.pos, true, 52, 8);
- this.pos += 8;
- },
- writeBytes: function(buffer) {
- var len = buffer.length;
- this.writeVarint(len);
- this.realloc(len);
- for (var i = 0; i < len; i++) this.buf[this.pos++] = buffer[i];
- },
- writeRawMessage: function(fn, obj) {
- this.pos++;
- var startPos = this.pos;
- fn(obj, this);
- var len = this.pos - startPos;
- if (len >= 0x80) makeRoomForExtraLength(startPos, len, this);
- this.pos = startPos - 1;
- this.writeVarint(len);
- this.pos += len;
- },
- writeMessage: function(tag, fn, obj) {
- this.writeTag(tag, Pbf.Bytes);
- this.writeRawMessage(fn, obj);
- },
- writePackedVarint: function(tag, arr) { this.writeMessage(tag, writePackedVarint, arr); },
- writePackedSVarint: function(tag, arr) { this.writeMessage(tag, writePackedSVarint, arr); },
- writePackedBoolean: function(tag, arr) { this.writeMessage(tag, writePackedBoolean, arr); },
- writePackedFloat: function(tag, arr) { this.writeMessage(tag, writePackedFloat, arr); },
- writePackedDouble: function(tag, arr) { this.writeMessage(tag, writePackedDouble, arr); },
- writePackedFixed32: function(tag, arr) { this.writeMessage(tag, writePackedFixed32, arr); },
- writePackedSFixed32: function(tag, arr) { this.writeMessage(tag, writePackedSFixed32, arr); },
- writePackedFixed64: function(tag, arr) { this.writeMessage(tag, writePackedFixed64, arr); },
- writePackedSFixed64: function(tag, arr) { this.writeMessage(tag, writePackedSFixed64, arr); },
- writeBytesField: function(tag, buffer) {
- this.writeTag(tag, Pbf.Bytes);
- this.writeBytes(buffer);
- },
- writeFixed32Field: function(tag, val) {
- this.writeTag(tag, Pbf.Fixed32);
- this.writeFixed32(val);
- },
- writeSFixed32Field: function(tag, val) {
- this.writeTag(tag, Pbf.Fixed32);
- this.writeSFixed32(val);
- },
- writeFixed64Field: function(tag, val) {
- this.writeTag(tag, Pbf.Fixed64);
- this.writeFixed64(val);
- },
- writeSFixed64Field: function(tag, val) {
- this.writeTag(tag, Pbf.Fixed64);
- this.writeSFixed64(val);
- },
- writeVarintField: function(tag, val) {
- this.writeTag(tag, Pbf.Varint);
- this.writeVarint(val);
- },
- writeSVarintField: function(tag, val) {
- this.writeTag(tag, Pbf.Varint);
- this.writeSVarint(val);
- },
- writeStringField: function(tag, str) {
- this.writeTag(tag, Pbf.Bytes);
- this.writeString(str);
- },
- writeFloatField: function(tag, val) {
- this.writeTag(tag, Pbf.Fixed32);
- this.writeFloat(val);
- },
- writeDoubleField: function(tag, val) {
- this.writeTag(tag, Pbf.Fixed64);
- this.writeDouble(val);
- },
- writeBooleanField: function(tag, val) {
- this.writeVarintField(tag, Boolean(val));
- }
- };
- function readVarintRemainder(l, s, p) {
- var buf = p.buf,
- h, b;
- b = buf[p.pos++]; h = (b & 0x70) >> 4; if (b < 0x80) return toNum(l, h, s);
- b = buf[p.pos++]; h |= (b & 0x7f) << 3; if (b < 0x80) return toNum(l, h, s);
- b = buf[p.pos++]; h |= (b & 0x7f) << 10; if (b < 0x80) return toNum(l, h, s);
- b = buf[p.pos++]; h |= (b & 0x7f) << 17; if (b < 0x80) return toNum(l, h, s);
- b = buf[p.pos++]; h |= (b & 0x7f) << 24; if (b < 0x80) return toNum(l, h, s);
- b = buf[p.pos++]; h |= (b & 0x01) << 31; if (b < 0x80) return toNum(l, h, s);
- throw new Error('Expected varint not more than 10 bytes');
- }
- function readPackedEnd(pbf) {
- return pbf.type === Pbf.Bytes ?
- pbf.readVarint() + pbf.pos : pbf.pos + 1;
- }
- function toNum(low, high, isSigned) {
- if (isSigned) {
- return high * 0x100000000 + (low >>> 0);
- }
- return ((high >>> 0) * 0x100000000) + (low >>> 0);
- }
- function writeBigVarint(val, pbf) {
- var low, high;
- if (val >= 0) {
- low = (val % 0x100000000) | 0;
- high = (val / 0x100000000) | 0;
- } else {
- low = ~(-val % 0x100000000);
- high = ~(-val / 0x100000000);
- if (low ^ 0xffffffff) {
- low = (low + 1) | 0;
- } else {
- low = 0;
- high = (high + 1) | 0;
- }
- }
- if (val >= 0x10000000000000000 || val < -0x10000000000000000) {
- throw new Error('Given varint doesn\'t fit into 10 bytes');
- }
- pbf.realloc(10);
- writeBigVarintLow(low, high, pbf);
- writeBigVarintHigh(high, pbf);
- }
- function writeBigVarintLow(low, high, pbf) {
- pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;
- pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;
- pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;
- pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;
- pbf.buf[pbf.pos] = low & 0x7f;
- }
- function writeBigVarintHigh(high, pbf) {
- var lsb = (high & 0x07) << 4;
- pbf.buf[pbf.pos++] |= lsb | ((high >>>= 3) ? 0x80 : 0); if (!high) return;
- pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;
- pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;
- pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;
- pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;
- pbf.buf[pbf.pos++] = high & 0x7f;
- }
- function makeRoomForExtraLength(startPos, len, pbf) {
- var extraLen =
- len <= 0x3fff ? 1 :
- len <= 0x1fffff ? 2 :
- len <= 0xfffffff ? 3 : Math.ceil(Math.log(len) / (Math.LN2 * 7));
- pbf.realloc(extraLen);
- for (var i = pbf.pos - 1; i >= startPos; i--) pbf.buf[i + extraLen] = pbf.buf[i];
- }
- function writePackedVarint(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeVarint(arr[i]); }
- function writePackedSVarint(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeSVarint(arr[i]); }
- function writePackedFloat(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeFloat(arr[i]); }
- function writePackedDouble(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeDouble(arr[i]); }
- function writePackedBoolean(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeBoolean(arr[i]); }
- function writePackedFixed32(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeFixed32(arr[i]); }
- function writePackedSFixed32(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeSFixed32(arr[i]); }
- function writePackedFixed64(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeFixed64(arr[i]); }
- function writePackedSFixed64(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeSFixed64(arr[i]); }
- function readUInt32(buf, pos) {
- return ((buf[pos]) |
- (buf[pos + 1] << 8) |
- (buf[pos + 2] << 16)) +
- (buf[pos + 3] * 0x1000000);
- }
- function writeInt32(buf, val, pos) {
- buf[pos] = val;
- buf[pos + 1] = (val >>> 8);
- buf[pos + 2] = (val >>> 16);
- buf[pos + 3] = (val >>> 24);
- }
- function readInt32(buf, pos) {
- return ((buf[pos]) |
- (buf[pos + 1] << 8) |
- (buf[pos + 2] << 16)) +
- (buf[pos + 3] << 24);
- }
- function readUtf8(buf, pos, end) {
- var str = '';
- var i = pos;
- while (i < end) {
- var b0 = buf[i];
- var c = null;
- var bytesPerSequence =
- b0 > 0xEF ? 4 :
- b0 > 0xDF ? 3 :
- b0 > 0xBF ? 2 : 1;
- if (i + bytesPerSequence > end) break;
- var b1, b2, b3;
- if (bytesPerSequence === 1) {
- if (b0 < 0x80) {
- c = b0;
- }
- } else if (bytesPerSequence === 2) {
- b1 = buf[i + 1];
- if ((b1 & 0xC0) === 0x80) {
- c = (b0 & 0x1F) << 0x6 | (b1 & 0x3F);
- if (c <= 0x7F) {
- c = null;
- }
- }
- } else if (bytesPerSequence === 3) {
- b1 = buf[i + 1];
- b2 = buf[i + 2];
- if ((b1 & 0xC0) === 0x80 && (b2 & 0xC0) === 0x80) {
- c = (b0 & 0xF) << 0xC | (b1 & 0x3F) << 0x6 | (b2 & 0x3F);
- if (c <= 0x7FF || (c >= 0xD800 && c <= 0xDFFF)) {
- c = null;
- }
- }
- } else if (bytesPerSequence === 4) {
- b1 = buf[i + 1];
- b2 = buf[i + 2];
- b3 = buf[i + 3];
- if ((b1 & 0xC0) === 0x80 && (b2 & 0xC0) === 0x80 && (b3 & 0xC0) === 0x80) {
- c = (b0 & 0xF) << 0x12 | (b1 & 0x3F) << 0xC | (b2 & 0x3F) << 0x6 | (b3 & 0x3F);
- if (c <= 0xFFFF || c >= 0x110000) {
- c = null;
- }
- }
- }
- if (c === null) {
- c = 0xFFFD;
- bytesPerSequence = 1;
- } else if (c > 0xFFFF) {
- c -= 0x10000;
- str += String.fromCharCode(c >>> 10 & 0x3FF | 0xD800);
- c = 0xDC00 | c & 0x3FF;
- }
- str += String.fromCharCode(c);
- i += bytesPerSequence;
- }
- return str;
- }
- function writeUtf8(buf, str, pos) {
- for (var i = 0, c, lead; i < str.length; i++) {
- c = str.charCodeAt(i);
- if (c > 0xD7FF && c < 0xE000) {
- if (lead) {
- if (c < 0xDC00) {
- buf[pos++] = 0xEF;
- buf[pos++] = 0xBF;
- buf[pos++] = 0xBD;
- lead = c;
- continue;
- } else {
- c = lead - 0xD800 << 10 | c - 0xDC00 | 0x10000;
- lead = null;
- }
- } else {
- if (c > 0xDBFF || (i + 1 === str.length)) {
- buf[pos++] = 0xEF;
- buf[pos++] = 0xBF;
- buf[pos++] = 0xBD;
- } else {
- lead = c;
- }
- continue;
- }
- } else if (lead) {
- buf[pos++] = 0xEF;
- buf[pos++] = 0xBF;
- buf[pos++] = 0xBD;
- lead = null;
- }
- if (c < 0x80) {
- buf[pos++] = c;
- } else {
- if (c < 0x800) {
- buf[pos++] = c >> 0x6 | 0xC0;
- } else {
- if (c < 0x10000) {
- buf[pos++] = c >> 0xC | 0xE0;
- } else {
- buf[pos++] = c >> 0x12 | 0xF0;
- buf[pos++] = c >> 0xC & 0x3F | 0x80;
- }
- buf[pos++] = c >> 0x6 & 0x3F | 0x80;
- }
- buf[pos++] = c & 0x3F | 0x80;
- }
- }
- return pos;
- }
- exports['default'] = pbf;
- }((this.PBF = this.PBF || {})));}).call(ol.ext);
- ol.ext.PBF = ol.ext.PBF.default;
- goog.provide('ol.render.Feature');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.extent');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.flat.center');
- goog.require('ol.geom.flat.interiorpoint');
- goog.require('ol.geom.flat.interpolate');
- goog.require('ol.geom.flat.transform');
- goog.require('ol.transform');
- /**
- * Lightweight, read-only, {@link ol.Feature} and {@link ol.geom.Geometry} like
- * structure, optimized for vector tile rendering and styling. Geometry access
- * through the API is limited to getting the type and extent of the geometry.
- *
- * @constructor
- * @param {ol.geom.GeometryType} type Geometry type.
- * @param {Array.<number>} flatCoordinates Flat coordinates. These always need
- * to be right-handed for polygons.
- * @param {Array.<number>|Array.<Array.<number>>} ends Ends or Endss.
- * @param {Object.<string, *>} properties Properties.
- * @param {number|string|undefined} id Feature id.
- */
- ol.render.Feature = function(type, flatCoordinates, ends, properties, id) {
- /**
- * @private
- * @type {ol.Extent|undefined}
- */
- this.extent_;
- /**
- * @private
- * @type {number|string|undefined}
- */
- this.id_ = id;
- /**
- * @private
- * @type {ol.geom.GeometryType}
- */
- this.type_ = type;
- /**
- * @private
- * @type {Array.<number>}
- */
- this.flatCoordinates_ = flatCoordinates;
- /**
- * @private
- * @type {Array.<number>}
- */
- this.flatInteriorPoints_ = null;
- /**
- * @private
- * @type {Array.<number>}
- */
- this.flatMidpoints_ = null;
- /**
- * @private
- * @type {Array.<number>|Array.<Array.<number>>}
- */
- this.ends_ = ends;
- /**
- * @private
- * @type {Object.<string, *>}
- */
- this.properties_ = properties;
- /**
- * @private
- * @type {ol.Transform}
- */
- this.tmpTransform_ = ol.transform.create();
- };
- /**
- * Get a feature property by its key.
- * @param {string} key Key
- * @return {*} Value for the requested key.
- * @api
- */
- ol.render.Feature.prototype.get = function(key) {
- return this.properties_[key];
- };
- /**
- * @return {Array.<number>|Array.<Array.<number>>} Ends or endss.
- */
- ol.render.Feature.prototype.getEnds =
- ol.render.Feature.prototype.getEndss = function() {
- return this.ends_;
- };
- /**
- * Get the extent of this feature's geometry.
- * @return {ol.Extent} Extent.
- * @api
- */
- ol.render.Feature.prototype.getExtent = function() {
- if (!this.extent_) {
- this.extent_ = this.type_ === ol.geom.GeometryType.POINT ?
- ol.extent.createOrUpdateFromCoordinate(this.flatCoordinates_) :
- ol.extent.createOrUpdateFromFlatCoordinates(
- this.flatCoordinates_, 0, this.flatCoordinates_.length, 2);
- }
- return this.extent_;
- };
- /**
- * @return {Array.<number>} Flat interior points.
- */
- ol.render.Feature.prototype.getFlatInteriorPoint = function() {
- if (!this.flatInteriorPoints_) {
- var flatCenter = ol.extent.getCenter(this.getExtent());
- this.flatInteriorPoints_ = ol.geom.flat.interiorpoint.linearRings(
- this.flatCoordinates_, 0, this.ends_, 2, flatCenter, 0);
- }
- return this.flatInteriorPoints_;
- };
- /**
- * @return {Array.<number>} Flat interior points.
- */
- ol.render.Feature.prototype.getFlatInteriorPoints = function() {
- if (!this.flatInteriorPoints_) {
- var flatCenters = ol.geom.flat.center.linearRingss(
- this.flatCoordinates_, 0, this.ends_, 2);
- this.flatInteriorPoints_ = ol.geom.flat.interiorpoint.linearRingss(
- this.flatCoordinates_, 0, this.ends_, 2, flatCenters);
- }
- return this.flatInteriorPoints_;
- };
- /**
- * @return {Array.<number>} Flat midpoint.
- */
- ol.render.Feature.prototype.getFlatMidpoint = function() {
- if (!this.flatMidpoints_) {
- this.flatMidpoints_ = ol.geom.flat.interpolate.lineString(
- this.flatCoordinates_, 0, this.flatCoordinates_.length, 2, 0.5);
- }
- return this.flatMidpoints_;
- };
- /**
- * @return {Array.<number>} Flat midpoints.
- */
- ol.render.Feature.prototype.getFlatMidpoints = function() {
- if (!this.flatMidpoints_) {
- this.flatMidpoints_ = [];
- var flatCoordinates = this.flatCoordinates_;
- var offset = 0;
- var ends = this.ends_;
- for (var i = 0, ii = ends.length; i < ii; ++i) {
- var end = ends[i];
- var midpoint = ol.geom.flat.interpolate.lineString(
- flatCoordinates, offset, end, 2, 0.5);
- ol.array.extend(this.flatMidpoints_, midpoint);
- offset = end;
- }
- }
- return this.flatMidpoints_;
- };
- /**
- * Get the feature identifier. This is a stable identifier for the feature and
- * is set when reading data from a remote source.
- * @return {number|string|undefined} Id.
- * @api
- */
- ol.render.Feature.prototype.getId = function() {
- return this.id_;
- };
- /**
- * @return {Array.<number>} Flat coordinates.
- */
- ol.render.Feature.prototype.getOrientedFlatCoordinates = function() {
- return this.flatCoordinates_;
- };
- /**
- * @return {Array.<number>} Flat coordinates.
- */
- ol.render.Feature.prototype.getFlatCoordinates =
- ol.render.Feature.prototype.getOrientedFlatCoordinates;
- /**
- * For API compatibility with {@link ol.Feature}, this method is useful when
- * determining the geometry type in style function (see {@link #getType}).
- * @return {ol.render.Feature} Feature.
- * @api
- */
- ol.render.Feature.prototype.getGeometry = function() {
- return this;
- };
- /**
- * Get the feature properties.
- * @return {Object.<string, *>} Feature properties.
- * @api
- */
- ol.render.Feature.prototype.getProperties = function() {
- return this.properties_;
- };
- /**
- * Get the feature for working with its geometry.
- * @return {ol.render.Feature} Feature.
- */
- ol.render.Feature.prototype.getSimplifiedGeometry =
- ol.render.Feature.prototype.getGeometry;
- /**
- * @return {number} Stride.
- */
- ol.render.Feature.prototype.getStride = function() {
- return 2;
- };
- /**
- * @return {undefined}
- */
- ol.render.Feature.prototype.getStyleFunction = ol.nullFunction;
- /**
- * Get the type of this feature's geometry.
- * @return {ol.geom.GeometryType} Geometry type.
- * @api
- */
- ol.render.Feature.prototype.getType = function() {
- return this.type_;
- };
- /**
- * Transform geometry coordinates from tile pixel space to projected.
- * The SRS of the source and destination are expected to be the same.
- *
- * @param {ol.ProjectionLike} source The current projection
- * @param {ol.ProjectionLike} destination The desired projection.
- */
- ol.render.Feature.prototype.transform = function(source, destination) {
- var pixelExtent = source.getExtent();
- var projectedExtent = source.getWorldExtent();
- var scale = ol.extent.getHeight(projectedExtent) / ol.extent.getHeight(pixelExtent);
- var transform = this.tmpTransform_;
- ol.transform.compose(transform,
- projectedExtent[0], projectedExtent[3],
- scale, -scale, 0,
- 0, 0);
- ol.geom.flat.transform.transform2D(this.flatCoordinates_, 0, this.flatCoordinates_.length, 2,
- transform, this.flatCoordinates_);
- };
- //FIXME Implement projection handling
- goog.provide('ol.format.MVT');
- goog.require('ol');
- goog.require('ol.asserts');
- goog.require('ol.ext.PBF');
- goog.require('ol.format.Feature');
- goog.require('ol.format.FormatType');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.LineString');
- goog.require('ol.geom.MultiLineString');
- goog.require('ol.geom.MultiPoint');
- goog.require('ol.geom.MultiPolygon');
- goog.require('ol.geom.Point');
- goog.require('ol.geom.Polygon');
- goog.require('ol.geom.flat.orient');
- goog.require('ol.proj.Projection');
- goog.require('ol.proj.Units');
- goog.require('ol.render.Feature');
- /**
- * @classdesc
- * Feature format for reading data in the Mapbox MVT format.
- *
- * @constructor
- * @extends {ol.format.Feature}
- * @param {olx.format.MVTOptions=} opt_options Options.
- * @api
- */
- ol.format.MVT = function(opt_options) {
- ol.format.Feature.call(this);
- var options = opt_options ? opt_options : {};
- /**
- * @type {ol.proj.Projection}
- */
- this.defaultDataProjection = new ol.proj.Projection({
- code: 'EPSG:3857',
- units: ol.proj.Units.TILE_PIXELS
- });
- /**
- * @private
- * @type {function((ol.geom.Geometry|Object.<string,*>)=)|
- * function(ol.geom.GeometryType,Array.<number>,
- * (Array.<number>|Array.<Array.<number>>),Object.<string,*>,number)}
- */
- this.featureClass_ = options.featureClass ?
- options.featureClass : ol.render.Feature;
- /**
- * @private
- * @type {string|undefined}
- */
- this.geometryName_ = options.geometryName;
- /**
- * @private
- * @type {string}
- */
- this.layerName_ = options.layerName ? options.layerName : 'layer';
- /**
- * @private
- * @type {Array.<string>}
- */
- this.layers_ = options.layers ? options.layers : null;
- /**
- * @private
- * @type {ol.Extent}
- */
- this.extent_ = null;
- };
- ol.inherits(ol.format.MVT, ol.format.Feature);
- /**
- * Reader callbacks for parsing the PBF.
- * @type {Object.<string, function(number, Object, ol.ext.PBF)>}
- */
- ol.format.MVT.pbfReaders_ = {
- layers: function(tag, layers, pbf) {
- if (tag === 3) {
- var layer = {
- keys: [],
- values: [],
- features: []
- };
- var end = pbf.readVarint() + pbf.pos;
- pbf.readFields(ol.format.MVT.pbfReaders_.layer, layer, end);
- layer.length = layer.features.length;
- if (layer.length) {
- layers[layer.name] = layer;
- }
- }
- },
- layer: function(tag, layer, pbf) {
- if (tag === 15) {
- layer.version = pbf.readVarint();
- } else if (tag === 1) {
- layer.name = pbf.readString();
- } else if (tag === 5) {
- layer.extent = pbf.readVarint();
- } else if (tag === 2) {
- layer.features.push(pbf.pos);
- } else if (tag === 3) {
- layer.keys.push(pbf.readString());
- } else if (tag === 4) {
- var value = null;
- var end = pbf.readVarint() + pbf.pos;
- while (pbf.pos < end) {
- tag = pbf.readVarint() >> 3;
- value = tag === 1 ? pbf.readString() :
- tag === 2 ? pbf.readFloat() :
- tag === 3 ? pbf.readDouble() :
- tag === 4 ? pbf.readVarint64() :
- tag === 5 ? pbf.readVarint() :
- tag === 6 ? pbf.readSVarint() :
- tag === 7 ? pbf.readBoolean() : null;
- }
- layer.values.push(value);
- }
- },
- feature: function(tag, feature, pbf) {
- if (tag == 1) {
- feature.id = pbf.readVarint();
- } else if (tag == 2) {
- var end = pbf.readVarint() + pbf.pos;
- while (pbf.pos < end) {
- var key = feature.layer.keys[pbf.readVarint()];
- var value = feature.layer.values[pbf.readVarint()];
- feature.properties[key] = value;
- }
- } else if (tag == 3) {
- feature.type = pbf.readVarint();
- } else if (tag == 4) {
- feature.geometry = pbf.pos;
- }
- }
- };
- /**
- * Read a raw feature from the pbf offset stored at index `i` in the raw layer.
- * @suppress {missingProperties}
- * @private
- * @param {ol.ext.PBF} pbf PBF.
- * @param {Object} layer Raw layer.
- * @param {number} i Index of the feature in the raw layer's `features` array.
- * @return {Object} Raw feature.
- */
- ol.format.MVT.readRawFeature_ = function(pbf, layer, i) {
- pbf.pos = layer.features[i];
- var end = pbf.readVarint() + pbf.pos;
- var feature = {
- layer: layer,
- type: 0,
- properties: {}
- };
- pbf.readFields(ol.format.MVT.pbfReaders_.feature, feature, end);
- return feature;
- };
- /**
- * Read the raw geometry from the pbf offset stored in a raw feature's geometry
- * proeprty.
- * @suppress {missingProperties}
- * @private
- * @param {ol.ext.PBF} pbf PBF.
- * @param {Object} feature Raw feature.
- * @param {Array.<number>} flatCoordinates Array to store flat coordinates in.
- * @param {Array.<number>} ends Array to store ends in.
- */
- ol.format.MVT.readRawGeometry_ = function(pbf, feature, flatCoordinates, ends) {
- pbf.pos = feature.geometry;
- var end = pbf.readVarint() + pbf.pos;
- var cmd = 1;
- var length = 0;
- var x = 0;
- var y = 0;
- var coordsLen = 0;
- var currentEnd = 0;
- while (pbf.pos < end) {
- if (!length) {
- var cmdLen = pbf.readVarint();
- cmd = cmdLen & 0x7;
- length = cmdLen >> 3;
- }
- length--;
- if (cmd === 1 || cmd === 2) {
- x += pbf.readSVarint();
- y += pbf.readSVarint();
- if (cmd === 1) { // moveTo
- if (coordsLen > currentEnd) {
- ends.push(coordsLen);
- currentEnd = coordsLen;
- }
- }
- flatCoordinates.push(x, y);
- coordsLen += 2;
- } else if (cmd === 7) {
- if (coordsLen > currentEnd) {
- // close polygon
- flatCoordinates.push(
- flatCoordinates[currentEnd], flatCoordinates[currentEnd + 1]);
- coordsLen += 2;
- }
- } else {
- ol.asserts.assert(false, 59); // Invalid command found in the PBF
- }
- }
- if (coordsLen > currentEnd) {
- ends.push(coordsLen);
- currentEnd = coordsLen;
- }
- };
- /**
- * @suppress {missingProperties}
- * @private
- * @param {number} type The raw feature's geometry type
- * @param {number} numEnds Number of ends of the flat coordinates of the
- * geometry.
- * @return {ol.geom.GeometryType} The geometry type.
- */
- ol.format.MVT.getGeometryType_ = function(type, numEnds) {
- /** @type {ol.geom.GeometryType} */
- var geometryType;
- if (type === 1) {
- geometryType = numEnds === 1 ?
- ol.geom.GeometryType.POINT : ol.geom.GeometryType.MULTI_POINT;
- } else if (type === 2) {
- geometryType = numEnds === 1 ?
- ol.geom.GeometryType.LINE_STRING :
- ol.geom.GeometryType.MULTI_LINE_STRING;
- } else if (type === 3) {
- geometryType = ol.geom.GeometryType.POLYGON;
- // MultiPolygon not relevant for rendering - winding order determines
- // outer rings of polygons.
- }
- return geometryType;
- };
- /**
- * @private
- * @param {ol.ext.PBF} pbf PBF
- * @param {Object} rawFeature Raw Mapbox feature.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {ol.Feature|ol.render.Feature} Feature.
- */
- ol.format.MVT.prototype.createFeature_ = function(pbf, rawFeature, opt_options) {
- var type = rawFeature.type;
- if (type === 0) {
- return null;
- }
- var feature;
- var id = rawFeature.id;
- var values = rawFeature.properties;
- values[this.layerName_] = rawFeature.layer.name;
- var flatCoordinates = [];
- var ends = [];
- ol.format.MVT.readRawGeometry_(pbf, rawFeature, flatCoordinates, ends);
- var geometryType = ol.format.MVT.getGeometryType_(type, ends.length);
- if (this.featureClass_ === ol.render.Feature) {
- feature = new this.featureClass_(geometryType, flatCoordinates, ends, values, id);
- } else {
- var geom;
- if (geometryType == ol.geom.GeometryType.POLYGON) {
- var endss = [];
- var offset = 0;
- var prevEndIndex = 0;
- for (var i = 0, ii = ends.length; i < ii; ++i) {
- var end = ends[i];
- if (!ol.geom.flat.orient.linearRingIsClockwise(flatCoordinates, offset, end, 2)) {
- endss.push(ends.slice(prevEndIndex, i));
- prevEndIndex = i;
- }
- offset = end;
- }
- if (endss.length > 1) {
- ends = endss;
- geom = new ol.geom.MultiPolygon(null);
- } else {
- geom = new ol.geom.Polygon(null);
- }
- } else {
- geom = geometryType === ol.geom.GeometryType.POINT ? new ol.geom.Point(null) :
- geometryType === ol.geom.GeometryType.LINE_STRING ? new ol.geom.LineString(null) :
- geometryType === ol.geom.GeometryType.POLYGON ? new ol.geom.Polygon(null) :
- geometryType === ol.geom.GeometryType.MULTI_POINT ? new ol.geom.MultiPoint (null) :
- geometryType === ol.geom.GeometryType.MULTI_LINE_STRING ? new ol.geom.MultiLineString(null) :
- null;
- }
- geom.setFlatCoordinates(ol.geom.GeometryLayout.XY, flatCoordinates, ends);
- feature = new this.featureClass_();
- if (this.geometryName_) {
- feature.setGeometryName(this.geometryName_);
- }
- var geometry = ol.format.Feature.transformWithOptions(geom, false, this.adaptOptions(opt_options));
- feature.setGeometry(geometry);
- feature.setId(id);
- feature.setProperties(values);
- }
- return feature;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.format.MVT.prototype.getLastExtent = function() {
- return this.extent_;
- };
- /**
- * @inheritDoc
- */
- ol.format.MVT.prototype.getType = function() {
- return ol.format.FormatType.ARRAY_BUFFER;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.format.MVT.prototype.readFeatures = function(source, opt_options) {
- var layers = this.layers_;
- var pbf = new ol.ext.PBF(/** @type {ArrayBuffer} */ (source));
- var pbfLayers = pbf.readFields(ol.format.MVT.pbfReaders_.layers, {});
- /** @type {Array.<ol.Feature|ol.render.Feature>} */
- var features = [];
- var pbfLayer;
- for (var name in pbfLayers) {
- if (layers && layers.indexOf(name) == -1) {
- continue;
- }
- if(opt_options !== undefined){
- var needSourceLayerNames = opt_options.needSourceLayerNames;
- if(needSourceLayerNames !== undefined && needSourceLayerNames[name] === undefined){
- continue;
- }
- }
- pbfLayer = pbfLayers[name];
- var rawFeature;
- for (var i = 0, ii = pbfLayer.length; i < ii; ++i) {
- rawFeature = ol.format.MVT.readRawFeature_(pbf, pbfLayer, i);
- features.push(this.createFeature_(pbf, rawFeature));
- }
- this.extent_ = pbfLayer ? [0, 0, pbfLayer.extent, pbfLayer.extent] : null;
- }
- return features;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.format.MVT.prototype.readProjection = function(source) {
- return this.defaultDataProjection;
- };
- /**
- * Sets the layers that features will be read from.
- * @param {Array.<string>} layers Layers.
- * @api
- */
- ol.format.MVT.prototype.setLayers = function(layers) {
- this.layers_ = layers;
- };
- /**
- * Not implemented.
- * @override
- */
- ol.format.MVT.prototype.readFeature = function() {};
- /**
- * Not implemented.
- * @override
- */
- ol.format.MVT.prototype.readGeometry = function() {};
- /**
- * Not implemented.
- * @override
- */
- ol.format.MVT.prototype.writeFeature = function() {};
- /**
- * Not implemented.
- * @override
- */
- ol.format.MVT.prototype.writeGeometry = function() {};
- /**
- * Not implemented.
- * @override
- */
- ol.format.MVT.prototype.writeFeatures = function() {};
- // FIXME add typedef for stack state objects
- goog.provide('ol.format.OSMXML');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.Feature');
- goog.require('ol.format.Feature');
- goog.require('ol.format.XMLFeature');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.LineString');
- goog.require('ol.geom.Point');
- goog.require('ol.geom.Polygon');
- goog.require('ol.obj');
- goog.require('ol.proj');
- goog.require('ol.xml');
- /**
- * @classdesc
- * Feature format for reading data in the
- * [OSMXML format](http://wiki.openstreetmap.org/wiki/OSM_XML).
- *
- * @constructor
- * @extends {ol.format.XMLFeature}
- * @api
- */
- ol.format.OSMXML = function() {
- ol.format.XMLFeature.call(this);
- /**
- * @inheritDoc
- */
- this.defaultDataProjection = ol.proj.get('EPSG:4326');
- };
- ol.inherits(ol.format.OSMXML, ol.format.XMLFeature);
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.OSMXML.readNode_ = function(node, objectStack) {
- var options = /** @type {olx.format.ReadOptions} */ (objectStack[0]);
- var state = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- var id = node.getAttribute('id');
- /** @type {ol.Coordinate} */
- var coordinates = [
- parseFloat(node.getAttribute('lon')),
- parseFloat(node.getAttribute('lat'))
- ];
- state.nodes[id] = coordinates;
- var values = ol.xml.pushParseAndPop({
- tags: {}
- }, ol.format.OSMXML.NODE_PARSERS_, node, objectStack);
- if (!ol.obj.isEmpty(values.tags)) {
- var geometry = new ol.geom.Point(coordinates);
- ol.format.Feature.transformWithOptions(geometry, false, options);
- var feature = new ol.Feature(geometry);
- feature.setId(id);
- feature.setProperties(values.tags);
- state.features.push(feature);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.OSMXML.readWay_ = function(node, objectStack) {
- var id = node.getAttribute('id');
- var values = ol.xml.pushParseAndPop({
- id: id,
- ndrefs: [],
- tags: {}
- }, ol.format.OSMXML.WAY_PARSERS_, node, objectStack);
- var state = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- state.ways.push(values);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.OSMXML.readNd_ = function(node, objectStack) {
- var values = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- values.ndrefs.push(node.getAttribute('ref'));
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.OSMXML.readTag_ = function(node, objectStack) {
- var values = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- values.tags[node.getAttribute('k')] = node.getAttribute('v');
- };
- /**
- * @const
- * @private
- * @type {Array.<string>}
- */
- ol.format.OSMXML.NAMESPACE_URIS_ = [
- null
- ];
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.OSMXML.WAY_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.OSMXML.NAMESPACE_URIS_, {
- 'nd': ol.format.OSMXML.readNd_,
- 'tag': ol.format.OSMXML.readTag_
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.OSMXML.PARSERS_ = ol.xml.makeStructureNS(
- ol.format.OSMXML.NAMESPACE_URIS_, {
- 'node': ol.format.OSMXML.readNode_,
- 'way': ol.format.OSMXML.readWay_
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.OSMXML.NODE_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.OSMXML.NAMESPACE_URIS_, {
- 'tag': ol.format.OSMXML.readTag_
- });
- /**
- * Read all features from an OSM source.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {Array.<ol.Feature>} Features.
- * @api
- */
- ol.format.OSMXML.prototype.readFeatures;
- /**
- * @inheritDoc
- */
- ol.format.OSMXML.prototype.readFeaturesFromNode = function(node, opt_options) {
- var options = this.getReadOptions(node, opt_options);
- if (node.localName == 'osm') {
- var state = ol.xml.pushParseAndPop({
- nodes: {},
- ways: [],
- features: []
- }, ol.format.OSMXML.PARSERS_, node, [options]);
- // parse nodes in ways
- for (var j = 0; j < state.ways.length; j++) {
- var values = /** @type {Object} */ (state.ways[j]);
- /** @type {Array.<number>} */
- var flatCoordinates = [];
- for (var i = 0, ii = values.ndrefs.length; i < ii; i++) {
- var point = state.nodes[values.ndrefs[i]];
- ol.array.extend(flatCoordinates, point);
- }
- var geometry;
- if (values.ndrefs[0] == values.ndrefs[values.ndrefs.length - 1]) {
- // closed way
- geometry = new ol.geom.Polygon(null);
- geometry.setFlatCoordinates(ol.geom.GeometryLayout.XY, flatCoordinates,
- [flatCoordinates.length]);
- } else {
- geometry = new ol.geom.LineString(null);
- geometry.setFlatCoordinates(ol.geom.GeometryLayout.XY, flatCoordinates);
- }
- ol.format.Feature.transformWithOptions(geometry, false, options);
- var feature = new ol.Feature(geometry);
- feature.setId(values.id);
- feature.setProperties(values.tags);
- state.features.push(feature);
- }
- if (state.features) {
- return state.features;
- }
- }
- return [];
- };
- /**
- * Read the projection from an OSM source.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @return {ol.proj.Projection} Projection.
- * @api
- */
- ol.format.OSMXML.prototype.readProjection;
- /**
- * Not implemented.
- * @inheritDoc
- */
- ol.format.OSMXML.prototype.writeFeatureNode = function(feature, opt_options) {};
- /**
- * Not implemented.
- * @inheritDoc
- */
- ol.format.OSMXML.prototype.writeFeaturesNode = function(features, opt_options) {};
- /**
- * Not implemented.
- * @inheritDoc
- */
- ol.format.OSMXML.prototype.writeGeometryNode = function(geometry, opt_options) {};
- goog.provide('ol.format.XLink');
- /**
- * @const
- * @type {string}
- */
- ol.format.XLink.NAMESPACE_URI = 'http://www.w3.org/1999/xlink';
- /**
- * @param {Node} node Node.
- * @return {boolean|undefined} Boolean.
- */
- ol.format.XLink.readHref = function(node) {
- return node.getAttributeNS(ol.format.XLink.NAMESPACE_URI, 'href');
- };
- goog.provide('ol.format.XML');
- goog.require('ol.xml');
- /**
- * @classdesc
- * Generic format for reading non-feature XML data
- *
- * @constructor
- * @abstract
- * @struct
- */
- ol.format.XML = function() {
- };
- /**
- * @param {Document|Node|string} source Source.
- * @return {Object} The parsed result.
- */
- ol.format.XML.prototype.read = function(source) {
- if (ol.xml.isDocument(source)) {
- return this.readFromDocument(/** @type {Document} */ (source));
- } else if (ol.xml.isNode(source)) {
- return this.readFromNode(/** @type {Node} */ (source));
- } else if (typeof source === 'string') {
- var doc = ol.xml.parse(source);
- return this.readFromDocument(doc);
- } else {
- return null;
- }
- };
- /**
- * @abstract
- * @param {Document} doc Document.
- * @return {Object} Object
- */
- ol.format.XML.prototype.readFromDocument = function(doc) {};
- /**
- * @abstract
- * @param {Node} node Node.
- * @return {Object} Object
- */
- ol.format.XML.prototype.readFromNode = function(node) {};
- goog.provide('ol.format.OWS');
- goog.require('ol');
- goog.require('ol.format.XLink');
- goog.require('ol.format.XML');
- goog.require('ol.format.XSD');
- goog.require('ol.xml');
- /**
- * @constructor
- * @extends {ol.format.XML}
- */
- ol.format.OWS = function() {
- ol.format.XML.call(this);
- };
- ol.inherits(ol.format.OWS, ol.format.XML);
- /**
- * @inheritDoc
- */
- ol.format.OWS.prototype.readFromDocument = function(doc) {
- for (var n = doc.firstChild; n; n = n.nextSibling) {
- if (n.nodeType == Node.ELEMENT_NODE) {
- return this.readFromNode(n);
- }
- }
- return null;
- };
- /**
- * @inheritDoc
- */
- ol.format.OWS.prototype.readFromNode = function(node) {
- var owsObject = ol.xml.pushParseAndPop({},
- ol.format.OWS.PARSERS_, node, []);
- return owsObject ? owsObject : null;
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} The address.
- */
- ol.format.OWS.readAddress_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop({},
- ol.format.OWS.ADDRESS_PARSERS_, node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} The values.
- */
- ol.format.OWS.readAllowedValues_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop({},
- ol.format.OWS.ALLOWED_VALUES_PARSERS_, node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} The constraint.
- */
- ol.format.OWS.readConstraint_ = function(node, objectStack) {
- var name = node.getAttribute('name');
- if (!name) {
- return undefined;
- }
- return ol.xml.pushParseAndPop({'name': name},
- ol.format.OWS.CONSTRAINT_PARSERS_, node,
- objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} The contact info.
- */
- ol.format.OWS.readContactInfo_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop({},
- ol.format.OWS.CONTACT_INFO_PARSERS_, node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} The DCP.
- */
- ol.format.OWS.readDcp_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop({},
- ol.format.OWS.DCP_PARSERS_, node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} The GET object.
- */
- ol.format.OWS.readGet_ = function(node, objectStack) {
- var href = ol.format.XLink.readHref(node);
- if (!href) {
- return undefined;
- }
- return ol.xml.pushParseAndPop({'href': href},
- ol.format.OWS.REQUEST_METHOD_PARSERS_, node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} The HTTP object.
- */
- ol.format.OWS.readHttp_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop({}, ol.format.OWS.HTTP_PARSERS_,
- node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} The operation.
- */
- ol.format.OWS.readOperation_ = function(node, objectStack) {
- var name = node.getAttribute('name');
- var value = ol.xml.pushParseAndPop({},
- ol.format.OWS.OPERATION_PARSERS_, node, objectStack);
- if (!value) {
- return undefined;
- }
- var object = /** @type {Object} */
- (objectStack[objectStack.length - 1]);
- object[name] = value;
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} The operations metadata.
- */
- ol.format.OWS.readOperationsMetadata_ = function(node,
- objectStack) {
- return ol.xml.pushParseAndPop({},
- ol.format.OWS.OPERATIONS_METADATA_PARSERS_, node,
- objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} The phone.
- */
- ol.format.OWS.readPhone_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop({},
- ol.format.OWS.PHONE_PARSERS_, node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} The service identification.
- */
- ol.format.OWS.readServiceIdentification_ = function(node,
- objectStack) {
- return ol.xml.pushParseAndPop(
- {}, ol.format.OWS.SERVICE_IDENTIFICATION_PARSERS_, node,
- objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} The service contact.
- */
- ol.format.OWS.readServiceContact_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- {}, ol.format.OWS.SERVICE_CONTACT_PARSERS_, node,
- objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} The service provider.
- */
- ol.format.OWS.readServiceProvider_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- {}, ol.format.OWS.SERVICE_PROVIDER_PARSERS_, node,
- objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {string|undefined} The value.
- */
- ol.format.OWS.readValue_ = function(node, objectStack) {
- return ol.format.XSD.readString(node);
- };
- /**
- * @const
- * @type {Array.<string>}
- * @private
- */
- ol.format.OWS.NAMESPACE_URIS_ = [
- null,
- 'http://www.opengis.net/ows/1.1'
- ];
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.OWS.PARSERS_ = ol.xml.makeStructureNS(
- ol.format.OWS.NAMESPACE_URIS_, {
- 'ServiceIdentification': ol.xml.makeObjectPropertySetter(
- ol.format.OWS.readServiceIdentification_),
- 'ServiceProvider': ol.xml.makeObjectPropertySetter(
- ol.format.OWS.readServiceProvider_),
- 'OperationsMetadata': ol.xml.makeObjectPropertySetter(
- ol.format.OWS.readOperationsMetadata_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.OWS.ADDRESS_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.OWS.NAMESPACE_URIS_, {
- 'DeliveryPoint': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString),
- 'City': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'AdministrativeArea': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString),
- 'PostalCode': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'Country': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'ElectronicMailAddress': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.OWS.ALLOWED_VALUES_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.OWS.NAMESPACE_URIS_, {
- 'Value': ol.xml.makeObjectPropertyPusher(ol.format.OWS.readValue_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.OWS.CONSTRAINT_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.OWS.NAMESPACE_URIS_, {
- 'AllowedValues': ol.xml.makeObjectPropertySetter(
- ol.format.OWS.readAllowedValues_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.OWS.CONTACT_INFO_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.OWS.NAMESPACE_URIS_, {
- 'Phone': ol.xml.makeObjectPropertySetter(ol.format.OWS.readPhone_),
- 'Address': ol.xml.makeObjectPropertySetter(ol.format.OWS.readAddress_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.OWS.DCP_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.OWS.NAMESPACE_URIS_, {
- 'HTTP': ol.xml.makeObjectPropertySetter(ol.format.OWS.readHttp_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.OWS.HTTP_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.OWS.NAMESPACE_URIS_, {
- 'Get': ol.xml.makeObjectPropertyPusher(ol.format.OWS.readGet_),
- 'Post': undefined // TODO
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.OWS.OPERATION_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.OWS.NAMESPACE_URIS_, {
- 'DCP': ol.xml.makeObjectPropertySetter(ol.format.OWS.readDcp_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.OWS.OPERATIONS_METADATA_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.OWS.NAMESPACE_URIS_, {
- 'Operation': ol.format.OWS.readOperation_
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.OWS.PHONE_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.OWS.NAMESPACE_URIS_, {
- 'Voice': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'Facsimile': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.OWS.REQUEST_METHOD_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.OWS.NAMESPACE_URIS_, {
- 'Constraint': ol.xml.makeObjectPropertyPusher(
- ol.format.OWS.readConstraint_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.OWS.SERVICE_CONTACT_PARSERS_ =
- ol.xml.makeStructureNS(
- ol.format.OWS.NAMESPACE_URIS_, {
- 'IndividualName': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString),
- 'PositionName': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'ContactInfo': ol.xml.makeObjectPropertySetter(
- ol.format.OWS.readContactInfo_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.OWS.SERVICE_IDENTIFICATION_PARSERS_ =
- ol.xml.makeStructureNS(
- ol.format.OWS.NAMESPACE_URIS_, {
- 'Abstract': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'AccessConstraints': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'Fees': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'Title': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'ServiceTypeVersion': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString),
- 'ServiceType': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.OWS.SERVICE_PROVIDER_PARSERS_ =
- ol.xml.makeStructureNS(
- ol.format.OWS.NAMESPACE_URIS_, {
- 'ProviderName': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'ProviderSite': ol.xml.makeObjectPropertySetter(ol.format.XLink.readHref),
- 'ServiceContact': ol.xml.makeObjectPropertySetter(
- ol.format.OWS.readServiceContact_)
- });
- goog.provide('ol.geom.flat.flip');
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {Array.<number>=} opt_dest Destination.
- * @param {number=} opt_destOffset Destination offset.
- * @return {Array.<number>} Flat coordinates.
- */
- ol.geom.flat.flip.flipXY = function(flatCoordinates, offset, end, stride, opt_dest, opt_destOffset) {
- var dest, destOffset;
- if (opt_dest !== undefined) {
- dest = opt_dest;
- destOffset = opt_destOffset !== undefined ? opt_destOffset : 0;
- } else {
- dest = [];
- destOffset = 0;
- }
- var j = offset;
- while (j < end) {
- var x = flatCoordinates[j++];
- dest[destOffset++] = flatCoordinates[j++];
- dest[destOffset++] = x;
- for (var k = 2; k < stride; ++k) {
- dest[destOffset++] = flatCoordinates[j++];
- }
- }
- dest.length = destOffset;
- return dest;
- };
- goog.provide('ol.format.Polyline');
- goog.require('ol');
- goog.require('ol.asserts');
- goog.require('ol.Feature');
- goog.require('ol.format.Feature');
- goog.require('ol.format.TextFeature');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.LineString');
- goog.require('ol.geom.SimpleGeometry');
- goog.require('ol.geom.flat.flip');
- goog.require('ol.geom.flat.inflate');
- goog.require('ol.proj');
- /**
- * @classdesc
- * Feature format for reading and writing data in the Encoded
- * Polyline Algorithm Format.
- *
- * @constructor
- * @extends {ol.format.TextFeature}
- * @param {olx.format.PolylineOptions=} opt_options
- * Optional configuration object.
- * @api
- */
- ol.format.Polyline = function(opt_options) {
- var options = opt_options ? opt_options : {};
- ol.format.TextFeature.call(this);
- /**
- * @inheritDoc
- */
- this.defaultDataProjection = ol.proj.get('EPSG:4326');
- /**
- * @private
- * @type {number}
- */
- this.factor_ = options.factor ? options.factor : 1e5;
- /**
- * @private
- * @type {ol.geom.GeometryLayout}
- */
- this.geometryLayout_ = options.geometryLayout ?
- options.geometryLayout : ol.geom.GeometryLayout.XY;
- };
- ol.inherits(ol.format.Polyline, ol.format.TextFeature);
- /**
- * Encode a list of n-dimensional points and return an encoded string
- *
- * Attention: This function will modify the passed array!
- *
- * @param {Array.<number>} numbers A list of n-dimensional points.
- * @param {number} stride The number of dimension of the points in the list.
- * @param {number=} opt_factor The factor by which the numbers will be
- * multiplied. The remaining decimal places will get rounded away.
- * Default is `1e5`.
- * @return {string} The encoded string.
- * @api
- */
- ol.format.Polyline.encodeDeltas = function(numbers, stride, opt_factor) {
- var factor = opt_factor ? opt_factor : 1e5;
- var d;
- var lastNumbers = new Array(stride);
- for (d = 0; d < stride; ++d) {
- lastNumbers[d] = 0;
- }
- var i, ii;
- for (i = 0, ii = numbers.length; i < ii;) {
- for (d = 0; d < stride; ++d, ++i) {
- var num = numbers[i];
- var delta = num - lastNumbers[d];
- lastNumbers[d] = num;
- numbers[i] = delta;
- }
- }
- return ol.format.Polyline.encodeFloats(numbers, factor);
- };
- /**
- * Decode a list of n-dimensional points from an encoded string
- *
- * @param {string} encoded An encoded string.
- * @param {number} stride The number of dimension of the points in the
- * encoded string.
- * @param {number=} opt_factor The factor by which the resulting numbers will
- * be divided. Default is `1e5`.
- * @return {Array.<number>} A list of n-dimensional points.
- * @api
- */
- ol.format.Polyline.decodeDeltas = function(encoded, stride, opt_factor) {
- var factor = opt_factor ? opt_factor : 1e5;
- var d;
- /** @type {Array.<number>} */
- var lastNumbers = new Array(stride);
- for (d = 0; d < stride; ++d) {
- lastNumbers[d] = 0;
- }
- var numbers = ol.format.Polyline.decodeFloats(encoded, factor);
- var i, ii;
- for (i = 0, ii = numbers.length; i < ii;) {
- for (d = 0; d < stride; ++d, ++i) {
- lastNumbers[d] += numbers[i];
- numbers[i] = lastNumbers[d];
- }
- }
- return numbers;
- };
- /**
- * Encode a list of floating point numbers and return an encoded string
- *
- * Attention: This function will modify the passed array!
- *
- * @param {Array.<number>} numbers A list of floating point numbers.
- * @param {number=} opt_factor The factor by which the numbers will be
- * multiplied. The remaining decimal places will get rounded away.
- * Default is `1e5`.
- * @return {string} The encoded string.
- * @api
- */
- ol.format.Polyline.encodeFloats = function(numbers, opt_factor) {
- var factor = opt_factor ? opt_factor : 1e5;
- var i, ii;
- for (i = 0, ii = numbers.length; i < ii; ++i) {
- numbers[i] = Math.round(numbers[i] * factor);
- }
- return ol.format.Polyline.encodeSignedIntegers(numbers);
- };
- /**
- * Decode a list of floating point numbers from an encoded string
- *
- * @param {string} encoded An encoded string.
- * @param {number=} opt_factor The factor by which the result will be divided.
- * Default is `1e5`.
- * @return {Array.<number>} A list of floating point numbers.
- * @api
- */
- ol.format.Polyline.decodeFloats = function(encoded, opt_factor) {
- var factor = opt_factor ? opt_factor : 1e5;
- var numbers = ol.format.Polyline.decodeSignedIntegers(encoded);
- var i, ii;
- for (i = 0, ii = numbers.length; i < ii; ++i) {
- numbers[i] /= factor;
- }
- return numbers;
- };
- /**
- * Encode a list of signed integers and return an encoded string
- *
- * Attention: This function will modify the passed array!
- *
- * @param {Array.<number>} numbers A list of signed integers.
- * @return {string} The encoded string.
- */
- ol.format.Polyline.encodeSignedIntegers = function(numbers) {
- var i, ii;
- for (i = 0, ii = numbers.length; i < ii; ++i) {
- var num = numbers[i];
- numbers[i] = (num < 0) ? ~(num << 1) : (num << 1);
- }
- return ol.format.Polyline.encodeUnsignedIntegers(numbers);
- };
- /**
- * Decode a list of signed integers from an encoded string
- *
- * @param {string} encoded An encoded string.
- * @return {Array.<number>} A list of signed integers.
- */
- ol.format.Polyline.decodeSignedIntegers = function(encoded) {
- var numbers = ol.format.Polyline.decodeUnsignedIntegers(encoded);
- var i, ii;
- for (i = 0, ii = numbers.length; i < ii; ++i) {
- var num = numbers[i];
- numbers[i] = (num & 1) ? ~(num >> 1) : (num >> 1);
- }
- return numbers;
- };
- /**
- * Encode a list of unsigned integers and return an encoded string
- *
- * @param {Array.<number>} numbers A list of unsigned integers.
- * @return {string} The encoded string.
- */
- ol.format.Polyline.encodeUnsignedIntegers = function(numbers) {
- var encoded = '';
- var i, ii;
- for (i = 0, ii = numbers.length; i < ii; ++i) {
- encoded += ol.format.Polyline.encodeUnsignedInteger(numbers[i]);
- }
- return encoded;
- };
- /**
- * Decode a list of unsigned integers from an encoded string
- *
- * @param {string} encoded An encoded string.
- * @return {Array.<number>} A list of unsigned integers.
- */
- ol.format.Polyline.decodeUnsignedIntegers = function(encoded) {
- var numbers = [];
- var current = 0;
- var shift = 0;
- var i, ii;
- for (i = 0, ii = encoded.length; i < ii; ++i) {
- var b = encoded.charCodeAt(i) - 63;
- current |= (b & 0x1f) << shift;
- if (b < 0x20) {
- numbers.push(current);
- current = 0;
- shift = 0;
- } else {
- shift += 5;
- }
- }
- return numbers;
- };
- /**
- * Encode one single unsigned integer and return an encoded string
- *
- * @param {number} num Unsigned integer that should be encoded.
- * @return {string} The encoded string.
- */
- ol.format.Polyline.encodeUnsignedInteger = function(num) {
- var value, encoded = '';
- while (num >= 0x20) {
- value = (0x20 | (num & 0x1f)) + 63;
- encoded += String.fromCharCode(value);
- num >>= 5;
- }
- value = num + 63;
- encoded += String.fromCharCode(value);
- return encoded;
- };
- /**
- * Read the feature from the Polyline source. The coordinates are assumed to be
- * in two dimensions and in latitude, longitude order.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {ol.Feature} Feature.
- * @api
- */
- ol.format.Polyline.prototype.readFeature;
- /**
- * @inheritDoc
- */
- ol.format.Polyline.prototype.readFeatureFromText = function(text, opt_options) {
- var geometry = this.readGeometryFromText(text, opt_options);
- return new ol.Feature(geometry);
- };
- /**
- * Read the feature from the source. As Polyline sources contain a single
- * feature, this will return the feature in an array.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {Array.<ol.Feature>} Features.
- * @api
- */
- ol.format.Polyline.prototype.readFeatures;
- /**
- * @inheritDoc
- */
- ol.format.Polyline.prototype.readFeaturesFromText = function(text, opt_options) {
- var feature = this.readFeatureFromText(text, opt_options);
- return [feature];
- };
- /**
- * Read the geometry from the source.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {ol.geom.Geometry} Geometry.
- * @api
- */
- ol.format.Polyline.prototype.readGeometry;
- /**
- * @inheritDoc
- */
- ol.format.Polyline.prototype.readGeometryFromText = function(text, opt_options) {
- var stride = ol.geom.SimpleGeometry.getStrideForLayout(this.geometryLayout_);
- var flatCoordinates = ol.format.Polyline.decodeDeltas(
- text, stride, this.factor_);
- ol.geom.flat.flip.flipXY(
- flatCoordinates, 0, flatCoordinates.length, stride, flatCoordinates);
- var coordinates = ol.geom.flat.inflate.coordinates(
- flatCoordinates, 0, flatCoordinates.length, stride);
- return /** @type {ol.geom.Geometry} */ (
- ol.format.Feature.transformWithOptions(
- new ol.geom.LineString(coordinates, this.geometryLayout_), false,
- this.adaptOptions(opt_options)));
- };
- /**
- * Read the projection from a Polyline source.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @return {ol.proj.Projection} Projection.
- * @api
- */
- ol.format.Polyline.prototype.readProjection;
- /**
- * @inheritDoc
- */
- ol.format.Polyline.prototype.writeFeatureText = function(feature, opt_options) {
- var geometry = feature.getGeometry();
- if (geometry) {
- return this.writeGeometryText(geometry, opt_options);
- } else {
- ol.asserts.assert(false, 40); // Expected `feature` to have a geometry
- return '';
- }
- };
- /**
- * @inheritDoc
- */
- ol.format.Polyline.prototype.writeFeaturesText = function(features, opt_options) {
- return this.writeFeatureText(features[0], opt_options);
- };
- /**
- * Write a single geometry in Polyline format.
- *
- * @function
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {string} Geometry.
- * @api
- */
- ol.format.Polyline.prototype.writeGeometry;
- /**
- * @inheritDoc
- */
- ol.format.Polyline.prototype.writeGeometryText = function(geometry, opt_options) {
- geometry = /** @type {ol.geom.LineString} */
- (ol.format.Feature.transformWithOptions(
- geometry, true, this.adaptOptions(opt_options)));
- var flatCoordinates = geometry.getFlatCoordinates();
- var stride = geometry.getStride();
- ol.geom.flat.flip.flipXY(
- flatCoordinates, 0, flatCoordinates.length, stride, flatCoordinates);
- return ol.format.Polyline.encodeDeltas(flatCoordinates, stride, this.factor_);
- };
- goog.provide('ol.format.TopoJSON');
- goog.require('ol');
- goog.require('ol.Feature');
- goog.require('ol.format.Feature');
- goog.require('ol.format.JSONFeature');
- goog.require('ol.geom.LineString');
- goog.require('ol.geom.MultiLineString');
- goog.require('ol.geom.MultiPoint');
- goog.require('ol.geom.MultiPolygon');
- goog.require('ol.geom.Point');
- goog.require('ol.geom.Polygon');
- goog.require('ol.proj');
- /**
- * @classdesc
- * Feature format for reading data in the TopoJSON format.
- *
- * @constructor
- * @extends {ol.format.JSONFeature}
- * @param {olx.format.TopoJSONOptions=} opt_options Options.
- * @api
- */
- ol.format.TopoJSON = function(opt_options) {
- var options = opt_options ? opt_options : {};
- ol.format.JSONFeature.call(this);
- /**
- * @private
- * @type {string|undefined}
- */
- this.layerName_ = options.layerName;
- /**
- * @private
- * @type {Array.<string>}
- */
- this.layers_ = options.layers ? options.layers : null;
- /**
- * @inheritDoc
- */
- this.defaultDataProjection = ol.proj.get(
- options.defaultDataProjection ?
- options.defaultDataProjection : 'EPSG:4326');
- };
- ol.inherits(ol.format.TopoJSON, ol.format.JSONFeature);
- /**
- * Concatenate arcs into a coordinate array.
- * @param {Array.<number>} indices Indices of arcs to concatenate. Negative
- * values indicate arcs need to be reversed.
- * @param {Array.<Array.<ol.Coordinate>>} arcs Array of arcs (already
- * transformed).
- * @return {Array.<ol.Coordinate>} Coordinates array.
- * @private
- */
- ol.format.TopoJSON.concatenateArcs_ = function(indices, arcs) {
- /** @type {Array.<ol.Coordinate>} */
- var coordinates = [];
- var index, arc;
- var i, ii;
- var j, jj;
- for (i = 0, ii = indices.length; i < ii; ++i) {
- index = indices[i];
- if (i > 0) {
- // splicing together arcs, discard last point
- coordinates.pop();
- }
- if (index >= 0) {
- // forward arc
- arc = arcs[index];
- } else {
- // reverse arc
- arc = arcs[~index].slice().reverse();
- }
- coordinates.push.apply(coordinates, arc);
- }
- // provide fresh copies of coordinate arrays
- for (j = 0, jj = coordinates.length; j < jj; ++j) {
- coordinates[j] = coordinates[j].slice();
- }
- return coordinates;
- };
- /**
- * Create a point from a TopoJSON geometry object.
- *
- * @param {TopoJSONGeometry} object TopoJSON object.
- * @param {Array.<number>} scale Scale for each dimension.
- * @param {Array.<number>} translate Translation for each dimension.
- * @return {ol.geom.Point} Geometry.
- * @private
- */
- ol.format.TopoJSON.readPointGeometry_ = function(object, scale, translate) {
- var coordinates = object.coordinates;
- if (scale && translate) {
- ol.format.TopoJSON.transformVertex_(coordinates, scale, translate);
- }
- return new ol.geom.Point(coordinates);
- };
- /**
- * Create a multi-point from a TopoJSON geometry object.
- *
- * @param {TopoJSONGeometry} object TopoJSON object.
- * @param {Array.<number>} scale Scale for each dimension.
- * @param {Array.<number>} translate Translation for each dimension.
- * @return {ol.geom.MultiPoint} Geometry.
- * @private
- */
- ol.format.TopoJSON.readMultiPointGeometry_ = function(object, scale,
- translate) {
- var coordinates = object.coordinates;
- var i, ii;
- if (scale && translate) {
- for (i = 0, ii = coordinates.length; i < ii; ++i) {
- ol.format.TopoJSON.transformVertex_(coordinates[i], scale, translate);
- }
- }
- return new ol.geom.MultiPoint(coordinates);
- };
- /**
- * Create a linestring from a TopoJSON geometry object.
- *
- * @param {TopoJSONGeometry} object TopoJSON object.
- * @param {Array.<Array.<ol.Coordinate>>} arcs Array of arcs.
- * @return {ol.geom.LineString} Geometry.
- * @private
- */
- ol.format.TopoJSON.readLineStringGeometry_ = function(object, arcs) {
- var coordinates = ol.format.TopoJSON.concatenateArcs_(object.arcs, arcs);
- return new ol.geom.LineString(coordinates);
- };
- /**
- * Create a multi-linestring from a TopoJSON geometry object.
- *
- * @param {TopoJSONGeometry} object TopoJSON object.
- * @param {Array.<Array.<ol.Coordinate>>} arcs Array of arcs.
- * @return {ol.geom.MultiLineString} Geometry.
- * @private
- */
- ol.format.TopoJSON.readMultiLineStringGeometry_ = function(object, arcs) {
- var coordinates = [];
- var i, ii;
- for (i = 0, ii = object.arcs.length; i < ii; ++i) {
- coordinates[i] = ol.format.TopoJSON.concatenateArcs_(object.arcs[i], arcs);
- }
- return new ol.geom.MultiLineString(coordinates);
- };
- /**
- * Create a polygon from a TopoJSON geometry object.
- *
- * @param {TopoJSONGeometry} object TopoJSON object.
- * @param {Array.<Array.<ol.Coordinate>>} arcs Array of arcs.
- * @return {ol.geom.Polygon} Geometry.
- * @private
- */
- ol.format.TopoJSON.readPolygonGeometry_ = function(object, arcs) {
- var coordinates = [];
- var i, ii;
- for (i = 0, ii = object.arcs.length; i < ii; ++i) {
- coordinates[i] = ol.format.TopoJSON.concatenateArcs_(object.arcs[i], arcs);
- }
- return new ol.geom.Polygon(coordinates);
- };
- /**
- * Create a multi-polygon from a TopoJSON geometry object.
- *
- * @param {TopoJSONGeometry} object TopoJSON object.
- * @param {Array.<Array.<ol.Coordinate>>} arcs Array of arcs.
- * @return {ol.geom.MultiPolygon} Geometry.
- * @private
- */
- ol.format.TopoJSON.readMultiPolygonGeometry_ = function(object, arcs) {
- var coordinates = [];
- var polyArray, ringCoords, j, jj;
- var i, ii;
- for (i = 0, ii = object.arcs.length; i < ii; ++i) {
- // for each polygon
- polyArray = object.arcs[i];
- ringCoords = [];
- for (j = 0, jj = polyArray.length; j < jj; ++j) {
- // for each ring
- ringCoords[j] = ol.format.TopoJSON.concatenateArcs_(polyArray[j], arcs);
- }
- coordinates[i] = ringCoords;
- }
- return new ol.geom.MultiPolygon(coordinates);
- };
- /**
- * Create features from a TopoJSON GeometryCollection object.
- *
- * @param {TopoJSONGeometryCollection} collection TopoJSON Geometry
- * object.
- * @param {Array.<Array.<ol.Coordinate>>} arcs Array of arcs.
- * @param {Array.<number>} scale Scale for each dimension.
- * @param {Array.<number>} translate Translation for each dimension.
- * @param {string|undefined} property Property to set the `GeometryCollection`'s parent
- * object to.
- * @param {string} name Name of the `Topology`'s child object.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {Array.<ol.Feature>} Array of features.
- * @private
- */
- ol.format.TopoJSON.readFeaturesFromGeometryCollection_ = function(
- collection, arcs, scale, translate, property, name, opt_options) {
- var geometries = collection.geometries;
- var features = [];
- var i, ii;
- for (i = 0, ii = geometries.length; i < ii; ++i) {
- features[i] = ol.format.TopoJSON.readFeatureFromGeometry_(
- geometries[i], arcs, scale, translate, property, name, opt_options);
- }
- return features;
- };
- /**
- * Create a feature from a TopoJSON geometry object.
- *
- * @param {TopoJSONGeometry} object TopoJSON geometry object.
- * @param {Array.<Array.<ol.Coordinate>>} arcs Array of arcs.
- * @param {Array.<number>} scale Scale for each dimension.
- * @param {Array.<number>} translate Translation for each dimension.
- * @param {string|undefined} property Property to set the `GeometryCollection`'s parent
- * object to.
- * @param {string} name Name of the `Topology`'s child object.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {ol.Feature} Feature.
- * @private
- */
- ol.format.TopoJSON.readFeatureFromGeometry_ = function(object, arcs,
- scale, translate, property, name, opt_options) {
- var geometry;
- var type = object.type;
- var geometryReader = ol.format.TopoJSON.GEOMETRY_READERS_[type];
- if ((type === 'Point') || (type === 'MultiPoint')) {
- geometry = geometryReader(object, scale, translate);
- } else {
- geometry = geometryReader(object, arcs);
- }
- var feature = new ol.Feature();
- feature.setGeometry(/** @type {ol.geom.Geometry} */ (
- ol.format.Feature.transformWithOptions(geometry, false, opt_options)));
- if (object.id !== undefined) {
- feature.setId(object.id);
- }
- var properties = object.properties;
- if (property) {
- if (!properties) {
- properties = {};
- }
- properties[property] = name;
- }
- if (properties) {
- feature.setProperties(properties);
- }
- return feature;
- };
- /**
- * Read all features from a TopoJSON source.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @return {Array.<ol.Feature>} Features.
- * @api
- */
- ol.format.TopoJSON.prototype.readFeatures;
- /**
- * @inheritDoc
- */
- ol.format.TopoJSON.prototype.readFeaturesFromObject = function(
- object, opt_options) {
- if (object.type == 'Topology') {
- var topoJSONTopology = /** @type {TopoJSONTopology} */ (object);
- var transform, scale = null, translate = null;
- if (topoJSONTopology.transform) {
- transform = topoJSONTopology.transform;
- scale = transform.scale;
- translate = transform.translate;
- }
- var arcs = topoJSONTopology.arcs;
- if (transform) {
- ol.format.TopoJSON.transformArcs_(arcs, scale, translate);
- }
- /** @type {Array.<ol.Feature>} */
- var features = [];
- var topoJSONFeatures = topoJSONTopology.objects;
- var property = this.layerName_;
- var objectName, feature;
- for (objectName in topoJSONFeatures) {
- if (this.layers_ && this.layers_.indexOf(objectName) == -1) {
- continue;
- }
- if (topoJSONFeatures[objectName].type === 'GeometryCollection') {
- feature = /** @type {TopoJSONGeometryCollection} */
- (topoJSONFeatures[objectName]);
- features.push.apply(features,
- ol.format.TopoJSON.readFeaturesFromGeometryCollection_(
- feature, arcs, scale, translate, property, objectName, opt_options));
- } else {
- feature = /** @type {TopoJSONGeometry} */
- (topoJSONFeatures[objectName]);
- features.push(ol.format.TopoJSON.readFeatureFromGeometry_(
- feature, arcs, scale, translate, property, objectName, opt_options));
- }
- }
- return features;
- } else {
- return [];
- }
- };
- /**
- * Apply a linear transform to array of arcs. The provided array of arcs is
- * modified in place.
- *
- * @param {Array.<Array.<ol.Coordinate>>} arcs Array of arcs.
- * @param {Array.<number>} scale Scale for each dimension.
- * @param {Array.<number>} translate Translation for each dimension.
- * @private
- */
- ol.format.TopoJSON.transformArcs_ = function(arcs, scale, translate) {
- var i, ii;
- for (i = 0, ii = arcs.length; i < ii; ++i) {
- ol.format.TopoJSON.transformArc_(arcs[i], scale, translate);
- }
- };
- /**
- * Apply a linear transform to an arc. The provided arc is modified in place.
- *
- * @param {Array.<ol.Coordinate>} arc Arc.
- * @param {Array.<number>} scale Scale for each dimension.
- * @param {Array.<number>} translate Translation for each dimension.
- * @private
- */
- ol.format.TopoJSON.transformArc_ = function(arc, scale, translate) {
- var x = 0;
- var y = 0;
- var vertex;
- var i, ii;
- for (i = 0, ii = arc.length; i < ii; ++i) {
- vertex = arc[i];
- x += vertex[0];
- y += vertex[1];
- vertex[0] = x;
- vertex[1] = y;
- ol.format.TopoJSON.transformVertex_(vertex, scale, translate);
- }
- };
- /**
- * Apply a linear transform to a vertex. The provided vertex is modified in
- * place.
- *
- * @param {ol.Coordinate} vertex Vertex.
- * @param {Array.<number>} scale Scale for each dimension.
- * @param {Array.<number>} translate Translation for each dimension.
- * @private
- */
- ol.format.TopoJSON.transformVertex_ = function(vertex, scale, translate) {
- vertex[0] = vertex[0] * scale[0] + translate[0];
- vertex[1] = vertex[1] * scale[1] + translate[1];
- };
- /**
- * Read the projection from a TopoJSON source.
- *
- * @param {Document|Node|Object|string} object Source.
- * @return {ol.proj.Projection} Projection.
- * @override
- * @api
- */
- ol.format.TopoJSON.prototype.readProjection;
- /**
- * @inheritDoc
- */
- ol.format.TopoJSON.prototype.readProjectionFromObject = function(object) {
- return this.defaultDataProjection;
- };
- /**
- * @const
- * @private
- * @type {Object.<string, function(TopoJSONGeometry, Array, ...Array): ol.geom.Geometry>}
- */
- ol.format.TopoJSON.GEOMETRY_READERS_ = {
- 'Point': ol.format.TopoJSON.readPointGeometry_,
- 'LineString': ol.format.TopoJSON.readLineStringGeometry_,
- 'Polygon': ol.format.TopoJSON.readPolygonGeometry_,
- 'MultiPoint': ol.format.TopoJSON.readMultiPointGeometry_,
- 'MultiLineString': ol.format.TopoJSON.readMultiLineStringGeometry_,
- 'MultiPolygon': ol.format.TopoJSON.readMultiPolygonGeometry_
- };
- /**
- * Not implemented.
- * @inheritDoc
- */
- ol.format.TopoJSON.prototype.writeFeatureObject = function(feature, opt_options) {};
- /**
- * Not implemented.
- * @inheritDoc
- */
- ol.format.TopoJSON.prototype.writeFeaturesObject = function(features, opt_options) {};
- /**
- * Not implemented.
- * @inheritDoc
- */
- ol.format.TopoJSON.prototype.writeGeometryObject = function(geometry, opt_options) {};
- /**
- * Not implemented.
- * @override
- */
- ol.format.TopoJSON.prototype.readGeometryFromObject = function() {};
- /**
- * Not implemented.
- * @override
- */
- ol.format.TopoJSON.prototype.readFeatureFromObject = function() {};
- goog.provide('ol.format.WFS');
- goog.require('ol');
- goog.require('ol.asserts');
- goog.require('ol.format.GML2');
- goog.require('ol.format.GML3');
- goog.require('ol.format.GMLBase');
- goog.require('ol.format.filter');
- goog.require('ol.format.XMLFeature');
- goog.require('ol.format.XSD');
- goog.require('ol.geom.Geometry');
- goog.require('ol.obj');
- goog.require('ol.proj');
- goog.require('ol.xml');
- /**
- * @classdesc
- * Feature format for reading and writing data in the WFS format.
- * By default, supports WFS version 1.1.0. You can pass a GML format
- * as option if you want to read a WFS that contains GML2 (WFS 1.0.0).
- * Also see {@link ol.format.GMLBase} which is used by this format.
- *
- * @constructor
- * @param {olx.format.WFSOptions=} opt_options
- * Optional configuration object.
- * @extends {ol.format.XMLFeature}
- * @api
- */
- ol.format.WFS = function(opt_options) {
- var options = opt_options ? opt_options : {};
- /**
- * @private
- * @type {Array.<string>|string|undefined}
- */
- this.featureType_ = options.featureType;
- /**
- * @private
- * @type {Object.<string, string>|string|undefined}
- */
- this.featureNS_ = options.featureNS;
- /**
- * @private
- * @type {ol.format.GMLBase}
- */
- this.gmlFormat_ = options.gmlFormat ?
- options.gmlFormat : new ol.format.GML3();
- /**
- * @private
- * @type {string}
- */
- this.schemaLocation_ = options.schemaLocation ?
- options.schemaLocation :
- ol.format.WFS.SCHEMA_LOCATIONS[ol.format.WFS.DEFAULT_VERSION];
- ol.format.XMLFeature.call(this);
- };
- ol.inherits(ol.format.WFS, ol.format.XMLFeature);
- /**
- * @const
- * @type {string}
- */
- ol.format.WFS.FEATURE_PREFIX = 'feature';
- /**
- * @const
- * @type {string}
- */
- ol.format.WFS.XMLNS = 'http://www.w3.org/2000/xmlns/';
- /**
- * @const
- * @type {string}
- */
- ol.format.WFS.OGCNS = 'http://www.opengis.net/ogc';
- /**
- * @const
- * @type {string}
- */
- ol.format.WFS.WFSNS = 'http://www.opengis.net/wfs';
- /**
- * @const
- * @type {string}
- */
- ol.format.WFS.FESNS = 'http://www.opengis.net/fes';
- /**
- * @const
- * @type {Object.<string, string>}
- */
- ol.format.WFS.SCHEMA_LOCATIONS = {
- '1.1.0': 'http://www.opengis.net/wfs ' +
- 'http://schemas.opengis.net/wfs/1.1.0/wfs.xsd',
- '1.0.0': 'http://www.opengis.net/wfs ' +
- 'http://schemas.opengis.net/wfs/1.0.0/wfs.xsd'
- };
- /**
- * @const
- * @type {string}
- */
- ol.format.WFS.DEFAULT_VERSION = '1.1.0';
- /**
- * @return {Array.<string>|string|undefined} featureType
- */
- ol.format.WFS.prototype.getFeatureType = function() {
- return this.featureType_;
- };
- /**
- * @param {Array.<string>|string|undefined} featureType Feature type(s) to parse.
- */
- ol.format.WFS.prototype.setFeatureType = function(featureType) {
- this.featureType_ = featureType;
- };
- /**
- * Read all features from a WFS FeatureCollection.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {Array.<ol.Feature>} Features.
- * @api
- */
- ol.format.WFS.prototype.readFeatures;
- /**
- * @inheritDoc
- */
- ol.format.WFS.prototype.readFeaturesFromNode = function(node, opt_options) {
- var context = /** @type {ol.XmlNodeStackItem} */ ({
- 'featureType': this.featureType_,
- 'featureNS': this.featureNS_
- });
- ol.obj.assign(context, this.getReadOptions(node,
- opt_options ? opt_options : {}));
- var objectStack = [context];
- this.gmlFormat_.FEATURE_COLLECTION_PARSERS[ol.format.GMLBase.GMLNS][
- 'featureMember'] =
- ol.xml.makeArrayPusher(ol.format.GMLBase.prototype.readFeaturesInternal);
- var features = ol.xml.pushParseAndPop([],
- this.gmlFormat_.FEATURE_COLLECTION_PARSERS, node,
- objectStack, this.gmlFormat_);
- if (!features) {
- features = [];
- }
- return features;
- };
- /**
- * Read transaction response of the source.
- *
- * @param {Document|Node|Object|string} source Source.
- * @return {ol.WFSTransactionResponse|undefined} Transaction response.
- * @api
- */
- ol.format.WFS.prototype.readTransactionResponse = function(source) {
- if (ol.xml.isDocument(source)) {
- return this.readTransactionResponseFromDocument(
- /** @type {Document} */ (source));
- } else if (ol.xml.isNode(source)) {
- return this.readTransactionResponseFromNode(/** @type {Node} */ (source));
- } else if (typeof source === 'string') {
- var doc = ol.xml.parse(source);
- return this.readTransactionResponseFromDocument(doc);
- } else {
- return undefined;
- }
- };
- /**
- * Read feature collection metadata of the source.
- *
- * @param {Document|Node|Object|string} source Source.
- * @return {ol.WFSFeatureCollectionMetadata|undefined}
- * FeatureCollection metadata.
- * @api
- */
- ol.format.WFS.prototype.readFeatureCollectionMetadata = function(source) {
- if (ol.xml.isDocument(source)) {
- return this.readFeatureCollectionMetadataFromDocument(
- /** @type {Document} */ (source));
- } else if (ol.xml.isNode(source)) {
- return this.readFeatureCollectionMetadataFromNode(
- /** @type {Node} */ (source));
- } else if (typeof source === 'string') {
- var doc = ol.xml.parse(source);
- return this.readFeatureCollectionMetadataFromDocument(doc);
- } else {
- return undefined;
- }
- };
- /**
- * @param {Document} doc Document.
- * @return {ol.WFSFeatureCollectionMetadata|undefined}
- * FeatureCollection metadata.
- */
- ol.format.WFS.prototype.readFeatureCollectionMetadataFromDocument = function(doc) {
- for (var n = doc.firstChild; n; n = n.nextSibling) {
- if (n.nodeType == Node.ELEMENT_NODE) {
- return this.readFeatureCollectionMetadataFromNode(n);
- }
- }
- return undefined;
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WFS.FEATURE_COLLECTION_PARSERS_ = {
- 'http://www.opengis.net/gml': {
- 'boundedBy': ol.xml.makeObjectPropertySetter(
- ol.format.GMLBase.prototype.readGeometryElement, 'bounds')
- }
- };
- /**
- * @param {Node} node Node.
- * @return {ol.WFSFeatureCollectionMetadata|undefined}
- * FeatureCollection metadata.
- */
- ol.format.WFS.prototype.readFeatureCollectionMetadataFromNode = function(node) {
- var result = {};
- var value = ol.format.XSD.readNonNegativeIntegerString(
- node.getAttribute('numberOfFeatures'));
- result['numberOfFeatures'] = value;
- return ol.xml.pushParseAndPop(
- /** @type {ol.WFSFeatureCollectionMetadata} */ (result),
- ol.format.WFS.FEATURE_COLLECTION_PARSERS_, node, [], this.gmlFormat_);
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WFS.TRANSACTION_SUMMARY_PARSERS_ = {
- 'http://www.opengis.net/wfs': {
- 'totalInserted': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readNonNegativeInteger),
- 'totalUpdated': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readNonNegativeInteger),
- 'totalDeleted': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readNonNegativeInteger)
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Transaction Summary.
- * @private
- */
- ol.format.WFS.readTransactionSummary_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- {}, ol.format.WFS.TRANSACTION_SUMMARY_PARSERS_, node, objectStack);
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WFS.OGC_FID_PARSERS_ = {
- 'http://www.opengis.net/ogc': {
- 'FeatureId': ol.xml.makeArrayPusher(function(node, objectStack) {
- return node.getAttribute('fid');
- })
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- */
- ol.format.WFS.fidParser_ = function(node, objectStack) {
- ol.xml.parseNode(ol.format.WFS.OGC_FID_PARSERS_, node, objectStack);
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WFS.INSERT_RESULTS_PARSERS_ = {
- 'http://www.opengis.net/wfs': {
- 'Feature': ol.format.WFS.fidParser_
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Array.<string>|undefined} Insert results.
- * @private
- */
- ol.format.WFS.readInsertResults_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- [], ol.format.WFS.INSERT_RESULTS_PARSERS_, node, objectStack);
- };
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WFS.TRANSACTION_RESPONSE_PARSERS_ = {
- 'http://www.opengis.net/wfs': {
- 'TransactionSummary': ol.xml.makeObjectPropertySetter(
- ol.format.WFS.readTransactionSummary_, 'transactionSummary'),
- 'InsertResults': ol.xml.makeObjectPropertySetter(
- ol.format.WFS.readInsertResults_, 'insertIds')
- }
- };
- /**
- * @param {Document} doc Document.
- * @return {ol.WFSTransactionResponse|undefined} Transaction response.
- */
- ol.format.WFS.prototype.readTransactionResponseFromDocument = function(doc) {
- for (var n = doc.firstChild; n; n = n.nextSibling) {
- if (n.nodeType == Node.ELEMENT_NODE) {
- return this.readTransactionResponseFromNode(n);
- }
- }
- return undefined;
- };
- /**
- * @param {Node} node Node.
- * @return {ol.WFSTransactionResponse|undefined} Transaction response.
- */
- ol.format.WFS.prototype.readTransactionResponseFromNode = function(node) {
- return ol.xml.pushParseAndPop(
- /** @type {ol.WFSTransactionResponse} */({}),
- ol.format.WFS.TRANSACTION_RESPONSE_PARSERS_, node, []);
- };
- /**
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.WFS.QUERY_SERIALIZERS_ = {
- 'http://www.opengis.net/wfs': {
- 'PropertyName': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode)
- }
- };
- /**
- * @param {Node} node Node.
- * @param {ol.Feature} feature Feature.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeFeature_ = function(node, feature, objectStack) {
- var context = objectStack[objectStack.length - 1];
- var featureType = context['featureType'];
- var featureNS = context['featureNS'];
- var gmlVersion = context['gmlVersion'];
- var child = ol.xml.createElementNS(featureNS, featureType);
- node.appendChild(child);
- if (gmlVersion === 2) {
- ol.format.GML2.prototype.writeFeatureElement(child, feature, objectStack);
- } else {
- ol.format.GML3.prototype.writeFeatureElement(child, feature, objectStack);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {number|string} fid Feature identifier.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeOgcFidFilter_ = function(node, fid, objectStack) {
- var filter = ol.xml.createElementNS(ol.format.WFS.OGCNS, 'Filter');
- var child = ol.xml.createElementNS(ol.format.WFS.OGCNS, 'FeatureId');
- filter.appendChild(child);
- child.setAttribute('fid', fid);
- node.appendChild(filter);
- };
- /**
- * @param {string|undefined} featurePrefix The prefix of the feature.
- * @param {string} featureType The type of the feature.
- * @returns {string} The value of the typeName property.
- * @private
- */
- ol.format.WFS.getTypeName_ = function(featurePrefix, featureType) {
- featurePrefix = featurePrefix ? featurePrefix :
- ol.format.WFS.FEATURE_PREFIX;
- var prefix = featurePrefix + ':';
- // The featureType already contains the prefix.
- if (featureType.indexOf(prefix) === 0) {
- return featureType;
- } else {
- return prefix + featureType;
- }
- };
- /**
- * @param {Node} node Node.
- * @param {ol.Feature} feature Feature.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeDelete_ = function(node, feature, objectStack) {
- var context = objectStack[objectStack.length - 1];
- ol.asserts.assert(feature.getId() !== undefined, 26); // Features must have an id set
- var featureType = context['featureType'];
- var featurePrefix = context['featurePrefix'];
- var featureNS = context['featureNS'];
- var typeName = ol.format.WFS.getTypeName_(featurePrefix, featureType);
- node.setAttribute('typeName', typeName);
- ol.xml.setAttributeNS(node, ol.format.WFS.XMLNS, 'xmlns:' + featurePrefix,
- featureNS);
- var fid = feature.getId();
- if (fid !== undefined) {
- ol.format.WFS.writeOgcFidFilter_(node, fid, objectStack);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {ol.Feature} feature Feature.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeUpdate_ = function(node, feature, objectStack) {
- var context = objectStack[objectStack.length - 1];
- ol.asserts.assert(feature.getId() !== undefined, 27); // Features must have an id set
- var featureType = context['featureType'];
- var featurePrefix = context['featurePrefix'];
- var featureNS = context['featureNS'];
- var typeName = ol.format.WFS.getTypeName_(featurePrefix, featureType);
- var geometryName = feature.getGeometryName();
- node.setAttribute('typeName', typeName);
- ol.xml.setAttributeNS(node, ol.format.WFS.XMLNS, 'xmlns:' + featurePrefix,
- featureNS);
- var fid = feature.getId();
- if (fid !== undefined) {
- var keys = feature.getKeys();
- var values = [];
- for (var i = 0, ii = keys.length; i < ii; i++) {
- var value = feature.get(keys[i]);
- if (value !== undefined) {
- var name = keys[i];
- if (value instanceof ol.geom.Geometry) {
- name = geometryName;
- }
- values.push({name: name, value: value});
- }
- }
- ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */ (
- {'gmlVersion': context['gmlVersion'], node: node,
- 'hasZ': context['hasZ'], 'srsName': context['srsName']}),
- ol.format.WFS.TRANSACTION_SERIALIZERS_,
- ol.xml.makeSimpleNodeFactory('Property'), values,
- objectStack);
- ol.format.WFS.writeOgcFidFilter_(node, fid, objectStack);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {Object} pair Property name and value.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeProperty_ = function(node, pair, objectStack) {
- var name = ol.xml.createElementNS(ol.format.WFS.WFSNS, 'Name');
- var context = objectStack[objectStack.length - 1];
- var gmlVersion = context['gmlVersion'];
- node.appendChild(name);
- ol.format.XSD.writeStringTextNode(name, pair.name);
- if (pair.value !== undefined && pair.value !== null) {
- var value = ol.xml.createElementNS(ol.format.WFS.WFSNS, 'Value');
- node.appendChild(value);
- if (pair.value instanceof ol.geom.Geometry) {
- if (gmlVersion === 2) {
- ol.format.GML2.prototype.writeGeometryElement(value,
- pair.value, objectStack);
- } else {
- ol.format.GML3.prototype.writeGeometryElement(value,
- pair.value, objectStack);
- }
- } else {
- ol.format.XSD.writeStringTextNode(value, pair.value);
- }
- }
- };
- /**
- * @param {Node} node Node.
- * @param {{vendorId: string, safeToIgnore: boolean, value: string}}
- * nativeElement The native element.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeNative_ = function(node, nativeElement, objectStack) {
- if (nativeElement.vendorId) {
- node.setAttribute('vendorId', nativeElement.vendorId);
- }
- if (nativeElement.safeToIgnore !== undefined) {
- node.setAttribute('safeToIgnore', nativeElement.safeToIgnore);
- }
- if (nativeElement.value !== undefined) {
- ol.format.XSD.writeStringTextNode(node, nativeElement.value);
- }
- };
- /**
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.WFS.TRANSACTION_SERIALIZERS_ = {
- 'http://www.opengis.net/wfs': {
- 'Insert': ol.xml.makeChildAppender(ol.format.WFS.writeFeature_),
- 'Update': ol.xml.makeChildAppender(ol.format.WFS.writeUpdate_),
- 'Delete': ol.xml.makeChildAppender(ol.format.WFS.writeDelete_),
- 'Property': ol.xml.makeChildAppender(ol.format.WFS.writeProperty_),
- 'Native': ol.xml.makeChildAppender(ol.format.WFS.writeNative_)
- }
- };
- /**
- * @param {Node} node Node.
- * @param {string} featureType Feature type.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeQuery_ = function(node, featureType, objectStack) {
- var context = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- var featurePrefix = context['featurePrefix'];
- var featureNS = context['featureNS'];
- var propertyNames = context['propertyNames'];
- var srsName = context['srsName'];
- var typeName;
- // If feature prefix is not defined, we must not use the default prefix.
- if (featurePrefix) {
- typeName = ol.format.WFS.getTypeName_(featurePrefix, featureType);
- } else {
- typeName = featureType;
- }
- node.setAttribute('typeName', typeName);
- if (srsName) {
- node.setAttribute('srsName', srsName);
- }
- if (featureNS) {
- ol.xml.setAttributeNS(node, ol.format.WFS.XMLNS, 'xmlns:' + featurePrefix,
- featureNS);
- }
- var item = /** @type {ol.XmlNodeStackItem} */ (ol.obj.assign({}, context));
- item.node = node;
- ol.xml.pushSerializeAndPop(item,
- ol.format.WFS.QUERY_SERIALIZERS_,
- ol.xml.makeSimpleNodeFactory('PropertyName'), propertyNames,
- objectStack);
- var filter = context['filter'];
- if (filter) {
- var child = ol.xml.createElementNS(ol.format.WFS.OGCNS, 'Filter');
- node.appendChild(child);
- ol.format.WFS.writeFilterCondition_(child, filter, objectStack);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {ol.format.filter.Filter} filter Filter.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeFilterCondition_ = function(node, filter, objectStack) {
- /** @type {ol.XmlNodeStackItem} */
- var item = {node: node};
- ol.xml.pushSerializeAndPop(item,
- ol.format.WFS.GETFEATURE_SERIALIZERS_,
- ol.xml.makeSimpleNodeFactory(filter.getTagName()),
- [filter], objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.format.filter.Bbox} filter Filter.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeBboxFilter_ = function(node, filter, objectStack) {
- var context = objectStack[objectStack.length - 1];
- context['srsName'] = filter.srsName;
- ol.format.WFS.writeOgcPropertyName_(node, filter.geometryName);
- ol.format.GML3.prototype.writeGeometryElement(node, filter.extent, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.format.filter.Contains} filter Filter.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeContainsFilter_ = function(node, filter, objectStack) {
- var context = objectStack[objectStack.length - 1];
- context['srsName'] = filter.srsName;
- ol.format.WFS.writeOgcPropertyName_(node, filter.geometryName);
- ol.format.GML3.prototype.writeGeometryElement(node, filter.geometry, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.format.filter.Intersects} filter Filter.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeIntersectsFilter_ = function(node, filter, objectStack) {
- var context = objectStack[objectStack.length - 1];
- context['srsName'] = filter.srsName;
- ol.format.WFS.writeOgcPropertyName_(node, filter.geometryName);
- ol.format.GML3.prototype.writeGeometryElement(node, filter.geometry, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.format.filter.Within} filter Filter.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeWithinFilter_ = function(node, filter, objectStack) {
- var context = objectStack[objectStack.length - 1];
- context['srsName'] = filter.srsName;
- ol.format.WFS.writeOgcPropertyName_(node, filter.geometryName);
- ol.format.GML3.prototype.writeGeometryElement(node, filter.geometry, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.format.filter.During} filter Filter.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeDuringFilter_ = function(node, filter, objectStack) {
- var valueReference = ol.xml.createElementNS(ol.format.WFS.FESNS, 'ValueReference');
- ol.format.XSD.writeStringTextNode(valueReference, filter.propertyName);
- node.appendChild(valueReference);
- var timePeriod = ol.xml.createElementNS(ol.format.GMLBase.GMLNS, 'TimePeriod');
- node.appendChild(timePeriod);
- var begin = ol.xml.createElementNS(ol.format.GMLBase.GMLNS, 'begin');
- timePeriod.appendChild(begin);
- ol.format.WFS.writeTimeInstant_(begin, filter.begin);
- var end = ol.xml.createElementNS(ol.format.GMLBase.GMLNS, 'end');
- timePeriod.appendChild(end);
- ol.format.WFS.writeTimeInstant_(end, filter.end);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.format.filter.LogicalNary} filter Filter.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeLogicalFilter_ = function(node, filter, objectStack) {
- /** @type {ol.XmlNodeStackItem} */
- var item = {node: node};
- var conditions = filter.conditions;
- for (var i = 0, ii = conditions.length; i < ii; ++i) {
- var condition = conditions[i];
- ol.xml.pushSerializeAndPop(item,
- ol.format.WFS.GETFEATURE_SERIALIZERS_,
- ol.xml.makeSimpleNodeFactory(condition.getTagName()),
- [condition], objectStack);
- }
- };
- /**
- * @param {Node} node Node.
- * @param {ol.format.filter.Not} filter Filter.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeNotFilter_ = function(node, filter, objectStack) {
- /** @type {ol.XmlNodeStackItem} */
- var item = {node: node};
- var condition = filter.condition;
- ol.xml.pushSerializeAndPop(item,
- ol.format.WFS.GETFEATURE_SERIALIZERS_,
- ol.xml.makeSimpleNodeFactory(condition.getTagName()),
- [condition], objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.format.filter.ComparisonBinary} filter Filter.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeComparisonFilter_ = function(node, filter, objectStack) {
- if (filter.matchCase !== undefined) {
- node.setAttribute('matchCase', filter.matchCase.toString());
- }
- ol.format.WFS.writeOgcPropertyName_(node, filter.propertyName);
- ol.format.WFS.writeOgcLiteral_(node, '' + filter.expression);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.format.filter.IsNull} filter Filter.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeIsNullFilter_ = function(node, filter, objectStack) {
- ol.format.WFS.writeOgcPropertyName_(node, filter.propertyName);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.format.filter.IsBetween} filter Filter.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeIsBetweenFilter_ = function(node, filter, objectStack) {
- ol.format.WFS.writeOgcPropertyName_(node, filter.propertyName);
- var lowerBoundary = ol.xml.createElementNS(ol.format.WFS.OGCNS, 'LowerBoundary');
- node.appendChild(lowerBoundary);
- ol.format.WFS.writeOgcLiteral_(lowerBoundary, '' + filter.lowerBoundary);
- var upperBoundary = ol.xml.createElementNS(ol.format.WFS.OGCNS, 'UpperBoundary');
- node.appendChild(upperBoundary);
- ol.format.WFS.writeOgcLiteral_(upperBoundary, '' + filter.upperBoundary);
- };
- /**
- * @param {Node} node Node.
- * @param {ol.format.filter.IsLike} filter Filter.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeIsLikeFilter_ = function(node, filter, objectStack) {
- node.setAttribute('wildCard', filter.wildCard);
- node.setAttribute('singleChar', filter.singleChar);
- node.setAttribute('escapeChar', filter.escapeChar);
- if (filter.matchCase !== undefined) {
- node.setAttribute('matchCase', filter.matchCase.toString());
- }
- ol.format.WFS.writeOgcPropertyName_(node, filter.propertyName);
- ol.format.WFS.writeOgcLiteral_(node, '' + filter.pattern);
- };
- /**
- * @param {string} tagName Tag name.
- * @param {Node} node Node.
- * @param {string} value Value.
- * @private
- */
- ol.format.WFS.writeOgcExpression_ = function(tagName, node, value) {
- var property = ol.xml.createElementNS(ol.format.WFS.OGCNS, tagName);
- ol.format.XSD.writeStringTextNode(property, value);
- node.appendChild(property);
- };
- /**
- * @param {Node} node Node.
- * @param {string} value PropertyName value.
- * @private
- */
- ol.format.WFS.writeOgcPropertyName_ = function(node, value) {
- ol.format.WFS.writeOgcExpression_('PropertyName', node, value);
- };
- /**
- * @param {Node} node Node.
- * @param {string} value PropertyName value.
- * @private
- */
- ol.format.WFS.writeOgcLiteral_ = function(node, value) {
- ol.format.WFS.writeOgcExpression_('Literal', node, value);
- };
- /**
- * @param {Node} node Node.
- * @param {string} time PropertyName value.
- * @private
- */
- ol.format.WFS.writeTimeInstant_ = function(node, time) {
- var timeInstant = ol.xml.createElementNS(ol.format.GMLBase.GMLNS, 'TimeInstant');
- node.appendChild(timeInstant);
- var timePosition = ol.xml.createElementNS(ol.format.GMLBase.GMLNS, 'timePosition');
- timeInstant.appendChild(timePosition);
- ol.format.XSD.writeStringTextNode(timePosition, time);
- };
- /**
- * @type {Object.<string, Object.<string, ol.XmlSerializer>>}
- * @private
- */
- ol.format.WFS.GETFEATURE_SERIALIZERS_ = {
- 'http://www.opengis.net/wfs': {
- 'Query': ol.xml.makeChildAppender(ol.format.WFS.writeQuery_)
- },
- 'http://www.opengis.net/ogc': {
- 'During': ol.xml.makeChildAppender(ol.format.WFS.writeDuringFilter_),
- 'And': ol.xml.makeChildAppender(ol.format.WFS.writeLogicalFilter_),
- 'Or': ol.xml.makeChildAppender(ol.format.WFS.writeLogicalFilter_),
- 'Not': ol.xml.makeChildAppender(ol.format.WFS.writeNotFilter_),
- 'BBOX': ol.xml.makeChildAppender(ol.format.WFS.writeBboxFilter_),
- 'Contains': ol.xml.makeChildAppender(ol.format.WFS.writeContainsFilter_),
- 'Intersects': ol.xml.makeChildAppender(ol.format.WFS.writeIntersectsFilter_),
- 'Within': ol.xml.makeChildAppender(ol.format.WFS.writeWithinFilter_),
- 'PropertyIsEqualTo': ol.xml.makeChildAppender(ol.format.WFS.writeComparisonFilter_),
- 'PropertyIsNotEqualTo': ol.xml.makeChildAppender(ol.format.WFS.writeComparisonFilter_),
- 'PropertyIsLessThan': ol.xml.makeChildAppender(ol.format.WFS.writeComparisonFilter_),
- 'PropertyIsLessThanOrEqualTo': ol.xml.makeChildAppender(ol.format.WFS.writeComparisonFilter_),
- 'PropertyIsGreaterThan': ol.xml.makeChildAppender(ol.format.WFS.writeComparisonFilter_),
- 'PropertyIsGreaterThanOrEqualTo': ol.xml.makeChildAppender(ol.format.WFS.writeComparisonFilter_),
- 'PropertyIsNull': ol.xml.makeChildAppender(ol.format.WFS.writeIsNullFilter_),
- 'PropertyIsBetween': ol.xml.makeChildAppender(ol.format.WFS.writeIsBetweenFilter_),
- 'PropertyIsLike': ol.xml.makeChildAppender(ol.format.WFS.writeIsLikeFilter_)
- }
- };
- /**
- * Encode filter as WFS `Filter` and return the Node.
- *
- * @param {ol.format.filter.Filter} filter Filter.
- * @return {Node} Result.
- * @api
- */
- ol.format.WFS.writeFilter = function(filter) {
- var child = ol.xml.createElementNS(ol.format.WFS.OGCNS, 'Filter');
- ol.format.WFS.writeFilterCondition_(child, filter, []);
- return child;
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<string>} featureTypes Feature types.
- * @param {Array.<*>} objectStack Node stack.
- * @private
- */
- ol.format.WFS.writeGetFeature_ = function(node, featureTypes, objectStack) {
- var context = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- var item = /** @type {ol.XmlNodeStackItem} */ (ol.obj.assign({}, context));
- item.node = node;
- ol.xml.pushSerializeAndPop(item,
- ol.format.WFS.GETFEATURE_SERIALIZERS_,
- ol.xml.makeSimpleNodeFactory('Query'), featureTypes,
- objectStack);
- };
- /**
- * Encode format as WFS `GetFeature` and return the Node.
- *
- * @param {olx.format.WFSWriteGetFeatureOptions} options Options.
- * @return {Node} Result.
- * @api
- */
- ol.format.WFS.prototype.writeGetFeature = function(options) {
- var node = ol.xml.createElementNS(ol.format.WFS.WFSNS, 'GetFeature');
- node.setAttribute('service', 'WFS');
- node.setAttribute('version', '1.1.0');
- var filter;
- if (options) {
- if (options.handle) {
- node.setAttribute('handle', options.handle);
- }
- if (options.outputFormat) {
- node.setAttribute('outputFormat', options.outputFormat);
- }
- if (options.maxFeatures !== undefined) {
- node.setAttribute('maxFeatures', options.maxFeatures);
- }
- if (options.resultType) {
- node.setAttribute('resultType', options.resultType);
- }
- if (options.startIndex !== undefined) {
- node.setAttribute('startIndex', options.startIndex);
- }
- if (options.count !== undefined) {
- node.setAttribute('count', options.count);
- }
- filter = options.filter;
- if (options.bbox) {
- ol.asserts.assert(options.geometryName,
- 12); // `options.geometryName` must also be provided when `options.bbox` is set
- var bbox = ol.format.filter.bbox(
- /** @type {string} */ (options.geometryName), options.bbox, options.srsName);
- if (filter) {
- // if bbox and filter are both set, combine the two into a single filter
- filter = ol.format.filter.and(filter, bbox);
- } else {
- filter = bbox;
- }
- }
- }
- ol.xml.setAttributeNS(node, 'http://www.w3.org/2001/XMLSchema-instance',
- 'xsi:schemaLocation', this.schemaLocation_);
- /** @type {ol.XmlNodeStackItem} */
- var context = {
- node: node,
- 'srsName': options.srsName,
- 'featureNS': options.featureNS ? options.featureNS : this.featureNS_,
- 'featurePrefix': options.featurePrefix,
- 'geometryName': options.geometryName,
- 'filter': filter,
- 'propertyNames': options.propertyNames ? options.propertyNames : []
- };
- ol.asserts.assert(Array.isArray(options.featureTypes),
- 11); // `options.featureTypes` should be an Array
- ol.format.WFS.writeGetFeature_(node, /** @type {!Array.<string>} */ (options.featureTypes), [context]);
- return node;
- };
- /**
- * Encode format as WFS `Transaction` and return the Node.
- *
- * @param {Array.<ol.Feature>} inserts The features to insert.
- * @param {Array.<ol.Feature>} updates The features to update.
- * @param {Array.<ol.Feature>} deletes The features to delete.
- * @param {olx.format.WFSWriteTransactionOptions} options Write options.
- * @return {Node} Result.
- * @api
- */
- ol.format.WFS.prototype.writeTransaction = function(inserts, updates, deletes,
- options) {
- var objectStack = [];
- var node = ol.xml.createElementNS(ol.format.WFS.WFSNS, 'Transaction');
- var version = options.version ?
- options.version : ol.format.WFS.DEFAULT_VERSION;
- var gmlVersion = version === '1.0.0' ? 2 : 3;
- node.setAttribute('service', 'WFS');
- node.setAttribute('version', version);
- var baseObj;
- /** @type {ol.XmlNodeStackItem} */
- var obj;
- if (options) {
- baseObj = options.gmlOptions ? options.gmlOptions : {};
- if (options.handle) {
- node.setAttribute('handle', options.handle);
- }
- }
- var schemaLocation = ol.format.WFS.SCHEMA_LOCATIONS[version];
- ol.xml.setAttributeNS(node, 'http://www.w3.org/2001/XMLSchema-instance',
- 'xsi:schemaLocation', schemaLocation);
- var featurePrefix = options.featurePrefix ? options.featurePrefix : ol.format.WFS.FEATURE_PREFIX;
- if (inserts) {
- obj = {node: node, 'featureNS': options.featureNS,
- 'featureType': options.featureType, 'featurePrefix': featurePrefix,
- 'gmlVersion': gmlVersion, 'hasZ': options.hasZ, 'srsName': options.srsName};
- ol.obj.assign(obj, baseObj);
- ol.xml.pushSerializeAndPop(obj,
- ol.format.WFS.TRANSACTION_SERIALIZERS_,
- ol.xml.makeSimpleNodeFactory('Insert'), inserts,
- objectStack);
- }
- if (updates) {
- obj = {node: node, 'featureNS': options.featureNS,
- 'featureType': options.featureType, 'featurePrefix': featurePrefix,
- 'gmlVersion': gmlVersion, 'hasZ': options.hasZ, 'srsName': options.srsName};
- ol.obj.assign(obj, baseObj);
- ol.xml.pushSerializeAndPop(obj,
- ol.format.WFS.TRANSACTION_SERIALIZERS_,
- ol.xml.makeSimpleNodeFactory('Update'), updates,
- objectStack);
- }
- if (deletes) {
- ol.xml.pushSerializeAndPop({node: node, 'featureNS': options.featureNS,
- 'featureType': options.featureType, 'featurePrefix': featurePrefix,
- 'gmlVersion': gmlVersion, 'srsName': options.srsName},
- ol.format.WFS.TRANSACTION_SERIALIZERS_,
- ol.xml.makeSimpleNodeFactory('Delete'), deletes,
- objectStack);
- }
- if (options.nativeElements) {
- ol.xml.pushSerializeAndPop({node: node, 'featureNS': options.featureNS,
- 'featureType': options.featureType, 'featurePrefix': featurePrefix,
- 'gmlVersion': gmlVersion, 'srsName': options.srsName},
- ol.format.WFS.TRANSACTION_SERIALIZERS_,
- ol.xml.makeSimpleNodeFactory('Native'), options.nativeElements,
- objectStack);
- }
- return node;
- };
- /**
- * Read the projection from a WFS source.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @return {?ol.proj.Projection} Projection.
- * @api
- */
- ol.format.WFS.prototype.readProjection;
- /**
- * @inheritDoc
- */
- ol.format.WFS.prototype.readProjectionFromDocument = function(doc) {
- for (var n = doc.firstChild; n; n = n.nextSibling) {
- if (n.nodeType == Node.ELEMENT_NODE) {
- return this.readProjectionFromNode(n);
- }
- }
- return null;
- };
- /**
- * @inheritDoc
- */
- ol.format.WFS.prototype.readProjectionFromNode = function(node) {
- if (node.firstElementChild &&
- node.firstElementChild.firstElementChild) {
- node = node.firstElementChild.firstElementChild;
- for (var n = node.firstElementChild; n; n = n.nextElementSibling) {
- if (!(n.childNodes.length === 0 ||
- (n.childNodes.length === 1 &&
- n.firstChild.nodeType === 3))) {
- var objectStack = [{}];
- this.gmlFormat_.readGeometryElement(n, objectStack);
- return ol.proj.get(objectStack.pop().srsName);
- }
- }
- }
- return null;
- };
- goog.provide('ol.format.WKT');
- goog.require('ol');
- goog.require('ol.Feature');
- goog.require('ol.format.Feature');
- goog.require('ol.format.TextFeature');
- goog.require('ol.geom.GeometryCollection');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.LineString');
- goog.require('ol.geom.MultiLineString');
- goog.require('ol.geom.MultiPoint');
- goog.require('ol.geom.MultiPolygon');
- goog.require('ol.geom.Point');
- goog.require('ol.geom.Polygon');
- goog.require('ol.geom.SimpleGeometry');
- /**
- * @classdesc
- * Geometry format for reading and writing data in the `WellKnownText` (WKT)
- * format.
- *
- * @constructor
- * @extends {ol.format.TextFeature}
- * @param {olx.format.WKTOptions=} opt_options Options.
- * @api
- */
- ol.format.WKT = function(opt_options) {
- var options = opt_options ? opt_options : {};
- ol.format.TextFeature.call(this);
- /**
- * Split GeometryCollection into multiple features.
- * @type {boolean}
- * @private
- */
- this.splitCollection_ = options.splitCollection !== undefined ?
- options.splitCollection : false;
- };
- ol.inherits(ol.format.WKT, ol.format.TextFeature);
- /**
- * @const
- * @type {string}
- */
- ol.format.WKT.EMPTY = 'EMPTY';
- /**
- * @const
- * @type {string}
- */
- ol.format.WKT.Z = 'Z';
- /**
- * @const
- * @type {string}
- */
- ol.format.WKT.M = 'M';
- /**
- * @const
- * @type {string}
- */
- ol.format.WKT.ZM = 'ZM';
- /**
- * @param {ol.geom.Point} geom Point geometry.
- * @return {string} Coordinates part of Point as WKT.
- * @private
- */
- ol.format.WKT.encodePointGeometry_ = function(geom) {
- var coordinates = geom.getCoordinates();
- if (coordinates.length === 0) {
- return '';
- }
- return coordinates.join(' ');
- };
- /**
- * @param {ol.geom.MultiPoint} geom MultiPoint geometry.
- * @return {string} Coordinates part of MultiPoint as WKT.
- * @private
- */
- ol.format.WKT.encodeMultiPointGeometry_ = function(geom) {
- var array = [];
- var components = geom.getPoints();
- for (var i = 0, ii = components.length; i < ii; ++i) {
- array.push('(' + ol.format.WKT.encodePointGeometry_(components[i]) + ')');
- }
- return array.join(',');
- };
- /**
- * @param {ol.geom.GeometryCollection} geom GeometryCollection geometry.
- * @return {string} Coordinates part of GeometryCollection as WKT.
- * @private
- */
- ol.format.WKT.encodeGeometryCollectionGeometry_ = function(geom) {
- var array = [];
- var geoms = geom.getGeometries();
- for (var i = 0, ii = geoms.length; i < ii; ++i) {
- array.push(ol.format.WKT.encode_(geoms[i]));
- }
- return array.join(',');
- };
- /**
- * @param {ol.geom.LineString|ol.geom.LinearRing} geom LineString geometry.
- * @return {string} Coordinates part of LineString as WKT.
- * @private
- */
- ol.format.WKT.encodeLineStringGeometry_ = function(geom) {
- var coordinates = geom.getCoordinates();
- var array = [];
- for (var i = 0, ii = coordinates.length; i < ii; ++i) {
- array.push(coordinates[i].join(' '));
- }
- return array.join(',');
- };
- /**
- * @param {ol.geom.MultiLineString} geom MultiLineString geometry.
- * @return {string} Coordinates part of MultiLineString as WKT.
- * @private
- */
- ol.format.WKT.encodeMultiLineStringGeometry_ = function(geom) {
- var array = [];
- var components = geom.getLineStrings();
- for (var i = 0, ii = components.length; i < ii; ++i) {
- array.push('(' + ol.format.WKT.encodeLineStringGeometry_(
- components[i]) + ')');
- }
- return array.join(',');
- };
- /**
- * @param {ol.geom.Polygon} geom Polygon geometry.
- * @return {string} Coordinates part of Polygon as WKT.
- * @private
- */
- ol.format.WKT.encodePolygonGeometry_ = function(geom) {
- var array = [];
- var rings = geom.getLinearRings();
- for (var i = 0, ii = rings.length; i < ii; ++i) {
- array.push('(' + ol.format.WKT.encodeLineStringGeometry_(
- rings[i]) + ')');
- }
- return array.join(',');
- };
- /**
- * @param {ol.geom.MultiPolygon} geom MultiPolygon geometry.
- * @return {string} Coordinates part of MultiPolygon as WKT.
- * @private
- */
- ol.format.WKT.encodeMultiPolygonGeometry_ = function(geom) {
- var array = [];
- var components = geom.getPolygons();
- for (var i = 0, ii = components.length; i < ii; ++i) {
- array.push('(' + ol.format.WKT.encodePolygonGeometry_(
- components[i]) + ')');
- }
- return array.join(',');
- };
- /**
- * @param {ol.geom.SimpleGeometry} geom SimpleGeometry geometry.
- * @return {string} Potential dimensional information for WKT type.
- * @private
- */
- ol.format.WKT.encodeGeometryLayout_ = function(geom) {
- var layout = geom.getLayout();
- var dimInfo = '';
- if (layout === ol.geom.GeometryLayout.XYZ || layout === ol.geom.GeometryLayout.XYZM) {
- dimInfo += ol.format.WKT.Z;
- }
- if (layout === ol.geom.GeometryLayout.XYM || layout === ol.geom.GeometryLayout.XYZM) {
- dimInfo += ol.format.WKT.M;
- }
- return dimInfo;
- };
- /**
- * Encode a geometry as WKT.
- * @param {ol.geom.Geometry} geom The geometry to encode.
- * @return {string} WKT string for the geometry.
- * @private
- */
- ol.format.WKT.encode_ = function(geom) {
- var type = geom.getType();
- var geometryEncoder = ol.format.WKT.GeometryEncoder_[type];
- var enc = geometryEncoder(geom);
- type = type.toUpperCase();
- if (geom instanceof ol.geom.SimpleGeometry) {
- var dimInfo = ol.format.WKT.encodeGeometryLayout_(geom);
- if (dimInfo.length > 0) {
- type += ' ' + dimInfo;
- }
- }
- if (enc.length === 0) {
- return type + ' ' + ol.format.WKT.EMPTY;
- }
- return type + '(' + enc + ')';
- };
- /**
- * @const
- * @type {Object.<string, function(ol.geom.Geometry): string>}
- * @private
- */
- ol.format.WKT.GeometryEncoder_ = {
- 'Point': ol.format.WKT.encodePointGeometry_,
- 'LineString': ol.format.WKT.encodeLineStringGeometry_,
- 'Polygon': ol.format.WKT.encodePolygonGeometry_,
- 'MultiPoint': ol.format.WKT.encodeMultiPointGeometry_,
- 'MultiLineString': ol.format.WKT.encodeMultiLineStringGeometry_,
- 'MultiPolygon': ol.format.WKT.encodeMultiPolygonGeometry_,
- 'GeometryCollection': ol.format.WKT.encodeGeometryCollectionGeometry_
- };
- /**
- * Parse a WKT string.
- * @param {string} wkt WKT string.
- * @return {ol.geom.Geometry|undefined}
- * The geometry created.
- * @private
- */
- ol.format.WKT.prototype.parse_ = function(wkt) {
- var lexer = new ol.format.WKT.Lexer(wkt);
- var parser = new ol.format.WKT.Parser(lexer);
- return parser.parse();
- };
- /**
- * Read a feature from a WKT source.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {ol.Feature} Feature.
- * @api
- */
- ol.format.WKT.prototype.readFeature;
- /**
- * @inheritDoc
- */
- ol.format.WKT.prototype.readFeatureFromText = function(text, opt_options) {
- var geom = this.readGeometryFromText(text, opt_options);
- if (geom) {
- var feature = new ol.Feature();
- feature.setGeometry(geom);
- return feature;
- }
- return null;
- };
- /**
- * Read all features from a WKT source.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {Array.<ol.Feature>} Features.
- * @api
- */
- ol.format.WKT.prototype.readFeatures;
- /**
- * @inheritDoc
- */
- ol.format.WKT.prototype.readFeaturesFromText = function(text, opt_options) {
- var geometries = [];
- var geometry = this.readGeometryFromText(text, opt_options);
- if (this.splitCollection_ &&
- geometry.getType() == ol.geom.GeometryType.GEOMETRY_COLLECTION) {
- geometries = (/** @type {ol.geom.GeometryCollection} */ (geometry))
- .getGeometriesArray();
- } else {
- geometries = [geometry];
- }
- var feature, features = [];
- for (var i = 0, ii = geometries.length; i < ii; ++i) {
- feature = new ol.Feature();
- feature.setGeometry(geometries[i]);
- features.push(feature);
- }
- return features;
- };
- /**
- * Read a single geometry from a WKT source.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {ol.geom.Geometry} Geometry.
- * @api
- */
- ol.format.WKT.prototype.readGeometry;
- /**
- * @inheritDoc
- */
- ol.format.WKT.prototype.readGeometryFromText = function(text, opt_options) {
- var geometry = this.parse_(text);
- if (geometry) {
- return /** @type {ol.geom.Geometry} */ (
- ol.format.Feature.transformWithOptions(geometry, false, opt_options));
- } else {
- return null;
- }
- };
- /**
- * Encode a feature as a WKT string.
- *
- * @function
- * @param {ol.Feature} feature Feature.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {string} WKT string.
- * @api
- */
- ol.format.WKT.prototype.writeFeature;
- /**
- * @inheritDoc
- */
- ol.format.WKT.prototype.writeFeatureText = function(feature, opt_options) {
- var geometry = feature.getGeometry();
- if (geometry) {
- return this.writeGeometryText(geometry, opt_options);
- }
- return '';
- };
- /**
- * Encode an array of features as a WKT string.
- *
- * @function
- * @param {Array.<ol.Feature>} features Features.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {string} WKT string.
- * @api
- */
- ol.format.WKT.prototype.writeFeatures;
- /**
- * @inheritDoc
- */
- ol.format.WKT.prototype.writeFeaturesText = function(features, opt_options) {
- if (features.length == 1) {
- return this.writeFeatureText(features[0], opt_options);
- }
- var geometries = [];
- for (var i = 0, ii = features.length; i < ii; ++i) {
- geometries.push(features[i].getGeometry());
- }
- var collection = new ol.geom.GeometryCollection(geometries);
- return this.writeGeometryText(collection, opt_options);
- };
- /**
- * Write a single geometry as a WKT string.
- *
- * @function
- * @param {ol.geom.Geometry} geometry Geometry.
- * @param {olx.format.WriteOptions=} opt_options Write options.
- * @return {string} WKT string.
- * @api
- */
- ol.format.WKT.prototype.writeGeometry;
- /**
- * @inheritDoc
- */
- ol.format.WKT.prototype.writeGeometryText = function(geometry, opt_options) {
- return ol.format.WKT.encode_(/** @type {ol.geom.Geometry} */ (
- ol.format.Feature.transformWithOptions(geometry, true, opt_options)));
- };
- /**
- * @const
- * @enum {number}
- * @private
- */
- ol.format.WKT.TokenType_ = {
- TEXT: 1,
- LEFT_PAREN: 2,
- RIGHT_PAREN: 3,
- NUMBER: 4,
- COMMA: 5,
- EOF: 6
- };
- /**
- * Class to tokenize a WKT string.
- * @param {string} wkt WKT string.
- * @constructor
- * @protected
- */
- ol.format.WKT.Lexer = function(wkt) {
- /**
- * @type {string}
- */
- this.wkt = wkt;
- /**
- * @type {number}
- * @private
- */
- this.index_ = -1;
- };
- /**
- * @param {string} c Character.
- * @return {boolean} Whether the character is alphabetic.
- * @private
- */
- ol.format.WKT.Lexer.prototype.isAlpha_ = function(c) {
- return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z';
- };
- /**
- * @param {string} c Character.
- * @param {boolean=} opt_decimal Whether the string number
- * contains a dot, i.e. is a decimal number.
- * @return {boolean} Whether the character is numeric.
- * @private
- */
- ol.format.WKT.Lexer.prototype.isNumeric_ = function(c, opt_decimal) {
- var decimal = opt_decimal !== undefined ? opt_decimal : false;
- return c >= '0' && c <= '9' || c == '.' && !decimal;
- };
- /**
- * @param {string} c Character.
- * @return {boolean} Whether the character is whitespace.
- * @private
- */
- ol.format.WKT.Lexer.prototype.isWhiteSpace_ = function(c) {
- return c == ' ' || c == '\t' || c == '\r' || c == '\n';
- };
- /**
- * @return {string} Next string character.
- * @private
- */
- ol.format.WKT.Lexer.prototype.nextChar_ = function() {
- return this.wkt.charAt(++this.index_);
- };
- /**
- * Fetch and return the next token.
- * @return {!ol.WKTToken} Next string token.
- */
- ol.format.WKT.Lexer.prototype.nextToken = function() {
- var c = this.nextChar_();
- var token = {position: this.index_, value: c};
- if (c == '(') {
- token.type = ol.format.WKT.TokenType_.LEFT_PAREN;
- } else if (c == ',') {
- token.type = ol.format.WKT.TokenType_.COMMA;
- } else if (c == ')') {
- token.type = ol.format.WKT.TokenType_.RIGHT_PAREN;
- } else if (this.isNumeric_(c) || c == '-') {
- token.type = ol.format.WKT.TokenType_.NUMBER;
- token.value = this.readNumber_();
- } else if (this.isAlpha_(c)) {
- token.type = ol.format.WKT.TokenType_.TEXT;
- token.value = this.readText_();
- } else if (this.isWhiteSpace_(c)) {
- return this.nextToken();
- } else if (c === '') {
- token.type = ol.format.WKT.TokenType_.EOF;
- } else {
- throw new Error('Unexpected character: ' + c);
- }
- return token;
- };
- /**
- * @return {number} Numeric token value.
- * @private
- */
- ol.format.WKT.Lexer.prototype.readNumber_ = function() {
- var c, index = this.index_;
- var decimal = false;
- var scientificNotation = false;
- do {
- if (c == '.') {
- decimal = true;
- } else if (c == 'e' || c == 'E') {
- scientificNotation = true;
- }
- c = this.nextChar_();
- } while (
- this.isNumeric_(c, decimal) ||
- // if we haven't detected a scientific number before, 'e' or 'E'
- // hint that we should continue to read
- !scientificNotation && (c == 'e' || c == 'E') ||
- // once we know that we have a scientific number, both '-' and '+'
- // are allowed
- scientificNotation && (c == '-' || c == '+')
- );
- return parseFloat(this.wkt.substring(index, this.index_--));
- };
- /**
- * @return {string} String token value.
- * @private
- */
- ol.format.WKT.Lexer.prototype.readText_ = function() {
- var c, index = this.index_;
- do {
- c = this.nextChar_();
- } while (this.isAlpha_(c));
- return this.wkt.substring(index, this.index_--).toUpperCase();
- };
- /**
- * Class to parse the tokens from the WKT string.
- * @param {ol.format.WKT.Lexer} lexer The lexer.
- * @constructor
- * @protected
- */
- ol.format.WKT.Parser = function(lexer) {
- /**
- * @type {ol.format.WKT.Lexer}
- * @private
- */
- this.lexer_ = lexer;
- /**
- * @type {ol.WKTToken}
- * @private
- */
- this.token_;
- /**
- * @type {ol.geom.GeometryLayout}
- * @private
- */
- this.layout_ = ol.geom.GeometryLayout.XY;
- };
- /**
- * Fetch the next token form the lexer and replace the active token.
- * @private
- */
- ol.format.WKT.Parser.prototype.consume_ = function() {
- this.token_ = this.lexer_.nextToken();
- };
- /**
- * Tests if the given type matches the type of the current token.
- * @param {ol.format.WKT.TokenType_} type Token type.
- * @return {boolean} Whether the token matches the given type.
- */
- ol.format.WKT.Parser.prototype.isTokenType = function(type) {
- var isMatch = this.token_.type == type;
- return isMatch;
- };
- /**
- * If the given type matches the current token, consume it.
- * @param {ol.format.WKT.TokenType_} type Token type.
- * @return {boolean} Whether the token matches the given type.
- */
- ol.format.WKT.Parser.prototype.match = function(type) {
- var isMatch = this.isTokenType(type);
- if (isMatch) {
- this.consume_();
- }
- return isMatch;
- };
- /**
- * Try to parse the tokens provided by the lexer.
- * @return {ol.geom.Geometry} The geometry.
- */
- ol.format.WKT.Parser.prototype.parse = function() {
- this.consume_();
- var geometry = this.parseGeometry_();
- return geometry;
- };
- /**
- * Try to parse the dimensional info.
- * @return {ol.geom.GeometryLayout} The layout.
- * @private
- */
- ol.format.WKT.Parser.prototype.parseGeometryLayout_ = function() {
- var layout = ol.geom.GeometryLayout.XY;
- var dimToken = this.token_;
- if (this.isTokenType(ol.format.WKT.TokenType_.TEXT)) {
- var dimInfo = dimToken.value;
- if (dimInfo === ol.format.WKT.Z) {
- layout = ol.geom.GeometryLayout.XYZ;
- } else if (dimInfo === ol.format.WKT.M) {
- layout = ol.geom.GeometryLayout.XYM;
- } else if (dimInfo === ol.format.WKT.ZM) {
- layout = ol.geom.GeometryLayout.XYZM;
- }
- if (layout !== ol.geom.GeometryLayout.XY) {
- this.consume_();
- }
- }
- return layout;
- };
- /**
- * @return {!ol.geom.Geometry} The geometry.
- * @private
- */
- ol.format.WKT.Parser.prototype.parseGeometry_ = function() {
- var token = this.token_;
- if (this.match(ol.format.WKT.TokenType_.TEXT)) {
- var geomType = token.value;
- this.layout_ = this.parseGeometryLayout_();
- if (geomType == ol.geom.GeometryType.GEOMETRY_COLLECTION.toUpperCase()) {
- var geometries = this.parseGeometryCollectionText_();
- return new ol.geom.GeometryCollection(geometries);
- } else {
- var parser = ol.format.WKT.Parser.GeometryParser_[geomType];
- var ctor = ol.format.WKT.Parser.GeometryConstructor_[geomType];
- if (!parser || !ctor) {
- throw new Error('Invalid geometry type: ' + geomType);
- }
- var coordinates = parser.call(this);
- return new ctor(coordinates, this.layout_);
- }
- }
- throw new Error(this.formatErrorMessage_());
- };
- /**
- * @return {!Array.<ol.geom.Geometry>} A collection of geometries.
- * @private
- */
- ol.format.WKT.Parser.prototype.parseGeometryCollectionText_ = function() {
- if (this.match(ol.format.WKT.TokenType_.LEFT_PAREN)) {
- var geometries = [];
- do {
- geometries.push(this.parseGeometry_());
- } while (this.match(ol.format.WKT.TokenType_.COMMA));
- if (this.match(ol.format.WKT.TokenType_.RIGHT_PAREN)) {
- return geometries;
- }
- } else if (this.isEmptyGeometry_()) {
- return [];
- }
- throw new Error(this.formatErrorMessage_());
- };
- /**
- * @return {Array.<number>} All values in a point.
- * @private
- */
- ol.format.WKT.Parser.prototype.parsePointText_ = function() {
- if (this.match(ol.format.WKT.TokenType_.LEFT_PAREN)) {
- var coordinates = this.parsePoint_();
- if (this.match(ol.format.WKT.TokenType_.RIGHT_PAREN)) {
- return coordinates;
- }
- } else if (this.isEmptyGeometry_()) {
- return null;
- }
- throw new Error(this.formatErrorMessage_());
- };
- /**
- * @return {!Array.<!Array.<number>>} All points in a linestring.
- * @private
- */
- ol.format.WKT.Parser.prototype.parseLineStringText_ = function() {
- if (this.match(ol.format.WKT.TokenType_.LEFT_PAREN)) {
- var coordinates = this.parsePointList_();
- if (this.match(ol.format.WKT.TokenType_.RIGHT_PAREN)) {
- return coordinates;
- }
- } else if (this.isEmptyGeometry_()) {
- return [];
- }
- throw new Error(this.formatErrorMessage_());
- };
- /**
- * @return {!Array.<!Array.<number>>} All points in a polygon.
- * @private
- */
- ol.format.WKT.Parser.prototype.parsePolygonText_ = function() {
- if (this.match(ol.format.WKT.TokenType_.LEFT_PAREN)) {
- var coordinates = this.parseLineStringTextList_();
- if (this.match(ol.format.WKT.TokenType_.RIGHT_PAREN)) {
- return coordinates;
- }
- } else if (this.isEmptyGeometry_()) {
- return [];
- }
- throw new Error(this.formatErrorMessage_());
- };
- /**
- * @return {!Array.<!Array.<number>>} All points in a multipoint.
- * @private
- */
- ol.format.WKT.Parser.prototype.parseMultiPointText_ = function() {
- if (this.match(ol.format.WKT.TokenType_.LEFT_PAREN)) {
- var coordinates;
- if (this.token_.type == ol.format.WKT.TokenType_.LEFT_PAREN) {
- coordinates = this.parsePointTextList_();
- } else {
- coordinates = this.parsePointList_();
- }
- if (this.match(ol.format.WKT.TokenType_.RIGHT_PAREN)) {
- return coordinates;
- }
- } else if (this.isEmptyGeometry_()) {
- return [];
- }
- throw new Error(this.formatErrorMessage_());
- };
- /**
- * @return {!Array.<!Array.<number>>} All linestring points
- * in a multilinestring.
- * @private
- */
- ol.format.WKT.Parser.prototype.parseMultiLineStringText_ = function() {
- if (this.match(ol.format.WKT.TokenType_.LEFT_PAREN)) {
- var coordinates = this.parseLineStringTextList_();
- if (this.match(ol.format.WKT.TokenType_.RIGHT_PAREN)) {
- return coordinates;
- }
- } else if (this.isEmptyGeometry_()) {
- return [];
- }
- throw new Error(this.formatErrorMessage_());
- };
- /**
- * @return {!Array.<!Array.<number>>} All polygon points in a multipolygon.
- * @private
- */
- ol.format.WKT.Parser.prototype.parseMultiPolygonText_ = function() {
- if (this.match(ol.format.WKT.TokenType_.LEFT_PAREN)) {
- var coordinates = this.parsePolygonTextList_();
- if (this.match(ol.format.WKT.TokenType_.RIGHT_PAREN)) {
- return coordinates;
- }
- } else if (this.isEmptyGeometry_()) {
- return [];
- }
- throw new Error(this.formatErrorMessage_());
- };
- /**
- * @return {!Array.<number>} A point.
- * @private
- */
- ol.format.WKT.Parser.prototype.parsePoint_ = function() {
- var coordinates = [];
- var dimensions = this.layout_.length;
- for (var i = 0; i < dimensions; ++i) {
- var token = this.token_;
- if (this.match(ol.format.WKT.TokenType_.NUMBER)) {
- coordinates.push(token.value);
- } else {
- break;
- }
- }
- if (coordinates.length == dimensions) {
- return coordinates;
- }
- throw new Error(this.formatErrorMessage_());
- };
- /**
- * @return {!Array.<!Array.<number>>} An array of points.
- * @private
- */
- ol.format.WKT.Parser.prototype.parsePointList_ = function() {
- var coordinates = [this.parsePoint_()];
- while (this.match(ol.format.WKT.TokenType_.COMMA)) {
- coordinates.push(this.parsePoint_());
- }
- return coordinates;
- };
- /**
- * @return {!Array.<!Array.<number>>} An array of points.
- * @private
- */
- ol.format.WKT.Parser.prototype.parsePointTextList_ = function() {
- var coordinates = [this.parsePointText_()];
- while (this.match(ol.format.WKT.TokenType_.COMMA)) {
- coordinates.push(this.parsePointText_());
- }
- return coordinates;
- };
- /**
- * @return {!Array.<!Array.<number>>} An array of points.
- * @private
- */
- ol.format.WKT.Parser.prototype.parseLineStringTextList_ = function() {
- var coordinates = [this.parseLineStringText_()];
- while (this.match(ol.format.WKT.TokenType_.COMMA)) {
- coordinates.push(this.parseLineStringText_());
- }
- return coordinates;
- };
- /**
- * @return {!Array.<!Array.<number>>} An array of points.
- * @private
- */
- ol.format.WKT.Parser.prototype.parsePolygonTextList_ = function() {
- var coordinates = [this.parsePolygonText_()];
- while (this.match(ol.format.WKT.TokenType_.COMMA)) {
- coordinates.push(this.parsePolygonText_());
- }
- return coordinates;
- };
- /**
- * @return {boolean} Whether the token implies an empty geometry.
- * @private
- */
- ol.format.WKT.Parser.prototype.isEmptyGeometry_ = function() {
- var isEmpty = this.isTokenType(ol.format.WKT.TokenType_.TEXT) &&
- this.token_.value == ol.format.WKT.EMPTY;
- if (isEmpty) {
- this.consume_();
- }
- return isEmpty;
- };
- /**
- * Create an error message for an unexpected token error.
- * @return {string} Error message.
- * @private
- */
- ol.format.WKT.Parser.prototype.formatErrorMessage_ = function() {
- return 'Unexpected `' + this.token_.value + '` at position ' +
- this.token_.position + ' in `' + this.lexer_.wkt + '`';
- };
- /**
- * @enum {function (new:ol.geom.Geometry, Array, ol.geom.GeometryLayout)}
- * @private
- */
- ol.format.WKT.Parser.GeometryConstructor_ = {
- 'POINT': ol.geom.Point,
- 'LINESTRING': ol.geom.LineString,
- 'POLYGON': ol.geom.Polygon,
- 'MULTIPOINT': ol.geom.MultiPoint,
- 'MULTILINESTRING': ol.geom.MultiLineString,
- 'MULTIPOLYGON': ol.geom.MultiPolygon
- };
- /**
- * @enum {(function(): Array)}
- * @private
- */
- ol.format.WKT.Parser.GeometryParser_ = {
- 'POINT': ol.format.WKT.Parser.prototype.parsePointText_,
- 'LINESTRING': ol.format.WKT.Parser.prototype.parseLineStringText_,
- 'POLYGON': ol.format.WKT.Parser.prototype.parsePolygonText_,
- 'MULTIPOINT': ol.format.WKT.Parser.prototype.parseMultiPointText_,
- 'MULTILINESTRING': ol.format.WKT.Parser.prototype.parseMultiLineStringText_,
- 'MULTIPOLYGON': ol.format.WKT.Parser.prototype.parseMultiPolygonText_
- };
- goog.provide('ol.format.WMSCapabilities');
- goog.require('ol');
- goog.require('ol.format.XLink');
- goog.require('ol.format.XML');
- goog.require('ol.format.XSD');
- goog.require('ol.xml');
- /**
- * @classdesc
- * Format for reading WMS capabilities data
- *
- * @constructor
- * @extends {ol.format.XML}
- * @api
- */
- ol.format.WMSCapabilities = function() {
- ol.format.XML.call(this);
- /**
- * @type {string|undefined}
- */
- this.version = undefined;
- };
- ol.inherits(ol.format.WMSCapabilities, ol.format.XML);
- /**
- * Read a WMS capabilities document.
- *
- * @function
- * @param {Document|Node|string} source The XML source.
- * @return {Object} An object representing the WMS capabilities.
- * @api
- */
- ol.format.WMSCapabilities.prototype.read;
- /**
- * @inheritDoc
- */
- ol.format.WMSCapabilities.prototype.readFromDocument = function(doc) {
- for (var n = doc.firstChild; n; n = n.nextSibling) {
- if (n.nodeType == Node.ELEMENT_NODE) {
- return this.readFromNode(n);
- }
- }
- return null;
- };
- /**
- * @inheritDoc
- */
- ol.format.WMSCapabilities.prototype.readFromNode = function(node) {
- this.version = node.getAttribute('version').trim();
- var wmsCapabilityObject = ol.xml.pushParseAndPop({
- 'version': this.version
- }, ol.format.WMSCapabilities.PARSERS_, node, []);
- return wmsCapabilityObject ? wmsCapabilityObject : null;
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Attribution object.
- */
- ol.format.WMSCapabilities.readAttribution_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- {}, ol.format.WMSCapabilities.ATTRIBUTION_PARSERS_, node, objectStack);
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object} Bounding box object.
- */
- ol.format.WMSCapabilities.readBoundingBox_ = function(node, objectStack) {
- var extent = [
- ol.format.XSD.readDecimalString(node.getAttribute('minx')),
- ol.format.XSD.readDecimalString(node.getAttribute('miny')),
- ol.format.XSD.readDecimalString(node.getAttribute('maxx')),
- ol.format.XSD.readDecimalString(node.getAttribute('maxy'))
- ];
- var resolutions = [
- ol.format.XSD.readDecimalString(node.getAttribute('resx')),
- ol.format.XSD.readDecimalString(node.getAttribute('resy'))
- ];
- return {
- 'crs': node.getAttribute('CRS'),
- 'extent': extent,
- 'res': resolutions
- };
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {ol.Extent|undefined} Bounding box object.
- */
- ol.format.WMSCapabilities.readEXGeographicBoundingBox_ = function(node, objectStack) {
- var geographicBoundingBox = ol.xml.pushParseAndPop(
- {},
- ol.format.WMSCapabilities.EX_GEOGRAPHIC_BOUNDING_BOX_PARSERS_,
- node, objectStack);
- if (!geographicBoundingBox) {
- return undefined;
- }
- var westBoundLongitude = /** @type {number|undefined} */
- (geographicBoundingBox['westBoundLongitude']);
- var southBoundLatitude = /** @type {number|undefined} */
- (geographicBoundingBox['southBoundLatitude']);
- var eastBoundLongitude = /** @type {number|undefined} */
- (geographicBoundingBox['eastBoundLongitude']);
- var northBoundLatitude = /** @type {number|undefined} */
- (geographicBoundingBox['northBoundLatitude']);
- if (westBoundLongitude === undefined || southBoundLatitude === undefined ||
- eastBoundLongitude === undefined || northBoundLatitude === undefined) {
- return undefined;
- }
- return [
- westBoundLongitude, southBoundLatitude,
- eastBoundLongitude, northBoundLatitude
- ];
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} Capability object.
- */
- ol.format.WMSCapabilities.readCapability_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- {}, ol.format.WMSCapabilities.CAPABILITY_PARSERS_, node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} Service object.
- */
- ol.format.WMSCapabilities.readService_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- {}, ol.format.WMSCapabilities.SERVICE_PARSERS_, node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} Contact information object.
- */
- ol.format.WMSCapabilities.readContactInformation_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- {}, ol.format.WMSCapabilities.CONTACT_INFORMATION_PARSERS_,
- node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} Contact person object.
- */
- ol.format.WMSCapabilities.readContactPersonPrimary_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- {}, ol.format.WMSCapabilities.CONTACT_PERSON_PARSERS_,
- node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} Contact address object.
- */
- ol.format.WMSCapabilities.readContactAddress_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- {}, ol.format.WMSCapabilities.CONTACT_ADDRESS_PARSERS_,
- node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Array.<string>|undefined} Format array.
- */
- ol.format.WMSCapabilities.readException_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- [], ol.format.WMSCapabilities.EXCEPTION_PARSERS_, node, objectStack);
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @private
- * @return {Object|undefined} Layer object.
- */
- ol.format.WMSCapabilities.readCapabilityLayer_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- {}, ol.format.WMSCapabilities.LAYER_PARSERS_, node, objectStack);
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Layer object.
- */
- ol.format.WMSCapabilities.readLayer_ = function(node, objectStack) {
- var parentLayerObject = /** @type {Object.<string,*>} */
- (objectStack[objectStack.length - 1]);
- var layerObject = ol.xml.pushParseAndPop(
- {}, ol.format.WMSCapabilities.LAYER_PARSERS_, node, objectStack);
- if (!layerObject) {
- return undefined;
- }
- var queryable =
- ol.format.XSD.readBooleanString(node.getAttribute('queryable'));
- if (queryable === undefined) {
- queryable = parentLayerObject['queryable'];
- }
- layerObject['queryable'] = queryable !== undefined ? queryable : false;
- var cascaded = ol.format.XSD.readNonNegativeIntegerString(
- node.getAttribute('cascaded'));
- if (cascaded === undefined) {
- cascaded = parentLayerObject['cascaded'];
- }
- layerObject['cascaded'] = cascaded;
- var opaque = ol.format.XSD.readBooleanString(node.getAttribute('opaque'));
- if (opaque === undefined) {
- opaque = parentLayerObject['opaque'];
- }
- layerObject['opaque'] = opaque !== undefined ? opaque : false;
- var noSubsets =
- ol.format.XSD.readBooleanString(node.getAttribute('noSubsets'));
- if (noSubsets === undefined) {
- noSubsets = parentLayerObject['noSubsets'];
- }
- layerObject['noSubsets'] = noSubsets !== undefined ? noSubsets : false;
- var fixedWidth =
- ol.format.XSD.readDecimalString(node.getAttribute('fixedWidth'));
- if (!fixedWidth) {
- fixedWidth = parentLayerObject['fixedWidth'];
- }
- layerObject['fixedWidth'] = fixedWidth;
- var fixedHeight =
- ol.format.XSD.readDecimalString(node.getAttribute('fixedHeight'));
- if (!fixedHeight) {
- fixedHeight = parentLayerObject['fixedHeight'];
- }
- layerObject['fixedHeight'] = fixedHeight;
- // See 7.2.4.8
- var addKeys = ['Style', 'CRS', 'AuthorityURL'];
- addKeys.forEach(function(key) {
- if (key in parentLayerObject) {
- var childValue = layerObject[key] || [];
- layerObject[key] = childValue.concat(parentLayerObject[key]);
- }
- });
- var replaceKeys = ['EX_GeographicBoundingBox', 'BoundingBox', 'Dimension',
- 'Attribution', 'MinScaleDenominator', 'MaxScaleDenominator'];
- replaceKeys.forEach(function(key) {
- if (!(key in layerObject)) {
- var parentValue = parentLayerObject[key];
- layerObject[key] = parentValue;
- }
- });
- return layerObject;
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object} Dimension object.
- */
- ol.format.WMSCapabilities.readDimension_ = function(node, objectStack) {
- var dimensionObject = {
- 'name': node.getAttribute('name'),
- 'units': node.getAttribute('units'),
- 'unitSymbol': node.getAttribute('unitSymbol'),
- 'default': node.getAttribute('default'),
- 'multipleValues': ol.format.XSD.readBooleanString(
- node.getAttribute('multipleValues')),
- 'nearestValue': ol.format.XSD.readBooleanString(
- node.getAttribute('nearestValue')),
- 'current': ol.format.XSD.readBooleanString(node.getAttribute('current')),
- 'values': ol.format.XSD.readString(node)
- };
- return dimensionObject;
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Online resource object.
- */
- ol.format.WMSCapabilities.readFormatOnlineresource_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- {}, ol.format.WMSCapabilities.FORMAT_ONLINERESOURCE_PARSERS_,
- node, objectStack);
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Request object.
- */
- ol.format.WMSCapabilities.readRequest_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- {}, ol.format.WMSCapabilities.REQUEST_PARSERS_, node, objectStack);
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} DCP type object.
- */
- ol.format.WMSCapabilities.readDCPType_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- {}, ol.format.WMSCapabilities.DCPTYPE_PARSERS_, node, objectStack);
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} HTTP object.
- */
- ol.format.WMSCapabilities.readHTTP_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- {}, ol.format.WMSCapabilities.HTTP_PARSERS_, node, objectStack);
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Operation type object.
- */
- ol.format.WMSCapabilities.readOperationType_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- {}, ol.format.WMSCapabilities.OPERATIONTYPE_PARSERS_, node, objectStack);
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Online resource object.
- */
- ol.format.WMSCapabilities.readSizedFormatOnlineresource_ = function(node, objectStack) {
- var formatOnlineresource =
- ol.format.WMSCapabilities.readFormatOnlineresource_(node, objectStack);
- if (formatOnlineresource) {
- var size = [
- ol.format.XSD.readNonNegativeIntegerString(node.getAttribute('width')),
- ol.format.XSD.readNonNegativeIntegerString(node.getAttribute('height'))
- ];
- formatOnlineresource['size'] = size;
- return formatOnlineresource;
- }
- return undefined;
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Authority URL object.
- */
- ol.format.WMSCapabilities.readAuthorityURL_ = function(node, objectStack) {
- var authorityObject =
- ol.format.WMSCapabilities.readFormatOnlineresource_(node, objectStack);
- if (authorityObject) {
- authorityObject['name'] = node.getAttribute('name');
- return authorityObject;
- }
- return undefined;
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Metadata URL object.
- */
- ol.format.WMSCapabilities.readMetadataURL_ = function(node, objectStack) {
- var metadataObject =
- ol.format.WMSCapabilities.readFormatOnlineresource_(node, objectStack);
- if (metadataObject) {
- metadataObject['type'] = node.getAttribute('type');
- return metadataObject;
- }
- return undefined;
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Style object.
- */
- ol.format.WMSCapabilities.readStyle_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- {}, ol.format.WMSCapabilities.STYLE_PARSERS_, node, objectStack);
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Array.<string>|undefined} Keyword list.
- */
- ol.format.WMSCapabilities.readKeywordList_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop(
- [], ol.format.WMSCapabilities.KEYWORDLIST_PARSERS_, node, objectStack);
- };
- /**
- * @const
- * @private
- * @type {Array.<string>}
- */
- ol.format.WMSCapabilities.NAMESPACE_URIS_ = [
- null,
- 'http://www.opengis.net/wms'
- ];
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMSCapabilities.PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMSCapabilities.NAMESPACE_URIS_, {
- 'Service': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readService_),
- 'Capability': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readCapability_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMSCapabilities.CAPABILITY_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMSCapabilities.NAMESPACE_URIS_, {
- 'Request': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readRequest_),
- 'Exception': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readException_),
- 'Layer': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readCapabilityLayer_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMSCapabilities.SERVICE_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMSCapabilities.NAMESPACE_URIS_, {
- 'Name': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'Title': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'Abstract': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'KeywordList': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readKeywordList_),
- 'OnlineResource': ol.xml.makeObjectPropertySetter(
- ol.format.XLink.readHref),
- 'ContactInformation': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readContactInformation_),
- 'Fees': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'AccessConstraints': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString),
- 'LayerLimit': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readNonNegativeInteger),
- 'MaxWidth': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readNonNegativeInteger),
- 'MaxHeight': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readNonNegativeInteger)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMSCapabilities.CONTACT_INFORMATION_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMSCapabilities.NAMESPACE_URIS_, {
- 'ContactPersonPrimary': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readContactPersonPrimary_),
- 'ContactPosition': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString),
- 'ContactAddress': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readContactAddress_),
- 'ContactVoiceTelephone': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString),
- 'ContactFacsimileTelephone': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString),
- 'ContactElectronicMailAddress': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMSCapabilities.CONTACT_PERSON_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMSCapabilities.NAMESPACE_URIS_, {
- 'ContactPerson': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString),
- 'ContactOrganization': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMSCapabilities.CONTACT_ADDRESS_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMSCapabilities.NAMESPACE_URIS_, {
- 'AddressType': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'Address': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'City': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'StateOrProvince': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString),
- 'PostCode': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'Country': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMSCapabilities.EXCEPTION_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMSCapabilities.NAMESPACE_URIS_, {
- 'Format': ol.xml.makeArrayPusher(ol.format.XSD.readString)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMSCapabilities.LAYER_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMSCapabilities.NAMESPACE_URIS_, {
- 'Name': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'Title': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'Abstract': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'KeywordList': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readKeywordList_),
- 'CRS': ol.xml.makeObjectPropertyPusher(ol.format.XSD.readString),
- 'EX_GeographicBoundingBox': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readEXGeographicBoundingBox_),
- 'BoundingBox': ol.xml.makeObjectPropertyPusher(
- ol.format.WMSCapabilities.readBoundingBox_),
- 'Dimension': ol.xml.makeObjectPropertyPusher(
- ol.format.WMSCapabilities.readDimension_),
- 'Attribution': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readAttribution_),
- 'AuthorityURL': ol.xml.makeObjectPropertyPusher(
- ol.format.WMSCapabilities.readAuthorityURL_),
- 'Identifier': ol.xml.makeObjectPropertyPusher(ol.format.XSD.readString),
- 'MetadataURL': ol.xml.makeObjectPropertyPusher(
- ol.format.WMSCapabilities.readMetadataURL_),
- 'DataURL': ol.xml.makeObjectPropertyPusher(
- ol.format.WMSCapabilities.readFormatOnlineresource_),
- 'FeatureListURL': ol.xml.makeObjectPropertyPusher(
- ol.format.WMSCapabilities.readFormatOnlineresource_),
- 'Style': ol.xml.makeObjectPropertyPusher(
- ol.format.WMSCapabilities.readStyle_),
- 'MinScaleDenominator': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readDecimal),
- 'MaxScaleDenominator': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readDecimal),
- 'Layer': ol.xml.makeObjectPropertyPusher(
- ol.format.WMSCapabilities.readLayer_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMSCapabilities.ATTRIBUTION_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMSCapabilities.NAMESPACE_URIS_, {
- 'Title': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'OnlineResource': ol.xml.makeObjectPropertySetter(
- ol.format.XLink.readHref),
- 'LogoURL': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readSizedFormatOnlineresource_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMSCapabilities.EX_GEOGRAPHIC_BOUNDING_BOX_PARSERS_ =
- ol.xml.makeStructureNS(ol.format.WMSCapabilities.NAMESPACE_URIS_, {
- 'westBoundLongitude': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readDecimal),
- 'eastBoundLongitude': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readDecimal),
- 'southBoundLatitude': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readDecimal),
- 'northBoundLatitude': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readDecimal)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMSCapabilities.REQUEST_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMSCapabilities.NAMESPACE_URIS_, {
- 'GetCapabilities': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readOperationType_),
- 'GetMap': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readOperationType_),
- 'GetFeatureInfo': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readOperationType_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMSCapabilities.OPERATIONTYPE_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMSCapabilities.NAMESPACE_URIS_, {
- 'Format': ol.xml.makeObjectPropertyPusher(ol.format.XSD.readString),
- 'DCPType': ol.xml.makeObjectPropertyPusher(
- ol.format.WMSCapabilities.readDCPType_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMSCapabilities.DCPTYPE_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMSCapabilities.NAMESPACE_URIS_, {
- 'HTTP': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readHTTP_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMSCapabilities.HTTP_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMSCapabilities.NAMESPACE_URIS_, {
- 'Get': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readFormatOnlineresource_),
- 'Post': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readFormatOnlineresource_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMSCapabilities.STYLE_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMSCapabilities.NAMESPACE_URIS_, {
- 'Name': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'Title': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'Abstract': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'LegendURL': ol.xml.makeObjectPropertyPusher(
- ol.format.WMSCapabilities.readSizedFormatOnlineresource_),
- 'StyleSheetURL': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readFormatOnlineresource_),
- 'StyleURL': ol.xml.makeObjectPropertySetter(
- ol.format.WMSCapabilities.readFormatOnlineresource_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMSCapabilities.FORMAT_ONLINERESOURCE_PARSERS_ =
- ol.xml.makeStructureNS(ol.format.WMSCapabilities.NAMESPACE_URIS_, {
- 'Format': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
- 'OnlineResource': ol.xml.makeObjectPropertySetter(
- ol.format.XLink.readHref)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMSCapabilities.KEYWORDLIST_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMSCapabilities.NAMESPACE_URIS_, {
- 'Keyword': ol.xml.makeArrayPusher(ol.format.XSD.readString)
- });
- goog.provide('ol.format.WMSGetFeatureInfo');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.format.GML2');
- goog.require('ol.format.XMLFeature');
- goog.require('ol.obj');
- goog.require('ol.xml');
- /**
- * @classdesc
- * Format for reading WMSGetFeatureInfo format. It uses
- * {@link ol.format.GML2} to read features.
- *
- * @constructor
- * @extends {ol.format.XMLFeature}
- * @param {olx.format.WMSGetFeatureInfoOptions=} opt_options Options.
- * @api
- */
- ol.format.WMSGetFeatureInfo = function(opt_options) {
- var options = opt_options ? opt_options : {};
- /**
- * @private
- * @type {string}
- */
- this.featureNS_ = 'http://mapserver.gis.umn.edu/mapserver';
- /**
- * @private
- * @type {ol.format.GML2}
- */
- this.gmlFormat_ = new ol.format.GML2();
- /**
- * @private
- * @type {Array.<string>}
- */
- this.layers_ = options.layers ? options.layers : null;
- ol.format.XMLFeature.call(this);
- };
- ol.inherits(ol.format.WMSGetFeatureInfo, ol.format.XMLFeature);
- /**
- * @const
- * @type {string}
- * @private
- */
- ol.format.WMSGetFeatureInfo.featureIdentifier_ = '_feature';
- /**
- * @const
- * @type {string}
- * @private
- */
- ol.format.WMSGetFeatureInfo.layerIdentifier_ = '_layer';
- /**
- * @return {Array.<string>} layers
- */
- ol.format.WMSGetFeatureInfo.prototype.getLayers = function() {
- return this.layers_;
- };
- /**
- * @param {Array.<string>} layers Layers to parse.
- */
- ol.format.WMSGetFeatureInfo.prototype.setLayers = function(layers) {
- this.layers_ = layers;
- };
- /**
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Array.<ol.Feature>} Features.
- * @private
- */
- ol.format.WMSGetFeatureInfo.prototype.readFeatures_ = function(node, objectStack) {
- node.setAttribute('namespaceURI', this.featureNS_);
- var localName = node.localName;
- /** @type {Array.<ol.Feature>} */
- var features = [];
- if (node.childNodes.length === 0) {
- return features;
- }
- if (localName == 'msGMLOutput') {
- for (var i = 0, ii = node.childNodes.length; i < ii; i++) {
- var layer = node.childNodes[i];
- if (layer.nodeType !== Node.ELEMENT_NODE) {
- continue;
- }
- var context = objectStack[0];
- var toRemove = ol.format.WMSGetFeatureInfo.layerIdentifier_;
- var layerName = layer.localName.replace(toRemove, '');
- if (this.layers_ && !ol.array.includes(this.layers_, layerName)) {
- continue;
- }
- var featureType = layerName +
- ol.format.WMSGetFeatureInfo.featureIdentifier_;
- context['featureType'] = featureType;
- context['featureNS'] = this.featureNS_;
- var parsers = {};
- parsers[featureType] = ol.xml.makeArrayPusher(
- this.gmlFormat_.readFeatureElement, this.gmlFormat_);
- var parsersNS = ol.xml.makeStructureNS(
- [context['featureNS'], null], parsers);
- layer.setAttribute('namespaceURI', this.featureNS_);
- var layerFeatures = ol.xml.pushParseAndPop(
- [], parsersNS, layer, objectStack, this.gmlFormat_);
- if (layerFeatures) {
- ol.array.extend(features, layerFeatures);
- }
- }
- }
- if (localName == 'FeatureCollection') {
- var gmlFeatures = ol.xml.pushParseAndPop([],
- this.gmlFormat_.FEATURE_COLLECTION_PARSERS, node,
- [{}], this.gmlFormat_);
- if (gmlFeatures) {
- features = gmlFeatures;
- }
- }
- return features;
- };
- /**
- * Read all features from a WMSGetFeatureInfo response.
- *
- * @function
- * @param {Document|Node|Object|string} source Source.
- * @param {olx.format.ReadOptions=} opt_options Options.
- * @return {Array.<ol.Feature>} Features.
- * @api
- */
- ol.format.WMSGetFeatureInfo.prototype.readFeatures;
- /**
- * @inheritDoc
- */
- ol.format.WMSGetFeatureInfo.prototype.readFeaturesFromNode = function(node, opt_options) {
- var options = {};
- if (opt_options) {
- ol.obj.assign(options, this.getReadOptions(node, opt_options));
- }
- return this.readFeatures_(node, [options]);
- };
- /**
- * Not implemented.
- * @inheritDoc
- */
- ol.format.WMSGetFeatureInfo.prototype.writeFeatureNode = function(feature, opt_options) {};
- /**
- * Not implemented.
- * @inheritDoc
- */
- ol.format.WMSGetFeatureInfo.prototype.writeFeaturesNode = function(features, opt_options) {};
- /**
- * Not implemented.
- * @inheritDoc
- */
- ol.format.WMSGetFeatureInfo.prototype.writeGeometryNode = function(geometry, opt_options) {};
- goog.provide('ol.format.WMTSCapabilities');
- goog.require('ol');
- goog.require('ol.extent');
- goog.require('ol.format.OWS');
- goog.require('ol.format.XLink');
- goog.require('ol.format.XML');
- goog.require('ol.format.XSD');
- goog.require('ol.xml');
- /**
- * @classdesc
- * Format for reading WMTS capabilities data.
- *
- * @constructor
- * @extends {ol.format.XML}
- * @api
- */
- ol.format.WMTSCapabilities = function() {
- ol.format.XML.call(this);
- /**
- * @type {ol.format.OWS}
- * @private
- */
- this.owsParser_ = new ol.format.OWS();
- };
- ol.inherits(ol.format.WMTSCapabilities, ol.format.XML);
- /**
- * Read a WMTS capabilities document.
- *
- * @function
- * @param {Document|Node|string} source The XML source.
- * @return {Object} An object representing the WMTS capabilities.
- * @api
- */
- ol.format.WMTSCapabilities.prototype.read;
- /**
- * @inheritDoc
- */
- ol.format.WMTSCapabilities.prototype.readFromDocument = function(doc) {
- for (var n = doc.firstChild; n; n = n.nextSibling) {
- if (n.nodeType == Node.ELEMENT_NODE) {
- return this.readFromNode(n);
- }
- }
- return null;
- };
- /**
- * @inheritDoc
- */
- ol.format.WMTSCapabilities.prototype.readFromNode = function(node) {
- var version = node.getAttribute('version').trim();
- var WMTSCapabilityObject = this.owsParser_.readFromNode(node);
- if (!WMTSCapabilityObject) {
- return null;
- }
- WMTSCapabilityObject['version'] = version;
- WMTSCapabilityObject = ol.xml.pushParseAndPop(WMTSCapabilityObject,
- ol.format.WMTSCapabilities.PARSERS_, node, []);
- return WMTSCapabilityObject ? WMTSCapabilityObject : null;
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Attribution object.
- */
- ol.format.WMTSCapabilities.readContents_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop({},
- ol.format.WMTSCapabilities.CONTENTS_PARSERS_, node, objectStack);
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Layers object.
- */
- ol.format.WMTSCapabilities.readLayer_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop({},
- ol.format.WMTSCapabilities.LAYER_PARSERS_, node, objectStack);
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Tile Matrix Set object.
- */
- ol.format.WMTSCapabilities.readTileMatrixSet_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop({},
- ol.format.WMTSCapabilities.TMS_PARSERS_, node, objectStack);
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Style object.
- */
- ol.format.WMTSCapabilities.readStyle_ = function(node, objectStack) {
- var style = ol.xml.pushParseAndPop({},
- ol.format.WMTSCapabilities.STYLE_PARSERS_, node, objectStack);
- if (!style) {
- return undefined;
- }
- var isDefault = node.getAttribute('isDefault') === 'true';
- style['isDefault'] = isDefault;
- return style;
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Tile Matrix Set Link object.
- */
- ol.format.WMTSCapabilities.readTileMatrixSetLink_ = function(node,
- objectStack) {
- return ol.xml.pushParseAndPop({},
- ol.format.WMTSCapabilities.TMS_LINKS_PARSERS_, node, objectStack);
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Dimension object.
- */
- ol.format.WMTSCapabilities.readDimensions_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop({},
- ol.format.WMTSCapabilities.DIMENSION_PARSERS_, node, objectStack);
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Resource URL object.
- */
- ol.format.WMTSCapabilities.readResourceUrl_ = function(node, objectStack) {
- var format = node.getAttribute('format');
- var template = node.getAttribute('template');
- var resourceType = node.getAttribute('resourceType');
- var resource = {};
- if (format) {
- resource['format'] = format;
- }
- if (template) {
- resource['template'] = template;
- }
- if (resourceType) {
- resource['resourceType'] = resourceType;
- }
- return resource;
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} WGS84 BBox object.
- */
- ol.format.WMTSCapabilities.readWgs84BoundingBox_ = function(node, objectStack) {
- var coordinates = ol.xml.pushParseAndPop([],
- ol.format.WMTSCapabilities.WGS84_BBOX_READERS_, node, objectStack);
- if (coordinates.length != 2) {
- return undefined;
- }
- return ol.extent.boundingExtent(coordinates);
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Legend object.
- */
- ol.format.WMTSCapabilities.readLegendUrl_ = function(node, objectStack) {
- var legend = {};
- legend['format'] = node.getAttribute('format');
- legend['href'] = ol.format.XLink.readHref(node);
- return legend;
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} Coordinates object.
- */
- ol.format.WMTSCapabilities.readCoordinates_ = function(node, objectStack) {
- var coordinates = ol.format.XSD.readString(node).split(' ');
- if (!coordinates || coordinates.length != 2) {
- return undefined;
- }
- var x = +coordinates[0];
- var y = +coordinates[1];
- if (isNaN(x) || isNaN(y)) {
- return undefined;
- }
- return [x, y];
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} TileMatrix object.
- */
- ol.format.WMTSCapabilities.readTileMatrix_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop({},
- ol.format.WMTSCapabilities.TM_PARSERS_, node, objectStack);
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} TileMatrixSetLimits Object.
- */
- ol.format.WMTSCapabilities.readTileMatrixLimitsList_ = function(node,
- objectStack) {
- return ol.xml.pushParseAndPop([],
- ol.format.WMTSCapabilities.TMS_LIMITS_LIST_PARSERS_, node,
- objectStack);
- };
- /**
- * @private
- * @param {Node} node Node.
- * @param {Array.<*>} objectStack Object stack.
- * @return {Object|undefined} TileMatrixLimits Array.
- */
- ol.format.WMTSCapabilities.readTileMatrixLimits_ = function(node, objectStack) {
- return ol.xml.pushParseAndPop({},
- ol.format.WMTSCapabilities.TMS_LIMITS_PARSERS_, node, objectStack);
- };
- /**
- * @const
- * @private
- * @type {Array.<string>}
- */
- ol.format.WMTSCapabilities.NAMESPACE_URIS_ = [
- null,
- 'http://www.opengis.net/wmts/1.0'
- ];
- /**
- * @const
- * @private
- * @type {Array.<string>}
- */
- ol.format.WMTSCapabilities.OWS_NAMESPACE_URIS_ = [
- null,
- 'http://www.opengis.net/ows/1.1'
- ];
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMTSCapabilities.PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMTSCapabilities.NAMESPACE_URIS_, {
- 'Contents': ol.xml.makeObjectPropertySetter(
- ol.format.WMTSCapabilities.readContents_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMTSCapabilities.CONTENTS_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMTSCapabilities.NAMESPACE_URIS_, {
- 'Layer': ol.xml.makeObjectPropertyPusher(
- ol.format.WMTSCapabilities.readLayer_),
- 'TileMatrixSet': ol.xml.makeObjectPropertyPusher(
- ol.format.WMTSCapabilities.readTileMatrixSet_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMTSCapabilities.LAYER_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMTSCapabilities.NAMESPACE_URIS_, {
- 'Style': ol.xml.makeObjectPropertyPusher(
- ol.format.WMTSCapabilities.readStyle_),
- 'Format': ol.xml.makeObjectPropertyPusher(
- ol.format.XSD.readString),
- 'TileMatrixSetLink': ol.xml.makeObjectPropertyPusher(
- ol.format.WMTSCapabilities.readTileMatrixSetLink_),
- 'Dimension': ol.xml.makeObjectPropertyPusher(
- ol.format.WMTSCapabilities.readDimensions_),
- 'ResourceURL': ol.xml.makeObjectPropertyPusher(
- ol.format.WMTSCapabilities.readResourceUrl_)
- }, ol.xml.makeStructureNS(ol.format.WMTSCapabilities.OWS_NAMESPACE_URIS_, {
- 'Title': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString),
- 'Abstract': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString),
- 'WGS84BoundingBox': ol.xml.makeObjectPropertySetter(
- ol.format.WMTSCapabilities.readWgs84BoundingBox_),
- 'Identifier': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString)
- }));
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMTSCapabilities.STYLE_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMTSCapabilities.NAMESPACE_URIS_, {
- 'LegendURL': ol.xml.makeObjectPropertyPusher(
- ol.format.WMTSCapabilities.readLegendUrl_)
- }, ol.xml.makeStructureNS(ol.format.WMTSCapabilities.OWS_NAMESPACE_URIS_, {
- 'Title': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString),
- 'Identifier': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString)
- }));
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMTSCapabilities.TMS_LINKS_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMTSCapabilities.NAMESPACE_URIS_, {
- 'TileMatrixSet': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString),
- 'TileMatrixSetLimits': ol.xml.makeObjectPropertySetter(
- ol.format.WMTSCapabilities.readTileMatrixLimitsList_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMTSCapabilities.TMS_LIMITS_LIST_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMTSCapabilities.NAMESPACE_URIS_, {
- 'TileMatrixLimits': ol.xml.makeArrayPusher(
- ol.format.WMTSCapabilities.readTileMatrixLimits_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMTSCapabilities.TMS_LIMITS_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMTSCapabilities.NAMESPACE_URIS_, {
- 'TileMatrix': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString),
- 'MinTileRow': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readNonNegativeInteger),
- 'MaxTileRow': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readNonNegativeInteger),
- 'MinTileCol': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readNonNegativeInteger),
- 'MaxTileCol': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readNonNegativeInteger)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMTSCapabilities.DIMENSION_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMTSCapabilities.NAMESPACE_URIS_, {
- 'Default': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString),
- 'Value': ol.xml.makeObjectPropertyPusher(
- ol.format.XSD.readString)
- }, ol.xml.makeStructureNS(ol.format.WMTSCapabilities.OWS_NAMESPACE_URIS_, {
- 'Identifier': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString)
- }));
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMTSCapabilities.WGS84_BBOX_READERS_ = ol.xml.makeStructureNS(
- ol.format.WMTSCapabilities.OWS_NAMESPACE_URIS_, {
- 'LowerCorner': ol.xml.makeArrayPusher(
- ol.format.WMTSCapabilities.readCoordinates_),
- 'UpperCorner': ol.xml.makeArrayPusher(
- ol.format.WMTSCapabilities.readCoordinates_)
- });
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMTSCapabilities.TMS_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMTSCapabilities.NAMESPACE_URIS_, {
- 'WellKnownScaleSet': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString),
- 'TileMatrix': ol.xml.makeObjectPropertyPusher(
- ol.format.WMTSCapabilities.readTileMatrix_)
- }, ol.xml.makeStructureNS(ol.format.WMTSCapabilities.OWS_NAMESPACE_URIS_, {
- 'SupportedCRS': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString),
- 'Identifier': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString)
- }));
- /**
- * @const
- * @type {Object.<string, Object.<string, ol.XmlParser>>}
- * @private
- */
- ol.format.WMTSCapabilities.TM_PARSERS_ = ol.xml.makeStructureNS(
- ol.format.WMTSCapabilities.NAMESPACE_URIS_, {
- 'TopLeftCorner': ol.xml.makeObjectPropertySetter(
- ol.format.WMTSCapabilities.readCoordinates_),
- 'ScaleDenominator': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readDecimal),
- 'TileWidth': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readNonNegativeInteger),
- 'TileHeight': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readNonNegativeInteger),
- 'MatrixWidth': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readNonNegativeInteger),
- 'MatrixHeight': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readNonNegativeInteger)
- }, ol.xml.makeStructureNS(ol.format.WMTSCapabilities.OWS_NAMESPACE_URIS_, {
- 'Identifier': ol.xml.makeObjectPropertySetter(
- ol.format.XSD.readString)
- }));
- goog.provide('ol.GeolocationProperty');
- /**
- * @enum {string}
- */
- ol.GeolocationProperty = {
- ACCURACY: 'accuracy',
- ACCURACY_GEOMETRY: 'accuracyGeometry',
- ALTITUDE: 'altitude',
- ALTITUDE_ACCURACY: 'altitudeAccuracy',
- HEADING: 'heading',
- POSITION: 'position',
- PROJECTION: 'projection',
- SPEED: 'speed',
- TRACKING: 'tracking',
- TRACKING_OPTIONS: 'trackingOptions'
- };
- // FIXME handle geolocation not supported
- goog.provide('ol.Geolocation');
- goog.require('ol');
- goog.require('ol.GeolocationProperty');
- goog.require('ol.Object');
- goog.require('ol.Sphere');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.geom.Polygon');
- goog.require('ol.has');
- goog.require('ol.math');
- goog.require('ol.proj');
- goog.require('ol.proj.EPSG4326');
- /**
- * @classdesc
- * Helper class for providing HTML5 Geolocation capabilities.
- * The [Geolocation API](http://www.w3.org/TR/geolocation-API/)
- * is used to locate a user's position.
- *
- * To get notified of position changes, register a listener for the generic
- * `change` event on your instance of `ol.Geolocation`.
- *
- * Example:
- *
- * var geolocation = new ol.Geolocation({
- * // take the projection to use from the map's view
- * projection: view.getProjection()
- * });
- * // listen to changes in position
- * geolocation.on('change', function(evt) {
- * window.console.log(geolocation.getPosition());
- * });
- *
- * @fires error
- * @constructor
- * @extends {ol.Object}
- * @param {olx.GeolocationOptions=} opt_options Options.
- * @api
- */
- ol.Geolocation = function(opt_options) {
- ol.Object.call(this);
- var options = opt_options || {};
- /**
- * The unprojected (EPSG:4326) device position.
- * @private
- * @type {ol.Coordinate}
- */
- this.position_ = null;
- /**
- * @private
- * @type {ol.TransformFunction}
- */
- this.transform_ = ol.proj.identityTransform;
- /**
- * @private
- * @type {ol.Sphere}
- */
- this.sphere_ = new ol.Sphere(ol.proj.EPSG4326.RADIUS);
- /**
- * @private
- * @type {number|undefined}
- */
- this.watchId_ = undefined;
- ol.events.listen(
- this, ol.Object.getChangeEventType(ol.GeolocationProperty.PROJECTION),
- this.handleProjectionChanged_, this);
- ol.events.listen(
- this, ol.Object.getChangeEventType(ol.GeolocationProperty.TRACKING),
- this.handleTrackingChanged_, this);
- if (options.projection !== undefined) {
- this.setProjection(options.projection);
- }
- if (options.trackingOptions !== undefined) {
- this.setTrackingOptions(options.trackingOptions);
- }
- this.setTracking(options.tracking !== undefined ? options.tracking : false);
- };
- ol.inherits(ol.Geolocation, ol.Object);
- /**
- * @inheritDoc
- */
- ol.Geolocation.prototype.disposeInternal = function() {
- this.setTracking(false);
- ol.Object.prototype.disposeInternal.call(this);
- };
- /**
- * @private
- */
- ol.Geolocation.prototype.handleProjectionChanged_ = function() {
- var projection = this.getProjection();
- if (projection) {
- this.transform_ = ol.proj.getTransformFromProjections(
- ol.proj.get('EPSG:4326'), projection);
- if (this.position_) {
- this.set(
- ol.GeolocationProperty.POSITION, this.transform_(this.position_));
- }
- }
- };
- /**
- * @private
- */
- ol.Geolocation.prototype.handleTrackingChanged_ = function() {
- if (ol.has.GEOLOCATION) {
- var tracking = this.getTracking();
- if (tracking && this.watchId_ === undefined) {
- this.watchId_ = navigator.geolocation.watchPosition(
- this.positionChange_.bind(this),
- this.positionError_.bind(this),
- this.getTrackingOptions());
- } else if (!tracking && this.watchId_ !== undefined) {
- navigator.geolocation.clearWatch(this.watchId_);
- this.watchId_ = undefined;
- }
- }
- };
- /**
- * @private
- * @param {GeolocationPosition} position position event.
- */
- ol.Geolocation.prototype.positionChange_ = function(position) {
- var coords = position.coords;
- this.set(ol.GeolocationProperty.ACCURACY, coords.accuracy);
- this.set(ol.GeolocationProperty.ALTITUDE,
- coords.altitude === null ? undefined : coords.altitude);
- this.set(ol.GeolocationProperty.ALTITUDE_ACCURACY,
- coords.altitudeAccuracy === null ?
- undefined : coords.altitudeAccuracy);
- this.set(ol.GeolocationProperty.HEADING, coords.heading === null ?
- undefined : ol.math.toRadians(coords.heading));
- if (!this.position_) {
- this.position_ = [coords.longitude, coords.latitude];
- } else {
- this.position_[0] = coords.longitude;
- this.position_[1] = coords.latitude;
- }
- var projectedPosition = this.transform_(this.position_);
- this.set(ol.GeolocationProperty.POSITION, projectedPosition);
- this.set(ol.GeolocationProperty.SPEED,
- coords.speed === null ? undefined : coords.speed);
- var geometry = ol.geom.Polygon.circular(
- this.sphere_, this.position_, coords.accuracy);
- geometry.applyTransform(this.transform_);
- this.set(ol.GeolocationProperty.ACCURACY_GEOMETRY, geometry);
- this.changed();
- };
- /**
- * Triggered when the Geolocation returns an error.
- * @event error
- * @api
- */
- /**
- * @private
- * @param {GeolocationPositionError} error error object.
- */
- ol.Geolocation.prototype.positionError_ = function(error) {
- error.type = ol.events.EventType.ERROR;
- this.setTracking(false);
- this.dispatchEvent(/** @type {{type: string, target: undefined}} */ (error));
- };
- /**
- * Get the accuracy of the position in meters.
- * @return {number|undefined} The accuracy of the position measurement in
- * meters.
- * @observable
- * @api
- */
- ol.Geolocation.prototype.getAccuracy = function() {
- return /** @type {number|undefined} */ (
- this.get(ol.GeolocationProperty.ACCURACY));
- };
- /**
- * Get a geometry of the position accuracy.
- * @return {?ol.geom.Polygon} A geometry of the position accuracy.
- * @observable
- * @api
- */
- ol.Geolocation.prototype.getAccuracyGeometry = function() {
- return /** @type {?ol.geom.Polygon} */ (
- this.get(ol.GeolocationProperty.ACCURACY_GEOMETRY) || null);
- };
- /**
- * Get the altitude associated with the position.
- * @return {number|undefined} The altitude of the position in meters above mean
- * sea level.
- * @observable
- * @api
- */
- ol.Geolocation.prototype.getAltitude = function() {
- return /** @type {number|undefined} */ (
- this.get(ol.GeolocationProperty.ALTITUDE));
- };
- /**
- * Get the altitude accuracy of the position.
- * @return {number|undefined} The accuracy of the altitude measurement in
- * meters.
- * @observable
- * @api
- */
- ol.Geolocation.prototype.getAltitudeAccuracy = function() {
- return /** @type {number|undefined} */ (
- this.get(ol.GeolocationProperty.ALTITUDE_ACCURACY));
- };
- /**
- * Get the heading as radians clockwise from North.
- * @return {number|undefined} The heading of the device in radians from north.
- * @observable
- * @api
- */
- ol.Geolocation.prototype.getHeading = function() {
- return /** @type {number|undefined} */ (
- this.get(ol.GeolocationProperty.HEADING));
- };
- /**
- * Get the position of the device.
- * @return {ol.Coordinate|undefined} The current position of the device reported
- * in the current projection.
- * @observable
- * @api
- */
- ol.Geolocation.prototype.getPosition = function() {
- return /** @type {ol.Coordinate|undefined} */ (
- this.get(ol.GeolocationProperty.POSITION));
- };
- /**
- * Get the projection associated with the position.
- * @return {ol.proj.Projection|undefined} The projection the position is
- * reported in.
- * @observable
- * @api
- */
- ol.Geolocation.prototype.getProjection = function() {
- return /** @type {ol.proj.Projection|undefined} */ (
- this.get(ol.GeolocationProperty.PROJECTION));
- };
- /**
- * Get the speed in meters per second.
- * @return {number|undefined} The instantaneous speed of the device in meters
- * per second.
- * @observable
- * @api
- */
- ol.Geolocation.prototype.getSpeed = function() {
- return /** @type {number|undefined} */ (
- this.get(ol.GeolocationProperty.SPEED));
- };
- /**
- * Determine if the device location is being tracked.
- * @return {boolean} The device location is being tracked.
- * @observable
- * @api
- */
- ol.Geolocation.prototype.getTracking = function() {
- return /** @type {boolean} */ (
- this.get(ol.GeolocationProperty.TRACKING));
- };
- /**
- * Get the tracking options.
- * @see http://www.w3.org/TR/geolocation-API/#position-options
- * @return {GeolocationPositionOptions|undefined} PositionOptions as defined by
- * the [HTML5 Geolocation spec
- * ](http://www.w3.org/TR/geolocation-API/#position_options_interface).
- * @observable
- * @api
- */
- ol.Geolocation.prototype.getTrackingOptions = function() {
- return /** @type {GeolocationPositionOptions|undefined} */ (
- this.get(ol.GeolocationProperty.TRACKING_OPTIONS));
- };
- /**
- * Set the projection to use for transforming the coordinates.
- * @param {ol.ProjectionLike} projection The projection the position is
- * reported in.
- * @observable
- * @api
- */
- ol.Geolocation.prototype.setProjection = function(projection) {
- this.set(ol.GeolocationProperty.PROJECTION, ol.proj.get(projection));
- };
- /**
- * Enable or disable tracking.
- * @param {boolean} tracking Enable tracking.
- * @observable
- * @api
- */
- ol.Geolocation.prototype.setTracking = function(tracking) {
- this.set(ol.GeolocationProperty.TRACKING, tracking);
- };
- /**
- * Set the tracking options.
- * @see http://www.w3.org/TR/geolocation-API/#position-options
- * @param {GeolocationPositionOptions} options PositionOptions as defined by the
- * [HTML5 Geolocation spec
- * ](http://www.w3.org/TR/geolocation-API/#position_options_interface).
- * @observable
- * @api
- */
- ol.Geolocation.prototype.setTrackingOptions = function(options) {
- this.set(ol.GeolocationProperty.TRACKING_OPTIONS, options);
- };
- goog.provide('ol.geom.Circle');
- goog.require('ol');
- goog.require('ol.extent');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.SimpleGeometry');
- goog.require('ol.geom.flat.deflate');
- /**
- * @classdesc
- * Circle geometry.
- *
- * @constructor
- * @extends {ol.geom.SimpleGeometry}
- * @param {ol.Coordinate} center Center.
- * @param {number=} opt_radius Radius.
- * @param {ol.geom.GeometryLayout=} opt_layout Layout.
- * @api
- */
- ol.geom.Circle = function(center, opt_radius, opt_layout) {
- ol.geom.SimpleGeometry.call(this);
- var radius = opt_radius ? opt_radius : 0;
- this.setCenterAndRadius(center, radius, opt_layout);
- };
- ol.inherits(ol.geom.Circle, ol.geom.SimpleGeometry);
- /**
- * Make a complete copy of the geometry.
- * @return {!ol.geom.Circle} Clone.
- * @override
- * @api
- */
- ol.geom.Circle.prototype.clone = function() {
- var circle = new ol.geom.Circle(null);
- circle.setFlatCoordinates(this.layout, this.flatCoordinates.slice());
- return circle;
- };
- /**
- * @inheritDoc
- */
- ol.geom.Circle.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) {
- var flatCoordinates = this.flatCoordinates;
- var dx = x - flatCoordinates[0];
- var dy = y - flatCoordinates[1];
- var squaredDistance = dx * dx + dy * dy;
- if (squaredDistance < minSquaredDistance) {
- var i;
- if (squaredDistance === 0) {
- for (i = 0; i < this.stride; ++i) {
- closestPoint[i] = flatCoordinates[i];
- }
- } else {
- var delta = this.getRadius() / Math.sqrt(squaredDistance);
- closestPoint[0] = flatCoordinates[0] + delta * dx;
- closestPoint[1] = flatCoordinates[1] + delta * dy;
- for (i = 2; i < this.stride; ++i) {
- closestPoint[i] = flatCoordinates[i];
- }
- }
- closestPoint.length = this.stride;
- return squaredDistance;
- } else {
- return minSquaredDistance;
- }
- };
- /**
- * @inheritDoc
- */
- ol.geom.Circle.prototype.containsXY = function(x, y) {
- var flatCoordinates = this.flatCoordinates;
- var dx = x - flatCoordinates[0];
- var dy = y - flatCoordinates[1];
- return dx * dx + dy * dy <= this.getRadiusSquared_();
- };
- /**
- * Return the center of the circle as {@link ol.Coordinate coordinate}.
- * @return {ol.Coordinate} Center.
- * @api
- */
- ol.geom.Circle.prototype.getCenter = function() {
- return this.flatCoordinates.slice(0, this.stride);
- };
- /**
- * @inheritDoc
- */
- ol.geom.Circle.prototype.computeExtent = function(extent) {
- var flatCoordinates = this.flatCoordinates;
- var radius = flatCoordinates[this.stride] - flatCoordinates[0];
- return ol.extent.createOrUpdate(
- flatCoordinates[0] - radius, flatCoordinates[1] - radius,
- flatCoordinates[0] + radius, flatCoordinates[1] + radius,
- extent);
- };
- /**
- * Return the radius of the circle.
- * @return {number} Radius.
- * @api
- */
- ol.geom.Circle.prototype.getRadius = function() {
- return Math.sqrt(this.getRadiusSquared_());
- };
- /**
- * @private
- * @return {number} Radius squared.
- */
- ol.geom.Circle.prototype.getRadiusSquared_ = function() {
- var dx = this.flatCoordinates[this.stride] - this.flatCoordinates[0];
- var dy = this.flatCoordinates[this.stride + 1] - this.flatCoordinates[1];
- return dx * dx + dy * dy;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.Circle.prototype.getType = function() {
- return ol.geom.GeometryType.CIRCLE;
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.geom.Circle.prototype.intersectsExtent = function(extent) {
- var circleExtent = this.getExtent();
- if (ol.extent.intersects(extent, circleExtent)) {
- var center = this.getCenter();
- if (extent[0] <= center[0] && extent[2] >= center[0]) {
- return true;
- }
- if (extent[1] <= center[1] && extent[3] >= center[1]) {
- return true;
- }
- return ol.extent.forEachCorner(extent, this.intersectsCoordinate, this);
- }
- return false;
- };
- /**
- * Set the center of the circle as {@link ol.Coordinate coordinate}.
- * @param {ol.Coordinate} center Center.
- * @api
- */
- ol.geom.Circle.prototype.setCenter = function(center) {
- var stride = this.stride;
- var radius = this.flatCoordinates[stride] - this.flatCoordinates[0];
- var flatCoordinates = center.slice();
- flatCoordinates[stride] = flatCoordinates[0] + radius;
- var i;
- for (i = 1; i < stride; ++i) {
- flatCoordinates[stride + i] = center[i];
- }
- this.setFlatCoordinates(this.layout, flatCoordinates);
- };
- /**
- * Set the center (as {@link ol.Coordinate coordinate}) and the radius (as
- * number) of the circle.
- * @param {ol.Coordinate} center Center.
- * @param {number} radius Radius.
- * @param {ol.geom.GeometryLayout=} opt_layout Layout.
- * @api
- */
- ol.geom.Circle.prototype.setCenterAndRadius = function(center, radius, opt_layout) {
- if (!center) {
- this.setFlatCoordinates(ol.geom.GeometryLayout.XY, null);
- } else {
- this.setLayout(opt_layout, center, 0);
- if (!this.flatCoordinates) {
- this.flatCoordinates = [];
- }
- /** @type {Array.<number>} */
- var flatCoordinates = this.flatCoordinates;
- var offset = ol.geom.flat.deflate.coordinate(
- flatCoordinates, 0, center, this.stride);
- flatCoordinates[offset++] = flatCoordinates[0] + radius;
- var i, ii;
- for (i = 1, ii = this.stride; i < ii; ++i) {
- flatCoordinates[offset++] = flatCoordinates[i];
- }
- flatCoordinates.length = offset;
- this.changed();
- }
- };
- /**
- * @inheritDoc
- */
- ol.geom.Circle.prototype.getCoordinates = function() {};
- /**
- * @inheritDoc
- */
- ol.geom.Circle.prototype.setCoordinates = function(coordinates, opt_layout) {};
- /**
- * @param {ol.geom.GeometryLayout} layout Layout.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- */
- ol.geom.Circle.prototype.setFlatCoordinates = function(layout, flatCoordinates) {
- this.setFlatCoordinatesInternal(layout, flatCoordinates);
- this.changed();
- };
- /**
- * Set the radius of the circle. The radius is in the units of the projection.
- * @param {number} radius Radius.
- * @api
- */
- ol.geom.Circle.prototype.setRadius = function(radius) {
- this.flatCoordinates[this.stride] = this.flatCoordinates[0] + radius;
- this.changed();
- };
- /**
- * Transform each coordinate of the circle from one coordinate reference system
- * to another. The geometry is modified in place.
- * If you do not want the geometry modified in place, first clone() it and
- * then use this function on the clone.
- *
- * Internally a circle is currently represented by two points: the center of
- * the circle `[cx, cy]`, and the point to the right of the circle
- * `[cx + r, cy]`. This `transform` function just transforms these two points.
- * So the resulting geometry is also a circle, and that circle does not
- * correspond to the shape that would be obtained by transforming every point
- * of the original circle.
- *
- * @param {ol.ProjectionLike} source The current projection. Can be a
- * string identifier or a {@link ol.proj.Projection} object.
- * @param {ol.ProjectionLike} destination The desired projection. Can be a
- * string identifier or a {@link ol.proj.Projection} object.
- * @return {ol.geom.Circle} This geometry. Note that original geometry is
- * modified in place.
- * @function
- * @api
- */
- ol.geom.Circle.prototype.transform;
- goog.provide('ol.geom.flat.geodesic');
- goog.require('ol.math');
- goog.require('ol.proj');
- /**
- * @private
- * @param {function(number): ol.Coordinate} interpolate Interpolate function.
- * @param {ol.TransformFunction} transform Transform from longitude/latitude to
- * projected coordinates.
- * @param {number} squaredTolerance Squared tolerance.
- * @return {Array.<number>} Flat coordinates.
- */
- ol.geom.flat.geodesic.line_ = function(interpolate, transform, squaredTolerance) {
- // FIXME reduce garbage generation
- // FIXME optimize stack operations
- /** @type {Array.<number>} */
- var flatCoordinates = [];
- var geoA = interpolate(0);
- var geoB = interpolate(1);
- var a = transform(geoA);
- var b = transform(geoB);
- /** @type {Array.<ol.Coordinate>} */
- var geoStack = [geoB, geoA];
- /** @type {Array.<ol.Coordinate>} */
- var stack = [b, a];
- /** @type {Array.<number>} */
- var fractionStack = [1, 0];
- /** @type {Object.<string, boolean>} */
- var fractions = {};
- var maxIterations = 1e5;
- var geoM, m, fracA, fracB, fracM, key;
- while (--maxIterations > 0 && fractionStack.length > 0) {
- // Pop the a coordinate off the stack
- fracA = fractionStack.pop();
- geoA = geoStack.pop();
- a = stack.pop();
- // Add the a coordinate if it has not been added yet
- key = fracA.toString();
- if (!(key in fractions)) {
- flatCoordinates.push(a[0], a[1]);
- fractions[key] = true;
- }
- // Pop the b coordinate off the stack
- fracB = fractionStack.pop();
- geoB = geoStack.pop();
- b = stack.pop();
- // Find the m point between the a and b coordinates
- fracM = (fracA + fracB) / 2;
- geoM = interpolate(fracM);
- m = transform(geoM);
- if (ol.math.squaredSegmentDistance(m[0], m[1], a[0], a[1],
- b[0], b[1]) < squaredTolerance) {
- // If the m point is sufficiently close to the straight line, then we
- // discard it. Just use the b coordinate and move on to the next line
- // segment.
- flatCoordinates.push(b[0], b[1]);
- key = fracB.toString();
- fractions[key] = true;
- } else {
- // Otherwise, we need to subdivide the current line segment. Split it
- // into two and push the two line segments onto the stack.
- fractionStack.push(fracB, fracM, fracM, fracA);
- stack.push(b, m, m, a);
- geoStack.push(geoB, geoM, geoM, geoA);
- }
- }
- return flatCoordinates;
- };
- /**
- * Generate a great-circle arcs between two lat/lon points.
- * @param {number} lon1 Longitude 1 in degrees.
- * @param {number} lat1 Latitude 1 in degrees.
- * @param {number} lon2 Longitude 2 in degrees.
- * @param {number} lat2 Latitude 2 in degrees.
- * @param {ol.proj.Projection} projection Projection.
- * @param {number} squaredTolerance Squared tolerance.
- * @return {Array.<number>} Flat coordinates.
- */
- ol.geom.flat.geodesic.greatCircleArc = function(
- lon1, lat1, lon2, lat2, projection, squaredTolerance) {
- var geoProjection = ol.proj.get('EPSG:4326');
- var cosLat1 = Math.cos(ol.math.toRadians(lat1));
- var sinLat1 = Math.sin(ol.math.toRadians(lat1));
- var cosLat2 = Math.cos(ol.math.toRadians(lat2));
- var sinLat2 = Math.sin(ol.math.toRadians(lat2));
- var cosDeltaLon = Math.cos(ol.math.toRadians(lon2 - lon1));
- var sinDeltaLon = Math.sin(ol.math.toRadians(lon2 - lon1));
- var d = sinLat1 * sinLat2 + cosLat1 * cosLat2 * cosDeltaLon;
- return ol.geom.flat.geodesic.line_(
- /**
- * @param {number} frac Fraction.
- * @return {ol.Coordinate} Coordinate.
- */
- function(frac) {
- if (1 <= d) {
- return [lon2, lat2];
- }
- var D = frac * Math.acos(d);
- var cosD = Math.cos(D);
- var sinD = Math.sin(D);
- var y = sinDeltaLon * cosLat2;
- var x = cosLat1 * sinLat2 - sinLat1 * cosLat2 * cosDeltaLon;
- var theta = Math.atan2(y, x);
- var lat = Math.asin(sinLat1 * cosD + cosLat1 * sinD * Math.cos(theta));
- var lon = ol.math.toRadians(lon1) +
- Math.atan2(Math.sin(theta) * sinD * cosLat1,
- cosD - sinLat1 * Math.sin(lat));
- return [ol.math.toDegrees(lon), ol.math.toDegrees(lat)];
- }, ol.proj.getTransform(geoProjection, projection), squaredTolerance);
- };
- /**
- * Generate a meridian (line at constant longitude).
- * @param {number} lon Longitude.
- * @param {number} lat1 Latitude 1.
- * @param {number} lat2 Latitude 2.
- * @param {ol.proj.Projection} projection Projection.
- * @param {number} squaredTolerance Squared tolerance.
- * @return {Array.<number>} Flat coordinates.
- */
- ol.geom.flat.geodesic.meridian = function(lon, lat1, lat2, projection, squaredTolerance) {
- var epsg4326Projection = ol.proj.get('EPSG:4326');
- return ol.geom.flat.geodesic.line_(
- /**
- * @param {number} frac Fraction.
- * @return {ol.Coordinate} Coordinate.
- */
- function(frac) {
- return [lon, lat1 + ((lat2 - lat1) * frac)];
- },
- ol.proj.getTransform(epsg4326Projection, projection), squaredTolerance);
- };
- /**
- * Generate a parallel (line at constant latitude).
- * @param {number} lat Latitude.
- * @param {number} lon1 Longitude 1.
- * @param {number} lon2 Longitude 2.
- * @param {ol.proj.Projection} projection Projection.
- * @param {number} squaredTolerance Squared tolerance.
- * @return {Array.<number>} Flat coordinates.
- */
- ol.geom.flat.geodesic.parallel = function(lat, lon1, lon2, projection, squaredTolerance) {
- var epsg4326Projection = ol.proj.get('EPSG:4326');
- return ol.geom.flat.geodesic.line_(
- /**
- * @param {number} frac Fraction.
- * @return {ol.Coordinate} Coordinate.
- */
- function(frac) {
- return [lon1 + ((lon2 - lon1) * frac), lat];
- },
- ol.proj.getTransform(epsg4326Projection, projection), squaredTolerance);
- };
- goog.provide('ol.geom.flat.topology');
- goog.require('ol.geom.flat.area');
- /**
- * Check if the linestring is a boundary.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @return {boolean} The linestring is a boundary.
- */
- ol.geom.flat.topology.lineStringIsClosed = function(flatCoordinates, offset, end, stride) {
- var lastCoord = end - stride;
- if (flatCoordinates[offset] === flatCoordinates[lastCoord] &&
- flatCoordinates[offset + 1] === flatCoordinates[lastCoord + 1] && (end - offset) / stride > 3) {
- return !!ol.geom.flat.area.linearRing(flatCoordinates, offset, end, stride);
- }
- return false;
- };
- goog.provide('ol.Graticule');
- goog.require('ol.coordinate');
- goog.require('ol.extent');
- goog.require('ol.geom.GeometryLayout');
- goog.require('ol.geom.LineString');
- goog.require('ol.geom.Point');
- goog.require('ol.geom.flat.geodesic');
- goog.require('ol.math');
- goog.require('ol.proj');
- goog.require('ol.render.EventType');
- goog.require('ol.style.Fill');
- goog.require('ol.style.Stroke');
- goog.require('ol.style.Text');
- /**
- * Render a grid for a coordinate system on a map.
- * @constructor
- * @param {olx.GraticuleOptions=} opt_options Options.
- * @api
- */
- ol.Graticule = function(opt_options) {
- var options = opt_options || {};
- /**
- * @type {ol.PluggableMap}
- * @private
- */
- this.map_ = null;
- /**
- * @type {ol.proj.Projection}
- * @private
- */
- this.projection_ = null;
- /**
- * @type {number}
- * @private
- */
- this.maxLat_ = Infinity;
- /**
- * @type {number}
- * @private
- */
- this.maxLon_ = Infinity;
- /**
- * @type {number}
- * @private
- */
- this.minLat_ = -Infinity;
- /**
- * @type {number}
- * @private
- */
- this.minLon_ = -Infinity;
- /**
- * @type {number}
- * @private
- */
- this.maxLatP_ = Infinity;
- /**
- * @type {number}
- * @private
- */
- this.maxLonP_ = Infinity;
- /**
- * @type {number}
- * @private
- */
- this.minLatP_ = -Infinity;
- /**
- * @type {number}
- * @private
- */
- this.minLonP_ = -Infinity;
- /**
- * @type {number}
- * @private
- */
- this.targetSize_ = options.targetSize !== undefined ?
- options.targetSize : 100;
- /**
- * @type {number}
- * @private
- */
- this.maxLines_ = options.maxLines !== undefined ? options.maxLines : 100;
- /**
- * @type {Array.<ol.geom.LineString>}
- * @private
- */
- this.meridians_ = [];
- /**
- * @type {Array.<ol.geom.LineString>}
- * @private
- */
- this.parallels_ = [];
- /**
- * @type {ol.style.Stroke}
- * @private
- */
- this.strokeStyle_ = options.strokeStyle !== undefined ?
- options.strokeStyle : ol.Graticule.DEFAULT_STROKE_STYLE_;
- /**
- * @type {ol.TransformFunction|undefined}
- * @private
- */
- this.fromLonLatTransform_ = undefined;
- /**
- * @type {ol.TransformFunction|undefined}
- * @private
- */
- this.toLonLatTransform_ = undefined;
- /**
- * @type {ol.Coordinate}
- * @private
- */
- this.projectionCenterLonLat_ = null;
- /**
- * @type {Array.<ol.GraticuleLabelDataType>}
- * @private
- */
- this.meridiansLabels_ = null;
- /**
- * @type {Array.<ol.GraticuleLabelDataType>}
- * @private
- */
- this.parallelsLabels_ = null;
- if (options.showLabels == true) {
- var degreesToString = ol.coordinate.degreesToStringHDMS;
- /**
- * @type {null|function(number):string}
- * @private
- */
- this.lonLabelFormatter_ = options.lonLabelFormatter == undefined ?
- degreesToString.bind(this, 'EW') : options.lonLabelFormatter;
- /**
- * @type {function(number):string}
- * @private
- */
- this.latLabelFormatter_ = options.latLabelFormatter == undefined ?
- degreesToString.bind(this, 'NS') : options.latLabelFormatter;
- /**
- * Longitude label position in fractions (0..1) of view extent. 0 means
- * bottom, 1 means top.
- * @type {number}
- * @private
- */
- this.lonLabelPosition_ = options.lonLabelPosition == undefined ? 0 :
- options.lonLabelPosition;
- /**
- * Latitude Label position in fractions (0..1) of view extent. 0 means left, 1
- * means right.
- * @type {number}
- * @private
- */
- this.latLabelPosition_ = options.latLabelPosition == undefined ? 1 :
- options.latLabelPosition;
- /**
- * @type {ol.style.Text}
- * @private
- */
- this.lonLabelStyle_ = options.lonLabelStyle !== undefined ? options.lonLabelStyle :
- new ol.style.Text({
- font: '12px Calibri,sans-serif',
- textBaseline: 'bottom',
- fill: new ol.style.Fill({
- color: 'rgba(0,0,0,1)'
- }),
- stroke: new ol.style.Stroke({
- color: 'rgba(255,255,255,1)',
- width: 3
- })
- });
- /**
- * @type {ol.style.Text}
- * @private
- */
- this.latLabelStyle_ = options.latLabelStyle !== undefined ? options.latLabelStyle :
- new ol.style.Text({
- font: '12px Calibri,sans-serif',
- textAlign: 'end',
- fill: new ol.style.Fill({
- color: 'rgba(0,0,0,1)'
- }),
- stroke: new ol.style.Stroke({
- color: 'rgba(255,255,255,1)',
- width: 3
- })
- });
- this.meridiansLabels_ = [];
- this.parallelsLabels_ = [];
- }
- this.setMap(options.map !== undefined ? options.map : null);
- };
- /**
- * @type {ol.style.Stroke}
- * @private
- * @const
- */
- ol.Graticule.DEFAULT_STROKE_STYLE_ = new ol.style.Stroke({
- color: 'rgba(0,0,0,0.2)'
- });
- /**
- * TODO can be configurable
- * @type {Array.<number>}
- * @private
- */
- ol.Graticule.intervals_ = [90, 45, 30, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05,
- 0.01, 0.005, 0.002, 0.001];
- /**
- * @param {number} lon Longitude.
- * @param {number} minLat Minimal latitude.
- * @param {number} maxLat Maximal latitude.
- * @param {number} squaredTolerance Squared tolerance.
- * @param {ol.Extent} extent Extent.
- * @param {number} index Index.
- * @return {number} Index.
- * @private
- */
- ol.Graticule.prototype.addMeridian_ = function(lon, minLat, maxLat, squaredTolerance, extent, index) {
- var lineString = this.getMeridian_(lon, minLat, maxLat,
- squaredTolerance, index);
- if (ol.extent.intersects(lineString.getExtent(), extent)) {
- if (this.meridiansLabels_) {
- var textPoint = this.getMeridianPoint_(lineString, extent, index);
- this.meridiansLabels_[index] = {
- geom: textPoint,
- text: this.lonLabelFormatter_(lon)
- };
- }
- this.meridians_[index++] = lineString;
- }
- return index;
- };
- /**
- * @param {ol.geom.LineString} lineString Meridian
- * @param {ol.Extent} extent Extent.
- * @param {number} index Index.
- * @return {ol.geom.Point} Meridian point.
- * @private
- */
- ol.Graticule.prototype.getMeridianPoint_ = function(lineString, extent, index) {
- var flatCoordinates = lineString.getFlatCoordinates();
- var clampedBottom = Math.max(extent[1], flatCoordinates[1]);
- var clampedTop = Math.min(extent[3], flatCoordinates[flatCoordinates.length - 1]);
- var lat = ol.math.clamp(
- extent[1] + Math.abs(extent[1] - extent[3]) * this.lonLabelPosition_,
- clampedBottom, clampedTop);
- var coordinate = [flatCoordinates[0], lat];
- var point = this.meridiansLabels_[index] !== undefined ?
- this.meridiansLabels_[index].geom : new ol.geom.Point(null);
- point.setCoordinates(coordinate);
- return point;
- };
- /**
- * @param {number} lat Latitude.
- * @param {number} minLon Minimal longitude.
- * @param {number} maxLon Maximal longitude.
- * @param {number} squaredTolerance Squared tolerance.
- * @param {ol.Extent} extent Extent.
- * @param {number} index Index.
- * @return {number} Index.
- * @private
- */
- ol.Graticule.prototype.addParallel_ = function(lat, minLon, maxLon, squaredTolerance, extent, index) {
- var lineString = this.getParallel_(lat, minLon, maxLon, squaredTolerance,
- index);
- if (ol.extent.intersects(lineString.getExtent(), extent)) {
- if (this.parallelsLabels_) {
- var textPoint = this.getParallelPoint_(lineString, extent, index);
- this.parallelsLabels_[index] = {
- geom: textPoint,
- text: this.latLabelFormatter_(lat)
- };
- }
- this.parallels_[index++] = lineString;
- }
- return index;
- };
- /**
- * @param {ol.geom.LineString} lineString Parallels.
- * @param {ol.Extent} extent Extent.
- * @param {number} index Index.
- * @return {ol.geom.Point} Parallel point.
- * @private
- */
- ol.Graticule.prototype.getParallelPoint_ = function(lineString, extent, index) {
- var flatCoordinates = lineString.getFlatCoordinates();
- var clampedLeft = Math.max(extent[0], flatCoordinates[0]);
- var clampedRight = Math.min(extent[2], flatCoordinates[flatCoordinates.length - 2]);
- var lon = ol.math.clamp(
- extent[0] + Math.abs(extent[0] - extent[2]) * this.latLabelPosition_,
- clampedLeft, clampedRight);
- var coordinate = [lon, flatCoordinates[1]];
- var point = this.parallelsLabels_[index] !== undefined ?
- this.parallelsLabels_[index].geom : new ol.geom.Point(null);
- point.setCoordinates(coordinate);
- return point;
- };
- /**
- * @param {ol.Extent} extent Extent.
- * @param {ol.Coordinate} center Center.
- * @param {number} resolution Resolution.
- * @param {number} squaredTolerance Squared tolerance.
- * @private
- */
- ol.Graticule.prototype.createGraticule_ = function(extent, center, resolution, squaredTolerance) {
- var interval = this.getInterval_(resolution);
- if (interval == -1) {
- this.meridians_.length = this.parallels_.length = 0;
- if (this.meridiansLabels_) {
- this.meridiansLabels_.length = 0;
- }
- if (this.parallelsLabels_) {
- this.parallelsLabels_.length = 0;
- }
- return;
- }
- var centerLonLat = this.toLonLatTransform_(center);
- var centerLon = centerLonLat[0];
- var centerLat = centerLonLat[1];
- var maxLines = this.maxLines_;
- var cnt, idx, lat, lon;
- var validExtent = [
- Math.max(extent[0], this.minLonP_),
- Math.max(extent[1], this.minLatP_),
- Math.min(extent[2], this.maxLonP_),
- Math.min(extent[3], this.maxLatP_)
- ];
- validExtent = ol.proj.transformExtent(validExtent, this.projection_,
- 'EPSG:4326');
- var maxLat = validExtent[3];
- var maxLon = validExtent[2];
- var minLat = validExtent[1];
- var minLon = validExtent[0];
- // Create meridians
- centerLon = Math.floor(centerLon / interval) * interval;
- lon = ol.math.clamp(centerLon, this.minLon_, this.maxLon_);
- idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, 0);
- cnt = 0;
- while (lon != this.minLon_ && cnt++ < maxLines) {
- lon = Math.max(lon - interval, this.minLon_);
- idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, idx);
- }
- lon = ol.math.clamp(centerLon, this.minLon_, this.maxLon_);
- cnt = 0;
- while (lon != this.maxLon_ && cnt++ < maxLines) {
- lon = Math.min(lon + interval, this.maxLon_);
- idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, idx);
- }
- this.meridians_.length = idx;
- if (this.meridiansLabels_) {
- this.meridiansLabels_.length = idx;
- }
- // Create parallels
- centerLat = Math.floor(centerLat / interval) * interval;
- lat = ol.math.clamp(centerLat, this.minLat_, this.maxLat_);
- idx = this.addParallel_(lat, minLon, maxLon, squaredTolerance, extent, 0);
- cnt = 0;
- while (lat != this.minLat_ && cnt++ < maxLines) {
- lat = Math.max(lat - interval, this.minLat_);
- idx = this.addParallel_(lat, minLon, maxLon, squaredTolerance, extent, idx);
- }
- lat = ol.math.clamp(centerLat, this.minLat_, this.maxLat_);
- cnt = 0;
- while (lat != this.maxLat_ && cnt++ < maxLines) {
- lat = Math.min(lat + interval, this.maxLat_);
- idx = this.addParallel_(lat, minLon, maxLon, squaredTolerance, extent, idx);
- }
- this.parallels_.length = idx;
- if (this.parallelsLabels_) {
- this.parallelsLabels_.length = idx;
- }
- };
- /**
- * @param {number} resolution Resolution.
- * @return {number} The interval in degrees.
- * @private
- */
- ol.Graticule.prototype.getInterval_ = function(resolution) {
- var centerLon = this.projectionCenterLonLat_[0];
- var centerLat = this.projectionCenterLonLat_[1];
- var interval = -1;
- var i, ii, delta, dist;
- var target = Math.pow(this.targetSize_ * resolution, 2);
- /** @type {Array.<number>} **/
- var p1 = [];
- /** @type {Array.<number>} **/
- var p2 = [];
- for (i = 0, ii = ol.Graticule.intervals_.length; i < ii; ++i) {
- delta = ol.Graticule.intervals_[i] / 2;
- p1[0] = centerLon - delta;
- p1[1] = centerLat - delta;
- p2[0] = centerLon + delta;
- p2[1] = centerLat + delta;
- this.fromLonLatTransform_(p1, p1);
- this.fromLonLatTransform_(p2, p2);
- dist = Math.pow(p2[0] - p1[0], 2) + Math.pow(p2[1] - p1[1], 2);
- if (dist <= target) {
- break;
- }
- interval = ol.Graticule.intervals_[i];
- }
- return interval;
- };
- /**
- * Get the map associated with this graticule.
- * @return {ol.PluggableMap} The map.
- * @api
- */
- ol.Graticule.prototype.getMap = function() {
- return this.map_;
- };
- /**
- * @param {number} lon Longitude.
- * @param {number} minLat Minimal latitude.
- * @param {number} maxLat Maximal latitude.
- * @param {number} squaredTolerance Squared tolerance.
- * @return {ol.geom.LineString} The meridian line string.
- * @param {number} index Index.
- * @private
- */
- ol.Graticule.prototype.getMeridian_ = function(lon, minLat, maxLat,
- squaredTolerance, index) {
- var flatCoordinates = ol.geom.flat.geodesic.meridian(lon,
- minLat, maxLat, this.projection_, squaredTolerance);
- var lineString = this.meridians_[index] !== undefined ?
- this.meridians_[index] : new ol.geom.LineString(null);
- lineString.setFlatCoordinates(ol.geom.GeometryLayout.XY, flatCoordinates);
- return lineString;
- };
- /**
- * Get the list of meridians. Meridians are lines of equal longitude.
- * @return {Array.<ol.geom.LineString>} The meridians.
- * @api
- */
- ol.Graticule.prototype.getMeridians = function() {
- return this.meridians_;
- };
- /**
- * @param {number} lat Latitude.
- * @param {number} minLon Minimal longitude.
- * @param {number} maxLon Maximal longitude.
- * @param {number} squaredTolerance Squared tolerance.
- * @return {ol.geom.LineString} The parallel line string.
- * @param {number} index Index.
- * @private
- */
- ol.Graticule.prototype.getParallel_ = function(lat, minLon, maxLon,
- squaredTolerance, index) {
- var flatCoordinates = ol.geom.flat.geodesic.parallel(lat,
- minLon, maxLon, this.projection_, squaredTolerance);
- var lineString = this.parallels_[index] !== undefined ?
- this.parallels_[index] : new ol.geom.LineString(null);
- lineString.setFlatCoordinates(ol.geom.GeometryLayout.XY, flatCoordinates);
- return lineString;
- };
- /**
- * Get the list of parallels. Parallels are lines of equal latitude.
- * @return {Array.<ol.geom.LineString>} The parallels.
- * @api
- */
- ol.Graticule.prototype.getParallels = function() {
- return this.parallels_;
- };
- /**
- * @param {ol.render.Event} e Event.
- * @private
- */
- ol.Graticule.prototype.handlePostCompose_ = function(e) {
- var vectorContext = e.vectorContext;
- var frameState = e.frameState;
- var extent = frameState.extent;
- var viewState = frameState.viewState;
- var center = viewState.center;
- var projection = viewState.projection;
- var resolution = viewState.resolution;
- var pixelRatio = frameState.pixelRatio;
- var squaredTolerance =
- resolution * resolution / (4 * pixelRatio * pixelRatio);
- var updateProjectionInfo = !this.projection_ ||
- !ol.proj.equivalent(this.projection_, projection);
- if (updateProjectionInfo) {
- this.updateProjectionInfo_(projection);
- }
- this.createGraticule_(extent, center, resolution, squaredTolerance);
- // Draw the lines
- vectorContext.setFillStrokeStyle(null, this.strokeStyle_);
- var i, l, line;
- for (i = 0, l = this.meridians_.length; i < l; ++i) {
- line = this.meridians_[i];
- vectorContext.drawGeometry(line);
- }
- for (i = 0, l = this.parallels_.length; i < l; ++i) {
- line = this.parallels_[i];
- vectorContext.drawGeometry(line);
- }
- var labelData;
- if (this.meridiansLabels_) {
- for (i = 0, l = this.meridiansLabels_.length; i < l; ++i) {
- labelData = this.meridiansLabels_[i];
- this.lonLabelStyle_.setText(labelData.text);
- vectorContext.setTextStyle(this.lonLabelStyle_);
- vectorContext.drawGeometry(labelData.geom);
- }
- }
- if (this.parallelsLabels_) {
- for (i = 0, l = this.parallelsLabels_.length; i < l; ++i) {
- labelData = this.parallelsLabels_[i];
- this.latLabelStyle_.setText(labelData.text);
- vectorContext.setTextStyle(this.latLabelStyle_);
- vectorContext.drawGeometry(labelData.geom);
- }
- }
- };
- /**
- * @param {ol.proj.Projection} projection Projection.
- * @private
- */
- ol.Graticule.prototype.updateProjectionInfo_ = function(projection) {
- var epsg4326Projection = ol.proj.get('EPSG:4326');
- var extent = projection.getExtent();
- var worldExtent = projection.getWorldExtent();
- var worldExtentP = ol.proj.transformExtent(worldExtent,
- epsg4326Projection, projection);
- var maxLat = worldExtent[3];
- var maxLon = worldExtent[2];
- var minLat = worldExtent[1];
- var minLon = worldExtent[0];
- var maxLatP = worldExtentP[3];
- var maxLonP = worldExtentP[2];
- var minLatP = worldExtentP[1];
- var minLonP = worldExtentP[0];
- this.maxLat_ = maxLat;
- this.maxLon_ = maxLon;
- this.minLat_ = minLat;
- this.minLon_ = minLon;
- this.maxLatP_ = maxLatP;
- this.maxLonP_ = maxLonP;
- this.minLatP_ = minLatP;
- this.minLonP_ = minLonP;
- this.fromLonLatTransform_ = ol.proj.getTransform(
- epsg4326Projection, projection);
- this.toLonLatTransform_ = ol.proj.getTransform(
- projection, epsg4326Projection);
- this.projectionCenterLonLat_ = this.toLonLatTransform_(
- ol.extent.getCenter(extent));
- this.projection_ = projection;
- };
- /**
- * Set the map for this graticule. The graticule will be rendered on the
- * provided map.
- * @param {ol.PluggableMap} map Map.
- * @api
- */
- ol.Graticule.prototype.setMap = function(map) {
- if (this.map_) {
- this.map_.un(ol.render.EventType.POSTCOMPOSE,
- this.handlePostCompose_, this);
- this.map_.render();
- }
- if (map) {
- map.on(ol.render.EventType.POSTCOMPOSE,
- this.handlePostCompose_, this);
- map.render();
- }
- this.map_ = map;
- };
- goog.provide('ol.Image');
- goog.require('ol');
- goog.require('ol.ImageBase');
- goog.require('ol.ImageState');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.extent');
- /**
- * @constructor
- * @extends {ol.ImageBase}
- * @param {ol.Extent} extent Extent.
- * @param {number|undefined} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @param {string} src Image source URI.
- * @param {?string} crossOrigin Cross origin.
- * @param {ol.ImageLoadFunctionType} imageLoadFunction Image load function.
- */
- ol.Image = function(extent, resolution, pixelRatio, src, crossOrigin, imageLoadFunction) {
- ol.ImageBase.call(this, extent, resolution, pixelRatio, ol.ImageState.IDLE);
- /**
- * @private
- * @type {string}
- */
- this.src_ = src;
- /**
- * @private
- * @type {HTMLCanvasElement|Image|HTMLVideoElement}
- */
- this.image_ = new Image();
- if (crossOrigin !== null) {
- this.image_.crossOrigin = crossOrigin;
- }
- /**
- * @private
- * @type {Array.<ol.EventsKey>}
- */
- this.imageListenerKeys_ = null;
- /**
- * @protected
- * @type {ol.ImageState}
- */
- this.state = ol.ImageState.IDLE;
- /**
- * @private
- * @type {ol.ImageLoadFunctionType}
- */
- this.imageLoadFunction_ = imageLoadFunction;
- };
- ol.inherits(ol.Image, ol.ImageBase);
- /**
- * @inheritDoc
- * @api
- */
- ol.Image.prototype.getImage = function() {
- return this.image_;
- };
- /**
- * Tracks loading or read errors.
- *
- * @private
- */
- ol.Image.prototype.handleImageError_ = function() {
- this.state = ol.ImageState.ERROR;
- this.unlistenImage_();
- this.changed();
- };
- /**
- * Tracks successful image load.
- *
- * @private
- */
- ol.Image.prototype.handleImageLoad_ = function() {
- if (this.resolution === undefined) {
- this.resolution = ol.extent.getHeight(this.extent) / this.image_.height;
- }
- this.state = ol.ImageState.LOADED;
- this.unlistenImage_();
- this.changed();
- };
- /**
- * Load the image or retry if loading previously failed.
- * Loading is taken care of by the tile queue, and calling this method is
- * only needed for preloading or for reloading in case of an error.
- * @override
- * @api
- */
- ol.Image.prototype.load = function() {
- if (this.state == ol.ImageState.IDLE || this.state == ol.ImageState.ERROR) {
- this.state = ol.ImageState.LOADING;
- this.changed();
- this.imageListenerKeys_ = [
- ol.events.listenOnce(this.image_, ol.events.EventType.ERROR,
- this.handleImageError_, this),
- ol.events.listenOnce(this.image_, ol.events.EventType.LOAD,
- this.handleImageLoad_, this)
- ];
- this.imageLoadFunction_(this, this.src_);
- }
- };
- /**
- * @param {HTMLCanvasElement|Image|HTMLVideoElement} image Image.
- */
- ol.Image.prototype.setImage = function(image) {
- this.image_ = image;
- };
- /**
- * Discards event handlers which listen for load completion or errors.
- *
- * @private
- */
- ol.Image.prototype.unlistenImage_ = function() {
- this.imageListenerKeys_.forEach(ol.events.unlistenByKey);
- this.imageListenerKeys_ = null;
- };
- goog.provide('ol.Tile');
- goog.require('ol');
- goog.require('ol.TileState');
- goog.require('ol.easing');
- goog.require('ol.events.EventTarget');
- goog.require('ol.events.EventType');
- /**
- * @classdesc
- * Base class for tiles.
- *
- * @constructor
- * @abstract
- * @extends {ol.events.EventTarget}
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {ol.TileState} state State.
- * @param {olx.TileOptions=} opt_options Tile options.
- */
- ol.Tile = function(tileCoord, state, opt_options) {
- ol.events.EventTarget.call(this);
- var options = opt_options ? opt_options : {};
- /**
- * @type {ol.TileCoord}
- */
- this.tileCoord = tileCoord;
- /**
- * @protected
- * @type {ol.TileState}
- */
- this.state = state;
- /**
- * An "interim" tile for this tile. The interim tile may be used while this
- * one is loading, for "smooth" transitions when changing params/dimensions
- * on the source.
- * @type {ol.Tile}
- */
- this.interimTile = null;
- /**
- * A key assigned to the tile. This is used by the tile source to determine
- * if this tile can effectively be used, or if a new tile should be created
- * and this one be used as an interim tile for this new tile.
- * @type {string}
- */
- this.key = '';
- /**
- * The duration for the opacity transition.
- * @type {number}
- */
- this.transition_ = options.transition === undefined ?
- 250 : options.transition;
- /**
- * Lookup of start times for rendering transitions. If the start time is
- * equal to -1, the transition is complete.
- * @type {Object.<number, number>}
- */
- this.transitionStarts_ = {};
- };
- ol.inherits(ol.Tile, ol.events.EventTarget);
- /**
- * @protected
- */
- ol.Tile.prototype.changed = function() {
- this.dispatchEvent(ol.events.EventType.CHANGE);
- };
- /**
- * @return {string} Key.
- */
- ol.Tile.prototype.getKey = function() {
- return this.key + '/' + this.tileCoord;
- };
- /**
- * Get the interim tile most suitable for rendering using the chain of interim
- * tiles. This corresponds to the most recent tile that has been loaded, if no
- * such tile exists, the original tile is returned.
- * @return {!ol.Tile} Best tile for rendering.
- */
- ol.Tile.prototype.getInterimTile = function() {
- if (!this.interimTile) {
- //empty chain
- return this;
- }
- var tile = this.interimTile;
- // find the first loaded tile and return it. Since the chain is sorted in
- // decreasing order of creation time, there is no need to search the remainder
- // of the list (all those tiles correspond to older requests and will be
- // cleaned up by refreshInterimChain)
- do {
- if (tile.getState() == ol.TileState.LOADED) {
- return tile;
- }
- tile = tile.interimTile;
- } while (tile);
- // we can not find a better tile
- return this;
- };
- /**
- * Goes through the chain of interim tiles and discards sections of the chain
- * that are no longer relevant.
- */
- ol.Tile.prototype.refreshInterimChain = function() {
- if (!this.interimTile) {
- return;
- }
- var tile = this.interimTile;
- var prev = this;
- do {
- if (tile.getState() == ol.TileState.LOADED) {
- //we have a loaded tile, we can discard the rest of the list
- //we would could abort any LOADING tile request
- //older than this tile (i.e. any LOADING tile following this entry in the chain)
- tile.interimTile = null;
- break;
- } else if (tile.getState() == ol.TileState.LOADING) {
- //keep this LOADING tile any loaded tiles later in the chain are
- //older than this tile, so we're still interested in the request
- prev = tile;
- } else if (tile.getState() == ol.TileState.IDLE) {
- //the head of the list is the most current tile, we don't need
- //to start any other requests for this chain
- prev.interimTile = tile.interimTile;
- } else {
- prev = tile;
- }
- tile = prev.interimTile;
- } while (tile);
- };
- /**
- * Get the tile coordinate for this tile.
- * @return {ol.TileCoord} The tile coordinate.
- * @api
- */
- ol.Tile.prototype.getTileCoord = function() {
- return this.tileCoord;
- };
- /**
- * @return {ol.TileState} State.
- */
- ol.Tile.prototype.getState = function() {
- return this.state;
- };
- /**
- * @param {ol.TileState} state State.
- */
- ol.Tile.prototype.setState = function(state) {
- this.state = state;
- this.changed();
- };
- /**
- * Load the image or retry if loading previously failed.
- * Loading is taken care of by the tile queue, and calling this method is
- * only needed for preloading or for reloading in case of an error.
- * @abstract
- * @api
- */
- ol.Tile.prototype.load = function() {};
- /**
- * Get the alpha value for rendering.
- * @param {number} id An id for the renderer.
- * @param {number} time The render frame time.
- * @return {number} A number between 0 and 1.
- */
- ol.Tile.prototype.getAlpha = function(id, time) {
- if (!this.transition_) {
- return 1;
- }
- var start = this.transitionStarts_[id];
- if (!start) {
- start = time;
- this.transitionStarts_[id] = start;
- } else if (start === -1) {
- return 1;
- }
- var delta = time - start + (1000 / 60); // avoid rendering at 0
- if (delta >= this.transition_) {
- return 1;
- }
- return ol.easing.easeIn(delta / this.transition_);
- };
- /**
- * Determine if a tile is in an alpha transition. A tile is considered in
- * transition if tile.getAlpha() has not yet been called or has been called
- * and returned 1.
- * @param {number} id An id for the renderer.
- * @return {boolean} The tile is in transition.
- */
- ol.Tile.prototype.inTransition = function(id) {
- if (!this.transition_) {
- return false;
- }
- return this.transitionStarts_[id] !== -1;
- };
- /**
- * Mark a transition as complete.
- * @param {number} id An id for the renderer.
- */
- ol.Tile.prototype.endTransition = function(id) {
- if (this.transition_) {
- this.transitionStarts_[id] = -1;
- }
- };
- goog.provide('ol.ImageTile');
- goog.require('ol');
- goog.require('ol.Tile');
- goog.require('ol.TileState');
- goog.require('ol.dom');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- /**
- * @constructor
- * @extends {ol.Tile}
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {ol.TileState} state State.
- * @param {string} src Image source URI.
- * @param {?string} crossOrigin Cross origin.
- * @param {ol.TileLoadFunctionType} tileLoadFunction Tile load function.
- * @param {olx.TileOptions=} opt_options Tile options.
- */
- ol.ImageTile = function(tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options) {
- ol.Tile.call(this, tileCoord, state, opt_options);
- /**
- * @private
- * @type {?string}
- */
- this.crossOrigin_ = crossOrigin;
- /**
- * Image URI
- *
- * @private
- * @type {string}
- */
- this.src_ = src;
- /**
- * @private
- * @type {Image|HTMLCanvasElement}
- */
- this.image_ = new Image();
- if (crossOrigin !== null) {
- this.image_.crossOrigin = crossOrigin;
- }
- /**
- * @private
- * @type {Array.<ol.EventsKey>}
- */
- this.imageListenerKeys_ = null;
- /**
- * @private
- * @type {ol.TileLoadFunctionType}
- */
- this.tileLoadFunction_ = tileLoadFunction;
- };
- ol.inherits(ol.ImageTile, ol.Tile);
- /**
- * @inheritDoc
- */
- ol.ImageTile.prototype.disposeInternal = function() {
- if (this.state == ol.TileState.LOADING) {
- this.unlistenImage_();
- this.image_ = ol.ImageTile.getBlankImage();
- }
- if (this.interimTile) {
- this.interimTile.dispose();
- }
- this.state = ol.TileState.ABORT;
- this.changed();
- ol.Tile.prototype.disposeInternal.call(this);
- };
- /**
- * Get the HTML image element for this tile (may be a Canvas, Image, or Video).
- * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.
- * @api
- */
- ol.ImageTile.prototype.getImage = function() {
- return this.image_;
- };
- /**
- * @inheritDoc
- */
- ol.ImageTile.prototype.getKey = function() {
- return this.src_;
- };
- /**
- * Tracks loading or read errors.
- *
- * @private
- */
- ol.ImageTile.prototype.handleImageError_ = function() {
- this.state = ol.TileState.ERROR;
- this.unlistenImage_();
- this.image_ = ol.ImageTile.getBlankImage();
- this.changed();
- };
- /**
- * Tracks successful image load.
- *
- * @private
- */
- ol.ImageTile.prototype.handleImageLoad_ = function() {
- if (this.image_.naturalWidth && this.image_.naturalHeight) {
- this.state = ol.TileState.LOADED;
- } else {
- this.state = ol.TileState.EMPTY;
- }
- this.unlistenImage_();
- this.changed();
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.ImageTile.prototype.load = function() {
- if (this.state == ol.TileState.ERROR) {
- this.state = ol.TileState.IDLE;
- this.image_ = new Image();
- if (this.crossOrigin_ !== null) {
- this.image_.crossOrigin = this.crossOrigin_;
- }
- }
- if (this.state == ol.TileState.IDLE) {
- this.state = ol.TileState.LOADING;
- this.changed();
- this.imageListenerKeys_ = [
- ol.events.listenOnce(this.image_, ol.events.EventType.ERROR,
- this.handleImageError_, this),
- ol.events.listenOnce(this.image_, ol.events.EventType.LOAD,
- this.handleImageLoad_, this)
- ];
- this.tileLoadFunction_(this, this.src_);
- }
- };
- /**
- * Discards event handlers which listen for load completion or errors.
- *
- * @private
- */
- ol.ImageTile.prototype.unlistenImage_ = function() {
- this.imageListenerKeys_.forEach(ol.events.unlistenByKey);
- this.imageListenerKeys_ = null;
- };
- /**
- * Get a 1-pixel blank image.
- * @return {HTMLCanvasElement} Blank image.
- */
- ol.ImageTile.getBlankImage = function() {
- var ctx = ol.dom.createCanvasContext2D(1, 1);
- ctx.fillStyle = 'rgba(0,0,0,0)';
- ctx.fillRect(0, 0, 1, 1);
- return ctx.canvas;
- };
- // FIXME should handle all geo-referenced data, not just vector data
- goog.provide('ol.interaction.DragAndDrop');
- goog.require('ol');
- goog.require('ol.functions');
- goog.require('ol.events');
- goog.require('ol.events.Event');
- goog.require('ol.events.EventType');
- goog.require('ol.interaction.Interaction');
- goog.require('ol.proj');
- /**
- * @classdesc
- * Handles input of vector data by drag and drop.
- *
- * @constructor
- * @extends {ol.interaction.Interaction}
- * @fires ol.interaction.DragAndDrop.Event
- * @param {olx.interaction.DragAndDropOptions=} opt_options Options.
- * @api
- */
- ol.interaction.DragAndDrop = function(opt_options) {
- var options = opt_options ? opt_options : {};
- ol.interaction.Interaction.call(this, {
- handleEvent: ol.interaction.DragAndDrop.handleEvent
- });
- /**
- * @private
- * @type {Array.<function(new: ol.format.Feature)>}
- */
- this.formatConstructors_ = options.formatConstructors ?
- options.formatConstructors : [];
- /**
- * @private
- * @type {ol.proj.Projection}
- */
- this.projection_ = options.projection ?
- ol.proj.get(options.projection) : null;
- /**
- * @private
- * @type {Array.<ol.EventsKey>}
- */
- this.dropListenKeys_ = null;
- /**
- * @private
- * @type {ol.source.Vector}
- */
- this.source_ = options.source || null;
- /**
- * @private
- * @type {Element}
- */
- this.target = options.target ? options.target : null;
- };
- ol.inherits(ol.interaction.DragAndDrop, ol.interaction.Interaction);
- /**
- * @param {Event} event Event.
- * @this {ol.interaction.DragAndDrop}
- * @private
- */
- ol.interaction.DragAndDrop.handleDrop_ = function(event) {
- var files = event.dataTransfer.files;
- var i, ii, file;
- for (i = 0, ii = files.length; i < ii; ++i) {
- file = files.item(i);
- var reader = new FileReader();
- reader.addEventListener(ol.events.EventType.LOAD,
- this.handleResult_.bind(this, file));
- reader.readAsText(file);
- }
- };
- /**
- * @param {Event} event Event.
- * @private
- */
- ol.interaction.DragAndDrop.handleStop_ = function(event) {
- event.stopPropagation();
- event.preventDefault();
- event.dataTransfer.dropEffect = 'copy';
- };
- /**
- * @param {File} file File.
- * @param {Event} event Load event.
- * @private
- */
- ol.interaction.DragAndDrop.prototype.handleResult_ = function(file, event) {
- var result = event.target.result;
- var map = this.getMap();
- var projection = this.projection_;
- if (!projection) {
- var view = map.getView();
- projection = view.getProjection();
- }
- var formatConstructors = this.formatConstructors_;
- var features = [];
- var i, ii;
- for (i = 0, ii = formatConstructors.length; i < ii; ++i) {
- /**
- * Avoid "cannot instantiate abstract class" error.
- * @type {Function}
- */
- var formatConstructor = formatConstructors[i];
- /**
- * @type {ol.format.Feature}
- */
- var format = new formatConstructor();
- features = this.tryReadFeatures_(format, result, {
- featureProjection: projection
- });
- if (features && features.length > 0) {
- break;
- }
- }
- if (this.source_) {
- this.source_.clear();
- this.source_.addFeatures(features);
- }
- this.dispatchEvent(
- new ol.interaction.DragAndDrop.Event(
- ol.interaction.DragAndDrop.EventType_.ADD_FEATURES, file,
- features, projection));
- };
- /**
- * Handles the {@link ol.MapBrowserEvent map browser event} unconditionally and
- * neither prevents the browser default nor stops event propagation.
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} `false` to stop event propagation.
- * @this {ol.interaction.DragAndDrop}
- * @api
- */
- ol.interaction.DragAndDrop.handleEvent = ol.functions.TRUE;
- /**
- * @private
- */
- ol.interaction.DragAndDrop.prototype.registerListeners_ = function() {
- var map = this.getMap();
- if (map) {
- var dropArea = this.target ? this.target : map.getViewport();
- this.dropListenKeys_ = [
- ol.events.listen(dropArea, ol.events.EventType.DROP,
- ol.interaction.DragAndDrop.handleDrop_, this),
- ol.events.listen(dropArea, ol.events.EventType.DRAGENTER,
- ol.interaction.DragAndDrop.handleStop_, this),
- ol.events.listen(dropArea, ol.events.EventType.DRAGOVER,
- ol.interaction.DragAndDrop.handleStop_, this),
- ol.events.listen(dropArea, ol.events.EventType.DROP,
- ol.interaction.DragAndDrop.handleStop_, this)
- ];
- }
- };
- /**
- * @inheritDoc
- */
- ol.interaction.DragAndDrop.prototype.setActive = function(active) {
- ol.interaction.Interaction.prototype.setActive.call(this, active);
- if (active) {
- this.registerListeners_();
- } else {
- this.unregisterListeners_();
- }
- };
- /**
- * @inheritDoc
- */
- ol.interaction.DragAndDrop.prototype.setMap = function(map) {
- this.unregisterListeners_();
- ol.interaction.Interaction.prototype.setMap.call(this, map);
- if (this.getActive()) {
- this.registerListeners_();
- }
- };
- /**
- * @param {ol.format.Feature} format Format.
- * @param {string} text Text.
- * @param {olx.format.ReadOptions} options Read options.
- * @private
- * @return {Array.<ol.Feature>} Features.
- */
- ol.interaction.DragAndDrop.prototype.tryReadFeatures_ = function(format, text, options) {
- try {
- return format.readFeatures(text, options);
- } catch (e) {
- return null;
- }
- };
- /**
- * @private
- */
- ol.interaction.DragAndDrop.prototype.unregisterListeners_ = function() {
- if (this.dropListenKeys_) {
- this.dropListenKeys_.forEach(ol.events.unlistenByKey);
- this.dropListenKeys_ = null;
- }
- };
- /**
- * @enum {string}
- * @private
- */
- ol.interaction.DragAndDrop.EventType_ = {
- /**
- * Triggered when features are added
- * @event ol.interaction.DragAndDrop.Event#addfeatures
- * @api
- */
- ADD_FEATURES: 'addfeatures'
- };
- /**
- * @classdesc
- * Events emitted by {@link ol.interaction.DragAndDrop} instances are instances
- * of this type.
- *
- * @constructor
- * @extends {ol.events.Event}
- * @implements {oli.interaction.DragAndDropEvent}
- * @param {ol.interaction.DragAndDrop.EventType_} type Type.
- * @param {File} file File.
- * @param {Array.<ol.Feature>=} opt_features Features.
- * @param {ol.proj.Projection=} opt_projection Projection.
- */
- ol.interaction.DragAndDrop.Event = function(type, file, opt_features, opt_projection) {
- ol.events.Event.call(this, type);
- /**
- * The features parsed from dropped data.
- * @type {Array.<ol.Feature>|undefined}
- * @api
- */
- this.features = opt_features;
- /**
- * The dropped file.
- * @type {File}
- * @api
- */
- this.file = file;
- /**
- * The feature projection.
- * @type {ol.proj.Projection|undefined}
- * @api
- */
- this.projection = opt_projection;
- };
- ol.inherits(ol.interaction.DragAndDrop.Event, ol.events.Event);
- goog.provide('ol.interaction.DragRotateAndZoom');
- goog.require('ol');
- goog.require('ol.RotationConstraint');
- goog.require('ol.ViewHint');
- goog.require('ol.events.condition');
- goog.require('ol.interaction.Interaction');
- goog.require('ol.interaction.Pointer');
- /**
- * @classdesc
- * Allows the user to zoom and rotate the map by clicking and dragging
- * on the map. By default, this interaction is limited to when the shift
- * key is held down.
- *
- * This interaction is only supported for mouse devices.
- *
- * And this interaction is not included in the default interactions.
- *
- * @constructor
- * @extends {ol.interaction.Pointer}
- * @param {olx.interaction.DragRotateAndZoomOptions=} opt_options Options.
- * @api
- */
- ol.interaction.DragRotateAndZoom = function(opt_options) {
- var options = opt_options ? opt_options : {};
- ol.interaction.Pointer.call(this, {
- handleDownEvent: ol.interaction.DragRotateAndZoom.handleDownEvent_,
- handleDragEvent: ol.interaction.DragRotateAndZoom.handleDragEvent_,
- handleUpEvent: ol.interaction.DragRotateAndZoom.handleUpEvent_
- });
- /**
- * @private
- * @type {ol.EventsConditionType}
- */
- this.condition_ = options.condition ?
- options.condition : ol.events.condition.shiftKeyOnly;
- /**
- * @private
- * @type {number|undefined}
- */
- this.lastAngle_ = undefined;
- /**
- * @private
- * @type {number|undefined}
- */
- this.lastMagnitude_ = undefined;
- /**
- * @private
- * @type {number}
- */
- this.lastScaleDelta_ = 0;
- /**
- * @private
- * @type {number}
- */
- this.duration_ = options.duration !== undefined ? options.duration : 400;
- };
- ol.inherits(ol.interaction.DragRotateAndZoom, ol.interaction.Pointer);
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @this {ol.interaction.DragRotateAndZoom}
- * @private
- */
- ol.interaction.DragRotateAndZoom.handleDragEvent_ = function(mapBrowserEvent) {
- if (!ol.events.condition.mouseOnly(mapBrowserEvent)) {
- return;
- }
- var map = mapBrowserEvent.map;
- var size = map.getSize();
- var offset = mapBrowserEvent.pixel;
- var deltaX = offset[0] - size[0] / 2;
- var deltaY = size[1] / 2 - offset[1];
- var theta = Math.atan2(deltaY, deltaX);
- var magnitude = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
- var view = map.getView();
- if (view.getConstraints().rotation !== ol.RotationConstraint.disable && this.lastAngle_ !== undefined) {
- var angleDelta = theta - this.lastAngle_;
- ol.interaction.Interaction.rotateWithoutConstraints(
- view, view.getRotation() - angleDelta);
- }
- this.lastAngle_ = theta;
- if (this.lastMagnitude_ !== undefined) {
- var resolution = this.lastMagnitude_ * (view.getResolution() / magnitude);
- ol.interaction.Interaction.zoomWithoutConstraints(view, resolution);
- }
- if (this.lastMagnitude_ !== undefined) {
- this.lastScaleDelta_ = this.lastMagnitude_ / magnitude;
- }
- this.lastMagnitude_ = magnitude;
- };
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @return {boolean} Stop drag sequence?
- * @this {ol.interaction.DragRotateAndZoom}
- * @private
- */
- ol.interaction.DragRotateAndZoom.handleUpEvent_ = function(mapBrowserEvent) {
- if (!ol.events.condition.mouseOnly(mapBrowserEvent)) {
- return true;
- }
- var map = mapBrowserEvent.map;
- var view = map.getView();
- view.setHint(ol.ViewHint.INTERACTING, -1);
- var direction = this.lastScaleDelta_ - 1;
- ol.interaction.Interaction.rotate(view, view.getRotation());
- ol.interaction.Interaction.zoom(view, view.getResolution(),
- undefined, this.duration_, direction);
- this.lastScaleDelta_ = 0;
- return false;
- };
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @return {boolean} Start drag sequence?
- * @this {ol.interaction.DragRotateAndZoom}
- * @private
- */
- ol.interaction.DragRotateAndZoom.handleDownEvent_ = function(mapBrowserEvent) {
- if (!ol.events.condition.mouseOnly(mapBrowserEvent)) {
- return false;
- }
- if (this.condition_(mapBrowserEvent)) {
- mapBrowserEvent.map.getView().setHint(ol.ViewHint.INTERACTING, 1);
- this.lastAngle_ = undefined;
- this.lastMagnitude_ = undefined;
- return true;
- } else {
- return false;
- }
- };
- goog.provide('ol.interaction.DrawEventType');
- /**
- * @enum {string}
- */
- ol.interaction.DrawEventType = {
- /**
- * Triggered upon feature draw start
- * @event ol.interaction.Draw.Event#drawstart
- * @api
- */
- DRAWSTART: 'drawstart',
- /**
- * Triggered upon feature draw end
- * @event ol.interaction.Draw.Event#drawend
- * @api
- */
- DRAWEND: 'drawend'
- };
- goog.provide('ol.layer.Vector');
- goog.require('ol');
- goog.require('ol.LayerType');
- goog.require('ol.layer.Layer');
- goog.require('ol.layer.VectorRenderType');
- goog.require('ol.obj');
- goog.require('ol.style.Style');
- /**
- * @classdesc
- * Vector data that is rendered client-side.
- * Note that any property set in the options is set as a {@link ol.Object}
- * property on the layer object; for example, setting `title: 'My Title'` in the
- * options means that `title` is observable, and has get/set accessors.
- *
- * @constructor
- * @extends {ol.layer.Layer}
- * @fires ol.render.Event
- * @param {olx.layer.VectorOptions=} opt_options Options.
- * @api
- */
- ol.layer.Vector = function(opt_options) {
- var options = opt_options ?
- opt_options : /** @type {olx.layer.VectorOptions} */ ({});
- var baseOptions = ol.obj.assign({}, options);
- delete baseOptions.style;
- delete baseOptions.renderBuffer;
- delete baseOptions.updateWhileAnimating;
- delete baseOptions.updateWhileInteracting;
- ol.layer.Layer.call(this, /** @type {olx.layer.LayerOptions} */ (baseOptions));
- /**
- * @private
- * @type {boolean}
- */
- this.declutter_ = options.declutter !== undefined ? options.declutter : false;
- /**
- * @type {number}
- * @private
- */
- this.renderBuffer_ = options.renderBuffer !== undefined ?
- options.renderBuffer : 100;
- /**
- * User provided style.
- * @type {ol.style.Style|Array.<ol.style.Style>|ol.StyleFunction}
- * @private
- */
- this.style_ = null;
- /**
- * Style function for use within the library.
- * @type {ol.StyleFunction|undefined}
- * @private
- */
- this.styleFunction_ = undefined;
- this.setStyle(options.style);
- /**
- * @type {boolean}
- * @private
- */
- this.updateWhileAnimating_ = options.updateWhileAnimating !== undefined ?
- options.updateWhileAnimating : false;
- /**
- * @type {boolean}
- * @private
- */
- this.updateWhileInteracting_ = options.updateWhileInteracting !== undefined ?
- options.updateWhileInteracting : false;
- /**
- * @private
- * @type {ol.layer.VectorTileRenderType|string}
- */
- this.renderMode_ = options.renderMode || ol.layer.VectorRenderType.VECTOR;
- /**
- * The layer type.
- * @protected
- * @type {ol.LayerType}
- */
- this.type = ol.LayerType.VECTOR;
- };
- ol.inherits(ol.layer.Vector, ol.layer.Layer);
- /**
- * @return {boolean} Declutter.
- */
- ol.layer.Vector.prototype.getDeclutter = function() {
- return this.declutter_;
- };
- /**
- * @param {boolean} declutter Declutter.
- */
- ol.layer.Vector.prototype.setDeclutter = function(declutter) {
- this.declutter_ = declutter;
- };
- /**
- * @return {number|undefined} Render buffer.
- */
- ol.layer.Vector.prototype.getRenderBuffer = function() {
- return this.renderBuffer_;
- };
- /**
- * @return {function(ol.Feature, ol.Feature): number|null|undefined} Render
- * order.
- */
- ol.layer.Vector.prototype.getRenderOrder = function() {
- return /** @type {ol.RenderOrderFunction|null|undefined} */ (
- this.get(ol.layer.Vector.Property_.RENDER_ORDER));
- };
- /**
- * Return the associated {@link ol.source.Vector vectorsource} of the layer.
- * @function
- * @return {ol.source.Vector} Source.
- * @api
- */
- ol.layer.Vector.prototype.getSource;
- /**
- * Get the style for features. This returns whatever was passed to the `style`
- * option at construction or to the `setStyle` method.
- * @return {ol.style.Style|Array.<ol.style.Style>|ol.StyleFunction}
- * Layer style.
- * @api
- */
- ol.layer.Vector.prototype.getStyle = function() {
- return this.style_;
- };
- /**
- * Get the style function.
- * @return {ol.StyleFunction|undefined} Layer style function.
- * @api
- */
- ol.layer.Vector.prototype.getStyleFunction = function() {
- return this.styleFunction_;
- };
- /**
- * @return {boolean} Whether the rendered layer should be updated while
- * animating.
- */
- ol.layer.Vector.prototype.getUpdateWhileAnimating = function() {
- return this.updateWhileAnimating_;
- };
- /**
- * @return {boolean} Whether the rendered layer should be updated while
- * interacting.
- */
- ol.layer.Vector.prototype.getUpdateWhileInteracting = function() {
- return this.updateWhileInteracting_;
- };
- /**
- * @param {ol.RenderOrderFunction|null|undefined} renderOrder
- * Render order.
- */
- ol.layer.Vector.prototype.setRenderOrder = function(renderOrder) {
- this.set(ol.layer.Vector.Property_.RENDER_ORDER, renderOrder);
- };
- /**
- * Set the style for features. This can be a single style object, an array
- * of styles, or a function that takes a feature and resolution and returns
- * an array of styles. If it is `undefined` the default style is used. If
- * it is `null` the layer has no style (a `null` style), so only features
- * that have their own styles will be rendered in the layer. See
- * {@link ol.style} for information on the default style.
- * @param {ol.style.Style|Array.<ol.style.Style>|ol.StyleFunction|null|undefined}
- * style Layer style.
- * @api
- */
- ol.layer.Vector.prototype.setStyle = function(style) {
- this.style_ = style !== undefined ? style : ol.style.Style.defaultFunction;
- this.styleFunction_ = style === null ?
- undefined : ol.style.Style.createFunction(this.style_);
- this.changed();
- };
- /**
- * @return {ol.layer.VectorRenderType|string} The render mode.
- */
- ol.layer.Vector.prototype.getRenderMode = function() {
- return this.renderMode_;
- };
- /**
- * @enum {string}
- * @private
- */
- ol.layer.Vector.Property_ = {
- RENDER_ORDER: 'renderOrder'
- };
- goog.provide('ol.loadingstrategy');
- /**
- * Strategy function for loading all features with a single request.
- * @param {ol.Extent} extent Extent.
- * @param {number} resolution Resolution.
- * @return {Array.<ol.Extent>} Extents.
- * @api
- */
- ol.loadingstrategy.all = function(extent, resolution) {
- return [[-Infinity, -Infinity, Infinity, Infinity]];
- };
- /**
- * Strategy function for loading features based on the view's extent and
- * resolution.
- * @param {ol.Extent} extent Extent.
- * @param {number} resolution Resolution.
- * @return {Array.<ol.Extent>} Extents.
- * @api
- */
- ol.loadingstrategy.bbox = function(extent, resolution) {
- return [extent];
- };
- /**
- * Creates a strategy function for loading features based on a tile grid.
- * @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
- * @return {function(ol.Extent, number): Array.<ol.Extent>} Loading strategy.
- * @api
- */
- ol.loadingstrategy.tile = function(tileGrid) {
- return (
- /**
- * @param {ol.Extent} extent Extent.
- * @param {number} resolution Resolution.
- * @return {Array.<ol.Extent>} Extents.
- */
- function(extent, resolution) {
- var z = tileGrid.getZForResolution(resolution);
- var tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
- /** @type {Array.<ol.Extent>} */
- var extents = [];
- /** @type {ol.TileCoord} */
- var tileCoord = [z, 0, 0];
- for (tileCoord[1] = tileRange.minX; tileCoord[1] <= tileRange.maxX;
- ++tileCoord[1]) {
- for (tileCoord[2] = tileRange.minY; tileCoord[2] <= tileRange.maxY;
- ++tileCoord[2]) {
- extents.push(tileGrid.getTileCoordExtent(tileCoord));
- }
- }
- return extents;
- });
- };
- goog.provide('ol.source.Source');
- goog.require('ol');
- goog.require('ol.Attribution');
- goog.require('ol.Object');
- goog.require('ol.proj');
- goog.require('ol.source.State');
- /**
- * @classdesc
- * Abstract base class; normally only used for creating subclasses and not
- * instantiated in apps.
- * Base class for {@link ol.layer.Layer} sources.
- *
- * A generic `change` event is triggered when the state of the source changes.
- *
- * @constructor
- * @abstract
- * @extends {ol.Object}
- * @param {ol.SourceSourceOptions} options Source options.
- * @api
- */
- ol.source.Source = function(options) {
- ol.Object.call(this);
- /**
- * @private
- * @type {ol.proj.Projection}
- */
- this.projection_ = ol.proj.get(options.projection);
- /**
- * @private
- * @type {Array.<ol.Attribution>}
- */
- this.attributions_ = null;
- /**
- * @private
- * @type {?ol.Attribution2}
- */
- this.attributions2_ = this.adaptAttributions_(options.attributions);
- /**
- * @private
- * @type {string|olx.LogoOptions|undefined}
- */
- this.logo_ = options.logo;
- /**
- * @private
- * @type {ol.source.State}
- */
- this.state_ = options.state !== undefined ?
- options.state : ol.source.State.READY;
- /**
- * @private
- * @type {boolean}
- */
- this.wrapX_ = options.wrapX !== undefined ? options.wrapX : false;
- };
- ol.inherits(ol.source.Source, ol.Object);
- /**
- * Turns the attributions option into an attributions function.
- * @suppress {deprecated}
- * @param {ol.AttributionLike|undefined} attributionLike The attribution option.
- * @return {?ol.Attribution2} An attribution function (or null).
- */
- ol.source.Source.prototype.adaptAttributions_ = function(attributionLike) {
- if (!attributionLike) {
- return null;
- }
- if (attributionLike instanceof ol.Attribution) {
- // TODO: remove attributions_ in next major release
- this.attributions_ = [attributionLike];
- return function(frameState) {
- return [attributionLike.getHTML()];
- };
- }
- if (Array.isArray(attributionLike)) {
- if (attributionLike[0] instanceof ol.Attribution) {
- // TODO: remove attributions_ in next major release
- this.attributions_ = attributionLike;
- var attributions = attributionLike.map(function(attribution) {
- return attribution.getHTML();
- });
- return function(frameState) {
- return attributions;
- };
- }
- // TODO: remove attributions_ in next major release
- this.attributions_ = attributionLike.map(function(attribution) {
- return new ol.Attribution({html: attribution});
- });
- return function(frameState) {
- return attributionLike;
- };
- }
- if (typeof attributionLike === 'function') {
- return attributionLike;
- }
- // TODO: remove attributions_ in next major release
- this.attributions_ = [
- new ol.Attribution({html: attributionLike})
- ];
- return function(frameState) {
- return [attributionLike];
- };
- };
- /**
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {number} resolution Resolution.
- * @param {number} rotation Rotation.
- * @param {number} hitTolerance Hit tolerance in pixels.
- * @param {Object.<string, boolean>} skippedFeatureUids Skipped feature uids.
- * @param {function((ol.Feature|ol.render.Feature)): T} callback Feature
- * callback.
- * @return {T|undefined} Callback result.
- * @template T
- */
- ol.source.Source.prototype.forEachFeatureAtCoordinate = ol.nullFunction;
- /**
- * Get the attributions of the source.
- * @return {Array.<ol.Attribution>} Attributions.
- * @api
- */
- ol.source.Source.prototype.getAttributions = function() {
- return this.attributions_;
- };
- /**
- * Get the attribution function for the source.
- * @return {?ol.Attribution2} Attribution function.
- */
- ol.source.Source.prototype.getAttributions2 = function() {
- return this.attributions2_;
- };
- /**
- * Get the logo of the source.
- * @return {string|olx.LogoOptions|undefined} Logo.
- * @api
- */
- ol.source.Source.prototype.getLogo = function() {
- return this.logo_;
- };
- /**
- * Get the projection of the source.
- * @return {ol.proj.Projection} Projection.
- * @api
- */
- ol.source.Source.prototype.getProjection = function() {
- return this.projection_;
- };
- /**
- * @abstract
- * @return {Array.<number>|undefined} Resolutions.
- */
- ol.source.Source.prototype.getResolutions = function() {};
- /**
- * Get the state of the source, see {@link ol.source.State} for possible states.
- * @return {ol.source.State} State.
- * @api
- */
- ol.source.Source.prototype.getState = function() {
- return this.state_;
- };
- /**
- * @return {boolean|undefined} Wrap X.
- */
- ol.source.Source.prototype.getWrapX = function() {
- return this.wrapX_;
- };
- /**
- * Refreshes the source and finally dispatches a 'change' event.
- * @api
- */
- ol.source.Source.prototype.refresh = function() {
- this.changed();
- };
- /**
- * Set the attributions of the source.
- * @param {ol.AttributionLike|undefined} attributions Attributions.
- * Can be passed as `string`, `Array<string>`, `{@link ol.Attribution2}`,
- * or `undefined`.
- * @api
- */
- ol.source.Source.prototype.setAttributions = function(attributions) {
- this.attributions2_ = this.adaptAttributions_(attributions);
- this.changed();
- };
- /**
- * Set the logo of the source.
- * @param {string|olx.LogoOptions|undefined} logo Logo.
- */
- ol.source.Source.prototype.setLogo = function(logo) {
- this.logo_ = logo;
- };
- /**
- * Set the state of the source.
- * @param {ol.source.State} state State.
- * @protected
- */
- ol.source.Source.prototype.setState = function(state) {
- this.state_ = state;
- this.changed();
- };
- goog.provide('ol.source.VectorEventType');
- /**
- * @enum {string}
- */
- ol.source.VectorEventType = {
- /**
- * Triggered when a feature is added to the source.
- * @event ol.source.Vector.Event#addfeature
- * @api
- */
- ADDFEATURE: 'addfeature',
- /**
- * Triggered when a feature is updated.
- * @event ol.source.Vector.Event#changefeature
- * @api
- */
- CHANGEFEATURE: 'changefeature',
- /**
- * Triggered when the clear method is called on the source.
- * @event ol.source.Vector.Event#clear
- * @api
- */
- CLEAR: 'clear',
- /**
- * Triggered when a feature is removed from the source.
- * See {@link ol.source.Vector#clear source.clear()} for exceptions.
- * @event ol.source.Vector.Event#removefeature
- * @api
- */
- REMOVEFEATURE: 'removefeature'
- };
- goog.provide('ol.structs.RBush');
- goog.require('ol');
- goog.require('ol.ext.rbush');
- goog.require('ol.extent');
- goog.require('ol.obj');
- /**
- * Wrapper around the RBush by Vladimir Agafonkin.
- *
- * @constructor
- * @param {number=} opt_maxEntries Max entries.
- * @see https://github.com/mourner/rbush
- * @struct
- * @template T
- */
- ol.structs.RBush = function(opt_maxEntries) {
- /**
- * @private
- */
- this.rbush_ = ol.ext.rbush(opt_maxEntries);
- /**
- * A mapping between the objects added to this rbush wrapper
- * and the objects that are actually added to the internal rbush.
- * @private
- * @type {Object.<number, ol.RBushEntry>}
- */
- this.items_ = {};
- };
- /**
- * Insert a value into the RBush.
- * @param {ol.Extent} extent Extent.
- * @param {T} value Value.
- */
- ol.structs.RBush.prototype.insert = function(extent, value) {
- /** @type {ol.RBushEntry} */
- var item = {
- minX: extent[0],
- minY: extent[1],
- maxX: extent[2],
- maxY: extent[3],
- value: value
- };
- this.rbush_.insert(item);
- this.items_[ol.getUid(value)] = item;
- };
- /**
- * Bulk-insert values into the RBush.
- * @param {Array.<ol.Extent>} extents Extents.
- * @param {Array.<T>} values Values.
- */
- ol.structs.RBush.prototype.load = function(extents, values) {
- var items = new Array(values.length);
- for (var i = 0, l = values.length; i < l; i++) {
- var extent = extents[i];
- var value = values[i];
- /** @type {ol.RBushEntry} */
- var item = {
- minX: extent[0],
- minY: extent[1],
- maxX: extent[2],
- maxY: extent[3],
- value: value
- };
- items[i] = item;
- this.items_[ol.getUid(value)] = item;
- }
- this.rbush_.load(items);
- };
- /**
- * Remove a value from the RBush.
- * @param {T} value Value.
- * @return {boolean} Removed.
- */
- ol.structs.RBush.prototype.remove = function(value) {
- var uid = ol.getUid(value);
- // get the object in which the value was wrapped when adding to the
- // internal rbush. then use that object to do the removal.
- var item = this.items_[uid];
- delete this.items_[uid];
- return this.rbush_.remove(item) !== null;
- };
- /**
- * Update the extent of a value in the RBush.
- * @param {ol.Extent} extent Extent.
- * @param {T} value Value.
- */
- ol.structs.RBush.prototype.update = function(extent, value) {
- var item = this.items_[ol.getUid(value)];
- var bbox = [item.minX, item.minY, item.maxX, item.maxY];
- if (!ol.extent.equals(bbox, extent)) {
- this.remove(value);
- this.insert(extent, value);
- }
- };
- /**
- * Return all values in the RBush.
- * @return {Array.<T>} All.
- */
- ol.structs.RBush.prototype.getAll = function() {
- var items = this.rbush_.all();
- return items.map(function(item) {
- return item.value;
- });
- };
- /**
- * Return all values in the given extent.
- * @param {ol.Extent} extent Extent.
- * @return {Array.<T>} All in extent.
- */
- ol.structs.RBush.prototype.getInExtent = function(extent) {
- /** @type {ol.RBushEntry} */
- var bbox = {
- minX: extent[0],
- minY: extent[1],
- maxX: extent[2],
- maxY: extent[3]
- };
- var items = this.rbush_.search(bbox);
- return items.map(function(item) {
- return item.value;
- });
- };
- /**
- * Calls a callback function with each value in the tree.
- * If the callback returns a truthy value, this value is returned without
- * checking the rest of the tree.
- * @param {function(this: S, T): *} callback Callback.
- * @param {S=} opt_this The object to use as `this` in `callback`.
- * @return {*} Callback return value.
- * @template S
- */
- ol.structs.RBush.prototype.forEach = function(callback, opt_this) {
- return this.forEach_(this.getAll(), callback, opt_this);
- };
- /**
- * Calls a callback function with each value in the provided extent.
- * @param {ol.Extent} extent Extent.
- * @param {function(this: S, T): *} callback Callback.
- * @param {S=} opt_this The object to use as `this` in `callback`.
- * @return {*} Callback return value.
- * @template S
- */
- ol.structs.RBush.prototype.forEachInExtent = function(extent, callback, opt_this) {
- return this.forEach_(this.getInExtent(extent), callback, opt_this);
- };
- /**
- * @param {Array.<T>} values Values.
- * @param {function(this: S, T): *} callback Callback.
- * @param {S=} opt_this The object to use as `this` in `callback`.
- * @private
- * @return {*} Callback return value.
- * @template S
- */
- ol.structs.RBush.prototype.forEach_ = function(values, callback, opt_this) {
- var result;
- for (var i = 0, l = values.length; i < l; i++) {
- result = callback.call(opt_this, values[i]);
- if (result) {
- return result;
- }
- }
- return result;
- };
- /**
- * @return {boolean} Is empty.
- */
- ol.structs.RBush.prototype.isEmpty = function() {
- return ol.obj.isEmpty(this.items_);
- };
- /**
- * Remove all values from the RBush.
- */
- ol.structs.RBush.prototype.clear = function() {
- this.rbush_.clear();
- this.items_ = {};
- };
- /**
- * @param {ol.Extent=} opt_extent Extent.
- * @return {ol.Extent} Extent.
- */
- ol.structs.RBush.prototype.getExtent = function(opt_extent) {
- // FIXME add getExtent() to rbush
- var data = this.rbush_.data;
- return ol.extent.createOrUpdate(data.minX, data.minY, data.maxX, data.maxY, opt_extent);
- };
- /**
- * @param {ol.structs.RBush} rbush R-Tree.
- */
- ol.structs.RBush.prototype.concat = function(rbush) {
- this.rbush_.load(rbush.rbush_.all());
- for (var i in rbush.items_) {
- this.items_[i | 0] = rbush.items_[i | 0];
- }
- };
- // FIXME bulk feature upload - suppress events
- // FIXME make change-detection more refined (notably, geometry hint)
- goog.provide('ol.source.Vector');
- goog.require('ol');
- goog.require('ol.Collection');
- goog.require('ol.CollectionEventType');
- goog.require('ol.ObjectEventType');
- goog.require('ol.array');
- goog.require('ol.asserts');
- goog.require('ol.events');
- goog.require('ol.events.Event');
- goog.require('ol.events.EventType');
- goog.require('ol.extent');
- goog.require('ol.featureloader');
- goog.require('ol.functions');
- goog.require('ol.loadingstrategy');
- goog.require('ol.obj');
- goog.require('ol.source.Source');
- goog.require('ol.source.State');
- goog.require('ol.source.VectorEventType');
- goog.require('ol.structs.RBush');
- /**
- * @classdesc
- * Provides a source of features for vector layers. Vector features provided
- * by this source are suitable for editing. See {@link ol.source.VectorTile} for
- * vector data that is optimized for rendering.
- *
- * @constructor
- * @extends {ol.source.Source}
- * @fires ol.source.Vector.Event
- * @param {olx.source.VectorOptions=} opt_options Vector source options.
- * @api
- */
- ol.source.Vector = function(opt_options) {
- var options = opt_options || {};
- ol.source.Source.call(this, {
- attributions: options.attributions,
- logo: options.logo,
- projection: undefined,
- state: ol.source.State.READY,
- wrapX: options.wrapX !== undefined ? options.wrapX : true
- });
- /**
- * @private
- * @type {ol.FeatureLoader}
- */
- this.loader_ = ol.nullFunction;
- /**
- * @private
- * @type {ol.format.Feature|undefined}
- */
- this.format_ = options.format;
- /**
- * @private
- * @type {boolean}
- */
- this.overlaps_ = options.overlaps == undefined ? true : options.overlaps;
- /**
- * @private
- * @type {string|ol.FeatureUrlFunction|undefined}
- */
- this.url_ = options.url;
- if (options.loader !== undefined) {
- this.loader_ = options.loader;
- } else if (this.url_ !== undefined) {
- ol.asserts.assert(this.format_, 7); // `format` must be set when `url` is set
- // create a XHR feature loader for "url" and "format"
- this.loader_ = ol.featureloader.xhr(this.url_, /** @type {ol.format.Feature} */ (this.format_));
- }
- /**
- * @private
- * @type {ol.LoadingStrategy}
- */
- this.strategy_ = options.strategy !== undefined ? options.strategy :
- ol.loadingstrategy.all;
- var useSpatialIndex =
- options.useSpatialIndex !== undefined ? options.useSpatialIndex : true;
- /**
- * @private
- * @type {ol.structs.RBush.<ol.Feature>}
- */
- this.featuresRtree_ = useSpatialIndex ? new ol.structs.RBush() : null;
- /**
- * @private
- * @type {ol.structs.RBush.<{extent: ol.Extent}>}
- */
- this.loadedExtentsRtree_ = new ol.structs.RBush();
- /**
- * @private
- * @type {Object.<string, ol.Feature>}
- */
- this.nullGeometryFeatures_ = {};
- /**
- * A lookup of features by id (the return from feature.getId()).
- * @private
- * @type {Object.<string, ol.Feature>}
- */
- this.idIndex_ = {};
- /**
- * A lookup of features without id (keyed by ol.getUid(feature)).
- * @private
- * @type {Object.<string, ol.Feature>}
- */
- this.undefIdIndex_ = {};
- /**
- * @private
- * @type {Object.<string, Array.<ol.EventsKey>>}
- */
- this.featureChangeKeys_ = {};
- /**
- * @private
- * @type {ol.Collection.<ol.Feature>}
- */
- this.featuresCollection_ = null;
- var collection, features;
- if (options.features instanceof ol.Collection) {
- collection = options.features;
- features = collection.getArray();
- } else if (Array.isArray(options.features)) {
- features = options.features;
- }
- if (!useSpatialIndex && collection === undefined) {
- collection = new ol.Collection(features);
- }
- if (features !== undefined) {
- this.addFeaturesInternal(features);
- }
- if (collection !== undefined) {
- this.bindFeaturesCollection_(collection);
- }
- };
- ol.inherits(ol.source.Vector, ol.source.Source);
- /**
- * Add a single feature to the source. If you want to add a batch of features
- * at once, call {@link ol.source.Vector#addFeatures source.addFeatures()}
- * instead. A feature will not be added to the source if feature with
- * the same id is already there. The reason for this behavior is to avoid
- * feature duplication when using bbox or tile loading strategies.
- * @param {ol.Feature} feature Feature to add.
- * @api
- */
- ol.source.Vector.prototype.addFeature = function(feature) {
- this.addFeatureInternal(feature);
- this.changed();
- };
- /**
- * Add a feature without firing a `change` event.
- * @param {ol.Feature} feature Feature.
- * @protected
- */
- ol.source.Vector.prototype.addFeatureInternal = function(feature) {
- var featureKey = ol.getUid(feature).toString();
- if (!this.addToIndex_(featureKey, feature)) {
- return;
- }
- this.setupChangeEvents_(featureKey, feature);
- var geometry = feature.getGeometry();
- if (geometry) {
- var extent = geometry.getExtent();
- if (this.featuresRtree_) {
- this.featuresRtree_.insert(extent, feature);
- }
- } else {
- this.nullGeometryFeatures_[featureKey] = feature;
- }
- this.dispatchEvent(
- new ol.source.Vector.Event(ol.source.VectorEventType.ADDFEATURE, feature));
- };
- /**
- * @param {string} featureKey Unique identifier for the feature.
- * @param {ol.Feature} feature The feature.
- * @private
- */
- ol.source.Vector.prototype.setupChangeEvents_ = function(featureKey, feature) {
- this.featureChangeKeys_[featureKey] = [
- ol.events.listen(feature, ol.events.EventType.CHANGE,
- this.handleFeatureChange_, this),
- ol.events.listen(feature, ol.ObjectEventType.PROPERTYCHANGE,
- this.handleFeatureChange_, this)
- ];
- };
- /**
- * @param {string} featureKey Unique identifier for the feature.
- * @param {ol.Feature} feature The feature.
- * @return {boolean} The feature is "valid", in the sense that it is also a
- * candidate for insertion into the Rtree.
- * @private
- */
- ol.source.Vector.prototype.addToIndex_ = function(featureKey, feature) {
- var valid = true;
- var id = feature.getId();
- if (id !== undefined) {
- if (!(id.toString() in this.idIndex_)) {
- this.idIndex_[id.toString()] = feature;
- } else {
- valid = false;
- }
- } else {
- ol.asserts.assert(!(featureKey in this.undefIdIndex_),
- 30); // The passed `feature` was already added to the source
- this.undefIdIndex_[featureKey] = feature;
- }
- return valid;
- };
- /**
- * Add a batch of features to the source.
- * @param {Array.<ol.Feature>} features Features to add.
- * @api
- */
- ol.source.Vector.prototype.addFeatures = function(features) {
- this.addFeaturesInternal(features);
- this.changed();
- };
- /**
- * Add features without firing a `change` event.
- * @param {Array.<ol.Feature>} features Features.
- * @protected
- */
- ol.source.Vector.prototype.addFeaturesInternal = function(features) {
- var featureKey, i, length, feature;
- var extents = [];
- var newFeatures = [];
- var geometryFeatures = [];
- for (i = 0, length = features.length; i < length; i++) {
- feature = features[i];
- featureKey = ol.getUid(feature).toString();
- if (this.addToIndex_(featureKey, feature)) {
- newFeatures.push(feature);
- }
- }
- for (i = 0, length = newFeatures.length; i < length; i++) {
- feature = newFeatures[i];
- featureKey = ol.getUid(feature).toString();
- this.setupChangeEvents_(featureKey, feature);
- var geometry = feature.getGeometry();
- if (geometry) {
- var extent = geometry.getExtent();
- extents.push(extent);
- geometryFeatures.push(feature);
- } else {
- this.nullGeometryFeatures_[featureKey] = feature;
- }
- }
- if (this.featuresRtree_) {
- this.featuresRtree_.load(extents, geometryFeatures);
- }
- for (i = 0, length = newFeatures.length; i < length; i++) {
- this.dispatchEvent(new ol.source.Vector.Event(
- ol.source.VectorEventType.ADDFEATURE, newFeatures[i]));
- }
- };
- /**
- * @param {!ol.Collection.<ol.Feature>} collection Collection.
- * @private
- */
- ol.source.Vector.prototype.bindFeaturesCollection_ = function(collection) {
- var modifyingCollection = false;
- ol.events.listen(this, ol.source.VectorEventType.ADDFEATURE,
- function(evt) {
- if (!modifyingCollection) {
- modifyingCollection = true;
- collection.push(evt.feature);
- modifyingCollection = false;
- }
- });
- ol.events.listen(this, ol.source.VectorEventType.REMOVEFEATURE,
- function(evt) {
- if (!modifyingCollection) {
- modifyingCollection = true;
- collection.remove(evt.feature);
- modifyingCollection = false;
- }
- });
- ol.events.listen(collection, ol.CollectionEventType.ADD,
- function(evt) {
- if (!modifyingCollection) {
- modifyingCollection = true;
- this.addFeature(/** @type {ol.Feature} */ (evt.element));
- modifyingCollection = false;
- }
- }, this);
- ol.events.listen(collection, ol.CollectionEventType.REMOVE,
- function(evt) {
- if (!modifyingCollection) {
- modifyingCollection = true;
- this.removeFeature(/** @type {ol.Feature} */ (evt.element));
- modifyingCollection = false;
- }
- }, this);
- this.featuresCollection_ = collection;
- };
- /**
- * Remove all features from the source.
- * @param {boolean=} opt_fast Skip dispatching of {@link removefeature} events.
- * @api
- */
- ol.source.Vector.prototype.clear = function(opt_fast) {
- if (opt_fast) {
- for (var featureId in this.featureChangeKeys_) {
- var keys = this.featureChangeKeys_[featureId];
- keys.forEach(ol.events.unlistenByKey);
- }
- if (!this.featuresCollection_) {
- this.featureChangeKeys_ = {};
- this.idIndex_ = {};
- this.undefIdIndex_ = {};
- }
- } else {
- if (this.featuresRtree_) {
- this.featuresRtree_.forEach(this.removeFeatureInternal, this);
- for (var id in this.nullGeometryFeatures_) {
- this.removeFeatureInternal(this.nullGeometryFeatures_[id]);
- }
- }
- }
- if (this.featuresCollection_) {
- this.featuresCollection_.clear();
- }
- if (this.featuresRtree_) {
- this.featuresRtree_.clear();
- }
- this.loadedExtentsRtree_.clear();
- this.nullGeometryFeatures_ = {};
- var clearEvent = new ol.source.Vector.Event(ol.source.VectorEventType.CLEAR);
- this.dispatchEvent(clearEvent);
- this.changed();
- };
- /**
- * Iterate through all features on the source, calling the provided callback
- * with each one. If the callback returns any "truthy" value, iteration will
- * stop and the function will return the same value.
- *
- * @param {function(this: T, ol.Feature): S} callback Called with each feature
- * on the source. Return a truthy value to stop iteration.
- * @param {T=} opt_this The object to use as `this` in the callback.
- * @return {S|undefined} The return value from the last call to the callback.
- * @template T,S
- * @api
- */
- ol.source.Vector.prototype.forEachFeature = function(callback, opt_this) {
- if (this.featuresRtree_) {
- return this.featuresRtree_.forEach(callback, opt_this);
- } else if (this.featuresCollection_) {
- return this.featuresCollection_.forEach(callback, opt_this);
- }
- };
- /**
- * Iterate through all features whose geometries contain the provided
- * coordinate, calling the callback with each feature. If the callback returns
- * a "truthy" value, iteration will stop and the function will return the same
- * value.
- *
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {function(this: T, ol.Feature): S} callback Called with each feature
- * whose goemetry contains the provided coordinate.
- * @param {T=} opt_this The object to use as `this` in the callback.
- * @return {S|undefined} The return value from the last call to the callback.
- * @template T,S
- */
- ol.source.Vector.prototype.forEachFeatureAtCoordinateDirect = function(coordinate, callback, opt_this) {
- var extent = [coordinate[0], coordinate[1], coordinate[0], coordinate[1]];
- return this.forEachFeatureInExtent(extent, function(feature) {
- var geometry = feature.getGeometry();
- if (geometry.intersectsCoordinate(coordinate)) {
- return callback.call(opt_this, feature);
- } else {
- return undefined;
- }
- });
- };
- /**
- * Iterate through all features whose bounding box intersects the provided
- * extent (note that the feature's geometry may not intersect the extent),
- * calling the callback with each feature. If the callback returns a "truthy"
- * value, iteration will stop and the function will return the same value.
- *
- * If you are interested in features whose geometry intersects an extent, call
- * the {@link ol.source.Vector#forEachFeatureIntersectingExtent
- * source.forEachFeatureIntersectingExtent()} method instead.
- *
- * When `useSpatialIndex` is set to false, this method will loop through all
- * features, equivalent to {@link ol.source.Vector#forEachFeature}.
- *
- * @param {ol.Extent} extent Extent.
- * @param {function(this: T, ol.Feature): S} callback Called with each feature
- * whose bounding box intersects the provided extent.
- * @param {T=} opt_this The object to use as `this` in the callback.
- * @return {S|undefined} The return value from the last call to the callback.
- * @template T,S
- * @api
- */
- ol.source.Vector.prototype.forEachFeatureInExtent = function(extent, callback, opt_this) {
- if (this.featuresRtree_) {
- return this.featuresRtree_.forEachInExtent(extent, callback, opt_this);
- } else if (this.featuresCollection_) {
- return this.featuresCollection_.forEach(callback, opt_this);
- }
- };
- /**
- * Iterate through all features whose geometry intersects the provided extent,
- * calling the callback with each feature. If the callback returns a "truthy"
- * value, iteration will stop and the function will return the same value.
- *
- * If you only want to test for bounding box intersection, call the
- * {@link ol.source.Vector#forEachFeatureInExtent
- * source.forEachFeatureInExtent()} method instead.
- *
- * @param {ol.Extent} extent Extent.
- * @param {function(this: T, ol.Feature): S} callback Called with each feature
- * whose geometry intersects the provided extent.
- * @param {T=} opt_this The object to use as `this` in the callback.
- * @return {S|undefined} The return value from the last call to the callback.
- * @template T,S
- * @api
- */
- ol.source.Vector.prototype.forEachFeatureIntersectingExtent = function(extent, callback, opt_this) {
- return this.forEachFeatureInExtent(extent,
- /**
- * @param {ol.Feature} feature Feature.
- * @return {S|undefined} The return value from the last call to the callback.
- * @template S
- */
- function(feature) {
- var geometry = feature.getGeometry();
- if (geometry.intersectsExtent(extent)) {
- var result = callback.call(opt_this, feature);
- if (result) {
- return result;
- }
- }
- });
- };
- /**
- * Get the features collection associated with this source. Will be `null`
- * unless the source was configured with `useSpatialIndex` set to `false`, or
- * with an {@link ol.Collection} as `features`.
- * @return {ol.Collection.<ol.Feature>} The collection of features.
- * @api
- */
- ol.source.Vector.prototype.getFeaturesCollection = function() {
- return this.featuresCollection_;
- };
- /**
- * Get all features on the source in random order.
- * @return {Array.<ol.Feature>} Features.
- * @api
- */
- ol.source.Vector.prototype.getFeatures = function() {
- var features;
- if (this.featuresCollection_) {
- features = this.featuresCollection_.getArray();
- } else if (this.featuresRtree_) {
- features = this.featuresRtree_.getAll();
- if (!ol.obj.isEmpty(this.nullGeometryFeatures_)) {
- ol.array.extend(
- features, ol.obj.getValues(this.nullGeometryFeatures_));
- }
- }
- return /** @type {Array.<ol.Feature>} */ (features);
- };
- /**
- * Get all features whose geometry intersects the provided coordinate.
- * @param {ol.Coordinate} coordinate Coordinate.
- * @return {Array.<ol.Feature>} Features.
- * @api
- */
- ol.source.Vector.prototype.getFeaturesAtCoordinate = function(coordinate) {
- var features = [];
- this.forEachFeatureAtCoordinateDirect(coordinate, function(feature) {
- features.push(feature);
- });
- return features;
- };
- /**
- * Get all features in the provided extent. Note that this returns an array of
- * all features intersecting the given extent in random order (so it may include
- * features whose geometries do not intersect the extent).
- *
- * This method is not available when the source is configured with
- * `useSpatialIndex` set to `false`.
- * @param {ol.Extent} extent Extent.
- * @return {Array.<ol.Feature>} Features.
- * @api
- */
- ol.source.Vector.prototype.getFeaturesInExtent = function(extent) {
- return this.featuresRtree_.getInExtent(extent);
- };
- /**
- * Get the closest feature to the provided coordinate.
- *
- * This method is not available when the source is configured with
- * `useSpatialIndex` set to `false`.
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {function(ol.Feature):boolean=} opt_filter Feature filter function.
- * The filter function will receive one argument, the {@link ol.Feature feature}
- * and it should return a boolean value. By default, no filtering is made.
- * @return {ol.Feature} Closest feature.
- * @api
- */
- ol.source.Vector.prototype.getClosestFeatureToCoordinate = function(coordinate, opt_filter) {
- // Find the closest feature using branch and bound. We start searching an
- // infinite extent, and find the distance from the first feature found. This
- // becomes the closest feature. We then compute a smaller extent which any
- // closer feature must intersect. We continue searching with this smaller
- // extent, trying to find a closer feature. Every time we find a closer
- // feature, we update the extent being searched so that any even closer
- // feature must intersect it. We continue until we run out of features.
- var x = coordinate[0];
- var y = coordinate[1];
- var closestFeature = null;
- var closestPoint = [NaN, NaN];
- var minSquaredDistance = Infinity;
- var extent = [-Infinity, -Infinity, Infinity, Infinity];
- var filter = opt_filter ? opt_filter : ol.functions.TRUE;
- this.featuresRtree_.forEachInExtent(extent,
- /**
- * @param {ol.Feature} feature Feature.
- */
- function(feature) {
- if (filter(feature)) {
- var geometry = feature.getGeometry();
- var previousMinSquaredDistance = minSquaredDistance;
- minSquaredDistance = geometry.closestPointXY(
- x, y, closestPoint, minSquaredDistance);
- if (minSquaredDistance < previousMinSquaredDistance) {
- closestFeature = feature;
- // This is sneaky. Reduce the extent that it is currently being
- // searched while the R-Tree traversal using this same extent object
- // is still in progress. This is safe because the new extent is
- // strictly contained by the old extent.
- var minDistance = Math.sqrt(minSquaredDistance);
- extent[0] = x - minDistance;
- extent[1] = y - minDistance;
- extent[2] = x + minDistance;
- extent[3] = y + minDistance;
- }
- }
- });
- return closestFeature;
- };
- /**
- * Get the extent of the features currently in the source.
- *
- * This method is not available when the source is configured with
- * `useSpatialIndex` set to `false`.
- * @param {ol.Extent=} opt_extent Destination extent. If provided, no new extent
- * will be created. Instead, that extent's coordinates will be overwritten.
- * @return {ol.Extent} Extent.
- * @api
- */
- ol.source.Vector.prototype.getExtent = function(opt_extent) {
- return this.featuresRtree_.getExtent(opt_extent);
- };
- /**
- * Get a feature by its identifier (the value returned by feature.getId()).
- * Note that the index treats string and numeric identifiers as the same. So
- * `source.getFeatureById(2)` will return a feature with id `'2'` or `2`.
- *
- * @param {string|number} id Feature identifier.
- * @return {ol.Feature} The feature (or `null` if not found).
- * @api
- */
- ol.source.Vector.prototype.getFeatureById = function(id) {
- var feature = this.idIndex_[id.toString()];
- return feature !== undefined ? feature : null;
- };
- /**
- * Get the format associated with this source.
- *
- * @return {ol.format.Feature|undefined} The feature format.
- * @api
- */
- ol.source.Vector.prototype.getFormat = function() {
- return this.format_;
- };
- /**
- * @return {boolean} The source can have overlapping geometries.
- */
- ol.source.Vector.prototype.getOverlaps = function() {
- return this.overlaps_;
- };
- /**
- * @override
- */
- ol.source.Vector.prototype.getResolutions = function() {};
- /**
- * Get the url associated with this source.
- *
- * @return {string|ol.FeatureUrlFunction|undefined} The url.
- * @api
- */
- ol.source.Vector.prototype.getUrl = function() {
- return this.url_;
- };
- /**
- * @param {ol.events.Event} event Event.
- * @private
- */
- ol.source.Vector.prototype.handleFeatureChange_ = function(event) {
- var feature = /** @type {ol.Feature} */ (event.target);
- var featureKey = ol.getUid(feature).toString();
- var geometry = feature.getGeometry();
- if (!geometry) {
- if (!(featureKey in this.nullGeometryFeatures_)) {
- if (this.featuresRtree_) {
- this.featuresRtree_.remove(feature);
- }
- this.nullGeometryFeatures_[featureKey] = feature;
- }
- } else {
- var extent = geometry.getExtent();
- if (featureKey in this.nullGeometryFeatures_) {
- delete this.nullGeometryFeatures_[featureKey];
- if (this.featuresRtree_) {
- this.featuresRtree_.insert(extent, feature);
- }
- } else {
- if (this.featuresRtree_) {
- this.featuresRtree_.update(extent, feature);
- }
- }
- }
- var id = feature.getId();
- if (id !== undefined) {
- var sid = id.toString();
- if (featureKey in this.undefIdIndex_) {
- delete this.undefIdIndex_[featureKey];
- this.idIndex_[sid] = feature;
- } else {
- if (this.idIndex_[sid] !== feature) {
- this.removeFromIdIndex_(feature);
- this.idIndex_[sid] = feature;
- }
- }
- } else {
- if (!(featureKey in this.undefIdIndex_)) {
- this.removeFromIdIndex_(feature);
- this.undefIdIndex_[featureKey] = feature;
- }
- }
- this.changed();
- this.dispatchEvent(new ol.source.Vector.Event(
- ol.source.VectorEventType.CHANGEFEATURE, feature));
- };
- /**
- * @return {boolean} Is empty.
- */
- ol.source.Vector.prototype.isEmpty = function() {
- return this.featuresRtree_.isEmpty() &&
- ol.obj.isEmpty(this.nullGeometryFeatures_);
- };
- /**
- * @param {ol.Extent} extent Extent.
- * @param {number} resolution Resolution.
- * @param {ol.proj.Projection} projection Projection.
- */
- ol.source.Vector.prototype.loadFeatures = function(
- extent, resolution, projection) {
- var loadedExtentsRtree = this.loadedExtentsRtree_;
- var extentsToLoad = this.strategy_(extent, resolution);
- var i, ii;
- for (i = 0, ii = extentsToLoad.length; i < ii; ++i) {
- var extentToLoad = extentsToLoad[i];
- var alreadyLoaded = loadedExtentsRtree.forEachInExtent(extentToLoad,
- /**
- * @param {{extent: ol.Extent}} object Object.
- * @return {boolean} Contains.
- */
- function(object) {
- return ol.extent.containsExtent(object.extent, extentToLoad);
- });
- if (!alreadyLoaded) {
- this.loader_.call(this, extentToLoad, resolution, projection);
- loadedExtentsRtree.insert(extentToLoad, {extent: extentToLoad.slice()});
- }
- }
- };
- /**
- * Remove an extent from the list of loaded extents.
- * @param {ol.Extent} extent Extent.
- * @api
- */
- ol.source.Vector.prototype.removeLoadedExtent = function(extent) {
- var loadedExtentsRtree = this.loadedExtentsRtree_;
- var obj;
- loadedExtentsRtree.forEachInExtent(extent, function(object) {
- if (ol.extent.equals(object.extent, extent)) {
- obj = object;
- return true;
- }
- });
- if (obj) {
- loadedExtentsRtree.remove(obj);
- }
- };
- /**
- * Remove a single feature from the source. If you want to remove all features
- * at once, use the {@link ol.source.Vector#clear source.clear()} method
- * instead.
- * @param {ol.Feature} feature Feature to remove.
- * @api
- */
- ol.source.Vector.prototype.removeFeature = function(feature) {
- var featureKey = ol.getUid(feature).toString();
- if (featureKey in this.nullGeometryFeatures_) {
- delete this.nullGeometryFeatures_[featureKey];
- } else {
- if (this.featuresRtree_) {
- this.featuresRtree_.remove(feature);
- }
- }
- this.removeFeatureInternal(feature);
- this.changed();
- };
- /**
- * Remove feature without firing a `change` event.
- * @param {ol.Feature} feature Feature.
- * @protected
- */
- ol.source.Vector.prototype.removeFeatureInternal = function(feature) {
- var featureKey = ol.getUid(feature).toString();
- this.featureChangeKeys_[featureKey].forEach(ol.events.unlistenByKey);
- delete this.featureChangeKeys_[featureKey];
- var id = feature.getId();
- if (id !== undefined) {
- delete this.idIndex_[id.toString()];
- } else {
- delete this.undefIdIndex_[featureKey];
- }
- this.dispatchEvent(new ol.source.Vector.Event(
- ol.source.VectorEventType.REMOVEFEATURE, feature));
- };
- /**
- * Remove a feature from the id index. Called internally when the feature id
- * may have changed.
- * @param {ol.Feature} feature The feature.
- * @return {boolean} Removed the feature from the index.
- * @private
- */
- ol.source.Vector.prototype.removeFromIdIndex_ = function(feature) {
- var removed = false;
- for (var id in this.idIndex_) {
- if (this.idIndex_[id] === feature) {
- delete this.idIndex_[id];
- removed = true;
- break;
- }
- }
- return removed;
- };
- /**
- * Set the new loader of the source. The next loadFeatures call will use the
- * new loader.
- * @param {ol.FeatureLoader} loader The loader to set.
- * @api
- */
- ol.source.Vector.prototype.setLoader = function(loader) {
- this.loader_ = loader;
- };
- /**
- * @classdesc
- * Events emitted by {@link ol.source.Vector} instances are instances of this
- * type.
- *
- * @constructor
- * @extends {ol.events.Event}
- * @implements {oli.source.Vector.Event}
- * @param {string} type Type.
- * @param {ol.Feature=} opt_feature Feature.
- */
- ol.source.Vector.Event = function(type, opt_feature) {
- ol.events.Event.call(this, type);
- /**
- * The feature being added or removed.
- * @type {ol.Feature|undefined}
- * @api
- */
- this.feature = opt_feature;
- };
- ol.inherits(ol.source.Vector.Event, ol.events.Event);
- goog.provide('ol.interaction.Draw');
- goog.require('ol');
- goog.require('ol.Feature');
- goog.require('ol.MapBrowserEventType');
- goog.require('ol.Object');
- goog.require('ol.coordinate');
- goog.require('ol.events');
- goog.require('ol.events.Event');
- goog.require('ol.events.condition');
- goog.require('ol.extent');
- goog.require('ol.functions');
- goog.require('ol.geom.Circle');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.LineString');
- goog.require('ol.geom.MultiLineString');
- goog.require('ol.geom.MultiPoint');
- goog.require('ol.geom.MultiPolygon');
- goog.require('ol.geom.Point');
- goog.require('ol.geom.Polygon');
- goog.require('ol.interaction.DrawEventType');
- goog.require('ol.interaction.Pointer');
- goog.require('ol.interaction.Property');
- goog.require('ol.layer.Vector');
- goog.require('ol.source.Vector');
- goog.require('ol.style.Style');
- /**
- * @classdesc
- * Interaction for drawing feature geometries.
- *
- * @constructor
- * @extends {ol.interaction.Pointer}
- * @fires ol.interaction.Draw.Event
- * @param {olx.interaction.DrawOptions} options Options.
- * @api
- */
- ol.interaction.Draw = function(options) {
- ol.interaction.Pointer.call(this, {
- handleDownEvent: ol.interaction.Draw.handleDownEvent_,
- handleEvent: ol.interaction.Draw.handleEvent,
- handleUpEvent: ol.interaction.Draw.handleUpEvent_
- });
- /**
- * @type {boolean}
- * @private
- */
- this.shouldHandle_ = false;
- /**
- * @type {ol.Pixel}
- * @private
- */
- this.downPx_ = null;
- /**
- * @type {boolean}
- * @private
- */
- this.freehand_ = false;
- /**
- * Target source for drawn features.
- * @type {ol.source.Vector}
- * @private
- */
- this.source_ = options.source ? options.source : null;
- /**
- * Target collection for drawn features.
- * @type {ol.Collection.<ol.Feature>}
- * @private
- */
- this.features_ = options.features ? options.features : null;
- /**
- * Pixel distance for snapping.
- * @type {number}
- * @private
- */
- this.snapTolerance_ = options.snapTolerance ? options.snapTolerance : 12;
- /**
- * Geometry type.
- * @type {ol.geom.GeometryType}
- * @private
- */
- this.type_ = /** @type {ol.geom.GeometryType} */ (options.type);
- /**
- * Drawing mode (derived from geometry type.
- * @type {ol.interaction.Draw.Mode_}
- * @private
- */
- this.mode_ = ol.interaction.Draw.getMode_(this.type_);
- /**
- * Stop click, singleclick, and doubleclick events from firing during drawing.
- * Default is `false`.
- * @type {boolean}
- * @private
- */
- this.stopClick_ = !!options.stopClick;
- /**
- * The number of points that must be drawn before a polygon ring or line
- * string can be finished. The default is 3 for polygon rings and 2 for
- * line strings.
- * @type {number}
- * @private
- */
- this.minPoints_ = options.minPoints ?
- options.minPoints :
- (this.mode_ === ol.interaction.Draw.Mode_.POLYGON ? 3 : 2);
- /**
- * The number of points that can be drawn before a polygon ring or line string
- * is finished. The default is no restriction.
- * @type {number}
- * @private
- */
- this.maxPoints_ = options.maxPoints ? options.maxPoints : Infinity;
- /**
- * A function to decide if a potential finish coordinate is permissible
- * @private
- * @type {ol.EventsConditionType}
- */
- this.finishCondition_ = options.finishCondition ? options.finishCondition : ol.functions.TRUE;
- var geometryFunction = options.geometryFunction;
- if (!geometryFunction) {
- if (this.type_ === ol.geom.GeometryType.CIRCLE) {
- /**
- * @param {!Array.<ol.Coordinate>} coordinates
- * The coordinates.
- * @param {ol.geom.SimpleGeometry=} opt_geometry Optional geometry.
- * @return {ol.geom.SimpleGeometry} A geometry.
- */
- geometryFunction = function(coordinates, opt_geometry) {
- var circle = opt_geometry ? /** @type {ol.geom.Circle} */ (opt_geometry) :
- new ol.geom.Circle([NaN, NaN]);
- var squaredLength = ol.coordinate.squaredDistance(
- coordinates[0], coordinates[1]);
- circle.setCenterAndRadius(coordinates[0], Math.sqrt(squaredLength));
- return circle;
- };
- } else {
- var Constructor;
- var mode = this.mode_;
- if (mode === ol.interaction.Draw.Mode_.POINT) {
- Constructor = ol.geom.Point;
- } else if (mode === ol.interaction.Draw.Mode_.LINE_STRING) {
- Constructor = ol.geom.LineString;
- } else if (mode === ol.interaction.Draw.Mode_.POLYGON) {
- Constructor = ol.geom.Polygon;
- }
- /**
- * @param {!Array.<ol.Coordinate>} coordinates
- * The coordinates.
- * @param {ol.geom.SimpleGeometry=} opt_geometry Optional geometry.
- * @return {ol.geom.SimpleGeometry} A geometry.
- */
- geometryFunction = function(coordinates, opt_geometry) {
- var geometry = opt_geometry;
- if (geometry) {
- if (mode === ol.interaction.Draw.Mode_.POLYGON) {
- if (coordinates[0].length) {
- // Add a closing coordinate to match the first
- geometry.setCoordinates([coordinates[0].concat([coordinates[0][0]])]);
- } else {
- geometry.setCoordinates([]);
- }
- } else {
- geometry.setCoordinates(coordinates);
- }
- } else {
- geometry = new Constructor(coordinates);
- }
- return geometry;
- };
- }
- }
- /**
- * @type {ol.DrawGeometryFunctionType}
- * @private
- */
- this.geometryFunction_ = geometryFunction;
- /**
- * Finish coordinate for the feature (first point for polygons, last point for
- * linestrings).
- * @type {ol.Coordinate}
- * @private
- */
- this.finishCoordinate_ = null;
- /**
- * Sketch feature.
- * @type {ol.Feature}
- * @private
- */
- this.sketchFeature_ = null;
- /**
- * Sketch point.
- * @type {ol.Feature}
- * @private
- */
- this.sketchPoint_ = null;
- /**
- * Sketch coordinates. Used when drawing a line or polygon.
- * @type {ol.Coordinate|Array.<ol.Coordinate>|Array.<Array.<ol.Coordinate>>}
- * @private
- */
- this.sketchCoords_ = null;
- /**
- * Sketch line. Used when drawing polygon.
- * @type {ol.Feature}
- * @private
- */
- this.sketchLine_ = null;
- /**
- * Sketch line coordinates. Used when drawing a polygon or circle.
- * @type {Array.<ol.Coordinate>}
- * @private
- */
- this.sketchLineCoords_ = null;
- /**
- * Squared tolerance for handling up events. If the squared distance
- * between a down and up event is greater than this tolerance, up events
- * will not be handled.
- * @type {number}
- * @private
- */
- this.squaredClickTolerance_ = options.clickTolerance ?
- options.clickTolerance * options.clickTolerance : 36;
- /**
- * Draw overlay where our sketch features are drawn.
- * @type {ol.layer.Vector}
- * @private
- */
- this.overlay_ = new ol.layer.Vector({
- source: new ol.source.Vector({
- useSpatialIndex: false,
- wrapX: options.wrapX ? options.wrapX : false
- }),
- style: options.style ? options.style :
- ol.interaction.Draw.getDefaultStyleFunction()
- });
- /**
- * Name of the geometry attribute for newly created features.
- * @type {string|undefined}
- * @private
- */
- this.geometryName_ = options.geometryName;
- /**
- * @private
- * @type {ol.EventsConditionType}
- */
- this.condition_ = options.condition ?
- options.condition : ol.events.condition.noModifierKeys;
- /**
- * @private
- * @type {ol.EventsConditionType}
- */
- this.freehandCondition_;
- if (options.freehand) {
- this.freehandCondition_ = ol.events.condition.always;
- } else {
- this.freehandCondition_ = options.freehandCondition ?
- options.freehandCondition : ol.events.condition.shiftKeyOnly;
- }
- ol.events.listen(this,
- ol.Object.getChangeEventType(ol.interaction.Property.ACTIVE),
- this.updateState_, this);
- };
- ol.inherits(ol.interaction.Draw, ol.interaction.Pointer);
- /**
- * @return {ol.StyleFunction} Styles.
- */
- ol.interaction.Draw.getDefaultStyleFunction = function() {
- var styles = ol.style.Style.createDefaultEditing();
- return function(feature, resolution) {
- return styles[feature.getGeometry().getType()];
- };
- };
- /**
- * @inheritDoc
- */
- ol.interaction.Draw.prototype.setMap = function(map) {
- ol.interaction.Pointer.prototype.setMap.call(this, map);
- this.updateState_();
- };
- /**
- * Handles the {@link ol.MapBrowserEvent map browser event} and may actually
- * draw or finish the drawing.
- * @param {ol.MapBrowserEvent} event Map browser event.
- * @return {boolean} `false` to stop event propagation.
- * @this {ol.interaction.Draw}
- * @api
- */
- ol.interaction.Draw.handleEvent = function(event) {
- this.freehand_ = this.mode_ !== ol.interaction.Draw.Mode_.POINT && this.freehandCondition_(event);
- var pass = true;
- if (this.freehand_ &&
- event.type === ol.MapBrowserEventType.POINTERDRAG &&
- this.sketchFeature_ !== null) {
- this.addToDrawing_(event);
- pass = false;
- } else if (this.freehand_ &&
- event.type === ol.MapBrowserEventType.POINTERDOWN) {
- pass = false;
- } else if (event.type === ol.MapBrowserEventType.POINTERMOVE) {
- pass = this.handlePointerMove_(event);
- } else if (event.type === ol.MapBrowserEventType.DBLCLICK) {
- pass = false;
- }
- return ol.interaction.Pointer.handleEvent.call(this, event) && pass;
- };
- /**
- * @param {ol.MapBrowserPointerEvent} event Event.
- * @return {boolean} Start drag sequence?
- * @this {ol.interaction.Draw}
- * @private
- */
- ol.interaction.Draw.handleDownEvent_ = function(event) {
- this.shouldHandle_ = !this.freehand_;
- if (this.freehand_) {
- this.downPx_ = event.pixel;
- if (!this.finishCoordinate_) {
- this.startDrawing_(event);
- }
- return true;
- } else if (this.condition_(event)) {
- this.downPx_ = event.pixel;
- return true;
- } else {
- return false;
- }
- };
- /**
- * @param {ol.MapBrowserPointerEvent} event Event.
- * @return {boolean} Stop drag sequence?
- * @this {ol.interaction.Draw}
- * @private
- */
- ol.interaction.Draw.handleUpEvent_ = function(event) {
- var pass = true;
- this.handlePointerMove_(event);
- var circleMode = this.mode_ === ol.interaction.Draw.Mode_.CIRCLE;
- if (this.shouldHandle_) {
- if (!this.finishCoordinate_) {
- this.startDrawing_(event);
- if (this.mode_ === ol.interaction.Draw.Mode_.POINT) {
- this.finishDrawing();
- }
- } else if (this.freehand_ || circleMode) {
- this.finishDrawing();
- } else if (this.atFinish_(event)) {
- if (this.finishCondition_(event)) {
- this.finishDrawing();
- }
- } else {
- this.addToDrawing_(event);
- }
- pass = false;
- } else if (this.freehand_) {
- this.finishCoordinate_ = null;
- this.abortDrawing_();
- }
- if (!pass && this.stopClick_) {
- event.stopPropagation();
- }
- return pass;
- };
- /**
- * Handle move events.
- * @param {ol.MapBrowserEvent} event A move event.
- * @return {boolean} Pass the event to other interactions.
- * @private
- */
- ol.interaction.Draw.prototype.handlePointerMove_ = function(event) {
- if (this.downPx_ &&
- ((!this.freehand_ && this.shouldHandle_) ||
- (this.freehand_ && !this.shouldHandle_))) {
- var downPx = this.downPx_;
- var clickPx = event.pixel;
- var dx = downPx[0] - clickPx[0];
- var dy = downPx[1] - clickPx[1];
- var squaredDistance = dx * dx + dy * dy;
- this.shouldHandle_ = this.freehand_ ?
- squaredDistance > this.squaredClickTolerance_ :
- squaredDistance <= this.squaredClickTolerance_;
- }
- if (this.finishCoordinate_) {
- this.modifyDrawing_(event);
- } else {
- this.createOrUpdateSketchPoint_(event);
- }
- return true;
- };
- /**
- * Determine if an event is within the snapping tolerance of the start coord.
- * @param {ol.MapBrowserEvent} event Event.
- * @return {boolean} The event is within the snapping tolerance of the start.
- * @private
- */
- ol.interaction.Draw.prototype.atFinish_ = function(event) {
- var at = false;
- if (this.sketchFeature_) {
- var potentiallyDone = false;
- var potentiallyFinishCoordinates = [this.finishCoordinate_];
- if (this.mode_ === ol.interaction.Draw.Mode_.LINE_STRING) {
- potentiallyDone = this.sketchCoords_.length > this.minPoints_;
- } else if (this.mode_ === ol.interaction.Draw.Mode_.POLYGON) {
- potentiallyDone = this.sketchCoords_[0].length >
- this.minPoints_;
- potentiallyFinishCoordinates = [this.sketchCoords_[0][0],
- this.sketchCoords_[0][this.sketchCoords_[0].length - 2]];
- }
- if (potentiallyDone) {
- var map = event.map;
- for (var i = 0, ii = potentiallyFinishCoordinates.length; i < ii; i++) {
- var finishCoordinate = potentiallyFinishCoordinates[i];
- var finishPixel = map.getPixelFromCoordinate(finishCoordinate);
- var pixel = event.pixel;
- var dx = pixel[0] - finishPixel[0];
- var dy = pixel[1] - finishPixel[1];
- var snapTolerance = this.freehand_ ? 1 : this.snapTolerance_;
- at = Math.sqrt(dx * dx + dy * dy) <= snapTolerance;
- if (at) {
- this.finishCoordinate_ = finishCoordinate;
- break;
- }
- }
- }
- }
- return at;
- };
- /**
- * @param {ol.MapBrowserEvent} event Event.
- * @private
- */
- ol.interaction.Draw.prototype.createOrUpdateSketchPoint_ = function(event) {
- var coordinates = event.coordinate.slice();
- if (!this.sketchPoint_) {
- this.sketchPoint_ = new ol.Feature(new ol.geom.Point(coordinates));
- this.updateSketchFeatures_();
- } else {
- var sketchPointGeom = /** @type {ol.geom.Point} */ (this.sketchPoint_.getGeometry());
- sketchPointGeom.setCoordinates(coordinates);
- }
- };
- /**
- * Start the drawing.
- * @param {ol.MapBrowserEvent} event Event.
- * @private
- */
- ol.interaction.Draw.prototype.startDrawing_ = function(event) {
- var start = event.coordinate;
- this.finishCoordinate_ = start;
- if (this.mode_ === ol.interaction.Draw.Mode_.POINT) {
- this.sketchCoords_ = start.slice();
- } else if (this.mode_ === ol.interaction.Draw.Mode_.POLYGON) {
- this.sketchCoords_ = [[start.slice(), start.slice()]];
- this.sketchLineCoords_ = this.sketchCoords_[0];
- } else {
- this.sketchCoords_ = [start.slice(), start.slice()];
- if (this.mode_ === ol.interaction.Draw.Mode_.CIRCLE) {
- this.sketchLineCoords_ = this.sketchCoords_;
- }
- }
- if (this.sketchLineCoords_) {
- this.sketchLine_ = new ol.Feature(
- new ol.geom.LineString(this.sketchLineCoords_));
- }
- var geometry = this.geometryFunction_(this.sketchCoords_);
- this.sketchFeature_ = new ol.Feature();
- if (this.geometryName_) {
- this.sketchFeature_.setGeometryName(this.geometryName_);
- }
- this.sketchFeature_.setGeometry(geometry);
- this.updateSketchFeatures_();
- this.dispatchEvent(new ol.interaction.Draw.Event(
- ol.interaction.DrawEventType.DRAWSTART, this.sketchFeature_));
- };
- /**
- * Modify the drawing.
- * @param {ol.MapBrowserEvent} event Event.
- * @private
- */
- ol.interaction.Draw.prototype.modifyDrawing_ = function(event) {
- var coordinate = event.coordinate;
- var geometry = /** @type {ol.geom.SimpleGeometry} */ (this.sketchFeature_.getGeometry());
- var coordinates, last;
- if (this.mode_ === ol.interaction.Draw.Mode_.POINT) {
- last = this.sketchCoords_;
- } else if (this.mode_ === ol.interaction.Draw.Mode_.POLYGON) {
- coordinates = this.sketchCoords_[0];
- last = coordinates[coordinates.length - 1];
- if (this.atFinish_(event)) {
- // snap to finish
- coordinate = this.finishCoordinate_.slice();
- }
- } else {
- coordinates = this.sketchCoords_;
- last = coordinates[coordinates.length - 1];
- }
- last[0] = coordinate[0];
- last[1] = coordinate[1];
- this.geometryFunction_(/** @type {!Array.<ol.Coordinate>} */ (this.sketchCoords_), geometry);
- if (this.sketchPoint_) {
- var sketchPointGeom = /** @type {ol.geom.Point} */ (this.sketchPoint_.getGeometry());
- sketchPointGeom.setCoordinates(coordinate);
- }
- var sketchLineGeom;
- if (geometry instanceof ol.geom.Polygon &&
- this.mode_ !== ol.interaction.Draw.Mode_.POLYGON) {
- if (!this.sketchLine_) {
- this.sketchLine_ = new ol.Feature(new ol.geom.LineString(null));
- }
- var ring = geometry.getLinearRing(0);
- sketchLineGeom = /** @type {ol.geom.LineString} */ (this.sketchLine_.getGeometry());
- sketchLineGeom.setFlatCoordinates(
- ring.getLayout(), ring.getFlatCoordinates());
- } else if (this.sketchLineCoords_) {
- sketchLineGeom = /** @type {ol.geom.LineString} */ (this.sketchLine_.getGeometry());
- sketchLineGeom.setCoordinates(this.sketchLineCoords_);
- }
- this.updateSketchFeatures_();
- };
- /**
- * Add a new coordinate to the drawing.
- * @param {ol.MapBrowserEvent} event Event.
- * @private
- */
- ol.interaction.Draw.prototype.addToDrawing_ = function(event) {
- var coordinate = event.coordinate;
- var geometry = /** @type {ol.geom.SimpleGeometry} */ (this.sketchFeature_.getGeometry());
- var done;
- var coordinates;
- if (this.mode_ === ol.interaction.Draw.Mode_.LINE_STRING) {
- this.finishCoordinate_ = coordinate.slice();
- coordinates = this.sketchCoords_;
- if (coordinates.length >= this.maxPoints_) {
- if (this.freehand_) {
- coordinates.pop();
- } else {
- done = true;
- }
- }
- coordinates.push(coordinate.slice());
- this.geometryFunction_(coordinates, geometry);
- } else if (this.mode_ === ol.interaction.Draw.Mode_.POLYGON) {
- coordinates = this.sketchCoords_[0];
- if (coordinates.length >= this.maxPoints_) {
- if (this.freehand_) {
- coordinates.pop();
- } else {
- done = true;
- }
- }
- coordinates.push(coordinate.slice());
- if (done) {
- this.finishCoordinate_ = coordinates[0];
- }
- this.geometryFunction_(this.sketchCoords_, geometry);
- }
- this.updateSketchFeatures_();
- if (done) {
- this.finishDrawing();
- }
- };
- /**
- * Remove last point of the feature currently being drawn.
- * @api
- */
- ol.interaction.Draw.prototype.removeLastPoint = function() {
- if (!this.sketchFeature_) {
- return;
- }
- var geometry = /** @type {ol.geom.SimpleGeometry} */ (this.sketchFeature_.getGeometry());
- var coordinates, sketchLineGeom;
- if (this.mode_ === ol.interaction.Draw.Mode_.LINE_STRING) {
- coordinates = this.sketchCoords_;
- coordinates.splice(-2, 1);
- this.geometryFunction_(coordinates, geometry);
- if (coordinates.length >= 2) {
- this.finishCoordinate_ = coordinates[coordinates.length - 2].slice();
- }
- } else if (this.mode_ === ol.interaction.Draw.Mode_.POLYGON) {
- coordinates = this.sketchCoords_[0];
- coordinates.splice(-2, 1);
- sketchLineGeom = /** @type {ol.geom.LineString} */ (this.sketchLine_.getGeometry());
- sketchLineGeom.setCoordinates(coordinates);
- this.geometryFunction_(this.sketchCoords_, geometry);
- }
- if (coordinates.length === 0) {
- this.finishCoordinate_ = null;
- }
- this.updateSketchFeatures_();
- };
- /**
- * Stop drawing and add the sketch feature to the target layer.
- * The {@link ol.interaction.DrawEventType.DRAWEND} event is dispatched before
- * inserting the feature.
- * @api
- */
- ol.interaction.Draw.prototype.finishDrawing = function() {
- var sketchFeature = this.abortDrawing_();
- var coordinates = this.sketchCoords_;
- var geometry = /** @type {ol.geom.SimpleGeometry} */ (sketchFeature.getGeometry());
- if (this.mode_ === ol.interaction.Draw.Mode_.LINE_STRING) {
- // remove the redundant last point
- coordinates.pop();
- this.geometryFunction_(coordinates, geometry);
- } else if (this.mode_ === ol.interaction.Draw.Mode_.POLYGON) {
- // remove the redundant last point in ring
- coordinates[0].pop();
- this.geometryFunction_(coordinates, geometry);
- coordinates = geometry.getCoordinates();
- }
- // cast multi-part geometries
- if (this.type_ === ol.geom.GeometryType.MULTI_POINT) {
- sketchFeature.setGeometry(new ol.geom.MultiPoint([coordinates]));
- } else if (this.type_ === ol.geom.GeometryType.MULTI_LINE_STRING) {
- sketchFeature.setGeometry(new ol.geom.MultiLineString([coordinates]));
- } else if (this.type_ === ol.geom.GeometryType.MULTI_POLYGON) {
- sketchFeature.setGeometry(new ol.geom.MultiPolygon([coordinates]));
- }
- // First dispatch event to allow full set up of feature
- this.dispatchEvent(new ol.interaction.Draw.Event(
- ol.interaction.DrawEventType.DRAWEND, sketchFeature));
- // Then insert feature
- if (this.features_) {
- this.features_.push(sketchFeature);
- }
- if (this.source_) {
- this.source_.addFeature(sketchFeature);
- }
- };
- /**
- * Stop drawing without adding the sketch feature to the target layer.
- * @return {ol.Feature} The sketch feature (or null if none).
- * @private
- */
- ol.interaction.Draw.prototype.abortDrawing_ = function() {
- this.finishCoordinate_ = null;
- var sketchFeature = this.sketchFeature_;
- if (sketchFeature) {
- this.sketchFeature_ = null;
- this.sketchPoint_ = null;
- this.sketchLine_ = null;
- this.overlay_.getSource().clear(true);
- }
- return sketchFeature;
- };
- /**
- * Extend an existing geometry by adding additional points. This only works
- * on features with `LineString` geometries, where the interaction will
- * extend lines by adding points to the end of the coordinates array.
- * @param {!ol.Feature} feature Feature to be extended.
- * @api
- */
- ol.interaction.Draw.prototype.extend = function(feature) {
- var geometry = feature.getGeometry();
- var lineString = /** @type {ol.geom.LineString} */ (geometry);
- this.sketchFeature_ = feature;
- this.sketchCoords_ = lineString.getCoordinates();
- var last = this.sketchCoords_[this.sketchCoords_.length - 1];
- this.finishCoordinate_ = last.slice();
- this.sketchCoords_.push(last.slice());
- this.updateSketchFeatures_();
- this.dispatchEvent(new ol.interaction.Draw.Event(
- ol.interaction.DrawEventType.DRAWSTART, this.sketchFeature_));
- };
- /**
- * @inheritDoc
- */
- ol.interaction.Draw.prototype.shouldStopEvent = ol.functions.FALSE;
- /**
- * Redraw the sketch features.
- * @private
- */
- ol.interaction.Draw.prototype.updateSketchFeatures_ = function() {
- var sketchFeatures = [];
- if (this.sketchFeature_) {
- sketchFeatures.push(this.sketchFeature_);
- }
- if (this.sketchLine_) {
- sketchFeatures.push(this.sketchLine_);
- }
- if (this.sketchPoint_) {
- sketchFeatures.push(this.sketchPoint_);
- }
- var overlaySource = this.overlay_.getSource();
- overlaySource.clear(true);
- overlaySource.addFeatures(sketchFeatures);
- };
- /**
- * @private
- */
- ol.interaction.Draw.prototype.updateState_ = function() {
- var map = this.getMap();
- var active = this.getActive();
- if (!map || !active) {
- this.abortDrawing_();
- }
- this.overlay_.setMap(active ? map : null);
- };
- /**
- * Create a `geometryFunction` for `type: 'Circle'` that will create a regular
- * polygon with a user specified number of sides and start angle instead of an
- * `ol.geom.Circle` geometry.
- * @param {number=} opt_sides Number of sides of the regular polygon. Default is
- * 32.
- * @param {number=} opt_angle Angle of the first point in radians. 0 means East.
- * Default is the angle defined by the heading from the center of the
- * regular polygon to the current pointer position.
- * @return {ol.DrawGeometryFunctionType} Function that draws a
- * polygon.
- * @api
- */
- ol.interaction.Draw.createRegularPolygon = function(opt_sides, opt_angle) {
- return (
- /**
- * @param {ol.Coordinate|Array.<ol.Coordinate>|Array.<Array.<ol.Coordinate>>} coordinates
- * @param {ol.geom.SimpleGeometry=} opt_geometry
- * @return {ol.geom.SimpleGeometry}
- */
- function(coordinates, opt_geometry) {
- var center = coordinates[0];
- var end = coordinates[1];
- var radius = Math.sqrt(
- ol.coordinate.squaredDistance(center, end));
- var geometry = opt_geometry ? /** @type {ol.geom.Polygon} */ (opt_geometry) :
- ol.geom.Polygon.fromCircle(new ol.geom.Circle(center), opt_sides);
- var angle = opt_angle ? opt_angle :
- Math.atan((end[1] - center[1]) / (end[0] - center[0]));
- ol.geom.Polygon.makeRegular(geometry, center, radius, angle);
- return geometry;
- }
- );
- };
- /**
- * Create a `geometryFunction` that will create a box-shaped polygon (aligned
- * with the coordinate system axes). Use this with the draw interaction and
- * `type: 'Circle'` to return a box instead of a circle geometry.
- * @return {ol.DrawGeometryFunctionType} Function that draws a box-shaped polygon.
- * @api
- */
- ol.interaction.Draw.createBox = function() {
- return (
- /**
- * @param {Array.<ol.Coordinate>} coordinates
- * @param {ol.geom.SimpleGeometry=} opt_geometry
- * @return {ol.geom.SimpleGeometry}
- */
- function(coordinates, opt_geometry) {
- var extent = ol.extent.boundingExtent(coordinates);
- var geometry = opt_geometry || new ol.geom.Polygon(null);
- geometry.setCoordinates([[
- ol.extent.getBottomLeft(extent),
- ol.extent.getBottomRight(extent),
- ol.extent.getTopRight(extent),
- ol.extent.getTopLeft(extent),
- ol.extent.getBottomLeft(extent)
- ]]);
- return geometry;
- }
- );
- };
- /**
- * Get the drawing mode. The mode for mult-part geometries is the same as for
- * their single-part cousins.
- * @param {ol.geom.GeometryType} type Geometry type.
- * @return {ol.interaction.Draw.Mode_} Drawing mode.
- * @private
- */
- ol.interaction.Draw.getMode_ = function(type) {
- var mode;
- if (type === ol.geom.GeometryType.POINT ||
- type === ol.geom.GeometryType.MULTI_POINT) {
- mode = ol.interaction.Draw.Mode_.POINT;
- } else if (type === ol.geom.GeometryType.LINE_STRING ||
- type === ol.geom.GeometryType.MULTI_LINE_STRING) {
- mode = ol.interaction.Draw.Mode_.LINE_STRING;
- } else if (type === ol.geom.GeometryType.POLYGON ||
- type === ol.geom.GeometryType.MULTI_POLYGON) {
- mode = ol.interaction.Draw.Mode_.POLYGON;
- } else if (type === ol.geom.GeometryType.CIRCLE) {
- mode = ol.interaction.Draw.Mode_.CIRCLE;
- }
- return /** @type {!ol.interaction.Draw.Mode_} */ (mode);
- };
- /**
- * Draw mode. This collapses multi-part geometry types with their single-part
- * cousins.
- * @enum {string}
- * @private
- */
- ol.interaction.Draw.Mode_ = {
- POINT: 'Point',
- LINE_STRING: 'LineString',
- POLYGON: 'Polygon',
- CIRCLE: 'Circle'
- };
- /**
- * @classdesc
- * Events emitted by {@link ol.interaction.Draw} instances are instances of
- * this type.
- *
- * @constructor
- * @extends {ol.events.Event}
- * @implements {oli.DrawEvent}
- * @param {ol.interaction.DrawEventType} type Type.
- * @param {ol.Feature} feature The feature drawn.
- */
- ol.interaction.Draw.Event = function(type, feature) {
- ol.events.Event.call(this, type);
- /**
- * The feature being drawn.
- * @type {ol.Feature}
- * @api
- */
- this.feature = feature;
- };
- ol.inherits(ol.interaction.Draw.Event, ol.events.Event);
- goog.provide('ol.interaction.ExtentEventType');
- /**
- * @enum {string}
- */
- ol.interaction.ExtentEventType = {
- /**
- * Triggered after the extent is changed
- * @event ol.interaction.Extent.Event#extentchanged
- * @api
- */
- EXTENTCHANGED: 'extentchanged'
- };
- goog.provide('ol.interaction.Extent');
- goog.require('ol');
- goog.require('ol.Feature');
- goog.require('ol.MapBrowserEventType');
- goog.require('ol.MapBrowserPointerEvent');
- goog.require('ol.coordinate');
- goog.require('ol.events.Event');
- goog.require('ol.extent');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.Point');
- goog.require('ol.geom.Polygon');
- goog.require('ol.interaction.ExtentEventType');
- goog.require('ol.interaction.Pointer');
- goog.require('ol.layer.Vector');
- goog.require('ol.source.Vector');
- goog.require('ol.style.Style');
- /**
- * @classdesc
- * Allows the user to draw a vector box by clicking and dragging on the map.
- * Once drawn, the vector box can be modified by dragging its vertices or edges.
- * This interaction is only supported for mouse devices.
- *
- * @constructor
- * @extends {ol.interaction.Pointer}
- * @fires ol.interaction.Extent.Event
- * @param {olx.interaction.ExtentOptions=} opt_options Options.
- * @api
- */
- ol.interaction.Extent = function(opt_options) {
- var options = opt_options || {};
- /**
- * Extent of the drawn box
- * @type {ol.Extent}
- * @private
- */
- this.extent_ = null;
- /**
- * Handler for pointer move events
- * @type {function (ol.Coordinate): ol.Extent|null}
- * @private
- */
- this.pointerHandler_ = null;
- /**
- * Pixel threshold to snap to extent
- * @type {number}
- * @private
- */
- this.pixelTolerance_ = options.pixelTolerance !== undefined ?
- options.pixelTolerance : 10;
- /**
- * Is the pointer snapped to an extent vertex
- * @type {boolean}
- * @private
- */
- this.snappedToVertex_ = false;
- /**
- * Feature for displaying the visible extent
- * @type {ol.Feature}
- * @private
- */
- this.extentFeature_ = null;
- /**
- * Feature for displaying the visible pointer
- * @type {ol.Feature}
- * @private
- */
- this.vertexFeature_ = null;
- if (!opt_options) {
- opt_options = {};
- }
- /* Inherit ol.interaction.Pointer */
- ol.interaction.Pointer.call(this, {
- handleDownEvent: ol.interaction.Extent.handleDownEvent_,
- handleDragEvent: ol.interaction.Extent.handleDragEvent_,
- handleEvent: ol.interaction.Extent.handleEvent_,
- handleUpEvent: ol.interaction.Extent.handleUpEvent_
- });
- /**
- * Layer for the extentFeature
- * @type {ol.layer.Vector}
- * @private
- */
- this.extentOverlay_ = new ol.layer.Vector({
- source: new ol.source.Vector({
- useSpatialIndex: false,
- wrapX: !!opt_options.wrapX
- }),
- style: opt_options.boxStyle ? opt_options.boxStyle : ol.interaction.Extent.getDefaultExtentStyleFunction_(),
- updateWhileAnimating: true,
- updateWhileInteracting: true
- });
- /**
- * Layer for the vertexFeature
- * @type {ol.layer.Vector}
- * @private
- */
- this.vertexOverlay_ = new ol.layer.Vector({
- source: new ol.source.Vector({
- useSpatialIndex: false,
- wrapX: !!opt_options.wrapX
- }),
- style: opt_options.pointerStyle ? opt_options.pointerStyle : ol.interaction.Extent.getDefaultPointerStyleFunction_(),
- updateWhileAnimating: true,
- updateWhileInteracting: true
- });
- if (opt_options.extent) {
- this.setExtent(opt_options.extent);
- }
- };
- ol.inherits(ol.interaction.Extent, ol.interaction.Pointer);
- /**
- * @param {ol.MapBrowserEvent} mapBrowserEvent Event.
- * @return {boolean} Propagate event?
- * @this {ol.interaction.Extent}
- * @private
- */
- ol.interaction.Extent.handleEvent_ = function(mapBrowserEvent) {
- if (!(mapBrowserEvent instanceof ol.MapBrowserPointerEvent)) {
- return true;
- }
- //display pointer (if not dragging)
- if (mapBrowserEvent.type == ol.MapBrowserEventType.POINTERMOVE && !this.handlingDownUpSequence) {
- this.handlePointerMove_(mapBrowserEvent);
- }
- //call pointer to determine up/down/drag
- ol.interaction.Pointer.handleEvent.call(this, mapBrowserEvent);
- //return false to stop propagation
- return false;
- };
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @return {boolean} Event handled?
- * @this {ol.interaction.Extent}
- * @private
- */
- ol.interaction.Extent.handleDownEvent_ = function(mapBrowserEvent) {
- var pixel = mapBrowserEvent.pixel;
- var map = mapBrowserEvent.map;
- var extent = this.getExtent();
- var vertex = this.snapToVertex_(pixel, map);
- //find the extent corner opposite the passed corner
- var getOpposingPoint = function(point) {
- var x_ = null;
- var y_ = null;
- if (point[0] == extent[0]) {
- x_ = extent[2];
- } else if (point[0] == extent[2]) {
- x_ = extent[0];
- }
- if (point[1] == extent[1]) {
- y_ = extent[3];
- } else if (point[1] == extent[3]) {
- y_ = extent[1];
- }
- if (x_ !== null && y_ !== null) {
- return [x_, y_];
- }
- return null;
- };
- if (vertex && extent) {
- var x = (vertex[0] == extent[0] || vertex[0] == extent[2]) ? vertex[0] : null;
- var y = (vertex[1] == extent[1] || vertex[1] == extent[3]) ? vertex[1] : null;
- //snap to point
- if (x !== null && y !== null) {
- this.pointerHandler_ = ol.interaction.Extent.getPointHandler_(getOpposingPoint(vertex));
- //snap to edge
- } else if (x !== null) {
- this.pointerHandler_ = ol.interaction.Extent.getEdgeHandler_(
- getOpposingPoint([x, extent[1]]),
- getOpposingPoint([x, extent[3]])
- );
- } else if (y !== null) {
- this.pointerHandler_ = ol.interaction.Extent.getEdgeHandler_(
- getOpposingPoint([extent[0], y]),
- getOpposingPoint([extent[2], y])
- );
- }
- //no snap - new bbox
- } else {
- vertex = map.getCoordinateFromPixel(pixel);
- this.setExtent([vertex[0], vertex[1], vertex[0], vertex[1]]);
- this.pointerHandler_ = ol.interaction.Extent.getPointHandler_(vertex);
- }
- return true; //event handled; start downup sequence
- };
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @return {boolean} Event handled?
- * @this {ol.interaction.Extent}
- * @private
- */
- ol.interaction.Extent.handleDragEvent_ = function(mapBrowserEvent) {
- if (this.pointerHandler_) {
- var pixelCoordinate = mapBrowserEvent.coordinate;
- this.setExtent(this.pointerHandler_(pixelCoordinate));
- this.createOrUpdatePointerFeature_(pixelCoordinate);
- }
- return true;
- };
- /**
- * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
- * @return {boolean} Stop drag sequence?
- * @this {ol.interaction.Extent}
- * @private
- */
- ol.interaction.Extent.handleUpEvent_ = function(mapBrowserEvent) {
- this.pointerHandler_ = null;
- //If bbox is zero area, set to null;
- var extent = this.getExtent();
- if (!extent || ol.extent.getArea(extent) === 0) {
- this.setExtent(null);
- }
- return false; //Stop handling downup sequence
- };
- /**
- * Returns the default style for the drawn bbox
- *
- * @return {ol.StyleFunction} Default Extent style
- * @private
- */
- ol.interaction.Extent.getDefaultExtentStyleFunction_ = function() {
- var style = ol.style.Style.createDefaultEditing();
- return function(feature, resolution) {
- return style[ol.geom.GeometryType.POLYGON];
- };
- };
- /**
- * Returns the default style for the pointer
- *
- * @return {ol.StyleFunction} Default pointer style
- * @private
- */
- ol.interaction.Extent.getDefaultPointerStyleFunction_ = function() {
- var style = ol.style.Style.createDefaultEditing();
- return function(feature, resolution) {
- return style[ol.geom.GeometryType.POINT];
- };
- };
- /**
- * @param {ol.Coordinate} fixedPoint corner that will be unchanged in the new extent
- * @returns {function (ol.Coordinate): ol.Extent} event handler
- * @private
- */
- ol.interaction.Extent.getPointHandler_ = function(fixedPoint) {
- return function(point) {
- return ol.extent.boundingExtent([fixedPoint, point]);
- };
- };
- /**
- * @param {ol.Coordinate} fixedP1 first corner that will be unchanged in the new extent
- * @param {ol.Coordinate} fixedP2 second corner that will be unchanged in the new extent
- * @returns {function (ol.Coordinate): ol.Extent|null} event handler
- * @private
- */
- ol.interaction.Extent.getEdgeHandler_ = function(fixedP1, fixedP2) {
- if (fixedP1[0] == fixedP2[0]) {
- return function(point) {
- return ol.extent.boundingExtent([fixedP1, [point[0], fixedP2[1]]]);
- };
- } else if (fixedP1[1] == fixedP2[1]) {
- return function(point) {
- return ol.extent.boundingExtent([fixedP1, [fixedP2[0], point[1]]]);
- };
- } else {
- return null;
- }
- };
- /**
- * @param {ol.Extent} extent extent
- * @returns {Array<Array<ol.Coordinate>>} extent line segments
- * @private
- */
- ol.interaction.Extent.getSegments_ = function(extent) {
- return [
- [[extent[0], extent[1]], [extent[0], extent[3]]],
- [[extent[0], extent[3]], [extent[2], extent[3]]],
- [[extent[2], extent[3]], [extent[2], extent[1]]],
- [[extent[2], extent[1]], [extent[0], extent[1]]]
- ];
- };
- /**
- * @param {ol.Pixel} pixel cursor location
- * @param {ol.PluggableMap} map map
- * @returns {ol.Coordinate|null} snapped vertex on extent
- * @private
- */
- ol.interaction.Extent.prototype.snapToVertex_ = function(pixel, map) {
- var pixelCoordinate = map.getCoordinateFromPixel(pixel);
- var sortByDistance = function(a, b) {
- return ol.coordinate.squaredDistanceToSegment(pixelCoordinate, a) -
- ol.coordinate.squaredDistanceToSegment(pixelCoordinate, b);
- };
- var extent = this.getExtent();
- if (extent) {
- //convert extents to line segments and find the segment closest to pixelCoordinate
- var segments = ol.interaction.Extent.getSegments_(extent);
- segments.sort(sortByDistance);
- var closestSegment = segments[0];
- var vertex = (ol.coordinate.closestOnSegment(pixelCoordinate,
- closestSegment));
- var vertexPixel = map.getPixelFromCoordinate(vertex);
- //if the distance is within tolerance, snap to the segment
- if (ol.coordinate.distance(pixel, vertexPixel) <= this.pixelTolerance_) {
- //test if we should further snap to a vertex
- var pixel1 = map.getPixelFromCoordinate(closestSegment[0]);
- var pixel2 = map.getPixelFromCoordinate(closestSegment[1]);
- var squaredDist1 = ol.coordinate.squaredDistance(vertexPixel, pixel1);
- var squaredDist2 = ol.coordinate.squaredDistance(vertexPixel, pixel2);
- var dist = Math.sqrt(Math.min(squaredDist1, squaredDist2));
- this.snappedToVertex_ = dist <= this.pixelTolerance_;
- if (this.snappedToVertex_) {
- vertex = squaredDist1 > squaredDist2 ?
- closestSegment[1] : closestSegment[0];
- }
- return vertex;
- }
- }
- return null;
- };
- /**
- * @param {ol.MapBrowserEvent} mapBrowserEvent pointer move event
- * @private
- */
- ol.interaction.Extent.prototype.handlePointerMove_ = function(mapBrowserEvent) {
- var pixel = mapBrowserEvent.pixel;
- var map = mapBrowserEvent.map;
- var vertex = this.snapToVertex_(pixel, map);
- if (!vertex) {
- vertex = map.getCoordinateFromPixel(pixel);
- }
- this.createOrUpdatePointerFeature_(vertex);
- };
- /**
- * @param {ol.Extent} extent extent
- * @returns {ol.Feature} extent as featrue
- * @private
- */
- ol.interaction.Extent.prototype.createOrUpdateExtentFeature_ = function(extent) {
- var extentFeature = this.extentFeature_;
- if (!extentFeature) {
- if (!extent) {
- extentFeature = new ol.Feature({});
- } else {
- extentFeature = new ol.Feature(ol.geom.Polygon.fromExtent(extent));
- }
- this.extentFeature_ = extentFeature;
- this.extentOverlay_.getSource().addFeature(extentFeature);
- } else {
- if (!extent) {
- extentFeature.setGeometry(undefined);
- } else {
- extentFeature.setGeometry(ol.geom.Polygon.fromExtent(extent));
- }
- }
- return extentFeature;
- };
- /**
- * @param {ol.Coordinate} vertex location of feature
- * @returns {ol.Feature} vertex as feature
- * @private
- */
- ol.interaction.Extent.prototype.createOrUpdatePointerFeature_ = function(vertex) {
- var vertexFeature = this.vertexFeature_;
- if (!vertexFeature) {
- vertexFeature = new ol.Feature(new ol.geom.Point(vertex));
- this.vertexFeature_ = vertexFeature;
- this.vertexOverlay_.getSource().addFeature(vertexFeature);
- } else {
- var geometry = /** @type {ol.geom.Point} */ (vertexFeature.getGeometry());
- geometry.setCoordinates(vertex);
- }
- return vertexFeature;
- };
- /**
- * @inheritDoc
- */
- ol.interaction.Extent.prototype.setMap = function(map) {
- this.extentOverlay_.setMap(map);
- this.vertexOverlay_.setMap(map);
- ol.interaction.Pointer.prototype.setMap.call(this, map);
- };
- /**
- * Returns the current drawn extent in the view projection
- *
- * @return {ol.Extent} Drawn extent in the view projection.
- * @api
- */
- ol.interaction.Extent.prototype.getExtent = function() {
- return this.extent_;
- };
- /**
- * Manually sets the drawn extent, using the view projection.
- *
- * @param {ol.Extent} extent Extent
- * @api
- */
- ol.interaction.Extent.prototype.setExtent = function(extent) {
- //Null extent means no bbox
- this.extent_ = extent ? extent : null;
- this.createOrUpdateExtentFeature_(extent);
- this.dispatchEvent(new ol.interaction.Extent.Event(this.extent_));
- };
- /**
- * @classdesc
- * Events emitted by {@link ol.interaction.Extent} instances are instances of
- * this type.
- *
- * @constructor
- * @implements {oli.ExtentEvent}
- * @param {ol.Extent} extent the new extent
- * @extends {ol.events.Event}
- */
- ol.interaction.Extent.Event = function(extent) {
- ol.events.Event.call(this, ol.interaction.ExtentEventType.EXTENTCHANGED);
- /**
- * The current extent.
- * @type {ol.Extent}
- * @api
- */
- this.extent = extent;
- };
- ol.inherits(ol.interaction.Extent.Event, ol.events.Event);
- goog.provide('ol.interaction.ModifyEventType');
- /**
- * @enum {string}
- */
- ol.interaction.ModifyEventType = {
- /**
- * Triggered upon feature modification start
- * @event ol.interaction.Modify.Event#modifystart
- * @api
- */
- MODIFYSTART: 'modifystart',
- /**
- * Triggered upon feature modification end
- * @event ol.interaction.Modify.Event#modifyend
- * @api
- */
- MODIFYEND: 'modifyend'
- };
- goog.provide('ol.interaction.Modify');
- goog.require('ol');
- goog.require('ol.Collection');
- goog.require('ol.CollectionEventType');
- goog.require('ol.Feature');
- goog.require('ol.MapBrowserEventType');
- goog.require('ol.MapBrowserPointerEvent');
- goog.require('ol.array');
- goog.require('ol.coordinate');
- goog.require('ol.events');
- goog.require('ol.events.Event');
- goog.require('ol.events.EventType');
- goog.require('ol.events.condition');
- goog.require('ol.extent');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.Point');
- goog.require('ol.interaction.ModifyEventType');
- goog.require('ol.interaction.Pointer');
- goog.require('ol.layer.Vector');
- goog.require('ol.source.Vector');
- goog.require('ol.source.VectorEventType');
- goog.require('ol.structs.RBush');
- goog.require('ol.style.Style');
- /**
- * @classdesc
- * Interaction for modifying feature geometries. To modify features that have
- * been added to an existing source, construct the modify interaction with the
- * `source` option. If you want to modify features in a collection (for example,
- * the collection used by a select interaction), construct the interaction with
- * the `features` option. The interaction must be constructed with either a
- * `source` or `features` option.
- *
- * By default, the interaction will allow deletion of vertices when the `alt`
- * key is pressed. To configure the interaction with a different condition
- * for deletion, use the `deleteCondition` option.
- *
- * @constructor
- * @extends {ol.interaction.Pointer}
- * @param {olx.interaction.ModifyOptions} options Options.
- * @fires ol.interaction.Modify.Event
- * @api
- */
- ol.interaction.Modify = function(options) {
- ol.interaction.Pointer.call(this, {
- handleDownEvent: ol.interaction.Modify.handleDownEvent_,
- handleDragEvent: ol.interaction.Modify.handleDragEvent_,
- handleEvent: ol.interaction.Modify.handleEvent,
- handleUpEvent: ol.interaction.Modify.handleUpEvent_
- });
- /**
- * @private
- * @type {ol.EventsConditionType}
- */
- this.condition_ = options.condition ?
- options.condition : ol.events.condition.primaryAction;
- /**
- * @private
- * @param {ol.MapBrowserEvent} mapBrowserEvent Browser event.
- * @return {boolean} Combined condition result.
- */
- this.defaultDeleteCondition_ = function(mapBrowserEvent) {
- return ol.events.condition.altKeyOnly(mapBrowserEvent) &&
- ol.events.condition.singleClick(mapBrowserEvent);
- };
- /**
- * @type {ol.EventsConditionType}
- * @private
- */
- this.deleteCondition_ = options.deleteCondition ?
- options.deleteCondition : this.defaultDeleteCondition_;
- /**
- * @type {ol.EventsConditionType}
- * @private
- */
- this.insertVertexCondition_ = options.insertVertexCondition ?
- options.insertVertexCondition : ol.events.condition.always;
- /**
- * Editing vertex.
- * @type {ol.Feature}
- * @private
- */
- this.vertexFeature_ = null;
- /**
- * Segments intersecting {@link this.vertexFeature_} by segment uid.
- * @type {Object.<string, boolean>}
- * @private
- */
- this.vertexSegments_ = null;
- /**
- * @type {ol.Pixel}
- * @private
- */
- this.lastPixel_ = [0, 0];
- /**
- * Tracks if the next `singleclick` event should be ignored to prevent
- * accidental deletion right after vertex creation.
- * @type {boolean}
- * @private
- */
- this.ignoreNextSingleClick_ = false;
- /**
- * @type {boolean}
- * @private
- */
- this.modified_ = false;
- /**
- * Segment RTree for each layer
- * @type {ol.structs.RBush.<ol.ModifySegmentDataType>}
- * @private
- */
- this.rBush_ = new ol.structs.RBush();
- /**
- * @type {number}
- * @private
- */
- this.pixelTolerance_ = options.pixelTolerance !== undefined ?
- options.pixelTolerance : 10;
- /**
- * @type {boolean}
- * @private
- */
- this.snappedToVertex_ = false;
- /**
- * Indicate whether the interaction is currently changing a feature's
- * coordinates.
- * @type {boolean}
- * @private
- */
- this.changingFeature_ = false;
- /**
- * @type {Array}
- * @private
- */
- this.dragSegments_ = [];
- /**
- * Draw overlay where sketch features are drawn.
- * @type {ol.layer.Vector}
- * @private
- */
- this.overlay_ = new ol.layer.Vector({
- source: new ol.source.Vector({
- useSpatialIndex: false,
- wrapX: !!options.wrapX
- }),
- style: options.style ? options.style :
- ol.interaction.Modify.getDefaultStyleFunction(),
- updateWhileAnimating: true,
- updateWhileInteracting: true
- });
- /**
- * @const
- * @private
- * @type {Object.<string, function(ol.Feature, ol.geom.Geometry)>}
- */
- this.SEGMENT_WRITERS_ = {
- 'Point': this.writePointGeometry_,
- 'LineString': this.writeLineStringGeometry_,
- 'LinearRing': this.writeLineStringGeometry_,
- 'Polygon': this.writePolygonGeometry_,
- 'MultiPoint': this.writeMultiPointGeometry_,
- 'MultiLineString': this.writeMultiLineStringGeometry_,
- 'MultiPolygon': this.writeMultiPolygonGeometry_,
- 'Circle': this.writeCircleGeometry_,
- 'GeometryCollection': this.writeGeometryCollectionGeometry_
- };
- /**
- * @type {ol.source.Vector}
- * @private
- */
- this.source_ = null;
- var features;
- if (options.source) {
- this.source_ = options.source;
- features = new ol.Collection(this.source_.getFeatures());
- ol.events.listen(this.source_, ol.source.VectorEventType.ADDFEATURE,
- this.handleSourceAdd_, this);
- ol.events.listen(this.source_, ol.source.VectorEventType.REMOVEFEATURE,
- this.handleSourceRemove_, this);
- } else {
- features = options.features;
- }
- if (!features) {
- throw new Error('The modify interaction requires features or a source');
- }
- /**
- * @type {ol.Collection.<ol.Feature>}
- * @private
- */
- this.features_ = features;
- this.features_.forEach(this.addFeature_, this);
- ol.events.listen(this.features_, ol.CollectionEventType.ADD,
- this.handleFeatureAdd_, this);
- ol.events.listen(this.features_, ol.CollectionEventType.REMOVE,
- this.handleFeatureRemove_, this);
- /**
- * @type {ol.MapBrowserPointerEvent}
- * @private
- */
- this.lastPointerEvent_ = null;
- };
- ol.inherits(ol.interaction.Modify, ol.interaction.Pointer);
- /**
- * @define {number} The segment index assigned to a circle's center when
- * breaking up a cicrle into ModifySegmentDataType segments.
- */
- ol.interaction.Modify.MODIFY_SEGMENT_CIRCLE_CENTER_INDEX = 0;
- /**
- * @define {number} The segment index assigned to a circle's circumference when
- * breaking up a circle into ModifySegmentDataType segments.
- */
- ol.interaction.Modify.MODIFY_SEGMENT_CIRCLE_CIRCUMFERENCE_INDEX = 1;
- /**
- * @param {ol.Feature} feature Feature.
- * @private
- */
- ol.interaction.Modify.prototype.addFeature_ = function(feature) {
- var geometry = feature.getGeometry();
- if (geometry && geometry.getType() in this.SEGMENT_WRITERS_) {
- this.SEGMENT_WRITERS_[geometry.getType()].call(this, feature, geometry);
- }
- var map = this.getMap();
- if (map && map.isRendered() && this.getActive()) {
- this.handlePointerAtPixel_(this.lastPixel_, map);
- }
- ol.events.listen(feature, ol.events.EventType.CHANGE,
- this.handleFeatureChange_, this);
- };
- /**
- * @param {ol.MapBrowserPointerEvent} evt Map browser event
- * @private
- */
- ol.interaction.Modify.prototype.willModifyFeatures_ = function(evt) {
- if (!this.modified_) {
- this.modified_ = true;
- this.dispatchEvent(new ol.interaction.Modify.Event(
- ol.interaction.ModifyEventType.MODIFYSTART, this.features_, evt));
- }
- };
- /**
- * @param {ol.Feature} feature Feature.
- * @private
- */
- ol.interaction.Modify.prototype.removeFeature_ = function(feature) {
- this.removeFeatureSegmentData_(feature);
- // Remove the vertex feature if the collection of canditate features
- // is empty.
- if (this.vertexFeature_ && this.features_.getLength() === 0) {
- this.overlay_.getSource().removeFeature(this.vertexFeature_);
- this.vertexFeature_ = null;
- }
- ol.events.unlisten(feature, ol.events.EventType.CHANGE,
- this.handleFeatureChange_, this);
- };
- /**
- * @param {ol.Feature} feature Feature.
- * @private
- */
- ol.interaction.Modify.prototype.removeFeatureSegmentData_ = function(feature) {
- var rBush = this.rBush_;
- var /** @type {Array.<ol.ModifySegmentDataType>} */ nodesToRemove = [];
- rBush.forEach(
- /**
- * @param {ol.ModifySegmentDataType} node RTree node.
- */
- function(node) {
- if (feature === node.feature) {
- nodesToRemove.push(node);
- }
- });
- for (var i = nodesToRemove.length - 1; i >= 0; --i) {
- rBush.remove(nodesToRemove[i]);
- }
- };
- /**
- * @inheritDoc
- */
- ol.interaction.Modify.prototype.setActive = function(active) {
- if (this.vertexFeature_ && !active) {
- this.overlay_.getSource().removeFeature(this.vertexFeature_);
- this.vertexFeature_ = null;
- }
- ol.interaction.Pointer.prototype.setActive.call(this, active);
- };
- /**
- * @inheritDoc
- */
- ol.interaction.Modify.prototype.setMap = function(map) {
- this.overlay_.setMap(map);
- ol.interaction.Pointer.prototype.setMap.call(this, map);
- };
- /**
- * @param {ol.source.Vector.Event} event Event.
- * @private
- */
- ol.interaction.Modify.prototype.handleSourceAdd_ = function(event) {
- if (event.feature) {
- this.features_.push(event.feature);
- }
- };
- /**
- * @param {ol.source.Vector.Event} event Event.
- * @private
- */
- ol.interaction.Modify.prototype.handleSourceRemove_ = function(event) {
- if (event.feature) {
- this.features_.remove(event.feature);
- }
- };
- /**
- * @param {ol.Collection.Event} evt Event.
- * @private
- */
- ol.interaction.Modify.prototype.handleFeatureAdd_ = function(evt) {
- this.addFeature_(/** @type {ol.Feature} */ (evt.element));
- };
- /**
- * @param {ol.events.Event} evt Event.
- * @private
- */
- ol.interaction.Modify.prototype.handleFeatureChange_ = function(evt) {
- if (!this.changingFeature_) {
- var feature = /** @type {ol.Feature} */ (evt.target);
- this.removeFeature_(feature);
- this.addFeature_(feature);
- }
- };
- /**
- * @param {ol.Collection.Event} evt Event.
- * @private
- */
- ol.interaction.Modify.prototype.handleFeatureRemove_ = function(evt) {
- var feature = /** @type {ol.Feature} */ (evt.element);
- this.removeFeature_(feature);
- };
- /**
- * @param {ol.Feature} feature Feature
- * @param {ol.geom.Point} geometry Geometry.
- * @private
- */
- ol.interaction.Modify.prototype.writePointGeometry_ = function(feature, geometry) {
- var coordinates = geometry.getCoordinates();
- var segmentData = /** @type {ol.ModifySegmentDataType} */ ({
- feature: feature,
- geometry: geometry,
- segment: [coordinates, coordinates]
- });
- this.rBush_.insert(geometry.getExtent(), segmentData);
- };
- /**
- * @param {ol.Feature} feature Feature
- * @param {ol.geom.MultiPoint} geometry Geometry.
- * @private
- */
- ol.interaction.Modify.prototype.writeMultiPointGeometry_ = function(feature, geometry) {
- var points = geometry.getCoordinates();
- var coordinates, i, ii, segmentData;
- for (i = 0, ii = points.length; i < ii; ++i) {
- coordinates = points[i];
- segmentData = /** @type {ol.ModifySegmentDataType} */ ({
- feature: feature,
- geometry: geometry,
- depth: [i],
- index: i,
- segment: [coordinates, coordinates]
- });
- this.rBush_.insert(geometry.getExtent(), segmentData);
- }
- };
- /**
- * @param {ol.Feature} feature Feature
- * @param {ol.geom.LineString} geometry Geometry.
- * @private
- */
- ol.interaction.Modify.prototype.writeLineStringGeometry_ = function(feature, geometry) {
- var coordinates = geometry.getCoordinates();
- var i, ii, segment, segmentData;
- for (i = 0, ii = coordinates.length - 1; i < ii; ++i) {
- segment = coordinates.slice(i, i + 2);
- segmentData = /** @type {ol.ModifySegmentDataType} */ ({
- feature: feature,
- geometry: geometry,
- index: i,
- segment: segment
- });
- this.rBush_.insert(ol.extent.boundingExtent(segment), segmentData);
- }
- };
- /**
- * @param {ol.Feature} feature Feature
- * @param {ol.geom.MultiLineString} geometry Geometry.
- * @private
- */
- ol.interaction.Modify.prototype.writeMultiLineStringGeometry_ = function(feature, geometry) {
- var lines = geometry.getCoordinates();
- var coordinates, i, ii, j, jj, segment, segmentData;
- for (j = 0, jj = lines.length; j < jj; ++j) {
- coordinates = lines[j];
- for (i = 0, ii = coordinates.length - 1; i < ii; ++i) {
- segment = coordinates.slice(i, i + 2);
- segmentData = /** @type {ol.ModifySegmentDataType} */ ({
- feature: feature,
- geometry: geometry,
- depth: [j],
- index: i,
- segment: segment
- });
- this.rBush_.insert(ol.extent.boundingExtent(segment), segmentData);
- }
- }
- };
- /**
- * @param {ol.Feature} feature Feature
- * @param {ol.geom.Polygon} geometry Geometry.
- * @private
- */
- ol.interaction.Modify.prototype.writePolygonGeometry_ = function(feature, geometry) {
- var rings = geometry.getCoordinates();
- var coordinates, i, ii, j, jj, segment, segmentData;
- for (j = 0, jj = rings.length; j < jj; ++j) {
- coordinates = rings[j];
- for (i = 0, ii = coordinates.length - 1; i < ii; ++i) {
- segment = coordinates.slice(i, i + 2);
- segmentData = /** @type {ol.ModifySegmentDataType} */ ({
- feature: feature,
- geometry: geometry,
- depth: [j],
- index: i,
- segment: segment
- });
- this.rBush_.insert(ol.extent.boundingExtent(segment), segmentData);
- }
- }
- };
- /**
- * @param {ol.Feature} feature Feature
- * @param {ol.geom.MultiPolygon} geometry Geometry.
- * @private
- */
- ol.interaction.Modify.prototype.writeMultiPolygonGeometry_ = function(feature, geometry) {
- var polygons = geometry.getCoordinates();
- var coordinates, i, ii, j, jj, k, kk, rings, segment, segmentData;
- for (k = 0, kk = polygons.length; k < kk; ++k) {
- rings = polygons[k];
- for (j = 0, jj = rings.length; j < jj; ++j) {
- coordinates = rings[j];
- for (i = 0, ii = coordinates.length - 1; i < ii; ++i) {
- segment = coordinates.slice(i, i + 2);
- segmentData = /** @type {ol.ModifySegmentDataType} */ ({
- feature: feature,
- geometry: geometry,
- depth: [j, k],
- index: i,
- segment: segment
- });
- this.rBush_.insert(ol.extent.boundingExtent(segment), segmentData);
- }
- }
- }
- };
- /**
- * We convert a circle into two segments. The segment at index
- * {@link ol.interaction.Modify.MODIFY_SEGMENT_CIRCLE_CENTER_INDEX} is the
- * circle's center (a point). The segment at index
- * {@link ol.interaction.Modify.MODIFY_SEGMENT_CIRCLE_CIRCUMFERENCE_INDEX} is
- * the circumference, and is not a line segment.
- *
- * @param {ol.Feature} feature Feature.
- * @param {ol.geom.Circle} geometry Geometry.
- * @private
- */
- ol.interaction.Modify.prototype.writeCircleGeometry_ = function(feature, geometry) {
- var coordinates = geometry.getCenter();
- var centerSegmentData = /** @type {ol.ModifySegmentDataType} */ ({
- feature: feature,
- geometry: geometry,
- index: ol.interaction.Modify.MODIFY_SEGMENT_CIRCLE_CENTER_INDEX,
- segment: [coordinates, coordinates]
- });
- var circumferenceSegmentData = /** @type {ol.ModifySegmentDataType} */ ({
- feature: feature,
- geometry: geometry,
- index: ol.interaction.Modify.MODIFY_SEGMENT_CIRCLE_CIRCUMFERENCE_INDEX,
- segment: [coordinates, coordinates]
- });
- var featureSegments = [centerSegmentData, circumferenceSegmentData];
- centerSegmentData.featureSegments = circumferenceSegmentData.featureSegments = featureSegments;
- this.rBush_.insert(ol.extent.createOrUpdateFromCoordinate(coordinates), centerSegmentData);
- this.rBush_.insert(geometry.getExtent(), circumferenceSegmentData);
- };
- /**
- * @param {ol.Feature} feature Feature
- * @param {ol.geom.GeometryCollection} geometry Geometry.
- * @private
- */
- ol.interaction.Modify.prototype.writeGeometryCollectionGeometry_ = function(feature, geometry) {
- var i, geometries = geometry.getGeometriesArray();
- for (i = 0; i < geometries.length; ++i) {
- this.SEGMENT_WRITERS_[geometries[i].getType()].call(
- this, feature, geometries[i]);
- }
- };
- /**
- * @param {ol.Coordinate} coordinates Coordinates.
- * @return {ol.Feature} Vertex feature.
- * @private
- */
- ol.interaction.Modify.prototype.createOrUpdateVertexFeature_ = function(coordinates) {
- var vertexFeature = this.vertexFeature_;
- if (!vertexFeature) {
- vertexFeature = new ol.Feature(new ol.geom.Point(coordinates));
- this.vertexFeature_ = vertexFeature;
- this.overlay_.getSource().addFeature(vertexFeature);
- } else {
- var geometry = /** @type {ol.geom.Point} */ (vertexFeature.getGeometry());
- geometry.setCoordinates(coordinates);
- }
- return vertexFeature;
- };
- /**
- * @param {ol.ModifySegmentDataType} a The first segment data.
- * @param {ol.ModifySegmentDataType} b The second segment data.
- * @return {number} The difference in indexes.
- * @private
- */
- ol.interaction.Modify.compareIndexes_ = function(a, b) {
- return a.index - b.index;
- };
- /**
- * @param {ol.MapBrowserPointerEvent} evt Event.
- * @return {boolean} Start drag sequence?
- * @this {ol.interaction.Modify}
- * @private
- */
- ol.interaction.Modify.handleDownEvent_ = function(evt) {
- if (!this.condition_(evt)) {
- return false;
- }
- this.handlePointerAtPixel_(evt.pixel, evt.map);
- var pixelCoordinate = evt.map.getCoordinateFromPixel(evt.pixel);
- this.dragSegments_.length = 0;
- this.modified_ = false;
- var vertexFeature = this.vertexFeature_;
- if (vertexFeature) {
- var insertVertices = [];
- var geometry = /** @type {ol.geom.Point} */ (vertexFeature.getGeometry());
- var vertex = geometry.getCoordinates();
- var vertexExtent = ol.extent.boundingExtent([vertex]);
- var segmentDataMatches = this.rBush_.getInExtent(vertexExtent);
- var componentSegments = {};
- segmentDataMatches.sort(ol.interaction.Modify.compareIndexes_);
- for (var i = 0, ii = segmentDataMatches.length; i < ii; ++i) {
- var segmentDataMatch = segmentDataMatches[i];
- var segment = segmentDataMatch.segment;
- var uid = ol.getUid(segmentDataMatch.feature);
- var depth = segmentDataMatch.depth;
- if (depth) {
- uid += '-' + depth.join('-'); // separate feature components
- }
- if (!componentSegments[uid]) {
- componentSegments[uid] = new Array(2);
- }
- if (segmentDataMatch.geometry.getType() === ol.geom.GeometryType.CIRCLE &&
- segmentDataMatch.index === ol.interaction.Modify.MODIFY_SEGMENT_CIRCLE_CIRCUMFERENCE_INDEX) {
- var closestVertex = ol.interaction.Modify.closestOnSegmentData_(pixelCoordinate, segmentDataMatch);
- if (ol.coordinate.equals(closestVertex, vertex) && !componentSegments[uid][0]) {
- this.dragSegments_.push([segmentDataMatch, 0]);
- componentSegments[uid][0] = segmentDataMatch;
- }
- } else if (ol.coordinate.equals(segment[0], vertex) &&
- !componentSegments[uid][0]) {
- this.dragSegments_.push([segmentDataMatch, 0]);
- componentSegments[uid][0] = segmentDataMatch;
- } else if (ol.coordinate.equals(segment[1], vertex) &&
- !componentSegments[uid][1]) {
- // prevent dragging closed linestrings by the connecting node
- if ((segmentDataMatch.geometry.getType() ===
- ol.geom.GeometryType.LINE_STRING ||
- segmentDataMatch.geometry.getType() ===
- ol.geom.GeometryType.MULTI_LINE_STRING) &&
- componentSegments[uid][0] &&
- componentSegments[uid][0].index === 0) {
- continue;
- }
- this.dragSegments_.push([segmentDataMatch, 1]);
- componentSegments[uid][1] = segmentDataMatch;
- } else if (this.insertVertexCondition_(evt) && ol.getUid(segment) in this.vertexSegments_ &&
- (!componentSegments[uid][0] && !componentSegments[uid][1])) {
- insertVertices.push([segmentDataMatch, vertex]);
- }
- }
- if (insertVertices.length) {
- this.willModifyFeatures_(evt);
- }
- for (var j = insertVertices.length - 1; j >= 0; --j) {
- this.insertVertex_.apply(this, insertVertices[j]);
- }
- }
- return !!this.vertexFeature_;
- };
- /**
- * @param {ol.MapBrowserPointerEvent} evt Event.
- * @this {ol.interaction.Modify}
- * @private
- */
- ol.interaction.Modify.handleDragEvent_ = function(evt) {
- this.ignoreNextSingleClick_ = false;
- this.willModifyFeatures_(evt);
- var vertex = evt.coordinate;
- for (var i = 0, ii = this.dragSegments_.length; i < ii; ++i) {
- var dragSegment = this.dragSegments_[i];
- var segmentData = dragSegment[0];
- var depth = segmentData.depth;
- var geometry = segmentData.geometry;
- var coordinates;
- var segment = segmentData.segment;
- var index = dragSegment[1];
- while (vertex.length < geometry.getStride()) {
- vertex.push(segment[index][vertex.length]);
- }
- switch (geometry.getType()) {
- case ol.geom.GeometryType.POINT:
- coordinates = vertex;
- segment[0] = segment[1] = vertex;
- break;
- case ol.geom.GeometryType.MULTI_POINT:
- coordinates = geometry.getCoordinates();
- coordinates[segmentData.index] = vertex;
- segment[0] = segment[1] = vertex;
- break;
- case ol.geom.GeometryType.LINE_STRING:
- coordinates = geometry.getCoordinates();
- coordinates[segmentData.index + index] = vertex;
- segment[index] = vertex;
- break;
- case ol.geom.GeometryType.MULTI_LINE_STRING:
- coordinates = geometry.getCoordinates();
- coordinates[depth[0]][segmentData.index + index] = vertex;
- segment[index] = vertex;
- break;
- case ol.geom.GeometryType.POLYGON:
- coordinates = geometry.getCoordinates();
- coordinates[depth[0]][segmentData.index + index] = vertex;
- segment[index] = vertex;
- break;
- case ol.geom.GeometryType.MULTI_POLYGON:
- coordinates = geometry.getCoordinates();
- coordinates[depth[1]][depth[0]][segmentData.index + index] = vertex;
- segment[index] = vertex;
- break;
- case ol.geom.GeometryType.CIRCLE:
- segment[0] = segment[1] = vertex;
- if (segmentData.index === ol.interaction.Modify.MODIFY_SEGMENT_CIRCLE_CENTER_INDEX) {
- this.changingFeature_ = true;
- geometry.setCenter(vertex);
- this.changingFeature_ = false;
- } else { // We're dragging the circle's circumference:
- this.changingFeature_ = true;
- geometry.setRadius(ol.coordinate.distance(geometry.getCenter(), vertex));
- this.changingFeature_ = false;
- }
- break;
- default:
- // pass
- }
- if (coordinates) {
- this.setGeometryCoordinates_(geometry, coordinates);
- }
- }
- this.createOrUpdateVertexFeature_(vertex);
- };
- /**
- * @param {ol.MapBrowserPointerEvent} evt Event.
- * @return {boolean} Stop drag sequence?
- * @this {ol.interaction.Modify}
- * @private
- */
- ol.interaction.Modify.handleUpEvent_ = function(evt) {
- var segmentData;
- var geometry;
- for (var i = this.dragSegments_.length - 1; i >= 0; --i) {
- segmentData = this.dragSegments_[i][0];
- geometry = segmentData.geometry;
- if (geometry.getType() === ol.geom.GeometryType.CIRCLE) {
- // Update a circle object in the R* bush:
- var coordinates = geometry.getCenter();
- var centerSegmentData = segmentData.featureSegments[0];
- var circumferenceSegmentData = segmentData.featureSegments[1];
- centerSegmentData.segment[0] = centerSegmentData.segment[1] = coordinates;
- circumferenceSegmentData.segment[0] = circumferenceSegmentData.segment[1] = coordinates;
- this.rBush_.update(ol.extent.createOrUpdateFromCoordinate(coordinates), centerSegmentData);
- this.rBush_.update(geometry.getExtent(), circumferenceSegmentData);
- } else {
- this.rBush_.update(ol.extent.boundingExtent(segmentData.segment),
- segmentData);
- }
- }
- if (this.modified_) {
- this.dispatchEvent(new ol.interaction.Modify.Event(
- ol.interaction.ModifyEventType.MODIFYEND, this.features_, evt));
- this.modified_ = false;
- }
- return false;
- };
- /**
- * Handles the {@link ol.MapBrowserEvent map browser event} and may modify the
- * geometry.
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} `false` to stop event propagation.
- * @this {ol.interaction.Modify}
- * @api
- */
- ol.interaction.Modify.handleEvent = function(mapBrowserEvent) {
- if (!(mapBrowserEvent instanceof ol.MapBrowserPointerEvent)) {
- return true;
- }
- this.lastPointerEvent_ = mapBrowserEvent;
- var handled;
- if (!mapBrowserEvent.map.getView().getInteracting() &&
- mapBrowserEvent.type == ol.MapBrowserEventType.POINTERMOVE &&
- !this.handlingDownUpSequence) {
- this.handlePointerMove_(mapBrowserEvent);
- }
- if (this.vertexFeature_ && this.deleteCondition_(mapBrowserEvent)) {
- if (mapBrowserEvent.type != ol.MapBrowserEventType.SINGLECLICK ||
- !this.ignoreNextSingleClick_) {
- handled = this.removePoint();
- } else {
- handled = true;
- }
- }
- if (mapBrowserEvent.type == ol.MapBrowserEventType.SINGLECLICK) {
- this.ignoreNextSingleClick_ = false;
- }
- return ol.interaction.Pointer.handleEvent.call(this, mapBrowserEvent) &&
- !handled;
- };
- /**
- * @param {ol.MapBrowserEvent} evt Event.
- * @private
- */
- ol.interaction.Modify.prototype.handlePointerMove_ = function(evt) {
- this.lastPixel_ = evt.pixel;
- this.handlePointerAtPixel_(evt.pixel, evt.map);
- };
- /**
- * @param {ol.Pixel} pixel Pixel
- * @param {ol.PluggableMap} map Map.
- * @private
- */
- ol.interaction.Modify.prototype.handlePointerAtPixel_ = function(pixel, map) {
- var pixelCoordinate = map.getCoordinateFromPixel(pixel);
- var sortByDistance = function(a, b) {
- return ol.interaction.Modify.pointDistanceToSegmentDataSquared_(pixelCoordinate, a) -
- ol.interaction.Modify.pointDistanceToSegmentDataSquared_(pixelCoordinate, b);
- };
- var box = ol.extent.buffer(
- ol.extent.createOrUpdateFromCoordinate(pixelCoordinate),
- map.getView().getResolution() * this.pixelTolerance_);
- var rBush = this.rBush_;
- var nodes = rBush.getInExtent(box);
- if (nodes.length > 0) {
- nodes.sort(sortByDistance);
- var node = nodes[0];
- var closestSegment = node.segment;
- var vertex = ol.interaction.Modify.closestOnSegmentData_(pixelCoordinate, node);
- var vertexPixel = map.getPixelFromCoordinate(vertex);
- var dist = ol.coordinate.distance(pixel, vertexPixel);
- if (dist <= this.pixelTolerance_) {
- var vertexSegments = {};
- if (node.geometry.getType() === ol.geom.GeometryType.CIRCLE &&
- node.index === ol.interaction.Modify.MODIFY_SEGMENT_CIRCLE_CIRCUMFERENCE_INDEX) {
- this.snappedToVertex_ = true;
- this.createOrUpdateVertexFeature_(vertex);
- } else {
- var pixel1 = map.getPixelFromCoordinate(closestSegment[0]);
- var pixel2 = map.getPixelFromCoordinate(closestSegment[1]);
- var squaredDist1 = ol.coordinate.squaredDistance(vertexPixel, pixel1);
- var squaredDist2 = ol.coordinate.squaredDistance(vertexPixel, pixel2);
- dist = Math.sqrt(Math.min(squaredDist1, squaredDist2));
- this.snappedToVertex_ = dist <= this.pixelTolerance_;
- if (this.snappedToVertex_) {
- vertex = squaredDist1 > squaredDist2 ?
- closestSegment[1] : closestSegment[0];
- }
- this.createOrUpdateVertexFeature_(vertex);
- var segment;
- for (var i = 1, ii = nodes.length; i < ii; ++i) {
- segment = nodes[i].segment;
- if ((ol.coordinate.equals(closestSegment[0], segment[0]) &&
- ol.coordinate.equals(closestSegment[1], segment[1]) ||
- (ol.coordinate.equals(closestSegment[0], segment[1]) &&
- ol.coordinate.equals(closestSegment[1], segment[0])))) {
- vertexSegments[ol.getUid(segment)] = true;
- } else {
- break;
- }
- }
- }
- vertexSegments[ol.getUid(closestSegment)] = true;
- this.vertexSegments_ = vertexSegments;
- return;
- }
- }
- if (this.vertexFeature_) {
- this.overlay_.getSource().removeFeature(this.vertexFeature_);
- this.vertexFeature_ = null;
- }
- };
- /**
- * Returns the distance from a point to a line segment.
- *
- * @param {ol.Coordinate} pointCoordinates The coordinates of the point from
- * which to calculate the distance.
- * @param {ol.ModifySegmentDataType} segmentData The object describing the line
- * segment we are calculating the distance to.
- * @return {number} The square of the distance between a point and a line segment.
- */
- ol.interaction.Modify.pointDistanceToSegmentDataSquared_ = function(pointCoordinates, segmentData) {
- var geometry = segmentData.geometry;
- if (geometry.getType() === ol.geom.GeometryType.CIRCLE) {
- var circleGeometry = /** @type {ol.geom.Circle} */ (geometry);
- if (segmentData.index === ol.interaction.Modify.MODIFY_SEGMENT_CIRCLE_CIRCUMFERENCE_INDEX) {
- var distanceToCenterSquared =
- ol.coordinate.squaredDistance(circleGeometry.getCenter(), pointCoordinates);
- var distanceToCircumference =
- Math.sqrt(distanceToCenterSquared) - circleGeometry.getRadius();
- return distanceToCircumference * distanceToCircumference;
- }
- }
- return ol.coordinate.squaredDistanceToSegment(pointCoordinates, segmentData.segment);
- };
- /**
- * Returns the point closest to a given line segment.
- *
- * @param {ol.Coordinate} pointCoordinates The point to which a closest point
- * should be found.
- * @param {ol.ModifySegmentDataType} segmentData The object describing the line
- * segment which should contain the closest point.
- * @return {ol.Coordinate} The point closest to the specified line segment.
- */
- ol.interaction.Modify.closestOnSegmentData_ = function(pointCoordinates, segmentData) {
- var geometry = segmentData.geometry;
- if (geometry.getType() === ol.geom.GeometryType.CIRCLE &&
- segmentData.index === ol.interaction.Modify.MODIFY_SEGMENT_CIRCLE_CIRCUMFERENCE_INDEX) {
- return geometry.getClosestPoint(pointCoordinates);
- }
- return ol.coordinate.closestOnSegment(pointCoordinates, segmentData.segment);
- };
- /**
- * @param {ol.ModifySegmentDataType} segmentData Segment data.
- * @param {ol.Coordinate} vertex Vertex.
- * @private
- */
- ol.interaction.Modify.prototype.insertVertex_ = function(segmentData, vertex) {
- var segment = segmentData.segment;
- var feature = segmentData.feature;
- var geometry = segmentData.geometry;
- var depth = segmentData.depth;
- var index = /** @type {number} */ (segmentData.index);
- var coordinates;
- while (vertex.length < geometry.getStride()) {
- vertex.push(0);
- }
- switch (geometry.getType()) {
- case ol.geom.GeometryType.MULTI_LINE_STRING:
- coordinates = geometry.getCoordinates();
- coordinates[depth[0]].splice(index + 1, 0, vertex);
- break;
- case ol.geom.GeometryType.POLYGON:
- coordinates = geometry.getCoordinates();
- coordinates[depth[0]].splice(index + 1, 0, vertex);
- break;
- case ol.geom.GeometryType.MULTI_POLYGON:
- coordinates = geometry.getCoordinates();
- coordinates[depth[1]][depth[0]].splice(index + 1, 0, vertex);
- break;
- case ol.geom.GeometryType.LINE_STRING:
- coordinates = geometry.getCoordinates();
- coordinates.splice(index + 1, 0, vertex);
- break;
- default:
- return;
- }
- this.setGeometryCoordinates_(geometry, coordinates);
- var rTree = this.rBush_;
- rTree.remove(segmentData);
- this.updateSegmentIndices_(geometry, index, depth, 1);
- var newSegmentData = /** @type {ol.ModifySegmentDataType} */ ({
- segment: [segment[0], vertex],
- feature: feature,
- geometry: geometry,
- depth: depth,
- index: index
- });
- rTree.insert(ol.extent.boundingExtent(newSegmentData.segment),
- newSegmentData);
- this.dragSegments_.push([newSegmentData, 1]);
- var newSegmentData2 = /** @type {ol.ModifySegmentDataType} */ ({
- segment: [vertex, segment[1]],
- feature: feature,
- geometry: geometry,
- depth: depth,
- index: index + 1
- });
- rTree.insert(ol.extent.boundingExtent(newSegmentData2.segment),
- newSegmentData2);
- this.dragSegments_.push([newSegmentData2, 0]);
- this.ignoreNextSingleClick_ = true;
- };
- /**
- * Removes the vertex currently being pointed.
- * @return {boolean} True when a vertex was removed.
- * @api
- */
- ol.interaction.Modify.prototype.removePoint = function() {
- if (this.lastPointerEvent_ && this.lastPointerEvent_.type != ol.MapBrowserEventType.POINTERDRAG) {
- var evt = this.lastPointerEvent_;
- this.willModifyFeatures_(evt);
- this.removeVertex_();
- this.dispatchEvent(new ol.interaction.Modify.Event(
- ol.interaction.ModifyEventType.MODIFYEND, this.features_, evt));
- this.modified_ = false;
- return true;
- }
- return false;
- };
- /**
- * Removes a vertex from all matching features.
- * @return {boolean} True when a vertex was removed.
- * @private
- */
- ol.interaction.Modify.prototype.removeVertex_ = function() {
- var dragSegments = this.dragSegments_;
- var segmentsByFeature = {};
- var deleted = false;
- var component, coordinates, dragSegment, geometry, i, index, left;
- var newIndex, right, segmentData, uid;
- for (i = dragSegments.length - 1; i >= 0; --i) {
- dragSegment = dragSegments[i];
- segmentData = dragSegment[0];
- uid = ol.getUid(segmentData.feature);
- if (segmentData.depth) {
- // separate feature components
- uid += '-' + segmentData.depth.join('-');
- }
- if (!(uid in segmentsByFeature)) {
- segmentsByFeature[uid] = {};
- }
- if (dragSegment[1] === 0) {
- segmentsByFeature[uid].right = segmentData;
- segmentsByFeature[uid].index = segmentData.index;
- } else if (dragSegment[1] == 1) {
- segmentsByFeature[uid].left = segmentData;
- segmentsByFeature[uid].index = segmentData.index + 1;
- }
- }
- for (uid in segmentsByFeature) {
- right = segmentsByFeature[uid].right;
- left = segmentsByFeature[uid].left;
- index = segmentsByFeature[uid].index;
- newIndex = index - 1;
- if (left !== undefined) {
- segmentData = left;
- } else {
- segmentData = right;
- }
- if (newIndex < 0) {
- newIndex = 0;
- }
- geometry = segmentData.geometry;
- coordinates = geometry.getCoordinates();
- component = coordinates;
- deleted = false;
- switch (geometry.getType()) {
- case ol.geom.GeometryType.MULTI_LINE_STRING:
- if (coordinates[segmentData.depth[0]].length > 2) {
- coordinates[segmentData.depth[0]].splice(index, 1);
- deleted = true;
- }
- break;
- case ol.geom.GeometryType.LINE_STRING:
- if (coordinates.length > 2) {
- coordinates.splice(index, 1);
- deleted = true;
- }
- break;
- case ol.geom.GeometryType.MULTI_POLYGON:
- component = component[segmentData.depth[1]];
- /* falls through */
- case ol.geom.GeometryType.POLYGON:
- component = component[segmentData.depth[0]];
- if (component.length > 4) {
- if (index == component.length - 1) {
- index = 0;
- }
- component.splice(index, 1);
- deleted = true;
- if (index === 0) {
- // close the ring again
- component.pop();
- component.push(component[0]);
- newIndex = component.length - 1;
- }
- }
- break;
- default:
- // pass
- }
- if (deleted) {
- this.setGeometryCoordinates_(geometry, coordinates);
- var segments = [];
- if (left !== undefined) {
- this.rBush_.remove(left);
- segments.push(left.segment[0]);
- }
- if (right !== undefined) {
- this.rBush_.remove(right);
- segments.push(right.segment[1]);
- }
- if (left !== undefined && right !== undefined) {
- var newSegmentData = /** @type {ol.ModifySegmentDataType} */ ({
- depth: segmentData.depth,
- feature: segmentData.feature,
- geometry: segmentData.geometry,
- index: newIndex,
- segment: segments
- });
- this.rBush_.insert(ol.extent.boundingExtent(newSegmentData.segment),
- newSegmentData);
- }
- this.updateSegmentIndices_(geometry, index, segmentData.depth, -1);
- if (this.vertexFeature_) {
- this.overlay_.getSource().removeFeature(this.vertexFeature_);
- this.vertexFeature_ = null;
- }
- dragSegments.length = 0;
- }
- }
- return deleted;
- };
- /**
- * @param {ol.geom.SimpleGeometry} geometry Geometry.
- * @param {Array} coordinates Coordinates.
- * @private
- */
- ol.interaction.Modify.prototype.setGeometryCoordinates_ = function(geometry, coordinates) {
- this.changingFeature_ = true;
- geometry.setCoordinates(coordinates);
- this.changingFeature_ = false;
- };
- /**
- * @param {ol.geom.SimpleGeometry} geometry Geometry.
- * @param {number} index Index.
- * @param {Array.<number>|undefined} depth Depth.
- * @param {number} delta Delta (1 or -1).
- * @private
- */
- ol.interaction.Modify.prototype.updateSegmentIndices_ = function(
- geometry, index, depth, delta) {
- this.rBush_.forEachInExtent(geometry.getExtent(), function(segmentDataMatch) {
- if (segmentDataMatch.geometry === geometry &&
- (depth === undefined || segmentDataMatch.depth === undefined ||
- ol.array.equals(segmentDataMatch.depth, depth)) &&
- segmentDataMatch.index > index) {
- segmentDataMatch.index += delta;
- }
- });
- };
- /**
- * @return {ol.StyleFunction} Styles.
- */
- ol.interaction.Modify.getDefaultStyleFunction = function() {
- var style = ol.style.Style.createDefaultEditing();
- return function(feature, resolution) {
- return style[ol.geom.GeometryType.POINT];
- };
- };
- /**
- * @classdesc
- * Events emitted by {@link ol.interaction.Modify} instances are instances of
- * this type.
- *
- * @constructor
- * @extends {ol.events.Event}
- * @implements {oli.ModifyEvent}
- * @param {ol.interaction.ModifyEventType} type Type.
- * @param {ol.Collection.<ol.Feature>} features The features modified.
- * @param {ol.MapBrowserPointerEvent} mapBrowserPointerEvent Associated
- * {@link ol.MapBrowserPointerEvent}.
- */
- ol.interaction.Modify.Event = function(type, features, mapBrowserPointerEvent) {
- ol.events.Event.call(this, type);
- /**
- * The features being modified.
- * @type {ol.Collection.<ol.Feature>}
- * @api
- */
- this.features = features;
- /**
- * Associated {@link ol.MapBrowserEvent}.
- * @type {ol.MapBrowserEvent}
- * @api
- */
- this.mapBrowserEvent = mapBrowserPointerEvent;
- };
- ol.inherits(ol.interaction.Modify.Event, ol.events.Event);
- goog.provide('ol.interaction.Select');
- goog.require('ol');
- goog.require('ol.CollectionEventType');
- goog.require('ol.array');
- goog.require('ol.events');
- goog.require('ol.events.Event');
- goog.require('ol.events.condition');
- goog.require('ol.functions');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.interaction.Interaction');
- goog.require('ol.layer.Vector');
- goog.require('ol.obj');
- goog.require('ol.source.Vector');
- goog.require('ol.style.Style');
- /**
- * @classdesc
- * Interaction for selecting vector features. By default, selected features are
- * styled differently, so this interaction can be used for visual highlighting,
- * as well as selecting features for other actions, such as modification or
- * output. There are three ways of controlling which features are selected:
- * using the browser event as defined by the `condition` and optionally the
- * `toggle`, `add`/`remove`, and `multi` options; a `layers` filter; and a
- * further feature filter using the `filter` option.
- *
- * Selected features are added to an internal unmanaged layer.
- *
- * @constructor
- * @extends {ol.interaction.Interaction}
- * @param {olx.interaction.SelectOptions=} opt_options Options.
- * @fires ol.interaction.Select.Event
- * @api
- */
- ol.interaction.Select = function(opt_options) {
- ol.interaction.Interaction.call(this, {
- handleEvent: ol.interaction.Select.handleEvent
- });
- var options = opt_options ? opt_options : {};
- /**
- * @private
- * @type {ol.EventsConditionType}
- */
- this.condition_ = options.condition ?
- options.condition : ol.events.condition.singleClick;
- /**
- * @private
- * @type {ol.EventsConditionType}
- */
- this.addCondition_ = options.addCondition ?
- options.addCondition : ol.events.condition.never;
- /**
- * @private
- * @type {ol.EventsConditionType}
- */
- this.removeCondition_ = options.removeCondition ?
- options.removeCondition : ol.events.condition.never;
- /**
- * @private
- * @type {ol.EventsConditionType}
- */
- this.toggleCondition_ = options.toggleCondition ?
- options.toggleCondition : ol.events.condition.shiftKeyOnly;
- /**
- * @private
- * @type {boolean}
- */
- this.multi_ = options.multi ? options.multi : false;
- /**
- * @private
- * @type {ol.SelectFilterFunction}
- */
- this.filter_ = options.filter ? options.filter :
- ol.functions.TRUE;
- /**
- * @private
- * @type {number}
- */
- this.hitTolerance_ = options.hitTolerance ? options.hitTolerance : 0;
- var featureOverlay = new ol.layer.Vector({
- source: new ol.source.Vector({
- useSpatialIndex: false,
- features: options.features,
- wrapX: options.wrapX
- }),
- style: options.style ? options.style :
- ol.interaction.Select.getDefaultStyleFunction(),
- updateWhileAnimating: true,
- updateWhileInteracting: true
- });
- /**
- * @private
- * @type {ol.layer.Vector}
- */
- this.featureOverlay_ = featureOverlay;
- /** @type {function(ol.layer.Layer): boolean} */
- var layerFilter;
- if (options.layers) {
- if (typeof options.layers === 'function') {
- layerFilter = options.layers;
- } else {
- var layers = options.layers;
- layerFilter = function(layer) {
- return ol.array.includes(layers, layer);
- };
- }
- } else {
- layerFilter = ol.functions.TRUE;
- }
- /**
- * @private
- * @type {function(ol.layer.Layer): boolean}
- */
- this.layerFilter_ = layerFilter;
- /**
- * An association between selected feature (key)
- * and layer (value)
- * @private
- * @type {Object.<number, ol.layer.Layer>}
- */
- this.featureLayerAssociation_ = {};
- var features = this.featureOverlay_.getSource().getFeaturesCollection();
- ol.events.listen(features, ol.CollectionEventType.ADD,
- this.addFeature_, this);
- ol.events.listen(features, ol.CollectionEventType.REMOVE,
- this.removeFeature_, this);
- };
- ol.inherits(ol.interaction.Select, ol.interaction.Interaction);
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @param {ol.layer.Layer} layer Layer.
- * @private
- */
- ol.interaction.Select.prototype.addFeatureLayerAssociation_ = function(feature, layer) {
- var key = ol.getUid(feature);
- this.featureLayerAssociation_[key] = layer;
- };
- /**
- * Get the selected features.
- * @return {ol.Collection.<ol.Feature>} Features collection.
- * @api
- */
- ol.interaction.Select.prototype.getFeatures = function() {
- return this.featureOverlay_.getSource().getFeaturesCollection();
- };
- /**
- * Returns the Hit-detection tolerance.
- * @returns {number} Hit tolerance in pixels.
- * @api
- */
- ol.interaction.Select.prototype.getHitTolerance = function() {
- return this.hitTolerance_;
- };
- /**
- * Returns the associated {@link ol.layer.Vector vectorlayer} of
- * the (last) selected feature. Note that this will not work with any
- * programmatic method like pushing features to
- * {@link ol.interaction.Select#getFeatures collection}.
- * @param {ol.Feature|ol.render.Feature} feature Feature
- * @return {ol.layer.Vector} Layer.
- * @api
- */
- ol.interaction.Select.prototype.getLayer = function(feature) {
- var key = ol.getUid(feature);
- return /** @type {ol.layer.Vector} */ (this.featureLayerAssociation_[key]);
- };
- /**
- * Handles the {@link ol.MapBrowserEvent map browser event} and may change the
- * selected state of features.
- * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
- * @return {boolean} `false` to stop event propagation.
- * @this {ol.interaction.Select}
- * @api
- */
- ol.interaction.Select.handleEvent = function(mapBrowserEvent) {
- if (!this.condition_(mapBrowserEvent)) {
- return true;
- }
- var add = this.addCondition_(mapBrowserEvent);
- var remove = this.removeCondition_(mapBrowserEvent);
- var toggle = this.toggleCondition_(mapBrowserEvent);
- var set = !add && !remove && !toggle;
- var map = mapBrowserEvent.map;
- var features = this.featureOverlay_.getSource().getFeaturesCollection();
- var deselected = [];
- var selected = [];
- if (set) {
- // Replace the currently selected feature(s) with the feature(s) at the
- // pixel, or clear the selected feature(s) if there is no feature at
- // the pixel.
- ol.obj.clear(this.featureLayerAssociation_);
- map.forEachFeatureAtPixel(mapBrowserEvent.pixel,
- (
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @param {ol.layer.Layer} layer Layer.
- * @return {boolean|undefined} Continue to iterate over the features.
- */
- function(feature, layer) {
- if (this.filter_(feature, layer)) {
- selected.push(feature);
- this.addFeatureLayerAssociation_(feature, layer);
- return !this.multi_;
- }
- }).bind(this), {
- layerFilter: this.layerFilter_,
- hitTolerance: this.hitTolerance_
- });
- var i;
- for (i = features.getLength() - 1; i >= 0; --i) {
- var feature = features.item(i);
- var index = selected.indexOf(feature);
- if (index > -1) {
- // feature is already selected
- selected.splice(index, 1);
- } else {
- features.remove(feature);
- deselected.push(feature);
- }
- }
- if (selected.length !== 0) {
- features.extend(selected);
- }
- } else {
- // Modify the currently selected feature(s).
- map.forEachFeatureAtPixel(mapBrowserEvent.pixel,
- (
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @param {ol.layer.Layer} layer Layer.
- * @return {boolean|undefined} Continue to iterate over the features.
- */
- function(feature, layer) {
- if (this.filter_(feature, layer)) {
- if ((add || toggle) &&
- !ol.array.includes(features.getArray(), feature)) {
- selected.push(feature);
- this.addFeatureLayerAssociation_(feature, layer);
- } else if ((remove || toggle) &&
- ol.array.includes(features.getArray(), feature)) {
- deselected.push(feature);
- this.removeFeatureLayerAssociation_(feature);
- }
- return !this.multi_;
- }
- }).bind(this), {
- layerFilter: this.layerFilter_,
- hitTolerance: this.hitTolerance_
- });
- var j;
- for (j = deselected.length - 1; j >= 0; --j) {
- features.remove(deselected[j]);
- }
- features.extend(selected);
- }
- if (selected.length > 0 || deselected.length > 0) {
- this.dispatchEvent(
- new ol.interaction.Select.Event(ol.interaction.Select.EventType_.SELECT,
- selected, deselected, mapBrowserEvent));
- }
- return ol.events.condition.pointerMove(mapBrowserEvent);
- };
- /**
- * Hit-detection tolerance. Pixels inside the radius around the given position
- * will be checked for features. This only works for the canvas renderer and
- * not for WebGL.
- * @param {number} hitTolerance Hit tolerance in pixels.
- * @api
- */
- ol.interaction.Select.prototype.setHitTolerance = function(hitTolerance) {
- this.hitTolerance_ = hitTolerance;
- };
- /**
- * Remove the interaction from its current map, if any, and attach it to a new
- * map, if any. Pass `null` to just remove the interaction from the current map.
- * @param {ol.PluggableMap} map Map.
- * @override
- * @api
- */
- ol.interaction.Select.prototype.setMap = function(map) {
- var currentMap = this.getMap();
- var selectedFeatures =
- this.featureOverlay_.getSource().getFeaturesCollection();
- if (currentMap) {
- selectedFeatures.forEach(currentMap.unskipFeature, currentMap);
- }
- ol.interaction.Interaction.prototype.setMap.call(this, map);
- this.featureOverlay_.setMap(map);
- if (map) {
- selectedFeatures.forEach(map.skipFeature, map);
- }
- };
- /**
- * @return {ol.StyleFunction} Styles.
- */
- ol.interaction.Select.getDefaultStyleFunction = function() {
- var styles = ol.style.Style.createDefaultEditing();
- ol.array.extend(styles[ol.geom.GeometryType.POLYGON],
- styles[ol.geom.GeometryType.LINE_STRING]);
- ol.array.extend(styles[ol.geom.GeometryType.GEOMETRY_COLLECTION],
- styles[ol.geom.GeometryType.LINE_STRING]);
- return function(feature, resolution) {
- if (!feature.getGeometry()) {
- return null;
- }
- return styles[feature.getGeometry().getType()];
- };
- };
- /**
- * @param {ol.Collection.Event} evt Event.
- * @private
- */
- ol.interaction.Select.prototype.addFeature_ = function(evt) {
- var map = this.getMap();
- if (map) {
- map.skipFeature(/** @type {ol.Feature} */ (evt.element));
- }
- };
- /**
- * @param {ol.Collection.Event} evt Event.
- * @private
- */
- ol.interaction.Select.prototype.removeFeature_ = function(evt) {
- var map = this.getMap();
- if (map) {
- map.unskipFeature(/** @type {ol.Feature} */ (evt.element));
- }
- };
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @private
- */
- ol.interaction.Select.prototype.removeFeatureLayerAssociation_ = function(feature) {
- var key = ol.getUid(feature);
- delete this.featureLayerAssociation_[key];
- };
- /**
- * @classdesc
- * Events emitted by {@link ol.interaction.Select} instances are instances of
- * this type.
- *
- * @param {ol.interaction.Select.EventType_} type The event type.
- * @param {Array.<ol.Feature>} selected Selected features.
- * @param {Array.<ol.Feature>} deselected Deselected features.
- * @param {ol.MapBrowserEvent} mapBrowserEvent Associated
- * {@link ol.MapBrowserEvent}.
- * @implements {oli.SelectEvent}
- * @extends {ol.events.Event}
- * @constructor
- */
- ol.interaction.Select.Event = function(type, selected, deselected, mapBrowserEvent) {
- ol.events.Event.call(this, type);
- /**
- * Selected features array.
- * @type {Array.<ol.Feature>}
- * @api
- */
- this.selected = selected;
- /**
- * Deselected features array.
- * @type {Array.<ol.Feature>}
- * @api
- */
- this.deselected = deselected;
- /**
- * Associated {@link ol.MapBrowserEvent}.
- * @type {ol.MapBrowserEvent}
- * @api
- */
- this.mapBrowserEvent = mapBrowserEvent;
- };
- ol.inherits(ol.interaction.Select.Event, ol.events.Event);
- /**
- * @enum {string}
- * @private
- */
- ol.interaction.Select.EventType_ = {
- /**
- * Triggered when feature(s) has been (de)selected.
- * @event ol.interaction.Select.Event#select
- * @api
- */
- SELECT: 'select'
- };
- goog.provide('ol.interaction.Snap');
- goog.require('ol');
- goog.require('ol.Collection');
- goog.require('ol.CollectionEventType');
- goog.require('ol.coordinate');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.extent');
- goog.require('ol.functions');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.geom.Polygon');
- goog.require('ol.interaction.Pointer');
- goog.require('ol.obj');
- goog.require('ol.source.Vector');
- goog.require('ol.source.VectorEventType');
- goog.require('ol.structs.RBush');
- /**
- * @classdesc
- * Handles snapping of vector features while modifying or drawing them. The
- * features can come from a {@link ol.source.Vector} or {@link ol.Collection}
- * Any interaction object that allows the user to interact
- * with the features using the mouse can benefit from the snapping, as long
- * as it is added before.
- *
- * The snap interaction modifies map browser event `coordinate` and `pixel`
- * properties to force the snap to occur to any interaction that them.
- *
- * Example:
- *
- * var snap = new ol.interaction.Snap({
- * source: source
- * });
- *
- * @constructor
- * @extends {ol.interaction.Pointer}
- * @param {olx.interaction.SnapOptions=} opt_options Options.
- * @api
- */
- ol.interaction.Snap = function(opt_options) {
- ol.interaction.Pointer.call(this, {
- handleEvent: ol.interaction.Snap.handleEvent_,
- handleDownEvent: ol.functions.TRUE,
- handleUpEvent: ol.interaction.Snap.handleUpEvent_
- });
- var options = opt_options ? opt_options : {};
- /**
- * @type {ol.source.Vector}
- * @private
- */
- this.source_ = options.source ? options.source : null;
- /**
- * @private
- * @type {boolean}
- */
- this.vertex_ = options.vertex !== undefined ? options.vertex : true;
- /**
- * @private
- * @type {boolean}
- */
- this.edge_ = options.edge !== undefined ? options.edge : true;
- /**
- * @type {ol.Collection.<ol.Feature>}
- * @private
- */
- this.features_ = options.features ? options.features : null;
- /**
- * @type {Array.<ol.EventsKey>}
- * @private
- */
- this.featuresListenerKeys_ = [];
- /**
- * @type {Object.<number, ol.EventsKey>}
- * @private
- */
- this.featureChangeListenerKeys_ = {};
- /**
- * Extents are preserved so indexed segment can be quickly removed
- * when its feature geometry changes
- * @type {Object.<number, ol.Extent>}
- * @private
- */
- this.indexedFeaturesExtents_ = {};
- /**
- * If a feature geometry changes while a pointer drag|move event occurs, the
- * feature doesn't get updated right away. It will be at the next 'pointerup'
- * event fired.
- * @type {Object.<number, ol.Feature>}
- * @private
- */
- this.pendingFeatures_ = {};
- /**
- * Used for distance sorting in sortByDistance_
- * @type {ol.Coordinate}
- * @private
- */
- this.pixelCoordinate_ = null;
- /**
- * @type {number}
- * @private
- */
- this.pixelTolerance_ = options.pixelTolerance !== undefined ?
- options.pixelTolerance : 10;
- /**
- * @type {function(ol.SnapSegmentDataType, ol.SnapSegmentDataType): number}
- * @private
- */
- this.sortByDistance_ = ol.interaction.Snap.sortByDistance.bind(this);
- /**
- * Segment RTree for each layer
- * @type {ol.structs.RBush.<ol.SnapSegmentDataType>}
- * @private
- */
- this.rBush_ = new ol.structs.RBush();
- /**
- * @const
- * @private
- * @type {Object.<string, function(ol.Feature, ol.geom.Geometry)>}
- */
- this.SEGMENT_WRITERS_ = {
- 'Point': this.writePointGeometry_,
- 'LineString': this.writeLineStringGeometry_,
- 'LinearRing': this.writeLineStringGeometry_,
- 'Polygon': this.writePolygonGeometry_,
- 'MultiPoint': this.writeMultiPointGeometry_,
- 'MultiLineString': this.writeMultiLineStringGeometry_,
- 'MultiPolygon': this.writeMultiPolygonGeometry_,
- 'GeometryCollection': this.writeGeometryCollectionGeometry_,
- 'Circle': this.writeCircleGeometry_
- };
- };
- ol.inherits(ol.interaction.Snap, ol.interaction.Pointer);
- /**
- * Add a feature to the collection of features that we may snap to.
- * @param {ol.Feature} feature Feature.
- * @param {boolean=} opt_listen Whether to listen to the feature change or not
- * Defaults to `true`.
- * @api
- */
- ol.interaction.Snap.prototype.addFeature = function(feature, opt_listen) {
- var listen = opt_listen !== undefined ? opt_listen : true;
- var feature_uid = ol.getUid(feature);
- var geometry = feature.getGeometry();
- if (geometry) {
- var segmentWriter = this.SEGMENT_WRITERS_[geometry.getType()];
- if (segmentWriter) {
- this.indexedFeaturesExtents_[feature_uid] = geometry.getExtent(
- ol.extent.createEmpty());
- segmentWriter.call(this, feature, geometry);
- }
- }
- if (listen) {
- this.featureChangeListenerKeys_[feature_uid] = ol.events.listen(
- feature,
- ol.events.EventType.CHANGE,
- this.handleFeatureChange_, this);
- }
- };
- /**
- * @param {ol.Feature} feature Feature.
- * @private
- */
- ol.interaction.Snap.prototype.forEachFeatureAdd_ = function(feature) {
- this.addFeature(feature);
- };
- /**
- * @param {ol.Feature} feature Feature.
- * @private
- */
- ol.interaction.Snap.prototype.forEachFeatureRemove_ = function(feature) {
- this.removeFeature(feature);
- };
- /**
- * @return {ol.Collection.<ol.Feature>|Array.<ol.Feature>} Features.
- * @private
- */
- ol.interaction.Snap.prototype.getFeatures_ = function() {
- var features;
- if (this.features_) {
- features = this.features_;
- } else if (this.source_) {
- features = this.source_.getFeatures();
- }
- return /** @type {!Array.<ol.Feature>|!ol.Collection.<ol.Feature>} */ (features);
- };
- /**
- * @param {ol.source.Vector.Event|ol.Collection.Event} evt Event.
- * @private
- */
- ol.interaction.Snap.prototype.handleFeatureAdd_ = function(evt) {
- var feature;
- if (evt instanceof ol.source.Vector.Event) {
- feature = evt.feature;
- } else if (evt instanceof ol.Collection.Event) {
- feature = evt.element;
- }
- this.addFeature(/** @type {ol.Feature} */ (feature));
- };
- /**
- * @param {ol.source.Vector.Event|ol.Collection.Event} evt Event.
- * @private
- */
- ol.interaction.Snap.prototype.handleFeatureRemove_ = function(evt) {
- var feature;
- if (evt instanceof ol.source.Vector.Event) {
- feature = evt.feature;
- } else if (evt instanceof ol.Collection.Event) {
- feature = evt.element;
- }
- this.removeFeature(/** @type {ol.Feature} */ (feature));
- };
- /**
- * @param {ol.events.Event} evt Event.
- * @private
- */
- ol.interaction.Snap.prototype.handleFeatureChange_ = function(evt) {
- var feature = /** @type {ol.Feature} */ (evt.target);
- if (this.handlingDownUpSequence) {
- var uid = ol.getUid(feature);
- if (!(uid in this.pendingFeatures_)) {
- this.pendingFeatures_[uid] = feature;
- }
- } else {
- this.updateFeature_(feature);
- }
- };
- /**
- * Remove a feature from the collection of features that we may snap to.
- * @param {ol.Feature} feature Feature
- * @param {boolean=} opt_unlisten Whether to unlisten to the feature change
- * or not. Defaults to `true`.
- * @api
- */
- ol.interaction.Snap.prototype.removeFeature = function(feature, opt_unlisten) {
- var unlisten = opt_unlisten !== undefined ? opt_unlisten : true;
- var feature_uid = ol.getUid(feature);
- var extent = this.indexedFeaturesExtents_[feature_uid];
- if (extent) {
- var rBush = this.rBush_;
- var i, nodesToRemove = [];
- rBush.forEachInExtent(extent, function(node) {
- if (feature === node.feature) {
- nodesToRemove.push(node);
- }
- });
- for (i = nodesToRemove.length - 1; i >= 0; --i) {
- rBush.remove(nodesToRemove[i]);
- }
- }
- if (unlisten) {
- ol.events.unlistenByKey(this.featureChangeListenerKeys_[feature_uid]);
- delete this.featureChangeListenerKeys_[feature_uid];
- }
- };
- /**
- * @inheritDoc
- */
- ol.interaction.Snap.prototype.setMap = function(map) {
- var currentMap = this.getMap();
- var keys = this.featuresListenerKeys_;
- var features = this.getFeatures_();
- if (currentMap) {
- keys.forEach(ol.events.unlistenByKey);
- keys.length = 0;
- features.forEach(this.forEachFeatureRemove_, this);
- }
- ol.interaction.Pointer.prototype.setMap.call(this, map);
- if (map) {
- if (this.features_) {
- keys.push(
- ol.events.listen(this.features_, ol.CollectionEventType.ADD,
- this.handleFeatureAdd_, this),
- ol.events.listen(this.features_, ol.CollectionEventType.REMOVE,
- this.handleFeatureRemove_, this)
- );
- } else if (this.source_) {
- keys.push(
- ol.events.listen(this.source_, ol.source.VectorEventType.ADDFEATURE,
- this.handleFeatureAdd_, this),
- ol.events.listen(this.source_, ol.source.VectorEventType.REMOVEFEATURE,
- this.handleFeatureRemove_, this)
- );
- }
- features.forEach(this.forEachFeatureAdd_, this);
- }
- };
- /**
- * @inheritDoc
- */
- ol.interaction.Snap.prototype.shouldStopEvent = ol.functions.FALSE;
- /**
- * @param {ol.Pixel} pixel Pixel
- * @param {ol.Coordinate} pixelCoordinate Coordinate
- * @param {ol.PluggableMap} map Map.
- * @return {ol.SnapResultType} Snap result
- */
- ol.interaction.Snap.prototype.snapTo = function(pixel, pixelCoordinate, map) {
- var lowerLeft = map.getCoordinateFromPixel(
- [pixel[0] - this.pixelTolerance_, pixel[1] + this.pixelTolerance_]);
- var upperRight = map.getCoordinateFromPixel(
- [pixel[0] + this.pixelTolerance_, pixel[1] - this.pixelTolerance_]);
- var box = ol.extent.boundingExtent([lowerLeft, upperRight]);
- var segments = this.rBush_.getInExtent(box);
- // If snapping on vertices only, don't consider circles
- if (this.vertex_ && !this.edge_) {
- segments = segments.filter(function(segment) {
- return segment.feature.getGeometry().getType() !==
- ol.geom.GeometryType.CIRCLE;
- });
- }
- var snappedToVertex = false;
- var snapped = false;
- var vertex = null;
- var vertexPixel = null;
- var dist, pixel1, pixel2, squaredDist1, squaredDist2;
- if (segments.length > 0) {
- this.pixelCoordinate_ = pixelCoordinate;
- segments.sort(this.sortByDistance_);
- var closestSegment = segments[0].segment;
- var isCircle = segments[0].feature.getGeometry().getType() ===
- ol.geom.GeometryType.CIRCLE;
- if (this.vertex_ && !this.edge_) {
- pixel1 = map.getPixelFromCoordinate(closestSegment[0]);
- pixel2 = map.getPixelFromCoordinate(closestSegment[1]);
- squaredDist1 = ol.coordinate.squaredDistance(pixel, pixel1);
- squaredDist2 = ol.coordinate.squaredDistance(pixel, pixel2);
- dist = Math.sqrt(Math.min(squaredDist1, squaredDist2));
- snappedToVertex = dist <= this.pixelTolerance_;
- if (snappedToVertex) {
- snapped = true;
- vertex = squaredDist1 > squaredDist2 ?
- closestSegment[1] : closestSegment[0];
- vertexPixel = map.getPixelFromCoordinate(vertex);
- }
- } else if (this.edge_) {
- if (isCircle) {
- vertex = ol.coordinate.closestOnCircle(pixelCoordinate,
- /** @type {ol.geom.Circle} */ (segments[0].feature.getGeometry()));
- } else {
- vertex = (ol.coordinate.closestOnSegment(pixelCoordinate,
- closestSegment));
- }
- vertexPixel = map.getPixelFromCoordinate(vertex);
- if (ol.coordinate.distance(pixel, vertexPixel) <= this.pixelTolerance_) {
- snapped = true;
- if (this.vertex_ && !isCircle) {
- pixel1 = map.getPixelFromCoordinate(closestSegment[0]);
- pixel2 = map.getPixelFromCoordinate(closestSegment[1]);
- squaredDist1 = ol.coordinate.squaredDistance(vertexPixel, pixel1);
- squaredDist2 = ol.coordinate.squaredDistance(vertexPixel, pixel2);
- dist = Math.sqrt(Math.min(squaredDist1, squaredDist2));
- snappedToVertex = dist <= this.pixelTolerance_;
- if (snappedToVertex) {
- vertex = squaredDist1 > squaredDist2 ?
- closestSegment[1] : closestSegment[0];
- vertexPixel = map.getPixelFromCoordinate(vertex);
- }
- }
- }
- }
- if (snapped) {
- vertexPixel = [Math.round(vertexPixel[0]), Math.round(vertexPixel[1])];
- }
- }
- return /** @type {ol.SnapResultType} */ ({
- snapped: snapped,
- vertex: vertex,
- vertexPixel: vertexPixel
- });
- };
- /**
- * @param {ol.Feature} feature Feature
- * @private
- */
- ol.interaction.Snap.prototype.updateFeature_ = function(feature) {
- this.removeFeature(feature, false);
- this.addFeature(feature, false);
- };
- /**
- * @param {ol.Feature} feature Feature
- * @param {ol.geom.Circle} geometry Geometry.
- * @private
- */
- ol.interaction.Snap.prototype.writeCircleGeometry_ = function(feature, geometry) {
- var polygon = ol.geom.Polygon.fromCircle(geometry);
- var coordinates = polygon.getCoordinates()[0];
- var i, ii, segment, segmentData;
- for (i = 0, ii = coordinates.length - 1; i < ii; ++i) {
- segment = coordinates.slice(i, i + 2);
- segmentData = /** @type {ol.SnapSegmentDataType} */ ({
- feature: feature,
- segment: segment
- });
- this.rBush_.insert(ol.extent.boundingExtent(segment), segmentData);
- }
- };
- /**
- * @param {ol.Feature} feature Feature
- * @param {ol.geom.GeometryCollection} geometry Geometry.
- * @private
- */
- ol.interaction.Snap.prototype.writeGeometryCollectionGeometry_ = function(feature, geometry) {
- var i, geometries = geometry.getGeometriesArray();
- for (i = 0; i < geometries.length; ++i) {
- var segmentWriter = this.SEGMENT_WRITERS_[geometries[i].getType()];
- if (segmentWriter) {
- segmentWriter.call(this, feature, geometries[i]);
- }
- }
- };
- /**
- * @param {ol.Feature} feature Feature
- * @param {ol.geom.LineString} geometry Geometry.
- * @private
- */
- ol.interaction.Snap.prototype.writeLineStringGeometry_ = function(feature, geometry) {
- var coordinates = geometry.getCoordinates();
- var i, ii, segment, segmentData;
- for (i = 0, ii = coordinates.length - 1; i < ii; ++i) {
- segment = coordinates.slice(i, i + 2);
- segmentData = /** @type {ol.SnapSegmentDataType} */ ({
- feature: feature,
- segment: segment
- });
- this.rBush_.insert(ol.extent.boundingExtent(segment), segmentData);
- }
- };
- /**
- * @param {ol.Feature} feature Feature
- * @param {ol.geom.MultiLineString} geometry Geometry.
- * @private
- */
- ol.interaction.Snap.prototype.writeMultiLineStringGeometry_ = function(feature, geometry) {
- var lines = geometry.getCoordinates();
- var coordinates, i, ii, j, jj, segment, segmentData;
- for (j = 0, jj = lines.length; j < jj; ++j) {
- coordinates = lines[j];
- for (i = 0, ii = coordinates.length - 1; i < ii; ++i) {
- segment = coordinates.slice(i, i + 2);
- segmentData = /** @type {ol.SnapSegmentDataType} */ ({
- feature: feature,
- segment: segment
- });
- this.rBush_.insert(ol.extent.boundingExtent(segment), segmentData);
- }
- }
- };
- /**
- * @param {ol.Feature} feature Feature
- * @param {ol.geom.MultiPoint} geometry Geometry.
- * @private
- */
- ol.interaction.Snap.prototype.writeMultiPointGeometry_ = function(feature, geometry) {
- var points = geometry.getCoordinates();
- var coordinates, i, ii, segmentData;
- for (i = 0, ii = points.length; i < ii; ++i) {
- coordinates = points[i];
- segmentData = /** @type {ol.SnapSegmentDataType} */ ({
- feature: feature,
- segment: [coordinates, coordinates]
- });
- this.rBush_.insert(geometry.getExtent(), segmentData);
- }
- };
- /**
- * @param {ol.Feature} feature Feature
- * @param {ol.geom.MultiPolygon} geometry Geometry.
- * @private
- */
- ol.interaction.Snap.prototype.writeMultiPolygonGeometry_ = function(feature, geometry) {
- var polygons = geometry.getCoordinates();
- var coordinates, i, ii, j, jj, k, kk, rings, segment, segmentData;
- for (k = 0, kk = polygons.length; k < kk; ++k) {
- rings = polygons[k];
- for (j = 0, jj = rings.length; j < jj; ++j) {
- coordinates = rings[j];
- for (i = 0, ii = coordinates.length - 1; i < ii; ++i) {
- segment = coordinates.slice(i, i + 2);
- segmentData = /** @type {ol.SnapSegmentDataType} */ ({
- feature: feature,
- segment: segment
- });
- this.rBush_.insert(ol.extent.boundingExtent(segment), segmentData);
- }
- }
- }
- };
- /**
- * @param {ol.Feature} feature Feature
- * @param {ol.geom.Point} geometry Geometry.
- * @private
- */
- ol.interaction.Snap.prototype.writePointGeometry_ = function(feature, geometry) {
- var coordinates = geometry.getCoordinates();
- var segmentData = /** @type {ol.SnapSegmentDataType} */ ({
- feature: feature,
- segment: [coordinates, coordinates]
- });
- this.rBush_.insert(geometry.getExtent(), segmentData);
- };
- /**
- * @param {ol.Feature} feature Feature
- * @param {ol.geom.Polygon} geometry Geometry.
- * @private
- */
- ol.interaction.Snap.prototype.writePolygonGeometry_ = function(feature, geometry) {
- var rings = geometry.getCoordinates();
- var coordinates, i, ii, j, jj, segment, segmentData;
- for (j = 0, jj = rings.length; j < jj; ++j) {
- coordinates = rings[j];
- for (i = 0, ii = coordinates.length - 1; i < ii; ++i) {
- segment = coordinates.slice(i, i + 2);
- segmentData = /** @type {ol.SnapSegmentDataType} */ ({
- feature: feature,
- segment: segment
- });
- this.rBush_.insert(ol.extent.boundingExtent(segment), segmentData);
- }
- }
- };
- /**
- * Handle all pointer events events.
- * @param {ol.MapBrowserEvent} evt A move event.
- * @return {boolean} Pass the event to other interactions.
- * @this {ol.interaction.Snap}
- * @private
- */
- ol.interaction.Snap.handleEvent_ = function(evt) {
- var result = this.snapTo(evt.pixel, evt.coordinate, evt.map);
- if (result.snapped) {
- evt.coordinate = result.vertex.slice(0, 2);
- evt.pixel = result.vertexPixel;
- }
- return ol.interaction.Pointer.handleEvent.call(this, evt);
- };
- /**
- * @param {ol.MapBrowserPointerEvent} evt Event.
- * @return {boolean} Stop drag sequence?
- * @this {ol.interaction.Snap}
- * @private
- */
- ol.interaction.Snap.handleUpEvent_ = function(evt) {
- var featuresToUpdate = ol.obj.getValues(this.pendingFeatures_);
- if (featuresToUpdate.length) {
- featuresToUpdate.forEach(this.updateFeature_, this);
- this.pendingFeatures_ = {};
- }
- return false;
- };
- /**
- * Sort segments by distance, helper function
- * @param {ol.SnapSegmentDataType} a The first segment data.
- * @param {ol.SnapSegmentDataType} b The second segment data.
- * @return {number} The difference in distance.
- * @this {ol.interaction.Snap}
- */
- ol.interaction.Snap.sortByDistance = function(a, b) {
- return ol.coordinate.squaredDistanceToSegment(
- this.pixelCoordinate_, a.segment) -
- ol.coordinate.squaredDistanceToSegment(
- this.pixelCoordinate_, b.segment);
- };
- goog.provide('ol.interaction.TranslateEventType');
- /**
- * @enum {string}
- */
- ol.interaction.TranslateEventType = {
- /**
- * Triggered upon feature translation start.
- * @event ol.interaction.Translate.Event#translatestart
- * @api
- */
- TRANSLATESTART: 'translatestart',
- /**
- * Triggered upon feature translation.
- * @event ol.interaction.Translate.Event#translating
- * @api
- */
- TRANSLATING: 'translating',
- /**
- * Triggered upon feature translation end.
- * @event ol.interaction.Translate.Event#translateend
- * @api
- */
- TRANSLATEEND: 'translateend'
- };
- goog.provide('ol.interaction.Translate');
- goog.require('ol');
- goog.require('ol.Collection');
- goog.require('ol.Object');
- goog.require('ol.events');
- goog.require('ol.events.Event');
- goog.require('ol.functions');
- goog.require('ol.array');
- goog.require('ol.interaction.Pointer');
- goog.require('ol.interaction.Property');
- goog.require('ol.interaction.TranslateEventType');
- /**
- * @classdesc
- * Interaction for translating (moving) features.
- *
- * @constructor
- * @extends {ol.interaction.Pointer}
- * @fires ol.interaction.Translate.Event
- * @param {olx.interaction.TranslateOptions=} opt_options Options.
- * @api
- */
- ol.interaction.Translate = function(opt_options) {
- ol.interaction.Pointer.call(this, {
- handleDownEvent: ol.interaction.Translate.handleDownEvent_,
- handleDragEvent: ol.interaction.Translate.handleDragEvent_,
- handleMoveEvent: ol.interaction.Translate.handleMoveEvent_,
- handleUpEvent: ol.interaction.Translate.handleUpEvent_
- });
- var options = opt_options ? opt_options : {};
- /**
- * The last position we translated to.
- * @type {ol.Coordinate}
- * @private
- */
- this.lastCoordinate_ = null;
- /**
- * @type {ol.Collection.<ol.Feature>}
- * @private
- */
- this.features_ = options.features !== undefined ? options.features : null;
- /** @type {function(ol.layer.Layer): boolean} */
- var layerFilter;
- if (options.layers) {
- if (typeof options.layers === 'function') {
- layerFilter = options.layers;
- } else {
- var layers = options.layers;
- layerFilter = function(layer) {
- return ol.array.includes(layers, layer);
- };
- }
- } else {
- layerFilter = ol.functions.TRUE;
- }
- /**
- * @private
- * @type {function(ol.layer.Layer): boolean}
- */
- this.layerFilter_ = layerFilter;
- /**
- * @private
- * @type {number}
- */
- this.hitTolerance_ = options.hitTolerance ? options.hitTolerance : 0;
- /**
- * @type {ol.Feature}
- * @private
- */
- this.lastFeature_ = null;
- ol.events.listen(this,
- ol.Object.getChangeEventType(ol.interaction.Property.ACTIVE),
- this.handleActiveChanged_, this);
- };
- ol.inherits(ol.interaction.Translate, ol.interaction.Pointer);
- /**
- * @param {ol.MapBrowserPointerEvent} event Event.
- * @return {boolean} Start drag sequence?
- * @this {ol.interaction.Translate}
- * @private
- */
- ol.interaction.Translate.handleDownEvent_ = function(event) {
- this.lastFeature_ = this.featuresAtPixel_(event.pixel, event.map);
- if (!this.lastCoordinate_ && this.lastFeature_) {
- this.lastCoordinate_ = event.coordinate;
- ol.interaction.Translate.handleMoveEvent_.call(this, event);
- var features = this.features_ || new ol.Collection([this.lastFeature_]);
- this.dispatchEvent(
- new ol.interaction.Translate.Event(
- ol.interaction.TranslateEventType.TRANSLATESTART, features,
- event.coordinate));
- return true;
- }
- return false;
- };
- /**
- * @param {ol.MapBrowserPointerEvent} event Event.
- * @return {boolean} Stop drag sequence?
- * @this {ol.interaction.Translate}
- * @private
- */
- ol.interaction.Translate.handleUpEvent_ = function(event) {
- if (this.lastCoordinate_) {
- this.lastCoordinate_ = null;
- ol.interaction.Translate.handleMoveEvent_.call(this, event);
- var features = this.features_ || new ol.Collection([this.lastFeature_]);
- this.dispatchEvent(
- new ol.interaction.Translate.Event(
- ol.interaction.TranslateEventType.TRANSLATEEND, features,
- event.coordinate));
- return true;
- }
- return false;
- };
- /**
- * @param {ol.MapBrowserPointerEvent} event Event.
- * @this {ol.interaction.Translate}
- * @private
- */
- ol.interaction.Translate.handleDragEvent_ = function(event) {
- if (this.lastCoordinate_) {
- var newCoordinate = event.coordinate;
- var deltaX = newCoordinate[0] - this.lastCoordinate_[0];
- var deltaY = newCoordinate[1] - this.lastCoordinate_[1];
- var features = this.features_ || new ol.Collection([this.lastFeature_]);
- features.forEach(function(feature) {
- var geom = feature.getGeometry();
- geom.translate(deltaX, deltaY);
- feature.setGeometry(geom);
- });
- this.lastCoordinate_ = newCoordinate;
- this.dispatchEvent(
- new ol.interaction.Translate.Event(
- ol.interaction.TranslateEventType.TRANSLATING, features,
- newCoordinate));
- }
- };
- /**
- * @param {ol.MapBrowserEvent} event Event.
- * @this {ol.interaction.Translate}
- * @private
- */
- ol.interaction.Translate.handleMoveEvent_ = function(event) {
- var elem = event.map.getViewport();
- // Change the cursor to grab/grabbing if hovering any of the features managed
- // by the interaction
- if (this.featuresAtPixel_(event.pixel, event.map)) {
- elem.classList.remove(this.lastCoordinate_ ? 'ol-grab' : 'ol-grabbing');
- elem.classList.add(this.lastCoordinate_ ? 'ol-grabbing' : 'ol-grab');
- } else {
- elem.classList.remove('ol-grab', 'ol-grabbing');
- }
- };
- /**
- * Tests to see if the given coordinates intersects any of our selected
- * features.
- * @param {ol.Pixel} pixel Pixel coordinate to test for intersection.
- * @param {ol.PluggableMap} map Map to test the intersection on.
- * @return {ol.Feature} Returns the feature found at the specified pixel
- * coordinates.
- * @private
- */
- ol.interaction.Translate.prototype.featuresAtPixel_ = function(pixel, map) {
- return map.forEachFeatureAtPixel(pixel,
- function(feature) {
- if (!this.features_ ||
- ol.array.includes(this.features_.getArray(), feature)) {
- return feature;
- }
- }.bind(this), {
- layerFilter: this.layerFilter_,
- hitTolerance: this.hitTolerance_
- });
- };
- /**
- * Returns the Hit-detection tolerance.
- * @returns {number} Hit tolerance in pixels.
- * @api
- */
- ol.interaction.Translate.prototype.getHitTolerance = function() {
- return this.hitTolerance_;
- };
- /**
- * Hit-detection tolerance. Pixels inside the radius around the given position
- * will be checked for features. This only works for the canvas renderer and
- * not for WebGL.
- * @param {number} hitTolerance Hit tolerance in pixels.
- * @api
- */
- ol.interaction.Translate.prototype.setHitTolerance = function(hitTolerance) {
- this.hitTolerance_ = hitTolerance;
- };
- /**
- * @inheritDoc
- */
- ol.interaction.Translate.prototype.setMap = function(map) {
- var oldMap = this.getMap();
- ol.interaction.Pointer.prototype.setMap.call(this, map);
- this.updateState_(oldMap);
- };
- /**
- * @private
- */
- ol.interaction.Translate.prototype.handleActiveChanged_ = function() {
- this.updateState_(null);
- };
- /**
- * @param {ol.PluggableMap} oldMap Old map.
- * @private
- */
- ol.interaction.Translate.prototype.updateState_ = function(oldMap) {
- var map = this.getMap();
- var active = this.getActive();
- if (!map || !active) {
- map = map || oldMap;
- if (map) {
- var elem = map.getViewport();
- elem.classList.remove('ol-grab', 'ol-grabbing');
- }
- }
- };
- /**
- * @classdesc
- * Events emitted by {@link ol.interaction.Translate} instances are instances of
- * this type.
- *
- * @constructor
- * @extends {ol.events.Event}
- * @implements {oli.interaction.TranslateEvent}
- * @param {ol.interaction.TranslateEventType} type Type.
- * @param {ol.Collection.<ol.Feature>} features The features translated.
- * @param {ol.Coordinate} coordinate The event coordinate.
- */
- ol.interaction.Translate.Event = function(type, features, coordinate) {
- ol.events.Event.call(this, type);
- /**
- * The features being translated.
- * @type {ol.Collection.<ol.Feature>}
- * @api
- */
- this.features = features;
- /**
- * The coordinate of the drag event.
- * @const
- * @type {ol.Coordinate}
- * @api
- */
- this.coordinate = coordinate;
- };
- ol.inherits(ol.interaction.Translate.Event, ol.events.Event);
- goog.provide('ol.layer.Heatmap');
- goog.require('ol.events');
- goog.require('ol');
- goog.require('ol.Object');
- goog.require('ol.dom');
- goog.require('ol.layer.Vector');
- goog.require('ol.math');
- goog.require('ol.obj');
- goog.require('ol.render.EventType');
- goog.require('ol.style.Icon');
- goog.require('ol.style.Style');
- /**
- * @classdesc
- * Layer for rendering vector data as a heatmap.
- * Note that any property set in the options is set as a {@link ol.Object}
- * property on the layer object; for example, setting `title: 'My Title'` in the
- * options means that `title` is observable, and has get/set accessors.
- *
- * @constructor
- * @extends {ol.layer.Vector}
- * @fires ol.render.Event
- * @param {olx.layer.HeatmapOptions=} opt_options Options.
- * @api
- */
- ol.layer.Heatmap = function(opt_options) {
- var options = opt_options ? opt_options : {};
- var baseOptions = ol.obj.assign({}, options);
- delete baseOptions.gradient;
- delete baseOptions.radius;
- delete baseOptions.blur;
- delete baseOptions.shadow;
- delete baseOptions.weight;
- ol.layer.Vector.call(this, /** @type {olx.layer.VectorOptions} */ (baseOptions));
- /**
- * @private
- * @type {Uint8ClampedArray}
- */
- this.gradient_ = null;
- /**
- * @private
- * @type {number}
- */
- this.shadow_ = options.shadow !== undefined ? options.shadow : 250;
- /**
- * @private
- * @type {string|undefined}
- */
- this.circleImage_ = undefined;
- /**
- * @private
- * @type {Array.<Array.<ol.style.Style>>}
- */
- this.styleCache_ = null;
- ol.events.listen(this,
- ol.Object.getChangeEventType(ol.layer.Heatmap.Property_.GRADIENT),
- this.handleGradientChanged_, this);
- this.setGradient(options.gradient ?
- options.gradient : ol.layer.Heatmap.DEFAULT_GRADIENT);
- this.setBlur(options.blur !== undefined ? options.blur : 15);
- this.setRadius(options.radius !== undefined ? options.radius : 8);
- ol.events.listen(this,
- ol.Object.getChangeEventType(ol.layer.Heatmap.Property_.BLUR),
- this.handleStyleChanged_, this);
- ol.events.listen(this,
- ol.Object.getChangeEventType(ol.layer.Heatmap.Property_.RADIUS),
- this.handleStyleChanged_, this);
- this.handleStyleChanged_();
- var weight = options.weight ? options.weight : 'weight';
- var weightFunction;
- if (typeof weight === 'string') {
- weightFunction = function(feature) {
- return feature.get(weight);
- };
- } else {
- weightFunction = weight;
- }
- this.setStyle(function(feature, resolution) {
- var weight = weightFunction(feature);
- var opacity = weight !== undefined ? ol.math.clamp(weight, 0, 1) : 1;
- // cast to 8 bits
- var index = (255 * opacity) | 0;
- var style = this.styleCache_[index];
- if (!style) {
- style = [
- new ol.style.Style({
- image: new ol.style.Icon({
- opacity: opacity,
- src: this.circleImage_
- })
- })
- ];
- this.styleCache_[index] = style;
- }
- return style;
- }.bind(this));
- // For performance reasons, don't sort the features before rendering.
- // The render order is not relevant for a heatmap representation.
- this.setRenderOrder(null);
- ol.events.listen(this, ol.render.EventType.RENDER, this.handleRender_, this);
- };
- ol.inherits(ol.layer.Heatmap, ol.layer.Vector);
- /**
- * @const
- * @type {Array.<string>}
- */
- ol.layer.Heatmap.DEFAULT_GRADIENT = ['#00f', '#0ff', '#0f0', '#ff0', '#f00'];
- /**
- * @param {Array.<string>} colors A list of colored.
- * @return {Uint8ClampedArray} An array.
- * @private
- */
- ol.layer.Heatmap.createGradient_ = function(colors) {
- var width = 1;
- var height = 256;
- var context = ol.dom.createCanvasContext2D(width, height);
- var gradient = context.createLinearGradient(0, 0, width, height);
- var step = 1 / (colors.length - 1);
- for (var i = 0, ii = colors.length; i < ii; ++i) {
- gradient.addColorStop(i * step, colors[i]);
- }
- context.fillStyle = gradient;
- context.fillRect(0, 0, width, height);
- return context.getImageData(0, 0, width, height).data;
- };
- /**
- * @return {string} Data URL for a circle.
- * @private
- */
- ol.layer.Heatmap.prototype.createCircle_ = function() {
- var radius = this.getRadius();
- var blur = this.getBlur();
- var halfSize = radius + blur + 1;
- var size = 2 * halfSize;
- var context = ol.dom.createCanvasContext2D(size, size);
- context.shadowOffsetX = context.shadowOffsetY = this.shadow_;
- context.shadowBlur = blur;
- context.shadowColor = '#000';
- context.beginPath();
- var center = halfSize - this.shadow_;
- context.arc(center, center, radius, 0, Math.PI * 2, true);
- context.fill();
- return context.canvas.toDataURL();
- };
- /**
- * Return the blur size in pixels.
- * @return {number} Blur size in pixels.
- * @api
- * @observable
- */
- ol.layer.Heatmap.prototype.getBlur = function() {
- return /** @type {number} */ (this.get(ol.layer.Heatmap.Property_.BLUR));
- };
- /**
- * Return the gradient colors as array of strings.
- * @return {Array.<string>} Colors.
- * @api
- * @observable
- */
- ol.layer.Heatmap.prototype.getGradient = function() {
- return /** @type {Array.<string>} */ (
- this.get(ol.layer.Heatmap.Property_.GRADIENT));
- };
- /**
- * Return the size of the radius in pixels.
- * @return {number} Radius size in pixel.
- * @api
- * @observable
- */
- ol.layer.Heatmap.prototype.getRadius = function() {
- return /** @type {number} */ (this.get(ol.layer.Heatmap.Property_.RADIUS));
- };
- /**
- * @private
- */
- ol.layer.Heatmap.prototype.handleGradientChanged_ = function() {
- this.gradient_ = ol.layer.Heatmap.createGradient_(this.getGradient());
- };
- /**
- * @private
- */
- ol.layer.Heatmap.prototype.handleStyleChanged_ = function() {
- this.circleImage_ = this.createCircle_();
- this.styleCache_ = new Array(256);
- this.changed();
- };
- /**
- * @param {ol.render.Event} event Post compose event
- * @private
- */
- ol.layer.Heatmap.prototype.handleRender_ = function(event) {
- var context = event.context;
- var canvas = context.canvas;
- var image = context.getImageData(0, 0, canvas.width, canvas.height);
- var view8 = image.data;
- var i, ii, alpha;
- for (i = 0, ii = view8.length; i < ii; i += 4) {
- alpha = view8[i + 3] * 4;
- if (alpha) {
- view8[i] = this.gradient_[alpha];
- view8[i + 1] = this.gradient_[alpha + 1];
- view8[i + 2] = this.gradient_[alpha + 2];
- }
- }
- context.putImageData(image, 0, 0);
- };
- /**
- * Set the blur size in pixels.
- * @param {number} blur Blur size in pixels.
- * @api
- * @observable
- */
- ol.layer.Heatmap.prototype.setBlur = function(blur) {
- this.set(ol.layer.Heatmap.Property_.BLUR, blur);
- };
- /**
- * Set the gradient colors as array of strings.
- * @param {Array.<string>} colors Gradient.
- * @api
- * @observable
- */
- ol.layer.Heatmap.prototype.setGradient = function(colors) {
- this.set(ol.layer.Heatmap.Property_.GRADIENT, colors);
- };
- /**
- * Set the size of the radius in pixels.
- * @param {number} radius Radius size in pixel.
- * @api
- * @observable
- */
- ol.layer.Heatmap.prototype.setRadius = function(radius) {
- this.set(ol.layer.Heatmap.Property_.RADIUS, radius);
- };
- /**
- * @enum {string}
- * @private
- */
- ol.layer.Heatmap.Property_ = {
- BLUR: 'blur',
- GRADIENT: 'gradient',
- RADIUS: 'radius'
- };
- goog.provide('ol.layer.Image');
- goog.require('ol');
- goog.require('ol.LayerType');
- goog.require('ol.layer.Layer');
- /**
- * @classdesc
- * Server-rendered images that are available for arbitrary extents and
- * resolutions.
- * Note that any property set in the options is set as a {@link ol.Object}
- * property on the layer object; for example, setting `title: 'My Title'` in the
- * options means that `title` is observable, and has get/set accessors.
- *
- * @constructor
- * @extends {ol.layer.Layer}
- * @fires ol.render.Event
- * @param {olx.layer.ImageOptions=} opt_options Layer options.
- * @api
- */
- ol.layer.Image = function(opt_options) {
- var options = opt_options ? opt_options : {};
- ol.layer.Layer.call(this, /** @type {olx.layer.LayerOptions} */ (options));
- /**
- * The layer type.
- * @protected
- * @type {ol.LayerType}
- */
- this.type = ol.LayerType.IMAGE;
- };
- ol.inherits(ol.layer.Image, ol.layer.Layer);
- /**
- * Return the associated {@link ol.source.Image source} of the image layer.
- * @function
- * @return {ol.source.Image} Source.
- * @api
- */
- ol.layer.Image.prototype.getSource;
- goog.provide('ol.layer.TileProperty');
- /**
- * @enum {string}
- */
- ol.layer.TileProperty = {
- PRELOAD: 'preload',
- USE_INTERIM_TILES_ON_ERROR: 'useInterimTilesOnError'
- };
- goog.provide('ol.layer.Tile');
- goog.require('ol');
- goog.require('ol.LayerType');
- goog.require('ol.layer.Layer');
- goog.require('ol.layer.TileProperty');
- goog.require('ol.obj');
- /**
- * @classdesc
- * For layer sources that provide pre-rendered, tiled images in grids that are
- * organized by zoom levels for specific resolutions.
- * Note that any property set in the options is set as a {@link ol.Object}
- * property on the layer object; for example, setting `title: 'My Title'` in the
- * options means that `title` is observable, and has get/set accessors.
- *
- * @constructor
- * @extends {ol.layer.Layer}
- * @fires ol.render.Event
- * @param {olx.layer.TileOptions=} opt_options Tile layer options.
- * @api
- */
- ol.layer.Tile = function(opt_options) {
- var options = opt_options ? opt_options : {};
- var baseOptions = ol.obj.assign({}, options);
- delete baseOptions.preload;
- delete baseOptions.useInterimTilesOnError;
- ol.layer.Layer.call(this, /** @type {olx.layer.LayerOptions} */ (baseOptions));
- this.setPreload(options.preload !== undefined ? options.preload : 0);
- this.setUseInterimTilesOnError(options.useInterimTilesOnError !== undefined ?
- options.useInterimTilesOnError : true);
- /**
- * The layer type.
- * @protected
- * @type {ol.LayerType}
- */
- this.type = ol.LayerType.TILE;
- };
- ol.inherits(ol.layer.Tile, ol.layer.Layer);
- /**
- * Return the level as number to which we will preload tiles up to.
- * @return {number} The level to preload tiles up to.
- * @observable
- * @api
- */
- ol.layer.Tile.prototype.getPreload = function() {
- return /** @type {number} */ (this.get(ol.layer.TileProperty.PRELOAD));
- };
- /**
- * Return the associated {@link ol.source.Tile tilesource} of the layer.
- * @function
- * @return {ol.source.Tile} Source.
- * @api
- */
- ol.layer.Tile.prototype.getSource;
- /**
- * Set the level as number to which we will preload tiles up to.
- * @param {number} preload The level to preload tiles up to.
- * @observable
- * @api
- */
- ol.layer.Tile.prototype.setPreload = function(preload) {
- this.set(ol.layer.TileProperty.PRELOAD, preload);
- };
- /**
- * Whether we use interim tiles on error.
- * @return {boolean} Use interim tiles on error.
- * @observable
- * @api
- */
- ol.layer.Tile.prototype.getUseInterimTilesOnError = function() {
- return /** @type {boolean} */ (
- this.get(ol.layer.TileProperty.USE_INTERIM_TILES_ON_ERROR));
- };
- /**
- * Set whether we use interim tiles on error.
- * @param {boolean} useInterimTilesOnError Use interim tiles on error.
- * @observable
- * @api
- */
- ol.layer.Tile.prototype.setUseInterimTilesOnError = function(useInterimTilesOnError) {
- this.set(
- ol.layer.TileProperty.USE_INTERIM_TILES_ON_ERROR, useInterimTilesOnError);
- };
- goog.provide('ol.layer.VectorTile');
- goog.require('ol');
- goog.require('ol.LayerType');
- goog.require('ol.asserts');
- goog.require('ol.layer.TileProperty');
- goog.require('ol.layer.Vector');
- goog.require('ol.layer.VectorTileRenderType');
- goog.require('ol.obj');
- /**
- * @classdesc
- * Layer for vector tile data that is rendered client-side.
- * Note that any property set in the options is set as a {@link ol.Object}
- * property on the layer object; for example, setting `title: 'My Title'` in the
- * options means that `title` is observable, and has get/set accessors.
- *
- * @constructor
- * @extends {ol.layer.Vector}
- * @param {olx.layer.VectorTileOptions=} opt_options Options.
- * @api
- */
- ol.layer.VectorTile = function(opt_options) {
- var options = opt_options ? opt_options : {};
- var renderMode = options.renderMode || ol.layer.VectorTileRenderType.HYBRID;
- ol.asserts.assert(renderMode == undefined ||
- renderMode == ol.layer.VectorTileRenderType.IMAGE ||
- renderMode == ol.layer.VectorTileRenderType.HYBRID ||
- renderMode == ol.layer.VectorTileRenderType.VECTOR,
- 28); // `renderMode` must be `'image'`, `'hybrid'` or `'vector'`
- if (options.declutter && renderMode == ol.layer.VectorTileRenderType.IMAGE) {
- renderMode = ol.layer.VectorTileRenderType.HYBRID;
- }
- options.renderMode = renderMode;
- var baseOptions = ol.obj.assign({}, options);
- delete baseOptions.preload;
- delete baseOptions.useInterimTilesOnError;
- ol.layer.Vector.call(this, /** @type {olx.layer.VectorOptions} */ (baseOptions));
- this.setPreload(options.preload ? options.preload : 0);
- this.setUseInterimTilesOnError(options.useInterimTilesOnError ?
- options.useInterimTilesOnError : true);
- /**
- * The layer type.
- * @protected
- * @type {ol.LayerType}
- */
- this.type = ol.LayerType.VECTOR_TILE;
- };
- ol.inherits(ol.layer.VectorTile, ol.layer.Vector);
- /**
- * Return the level as number to which we will preload tiles up to.
- * @return {number} The level to preload tiles up to.
- * @observable
- * @api
- */
- ol.layer.VectorTile.prototype.getPreload = function() {
- return /** @type {number} */ (this.get(ol.layer.TileProperty.PRELOAD));
- };
- /**
- * Whether we use interim tiles on error.
- * @return {boolean} Use interim tiles on error.
- * @observable
- * @api
- */
- ol.layer.VectorTile.prototype.getUseInterimTilesOnError = function() {
- return /** @type {boolean} */ (
- this.get(ol.layer.TileProperty.USE_INTERIM_TILES_ON_ERROR));
- };
- /**
- * Set the level as number to which we will preload tiles up to.
- * @param {number} preload The level to preload tiles up to.
- * @observable
- * @api
- */
- ol.layer.VectorTile.prototype.setPreload = function(preload) {
- this.set(ol.layer.TileProperty.PRELOAD, preload);
- };
- /**
- * Set whether we use interim tiles on error.
- * @param {boolean} useInterimTilesOnError Use interim tiles on error.
- * @observable
- * @api
- */
- ol.layer.VectorTile.prototype.setUseInterimTilesOnError = function(useInterimTilesOnError) {
- this.set(
- ol.layer.TileProperty.USE_INTERIM_TILES_ON_ERROR, useInterimTilesOnError);
- };
- /**
- * Return the associated {@link ol.source.VectorTile vectortilesource} of the layer.
- * @function
- * @return {ol.source.VectorTile} Source.
- * @api
- */
- ol.layer.VectorTile.prototype.getSource;
- goog.provide('ol.webgl.Shader');
- goog.require('ol.functions');
- /**
- * @constructor
- * @abstract
- * @param {string} source Source.
- * @struct
- */
- ol.webgl.Shader = function(source) {
- /**
- * @private
- * @type {string}
- */
- this.source_ = source;
- };
- /**
- * @abstract
- * @return {number} Type.
- */
- ol.webgl.Shader.prototype.getType = function() {};
- /**
- * @return {string} Source.
- */
- ol.webgl.Shader.prototype.getSource = function() {
- return this.source_;
- };
- /**
- * @return {boolean} Is animated?
- */
- ol.webgl.Shader.prototype.isAnimated = ol.functions.FALSE;
- goog.provide('ol.webgl.Fragment');
- goog.require('ol');
- goog.require('ol.webgl');
- goog.require('ol.webgl.Shader');
- /**
- * @constructor
- * @extends {ol.webgl.Shader}
- * @param {string} source Source.
- * @struct
- */
- ol.webgl.Fragment = function(source) {
- ol.webgl.Shader.call(this, source);
- };
- ol.inherits(ol.webgl.Fragment, ol.webgl.Shader);
- /**
- * @inheritDoc
- */
- ol.webgl.Fragment.prototype.getType = function() {
- return ol.webgl.FRAGMENT_SHADER;
- };
- goog.provide('ol.webgl.Vertex');
- goog.require('ol');
- goog.require('ol.webgl');
- goog.require('ol.webgl.Shader');
- /**
- * @constructor
- * @extends {ol.webgl.Shader}
- * @param {string} source Source.
- * @struct
- */
- ol.webgl.Vertex = function(source) {
- ol.webgl.Shader.call(this, source);
- };
- ol.inherits(ol.webgl.Vertex, ol.webgl.Shader);
- /**
- * @inheritDoc
- */
- ol.webgl.Vertex.prototype.getType = function() {
- return ol.webgl.VERTEX_SHADER;
- };
- // This file is automatically generated, do not edit
- goog.provide('ol.render.webgl.circlereplay.defaultshader');
- goog.require('ol');
- goog.require('ol.webgl.Fragment');
- goog.require('ol.webgl.Vertex');
- ol.render.webgl.circlereplay.defaultshader.fragment = new ol.webgl.Fragment(ol.DEBUG_WEBGL ?
- 'precision mediump float;\nvarying vec2 v_center;\nvarying vec2 v_offset;\nvarying float v_halfWidth;\nvarying float v_pixelRatio;\n\n\n\nuniform float u_opacity;\nuniform vec4 u_fillColor;\nuniform vec4 u_strokeColor;\nuniform vec2 u_size;\n\nvoid main(void) {\n vec2 windowCenter = vec2((v_center.x + 1.0) / 2.0 * u_size.x * v_pixelRatio,\n (v_center.y + 1.0) / 2.0 * u_size.y * v_pixelRatio);\n vec2 windowOffset = vec2((v_offset.x + 1.0) / 2.0 * u_size.x * v_pixelRatio,\n (v_offset.y + 1.0) / 2.0 * u_size.y * v_pixelRatio);\n float radius = length(windowCenter - windowOffset);\n float dist = length(windowCenter - gl_FragCoord.xy);\n if (dist > radius + v_halfWidth) {\n if (u_strokeColor.a == 0.0) {\n gl_FragColor = u_fillColor;\n } else {\n gl_FragColor = u_strokeColor;\n }\n gl_FragColor.a = gl_FragColor.a - (dist - (radius + v_halfWidth));\n } else if (u_fillColor.a == 0.0) {\n // Hooray, no fill, just stroke. We can use real antialiasing.\n gl_FragColor = u_strokeColor;\n if (dist < radius - v_halfWidth) {\n gl_FragColor.a = gl_FragColor.a - (radius - v_halfWidth - dist);\n }\n } else {\n gl_FragColor = u_fillColor;\n float strokeDist = radius - v_halfWidth;\n float antialias = 2.0 * v_pixelRatio;\n if (dist > strokeDist) {\n gl_FragColor = u_strokeColor;\n } else if (dist >= strokeDist - antialias) {\n float step = smoothstep(strokeDist - antialias, strokeDist, dist);\n gl_FragColor = mix(u_fillColor, u_strokeColor, step);\n }\n }\n gl_FragColor.a = gl_FragColor.a * u_opacity;\n if (gl_FragColor.a <= 0.0) {\n discard;\n }\n}\n' :
- 'precision mediump float;varying vec2 a;varying vec2 b;varying float c;varying float d;uniform float m;uniform vec4 n;uniform vec4 o;uniform vec2 p;void main(void){vec2 windowCenter=vec2((a.x+1.0)/2.0*p.x*d,(a.y+1.0)/2.0*p.y*d);vec2 windowOffset=vec2((b.x+1.0)/2.0*p.x*d,(b.y+1.0)/2.0*p.y*d);float radius=length(windowCenter-windowOffset);float dist=length(windowCenter-gl_FragCoord.xy);if(dist>radius+c){if(o.a==0.0){gl_FragColor=n;}else{gl_FragColor=o;}gl_FragColor.a=gl_FragColor.a-(dist-(radius+c));}else if(n.a==0.0){gl_FragColor=o;if(dist<radius-c){gl_FragColor.a=gl_FragColor.a-(radius-c-dist);}} else{gl_FragColor=n;float strokeDist=radius-c;float antialias=2.0*d;if(dist>strokeDist){gl_FragColor=o;}else if(dist>=strokeDist-antialias){float step=smoothstep(strokeDist-antialias,strokeDist,dist);gl_FragColor=mix(n,o,step);}} gl_FragColor.a=gl_FragColor.a*m;if(gl_FragColor.a<=0.0){discard;}}');
- ol.render.webgl.circlereplay.defaultshader.vertex = new ol.webgl.Vertex(ol.DEBUG_WEBGL ?
- 'varying vec2 v_center;\nvarying vec2 v_offset;\nvarying float v_halfWidth;\nvarying float v_pixelRatio;\n\n\nattribute vec2 a_position;\nattribute float a_instruction;\nattribute float a_radius;\n\nuniform mat4 u_projectionMatrix;\nuniform mat4 u_offsetScaleMatrix;\nuniform mat4 u_offsetRotateMatrix;\nuniform float u_lineWidth;\nuniform float u_pixelRatio;\n\nvoid main(void) {\n mat4 offsetMatrix = u_offsetScaleMatrix * u_offsetRotateMatrix;\n v_center = vec4(u_projectionMatrix * vec4(a_position, 0.0, 1.0)).xy;\n v_pixelRatio = u_pixelRatio;\n float lineWidth = u_lineWidth * u_pixelRatio;\n v_halfWidth = lineWidth / 2.0;\n if (lineWidth == 0.0) {\n lineWidth = 2.0 * u_pixelRatio;\n }\n vec2 offset;\n // Radius with anitaliasing (roughly).\n float radius = a_radius + 3.0 * u_pixelRatio;\n // Until we get gl_VertexID in WebGL, we store an instruction.\n if (a_instruction == 0.0) {\n // Offsetting the edges of the triangle by lineWidth / 2 is necessary, however\n // we should also leave some space for the antialiasing, thus we offset by lineWidth.\n offset = vec2(-1.0, 1.0);\n } else if (a_instruction == 1.0) {\n offset = vec2(-1.0, -1.0);\n } else if (a_instruction == 2.0) {\n offset = vec2(1.0, -1.0);\n } else {\n offset = vec2(1.0, 1.0);\n }\n\n gl_Position = u_projectionMatrix * vec4(a_position + offset * radius, 0.0, 1.0) +\n offsetMatrix * vec4(offset * lineWidth, 0.0, 0.0);\n v_offset = vec4(u_projectionMatrix * vec4(a_position.x + a_radius, a_position.y,\n 0.0, 1.0)).xy;\n\n if (distance(v_center, v_offset) > 20000.0) {\n gl_Position = vec4(v_center, 0.0, 1.0);\n }\n}\n\n\n' :
- 'varying vec2 a;varying vec2 b;varying float c;varying float d;attribute vec2 e;attribute float f;attribute float g;uniform mat4 h;uniform mat4 i;uniform mat4 j;uniform float k;uniform float l;void main(void){mat4 offsetMatrix=i*j;a=vec4(h*vec4(e,0.0,1.0)).xy;d=l;float lineWidth=k*l;c=lineWidth/2.0;if(lineWidth==0.0){lineWidth=2.0*l;}vec2 offset;float radius=g+3.0*l;//Until we get gl_VertexID in WebGL,we store an instruction.if(f==0.0){//Offsetting the edges of the triangle by lineWidth/2 is necessary,however//we should also leave some space for the antialiasing,thus we offset by lineWidth.offset=vec2(-1.0,1.0);}else if(f==1.0){offset=vec2(-1.0,-1.0);}else if(f==2.0){offset=vec2(1.0,-1.0);}else{offset=vec2(1.0,1.0);}gl_Position=h*vec4(e+offset*radius,0.0,1.0)+offsetMatrix*vec4(offset*lineWidth,0.0,0.0);b=vec4(h*vec4(e.x+g,e.y,0.0,1.0)).xy;if(distance(a,b)>20000.0){gl_Position=vec4(a,0.0,1.0);}}');
- // This file is automatically generated, do not edit
- goog.provide('ol.render.webgl.circlereplay.defaultshader.Locations');
- goog.require('ol');
- /**
- * @constructor
- * @param {WebGLRenderingContext} gl GL.
- * @param {WebGLProgram} program Program.
- * @struct
- */
- ol.render.webgl.circlereplay.defaultshader.Locations = function(gl, program) {
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_projectionMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_offsetScaleMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_offsetRotateMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_lineWidth = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_lineWidth' : 'k');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_pixelRatio = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_pixelRatio' : 'l');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_opacity = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_opacity' : 'm');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_fillColor = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_fillColor' : 'n');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_strokeColor = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_strokeColor' : 'o');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_size = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_size' : 'p');
- /**
- * @type {number}
- */
- this.a_position = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_position' : 'e');
- /**
- * @type {number}
- */
- this.a_instruction = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_instruction' : 'f');
- /**
- * @type {number}
- */
- this.a_radius = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_radius' : 'g');
- };
- goog.provide('ol.vec.Mat4');
- /**
- * @return {Array.<number>} 4x4 matrix representing a 3D identity transform.
- */
- ol.vec.Mat4.create = function() {
- return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
- };
- /**
- * @param {Array.<number>} mat4 Flattened 4x4 matrix receiving the result.
- * @param {ol.Transform} transform Transformation matrix.
- * @return {Array.<number>} 2D transformation matrix as flattened 4x4 matrix.
- */
- ol.vec.Mat4.fromTransform = function(mat4, transform) {
- mat4[0] = transform[0];
- mat4[1] = transform[1];
- mat4[4] = transform[2];
- mat4[5] = transform[3];
- mat4[12] = transform[4];
- mat4[13] = transform[5];
- return mat4;
- };
- goog.provide('ol.render.webgl.Replay');
- goog.require('ol');
- goog.require('ol.extent');
- goog.require('ol.render.VectorContext');
- goog.require('ol.transform');
- goog.require('ol.vec.Mat4');
- goog.require('ol.webgl');
- /**
- * @constructor
- * @abstract
- * @extends {ol.render.VectorContext}
- * @param {number} tolerance Tolerance.
- * @param {ol.Extent} maxExtent Max extent.
- * @struct
- */
- ol.render.webgl.Replay = function(tolerance, maxExtent) {
- ol.render.VectorContext.call(this);
- /**
- * @protected
- * @type {number}
- */
- this.tolerance = tolerance;
- /**
- * @protected
- * @const
- * @type {ol.Extent}
- */
- this.maxExtent = maxExtent;
- /**
- * The origin of the coordinate system for the point coordinates sent to
- * the GPU. To eliminate jitter caused by precision problems in the GPU
- * we use the "Rendering Relative to Eye" technique described in the "3D
- * Engine Design for Virtual Globes" book.
- * @protected
- * @type {ol.Coordinate}
- */
- this.origin = ol.extent.getCenter(maxExtent);
- /**
- * @private
- * @type {ol.Transform}
- */
- this.projectionMatrix_ = ol.transform.create();
- /**
- * @private
- * @type {ol.Transform}
- */
- this.offsetRotateMatrix_ = ol.transform.create();
- /**
- * @private
- * @type {ol.Transform}
- */
- this.offsetScaleMatrix_ = ol.transform.create();
- /**
- * @private
- * @type {Array.<number>}
- */
- this.tmpMat4_ = ol.vec.Mat4.create();
- /**
- * @protected
- * @type {Array.<number>}
- */
- this.indices = [];
- /**
- * @protected
- * @type {?ol.webgl.Buffer}
- */
- this.indicesBuffer = null;
- /**
- * Start index per feature (the index).
- * @protected
- * @type {Array.<number>}
- */
- this.startIndices = [];
- /**
- * Start index per feature (the feature).
- * @protected
- * @type {Array.<ol.Feature|ol.render.Feature>}
- */
- this.startIndicesFeature = [];
- /**
- * @protected
- * @type {Array.<number>}
- */
- this.vertices = [];
- /**
- * @protected
- * @type {?ol.webgl.Buffer}
- */
- this.verticesBuffer = null;
- /**
- * Optional parameter for PolygonReplay instances.
- * @protected
- * @type {ol.render.webgl.LineStringReplay|undefined}
- */
- this.lineStringReplay = undefined;
- };
- ol.inherits(ol.render.webgl.Replay, ol.render.VectorContext);
- /**
- * @abstract
- * @param {ol.webgl.Context} context WebGL context.
- * @return {function()} Delete resources function.
- */
- ol.render.webgl.Replay.prototype.getDeleteResourcesFunction = function(context) {};
- /**
- * @abstract
- * @param {ol.webgl.Context} context Context.
- */
- ol.render.webgl.Replay.prototype.finish = function(context) {};
- /**
- * @abstract
- * @protected
- * @param {WebGLRenderingContext} gl gl.
- * @param {ol.webgl.Context} context Context.
- * @param {ol.Size} size Size.
- * @param {number} pixelRatio Pixel ratio.
- * @return {ol.render.webgl.circlereplay.defaultshader.Locations|
- ol.render.webgl.linestringreplay.defaultshader.Locations|
- ol.render.webgl.polygonreplay.defaultshader.Locations|
- ol.render.webgl.texturereplay.defaultshader.Locations} Locations.
- */
- ol.render.webgl.Replay.prototype.setUpProgram = function(gl, context, size, pixelRatio) {};
- /**
- * @abstract
- * @protected
- * @param {WebGLRenderingContext} gl gl.
- * @param {ol.render.webgl.circlereplay.defaultshader.Locations|
- ol.render.webgl.linestringreplay.defaultshader.Locations|
- ol.render.webgl.polygonreplay.defaultshader.Locations|
- ol.render.webgl.texturereplay.defaultshader.Locations} locations Locations.
- */
- ol.render.webgl.Replay.prototype.shutDownProgram = function(gl, locations) {};
- /**
- * @abstract
- * @protected
- * @param {WebGLRenderingContext} gl gl.
- * @param {ol.webgl.Context} context Context.
- * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
- * to skip.
- * @param {boolean} hitDetection Hit detection mode.
- */
- ol.render.webgl.Replay.prototype.drawReplay = function(gl, context, skippedFeaturesHash, hitDetection) {};
- /**
- * @abstract
- * @protected
- * @param {WebGLRenderingContext} gl gl.
- * @param {ol.webgl.Context} context Context.
- * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
- * to skip.
- * @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback.
- * @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
- * this extent are checked.
- * @return {T|undefined} Callback result.
- * @template T
- */
- ol.render.webgl.Replay.prototype.drawHitDetectionReplayOneByOne = function(gl, context, skippedFeaturesHash, featureCallback, opt_hitExtent) {};
- /**
- * @protected
- * @param {WebGLRenderingContext} gl gl.
- * @param {ol.webgl.Context} context Context.
- * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
- * to skip.
- * @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback.
- * @param {boolean} oneByOne Draw features one-by-one for the hit-detecion.
- * @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
- * this extent are checked.
- * @return {T|undefined} Callback result.
- * @template T
- */
- ol.render.webgl.Replay.prototype.drawHitDetectionReplay = function(gl, context, skippedFeaturesHash,
- featureCallback, oneByOne, opt_hitExtent) {
- if (!oneByOne) {
- // draw all hit-detection features in "once" (by texture group)
- return this.drawHitDetectionReplayAll(gl, context,
- skippedFeaturesHash, featureCallback);
- } else {
- // draw hit-detection features one by one
- return this.drawHitDetectionReplayOneByOne(gl, context,
- skippedFeaturesHash, featureCallback, opt_hitExtent);
- }
- };
- /**
- * @protected
- * @param {WebGLRenderingContext} gl gl.
- * @param {ol.webgl.Context} context Context.
- * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
- * to skip.
- * @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback.
- * @return {T|undefined} Callback result.
- * @template T
- */
- ol.render.webgl.Replay.prototype.drawHitDetectionReplayAll = function(gl, context, skippedFeaturesHash,
- featureCallback) {
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
- this.drawReplay(gl, context, skippedFeaturesHash, true);
- var result = featureCallback(null);
- if (result) {
- return result;
- } else {
- return undefined;
- }
- };
- /**
- * @param {ol.webgl.Context} context Context.
- * @param {ol.Coordinate} center Center.
- * @param {number} resolution Resolution.
- * @param {number} rotation Rotation.
- * @param {ol.Size} size Size.
- * @param {number} pixelRatio Pixel ratio.
- * @param {number} opacity Global opacity.
- * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
- * to skip.
- * @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback.
- * @param {boolean} oneByOne Draw features one-by-one for the hit-detecion.
- * @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
- * this extent are checked.
- * @return {T|undefined} Callback result.
- * @template T
- */
- ol.render.webgl.Replay.prototype.replay = function(context,
- center, resolution, rotation, size, pixelRatio,
- opacity, skippedFeaturesHash,
- featureCallback, oneByOne, opt_hitExtent) {
- var gl = context.getGL();
- var tmpStencil, tmpStencilFunc, tmpStencilMaskVal, tmpStencilRef, tmpStencilMask,
- tmpStencilOpFail, tmpStencilOpPass, tmpStencilOpZFail;
- if (this.lineStringReplay) {
- tmpStencil = gl.isEnabled(gl.STENCIL_TEST);
- tmpStencilFunc = gl.getParameter(gl.STENCIL_FUNC);
- tmpStencilMaskVal = gl.getParameter(gl.STENCIL_VALUE_MASK);
- tmpStencilRef = gl.getParameter(gl.STENCIL_REF);
- tmpStencilMask = gl.getParameter(gl.STENCIL_WRITEMASK);
- tmpStencilOpFail = gl.getParameter(gl.STENCIL_FAIL);
- tmpStencilOpPass = gl.getParameter(gl.STENCIL_PASS_DEPTH_PASS);
- tmpStencilOpZFail = gl.getParameter(gl.STENCIL_PASS_DEPTH_FAIL);
- gl.enable(gl.STENCIL_TEST);
- gl.clear(gl.STENCIL_BUFFER_BIT);
- gl.stencilMask(255);
- gl.stencilFunc(gl.ALWAYS, 1, 255);
- gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
- this.lineStringReplay.replay(context,
- center, resolution, rotation, size, pixelRatio,
- opacity, skippedFeaturesHash,
- featureCallback, oneByOne, opt_hitExtent);
- gl.stencilMask(0);
- gl.stencilFunc(gl.NOTEQUAL, 1, 255);
- }
- context.bindBuffer(ol.webgl.ARRAY_BUFFER, this.verticesBuffer);
- context.bindBuffer(ol.webgl.ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
- var locations = this.setUpProgram(gl, context, size, pixelRatio);
- // set the "uniform" values
- var projectionMatrix = ol.transform.reset(this.projectionMatrix_);
- ol.transform.scale(projectionMatrix, 2 / (resolution * size[0]), 2 / (resolution * size[1]));
- ol.transform.rotate(projectionMatrix, -rotation);
- ol.transform.translate(projectionMatrix, -(center[0] - this.origin[0]), -(center[1] - this.origin[1]));
- var offsetScaleMatrix = ol.transform.reset(this.offsetScaleMatrix_);
- ol.transform.scale(offsetScaleMatrix, 2 / size[0], 2 / size[1]);
- var offsetRotateMatrix = ol.transform.reset(this.offsetRotateMatrix_);
- if (rotation !== 0) {
- ol.transform.rotate(offsetRotateMatrix, -rotation);
- }
- gl.uniformMatrix4fv(locations.u_projectionMatrix, false,
- ol.vec.Mat4.fromTransform(this.tmpMat4_, projectionMatrix));
- gl.uniformMatrix4fv(locations.u_offsetScaleMatrix, false,
- ol.vec.Mat4.fromTransform(this.tmpMat4_, offsetScaleMatrix));
- gl.uniformMatrix4fv(locations.u_offsetRotateMatrix, false,
- ol.vec.Mat4.fromTransform(this.tmpMat4_, offsetRotateMatrix));
- gl.uniform1f(locations.u_opacity, opacity);
- // draw!
- var result;
- if (featureCallback === undefined) {
- this.drawReplay(gl, context, skippedFeaturesHash, false);
- } else {
- // draw feature by feature for the hit-detection
- result = this.drawHitDetectionReplay(gl, context, skippedFeaturesHash,
- featureCallback, oneByOne, opt_hitExtent);
- }
- // disable the vertex attrib arrays
- this.shutDownProgram(gl, locations);
- if (this.lineStringReplay) {
- if (!tmpStencil) {
- gl.disable(gl.STENCIL_TEST);
- }
- gl.clear(gl.STENCIL_BUFFER_BIT);
- gl.stencilFunc(/** @type {number} */ (tmpStencilFunc),
- /** @type {number} */ (tmpStencilRef), /** @type {number} */ (tmpStencilMaskVal));
- gl.stencilMask(/** @type {number} */ (tmpStencilMask));
- gl.stencilOp(/** @type {number} */ (tmpStencilOpFail),
- /** @type {number} */ (tmpStencilOpZFail), /** @type {number} */ (tmpStencilOpPass));
- }
- return result;
- };
- /**
- * @protected
- * @param {WebGLRenderingContext} gl gl.
- * @param {ol.webgl.Context} context Context.
- * @param {number} start Start index.
- * @param {number} end End index.
- */
- ol.render.webgl.Replay.prototype.drawElements = function(
- gl, context, start, end) {
- var elementType = context.hasOESElementIndexUint ?
- ol.webgl.UNSIGNED_INT : ol.webgl.UNSIGNED_SHORT;
- var elementSize = context.hasOESElementIndexUint ? 4 : 2;
- var numItems = end - start;
- var offsetInBytes = start * elementSize;
- gl.drawElements(ol.webgl.TRIANGLES, numItems, elementType, offsetInBytes);
- };
- goog.provide('ol.render.webgl');
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.defaultFont = '10px sans-serif';
- /**
- * @const
- * @type {ol.Color}
- */
- ol.render.webgl.defaultFillStyle = [0.0, 0.0, 0.0, 1.0];
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.defaultLineCap = 'round';
- /**
- * @const
- * @type {Array.<number>}
- */
- ol.render.webgl.defaultLineDash = [];
- /**
- * @const
- * @type {number}
- */
- ol.render.webgl.defaultLineDashOffset = 0;
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.defaultLineJoin = 'round';
- /**
- * @const
- * @type {number}
- */
- ol.render.webgl.defaultMiterLimit = 10;
- /**
- * @const
- * @type {ol.Color}
- */
- ol.render.webgl.defaultStrokeStyle = [0.0, 0.0, 0.0, 1.0];
- /**
- * @const
- * @type {number}
- */
- ol.render.webgl.defaultTextAlign = 0.5;
- /**
- * @const
- * @type {number}
- */
- ol.render.webgl.defaultTextBaseline = 0.5;
- /**
- * @const
- * @type {number}
- */
- ol.render.webgl.defaultLineWidth = 1;
- /**
- * Calculates the orientation of a triangle based on the determinant method.
- * @param {number} x1 First X coordinate.
- * @param {number} y1 First Y coordinate.
- * @param {number} x2 Second X coordinate.
- * @param {number} y2 Second Y coordinate.
- * @param {number} x3 Third X coordinate.
- * @param {number} y3 Third Y coordinate.
- * @return {boolean|undefined} Triangle is clockwise.
- */
- ol.render.webgl.triangleIsCounterClockwise = function(x1, y1, x2, y2, x3, y3) {
- var area = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1);
- return (area <= ol.render.webgl.EPSILON && area >= -ol.render.webgl.EPSILON) ?
- undefined : area > 0;
- };
- /**
- * @const
- * @type {number}
- */
- ol.render.webgl.EPSILON = Number.EPSILON || 2.220446049250313e-16;
- goog.provide('ol.webgl.Buffer');
- goog.require('ol.webgl');
- /**
- * @constructor
- * @param {Array.<number>=} opt_arr Array.
- * @param {number=} opt_usage Usage.
- * @struct
- */
- ol.webgl.Buffer = function(opt_arr, opt_usage) {
- /**
- * @private
- * @type {Array.<number>}
- */
- this.arr_ = opt_arr !== undefined ? opt_arr : [];
- /**
- * @private
- * @type {number}
- */
- this.usage_ = opt_usage !== undefined ?
- opt_usage : ol.webgl.Buffer.Usage_.STATIC_DRAW;
- };
- /**
- * @return {Array.<number>} Array.
- */
- ol.webgl.Buffer.prototype.getArray = function() {
- return this.arr_;
- };
- /**
- * @return {number} Usage.
- */
- ol.webgl.Buffer.prototype.getUsage = function() {
- return this.usage_;
- };
- /**
- * @enum {number}
- * @private
- */
- ol.webgl.Buffer.Usage_ = {
- STATIC_DRAW: ol.webgl.STATIC_DRAW,
- STREAM_DRAW: ol.webgl.STREAM_DRAW,
- DYNAMIC_DRAW: ol.webgl.DYNAMIC_DRAW
- };
- goog.provide('ol.render.webgl.CircleReplay');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.color');
- goog.require('ol.extent');
- goog.require('ol.obj');
- goog.require('ol.geom.flat.transform');
- goog.require('ol.render.webgl.circlereplay.defaultshader');
- goog.require('ol.render.webgl.circlereplay.defaultshader.Locations');
- goog.require('ol.render.webgl.Replay');
- goog.require('ol.render.webgl');
- goog.require('ol.webgl');
- goog.require('ol.webgl.Buffer');
- /**
- * @constructor
- * @extends {ol.render.webgl.Replay}
- * @param {number} tolerance Tolerance.
- * @param {ol.Extent} maxExtent Max extent.
- * @struct
- */
- ol.render.webgl.CircleReplay = function(tolerance, maxExtent) {
- ol.render.webgl.Replay.call(this, tolerance, maxExtent);
- /**
- * @private
- * @type {ol.render.webgl.circlereplay.defaultshader.Locations}
- */
- this.defaultLocations_ = null;
- /**
- * @private
- * @type {Array.<Array.<Array.<number>|number>>}
- */
- this.styles_ = [];
- /**
- * @private
- * @type {Array.<number>}
- */
- this.styleIndices_ = [];
- /**
- * @private
- * @type {number}
- */
- this.radius_ = 0;
- /**
- * @private
- * @type {{fillColor: (Array.<number>|null),
- * strokeColor: (Array.<number>|null),
- * lineDash: Array.<number>,
- * lineDashOffset: (number|undefined),
- * lineWidth: (number|undefined),
- * changed: boolean}|null}
- */
- this.state_ = {
- fillColor: null,
- strokeColor: null,
- lineDash: null,
- lineDashOffset: undefined,
- lineWidth: undefined,
- changed: false
- };
- };
- ol.inherits(ol.render.webgl.CircleReplay, ol.render.webgl.Replay);
- /**
- * @private
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- */
- ol.render.webgl.CircleReplay.prototype.drawCoordinates_ = function(
- flatCoordinates, offset, end, stride) {
- var numVertices = this.vertices.length;
- var numIndices = this.indices.length;
- var n = numVertices / 4;
- var i, ii;
- for (i = offset, ii = end; i < ii; i += stride) {
- this.vertices[numVertices++] = flatCoordinates[i];
- this.vertices[numVertices++] = flatCoordinates[i + 1];
- this.vertices[numVertices++] = 0;
- this.vertices[numVertices++] = this.radius_;
- this.vertices[numVertices++] = flatCoordinates[i];
- this.vertices[numVertices++] = flatCoordinates[i + 1];
- this.vertices[numVertices++] = 1;
- this.vertices[numVertices++] = this.radius_;
- this.vertices[numVertices++] = flatCoordinates[i];
- this.vertices[numVertices++] = flatCoordinates[i + 1];
- this.vertices[numVertices++] = 2;
- this.vertices[numVertices++] = this.radius_;
- this.vertices[numVertices++] = flatCoordinates[i];
- this.vertices[numVertices++] = flatCoordinates[i + 1];
- this.vertices[numVertices++] = 3;
- this.vertices[numVertices++] = this.radius_;
- this.indices[numIndices++] = n;
- this.indices[numIndices++] = n + 1;
- this.indices[numIndices++] = n + 2;
- this.indices[numIndices++] = n + 2;
- this.indices[numIndices++] = n + 3;
- this.indices[numIndices++] = n;
- n += 4;
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.CircleReplay.prototype.drawCircle = function(circleGeometry, feature) {
- var radius = circleGeometry.getRadius();
- var stride = circleGeometry.getStride();
- if (radius) {
- this.startIndices.push(this.indices.length);
- this.startIndicesFeature.push(feature);
- if (this.state_.changed) {
- this.styleIndices_.push(this.indices.length);
- this.state_.changed = false;
- }
- this.radius_ = radius;
- var flatCoordinates = circleGeometry.getFlatCoordinates();
- flatCoordinates = ol.geom.flat.transform.translate(flatCoordinates, 0, 2,
- stride, -this.origin[0], -this.origin[1]);
- this.drawCoordinates_(flatCoordinates, 0, 2, stride);
- } else {
- if (this.state_.changed) {
- this.styles_.pop();
- if (this.styles_.length) {
- var lastState = this.styles_[this.styles_.length - 1];
- this.state_.fillColor = /** @type {Array.<number>} */ (lastState[0]);
- this.state_.strokeColor = /** @type {Array.<number>} */ (lastState[1]);
- this.state_.lineWidth = /** @type {number} */ (lastState[2]);
- this.state_.changed = false;
- }
- }
- }
- };
- /**
- * @inheritDoc
- **/
- ol.render.webgl.CircleReplay.prototype.finish = function(context) {
- // create, bind, and populate the vertices buffer
- this.verticesBuffer = new ol.webgl.Buffer(this.vertices);
- // create, bind, and populate the indices buffer
- this.indicesBuffer = new ol.webgl.Buffer(this.indices);
- this.startIndices.push(this.indices.length);
- //Clean up, if there is nothing to draw
- if (this.styleIndices_.length === 0 && this.styles_.length > 0) {
- this.styles_ = [];
- }
- this.vertices = null;
- this.indices = null;
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.CircleReplay.prototype.getDeleteResourcesFunction = function(context) {
- // We only delete our stuff here. The shaders and the program may
- // be used by other CircleReplay instances (for other layers). And
- // they will be deleted when disposing of the ol.webgl.Context
- // object.
- var verticesBuffer = this.verticesBuffer;
- var indicesBuffer = this.indicesBuffer;
- return function() {
- context.deleteBuffer(verticesBuffer);
- context.deleteBuffer(indicesBuffer);
- };
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.CircleReplay.prototype.setUpProgram = function(gl, context, size, pixelRatio) {
- // get the program
- var fragmentShader, vertexShader;
- fragmentShader = ol.render.webgl.circlereplay.defaultshader.fragment;
- vertexShader = ol.render.webgl.circlereplay.defaultshader.vertex;
- var program = context.getProgram(fragmentShader, vertexShader);
- // get the locations
- var locations;
- if (!this.defaultLocations_) {
- locations = new ol.render.webgl.circlereplay.defaultshader.Locations(gl, program);
- this.defaultLocations_ = locations;
- } else {
- locations = this.defaultLocations_;
- }
- context.useProgram(program);
- // enable the vertex attrib arrays
- gl.enableVertexAttribArray(locations.a_position);
- gl.vertexAttribPointer(locations.a_position, 2, ol.webgl.FLOAT,
- false, 16, 0);
- gl.enableVertexAttribArray(locations.a_instruction);
- gl.vertexAttribPointer(locations.a_instruction, 1, ol.webgl.FLOAT,
- false, 16, 8);
- gl.enableVertexAttribArray(locations.a_radius);
- gl.vertexAttribPointer(locations.a_radius, 1, ol.webgl.FLOAT,
- false, 16, 12);
- // Enable renderer specific uniforms.
- gl.uniform2fv(locations.u_size, size);
- gl.uniform1f(locations.u_pixelRatio, pixelRatio);
- return locations;
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.CircleReplay.prototype.shutDownProgram = function(gl, locations) {
- gl.disableVertexAttribArray(locations.a_position);
- gl.disableVertexAttribArray(locations.a_instruction);
- gl.disableVertexAttribArray(locations.a_radius);
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.CircleReplay.prototype.drawReplay = function(gl, context, skippedFeaturesHash, hitDetection) {
- if (!ol.obj.isEmpty(skippedFeaturesHash)) {
- this.drawReplaySkipping_(gl, context, skippedFeaturesHash);
- } else {
- //Draw by style groups to minimize drawElements() calls.
- var i, start, end, nextStyle;
- end = this.startIndices[this.startIndices.length - 1];
- for (i = this.styleIndices_.length - 1; i >= 0; --i) {
- start = this.styleIndices_[i];
- nextStyle = this.styles_[i];
- this.setFillStyle_(gl, /** @type {Array.<number>} */ (nextStyle[0]));
- this.setStrokeStyle_(gl, /** @type {Array.<number>} */ (nextStyle[1]),
- /** @type {number} */ (nextStyle[2]));
- this.drawElements(gl, context, start, end);
- end = start;
- }
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.CircleReplay.prototype.drawHitDetectionReplayOneByOne = function(gl, context, skippedFeaturesHash,
- featureCallback, opt_hitExtent) {
- var i, start, end, nextStyle, groupStart, feature, featureUid, featureIndex;
- featureIndex = this.startIndices.length - 2;
- end = this.startIndices[featureIndex + 1];
- for (i = this.styleIndices_.length - 1; i >= 0; --i) {
- nextStyle = this.styles_[i];
- this.setFillStyle_(gl, /** @type {Array.<number>} */ (nextStyle[0]));
- this.setStrokeStyle_(gl, /** @type {Array.<number>} */ (nextStyle[1]),
- /** @type {number} */ (nextStyle[2]));
- groupStart = this.styleIndices_[i];
- while (featureIndex >= 0 &&
- this.startIndices[featureIndex] >= groupStart) {
- start = this.startIndices[featureIndex];
- feature = this.startIndicesFeature[featureIndex];
- featureUid = ol.getUid(feature).toString();
- if (skippedFeaturesHash[featureUid] === undefined &&
- feature.getGeometry() &&
- (opt_hitExtent === undefined || ol.extent.intersects(
- /** @type {Array<number>} */ (opt_hitExtent),
- feature.getGeometry().getExtent()))) {
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
- this.drawElements(gl, context, start, end);
- var result = featureCallback(feature);
- if (result) {
- return result;
- }
- }
- featureIndex--;
- end = start;
- }
- }
- return undefined;
- };
- /**
- * @private
- * @param {WebGLRenderingContext} gl gl.
- * @param {ol.webgl.Context} context Context.
- * @param {Object} skippedFeaturesHash Ids of features to skip.
- */
- ol.render.webgl.CircleReplay.prototype.drawReplaySkipping_ = function(gl, context, skippedFeaturesHash) {
- var i, start, end, nextStyle, groupStart, feature, featureUid, featureIndex, featureStart;
- featureIndex = this.startIndices.length - 2;
- end = start = this.startIndices[featureIndex + 1];
- for (i = this.styleIndices_.length - 1; i >= 0; --i) {
- nextStyle = this.styles_[i];
- this.setFillStyle_(gl, /** @type {Array.<number>} */ (nextStyle[0]));
- this.setStrokeStyle_(gl, /** @type {Array.<number>} */ (nextStyle[1]),
- /** @type {number} */ (nextStyle[2]));
- groupStart = this.styleIndices_[i];
- while (featureIndex >= 0 &&
- this.startIndices[featureIndex] >= groupStart) {
- featureStart = this.startIndices[featureIndex];
- feature = this.startIndicesFeature[featureIndex];
- featureUid = ol.getUid(feature).toString();
- if (skippedFeaturesHash[featureUid]) {
- if (start !== end) {
- this.drawElements(gl, context, start, end);
- }
- end = featureStart;
- }
- featureIndex--;
- start = featureStart;
- }
- if (start !== end) {
- this.drawElements(gl, context, start, end);
- }
- start = end = groupStart;
- }
- };
- /**
- * @private
- * @param {WebGLRenderingContext} gl gl.
- * @param {Array.<number>} color Color.
- */
- ol.render.webgl.CircleReplay.prototype.setFillStyle_ = function(gl, color) {
- gl.uniform4fv(this.defaultLocations_.u_fillColor, color);
- };
- /**
- * @private
- * @param {WebGLRenderingContext} gl gl.
- * @param {Array.<number>} color Color.
- * @param {number} lineWidth Line width.
- */
- ol.render.webgl.CircleReplay.prototype.setStrokeStyle_ = function(gl, color, lineWidth) {
- gl.uniform4fv(this.defaultLocations_.u_strokeColor, color);
- gl.uniform1f(this.defaultLocations_.u_lineWidth, lineWidth);
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.CircleReplay.prototype.setFillStrokeStyle = function(fillStyle, strokeStyle) {
- var strokeStyleColor, strokeStyleWidth;
- if (strokeStyle) {
- var strokeStyleLineDash = strokeStyle.getLineDash();
- this.state_.lineDash = strokeStyleLineDash ?
- strokeStyleLineDash : ol.render.webgl.defaultLineDash;
- var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();
- this.state_.lineDashOffset = strokeStyleLineDashOffset ?
- strokeStyleLineDashOffset : ol.render.webgl.defaultLineDashOffset;
- strokeStyleColor = strokeStyle.getColor();
- if (!(strokeStyleColor instanceof CanvasGradient) &&
- !(strokeStyleColor instanceof CanvasPattern)) {
- strokeStyleColor = ol.color.asArray(strokeStyleColor).map(function(c, i) {
- return i != 3 ? c / 255 : c;
- }) || ol.render.webgl.defaultStrokeStyle;
- } else {
- strokeStyleColor = ol.render.webgl.defaultStrokeStyle;
- }
- strokeStyleWidth = strokeStyle.getWidth();
- strokeStyleWidth = strokeStyleWidth !== undefined ?
- strokeStyleWidth : ol.render.webgl.defaultLineWidth;
- } else {
- strokeStyleColor = [0, 0, 0, 0];
- strokeStyleWidth = 0;
- }
- var fillStyleColor = fillStyle ? fillStyle.getColor() : [0, 0, 0, 0];
- if (!(fillStyleColor instanceof CanvasGradient) &&
- !(fillStyleColor instanceof CanvasPattern)) {
- fillStyleColor = ol.color.asArray(fillStyleColor).map(function(c, i) {
- return i != 3 ? c / 255 : c;
- }) || ol.render.webgl.defaultFillStyle;
- } else {
- fillStyleColor = ol.render.webgl.defaultFillStyle;
- }
- if (!this.state_.strokeColor || !ol.array.equals(this.state_.strokeColor, strokeStyleColor) ||
- !this.state_.fillColor || !ol.array.equals(this.state_.fillColor, fillStyleColor) ||
- this.state_.lineWidth !== strokeStyleWidth) {
- this.state_.changed = true;
- this.state_.fillColor = fillStyleColor;
- this.state_.strokeColor = strokeStyleColor;
- this.state_.lineWidth = strokeStyleWidth;
- this.styles_.push([fillStyleColor, strokeStyleColor, strokeStyleWidth]);
- }
- };
- // This file is automatically generated, do not edit
- goog.provide('ol.render.webgl.texturereplay.defaultshader');
- goog.require('ol');
- goog.require('ol.webgl.Fragment');
- goog.require('ol.webgl.Vertex');
- ol.render.webgl.texturereplay.defaultshader.fragment = new ol.webgl.Fragment(ol.DEBUG_WEBGL ?
- 'precision mediump float;\nvarying vec2 v_texCoord;\nvarying float v_opacity;\n\nuniform float u_opacity;\nuniform sampler2D u_image;\n\nvoid main(void) {\n vec4 texColor = texture2D(u_image, v_texCoord);\n gl_FragColor.rgb = texColor.rgb;\n float alpha = texColor.a * v_opacity * u_opacity;\n if (alpha == 0.0) {\n discard;\n }\n gl_FragColor.a = alpha;\n}\n' :
- 'precision mediump float;varying vec2 a;varying float b;uniform float k;uniform sampler2D l;void main(void){vec4 texColor=texture2D(l,a);gl_FragColor.rgb=texColor.rgb;float alpha=texColor.a*b*k;if(alpha==0.0){discard;}gl_FragColor.a=alpha;}');
- ol.render.webgl.texturereplay.defaultshader.vertex = new ol.webgl.Vertex(ol.DEBUG_WEBGL ?
- 'varying vec2 v_texCoord;\nvarying float v_opacity;\n\nattribute vec2 a_position;\nattribute vec2 a_texCoord;\nattribute vec2 a_offsets;\nattribute float a_opacity;\nattribute float a_rotateWithView;\n\nuniform mat4 u_projectionMatrix;\nuniform mat4 u_offsetScaleMatrix;\nuniform mat4 u_offsetRotateMatrix;\n\nvoid main(void) {\n mat4 offsetMatrix = u_offsetScaleMatrix;\n if (a_rotateWithView == 1.0) {\n offsetMatrix = u_offsetScaleMatrix * u_offsetRotateMatrix;\n }\n vec4 offsets = offsetMatrix * vec4(a_offsets, 0.0, 0.0);\n gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;\n v_texCoord = a_texCoord;\n v_opacity = a_opacity;\n}\n\n\n' :
- 'varying vec2 a;varying float b;attribute vec2 c;attribute vec2 d;attribute vec2 e;attribute float f;attribute float g;uniform mat4 h;uniform mat4 i;uniform mat4 j;void main(void){mat4 offsetMatrix=i;if(g==1.0){offsetMatrix=i*j;}vec4 offsets=offsetMatrix*vec4(e,0.0,0.0);gl_Position=h*vec4(c,0.0,1.0)+offsets;a=d;b=f;}');
- // This file is automatically generated, do not edit
- goog.provide('ol.render.webgl.texturereplay.defaultshader.Locations');
- goog.require('ol');
- /**
- * @constructor
- * @param {WebGLRenderingContext} gl GL.
- * @param {WebGLProgram} program Program.
- * @struct
- */
- ol.render.webgl.texturereplay.defaultshader.Locations = function(gl, program) {
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_projectionMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_offsetScaleMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_offsetRotateMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_opacity = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_opacity' : 'k');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_image = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_image' : 'l');
- /**
- * @type {number}
- */
- this.a_position = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_position' : 'c');
- /**
- * @type {number}
- */
- this.a_texCoord = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_texCoord' : 'd');
- /**
- * @type {number}
- */
- this.a_offsets = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_offsets' : 'e');
- /**
- * @type {number}
- */
- this.a_opacity = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_opacity' : 'f');
- /**
- * @type {number}
- */
- this.a_rotateWithView = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_rotateWithView' : 'g');
- };
- goog.provide('ol.webgl.ContextEventType');
- /**
- * @enum {string}
- */
- ol.webgl.ContextEventType = {
- LOST: 'webglcontextlost',
- RESTORED: 'webglcontextrestored'
- };
- goog.provide('ol.webgl.Context');
- goog.require('ol');
- goog.require('ol.Disposable');
- goog.require('ol.array');
- goog.require('ol.events');
- goog.require('ol.obj');
- goog.require('ol.webgl');
- goog.require('ol.webgl.ContextEventType');
- /**
- * @classdesc
- * A WebGL context for accessing low-level WebGL capabilities.
- *
- * @constructor
- * @extends {ol.Disposable}
- * @param {HTMLCanvasElement} canvas Canvas.
- * @param {WebGLRenderingContext} gl GL.
- */
- ol.webgl.Context = function(canvas, gl) {
- /**
- * @private
- * @type {HTMLCanvasElement}
- */
- this.canvas_ = canvas;
- /**
- * @private
- * @type {WebGLRenderingContext}
- */
- this.gl_ = gl;
- /**
- * @private
- * @type {Object.<string, ol.WebglBufferCacheEntry>}
- */
- this.bufferCache_ = {};
- /**
- * @private
- * @type {Object.<string, WebGLShader>}
- */
- this.shaderCache_ = {};
- /**
- * @private
- * @type {Object.<string, WebGLProgram>}
- */
- this.programCache_ = {};
- /**
- * @private
- * @type {WebGLProgram}
- */
- this.currentProgram_ = null;
- /**
- * @private
- * @type {WebGLFramebuffer}
- */
- this.hitDetectionFramebuffer_ = null;
- /**
- * @private
- * @type {WebGLTexture}
- */
- this.hitDetectionTexture_ = null;
- /**
- * @private
- * @type {WebGLRenderbuffer}
- */
- this.hitDetectionRenderbuffer_ = null;
- /**
- * @type {boolean}
- */
- this.hasOESElementIndexUint = ol.array.includes(
- ol.WEBGL_EXTENSIONS, 'OES_element_index_uint');
- // use the OES_element_index_uint extension if available
- if (this.hasOESElementIndexUint) {
- gl.getExtension('OES_element_index_uint');
- }
- ol.events.listen(this.canvas_, ol.webgl.ContextEventType.LOST,
- this.handleWebGLContextLost, this);
- ol.events.listen(this.canvas_, ol.webgl.ContextEventType.RESTORED,
- this.handleWebGLContextRestored, this);
- };
- ol.inherits(ol.webgl.Context, ol.Disposable);
- /**
- * Just bind the buffer if it's in the cache. Otherwise create
- * the WebGL buffer, bind it, populate it, and add an entry to
- * the cache.
- * @param {number} target Target.
- * @param {ol.webgl.Buffer} buf Buffer.
- */
- ol.webgl.Context.prototype.bindBuffer = function(target, buf) {
- var gl = this.getGL();
- var arr = buf.getArray();
- var bufferKey = String(ol.getUid(buf));
- if (bufferKey in this.bufferCache_) {
- var bufferCacheEntry = this.bufferCache_[bufferKey];
- gl.bindBuffer(target, bufferCacheEntry.buffer);
- } else {
- var buffer = gl.createBuffer();
- gl.bindBuffer(target, buffer);
- var /** @type {ArrayBufferView} */ arrayBuffer;
- if (target == ol.webgl.ARRAY_BUFFER) {
- arrayBuffer = new Float32Array(arr);
- } else if (target == ol.webgl.ELEMENT_ARRAY_BUFFER) {
- arrayBuffer = this.hasOESElementIndexUint ?
- new Uint32Array(arr) : new Uint16Array(arr);
- }
- gl.bufferData(target, arrayBuffer, buf.getUsage());
- this.bufferCache_[bufferKey] = {
- buf: buf,
- buffer: buffer
- };
- }
- };
- /**
- * @param {ol.webgl.Buffer} buf Buffer.
- */
- ol.webgl.Context.prototype.deleteBuffer = function(buf) {
- var gl = this.getGL();
- var bufferKey = String(ol.getUid(buf));
- var bufferCacheEntry = this.bufferCache_[bufferKey];
- if (!gl.isContextLost()) {
- gl.deleteBuffer(bufferCacheEntry.buffer);
- }
- delete this.bufferCache_[bufferKey];
- };
- /**
- * @inheritDoc
- */
- ol.webgl.Context.prototype.disposeInternal = function() {
- ol.events.unlistenAll(this.canvas_);
- var gl = this.getGL();
- if (!gl.isContextLost()) {
- var key;
- for (key in this.bufferCache_) {
- gl.deleteBuffer(this.bufferCache_[key].buffer);
- }
- for (key in this.programCache_) {
- gl.deleteProgram(this.programCache_[key]);
- }
- for (key in this.shaderCache_) {
- gl.deleteShader(this.shaderCache_[key]);
- }
- // delete objects for hit-detection
- gl.deleteFramebuffer(this.hitDetectionFramebuffer_);
- gl.deleteRenderbuffer(this.hitDetectionRenderbuffer_);
- gl.deleteTexture(this.hitDetectionTexture_);
- }
- };
- /**
- * @return {HTMLCanvasElement} Canvas.
- */
- ol.webgl.Context.prototype.getCanvas = function() {
- return this.canvas_;
- };
- /**
- * Get the WebGL rendering context
- * @return {WebGLRenderingContext} The rendering context.
- * @api
- */
- ol.webgl.Context.prototype.getGL = function() {
- return this.gl_;
- };
- /**
- * Get the frame buffer for hit detection.
- * @return {WebGLFramebuffer} The hit detection frame buffer.
- */
- ol.webgl.Context.prototype.getHitDetectionFramebuffer = function() {
- if (!this.hitDetectionFramebuffer_) {
- this.initHitDetectionFramebuffer_();
- }
- return this.hitDetectionFramebuffer_;
- };
- /**
- * Get shader from the cache if it's in the cache. Otherwise, create
- * the WebGL shader, compile it, and add entry to cache.
- * @param {ol.webgl.Shader} shaderObject Shader object.
- * @return {WebGLShader} Shader.
- */
- ol.webgl.Context.prototype.getShader = function(shaderObject) {
- var shaderKey = String(ol.getUid(shaderObject));
- if (shaderKey in this.shaderCache_) {
- return this.shaderCache_[shaderKey];
- } else {
- var gl = this.getGL();
- var shader = gl.createShader(shaderObject.getType());
- gl.shaderSource(shader, shaderObject.getSource());
- gl.compileShader(shader);
- this.shaderCache_[shaderKey] = shader;
- return shader;
- }
- };
- /**
- * Get the program from the cache if it's in the cache. Otherwise create
- * the WebGL program, attach the shaders to it, and add an entry to the
- * cache.
- * @param {ol.webgl.Fragment} fragmentShaderObject Fragment shader.
- * @param {ol.webgl.Vertex} vertexShaderObject Vertex shader.
- * @return {WebGLProgram} Program.
- */
- ol.webgl.Context.prototype.getProgram = function(
- fragmentShaderObject, vertexShaderObject) {
- var programKey =
- ol.getUid(fragmentShaderObject) + '/' + ol.getUid(vertexShaderObject);
- if (programKey in this.programCache_) {
- return this.programCache_[programKey];
- } else {
- var gl = this.getGL();
- var program = gl.createProgram();
- gl.attachShader(program, this.getShader(fragmentShaderObject));
- gl.attachShader(program, this.getShader(vertexShaderObject));
- gl.linkProgram(program);
- this.programCache_[programKey] = program;
- return program;
- }
- };
- /**
- * FIXME empy description for jsdoc
- */
- ol.webgl.Context.prototype.handleWebGLContextLost = function() {
- ol.obj.clear(this.bufferCache_);
- ol.obj.clear(this.shaderCache_);
- ol.obj.clear(this.programCache_);
- this.currentProgram_ = null;
- this.hitDetectionFramebuffer_ = null;
- this.hitDetectionTexture_ = null;
- this.hitDetectionRenderbuffer_ = null;
- };
- /**
- * FIXME empy description for jsdoc
- */
- ol.webgl.Context.prototype.handleWebGLContextRestored = function() {
- };
- /**
- * Creates a 1x1 pixel framebuffer for the hit-detection.
- * @private
- */
- ol.webgl.Context.prototype.initHitDetectionFramebuffer_ = function() {
- var gl = this.gl_;
- var framebuffer = gl.createFramebuffer();
- gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
- var texture = ol.webgl.Context.createEmptyTexture(gl, 1, 1);
- var renderbuffer = gl.createRenderbuffer();
- gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
- gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 1, 1);
- gl.framebufferTexture2D(
- gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
- gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT,
- gl.RENDERBUFFER, renderbuffer);
- gl.bindTexture(gl.TEXTURE_2D, null);
- gl.bindRenderbuffer(gl.RENDERBUFFER, null);
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
- this.hitDetectionFramebuffer_ = framebuffer;
- this.hitDetectionTexture_ = texture;
- this.hitDetectionRenderbuffer_ = renderbuffer;
- };
- /**
- * Use a program. If the program is already in use, this will return `false`.
- * @param {WebGLProgram} program Program.
- * @return {boolean} Changed.
- * @api
- */
- ol.webgl.Context.prototype.useProgram = function(program) {
- if (program == this.currentProgram_) {
- return false;
- } else {
- var gl = this.getGL();
- gl.useProgram(program);
- this.currentProgram_ = program;
- return true;
- }
- };
- /**
- * @param {WebGLRenderingContext} gl WebGL rendering context.
- * @param {number=} opt_wrapS wrapS.
- * @param {number=} opt_wrapT wrapT.
- * @return {WebGLTexture} The texture.
- * @private
- */
- ol.webgl.Context.createTexture_ = function(gl, opt_wrapS, opt_wrapT) {
- var texture = gl.createTexture();
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
- if (opt_wrapS !== undefined) {
- gl.texParameteri(
- ol.webgl.TEXTURE_2D, ol.webgl.TEXTURE_WRAP_S, opt_wrapS);
- }
- if (opt_wrapT !== undefined) {
- gl.texParameteri(
- ol.webgl.TEXTURE_2D, ol.webgl.TEXTURE_WRAP_T, opt_wrapT);
- }
- return texture;
- };
- /**
- * @param {WebGLRenderingContext} gl WebGL rendering context.
- * @param {number} width Width.
- * @param {number} height Height.
- * @param {number=} opt_wrapS wrapS.
- * @param {number=} opt_wrapT wrapT.
- * @return {WebGLTexture} The texture.
- */
- ol.webgl.Context.createEmptyTexture = function(
- gl, width, height, opt_wrapS, opt_wrapT) {
- var texture = ol.webgl.Context.createTexture_(gl, opt_wrapS, opt_wrapT);
- gl.texImage2D(
- gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE,
- null);
- return texture;
- };
- /**
- * @param {WebGLRenderingContext} gl WebGL rendering context.
- * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image.
- * @param {number=} opt_wrapS wrapS.
- * @param {number=} opt_wrapT wrapT.
- * @return {WebGLTexture} The texture.
- */
- ol.webgl.Context.createTexture = function(gl, image, opt_wrapS, opt_wrapT) {
- var texture = ol.webgl.Context.createTexture_(gl, opt_wrapS, opt_wrapT);
- gl.texImage2D(
- gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
- return texture;
- };
- goog.provide('ol.render.webgl.TextureReplay');
- goog.require('ol');
- goog.require('ol.extent');
- goog.require('ol.obj');
- goog.require('ol.render.webgl.texturereplay.defaultshader');
- goog.require('ol.render.webgl.texturereplay.defaultshader.Locations');
- goog.require('ol.render.webgl.Replay');
- goog.require('ol.webgl');
- goog.require('ol.webgl.Context');
- /**
- * @constructor
- * @abstract
- * @extends {ol.render.webgl.Replay}
- * @param {number} tolerance Tolerance.
- * @param {ol.Extent} maxExtent Max extent.
- * @struct
- */
- ol.render.webgl.TextureReplay = function(tolerance, maxExtent) {
- ol.render.webgl.Replay.call(this, tolerance, maxExtent);
- /**
- * @type {number|undefined}
- * @protected
- */
- this.anchorX = undefined;
- /**
- * @type {number|undefined}
- * @protected
- */
- this.anchorY = undefined;
- /**
- * @type {Array.<number>}
- * @protected
- */
- this.groupIndices = [];
- /**
- * @type {Array.<number>}
- * @protected
- */
- this.hitDetectionGroupIndices = [];
- /**
- * @type {number|undefined}
- * @protected
- */
- this.height = undefined;
- /**
- * @type {number|undefined}
- * @protected
- */
- this.imageHeight = undefined;
- /**
- * @type {number|undefined}
- * @protected
- */
- this.imageWidth = undefined;
- /**
- * @protected
- * @type {ol.render.webgl.texturereplay.defaultshader.Locations}
- */
- this.defaultLocations = null;
- /**
- * @protected
- * @type {number|undefined}
- */
- this.opacity = undefined;
- /**
- * @type {number|undefined}
- * @protected
- */
- this.originX = undefined;
- /**
- * @type {number|undefined}
- * @protected
- */
- this.originY = undefined;
- /**
- * @protected
- * @type {boolean|undefined}
- */
- this.rotateWithView = undefined;
- /**
- * @protected
- * @type {number|undefined}
- */
- this.rotation = undefined;
- /**
- * @protected
- * @type {number|undefined}
- */
- this.scale = undefined;
- /**
- * @type {number|undefined}
- * @protected
- */
- this.width = undefined;
- };
- ol.inherits(ol.render.webgl.TextureReplay, ol.render.webgl.Replay);
- /**
- * @inheritDoc
- */
- ol.render.webgl.TextureReplay.prototype.getDeleteResourcesFunction = function(context) {
- var verticesBuffer = this.verticesBuffer;
- var indicesBuffer = this.indicesBuffer;
- var textures = this.getTextures(true);
- var gl = context.getGL();
- return function() {
- if (!gl.isContextLost()) {
- var i, ii;
- for (i = 0, ii = textures.length; i < ii; ++i) {
- gl.deleteTexture(textures[i]);
- }
- }
- context.deleteBuffer(verticesBuffer);
- context.deleteBuffer(indicesBuffer);
- };
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @return {number} My end.
- * @protected
- */
- ol.render.webgl.TextureReplay.prototype.drawCoordinates = function(flatCoordinates, offset, end, stride) {
- var anchorX = /** @type {number} */ (this.anchorX);
- var anchorY = /** @type {number} */ (this.anchorY);
- var height = /** @type {number} */ (this.height);
- var imageHeight = /** @type {number} */ (this.imageHeight);
- var imageWidth = /** @type {number} */ (this.imageWidth);
- var opacity = /** @type {number} */ (this.opacity);
- var originX = /** @type {number} */ (this.originX);
- var originY = /** @type {number} */ (this.originY);
- var rotateWithView = this.rotateWithView ? 1.0 : 0.0;
- // this.rotation_ is anti-clockwise, but rotation is clockwise
- var rotation = /** @type {number} */ (-this.rotation);
- var scale = /** @type {number} */ (this.scale);
- var width = /** @type {number} */ (this.width);
- var cos = Math.cos(rotation);
- var sin = Math.sin(rotation);
- var numIndices = this.indices.length;
- var numVertices = this.vertices.length;
- var i, n, offsetX, offsetY, x, y;
- for (i = offset; i < end; i += stride) {
- x = flatCoordinates[i] - this.origin[0];
- y = flatCoordinates[i + 1] - this.origin[1];
- // There are 4 vertices per [x, y] point, one for each corner of the
- // rectangle we're going to draw. We'd use 1 vertex per [x, y] point if
- // WebGL supported Geometry Shaders (which can emit new vertices), but that
- // is not currently the case.
- //
- // And each vertex includes 8 values: the x and y coordinates, the x and
- // y offsets used to calculate the position of the corner, the u and
- // v texture coordinates for the corner, the opacity, and whether the
- // the image should be rotated with the view (rotateWithView).
- n = numVertices / 8;
- // bottom-left corner
- offsetX = -scale * anchorX;
- offsetY = -scale * (height - anchorY);
- this.vertices[numVertices++] = x;
- this.vertices[numVertices++] = y;
- this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
- this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
- this.vertices[numVertices++] = originX / imageWidth;
- this.vertices[numVertices++] = (originY + height) / imageHeight;
- this.vertices[numVertices++] = opacity;
- this.vertices[numVertices++] = rotateWithView;
- // bottom-right corner
- offsetX = scale * (width - anchorX);
- offsetY = -scale * (height - anchorY);
- this.vertices[numVertices++] = x;
- this.vertices[numVertices++] = y;
- this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
- this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
- this.vertices[numVertices++] = (originX + width) / imageWidth;
- this.vertices[numVertices++] = (originY + height) / imageHeight;
- this.vertices[numVertices++] = opacity;
- this.vertices[numVertices++] = rotateWithView;
- // top-right corner
- offsetX = scale * (width - anchorX);
- offsetY = scale * anchorY;
- this.vertices[numVertices++] = x;
- this.vertices[numVertices++] = y;
- this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
- this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
- this.vertices[numVertices++] = (originX + width) / imageWidth;
- this.vertices[numVertices++] = originY / imageHeight;
- this.vertices[numVertices++] = opacity;
- this.vertices[numVertices++] = rotateWithView;
- // top-left corner
- offsetX = -scale * anchorX;
- offsetY = scale * anchorY;
- this.vertices[numVertices++] = x;
- this.vertices[numVertices++] = y;
- this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
- this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
- this.vertices[numVertices++] = originX / imageWidth;
- this.vertices[numVertices++] = originY / imageHeight;
- this.vertices[numVertices++] = opacity;
- this.vertices[numVertices++] = rotateWithView;
- this.indices[numIndices++] = n;
- this.indices[numIndices++] = n + 1;
- this.indices[numIndices++] = n + 2;
- this.indices[numIndices++] = n;
- this.indices[numIndices++] = n + 2;
- this.indices[numIndices++] = n + 3;
- }
- return numVertices;
- };
- /**
- * @protected
- * @param {Array.<WebGLTexture>} textures Textures.
- * @param {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>} images
- * Images.
- * @param {Object.<string, WebGLTexture>} texturePerImage Texture cache.
- * @param {WebGLRenderingContext} gl Gl.
- */
- ol.render.webgl.TextureReplay.prototype.createTextures = function(textures, images, texturePerImage, gl) {
- var texture, image, uid, i;
- var ii = images.length;
- for (i = 0; i < ii; ++i) {
- image = images[i];
- uid = ol.getUid(image).toString();
- if (uid in texturePerImage) {
- texture = texturePerImage[uid];
- } else {
- texture = ol.webgl.Context.createTexture(
- gl, image, ol.webgl.CLAMP_TO_EDGE, ol.webgl.CLAMP_TO_EDGE);
- texturePerImage[uid] = texture;
- }
- textures[i] = texture;
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.TextureReplay.prototype.setUpProgram = function(gl, context, size, pixelRatio) {
- // get the program
- var fragmentShader = ol.render.webgl.texturereplay.defaultshader.fragment;
- var vertexShader = ol.render.webgl.texturereplay.defaultshader.vertex;
- var program = context.getProgram(fragmentShader, vertexShader);
- // get the locations
- var locations;
- if (!this.defaultLocations) {
- locations = new ol.render.webgl.texturereplay.defaultshader.Locations(gl, program);
- this.defaultLocations = locations;
- } else {
- locations = this.defaultLocations;
- }
- // use the program (FIXME: use the return value)
- context.useProgram(program);
- // enable the vertex attrib arrays
- gl.enableVertexAttribArray(locations.a_position);
- gl.vertexAttribPointer(locations.a_position, 2, ol.webgl.FLOAT,
- false, 32, 0);
- gl.enableVertexAttribArray(locations.a_offsets);
- gl.vertexAttribPointer(locations.a_offsets, 2, ol.webgl.FLOAT,
- false, 32, 8);
- gl.enableVertexAttribArray(locations.a_texCoord);
- gl.vertexAttribPointer(locations.a_texCoord, 2, ol.webgl.FLOAT,
- false, 32, 16);
- gl.enableVertexAttribArray(locations.a_opacity);
- gl.vertexAttribPointer(locations.a_opacity, 1, ol.webgl.FLOAT,
- false, 32, 24);
- gl.enableVertexAttribArray(locations.a_rotateWithView);
- gl.vertexAttribPointer(locations.a_rotateWithView, 1, ol.webgl.FLOAT,
- false, 32, 28);
- return locations;
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.TextureReplay.prototype.shutDownProgram = function(gl, locations) {
- gl.disableVertexAttribArray(locations.a_position);
- gl.disableVertexAttribArray(locations.a_offsets);
- gl.disableVertexAttribArray(locations.a_texCoord);
- gl.disableVertexAttribArray(locations.a_opacity);
- gl.disableVertexAttribArray(locations.a_rotateWithView);
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.TextureReplay.prototype.drawReplay = function(gl, context, skippedFeaturesHash, hitDetection) {
- var textures = hitDetection ? this.getHitDetectionTextures() : this.getTextures();
- var groupIndices = hitDetection ? this.hitDetectionGroupIndices : this.groupIndices;
- if (!ol.obj.isEmpty(skippedFeaturesHash)) {
- this.drawReplaySkipping(
- gl, context, skippedFeaturesHash, textures, groupIndices);
- } else {
- var i, ii, start;
- for (i = 0, ii = textures.length, start = 0; i < ii; ++i) {
- gl.bindTexture(ol.webgl.TEXTURE_2D, textures[i]);
- var end = groupIndices[i];
- this.drawElements(gl, context, start, end);
- start = end;
- }
- }
- };
- /**
- * Draw the replay while paying attention to skipped features.
- *
- * This functions creates groups of features that can be drawn to together,
- * so that the number of `drawElements` calls is minimized.
- *
- * For example given the following texture groups:
- *
- * Group 1: A B C
- * Group 2: D [E] F G
- *
- * If feature E should be skipped, the following `drawElements` calls will be
- * made:
- *
- * drawElements with feature A, B and C
- * drawElements with feature D
- * drawElements with feature F and G
- *
- * @protected
- * @param {WebGLRenderingContext} gl gl.
- * @param {ol.webgl.Context} context Context.
- * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
- * to skip.
- * @param {Array.<WebGLTexture>} textures Textures.
- * @param {Array.<number>} groupIndices Texture group indices.
- */
- ol.render.webgl.TextureReplay.prototype.drawReplaySkipping = function(gl, context, skippedFeaturesHash, textures,
- groupIndices) {
- var featureIndex = 0;
- var i, ii;
- for (i = 0, ii = textures.length; i < ii; ++i) {
- gl.bindTexture(ol.webgl.TEXTURE_2D, textures[i]);
- var groupStart = (i > 0) ? groupIndices[i - 1] : 0;
- var groupEnd = groupIndices[i];
- var start = groupStart;
- var end = groupStart;
- while (featureIndex < this.startIndices.length &&
- this.startIndices[featureIndex] <= groupEnd) {
- var feature = this.startIndicesFeature[featureIndex];
- var featureUid = ol.getUid(feature).toString();
- if (skippedFeaturesHash[featureUid] !== undefined) {
- // feature should be skipped
- if (start !== end) {
- // draw the features so far
- this.drawElements(gl, context, start, end);
- }
- // continue with the next feature
- start = (featureIndex === this.startIndices.length - 1) ?
- groupEnd : this.startIndices[featureIndex + 1];
- end = start;
- } else {
- // the feature is not skipped, augment the end index
- end = (featureIndex === this.startIndices.length - 1) ?
- groupEnd : this.startIndices[featureIndex + 1];
- }
- featureIndex++;
- }
- if (start !== end) {
- // draw the remaining features (in case there was no skipped feature
- // in this texture group, all features of a group are drawn together)
- this.drawElements(gl, context, start, end);
- }
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.TextureReplay.prototype.drawHitDetectionReplayOneByOne = function(gl, context, skippedFeaturesHash,
- featureCallback, opt_hitExtent) {
- var i, groupStart, start, end, feature, featureUid;
- var featureIndex = this.startIndices.length - 1;
- var hitDetectionTextures = this.getHitDetectionTextures();
- for (i = hitDetectionTextures.length - 1; i >= 0; --i) {
- gl.bindTexture(ol.webgl.TEXTURE_2D, hitDetectionTextures[i]);
- groupStart = (i > 0) ? this.hitDetectionGroupIndices[i - 1] : 0;
- end = this.hitDetectionGroupIndices[i];
- // draw all features for this texture group
- while (featureIndex >= 0 &&
- this.startIndices[featureIndex] >= groupStart) {
- start = this.startIndices[featureIndex];
- feature = this.startIndicesFeature[featureIndex];
- featureUid = ol.getUid(feature).toString();
- if (skippedFeaturesHash[featureUid] === undefined &&
- feature.getGeometry() &&
- (opt_hitExtent === undefined || ol.extent.intersects(
- /** @type {Array<number>} */ (opt_hitExtent),
- feature.getGeometry().getExtent()))) {
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
- this.drawElements(gl, context, start, end);
- var result = featureCallback(feature);
- if (result) {
- return result;
- }
- }
- end = start;
- featureIndex--;
- }
- }
- return undefined;
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.TextureReplay.prototype.finish = function(context) {
- this.anchorX = undefined;
- this.anchorY = undefined;
- this.height = undefined;
- this.imageHeight = undefined;
- this.imageWidth = undefined;
- this.indices = null;
- this.opacity = undefined;
- this.originX = undefined;
- this.originY = undefined;
- this.rotateWithView = undefined;
- this.rotation = undefined;
- this.scale = undefined;
- this.vertices = null;
- this.width = undefined;
- };
- /**
- * @abstract
- * @protected
- * @param {boolean=} opt_all Return hit detection textures with regular ones.
- * @returns {Array.<WebGLTexture>} Textures.
- */
- ol.render.webgl.TextureReplay.prototype.getTextures = function(opt_all) {};
- /**
- * @abstract
- * @protected
- * @returns {Array.<WebGLTexture>} Textures.
- */
- ol.render.webgl.TextureReplay.prototype.getHitDetectionTextures = function() {};
- goog.provide('ol.render.webgl.ImageReplay');
- goog.require('ol');
- goog.require('ol.render.webgl.TextureReplay');
- goog.require('ol.webgl.Buffer');
- /**
- * @constructor
- * @extends {ol.render.webgl.TextureReplay}
- * @param {number} tolerance Tolerance.
- * @param {ol.Extent} maxExtent Max extent.
- * @struct
- */
- ol.render.webgl.ImageReplay = function(tolerance, maxExtent) {
- ol.render.webgl.TextureReplay.call(this, tolerance, maxExtent);
- /**
- * @type {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>}
- * @protected
- */
- this.images_ = [];
- /**
- * @type {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>}
- * @protected
- */
- this.hitDetectionImages_ = [];
- /**
- * @type {Array.<WebGLTexture>}
- * @private
- */
- this.textures_ = [];
- /**
- * @type {Array.<WebGLTexture>}
- * @private
- */
- this.hitDetectionTextures_ = [];
- };
- ol.inherits(ol.render.webgl.ImageReplay, ol.render.webgl.TextureReplay);
- /**
- * @inheritDoc
- */
- ol.render.webgl.ImageReplay.prototype.drawMultiPoint = function(multiPointGeometry, feature) {
- this.startIndices.push(this.indices.length);
- this.startIndicesFeature.push(feature);
- var flatCoordinates = multiPointGeometry.getFlatCoordinates();
- var stride = multiPointGeometry.getStride();
- this.drawCoordinates(
- flatCoordinates, 0, flatCoordinates.length, stride);
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.ImageReplay.prototype.drawPoint = function(pointGeometry, feature) {
- this.startIndices.push(this.indices.length);
- this.startIndicesFeature.push(feature);
- var flatCoordinates = pointGeometry.getFlatCoordinates();
- var stride = pointGeometry.getStride();
- this.drawCoordinates(
- flatCoordinates, 0, flatCoordinates.length, stride);
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.ImageReplay.prototype.finish = function(context) {
- var gl = context.getGL();
- this.groupIndices.push(this.indices.length);
- this.hitDetectionGroupIndices.push(this.indices.length);
- // create, bind, and populate the vertices buffer
- this.verticesBuffer = new ol.webgl.Buffer(this.vertices);
- var indices = this.indices;
- // create, bind, and populate the indices buffer
- this.indicesBuffer = new ol.webgl.Buffer(indices);
- // create textures
- /** @type {Object.<string, WebGLTexture>} */
- var texturePerImage = {};
- this.createTextures(this.textures_, this.images_, texturePerImage, gl);
- this.createTextures(this.hitDetectionTextures_, this.hitDetectionImages_,
- texturePerImage, gl);
- this.images_ = null;
- this.hitDetectionImages_ = null;
- ol.render.webgl.TextureReplay.prototype.finish.call(this, context);
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.ImageReplay.prototype.setImageStyle = function(imageStyle) {
- var anchor = imageStyle.getAnchor();
- var image = imageStyle.getImage(1);
- var imageSize = imageStyle.getImageSize();
- var hitDetectionImage = imageStyle.getHitDetectionImage(1);
- var opacity = imageStyle.getOpacity();
- var origin = imageStyle.getOrigin();
- var rotateWithView = imageStyle.getRotateWithView();
- var rotation = imageStyle.getRotation();
- var size = imageStyle.getSize();
- var scale = imageStyle.getScale();
- var currentImage;
- if (this.images_.length === 0) {
- this.images_.push(image);
- } else {
- currentImage = this.images_[this.images_.length - 1];
- if (ol.getUid(currentImage) != ol.getUid(image)) {
- this.groupIndices.push(this.indices.length);
- this.images_.push(image);
- }
- }
- if (this.hitDetectionImages_.length === 0) {
- this.hitDetectionImages_.push(hitDetectionImage);
- } else {
- currentImage =
- this.hitDetectionImages_[this.hitDetectionImages_.length - 1];
- if (ol.getUid(currentImage) != ol.getUid(hitDetectionImage)) {
- this.hitDetectionGroupIndices.push(this.indices.length);
- this.hitDetectionImages_.push(hitDetectionImage);
- }
- }
- this.anchorX = anchor[0];
- this.anchorY = anchor[1];
- this.height = size[1];
- this.imageHeight = imageSize[1];
- this.imageWidth = imageSize[0];
- this.opacity = opacity;
- this.originX = origin[0];
- this.originY = origin[1];
- this.rotation = rotation;
- this.rotateWithView = rotateWithView;
- this.scale = scale;
- this.width = size[0];
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.ImageReplay.prototype.getTextures = function(opt_all) {
- return opt_all ? this.textures_.concat(this.hitDetectionTextures_) : this.textures_;
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.ImageReplay.prototype.getHitDetectionTextures = function() {
- return this.hitDetectionTextures_;
- };
- // This file is automatically generated, do not edit
- goog.provide('ol.render.webgl.linestringreplay.defaultshader');
- goog.require('ol');
- goog.require('ol.webgl.Fragment');
- goog.require('ol.webgl.Vertex');
- ol.render.webgl.linestringreplay.defaultshader.fragment = new ol.webgl.Fragment(ol.DEBUG_WEBGL ?
- 'precision mediump float;\nvarying float v_round;\nvarying vec2 v_roundVertex;\nvarying float v_halfWidth;\n\n\n\nuniform float u_opacity;\nuniform vec4 u_color;\nuniform vec2 u_size;\nuniform float u_pixelRatio;\n\nvoid main(void) {\n if (v_round > 0.0) {\n vec2 windowCoords = vec2((v_roundVertex.x + 1.0) / 2.0 * u_size.x * u_pixelRatio,\n (v_roundVertex.y + 1.0) / 2.0 * u_size.y * u_pixelRatio);\n if (length(windowCoords - gl_FragCoord.xy) > v_halfWidth * u_pixelRatio) {\n discard;\n }\n }\n gl_FragColor = u_color;\n float alpha = u_color.a * u_opacity;\n if (alpha == 0.0) {\n discard;\n }\n gl_FragColor.a = alpha;\n}\n' :
- 'precision mediump float;varying float a;varying vec2 aVertex;varying float c;uniform float m;uniform vec4 n;uniform vec2 o;uniform float p;void main(void){if(a>0.0){vec2 windowCoords=vec2((aVertex.x+1.0)/2.0*o.x*p,(aVertex.y+1.0)/2.0*o.y*p);if(length(windowCoords-gl_FragCoord.xy)>c*p){discard;}} gl_FragColor=n;float alpha=n.a*m;if(alpha==0.0){discard;}gl_FragColor.a=alpha;}');
- ol.render.webgl.linestringreplay.defaultshader.vertex = new ol.webgl.Vertex(ol.DEBUG_WEBGL ?
- 'varying float v_round;\nvarying vec2 v_roundVertex;\nvarying float v_halfWidth;\n\n\nattribute vec2 a_lastPos;\nattribute vec2 a_position;\nattribute vec2 a_nextPos;\nattribute float a_direction;\n\nuniform mat4 u_projectionMatrix;\nuniform mat4 u_offsetScaleMatrix;\nuniform mat4 u_offsetRotateMatrix;\nuniform float u_lineWidth;\nuniform float u_miterLimit;\n\nbool nearlyEquals(in float value, in float ref) {\n float epsilon = 0.000000000001;\n return value >= ref - epsilon && value <= ref + epsilon;\n}\n\nvoid alongNormal(out vec2 offset, in vec2 nextP, in float turnDir, in float direction) {\n vec2 dirVect = nextP - a_position;\n vec2 normal = normalize(vec2(-turnDir * dirVect.y, turnDir * dirVect.x));\n offset = u_lineWidth / 2.0 * normal * direction;\n}\n\nvoid miterUp(out vec2 offset, out float round, in bool isRound, in float direction) {\n float halfWidth = u_lineWidth / 2.0;\n vec2 tangent = normalize(normalize(a_nextPos - a_position) + normalize(a_position - a_lastPos));\n vec2 normal = vec2(-tangent.y, tangent.x);\n vec2 dirVect = a_nextPos - a_position;\n vec2 tmpNormal = normalize(vec2(-dirVect.y, dirVect.x));\n float miterLength = abs(halfWidth / dot(normal, tmpNormal));\n offset = normal * direction * miterLength;\n round = 0.0;\n if (isRound) {\n round = 1.0;\n } else if (miterLength > u_miterLimit + u_lineWidth) {\n offset = halfWidth * tmpNormal * direction;\n }\n}\n\nbool miterDown(out vec2 offset, in vec4 projPos, in mat4 offsetMatrix, in float direction) {\n bool degenerate = false;\n vec2 tangent = normalize(normalize(a_nextPos - a_position) + normalize(a_position - a_lastPos));\n vec2 normal = vec2(-tangent.y, tangent.x);\n vec2 dirVect = a_lastPos - a_position;\n vec2 tmpNormal = normalize(vec2(-dirVect.y, dirVect.x));\n vec2 longOffset, shortOffset, longVertex;\n vec4 shortProjVertex;\n float halfWidth = u_lineWidth / 2.0;\n if (length(a_nextPos - a_position) > length(a_lastPos - a_position)) {\n longOffset = tmpNormal * direction * halfWidth;\n shortOffset = normalize(vec2(dirVect.y, -dirVect.x)) * direction * halfWidth;\n longVertex = a_nextPos;\n shortProjVertex = u_projectionMatrix * vec4(a_lastPos, 0.0, 1.0);\n } else {\n shortOffset = tmpNormal * direction * halfWidth;\n longOffset = normalize(vec2(dirVect.y, -dirVect.x)) * direction * halfWidth;\n longVertex = a_lastPos;\n shortProjVertex = u_projectionMatrix * vec4(a_nextPos, 0.0, 1.0);\n }\n //Intersection algorithm based on theory by Paul Bourke (http://paulbourke.net/geometry/pointlineplane/).\n vec4 p1 = u_projectionMatrix * vec4(longVertex, 0.0, 1.0) + offsetMatrix * vec4(longOffset, 0.0, 0.0);\n vec4 p2 = projPos + offsetMatrix * vec4(longOffset, 0.0, 0.0);\n vec4 p3 = shortProjVertex + offsetMatrix * vec4(-shortOffset, 0.0, 0.0);\n vec4 p4 = shortProjVertex + offsetMatrix * vec4(shortOffset, 0.0, 0.0);\n float denom = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y);\n float firstU = ((p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x)) / denom;\n float secondU = ((p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x)) / denom;\n float epsilon = 0.000000000001;\n if (firstU > epsilon && firstU < 1.0 - epsilon && secondU > epsilon && secondU < 1.0 - epsilon) {\n shortProjVertex.x = p1.x + firstU * (p2.x - p1.x);\n shortProjVertex.y = p1.y + firstU * (p2.y - p1.y);\n offset = shortProjVertex.xy;\n degenerate = true;\n } else {\n float miterLength = abs(halfWidth / dot(normal, tmpNormal));\n offset = normal * direction * miterLength;\n }\n return degenerate;\n}\n\nvoid squareCap(out vec2 offset, out float round, in bool isRound, in vec2 nextP,\n in float turnDir, in float direction) {\n round = 0.0;\n vec2 dirVect = a_position - nextP;\n vec2 firstNormal = normalize(dirVect);\n vec2 secondNormal = vec2(turnDir * firstNormal.y * direction, -turnDir * firstNormal.x * direction);\n vec2 hypotenuse = normalize(firstNormal - secondNormal);\n vec2 normal = vec2(turnDir * hypotenuse.y * direction, -turnDir * hypotenuse.x * direction);\n float length = sqrt(v_halfWidth * v_halfWidth * 2.0);\n offset = normal * length;\n if (isRound) {\n round = 1.0;\n }\n}\n\nvoid main(void) {\n bool degenerate = false;\n float direction = float(sign(a_direction));\n mat4 offsetMatrix = u_offsetScaleMatrix * u_offsetRotateMatrix;\n vec2 offset;\n vec4 projPos = u_projectionMatrix * vec4(a_position, 0.0, 1.0);\n bool round = nearlyEquals(mod(a_direction, 2.0), 0.0);\n\n v_round = 0.0;\n v_halfWidth = u_lineWidth / 2.0;\n v_roundVertex = projPos.xy;\n\n if (nearlyEquals(mod(a_direction, 3.0), 0.0) || nearlyEquals(mod(a_direction, 17.0), 0.0)) {\n alongNormal(offset, a_nextPos, 1.0, direction);\n } else if (nearlyEquals(mod(a_direction, 5.0), 0.0) || nearlyEquals(mod(a_direction, 13.0), 0.0)) {\n alongNormal(offset, a_lastPos, -1.0, direction);\n } else if (nearlyEquals(mod(a_direction, 23.0), 0.0)) {\n miterUp(offset, v_round, round, direction);\n } else if (nearlyEquals(mod(a_direction, 19.0), 0.0)) {\n degenerate = miterDown(offset, projPos, offsetMatrix, direction);\n } else if (nearlyEquals(mod(a_direction, 7.0), 0.0)) {\n squareCap(offset, v_round, round, a_nextPos, 1.0, direction);\n } else if (nearlyEquals(mod(a_direction, 11.0), 0.0)) {\n squareCap(offset, v_round, round, a_lastPos, -1.0, direction);\n }\n if (!degenerate) {\n vec4 offsets = offsetMatrix * vec4(offset, 0.0, 0.0);\n gl_Position = projPos + offsets;\n } else {\n gl_Position = vec4(offset, 0.0, 1.0);\n }\n}\n\n\n' :
- 'varying float a;varying vec2 aVertex;varying float c;attribute vec2 d;attribute vec2 e;attribute vec2 f;attribute float g;uniform mat4 h;uniform mat4 i;uniform mat4 j;uniform float k;uniform float l;bool nearlyEquals(in float value,in float ref){float epsilon=0.000000000001;return value>=ref-epsilon&&value<=ref+epsilon;}void alongNormal(out vec2 offset,in vec2 nextP,in float turnDir,in float direction){vec2 dirVect=nextP-e;vec2 normal=normalize(vec2(-turnDir*dirVect.y,turnDir*dirVect.x));offset=k/2.0*normal*direction;}void miterUp(out vec2 offset,out float round,in bool isRound,in float direction){float halfWidth=k/2.0;vec2 tangent=normalize(normalize(f-e)+normalize(e-d));vec2 normal=vec2(-tangent.y,tangent.x);vec2 dirVect=f-e;vec2 tmpNormal=normalize(vec2(-dirVect.y,dirVect.x));float miterLength=abs(halfWidth/dot(normal,tmpNormal));offset=normal*direction*miterLength;round=0.0;if(isRound){round=1.0;}else if(miterLength>l+k){offset=halfWidth*tmpNormal*direction;}} bool miterDown(out vec2 offset,in vec4 projPos,in mat4 offsetMatrix,in float direction){bool degenerate=false;vec2 tangent=normalize(normalize(f-e)+normalize(e-d));vec2 normal=vec2(-tangent.y,tangent.x);vec2 dirVect=d-e;vec2 tmpNormal=normalize(vec2(-dirVect.y,dirVect.x));vec2 longOffset,shortOffset,longVertex;vec4 shortProjVertex;float halfWidth=k/2.0;if(length(f-e)>length(d-e)){longOffset=tmpNormal*direction*halfWidth;shortOffset=normalize(vec2(dirVect.y,-dirVect.x))*direction*halfWidth;longVertex=f;shortProjVertex=h*vec4(d,0.0,1.0);}else{shortOffset=tmpNormal*direction*halfWidth;longOffset=normalize(vec2(dirVect.y,-dirVect.x))*direction*halfWidth;longVertex=d;shortProjVertex=h*vec4(f,0.0,1.0);}vec4 p1=h*vec4(longVertex,0.0,1.0)+offsetMatrix*vec4(longOffset,0.0,0.0);vec4 p2=projPos+offsetMatrix*vec4(longOffset,0.0,0.0);vec4 p3=shortProjVertex+offsetMatrix*vec4(-shortOffset,0.0,0.0);vec4 p4=shortProjVertex+offsetMatrix*vec4(shortOffset,0.0,0.0);float denom=(p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y);float firstU=((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x))/denom;float secondU=((p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x))/denom;float epsilon=0.000000000001;if(firstU>epsilon&&firstU<1.0-epsilon&&secondU>epsilon&&secondU<1.0-epsilon){shortProjVertex.x=p1.x+firstU*(p2.x-p1.x);shortProjVertex.y=p1.y+firstU*(p2.y-p1.y);offset=shortProjVertex.xy;degenerate=true;}else{float miterLength=abs(halfWidth/dot(normal,tmpNormal));offset=normal*direction*miterLength;}return degenerate;}void squareCap(out vec2 offset,out float round,in bool isRound,in vec2 nextP,in float turnDir,in float direction){round=0.0;vec2 dirVect=e-nextP;vec2 firstNormal=normalize(dirVect);vec2 secondNormal=vec2(turnDir*firstNormal.y*direction,-turnDir*firstNormal.x*direction);vec2 hypotenuse=normalize(firstNormal-secondNormal);vec2 normal=vec2(turnDir*hypotenuse.y*direction,-turnDir*hypotenuse.x*direction);float length=sqrt(c*c*2.0);offset=normal*length;if(isRound){round=1.0;}} void main(void){bool degenerate=false;float direction=float(sign(g));mat4 offsetMatrix=i*j;vec2 offset;vec4 projPos=h*vec4(e,0.0,1.0);bool round=nearlyEquals(mod(g,2.0),0.0);a=0.0;c=k/2.0;aVertex=projPos.xy;if(nearlyEquals(mod(g,3.0),0.0)||nearlyEquals(mod(g,17.0),0.0)){alongNormal(offset,f,1.0,direction);}else if(nearlyEquals(mod(g,5.0),0.0)||nearlyEquals(mod(g,13.0),0.0)){alongNormal(offset,d,-1.0,direction);}else if(nearlyEquals(mod(g,23.0),0.0)){miterUp(offset,a,round,direction);}else if(nearlyEquals(mod(g,19.0),0.0)){degenerate=miterDown(offset,projPos,offsetMatrix,direction);}else if(nearlyEquals(mod(g,7.0),0.0)){squareCap(offset,a,round,f,1.0,direction);}else if(nearlyEquals(mod(g,11.0),0.0)){squareCap(offset,a,round,d,-1.0,direction);}if(!degenerate){vec4 offsets=offsetMatrix*vec4(offset,0.0,0.0);gl_Position=projPos+offsets;}else{gl_Position=vec4(offset,0.0,1.0);}}');
- // This file is automatically generated, do not edit
- goog.provide('ol.render.webgl.linestringreplay.defaultshader.Locations');
- goog.require('ol');
- /**
- * @constructor
- * @param {WebGLRenderingContext} gl GL.
- * @param {WebGLProgram} program Program.
- * @struct
- */
- ol.render.webgl.linestringreplay.defaultshader.Locations = function(gl, program) {
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_projectionMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_offsetScaleMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_offsetRotateMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_lineWidth = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_lineWidth' : 'k');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_miterLimit = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_miterLimit' : 'l');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_opacity = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_opacity' : 'm');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_color = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_color' : 'n');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_size = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_size' : 'o');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_pixelRatio = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_pixelRatio' : 'p');
- /**
- * @type {number}
- */
- this.a_lastPos = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_lastPos' : 'd');
- /**
- * @type {number}
- */
- this.a_position = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_position' : 'e');
- /**
- * @type {number}
- */
- this.a_nextPos = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_nextPos' : 'f');
- /**
- * @type {number}
- */
- this.a_direction = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_direction' : 'g');
- };
- goog.provide('ol.render.webgl.LineStringReplay');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.color');
- goog.require('ol.extent');
- goog.require('ol.geom.flat.orient');
- goog.require('ol.geom.flat.transform');
- goog.require('ol.geom.flat.topology');
- goog.require('ol.obj');
- goog.require('ol.render.webgl');
- goog.require('ol.render.webgl.Replay');
- goog.require('ol.render.webgl.linestringreplay.defaultshader');
- goog.require('ol.render.webgl.linestringreplay.defaultshader.Locations');
- goog.require('ol.webgl');
- goog.require('ol.webgl.Buffer');
- /**
- * @constructor
- * @extends {ol.render.webgl.Replay}
- * @param {number} tolerance Tolerance.
- * @param {ol.Extent} maxExtent Max extent.
- * @struct
- */
- ol.render.webgl.LineStringReplay = function(tolerance, maxExtent) {
- ol.render.webgl.Replay.call(this, tolerance, maxExtent);
- /**
- * @private
- * @type {ol.render.webgl.linestringreplay.defaultshader.Locations}
- */
- this.defaultLocations_ = null;
- /**
- * @private
- * @type {Array.<Array.<?>>}
- */
- this.styles_ = [];
- /**
- * @private
- * @type {Array.<number>}
- */
- this.styleIndices_ = [];
- /**
- * @private
- * @type {{strokeColor: (Array.<number>|null),
- * lineCap: (string|undefined),
- * lineDash: Array.<number>,
- * lineDashOffset: (number|undefined),
- * lineJoin: (string|undefined),
- * lineWidth: (number|undefined),
- * miterLimit: (number|undefined),
- * changed: boolean}|null}
- */
- this.state_ = {
- strokeColor: null,
- lineCap: undefined,
- lineDash: null,
- lineDashOffset: undefined,
- lineJoin: undefined,
- lineWidth: undefined,
- miterLimit: undefined,
- changed: false
- };
- };
- ol.inherits(ol.render.webgl.LineStringReplay, ol.render.webgl.Replay);
- /**
- * Draw one segment.
- * @private
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- */
- ol.render.webgl.LineStringReplay.prototype.drawCoordinates_ = function(flatCoordinates, offset, end, stride) {
- var i, ii;
- var numVertices = this.vertices.length;
- var numIndices = this.indices.length;
- //To save a vertex, the direction of a point is a product of the sign (1 or -1), a prime from
- //ol.render.webgl.LineStringReplay.Instruction_, and a rounding factor (1 or 2). If the product is even,
- //we round it. If it is odd, we don't.
- var lineJoin = this.state_.lineJoin === 'bevel' ? 0 :
- this.state_.lineJoin === 'miter' ? 1 : 2;
- var lineCap = this.state_.lineCap === 'butt' ? 0 :
- this.state_.lineCap === 'square' ? 1 : 2;
- var closed = ol.geom.flat.topology.lineStringIsClosed(flatCoordinates, offset, end, stride);
- var startCoords, sign, n;
- var lastIndex = numIndices;
- var lastSign = 1;
- //We need the adjacent vertices to define normals in joins. p0 = last, p1 = current, p2 = next.
- var p0, p1, p2;
- for (i = offset, ii = end; i < ii; i += stride) {
- n = numVertices / 7;
- p0 = p1;
- p1 = p2 || [flatCoordinates[i], flatCoordinates[i + 1]];
- //First vertex.
- if (i === offset) {
- p2 = [flatCoordinates[i + stride], flatCoordinates[i + stride + 1]];
- if (end - offset === stride * 2 && ol.array.equals(p1, p2)) {
- break;
- }
- if (closed) {
- //A closed line! Complete the circle.
- p0 = [flatCoordinates[end - stride * 2],
- flatCoordinates[end - stride * 2 + 1]];
- startCoords = p2;
- } else {
- //Add the first two/four vertices.
- if (lineCap) {
- numVertices = this.addVertices_([0, 0], p1, p2,
- lastSign * ol.render.webgl.LineStringReplay.Instruction_.BEGIN_LINE_CAP * lineCap, numVertices);
- numVertices = this.addVertices_([0, 0], p1, p2,
- -lastSign * ol.render.webgl.LineStringReplay.Instruction_.BEGIN_LINE_CAP * lineCap, numVertices);
- this.indices[numIndices++] = n + 2;
- this.indices[numIndices++] = n;
- this.indices[numIndices++] = n + 1;
- this.indices[numIndices++] = n + 1;
- this.indices[numIndices++] = n + 3;
- this.indices[numIndices++] = n + 2;
- }
- numVertices = this.addVertices_([0, 0], p1, p2,
- lastSign * ol.render.webgl.LineStringReplay.Instruction_.BEGIN_LINE * (lineCap || 1), numVertices);
- numVertices = this.addVertices_([0, 0], p1, p2,
- -lastSign * ol.render.webgl.LineStringReplay.Instruction_.BEGIN_LINE * (lineCap || 1), numVertices);
- lastIndex = numVertices / 7 - 1;
- continue;
- }
- } else if (i === end - stride) {
- //Last vertex.
- if (closed) {
- //Same as the first vertex.
- p2 = startCoords;
- break;
- } else {
- p0 = p0 || [0, 0];
- numVertices = this.addVertices_(p0, p1, [0, 0],
- lastSign * ol.render.webgl.LineStringReplay.Instruction_.END_LINE * (lineCap || 1), numVertices);
- numVertices = this.addVertices_(p0, p1, [0, 0],
- -lastSign * ol.render.webgl.LineStringReplay.Instruction_.END_LINE * (lineCap || 1), numVertices);
- this.indices[numIndices++] = n;
- this.indices[numIndices++] = lastIndex - 1;
- this.indices[numIndices++] = lastIndex;
- this.indices[numIndices++] = lastIndex;
- this.indices[numIndices++] = n + 1;
- this.indices[numIndices++] = n;
- if (lineCap) {
- numVertices = this.addVertices_(p0, p1, [0, 0],
- lastSign * ol.render.webgl.LineStringReplay.Instruction_.END_LINE_CAP * lineCap, numVertices);
- numVertices = this.addVertices_(p0, p1, [0, 0],
- -lastSign * ol.render.webgl.LineStringReplay.Instruction_.END_LINE_CAP * lineCap, numVertices);
- this.indices[numIndices++] = n + 2;
- this.indices[numIndices++] = n;
- this.indices[numIndices++] = n + 1;
- this.indices[numIndices++] = n + 1;
- this.indices[numIndices++] = n + 3;
- this.indices[numIndices++] = n + 2;
- }
- break;
- }
- } else {
- p2 = [flatCoordinates[i + stride], flatCoordinates[i + stride + 1]];
- }
- // We group CW and straight lines, thus the not so inituitive CCW checking function.
- sign = ol.render.webgl.triangleIsCounterClockwise(p0[0], p0[1], p1[0], p1[1], p2[0], p2[1])
- ? -1 : 1;
- numVertices = this.addVertices_(p0, p1, p2,
- sign * ol.render.webgl.LineStringReplay.Instruction_.BEVEL_FIRST * (lineJoin || 1), numVertices);
- numVertices = this.addVertices_(p0, p1, p2,
- sign * ol.render.webgl.LineStringReplay.Instruction_.BEVEL_SECOND * (lineJoin || 1), numVertices);
- numVertices = this.addVertices_(p0, p1, p2,
- -sign * ol.render.webgl.LineStringReplay.Instruction_.MITER_BOTTOM * (lineJoin || 1), numVertices);
- if (i > offset) {
- this.indices[numIndices++] = n;
- this.indices[numIndices++] = lastIndex - 1;
- this.indices[numIndices++] = lastIndex;
- this.indices[numIndices++] = n + 2;
- this.indices[numIndices++] = n;
- this.indices[numIndices++] = lastSign * sign > 0 ? lastIndex : lastIndex - 1;
- }
- this.indices[numIndices++] = n;
- this.indices[numIndices++] = n + 2;
- this.indices[numIndices++] = n + 1;
- lastIndex = n + 2;
- lastSign = sign;
- //Add miter
- if (lineJoin) {
- numVertices = this.addVertices_(p0, p1, p2,
- sign * ol.render.webgl.LineStringReplay.Instruction_.MITER_TOP * lineJoin, numVertices);
- this.indices[numIndices++] = n + 1;
- this.indices[numIndices++] = n + 3;
- this.indices[numIndices++] = n;
- }
- }
- if (closed) {
- n = n || numVertices / 7;
- sign = ol.geom.flat.orient.linearRingIsClockwise([p0[0], p0[1], p1[0], p1[1], p2[0], p2[1]], 0, 6, 2)
- ? 1 : -1;
- numVertices = this.addVertices_(p0, p1, p2,
- sign * ol.render.webgl.LineStringReplay.Instruction_.BEVEL_FIRST * (lineJoin || 1), numVertices);
- numVertices = this.addVertices_(p0, p1, p2,
- -sign * ol.render.webgl.LineStringReplay.Instruction_.MITER_BOTTOM * (lineJoin || 1), numVertices);
- this.indices[numIndices++] = n;
- this.indices[numIndices++] = lastIndex - 1;
- this.indices[numIndices++] = lastIndex;
- this.indices[numIndices++] = n + 1;
- this.indices[numIndices++] = n;
- this.indices[numIndices++] = lastSign * sign > 0 ? lastIndex : lastIndex - 1;
- }
- };
- /**
- * @param {Array.<number>} p0 Last coordinates.
- * @param {Array.<number>} p1 Current coordinates.
- * @param {Array.<number>} p2 Next coordinates.
- * @param {number} product Sign, instruction, and rounding product.
- * @param {number} numVertices Vertex counter.
- * @return {number} Vertex counter.
- * @private
- */
- ol.render.webgl.LineStringReplay.prototype.addVertices_ = function(p0, p1, p2, product, numVertices) {
- this.vertices[numVertices++] = p0[0];
- this.vertices[numVertices++] = p0[1];
- this.vertices[numVertices++] = p1[0];
- this.vertices[numVertices++] = p1[1];
- this.vertices[numVertices++] = p2[0];
- this.vertices[numVertices++] = p2[1];
- this.vertices[numVertices++] = product;
- return numVertices;
- };
- /**
- * Check if the linestring can be drawn (i. e. valid).
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @return {boolean} The linestring can be drawn.
- * @private
- */
- ol.render.webgl.LineStringReplay.prototype.isValid_ = function(flatCoordinates, offset, end, stride) {
- var range = end - offset;
- if (range < stride * 2) {
- return false;
- } else if (range === stride * 2) {
- var firstP = [flatCoordinates[offset], flatCoordinates[offset + 1]];
- var lastP = [flatCoordinates[offset + stride], flatCoordinates[offset + stride + 1]];
- return !ol.array.equals(firstP, lastP);
- }
- return true;
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.LineStringReplay.prototype.drawLineString = function(lineStringGeometry, feature) {
- var flatCoordinates = lineStringGeometry.getFlatCoordinates();
- var stride = lineStringGeometry.getStride();
- if (this.isValid_(flatCoordinates, 0, flatCoordinates.length, stride)) {
- flatCoordinates = ol.geom.flat.transform.translate(flatCoordinates, 0, flatCoordinates.length,
- stride, -this.origin[0], -this.origin[1]);
- if (this.state_.changed) {
- this.styleIndices_.push(this.indices.length);
- this.state_.changed = false;
- }
- this.startIndices.push(this.indices.length);
- this.startIndicesFeature.push(feature);
- this.drawCoordinates_(
- flatCoordinates, 0, flatCoordinates.length, stride);
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.LineStringReplay.prototype.drawMultiLineString = function(multiLineStringGeometry, feature) {
- var indexCount = this.indices.length;
- var ends = multiLineStringGeometry.getEnds();
- ends.unshift(0);
- var flatCoordinates = multiLineStringGeometry.getFlatCoordinates();
- var stride = multiLineStringGeometry.getStride();
- var i, ii;
- if (ends.length > 1) {
- for (i = 1, ii = ends.length; i < ii; ++i) {
- if (this.isValid_(flatCoordinates, ends[i - 1], ends[i], stride)) {
- var lineString = ol.geom.flat.transform.translate(flatCoordinates, ends[i - 1], ends[i],
- stride, -this.origin[0], -this.origin[1]);
- this.drawCoordinates_(
- lineString, 0, lineString.length, stride);
- }
- }
- }
- if (this.indices.length > indexCount) {
- this.startIndices.push(indexCount);
- this.startIndicesFeature.push(feature);
- if (this.state_.changed) {
- this.styleIndices_.push(indexCount);
- this.state_.changed = false;
- }
- }
- };
- /**
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {Array.<Array.<number>>} holeFlatCoordinates Hole flat coordinates.
- * @param {number} stride Stride.
- */
- ol.render.webgl.LineStringReplay.prototype.drawPolygonCoordinates = function(
- flatCoordinates, holeFlatCoordinates, stride) {
- if (!ol.geom.flat.topology.lineStringIsClosed(flatCoordinates, 0,
- flatCoordinates.length, stride)) {
- flatCoordinates.push(flatCoordinates[0]);
- flatCoordinates.push(flatCoordinates[1]);
- }
- this.drawCoordinates_(flatCoordinates, 0, flatCoordinates.length, stride);
- if (holeFlatCoordinates.length) {
- var i, ii;
- for (i = 0, ii = holeFlatCoordinates.length; i < ii; ++i) {
- if (!ol.geom.flat.topology.lineStringIsClosed(holeFlatCoordinates[i], 0,
- holeFlatCoordinates[i].length, stride)) {
- holeFlatCoordinates[i].push(holeFlatCoordinates[i][0]);
- holeFlatCoordinates[i].push(holeFlatCoordinates[i][1]);
- }
- this.drawCoordinates_(holeFlatCoordinates[i], 0,
- holeFlatCoordinates[i].length, stride);
- }
- }
- };
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @param {number=} opt_index Index count.
- */
- ol.render.webgl.LineStringReplay.prototype.setPolygonStyle = function(feature, opt_index) {
- var index = opt_index === undefined ? this.indices.length : opt_index;
- this.startIndices.push(index);
- this.startIndicesFeature.push(feature);
- if (this.state_.changed) {
- this.styleIndices_.push(index);
- this.state_.changed = false;
- }
- };
- /**
- * @return {number} Current index.
- */
- ol.render.webgl.LineStringReplay.prototype.getCurrentIndex = function() {
- return this.indices.length;
- };
- /**
- * @inheritDoc
- **/
- ol.render.webgl.LineStringReplay.prototype.finish = function(context) {
- // create, bind, and populate the vertices buffer
- this.verticesBuffer = new ol.webgl.Buffer(this.vertices);
- // create, bind, and populate the indices buffer
- this.indicesBuffer = new ol.webgl.Buffer(this.indices);
- this.startIndices.push(this.indices.length);
- //Clean up, if there is nothing to draw
- if (this.styleIndices_.length === 0 && this.styles_.length > 0) {
- this.styles_ = [];
- }
- this.vertices = null;
- this.indices = null;
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.LineStringReplay.prototype.getDeleteResourcesFunction = function(context) {
- var verticesBuffer = this.verticesBuffer;
- var indicesBuffer = this.indicesBuffer;
- return function() {
- context.deleteBuffer(verticesBuffer);
- context.deleteBuffer(indicesBuffer);
- };
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.LineStringReplay.prototype.setUpProgram = function(gl, context, size, pixelRatio) {
- // get the program
- var fragmentShader, vertexShader;
- fragmentShader = ol.render.webgl.linestringreplay.defaultshader.fragment;
- vertexShader = ol.render.webgl.linestringreplay.defaultshader.vertex;
- var program = context.getProgram(fragmentShader, vertexShader);
- // get the locations
- var locations;
- if (!this.defaultLocations_) {
- locations = new ol.render.webgl.linestringreplay.defaultshader.Locations(gl, program);
- this.defaultLocations_ = locations;
- } else {
- locations = this.defaultLocations_;
- }
- context.useProgram(program);
- // enable the vertex attrib arrays
- gl.enableVertexAttribArray(locations.a_lastPos);
- gl.vertexAttribPointer(locations.a_lastPos, 2, ol.webgl.FLOAT,
- false, 28, 0);
- gl.enableVertexAttribArray(locations.a_position);
- gl.vertexAttribPointer(locations.a_position, 2, ol.webgl.FLOAT,
- false, 28, 8);
- gl.enableVertexAttribArray(locations.a_nextPos);
- gl.vertexAttribPointer(locations.a_nextPos, 2, ol.webgl.FLOAT,
- false, 28, 16);
- gl.enableVertexAttribArray(locations.a_direction);
- gl.vertexAttribPointer(locations.a_direction, 1, ol.webgl.FLOAT,
- false, 28, 24);
- // Enable renderer specific uniforms.
- gl.uniform2fv(locations.u_size, size);
- gl.uniform1f(locations.u_pixelRatio, pixelRatio);
- return locations;
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.LineStringReplay.prototype.shutDownProgram = function(gl, locations) {
- gl.disableVertexAttribArray(locations.a_lastPos);
- gl.disableVertexAttribArray(locations.a_position);
- gl.disableVertexAttribArray(locations.a_nextPos);
- gl.disableVertexAttribArray(locations.a_direction);
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.LineStringReplay.prototype.drawReplay = function(gl, context, skippedFeaturesHash, hitDetection) {
- //Save GL parameters.
- var tmpDepthFunc = /** @type {number} */ (gl.getParameter(gl.DEPTH_FUNC));
- var tmpDepthMask = /** @type {boolean} */ (gl.getParameter(gl.DEPTH_WRITEMASK));
- if (!hitDetection) {
- gl.enable(gl.DEPTH_TEST);
- gl.depthMask(true);
- gl.depthFunc(gl.NOTEQUAL);
- }
- if (!ol.obj.isEmpty(skippedFeaturesHash)) {
- this.drawReplaySkipping_(gl, context, skippedFeaturesHash);
- } else {
- //Draw by style groups to minimize drawElements() calls.
- var i, start, end, nextStyle;
- end = this.startIndices[this.startIndices.length - 1];
- for (i = this.styleIndices_.length - 1; i >= 0; --i) {
- start = this.styleIndices_[i];
- nextStyle = this.styles_[i];
- this.setStrokeStyle_(gl, nextStyle[0], nextStyle[1], nextStyle[2]);
- this.drawElements(gl, context, start, end);
- gl.clear(gl.DEPTH_BUFFER_BIT);
- end = start;
- }
- }
- if (!hitDetection) {
- gl.disable(gl.DEPTH_TEST);
- gl.clear(gl.DEPTH_BUFFER_BIT);
- //Restore GL parameters.
- gl.depthMask(tmpDepthMask);
- gl.depthFunc(tmpDepthFunc);
- }
- };
- /**
- * @private
- * @param {WebGLRenderingContext} gl gl.
- * @param {ol.webgl.Context} context Context.
- * @param {Object} skippedFeaturesHash Ids of features to skip.
- */
- ol.render.webgl.LineStringReplay.prototype.drawReplaySkipping_ = function(gl, context, skippedFeaturesHash) {
- var i, start, end, nextStyle, groupStart, feature, featureUid, featureIndex, featureStart;
- featureIndex = this.startIndices.length - 2;
- end = start = this.startIndices[featureIndex + 1];
- for (i = this.styleIndices_.length - 1; i >= 0; --i) {
- nextStyle = this.styles_[i];
- this.setStrokeStyle_(gl, nextStyle[0], nextStyle[1], nextStyle[2]);
- groupStart = this.styleIndices_[i];
- while (featureIndex >= 0 &&
- this.startIndices[featureIndex] >= groupStart) {
- featureStart = this.startIndices[featureIndex];
- feature = this.startIndicesFeature[featureIndex];
- featureUid = ol.getUid(feature).toString();
- if (skippedFeaturesHash[featureUid]) {
- if (start !== end) {
- this.drawElements(gl, context, start, end);
- gl.clear(gl.DEPTH_BUFFER_BIT);
- }
- end = featureStart;
- }
- featureIndex--;
- start = featureStart;
- }
- if (start !== end) {
- this.drawElements(gl, context, start, end);
- gl.clear(gl.DEPTH_BUFFER_BIT);
- }
- start = end = groupStart;
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.LineStringReplay.prototype.drawHitDetectionReplayOneByOne = function(gl, context, skippedFeaturesHash,
- featureCallback, opt_hitExtent) {
- var i, start, end, nextStyle, groupStart, feature, featureUid, featureIndex;
- featureIndex = this.startIndices.length - 2;
- end = this.startIndices[featureIndex + 1];
- for (i = this.styleIndices_.length - 1; i >= 0; --i) {
- nextStyle = this.styles_[i];
- this.setStrokeStyle_(gl, nextStyle[0], nextStyle[1], nextStyle[2]);
- groupStart = this.styleIndices_[i];
- while (featureIndex >= 0 &&
- this.startIndices[featureIndex] >= groupStart) {
- start = this.startIndices[featureIndex];
- feature = this.startIndicesFeature[featureIndex];
- featureUid = ol.getUid(feature).toString();
- if (skippedFeaturesHash[featureUid] === undefined &&
- feature.getGeometry() &&
- (opt_hitExtent === undefined || ol.extent.intersects(
- /** @type {Array<number>} */ (opt_hitExtent),
- feature.getGeometry().getExtent()))) {
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
- this.drawElements(gl, context, start, end);
- var result = featureCallback(feature);
- if (result) {
- return result;
- }
- }
- featureIndex--;
- end = start;
- }
- }
- return undefined;
- };
- /**
- * @private
- * @param {WebGLRenderingContext} gl gl.
- * @param {Array.<number>} color Color.
- * @param {number} lineWidth Line width.
- * @param {number} miterLimit Miter limit.
- */
- ol.render.webgl.LineStringReplay.prototype.setStrokeStyle_ = function(gl, color, lineWidth, miterLimit) {
- gl.uniform4fv(this.defaultLocations_.u_color, color);
- gl.uniform1f(this.defaultLocations_.u_lineWidth, lineWidth);
- gl.uniform1f(this.defaultLocations_.u_miterLimit, miterLimit);
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.LineStringReplay.prototype.setFillStrokeStyle = function(fillStyle, strokeStyle) {
- var strokeStyleLineCap = strokeStyle.getLineCap();
- this.state_.lineCap = strokeStyleLineCap !== undefined ?
- strokeStyleLineCap : ol.render.webgl.defaultLineCap;
- var strokeStyleLineDash = strokeStyle.getLineDash();
- this.state_.lineDash = strokeStyleLineDash ?
- strokeStyleLineDash : ol.render.webgl.defaultLineDash;
- var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();
- this.state_.lineDashOffset = strokeStyleLineDashOffset ?
- strokeStyleLineDashOffset : ol.render.webgl.defaultLineDashOffset;
- var strokeStyleLineJoin = strokeStyle.getLineJoin();
- this.state_.lineJoin = strokeStyleLineJoin !== undefined ?
- strokeStyleLineJoin : ol.render.webgl.defaultLineJoin;
- var strokeStyleColor = strokeStyle.getColor();
- if (!(strokeStyleColor instanceof CanvasGradient) &&
- !(strokeStyleColor instanceof CanvasPattern)) {
- strokeStyleColor = ol.color.asArray(strokeStyleColor).map(function(c, i) {
- return i != 3 ? c / 255 : c;
- }) || ol.render.webgl.defaultStrokeStyle;
- } else {
- strokeStyleColor = ol.render.webgl.defaultStrokeStyle;
- }
- var strokeStyleWidth = strokeStyle.getWidth();
- strokeStyleWidth = strokeStyleWidth !== undefined ?
- strokeStyleWidth : ol.render.webgl.defaultLineWidth;
- var strokeStyleMiterLimit = strokeStyle.getMiterLimit();
- strokeStyleMiterLimit = strokeStyleMiterLimit !== undefined ?
- strokeStyleMiterLimit : ol.render.webgl.defaultMiterLimit;
- if (!this.state_.strokeColor || !ol.array.equals(this.state_.strokeColor, strokeStyleColor) ||
- this.state_.lineWidth !== strokeStyleWidth || this.state_.miterLimit !== strokeStyleMiterLimit) {
- this.state_.changed = true;
- this.state_.strokeColor = strokeStyleColor;
- this.state_.lineWidth = strokeStyleWidth;
- this.state_.miterLimit = strokeStyleMiterLimit;
- this.styles_.push([strokeStyleColor, strokeStyleWidth, strokeStyleMiterLimit]);
- }
- };
- /**
- * @enum {number}
- * @private
- */
- ol.render.webgl.LineStringReplay.Instruction_ = {
- ROUND: 2,
- BEGIN_LINE: 3,
- END_LINE: 5,
- BEGIN_LINE_CAP: 7,
- END_LINE_CAP: 11,
- BEVEL_FIRST: 13,
- BEVEL_SECOND: 17,
- MITER_BOTTOM: 19,
- MITER_TOP: 23
- };
- // This file is automatically generated, do not edit
- goog.provide('ol.render.webgl.polygonreplay.defaultshader');
- goog.require('ol');
- goog.require('ol.webgl.Fragment');
- goog.require('ol.webgl.Vertex');
- ol.render.webgl.polygonreplay.defaultshader.fragment = new ol.webgl.Fragment(ol.DEBUG_WEBGL ?
- 'precision mediump float;\n\n\n\nuniform vec4 u_color;\nuniform float u_opacity;\n\nvoid main(void) {\n gl_FragColor = u_color;\n float alpha = u_color.a * u_opacity;\n if (alpha == 0.0) {\n discard;\n }\n gl_FragColor.a = alpha;\n}\n' :
- 'precision mediump float;uniform vec4 e;uniform float f;void main(void){gl_FragColor=e;float alpha=e.a*f;if(alpha==0.0){discard;}gl_FragColor.a=alpha;}');
- ol.render.webgl.polygonreplay.defaultshader.vertex = new ol.webgl.Vertex(ol.DEBUG_WEBGL ?
- '\n\nattribute vec2 a_position;\n\nuniform mat4 u_projectionMatrix;\nuniform mat4 u_offsetScaleMatrix;\nuniform mat4 u_offsetRotateMatrix;\n\nvoid main(void) {\n gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0);\n}\n\n\n' :
- 'attribute vec2 a;uniform mat4 b;uniform mat4 c;uniform mat4 d;void main(void){gl_Position=b*vec4(a,0.0,1.0);}');
- // This file is automatically generated, do not edit
- goog.provide('ol.render.webgl.polygonreplay.defaultshader.Locations');
- goog.require('ol');
- /**
- * @constructor
- * @param {WebGLRenderingContext} gl GL.
- * @param {WebGLProgram} program Program.
- * @struct
- */
- ol.render.webgl.polygonreplay.defaultshader.Locations = function(gl, program) {
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_projectionMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'b');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_offsetScaleMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'c');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_offsetRotateMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'd');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_color = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_color' : 'e');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_opacity = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_opacity' : 'f');
- /**
- * @type {number}
- */
- this.a_position = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_position' : 'a');
- };
- goog.provide('ol.structs.LinkedList');
- /**
- * Creates an empty linked list structure.
- *
- * @constructor
- * @struct
- * @param {boolean=} opt_circular The last item is connected to the first one,
- * and the first item to the last one. Default is true.
- */
- ol.structs.LinkedList = function(opt_circular) {
- /**
- * @private
- * @type {ol.LinkedListItem|undefined}
- */
- this.first_ = undefined;
- /**
- * @private
- * @type {ol.LinkedListItem|undefined}
- */
- this.last_ = undefined;
- /**
- * @private
- * @type {ol.LinkedListItem|undefined}
- */
- this.head_ = undefined;
- /**
- * @private
- * @type {boolean}
- */
- this.circular_ = opt_circular === undefined ? true : opt_circular;
- /**
- * @private
- * @type {number}
- */
- this.length_ = 0;
- };
- /**
- * Inserts an item into the linked list right after the current one.
- *
- * @param {?} data Item data.
- */
- ol.structs.LinkedList.prototype.insertItem = function(data) {
- /** @type {ol.LinkedListItem} */
- var item = {
- prev: undefined,
- next: undefined,
- data: data
- };
- var head = this.head_;
- //Initialize the list.
- if (!head) {
- this.first_ = item;
- this.last_ = item;
- if (this.circular_) {
- item.next = item;
- item.prev = item;
- }
- } else {
- //Link the new item to the adjacent ones.
- var next = head.next;
- item.prev = head;
- item.next = next;
- head.next = item;
- if (next) {
- next.prev = item;
- }
- if (head === this.last_) {
- this.last_ = item;
- }
- }
- this.head_ = item;
- this.length_++;
- };
- /**
- * Removes the current item from the list. Sets the cursor to the next item,
- * if possible.
- */
- ol.structs.LinkedList.prototype.removeItem = function() {
- var head = this.head_;
- if (head) {
- var next = head.next;
- var prev = head.prev;
- if (next) {
- next.prev = prev;
- }
- if (prev) {
- prev.next = next;
- }
- this.head_ = next || prev;
- if (this.first_ === this.last_) {
- this.head_ = undefined;
- this.first_ = undefined;
- this.last_ = undefined;
- } else if (this.first_ === head) {
- this.first_ = this.head_;
- } else if (this.last_ === head) {
- this.last_ = prev ? this.head_.prev : this.head_;
- }
- this.length_--;
- }
- };
- /**
- * Sets the cursor to the first item, and returns the associated data.
- *
- * @return {?} Item data.
- */
- ol.structs.LinkedList.prototype.firstItem = function() {
- this.head_ = this.first_;
- if (this.head_) {
- return this.head_.data;
- }
- return undefined;
- };
- /**
- * Sets the cursor to the last item, and returns the associated data.
- *
- * @return {?} Item data.
- */
- ol.structs.LinkedList.prototype.lastItem = function() {
- this.head_ = this.last_;
- if (this.head_) {
- return this.head_.data;
- }
- return undefined;
- };
- /**
- * Sets the cursor to the next item, and returns the associated data.
- *
- * @return {?} Item data.
- */
- ol.structs.LinkedList.prototype.nextItem = function() {
- if (this.head_ && this.head_.next) {
- this.head_ = this.head_.next;
- return this.head_.data;
- }
- return undefined;
- };
- /**
- * Returns the next item's data without moving the cursor.
- *
- * @return {?} Item data.
- */
- ol.structs.LinkedList.prototype.getNextItem = function() {
- if (this.head_ && this.head_.next) {
- return this.head_.next.data;
- }
- return undefined;
- };
- /**
- * Sets the cursor to the previous item, and returns the associated data.
- *
- * @return {?} Item data.
- */
- ol.structs.LinkedList.prototype.prevItem = function() {
- if (this.head_ && this.head_.prev) {
- this.head_ = this.head_.prev;
- return this.head_.data;
- }
- return undefined;
- };
- /**
- * Returns the previous item's data without moving the cursor.
- *
- * @return {?} Item data.
- */
- ol.structs.LinkedList.prototype.getPrevItem = function() {
- if (this.head_ && this.head_.prev) {
- return this.head_.prev.data;
- }
- return undefined;
- };
- /**
- * Returns the current item's data.
- *
- * @return {?} Item data.
- */
- ol.structs.LinkedList.prototype.getCurrItem = function() {
- if (this.head_) {
- return this.head_.data;
- }
- return undefined;
- };
- /**
- * Sets the first item of the list. This only works for circular lists, and sets
- * the last item accordingly.
- */
- ol.structs.LinkedList.prototype.setFirstItem = function() {
- if (this.circular_ && this.head_) {
- this.first_ = this.head_;
- this.last_ = this.head_.prev;
- }
- };
- /**
- * Concatenates two lists.
- * @param {ol.structs.LinkedList} list List to merge into the current list.
- */
- ol.structs.LinkedList.prototype.concat = function(list) {
- if (list.head_) {
- if (this.head_) {
- var end = this.head_.next;
- this.head_.next = list.first_;
- list.first_.prev = this.head_;
- end.prev = list.last_;
- list.last_.next = end;
- this.length_ += list.length_;
- } else {
- this.head_ = list.head_;
- this.first_ = list.first_;
- this.last_ = list.last_;
- this.length_ = list.length_;
- }
- list.head_ = undefined;
- list.first_ = undefined;
- list.last_ = undefined;
- list.length_ = 0;
- }
- };
- /**
- * Returns the current length of the list.
- *
- * @return {number} Length.
- */
- ol.structs.LinkedList.prototype.getLength = function() {
- return this.length_;
- };
- goog.provide('ol.render.webgl.PolygonReplay');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.color');
- goog.require('ol.extent');
- goog.require('ol.obj');
- goog.require('ol.geom.flat.contains');
- goog.require('ol.geom.flat.orient');
- goog.require('ol.geom.flat.transform');
- goog.require('ol.render.webgl.polygonreplay.defaultshader');
- goog.require('ol.render.webgl.polygonreplay.defaultshader.Locations');
- goog.require('ol.render.webgl.LineStringReplay');
- goog.require('ol.render.webgl.Replay');
- goog.require('ol.render.webgl');
- goog.require('ol.style.Stroke');
- goog.require('ol.structs.LinkedList');
- goog.require('ol.structs.RBush');
- goog.require('ol.webgl');
- goog.require('ol.webgl.Buffer');
- /**
- * @constructor
- * @extends {ol.render.webgl.Replay}
- * @param {number} tolerance Tolerance.
- * @param {ol.Extent} maxExtent Max extent.
- * @struct
- */
- ol.render.webgl.PolygonReplay = function(tolerance, maxExtent) {
- ol.render.webgl.Replay.call(this, tolerance, maxExtent);
- this.lineStringReplay = new ol.render.webgl.LineStringReplay(
- tolerance, maxExtent);
- /**
- * @private
- * @type {ol.render.webgl.polygonreplay.defaultshader.Locations}
- */
- this.defaultLocations_ = null;
- /**
- * @private
- * @type {Array.<Array.<number>>}
- */
- this.styles_ = [];
- /**
- * @private
- * @type {Array.<number>}
- */
- this.styleIndices_ = [];
- /**
- * @private
- * @type {{fillColor: (Array.<number>|null),
- * changed: boolean}|null}
- */
- this.state_ = {
- fillColor: null,
- changed: false
- };
- };
- ol.inherits(ol.render.webgl.PolygonReplay, ol.render.webgl.Replay);
- /**
- * Draw one polygon.
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {Array.<Array.<number>>} holeFlatCoordinates Hole flat coordinates.
- * @param {number} stride Stride.
- * @private
- */
- ol.render.webgl.PolygonReplay.prototype.drawCoordinates_ = function(
- flatCoordinates, holeFlatCoordinates, stride) {
- // Triangulate the polygon
- var outerRing = new ol.structs.LinkedList();
- var rtree = new ol.structs.RBush();
- // Initialize the outer ring
- this.processFlatCoordinates_(flatCoordinates, stride, outerRing, rtree, true);
- var maxCoords = this.getMaxCoords_(outerRing);
- // Eliminate holes, if there are any
- if (holeFlatCoordinates.length) {
- var i, ii;
- var holeLists = [];
- for (i = 0, ii = holeFlatCoordinates.length; i < ii; ++i) {
- var holeList = {
- list: new ol.structs.LinkedList(),
- maxCoords: undefined,
- rtree: new ol.structs.RBush()
- };
- holeLists.push(holeList);
- this.processFlatCoordinates_(holeFlatCoordinates[i],
- stride, holeList.list, holeList.rtree, false);
- this.classifyPoints_(holeList.list, holeList.rtree, true);
- holeList.maxCoords = this.getMaxCoords_(holeList.list);
- }
- holeLists.sort(function(a, b) {
- return b.maxCoords[0] === a.maxCoords[0] ?
- a.maxCoords[1] - b.maxCoords[1] : b.maxCoords[0] - a.maxCoords[0];
- });
- for (i = 0; i < holeLists.length; ++i) {
- var currList = holeLists[i].list;
- var start = currList.firstItem();
- var currItem = start;
- var intersection;
- do {
- //TODO: Triangulate holes when they intersect the outer ring.
- if (this.getIntersections_(currItem, rtree).length) {
- intersection = true;
- break;
- }
- currItem = currList.nextItem();
- } while (start !== currItem);
- if (!intersection) {
- if (this.bridgeHole_(currList, holeLists[i].maxCoords[0], outerRing, maxCoords[0], rtree)) {
- rtree.concat(holeLists[i].rtree);
- this.classifyPoints_(outerRing, rtree, false);
- }
- }
- }
- } else {
- this.classifyPoints_(outerRing, rtree, false);
- }
- this.triangulate_(outerRing, rtree);
- };
- /**
- * Inserts flat coordinates in a linked list and adds them to the vertex buffer.
- * @private
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} stride Stride.
- * @param {ol.structs.LinkedList} list Linked list.
- * @param {ol.structs.RBush} rtree R-Tree of the polygon.
- * @param {boolean} clockwise Coordinate order should be clockwise.
- */
- ol.render.webgl.PolygonReplay.prototype.processFlatCoordinates_ = function(
- flatCoordinates, stride, list, rtree, clockwise) {
- var isClockwise = ol.geom.flat.orient.linearRingIsClockwise(flatCoordinates,
- 0, flatCoordinates.length, stride);
- var i, ii;
- var n = this.vertices.length / 2;
- /** @type {ol.WebglPolygonVertex} */
- var start;
- /** @type {ol.WebglPolygonVertex} */
- var p0;
- /** @type {ol.WebglPolygonVertex} */
- var p1;
- var extents = [];
- var segments = [];
- if (clockwise === isClockwise) {
- start = this.createPoint_(flatCoordinates[0], flatCoordinates[1], n++);
- p0 = start;
- for (i = stride, ii = flatCoordinates.length; i < ii; i += stride) {
- p1 = this.createPoint_(flatCoordinates[i], flatCoordinates[i + 1], n++);
- segments.push(this.insertItem_(p0, p1, list));
- extents.push([Math.min(p0.x, p1.x), Math.min(p0.y, p1.y), Math.max(p0.x, p1.x),
- Math.max(p0.y, p1.y)]);
- p0 = p1;
- }
- segments.push(this.insertItem_(p1, start, list));
- extents.push([Math.min(p0.x, p1.x), Math.min(p0.y, p1.y), Math.max(p0.x, p1.x),
- Math.max(p0.y, p1.y)]);
- } else {
- var end = flatCoordinates.length - stride;
- start = this.createPoint_(flatCoordinates[end], flatCoordinates[end + 1], n++);
- p0 = start;
- for (i = end - stride, ii = 0; i >= ii; i -= stride) {
- p1 = this.createPoint_(flatCoordinates[i], flatCoordinates[i + 1], n++);
- segments.push(this.insertItem_(p0, p1, list));
- extents.push([Math.min(p0.x, p1.x), Math.min(p0.y, p1.y), Math.max(p0.x, p1.x),
- Math.max(p0.y, p1.y)]);
- p0 = p1;
- }
- segments.push(this.insertItem_(p1, start, list));
- extents.push([Math.min(p0.x, p1.x), Math.min(p0.y, p1.y), Math.max(p0.x, p1.x),
- Math.max(p0.y, p1.y)]);
- }
- rtree.load(extents, segments);
- };
- /**
- * Returns the rightmost coordinates of a polygon on the X axis.
- * @private
- * @param {ol.structs.LinkedList} list Polygons ring.
- * @return {Array.<number>} Max X coordinates.
- */
- ol.render.webgl.PolygonReplay.prototype.getMaxCoords_ = function(list) {
- var start = list.firstItem();
- var seg = start;
- var maxCoords = [seg.p0.x, seg.p0.y];
- do {
- seg = list.nextItem();
- if (seg.p0.x > maxCoords[0]) {
- maxCoords = [seg.p0.x, seg.p0.y];
- }
- } while (seg !== start);
- return maxCoords;
- };
- /**
- * Classifies the points of a polygon list as convex, reflex. Removes collinear vertices.
- * @private
- * @param {ol.structs.LinkedList} list Polygon ring.
- * @param {ol.structs.RBush} rtree R-Tree of the polygon.
- * @param {boolean} ccw The orientation of the polygon is counter-clockwise.
- * @return {boolean} There were reclassified points.
- */
- ol.render.webgl.PolygonReplay.prototype.classifyPoints_ = function(list, rtree, ccw) {
- var start = list.firstItem();
- var s0 = start;
- var s1 = list.nextItem();
- var pointsReclassified = false;
- do {
- var reflex = ccw ? ol.render.webgl.triangleIsCounterClockwise(s1.p1.x,
- s1.p1.y, s0.p1.x, s0.p1.y, s0.p0.x, s0.p0.y) :
- ol.render.webgl.triangleIsCounterClockwise(s0.p0.x, s0.p0.y, s0.p1.x,
- s0.p1.y, s1.p1.x, s1.p1.y);
- if (reflex === undefined) {
- this.removeItem_(s0, s1, list, rtree);
- pointsReclassified = true;
- if (s1 === start) {
- start = list.getNextItem();
- }
- s1 = s0;
- list.prevItem();
- } else if (s0.p1.reflex !== reflex) {
- s0.p1.reflex = reflex;
- pointsReclassified = true;
- }
- s0 = s1;
- s1 = list.nextItem();
- } while (s0 !== start);
- return pointsReclassified;
- };
- /**
- * @private
- * @param {ol.structs.LinkedList} hole Linked list of the hole.
- * @param {number} holeMaxX Maximum X value of the hole.
- * @param {ol.structs.LinkedList} list Linked list of the polygon.
- * @param {number} listMaxX Maximum X value of the polygon.
- * @param {ol.structs.RBush} rtree R-Tree of the polygon.
- * @return {boolean} Bridging was successful.
- */
- ol.render.webgl.PolygonReplay.prototype.bridgeHole_ = function(hole, holeMaxX,
- list, listMaxX, rtree) {
- var seg = hole.firstItem();
- while (seg.p1.x !== holeMaxX) {
- seg = hole.nextItem();
- }
- var p1 = seg.p1;
- /** @type {ol.WebglPolygonVertex} */
- var p2 = {x: listMaxX, y: p1.y, i: -1};
- var minDist = Infinity;
- var i, ii, bestPoint;
- /** @type {ol.WebglPolygonVertex} */
- var p5;
- var intersectingSegments = this.getIntersections_({p0: p1, p1: p2}, rtree, true);
- for (i = 0, ii = intersectingSegments.length; i < ii; ++i) {
- var currSeg = intersectingSegments[i];
- var intersection = this.calculateIntersection_(p1, p2, currSeg.p0,
- currSeg.p1, true);
- var dist = Math.abs(p1.x - intersection[0]);
- if (dist < minDist && ol.render.webgl.triangleIsCounterClockwise(p1.x, p1.y,
- currSeg.p0.x, currSeg.p0.y, currSeg.p1.x, currSeg.p1.y) !== undefined) {
- minDist = dist;
- p5 = {x: intersection[0], y: intersection[1], i: -1};
- seg = currSeg;
- }
- }
- if (minDist === Infinity) {
- return false;
- }
- bestPoint = seg.p1;
- if (minDist > 0) {
- var pointsInTriangle = this.getPointsInTriangle_(p1, p5, seg.p1, rtree);
- if (pointsInTriangle.length) {
- var theta = Infinity;
- for (i = 0, ii = pointsInTriangle.length; i < ii; ++i) {
- var currPoint = pointsInTriangle[i];
- var currTheta = Math.atan2(p1.y - currPoint.y, p2.x - currPoint.x);
- if (currTheta < theta || (currTheta === theta && currPoint.x < bestPoint.x)) {
- theta = currTheta;
- bestPoint = currPoint;
- }
- }
- }
- }
- seg = list.firstItem();
- while (seg.p1.x !== bestPoint.x || seg.p1.y !== bestPoint.y) {
- seg = list.nextItem();
- }
- //We clone the bridge points as they can have different convexity.
- var p0Bridge = {x: p1.x, y: p1.y, i: p1.i, reflex: undefined};
- var p1Bridge = {x: seg.p1.x, y: seg.p1.y, i: seg.p1.i, reflex: undefined};
- hole.getNextItem().p0 = p0Bridge;
- this.insertItem_(p1, seg.p1, hole, rtree);
- this.insertItem_(p1Bridge, p0Bridge, hole, rtree);
- seg.p1 = p1Bridge;
- hole.setFirstItem();
- list.concat(hole);
- return true;
- };
- /**
- * @private
- * @param {ol.structs.LinkedList} list Linked list of the polygon.
- * @param {ol.structs.RBush} rtree R-Tree of the polygon.
- */
- ol.render.webgl.PolygonReplay.prototype.triangulate_ = function(list, rtree) {
- var ccw = false;
- var simple = this.isSimple_(list, rtree);
- // Start clipping ears
- while (list.getLength() > 3) {
- if (simple) {
- if (!this.clipEars_(list, rtree, simple, ccw)) {
- if (!this.classifyPoints_(list, rtree, ccw)) {
- // Due to the behavior of OL's PIP algorithm, the ear clipping cannot
- // introduce touching segments. However, the original data may have some.
- if (!this.resolveSelfIntersections_(list, rtree, true)) {
- break;
- }
- }
- }
- } else {
- if (!this.clipEars_(list, rtree, simple, ccw)) {
- // We ran out of ears, try to reclassify.
- if (!this.classifyPoints_(list, rtree, ccw)) {
- // We have a bad polygon, try to resolve local self-intersections.
- if (!this.resolveSelfIntersections_(list, rtree)) {
- simple = this.isSimple_(list, rtree);
- if (!simple) {
- // We have a really bad polygon, try more time consuming methods.
- this.splitPolygon_(list, rtree);
- break;
- } else {
- ccw = !this.isClockwise_(list);
- this.classifyPoints_(list, rtree, ccw);
- }
- }
- }
- }
- }
- }
- if (list.getLength() === 3) {
- var numIndices = this.indices.length;
- this.indices[numIndices++] = list.getPrevItem().p0.i;
- this.indices[numIndices++] = list.getCurrItem().p0.i;
- this.indices[numIndices++] = list.getNextItem().p0.i;
- }
- };
- /**
- * @private
- * @param {ol.structs.LinkedList} list Linked list of the polygon.
- * @param {ol.structs.RBush} rtree R-Tree of the polygon.
- * @param {boolean} simple The polygon is simple.
- * @param {boolean} ccw Orientation of the polygon is counter-clockwise.
- * @return {boolean} There were processed ears.
- */
- ol.render.webgl.PolygonReplay.prototype.clipEars_ = function(list, rtree, simple, ccw) {
- var numIndices = this.indices.length;
- var start = list.firstItem();
- var s0 = list.getPrevItem();
- var s1 = start;
- var s2 = list.nextItem();
- var s3 = list.getNextItem();
- var p0, p1, p2;
- var processedEars = false;
- do {
- p0 = s1.p0;
- p1 = s1.p1;
- p2 = s2.p1;
- if (p1.reflex === false) {
- // We might have a valid ear
- var variableCriterion;
- if (simple) {
- variableCriterion = this.getPointsInTriangle_(p0, p1, p2, rtree, true).length === 0;
- } else {
- variableCriterion = ccw ? this.diagonalIsInside_(s3.p1, p2, p1, p0,
- s0.p0) : this.diagonalIsInside_(s0.p0, p0, p1, p2, s3.p1);
- }
- if ((simple || this.getIntersections_({p0: p0, p1: p2}, rtree).length === 0) &&
- variableCriterion) {
- //The diagonal is completely inside the polygon
- if (simple || p0.reflex === false || p2.reflex === false ||
- ol.geom.flat.orient.linearRingIsClockwise([s0.p0.x, s0.p0.y, p0.x,
- p0.y, p1.x, p1.y, p2.x, p2.y, s3.p1.x, s3.p1.y], 0, 10, 2) === !ccw) {
- //The diagonal is persumably valid, we have an ear
- this.indices[numIndices++] = p0.i;
- this.indices[numIndices++] = p1.i;
- this.indices[numIndices++] = p2.i;
- this.removeItem_(s1, s2, list, rtree);
- if (s2 === start) {
- start = s3;
- }
- processedEars = true;
- }
- }
- }
- // Else we have a reflex point.
- s0 = list.getPrevItem();
- s1 = list.getCurrItem();
- s2 = list.nextItem();
- s3 = list.getNextItem();
- } while (s1 !== start && list.getLength() > 3);
- return processedEars;
- };
- /**
- * @private
- * @param {ol.structs.LinkedList} list Linked list of the polygon.
- * @param {ol.structs.RBush} rtree R-Tree of the polygon.
- * @param {boolean=} opt_touch Resolve touching segments.
- * @return {boolean} There were resolved intersections.
- */
- ol.render.webgl.PolygonReplay.prototype.resolveSelfIntersections_ = function(
- list, rtree, opt_touch) {
- var start = list.firstItem();
- list.nextItem();
- var s0 = start;
- var s1 = list.nextItem();
- var resolvedIntersections = false;
- do {
- var intersection = this.calculateIntersection_(s0.p0, s0.p1, s1.p0, s1.p1,
- opt_touch);
- if (intersection) {
- var breakCond = false;
- var numVertices = this.vertices.length;
- var numIndices = this.indices.length;
- var n = numVertices / 2;
- var seg = list.prevItem();
- list.removeItem();
- rtree.remove(seg);
- breakCond = (seg === start);
- var p;
- if (opt_touch) {
- if (intersection[0] === s0.p0.x && intersection[1] === s0.p0.y) {
- list.prevItem();
- p = s0.p0;
- s1.p0 = p;
- rtree.remove(s0);
- breakCond = breakCond || (s0 === start);
- } else {
- p = s1.p1;
- s0.p1 = p;
- rtree.remove(s1);
- breakCond = breakCond || (s1 === start);
- }
- list.removeItem();
- } else {
- p = this.createPoint_(intersection[0], intersection[1], n);
- s0.p1 = p;
- s1.p0 = p;
- rtree.update([Math.min(s0.p0.x, s0.p1.x), Math.min(s0.p0.y, s0.p1.y),
- Math.max(s0.p0.x, s0.p1.x), Math.max(s0.p0.y, s0.p1.y)], s0);
- rtree.update([Math.min(s1.p0.x, s1.p1.x), Math.min(s1.p0.y, s1.p1.y),
- Math.max(s1.p0.x, s1.p1.x), Math.max(s1.p0.y, s1.p1.y)], s1);
- }
- this.indices[numIndices++] = seg.p0.i;
- this.indices[numIndices++] = seg.p1.i;
- this.indices[numIndices++] = p.i;
- resolvedIntersections = true;
- if (breakCond) {
- break;
- }
- }
- s0 = list.getPrevItem();
- s1 = list.nextItem();
- } while (s0 !== start);
- return resolvedIntersections;
- };
- /**
- * @private
- * @param {ol.structs.LinkedList} list Linked list of the polygon.
- * @param {ol.structs.RBush} rtree R-Tree of the polygon.
- * @return {boolean} The polygon is simple.
- */
- ol.render.webgl.PolygonReplay.prototype.isSimple_ = function(list, rtree) {
- var start = list.firstItem();
- var seg = start;
- do {
- if (this.getIntersections_(seg, rtree).length) {
- return false;
- }
- seg = list.nextItem();
- } while (seg !== start);
- return true;
- };
- /**
- * @private
- * @param {ol.structs.LinkedList} list Linked list of the polygon.
- * @return {boolean} Orientation is clockwise.
- */
- ol.render.webgl.PolygonReplay.prototype.isClockwise_ = function(list) {
- var length = list.getLength() * 2;
- var flatCoordinates = new Array(length);
- var start = list.firstItem();
- var seg = start;
- var i = 0;
- do {
- flatCoordinates[i++] = seg.p0.x;
- flatCoordinates[i++] = seg.p0.y;
- seg = list.nextItem();
- } while (seg !== start);
- return ol.geom.flat.orient.linearRingIsClockwise(flatCoordinates, 0, length, 2);
- };
- /**
- * @private
- * @param {ol.structs.LinkedList} list Linked list of the polygon.
- * @param {ol.structs.RBush} rtree R-Tree of the polygon.
- */
- ol.render.webgl.PolygonReplay.prototype.splitPolygon_ = function(list, rtree) {
- var start = list.firstItem();
- var s0 = start;
- do {
- var intersections = this.getIntersections_(s0, rtree);
- if (intersections.length) {
- var s1 = intersections[0];
- var n = this.vertices.length / 2;
- var intersection = this.calculateIntersection_(s0.p0,
- s0.p1, s1.p0, s1.p1);
- var p = this.createPoint_(intersection[0], intersection[1], n);
- var newPolygon = new ol.structs.LinkedList();
- var newRtree = new ol.structs.RBush();
- this.insertItem_(p, s0.p1, newPolygon, newRtree);
- s0.p1 = p;
- rtree.update([Math.min(s0.p0.x, p.x), Math.min(s0.p0.y, p.y),
- Math.max(s0.p0.x, p.x), Math.max(s0.p0.y, p.y)], s0);
- var currItem = list.nextItem();
- while (currItem !== s1) {
- this.insertItem_(currItem.p0, currItem.p1, newPolygon, newRtree);
- rtree.remove(currItem);
- list.removeItem();
- currItem = list.getCurrItem();
- }
- this.insertItem_(s1.p0, p, newPolygon, newRtree);
- s1.p0 = p;
- rtree.update([Math.min(s1.p1.x, p.x), Math.min(s1.p1.y, p.y),
- Math.max(s1.p1.x, p.x), Math.max(s1.p1.y, p.y)], s1);
- this.classifyPoints_(list, rtree, false);
- this.triangulate_(list, rtree);
- this.classifyPoints_(newPolygon, newRtree, false);
- this.triangulate_(newPolygon, newRtree);
- break;
- }
- s0 = list.nextItem();
- } while (s0 !== start);
- };
- /**
- * @private
- * @param {number} x X coordinate.
- * @param {number} y Y coordinate.
- * @param {number} i Index.
- * @return {ol.WebglPolygonVertex} List item.
- */
- ol.render.webgl.PolygonReplay.prototype.createPoint_ = function(x, y, i) {
- var numVertices = this.vertices.length;
- this.vertices[numVertices++] = x;
- this.vertices[numVertices++] = y;
- /** @type {ol.WebglPolygonVertex} */
- var p = {
- x: x,
- y: y,
- i: i,
- reflex: undefined
- };
- return p;
- };
- /**
- * @private
- * @param {ol.WebglPolygonVertex} p0 First point of segment.
- * @param {ol.WebglPolygonVertex} p1 Second point of segment.
- * @param {ol.structs.LinkedList} list Polygon ring.
- * @param {ol.structs.RBush=} opt_rtree Insert the segment into the R-Tree.
- * @return {ol.WebglPolygonSegment} segment.
- */
- ol.render.webgl.PolygonReplay.prototype.insertItem_ = function(p0, p1, list, opt_rtree) {
- var seg = {
- p0: p0,
- p1: p1
- };
- list.insertItem(seg);
- if (opt_rtree) {
- opt_rtree.insert([Math.min(p0.x, p1.x), Math.min(p0.y, p1.y),
- Math.max(p0.x, p1.x), Math.max(p0.y, p1.y)], seg);
- }
- return seg;
- };
- /**
- * @private
- * @param {ol.WebglPolygonSegment} s0 Segment before the remove candidate.
- * @param {ol.WebglPolygonSegment} s1 Remove candidate segment.
- * @param {ol.structs.LinkedList} list Polygon ring.
- * @param {ol.structs.RBush} rtree R-Tree of the polygon.
- */
- ol.render.webgl.PolygonReplay.prototype.removeItem_ = function(s0, s1, list, rtree) {
- if (list.getCurrItem() === s1) {
- list.removeItem();
- s0.p1 = s1.p1;
- rtree.remove(s1);
- rtree.update([Math.min(s0.p0.x, s0.p1.x), Math.min(s0.p0.y, s0.p1.y),
- Math.max(s0.p0.x, s0.p1.x), Math.max(s0.p0.y, s0.p1.y)], s0);
- }
- };
- /**
- * @private
- * @param {ol.WebglPolygonVertex} p0 First point.
- * @param {ol.WebglPolygonVertex} p1 Second point.
- * @param {ol.WebglPolygonVertex} p2 Third point.
- * @param {ol.structs.RBush} rtree R-Tree of the polygon.
- * @param {boolean=} opt_reflex Only include reflex points.
- * @return {Array.<ol.WebglPolygonVertex>} Points in the triangle.
- */
- ol.render.webgl.PolygonReplay.prototype.getPointsInTriangle_ = function(p0, p1,
- p2, rtree, opt_reflex) {
- var i, ii, j, p;
- var result = [];
- var segmentsInExtent = rtree.getInExtent([Math.min(p0.x, p1.x, p2.x),
- Math.min(p0.y, p1.y, p2.y), Math.max(p0.x, p1.x, p2.x), Math.max(p0.y,
- p1.y, p2.y)]);
- for (i = 0, ii = segmentsInExtent.length; i < ii; ++i) {
- for (j in segmentsInExtent[i]) {
- p = segmentsInExtent[i][j];
- if (typeof p === 'object' && (!opt_reflex || p.reflex)) {
- if ((p.x !== p0.x || p.y !== p0.y) && (p.x !== p1.x || p.y !== p1.y) &&
- (p.x !== p2.x || p.y !== p2.y) && result.indexOf(p) === -1 &&
- ol.geom.flat.contains.linearRingContainsXY([p0.x, p0.y, p1.x, p1.y,
- p2.x, p2.y], 0, 6, 2, p.x, p.y)) {
- result.push(p);
- }
- }
- }
- }
- return result;
- };
- /**
- * @private
- * @param {ol.WebglPolygonSegment} segment Segment.
- * @param {ol.structs.RBush} rtree R-Tree of the polygon.
- * @param {boolean=} opt_touch Touching segments should be considered an intersection.
- * @return {Array.<ol.WebglPolygonSegment>} Intersecting segments.
- */
- ol.render.webgl.PolygonReplay.prototype.getIntersections_ = function(segment, rtree, opt_touch) {
- var p0 = segment.p0;
- var p1 = segment.p1;
- var segmentsInExtent = rtree.getInExtent([Math.min(p0.x, p1.x),
- Math.min(p0.y, p1.y), Math.max(p0.x, p1.x), Math.max(p0.y, p1.y)]);
- var result = [];
- var i, ii;
- for (i = 0, ii = segmentsInExtent.length; i < ii; ++i) {
- var currSeg = segmentsInExtent[i];
- if (segment !== currSeg && (opt_touch || currSeg.p0 !== p1 || currSeg.p1 !== p0) &&
- this.calculateIntersection_(p0, p1, currSeg.p0, currSeg.p1, opt_touch)) {
- result.push(currSeg);
- }
- }
- return result;
- };
- /**
- * Line intersection algorithm by Paul Bourke.
- * @see http://paulbourke.net/geometry/pointlineplane/
- *
- * @private
- * @param {ol.WebglPolygonVertex} p0 First point.
- * @param {ol.WebglPolygonVertex} p1 Second point.
- * @param {ol.WebglPolygonVertex} p2 Third point.
- * @param {ol.WebglPolygonVertex} p3 Fourth point.
- * @param {boolean=} opt_touch Touching segments should be considered an intersection.
- * @return {Array.<number>|undefined} Intersection coordinates.
- */
- ol.render.webgl.PolygonReplay.prototype.calculateIntersection_ = function(p0,
- p1, p2, p3, opt_touch) {
- var denom = (p3.y - p2.y) * (p1.x - p0.x) - (p3.x - p2.x) * (p1.y - p0.y);
- if (denom !== 0) {
- var ua = ((p3.x - p2.x) * (p0.y - p2.y) - (p3.y - p2.y) * (p0.x - p2.x)) / denom;
- var ub = ((p1.x - p0.x) * (p0.y - p2.y) - (p1.y - p0.y) * (p0.x - p2.x)) / denom;
- if ((!opt_touch && ua > ol.render.webgl.EPSILON && ua < 1 - ol.render.webgl.EPSILON &&
- ub > ol.render.webgl.EPSILON && ub < 1 - ol.render.webgl.EPSILON) || (opt_touch &&
- ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1)) {
- return [p0.x + ua * (p1.x - p0.x), p0.y + ua * (p1.y - p0.y)];
- }
- }
- return undefined;
- };
- /**
- * @private
- * @param {ol.WebglPolygonVertex} p0 Point before the start of the diagonal.
- * @param {ol.WebglPolygonVertex} p1 Start point of the diagonal.
- * @param {ol.WebglPolygonVertex} p2 Ear candidate.
- * @param {ol.WebglPolygonVertex} p3 End point of the diagonal.
- * @param {ol.WebglPolygonVertex} p4 Point after the end of the diagonal.
- * @return {boolean} Diagonal is inside the polygon.
- */
- ol.render.webgl.PolygonReplay.prototype.diagonalIsInside_ = function(p0, p1, p2, p3, p4) {
- if (p1.reflex === undefined || p3.reflex === undefined) {
- return false;
- }
- var p1IsLeftOf = (p2.x - p3.x) * (p1.y - p3.y) > (p2.y - p3.y) * (p1.x - p3.x);
- var p1IsRightOf = (p4.x - p3.x) * (p1.y - p3.y) < (p4.y - p3.y) * (p1.x - p3.x);
- var p3IsLeftOf = (p0.x - p1.x) * (p3.y - p1.y) > (p0.y - p1.y) * (p3.x - p1.x);
- var p3IsRightOf = (p2.x - p1.x) * (p3.y - p1.y) < (p2.y - p1.y) * (p3.x - p1.x);
- var p1InCone = p3.reflex ? p1IsRightOf || p1IsLeftOf : p1IsRightOf && p1IsLeftOf;
- var p3InCone = p1.reflex ? p3IsRightOf || p3IsLeftOf : p3IsRightOf && p3IsLeftOf;
- return p1InCone && p3InCone;
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.PolygonReplay.prototype.drawMultiPolygon = function(multiPolygonGeometry, feature) {
- var endss = multiPolygonGeometry.getEndss();
- var stride = multiPolygonGeometry.getStride();
- var currIndex = this.indices.length;
- var currLineIndex = this.lineStringReplay.getCurrentIndex();
- var flatCoordinates = multiPolygonGeometry.getFlatCoordinates();
- var i, ii, j, jj;
- var start = 0;
- for (i = 0, ii = endss.length; i < ii; ++i) {
- var ends = endss[i];
- if (ends.length > 0) {
- var outerRing = ol.geom.flat.transform.translate(flatCoordinates, start, ends[0],
- stride, -this.origin[0], -this.origin[1]);
- if (outerRing.length) {
- var holes = [];
- var holeFlatCoords;
- for (j = 1, jj = ends.length; j < jj; ++j) {
- if (ends[j] !== ends[j - 1]) {
- holeFlatCoords = ol.geom.flat.transform.translate(flatCoordinates, ends[j - 1],
- ends[j], stride, -this.origin[0], -this.origin[1]);
- holes.push(holeFlatCoords);
- }
- }
- this.lineStringReplay.drawPolygonCoordinates(outerRing, holes, stride);
- this.drawCoordinates_(outerRing, holes, stride);
- }
- }
- start = ends[ends.length - 1];
- }
- if (this.indices.length > currIndex) {
- this.startIndices.push(currIndex);
- this.startIndicesFeature.push(feature);
- if (this.state_.changed) {
- this.styleIndices_.push(currIndex);
- this.state_.changed = false;
- }
- }
- if (this.lineStringReplay.getCurrentIndex() > currLineIndex) {
- this.lineStringReplay.setPolygonStyle(feature, currLineIndex);
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.PolygonReplay.prototype.drawPolygon = function(polygonGeometry, feature) {
- var ends = polygonGeometry.getEnds();
- var stride = polygonGeometry.getStride();
- if (ends.length > 0) {
- var flatCoordinates = polygonGeometry.getFlatCoordinates().map(Number);
- var outerRing = ol.geom.flat.transform.translate(flatCoordinates, 0, ends[0],
- stride, -this.origin[0], -this.origin[1]);
- if (outerRing.length) {
- var holes = [];
- var i, ii, holeFlatCoords;
- for (i = 1, ii = ends.length; i < ii; ++i) {
- if (ends[i] !== ends[i - 1]) {
- holeFlatCoords = ol.geom.flat.transform.translate(flatCoordinates, ends[i - 1],
- ends[i], stride, -this.origin[0], -this.origin[1]);
- holes.push(holeFlatCoords);
- }
- }
- this.startIndices.push(this.indices.length);
- this.startIndicesFeature.push(feature);
- if (this.state_.changed) {
- this.styleIndices_.push(this.indices.length);
- this.state_.changed = false;
- }
- this.lineStringReplay.setPolygonStyle(feature);
- this.lineStringReplay.drawPolygonCoordinates(outerRing, holes, stride);
- this.drawCoordinates_(outerRing, holes, stride);
- }
- }
- };
- /**
- * @inheritDoc
- **/
- ol.render.webgl.PolygonReplay.prototype.finish = function(context) {
- // create, bind, and populate the vertices buffer
- this.verticesBuffer = new ol.webgl.Buffer(this.vertices);
- // create, bind, and populate the indices buffer
- this.indicesBuffer = new ol.webgl.Buffer(this.indices);
- this.startIndices.push(this.indices.length);
- this.lineStringReplay.finish(context);
- //Clean up, if there is nothing to draw
- if (this.styleIndices_.length === 0 && this.styles_.length > 0) {
- this.styles_ = [];
- }
- this.vertices = null;
- this.indices = null;
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.PolygonReplay.prototype.getDeleteResourcesFunction = function(context) {
- var verticesBuffer = this.verticesBuffer;
- var indicesBuffer = this.indicesBuffer;
- var lineDeleter = this.lineStringReplay.getDeleteResourcesFunction(context);
- return function() {
- context.deleteBuffer(verticesBuffer);
- context.deleteBuffer(indicesBuffer);
- lineDeleter();
- };
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.PolygonReplay.prototype.setUpProgram = function(gl, context, size, pixelRatio) {
- // get the program
- var fragmentShader, vertexShader;
- fragmentShader = ol.render.webgl.polygonreplay.defaultshader.fragment;
- vertexShader = ol.render.webgl.polygonreplay.defaultshader.vertex;
- var program = context.getProgram(fragmentShader, vertexShader);
- // get the locations
- var locations;
- if (!this.defaultLocations_) {
- locations = new ol.render.webgl.polygonreplay.defaultshader.Locations(gl, program);
- this.defaultLocations_ = locations;
- } else {
- locations = this.defaultLocations_;
- }
- context.useProgram(program);
- // enable the vertex attrib arrays
- gl.enableVertexAttribArray(locations.a_position);
- gl.vertexAttribPointer(locations.a_position, 2, ol.webgl.FLOAT,
- false, 8, 0);
- return locations;
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.PolygonReplay.prototype.shutDownProgram = function(gl, locations) {
- gl.disableVertexAttribArray(locations.a_position);
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.PolygonReplay.prototype.drawReplay = function(gl, context, skippedFeaturesHash, hitDetection) {
- //Save GL parameters.
- var tmpDepthFunc = /** @type {number} */ (gl.getParameter(gl.DEPTH_FUNC));
- var tmpDepthMask = /** @type {boolean} */ (gl.getParameter(gl.DEPTH_WRITEMASK));
- if (!hitDetection) {
- gl.enable(gl.DEPTH_TEST);
- gl.depthMask(true);
- gl.depthFunc(gl.NOTEQUAL);
- }
- if (!ol.obj.isEmpty(skippedFeaturesHash)) {
- this.drawReplaySkipping_(gl, context, skippedFeaturesHash);
- } else {
- //Draw by style groups to minimize drawElements() calls.
- var i, start, end, nextStyle;
- end = this.startIndices[this.startIndices.length - 1];
- for (i = this.styleIndices_.length - 1; i >= 0; --i) {
- start = this.styleIndices_[i];
- nextStyle = this.styles_[i];
- this.setFillStyle_(gl, nextStyle);
- this.drawElements(gl, context, start, end);
- end = start;
- }
- }
- if (!hitDetection) {
- gl.disable(gl.DEPTH_TEST);
- gl.clear(gl.DEPTH_BUFFER_BIT);
- //Restore GL parameters.
- gl.depthMask(tmpDepthMask);
- gl.depthFunc(tmpDepthFunc);
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.PolygonReplay.prototype.drawHitDetectionReplayOneByOne = function(gl, context, skippedFeaturesHash,
- featureCallback, opt_hitExtent) {
- var i, start, end, nextStyle, groupStart, feature, featureUid, featureIndex;
- featureIndex = this.startIndices.length - 2;
- end = this.startIndices[featureIndex + 1];
- for (i = this.styleIndices_.length - 1; i >= 0; --i) {
- nextStyle = this.styles_[i];
- this.setFillStyle_(gl, nextStyle);
- groupStart = this.styleIndices_[i];
- while (featureIndex >= 0 &&
- this.startIndices[featureIndex] >= groupStart) {
- start = this.startIndices[featureIndex];
- feature = this.startIndicesFeature[featureIndex];
- featureUid = ol.getUid(feature).toString();
- if (skippedFeaturesHash[featureUid] === undefined &&
- feature.getGeometry() &&
- (opt_hitExtent === undefined || ol.extent.intersects(
- /** @type {Array<number>} */ (opt_hitExtent),
- feature.getGeometry().getExtent()))) {
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
- this.drawElements(gl, context, start, end);
- var result = featureCallback(feature);
- if (result) {
- return result;
- }
- }
- featureIndex--;
- end = start;
- }
- }
- return undefined;
- };
- /**
- * @private
- * @param {WebGLRenderingContext} gl gl.
- * @param {ol.webgl.Context} context Context.
- * @param {Object} skippedFeaturesHash Ids of features to skip.
- */
- ol.render.webgl.PolygonReplay.prototype.drawReplaySkipping_ = function(gl, context, skippedFeaturesHash) {
- var i, start, end, nextStyle, groupStart, feature, featureUid, featureIndex, featureStart;
- featureIndex = this.startIndices.length - 2;
- end = start = this.startIndices[featureIndex + 1];
- for (i = this.styleIndices_.length - 1; i >= 0; --i) {
- nextStyle = this.styles_[i];
- this.setFillStyle_(gl, nextStyle);
- groupStart = this.styleIndices_[i];
- while (featureIndex >= 0 &&
- this.startIndices[featureIndex] >= groupStart) {
- featureStart = this.startIndices[featureIndex];
- feature = this.startIndicesFeature[featureIndex];
- featureUid = ol.getUid(feature).toString();
- if (skippedFeaturesHash[featureUid]) {
- if (start !== end) {
- this.drawElements(gl, context, start, end);
- gl.clear(gl.DEPTH_BUFFER_BIT);
- }
- end = featureStart;
- }
- featureIndex--;
- start = featureStart;
- }
- if (start !== end) {
- this.drawElements(gl, context, start, end);
- gl.clear(gl.DEPTH_BUFFER_BIT);
- }
- start = end = groupStart;
- }
- };
- /**
- * @private
- * @param {WebGLRenderingContext} gl gl.
- * @param {Array.<number>} color Color.
- */
- ol.render.webgl.PolygonReplay.prototype.setFillStyle_ = function(gl, color) {
- gl.uniform4fv(this.defaultLocations_.u_color, color);
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.PolygonReplay.prototype.setFillStrokeStyle = function(fillStyle, strokeStyle) {
- var fillStyleColor = fillStyle ? fillStyle.getColor() : [0, 0, 0, 0];
- if (!(fillStyleColor instanceof CanvasGradient) &&
- !(fillStyleColor instanceof CanvasPattern)) {
- fillStyleColor = ol.color.asArray(fillStyleColor).map(function(c, i) {
- return i != 3 ? c / 255 : c;
- }) || ol.render.webgl.defaultFillStyle;
- } else {
- fillStyleColor = ol.render.webgl.defaultFillStyle;
- }
- if (!this.state_.fillColor || !ol.array.equals(fillStyleColor, this.state_.fillColor)) {
- this.state_.fillColor = fillStyleColor;
- this.state_.changed = true;
- this.styles_.push(fillStyleColor);
- }
- //Provide a null stroke style, if no strokeStyle is provided. Required for the draw interaction to work.
- if (strokeStyle) {
- this.lineStringReplay.setFillStrokeStyle(null, strokeStyle);
- } else {
- var nullStrokeStyle = new ol.style.Stroke({
- color: [0, 0, 0, 0],
- lineWidth: 0
- });
- this.lineStringReplay.setFillStrokeStyle(null, nullStrokeStyle);
- }
- };
- goog.provide('ol.style.Atlas');
- goog.require('ol.dom');
- /**
- * This class facilitates the creation of image atlases.
- *
- * Images added to an atlas will be rendered onto a single
- * atlas canvas. The distribution of images on the canvas is
- * managed with the bin packing algorithm described in:
- * http://www.blackpawn.com/texts/lightmaps/
- *
- * @constructor
- * @struct
- * @param {number} size The size in pixels of the sprite image.
- * @param {number} space The space in pixels between images.
- * Because texture coordinates are float values, the edges of
- * images might not be completely correct (in a way that the
- * edges overlap when being rendered). To avoid this we add a
- * padding around each image.
- */
- ol.style.Atlas = function(size, space) {
- /**
- * @private
- * @type {number}
- */
- this.space_ = space;
- /**
- * @private
- * @type {Array.<ol.AtlasBlock>}
- */
- this.emptyBlocks_ = [{x: 0, y: 0, width: size, height: size}];
- /**
- * @private
- * @type {Object.<string, ol.AtlasInfo>}
- */
- this.entries_ = {};
- /**
- * @private
- * @type {CanvasRenderingContext2D}
- */
- this.context_ = ol.dom.createCanvasContext2D(size, size);
- /**
- * @private
- * @type {HTMLCanvasElement}
- */
- this.canvas_ = this.context_.canvas;
- };
- /**
- * @param {string} id The identifier of the entry to check.
- * @return {?ol.AtlasInfo} The atlas info.
- */
- ol.style.Atlas.prototype.get = function(id) {
- return this.entries_[id] || null;
- };
- /**
- * @param {string} id The identifier of the entry to add.
- * @param {number} width The width.
- * @param {number} height The height.
- * @param {function(CanvasRenderingContext2D, number, number)} renderCallback
- * Called to render the new image onto an atlas image.
- * @param {Object=} opt_this Value to use as `this` when executing
- * `renderCallback`.
- * @return {?ol.AtlasInfo} The position and atlas image for the entry.
- */
- ol.style.Atlas.prototype.add = function(id, width, height, renderCallback, opt_this) {
- var block, i, ii;
- for (i = 0, ii = this.emptyBlocks_.length; i < ii; ++i) {
- block = this.emptyBlocks_[i];
- if (block.width >= width + this.space_ &&
- block.height >= height + this.space_) {
- // we found a block that is big enough for our entry
- var entry = {
- offsetX: block.x + this.space_,
- offsetY: block.y + this.space_,
- image: this.canvas_
- };
- this.entries_[id] = entry;
- // render the image on the atlas image
- renderCallback.call(opt_this, this.context_,
- block.x + this.space_, block.y + this.space_);
- // split the block after the insertion, either horizontally or vertically
- this.split_(i, block, width + this.space_, height + this.space_);
- return entry;
- }
- }
- // there is no space for the new entry in this atlas
- return null;
- };
- /**
- * @private
- * @param {number} index The index of the block.
- * @param {ol.AtlasBlock} block The block to split.
- * @param {number} width The width of the entry to insert.
- * @param {number} height The height of the entry to insert.
- */
- ol.style.Atlas.prototype.split_ = function(index, block, width, height) {
- var deltaWidth = block.width - width;
- var deltaHeight = block.height - height;
- /** @type {ol.AtlasBlock} */
- var newBlock1;
- /** @type {ol.AtlasBlock} */
- var newBlock2;
- if (deltaWidth > deltaHeight) {
- // split vertically
- // block right of the inserted entry
- newBlock1 = {
- x: block.x + width,
- y: block.y,
- width: block.width - width,
- height: block.height
- };
- // block below the inserted entry
- newBlock2 = {
- x: block.x,
- y: block.y + height,
- width: width,
- height: block.height - height
- };
- this.updateBlocks_(index, newBlock1, newBlock2);
- } else {
- // split horizontally
- // block right of the inserted entry
- newBlock1 = {
- x: block.x + width,
- y: block.y,
- width: block.width - width,
- height: height
- };
- // block below the inserted entry
- newBlock2 = {
- x: block.x,
- y: block.y + height,
- width: block.width,
- height: block.height - height
- };
- this.updateBlocks_(index, newBlock1, newBlock2);
- }
- };
- /**
- * Remove the old block and insert new blocks at the same array position.
- * The new blocks are inserted at the same position, so that splitted
- * blocks (that are potentially smaller) are filled first.
- * @private
- * @param {number} index The index of the block to remove.
- * @param {ol.AtlasBlock} newBlock1 The 1st block to add.
- * @param {ol.AtlasBlock} newBlock2 The 2nd block to add.
- */
- ol.style.Atlas.prototype.updateBlocks_ = function(index, newBlock1, newBlock2) {
- var args = [index, 1];
- if (newBlock1.width > 0 && newBlock1.height > 0) {
- args.push(newBlock1);
- }
- if (newBlock2.width > 0 && newBlock2.height > 0) {
- args.push(newBlock2);
- }
- this.emptyBlocks_.splice.apply(this.emptyBlocks_, args);
- };
- goog.provide('ol.style.AtlasManager');
- goog.require('ol');
- goog.require('ol.style.Atlas');
- /**
- * Manages the creation of image atlases.
- *
- * Images added to this manager will be inserted into an atlas, which
- * will be used for rendering.
- * The `size` given in the constructor is the size for the first
- * atlas. After that, when new atlases are created, they will have
- * twice the size as the latest atlas (until `maxSize` is reached).
- *
- * If an application uses many images or very large images, it is recommended
- * to set a higher `size` value to avoid the creation of too many atlases.
- *
- * @constructor
- * @struct
- * @api
- * @param {olx.style.AtlasManagerOptions=} opt_options Options.
- */
- ol.style.AtlasManager = function(opt_options) {
- var options = opt_options || {};
- /**
- * The size in pixels of the latest atlas image.
- * @private
- * @type {number}
- */
- this.currentSize_ = options.initialSize !== undefined ?
- options.initialSize : ol.INITIAL_ATLAS_SIZE;
- /**
- * The maximum size in pixels of atlas images.
- * @private
- * @type {number}
- */
- this.maxSize_ = options.maxSize !== undefined ?
- options.maxSize : ol.MAX_ATLAS_SIZE != -1 ?
- ol.MAX_ATLAS_SIZE : ol.WEBGL_MAX_TEXTURE_SIZE !== undefined ?
- ol.WEBGL_MAX_TEXTURE_SIZE : 2048;
- /**
- * The size in pixels between images.
- * @private
- * @type {number}
- */
- this.space_ = options.space !== undefined ? options.space : 1;
- /**
- * @private
- * @type {Array.<ol.style.Atlas>}
- */
- this.atlases_ = [new ol.style.Atlas(this.currentSize_, this.space_)];
- /**
- * The size in pixels of the latest atlas image for hit-detection images.
- * @private
- * @type {number}
- */
- this.currentHitSize_ = this.currentSize_;
- /**
- * @private
- * @type {Array.<ol.style.Atlas>}
- */
- this.hitAtlases_ = [new ol.style.Atlas(this.currentHitSize_, this.space_)];
- };
- /**
- * @param {string} id The identifier of the entry to check.
- * @return {?ol.AtlasManagerInfo} The position and atlas image for the
- * entry, or `null` if the entry is not part of the atlas manager.
- */
- ol.style.AtlasManager.prototype.getInfo = function(id) {
- /** @type {?ol.AtlasInfo} */
- var info = this.getInfo_(this.atlases_, id);
- if (!info) {
- return null;
- }
- var hitInfo = /** @type {ol.AtlasInfo} */ (this.getInfo_(this.hitAtlases_, id));
- return this.mergeInfos_(info, hitInfo);
- };
- /**
- * @private
- * @param {Array.<ol.style.Atlas>} atlases The atlases to search.
- * @param {string} id The identifier of the entry to check.
- * @return {?ol.AtlasInfo} The position and atlas image for the entry,
- * or `null` if the entry is not part of the atlases.
- */
- ol.style.AtlasManager.prototype.getInfo_ = function(atlases, id) {
- var atlas, info, i, ii;
- for (i = 0, ii = atlases.length; i < ii; ++i) {
- atlas = atlases[i];
- info = atlas.get(id);
- if (info) {
- return info;
- }
- }
- return null;
- };
- /**
- * @private
- * @param {ol.AtlasInfo} info The info for the real image.
- * @param {ol.AtlasInfo} hitInfo The info for the hit-detection
- * image.
- * @return {?ol.AtlasManagerInfo} The position and atlas image for the
- * entry, or `null` if the entry is not part of the atlases.
- */
- ol.style.AtlasManager.prototype.mergeInfos_ = function(info, hitInfo) {
- return /** @type {ol.AtlasManagerInfo} */ ({
- offsetX: info.offsetX,
- offsetY: info.offsetY,
- image: info.image,
- hitImage: hitInfo.image
- });
- };
- /**
- * Add an image to the atlas manager.
- *
- * If an entry for the given id already exists, the entry will
- * be overridden (but the space on the atlas graphic will not be freed).
- *
- * If `renderHitCallback` is provided, the image (or the hit-detection version
- * of the image) will be rendered into a separate hit-detection atlas image.
- *
- * @param {string} id The identifier of the entry to add.
- * @param {number} width The width.
- * @param {number} height The height.
- * @param {function(CanvasRenderingContext2D, number, number)} renderCallback
- * Called to render the new image onto an atlas image.
- * @param {function(CanvasRenderingContext2D, number, number)=}
- * opt_renderHitCallback Called to render a hit-detection image onto a hit
- * detection atlas image.
- * @param {Object=} opt_this Value to use as `this` when executing
- * `renderCallback` and `renderHitCallback`.
- * @return {?ol.AtlasManagerInfo} The position and atlas image for the
- * entry, or `null` if the image is too big.
- */
- ol.style.AtlasManager.prototype.add = function(id, width, height,
- renderCallback, opt_renderHitCallback, opt_this) {
- if (width + this.space_ > this.maxSize_ ||
- height + this.space_ > this.maxSize_) {
- return null;
- }
- /** @type {?ol.AtlasInfo} */
- var info = this.add_(false,
- id, width, height, renderCallback, opt_this);
- if (!info) {
- return null;
- }
- // even if no hit-detection entry is requested, we insert a fake entry into
- // the hit-detection atlas, to make sure that the offset is the same for
- // the original image and the hit-detection image.
- var renderHitCallback = opt_renderHitCallback !== undefined ?
- opt_renderHitCallback : ol.nullFunction;
- var hitInfo = /** @type {ol.AtlasInfo} */ (this.add_(true,
- id, width, height, renderHitCallback, opt_this));
- return this.mergeInfos_(info, hitInfo);
- };
- /**
- * @private
- * @param {boolean} isHitAtlas If the hit-detection atlases are used.
- * @param {string} id The identifier of the entry to add.
- * @param {number} width The width.
- * @param {number} height The height.
- * @param {function(CanvasRenderingContext2D, number, number)} renderCallback
- * Called to render the new image onto an atlas image.
- * @param {Object=} opt_this Value to use as `this` when executing
- * `renderCallback` and `renderHitCallback`.
- * @return {?ol.AtlasInfo} The position and atlas image for the entry,
- * or `null` if the image is too big.
- */
- ol.style.AtlasManager.prototype.add_ = function(isHitAtlas, id, width, height,
- renderCallback, opt_this) {
- var atlases = (isHitAtlas) ? this.hitAtlases_ : this.atlases_;
- var atlas, info, i, ii;
- for (i = 0, ii = atlases.length; i < ii; ++i) {
- atlas = atlases[i];
- info = atlas.add(id, width, height, renderCallback, opt_this);
- if (info) {
- return info;
- } else if (!info && i === ii - 1) {
- // the entry could not be added to one of the existing atlases,
- // create a new atlas that is twice as big and try to add to this one.
- var size;
- if (isHitAtlas) {
- size = Math.min(this.currentHitSize_ * 2, this.maxSize_);
- this.currentHitSize_ = size;
- } else {
- size = Math.min(this.currentSize_ * 2, this.maxSize_);
- this.currentSize_ = size;
- }
- atlas = new ol.style.Atlas(size, this.space_);
- atlases.push(atlas);
- // run the loop another time
- ++ii;
- }
- }
- return null;
- };
- goog.provide('ol.render.webgl.TextReplay');
- goog.require('ol');
- goog.require('ol.colorlike');
- goog.require('ol.dom');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.has');
- goog.require('ol.render.replay');
- goog.require('ol.render.webgl');
- goog.require('ol.render.webgl.TextureReplay');
- goog.require('ol.style.AtlasManager');
- goog.require('ol.webgl.Buffer');
- /**
- * @constructor
- * @extends {ol.render.webgl.TextureReplay}
- * @param {number} tolerance Tolerance.
- * @param {ol.Extent} maxExtent Max extent.
- * @struct
- */
- ol.render.webgl.TextReplay = function(tolerance, maxExtent) {
- ol.render.webgl.TextureReplay.call(this, tolerance, maxExtent);
- /**
- * @private
- * @type {Array.<HTMLCanvasElement>}
- */
- this.images_ = [];
- /**
- * @private
- * @type {Array.<WebGLTexture>}
- */
- this.textures_ = [];
- /**
- * @private
- * @type {HTMLCanvasElement}
- */
- this.measureCanvas_ = ol.dom.createCanvasContext2D(0, 0).canvas;
- /**
- * @private
- * @type {{strokeColor: (ol.ColorLike|null),
- * lineCap: (string|undefined),
- * lineDash: Array.<number>,
- * lineDashOffset: (number|undefined),
- * lineJoin: (string|undefined),
- * lineWidth: number,
- * miterLimit: (number|undefined),
- * fillColor: (ol.ColorLike|null),
- * font: (string|undefined),
- * scale: (number|undefined)}}
- */
- this.state_ = {
- strokeColor: null,
- lineCap: undefined,
- lineDash: null,
- lineDashOffset: undefined,
- lineJoin: undefined,
- lineWidth: 0,
- miterLimit: undefined,
- fillColor: null,
- font: undefined,
- scale: undefined
- };
- /**
- * @private
- * @type {string}
- */
- this.text_ = '';
- /**
- * @private
- * @type {number|undefined}
- */
- this.textAlign_ = undefined;
- /**
- * @private
- * @type {number|undefined}
- */
- this.textBaseline_ = undefined;
- /**
- * @private
- * @type {number|undefined}
- */
- this.offsetX_ = undefined;
- /**
- * @private
- * @type {number|undefined}
- */
- this.offsetY_ = undefined;
- /**
- * @private
- * @type {Object.<string, ol.WebglGlyphAtlas>}
- */
- this.atlases_ = {};
- /**
- * @private
- * @type {ol.WebglGlyphAtlas|undefined}
- */
- this.currAtlas_ = undefined;
- this.scale = 1;
- this.opacity = 1;
- };
- ol.inherits(ol.render.webgl.TextReplay, ol.render.webgl.TextureReplay);
- /**
- * @inheritDoc
- */
- ol.render.webgl.TextReplay.prototype.drawText = function(geometry, feature) {
- if (this.text_) {
- var flatCoordinates = null;
- var offset = 0;
- var end = 2;
- var stride = 2;
- switch (geometry.getType()) {
- case ol.geom.GeometryType.POINT:
- case ol.geom.GeometryType.MULTI_POINT:
- flatCoordinates = geometry.getFlatCoordinates();
- end = flatCoordinates.length;
- stride = geometry.getStride();
- break;
- case ol.geom.GeometryType.CIRCLE:
- flatCoordinates = /** @type {ol.geom.Circle} */ (geometry).getCenter();
- break;
- case ol.geom.GeometryType.LINE_STRING:
- flatCoordinates = /** @type {ol.geom.LineString} */ (geometry).getFlatMidpoint();
- break;
- case ol.geom.GeometryType.MULTI_LINE_STRING:
- flatCoordinates = /** @type {ol.geom.MultiLineString} */ (geometry).getFlatMidpoints();
- end = flatCoordinates.length;
- break;
- case ol.geom.GeometryType.POLYGON:
- flatCoordinates = /** @type {ol.geom.Polygon} */ (geometry).getFlatInteriorPoint();
- break;
- case ol.geom.GeometryType.MULTI_POLYGON:
- flatCoordinates = /** @type {ol.geom.MultiPolygon} */ (geometry).getFlatInteriorPoints();
- end = flatCoordinates.length;
- break;
- default:
- }
- this.startIndices.push(this.indices.length);
- this.startIndicesFeature.push(feature);
- var glyphAtlas = this.currAtlas_;
- var lines = this.text_.split('\n');
- var textSize = this.getTextSize_(lines);
- var i, ii, j, jj, currX, currY, charArr, charInfo;
- var anchorX = Math.round(textSize[0] * this.textAlign_ - this.offsetX_);
- var anchorY = Math.round(textSize[1] * this.textBaseline_ - this.offsetY_);
- var lineWidth = (this.state_.lineWidth / 2) * this.state_.scale;
- for (i = 0, ii = lines.length; i < ii; ++i) {
- currX = 0;
- currY = glyphAtlas.height * i;
- charArr = lines[i].split('');
- for (j = 0, jj = charArr.length; j < jj; ++j) {
- charInfo = glyphAtlas.atlas.getInfo(charArr[j]);
- if (charInfo) {
- var image = charInfo.image;
- this.anchorX = anchorX - currX;
- this.anchorY = anchorY - currY;
- this.originX = j === 0 ? charInfo.offsetX - lineWidth : charInfo.offsetX;
- this.originY = charInfo.offsetY;
- this.height = glyphAtlas.height;
- this.width = j === 0 || j === charArr.length - 1 ?
- glyphAtlas.width[charArr[j]] + lineWidth : glyphAtlas.width[charArr[j]];
- this.imageHeight = image.height;
- this.imageWidth = image.width;
- var currentImage;
- if (this.images_.length === 0) {
- this.images_.push(image);
- } else {
- currentImage = this.images_[this.images_.length - 1];
- if (ol.getUid(currentImage) != ol.getUid(image)) {
- this.groupIndices.push(this.indices.length);
- this.images_.push(image);
- }
- }
- this.drawText_(flatCoordinates, offset, end, stride);
- }
- currX += this.width;
- }
- }
- }
- };
- /**
- * @private
- * @param {Array.<string>} lines Label to draw split to lines.
- * @return {Array.<number>} Size of the label in pixels.
- */
- ol.render.webgl.TextReplay.prototype.getTextSize_ = function(lines) {
- var self = this;
- var glyphAtlas = this.currAtlas_;
- var textHeight = lines.length * glyphAtlas.height;
- //Split every line to an array of chars, sum up their width, and select the longest.
- var textWidth = lines.map(function(str) {
- var sum = 0;
- var i, ii;
- for (i = 0, ii = str.length; i < ii; ++i) {
- var curr = str[i];
- if (!glyphAtlas.width[curr]) {
- self.addCharToAtlas_(curr);
- }
- sum += glyphAtlas.width[curr] ? glyphAtlas.width[curr] : 0;
- }
- return sum;
- }).reduce(function(max, curr) {
- return Math.max(max, curr);
- });
- return [textWidth, textHeight];
- };
- /**
- * @private
- * @param {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- */
- ol.render.webgl.TextReplay.prototype.drawText_ = function(flatCoordinates, offset,
- end, stride) {
- var i, ii;
- for (i = offset, ii = end; i < ii; i += stride) {
- this.drawCoordinates(flatCoordinates, offset, end, stride);
- }
- };
- /**
- * @private
- * @param {string} char Character.
- */
- ol.render.webgl.TextReplay.prototype.addCharToAtlas_ = function(char) {
- if (char.length === 1) {
- var glyphAtlas = this.currAtlas_;
- var state = this.state_;
- var mCtx = this.measureCanvas_.getContext('2d');
- mCtx.font = state.font;
- var width = Math.ceil(mCtx.measureText(char).width * state.scale);
- var info = glyphAtlas.atlas.add(char, width, glyphAtlas.height,
- function(ctx, x, y) {
- //Parameterize the canvas
- ctx.font = /** @type {string} */ (state.font);
- ctx.fillStyle = state.fillColor;
- ctx.strokeStyle = state.strokeColor;
- ctx.lineWidth = state.lineWidth;
- ctx.lineCap = /*** @type {string} */ (state.lineCap);
- ctx.lineJoin = /** @type {string} */ (state.lineJoin);
- ctx.miterLimit = /** @type {number} */ (state.miterLimit);
- ctx.textAlign = 'left';
- ctx.textBaseline = 'top';
- if (ol.has.CANVAS_LINE_DASH && state.lineDash) {
- //FIXME: use pixelRatio
- ctx.setLineDash(state.lineDash);
- ctx.lineDashOffset = /** @type {number} */ (state.lineDashOffset);
- }
- if (state.scale !== 1) {
- //FIXME: use pixelRatio
- ctx.setTransform(/** @type {number} */ (state.scale), 0, 0,
- /** @type {number} */ (state.scale), 0, 0);
- }
- //Draw the character on the canvas
- if (state.strokeColor) {
- ctx.strokeText(char, x, y);
- }
- if (state.fillColor) {
- ctx.fillText(char, x, y);
- }
- });
- if (info) {
- glyphAtlas.width[char] = width;
- }
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.TextReplay.prototype.finish = function(context) {
- var gl = context.getGL();
- this.groupIndices.push(this.indices.length);
- this.hitDetectionGroupIndices = this.groupIndices;
- // create, bind, and populate the vertices buffer
- this.verticesBuffer = new ol.webgl.Buffer(this.vertices);
- // create, bind, and populate the indices buffer
- this.indicesBuffer = new ol.webgl.Buffer(this.indices);
- // create textures
- /** @type {Object.<string, WebGLTexture>} */
- var texturePerImage = {};
- this.createTextures(this.textures_, this.images_, texturePerImage, gl);
- this.state_ = {
- strokeColor: null,
- lineCap: undefined,
- lineDash: null,
- lineDashOffset: undefined,
- lineJoin: undefined,
- lineWidth: 0,
- miterLimit: undefined,
- fillColor: null,
- font: undefined,
- scale: undefined
- };
- this.text_ = '';
- this.textAlign_ = undefined;
- this.textBaseline_ = undefined;
- this.offsetX_ = undefined;
- this.offsetY_ = undefined;
- this.images_ = null;
- this.atlases_ = {};
- this.currAtlas_ = undefined;
- ol.render.webgl.TextureReplay.prototype.finish.call(this, context);
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.TextReplay.prototype.setTextStyle = function(textStyle) {
- var state = this.state_;
- var textFillStyle = textStyle.getFill();
- var textStrokeStyle = textStyle.getStroke();
- if (!textStyle || !textStyle.getText() || (!textFillStyle && !textStrokeStyle)) {
- this.text_ = '';
- } else {
- if (!textFillStyle) {
- state.fillColor = null;
- } else {
- var textFillStyleColor = textFillStyle.getColor();
- state.fillColor = ol.colorlike.asColorLike(textFillStyleColor ?
- textFillStyleColor : ol.render.webgl.defaultFillStyle);
- }
- if (!textStrokeStyle) {
- state.strokeColor = null;
- state.lineWidth = 0;
- } else {
- var textStrokeStyleColor = textStrokeStyle.getColor();
- state.strokeColor = ol.colorlike.asColorLike(textStrokeStyleColor ?
- textStrokeStyleColor : ol.render.webgl.defaultStrokeStyle);
- state.lineWidth = textStrokeStyle.getWidth() || ol.render.webgl.defaultLineWidth;
- state.lineCap = textStrokeStyle.getLineCap() || ol.render.webgl.defaultLineCap;
- state.lineDashOffset = textStrokeStyle.getLineDashOffset() || ol.render.webgl.defaultLineDashOffset;
- state.lineJoin = textStrokeStyle.getLineJoin() || ol.render.webgl.defaultLineJoin;
- state.miterLimit = textStrokeStyle.getMiterLimit() || ol.render.webgl.defaultMiterLimit;
- var lineDash = textStrokeStyle.getLineDash();
- state.lineDash = lineDash ? lineDash.slice() : ol.render.webgl.defaultLineDash;
- }
- state.font = textStyle.getFont() || ol.render.webgl.defaultFont;
- state.scale = textStyle.getScale() || 1;
- this.text_ = /** @type {string} */ (textStyle.getText());
- var textAlign = ol.render.replay.TEXT_ALIGN[textStyle.getTextAlign()];
- var textBaseline = ol.render.replay.TEXT_ALIGN[textStyle.getTextBaseline()];
- this.textAlign_ = textAlign === undefined ?
- ol.render.webgl.defaultTextAlign : textAlign;
- this.textBaseline_ = textBaseline === undefined ?
- ol.render.webgl.defaultTextBaseline : textBaseline;
- this.offsetX_ = textStyle.getOffsetX() || 0;
- this.offsetY_ = textStyle.getOffsetY() || 0;
- this.rotateWithView = !!textStyle.getRotateWithView();
- this.rotation = textStyle.getRotation() || 0;
- this.currAtlas_ = this.getAtlas_(state);
- }
- };
- /**
- * @private
- * @param {Object} state Font attributes.
- * @return {ol.WebglGlyphAtlas} Glyph atlas.
- */
- ol.render.webgl.TextReplay.prototype.getAtlas_ = function(state) {
- var params = [];
- var i;
- for (i in state) {
- if (state[i] || state[i] === 0) {
- if (Array.isArray(state[i])) {
- params = params.concat(state[i]);
- } else {
- params.push(state[i]);
- }
- }
- }
- var hash = this.calculateHash_(params);
- if (!this.atlases_[hash]) {
- var mCtx = this.measureCanvas_.getContext('2d');
- mCtx.font = state.font;
- var height = Math.ceil((mCtx.measureText('M').width * 1.5 +
- state.lineWidth / 2) * state.scale);
- this.atlases_[hash] = {
- atlas: new ol.style.AtlasManager({
- space: state.lineWidth + 1
- }),
- width: {},
- height: height
- };
- }
- return this.atlases_[hash];
- };
- /**
- * @private
- * @param {Array.<string|number>} params Array of parameters.
- * @return {string} Hash string.
- */
- ol.render.webgl.TextReplay.prototype.calculateHash_ = function(params) {
- //TODO: Create a more performant, reliable, general hash function.
- var i, ii;
- var hash = '';
- for (i = 0, ii = params.length; i < ii; ++i) {
- hash += params[i];
- }
- return hash;
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.TextReplay.prototype.getTextures = function(opt_all) {
- return this.textures_;
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.TextReplay.prototype.getHitDetectionTextures = function() {
- return this.textures_;
- };
- goog.provide('ol.render.webgl.ReplayGroup');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.extent');
- goog.require('ol.obj');
- goog.require('ol.render.replay');
- goog.require('ol.render.ReplayGroup');
- goog.require('ol.render.webgl.CircleReplay');
- goog.require('ol.render.webgl.ImageReplay');
- goog.require('ol.render.webgl.LineStringReplay');
- goog.require('ol.render.webgl.PolygonReplay');
- goog.require('ol.render.webgl.TextReplay');
- /**
- * @constructor
- * @extends {ol.render.ReplayGroup}
- * @param {number} tolerance Tolerance.
- * @param {ol.Extent} maxExtent Max extent.
- * @param {number=} opt_renderBuffer Render buffer.
- * @struct
- */
- ol.render.webgl.ReplayGroup = function(tolerance, maxExtent, opt_renderBuffer) {
- ol.render.ReplayGroup.call(this);
- /**
- * @type {ol.Extent}
- * @private
- */
- this.maxExtent_ = maxExtent;
- /**
- * @type {number}
- * @private
- */
- this.tolerance_ = tolerance;
- /**
- * @type {number|undefined}
- * @private
- */
- this.renderBuffer_ = opt_renderBuffer;
- /**
- * @private
- * @type {!Object.<string,
- * Object.<ol.render.ReplayType, ol.render.webgl.Replay>>}
- */
- this.replaysByZIndex_ = {};
- };
- ol.inherits(ol.render.webgl.ReplayGroup, ol.render.ReplayGroup);
- /**
- * @param {ol.style.Style} style Style.
- * @param {boolean} group Group with previous replay.
- */
- ol.render.webgl.ReplayGroup.prototype.addDeclutter = function(style, group) {};
- /**
- * @param {ol.webgl.Context} context WebGL context.
- * @return {function()} Delete resources function.
- */
- ol.render.webgl.ReplayGroup.prototype.getDeleteResourcesFunction = function(context) {
- var functions = [];
- var zKey;
- for (zKey in this.replaysByZIndex_) {
- var replays = this.replaysByZIndex_[zKey];
- var replayKey;
- for (replayKey in replays) {
- functions.push(
- replays[replayKey].getDeleteResourcesFunction(context));
- }
- }
- return function() {
- var length = functions.length;
- var result;
- for (var i = 0; i < length; i++) {
- result = functions[i].apply(this, arguments);
- }
- return result;
- };
- };
- /**
- * @param {ol.webgl.Context} context Context.
- */
- ol.render.webgl.ReplayGroup.prototype.finish = function(context) {
- var zKey;
- for (zKey in this.replaysByZIndex_) {
- var replays = this.replaysByZIndex_[zKey];
- var replayKey;
- for (replayKey in replays) {
- replays[replayKey].finish(context);
- }
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.ReplayGroup.prototype.getReplay = function(zIndex, replayType) {
- var zIndexKey = zIndex !== undefined ? zIndex.toString() : '0';
- var replays = this.replaysByZIndex_[zIndexKey];
- if (replays === undefined) {
- replays = {};
- this.replaysByZIndex_[zIndexKey] = replays;
- }
- var replay = replays[replayType];
- if (replay === undefined) {
- /**
- * @type {Function}
- */
- var Constructor = ol.render.webgl.ReplayGroup.BATCH_CONSTRUCTORS_[replayType];
- replay = new Constructor(this.tolerance_, this.maxExtent_);
- replays[replayType] = replay;
- }
- return replay;
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.ReplayGroup.prototype.isEmpty = function() {
- return ol.obj.isEmpty(this.replaysByZIndex_);
- };
- /**
- * @param {ol.webgl.Context} context Context.
- * @param {ol.Coordinate} center Center.
- * @param {number} resolution Resolution.
- * @param {number} rotation Rotation.
- * @param {ol.Size} size Size.
- * @param {number} pixelRatio Pixel ratio.
- * @param {number} opacity Global opacity.
- * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
- * to skip.
- */
- ol.render.webgl.ReplayGroup.prototype.replay = function(context,
- center, resolution, rotation, size, pixelRatio,
- opacity, skippedFeaturesHash) {
- /** @type {Array.<number>} */
- var zs = Object.keys(this.replaysByZIndex_).map(Number);
- zs.sort(ol.array.numberSafeCompareFunction);
- var i, ii, j, jj, replays, replay;
- for (i = 0, ii = zs.length; i < ii; ++i) {
- replays = this.replaysByZIndex_[zs[i].toString()];
- for (j = 0, jj = ol.render.replay.ORDER.length; j < jj; ++j) {
- replay = replays[ol.render.replay.ORDER[j]];
- if (replay !== undefined) {
- replay.replay(context,
- center, resolution, rotation, size, pixelRatio,
- opacity, skippedFeaturesHash,
- undefined, false);
- }
- }
- }
- };
- /**
- * @private
- * @param {ol.webgl.Context} context Context.
- * @param {ol.Coordinate} center Center.
- * @param {number} resolution Resolution.
- * @param {number} rotation Rotation.
- * @param {ol.Size} size Size.
- * @param {number} pixelRatio Pixel ratio.
- * @param {number} opacity Global opacity.
- * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
- * to skip.
- * @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback.
- * @param {boolean} oneByOne Draw features one-by-one for the hit-detecion.
- * @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
- * this extent are checked.
- * @return {T|undefined} Callback result.
- * @template T
- */
- ol.render.webgl.ReplayGroup.prototype.replayHitDetection_ = function(context,
- center, resolution, rotation, size, pixelRatio, opacity,
- skippedFeaturesHash, featureCallback, oneByOne, opt_hitExtent) {
- /** @type {Array.<number>} */
- var zs = Object.keys(this.replaysByZIndex_).map(Number);
- zs.sort(function(a, b) {
- return b - a;
- });
- var i, ii, j, replays, replay, result;
- for (i = 0, ii = zs.length; i < ii; ++i) {
- replays = this.replaysByZIndex_[zs[i].toString()];
- for (j = ol.render.replay.ORDER.length - 1; j >= 0; --j) {
- replay = replays[ol.render.replay.ORDER[j]];
- if (replay !== undefined) {
- result = replay.replay(context,
- center, resolution, rotation, size, pixelRatio, opacity,
- skippedFeaturesHash, featureCallback, oneByOne, opt_hitExtent);
- if (result) {
- return result;
- }
- }
- }
- }
- return undefined;
- };
- /**
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {ol.webgl.Context} context Context.
- * @param {ol.Coordinate} center Center.
- * @param {number} resolution Resolution.
- * @param {number} rotation Rotation.
- * @param {ol.Size} size Size.
- * @param {number} pixelRatio Pixel ratio.
- * @param {number} opacity Global opacity.
- * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
- * to skip.
- * @param {function((ol.Feature|ol.render.Feature)): T|undefined} callback Feature callback.
- * @return {T|undefined} Callback result.
- * @template T
- */
- ol.render.webgl.ReplayGroup.prototype.forEachFeatureAtCoordinate = function(
- coordinate, context, center, resolution, rotation, size, pixelRatio,
- opacity, skippedFeaturesHash,
- callback) {
- var gl = context.getGL();
- gl.bindFramebuffer(
- gl.FRAMEBUFFER, context.getHitDetectionFramebuffer());
- /**
- * @type {ol.Extent}
- */
- var hitExtent;
- if (this.renderBuffer_ !== undefined) {
- // build an extent around the coordinate, so that only features that
- // intersect this extent are checked
- hitExtent = ol.extent.buffer(
- ol.extent.createOrUpdateFromCoordinate(coordinate),
- resolution * this.renderBuffer_);
- }
- return this.replayHitDetection_(context,
- coordinate, resolution, rotation, ol.render.webgl.ReplayGroup.HIT_DETECTION_SIZE_,
- pixelRatio, opacity, skippedFeaturesHash,
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @return {?} Callback result.
- */
- function(feature) {
- var imageData = new Uint8Array(4);
- gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, imageData);
- if (imageData[3] > 0) {
- var result = callback(feature);
- if (result) {
- return result;
- }
- }
- }, true, hitExtent);
- };
- /**
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {ol.webgl.Context} context Context.
- * @param {ol.Coordinate} center Center.
- * @param {number} resolution Resolution.
- * @param {number} rotation Rotation.
- * @param {ol.Size} size Size.
- * @param {number} pixelRatio Pixel ratio.
- * @param {number} opacity Global opacity.
- * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
- * to skip.
- * @return {boolean} Is there a feature at the given coordinate?
- */
- ol.render.webgl.ReplayGroup.prototype.hasFeatureAtCoordinate = function(
- coordinate, context, center, resolution, rotation, size, pixelRatio,
- opacity, skippedFeaturesHash) {
- var gl = context.getGL();
- gl.bindFramebuffer(
- gl.FRAMEBUFFER, context.getHitDetectionFramebuffer());
- var hasFeature = this.replayHitDetection_(context,
- coordinate, resolution, rotation, ol.render.webgl.ReplayGroup.HIT_DETECTION_SIZE_,
- pixelRatio, opacity, skippedFeaturesHash,
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @return {boolean} Is there a feature?
- */
- function(feature) {
- var imageData = new Uint8Array(4);
- gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, imageData);
- return imageData[3] > 0;
- }, false);
- return hasFeature !== undefined;
- };
- /**
- * @const
- * @private
- * @type {Array.<number>}
- */
- ol.render.webgl.ReplayGroup.HIT_DETECTION_SIZE_ = [1, 1];
- /**
- * @const
- * @private
- * @type {Object.<ol.render.ReplayType,
- * function(new: ol.render.webgl.Replay, number,
- * ol.Extent)>}
- */
- ol.render.webgl.ReplayGroup.BATCH_CONSTRUCTORS_ = {
- 'Circle': ol.render.webgl.CircleReplay,
- 'Image': ol.render.webgl.ImageReplay,
- 'LineString': ol.render.webgl.LineStringReplay,
- 'Polygon': ol.render.webgl.PolygonReplay,
- 'Text': ol.render.webgl.TextReplay
- };
- goog.provide('ol.render.webgl.Immediate');
- goog.require('ol');
- goog.require('ol.extent');
- goog.require('ol.geom.GeometryType');
- goog.require('ol.render.ReplayType');
- goog.require('ol.render.VectorContext');
- goog.require('ol.render.webgl.ReplayGroup');
- /**
- * @constructor
- * @extends {ol.render.VectorContext}
- * @param {ol.webgl.Context} context Context.
- * @param {ol.Coordinate} center Center.
- * @param {number} resolution Resolution.
- * @param {number} rotation Rotation.
- * @param {ol.Size} size Size.
- * @param {ol.Extent} extent Extent.
- * @param {number} pixelRatio Pixel ratio.
- * @struct
- */
- ol.render.webgl.Immediate = function(context, center, resolution, rotation, size, extent, pixelRatio) {
- ol.render.VectorContext.call(this);
- /**
- * @private
- */
- this.context_ = context;
- /**
- * @private
- */
- this.center_ = center;
- /**
- * @private
- */
- this.extent_ = extent;
- /**
- * @private
- */
- this.pixelRatio_ = pixelRatio;
- /**
- * @private
- */
- this.size_ = size;
- /**
- * @private
- */
- this.rotation_ = rotation;
- /**
- * @private
- */
- this.resolution_ = resolution;
- /**
- * @private
- * @type {ol.style.Image}
- */
- this.imageStyle_ = null;
- /**
- * @private
- * @type {ol.style.Fill}
- */
- this.fillStyle_ = null;
- /**
- * @private
- * @type {ol.style.Stroke}
- */
- this.strokeStyle_ = null;
- /**
- * @private
- * @type {ol.style.Text}
- */
- this.textStyle_ = null;
- };
- ol.inherits(ol.render.webgl.Immediate, ol.render.VectorContext);
- /**
- * @param {ol.render.webgl.ReplayGroup} replayGroup Replay group.
- * @param {ol.geom.Geometry|ol.render.Feature} geometry Geometry.
- * @private
- */
- ol.render.webgl.Immediate.prototype.drawText_ = function(replayGroup, geometry) {
- var context = this.context_;
- var replay = /** @type {ol.render.webgl.TextReplay} */ (
- replayGroup.getReplay(0, ol.render.ReplayType.TEXT));
- replay.setTextStyle(this.textStyle_);
- replay.drawText(geometry, null);
- replay.finish(context);
- // default colors
- var opacity = 1;
- var skippedFeatures = {};
- var featureCallback;
- var oneByOne = false;
- replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
- this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
- oneByOne);
- replay.getDeleteResourcesFunction(context)();
- };
- /**
- * Set the rendering style. Note that since this is an immediate rendering API,
- * any `zIndex` on the provided style will be ignored.
- *
- * @param {ol.style.Style} style The rendering style.
- * @override
- * @api
- */
- ol.render.webgl.Immediate.prototype.setStyle = function(style) {
- this.setFillStrokeStyle(style.getFill(), style.getStroke());
- this.setImageStyle(style.getImage());
- this.setTextStyle(style.getText());
- };
- /**
- * Render a geometry into the canvas. Call
- * {@link ol.render.webgl.Immediate#setStyle} first to set the rendering style.
- *
- * @param {ol.geom.Geometry|ol.render.Feature} geometry The geometry to render.
- * @override
- * @api
- */
- ol.render.webgl.Immediate.prototype.drawGeometry = function(geometry) {
- var type = geometry.getType();
- switch (type) {
- case ol.geom.GeometryType.POINT:
- this.drawPoint(/** @type {ol.geom.Point} */ (geometry), null);
- break;
- case ol.geom.GeometryType.LINE_STRING:
- this.drawLineString(/** @type {ol.geom.LineString} */ (geometry), null);
- break;
- case ol.geom.GeometryType.POLYGON:
- this.drawPolygon(/** @type {ol.geom.Polygon} */ (geometry), null);
- break;
- case ol.geom.GeometryType.MULTI_POINT:
- this.drawMultiPoint(/** @type {ol.geom.MultiPoint} */ (geometry), null);
- break;
- case ol.geom.GeometryType.MULTI_LINE_STRING:
- this.drawMultiLineString(/** @type {ol.geom.MultiLineString} */ (geometry), null);
- break;
- case ol.geom.GeometryType.MULTI_POLYGON:
- this.drawMultiPolygon(/** @type {ol.geom.MultiPolygon} */ (geometry), null);
- break;
- case ol.geom.GeometryType.GEOMETRY_COLLECTION:
- this.drawGeometryCollection(/** @type {ol.geom.GeometryCollection} */ (geometry), null);
- break;
- case ol.geom.GeometryType.CIRCLE:
- this.drawCircle(/** @type {ol.geom.Circle} */ (geometry), null);
- break;
- default:
- // pass
- }
- };
- /**
- * @inheritDoc
- * @api
- */
- ol.render.webgl.Immediate.prototype.drawFeature = function(feature, style) {
- var geometry = style.getGeometryFunction()(feature);
- if (!geometry ||
- !ol.extent.intersects(this.extent_, geometry.getExtent())) {
- return;
- }
- this.setStyle(style);
- this.drawGeometry(geometry);
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.Immediate.prototype.drawGeometryCollection = function(geometry, data) {
- var geometries = geometry.getGeometriesArray();
- var i, ii;
- for (i = 0, ii = geometries.length; i < ii; ++i) {
- this.drawGeometry(geometries[i]);
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.Immediate.prototype.drawPoint = function(geometry, data) {
- var context = this.context_;
- var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
- var replay = /** @type {ol.render.webgl.ImageReplay} */ (
- replayGroup.getReplay(0, ol.render.ReplayType.IMAGE));
- replay.setImageStyle(this.imageStyle_);
- replay.drawPoint(geometry, data);
- replay.finish(context);
- // default colors
- var opacity = 1;
- var skippedFeatures = {};
- var featureCallback;
- var oneByOne = false;
- replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
- this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
- oneByOne);
- replay.getDeleteResourcesFunction(context)();
- if (this.textStyle_) {
- this.drawText_(replayGroup, geometry);
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.Immediate.prototype.drawMultiPoint = function(geometry, data) {
- var context = this.context_;
- var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
- var replay = /** @type {ol.render.webgl.ImageReplay} */ (
- replayGroup.getReplay(0, ol.render.ReplayType.IMAGE));
- replay.setImageStyle(this.imageStyle_);
- replay.drawMultiPoint(geometry, data);
- replay.finish(context);
- var opacity = 1;
- var skippedFeatures = {};
- var featureCallback;
- var oneByOne = false;
- replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
- this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
- oneByOne);
- replay.getDeleteResourcesFunction(context)();
- if (this.textStyle_) {
- this.drawText_(replayGroup, geometry);
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.Immediate.prototype.drawLineString = function(geometry, data) {
- var context = this.context_;
- var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
- var replay = /** @type {ol.render.webgl.LineStringReplay} */ (
- replayGroup.getReplay(0, ol.render.ReplayType.LINE_STRING));
- replay.setFillStrokeStyle(null, this.strokeStyle_);
- replay.drawLineString(geometry, data);
- replay.finish(context);
- var opacity = 1;
- var skippedFeatures = {};
- var featureCallback;
- var oneByOne = false;
- replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
- this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
- oneByOne);
- replay.getDeleteResourcesFunction(context)();
- if (this.textStyle_) {
- this.drawText_(replayGroup, geometry);
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.Immediate.prototype.drawMultiLineString = function(geometry, data) {
- var context = this.context_;
- var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
- var replay = /** @type {ol.render.webgl.LineStringReplay} */ (
- replayGroup.getReplay(0, ol.render.ReplayType.LINE_STRING));
- replay.setFillStrokeStyle(null, this.strokeStyle_);
- replay.drawMultiLineString(geometry, data);
- replay.finish(context);
- var opacity = 1;
- var skippedFeatures = {};
- var featureCallback;
- var oneByOne = false;
- replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
- this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
- oneByOne);
- replay.getDeleteResourcesFunction(context)();
- if (this.textStyle_) {
- this.drawText_(replayGroup, geometry);
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.Immediate.prototype.drawPolygon = function(geometry, data) {
- var context = this.context_;
- var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
- var replay = /** @type {ol.render.webgl.PolygonReplay} */ (
- replayGroup.getReplay(0, ol.render.ReplayType.POLYGON));
- replay.setFillStrokeStyle(this.fillStyle_, this.strokeStyle_);
- replay.drawPolygon(geometry, data);
- replay.finish(context);
- var opacity = 1;
- var skippedFeatures = {};
- var featureCallback;
- var oneByOne = false;
- replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
- this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
- oneByOne);
- replay.getDeleteResourcesFunction(context)();
- if (this.textStyle_) {
- this.drawText_(replayGroup, geometry);
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.Immediate.prototype.drawMultiPolygon = function(geometry, data) {
- var context = this.context_;
- var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
- var replay = /** @type {ol.render.webgl.PolygonReplay} */ (
- replayGroup.getReplay(0, ol.render.ReplayType.POLYGON));
- replay.setFillStrokeStyle(this.fillStyle_, this.strokeStyle_);
- replay.drawMultiPolygon(geometry, data);
- replay.finish(context);
- var opacity = 1;
- var skippedFeatures = {};
- var featureCallback;
- var oneByOne = false;
- replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
- this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
- oneByOne);
- replay.getDeleteResourcesFunction(context)();
- if (this.textStyle_) {
- this.drawText_(replayGroup, geometry);
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.Immediate.prototype.drawCircle = function(geometry, data) {
- var context = this.context_;
- var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
- var replay = /** @type {ol.render.webgl.CircleReplay} */ (
- replayGroup.getReplay(0, ol.render.ReplayType.CIRCLE));
- replay.setFillStrokeStyle(this.fillStyle_, this.strokeStyle_);
- replay.drawCircle(geometry, data);
- replay.finish(context);
- var opacity = 1;
- var skippedFeatures = {};
- var featureCallback;
- var oneByOne = false;
- replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
- this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
- oneByOne);
- replay.getDeleteResourcesFunction(context)();
- if (this.textStyle_) {
- this.drawText_(replayGroup, geometry);
- }
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.Immediate.prototype.setImageStyle = function(imageStyle) {
- this.imageStyle_ = imageStyle;
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.Immediate.prototype.setFillStrokeStyle = function(fillStyle, strokeStyle) {
- this.fillStyle_ = fillStyle;
- this.strokeStyle_ = strokeStyle;
- };
- /**
- * @inheritDoc
- */
- ol.render.webgl.Immediate.prototype.setTextStyle = function(textStyle) {
- this.textStyle_ = textStyle;
- };
- // This file is automatically generated, do not edit
- goog.provide('ol.renderer.webgl.defaultmapshader');
- goog.require('ol');
- goog.require('ol.webgl.Fragment');
- goog.require('ol.webgl.Vertex');
- ol.renderer.webgl.defaultmapshader.fragment = new ol.webgl.Fragment(ol.DEBUG_WEBGL ?
- 'precision mediump float;\nvarying vec2 v_texCoord;\n\n\nuniform float u_opacity;\nuniform sampler2D u_texture;\n\nvoid main(void) {\n vec4 texColor = texture2D(u_texture, v_texCoord);\n gl_FragColor.rgb = texColor.rgb;\n gl_FragColor.a = texColor.a * u_opacity;\n}\n' :
- 'precision mediump float;varying vec2 a;uniform float f;uniform sampler2D g;void main(void){vec4 texColor=texture2D(g,a);gl_FragColor.rgb=texColor.rgb;gl_FragColor.a=texColor.a*f;}');
- ol.renderer.webgl.defaultmapshader.vertex = new ol.webgl.Vertex(ol.DEBUG_WEBGL ?
- 'varying vec2 v_texCoord;\n\n\nattribute vec2 a_position;\nattribute vec2 a_texCoord;\n\nuniform mat4 u_texCoordMatrix;\nuniform mat4 u_projectionMatrix;\n\nvoid main(void) {\n gl_Position = u_projectionMatrix * vec4(a_position, 0., 1.);\n v_texCoord = (u_texCoordMatrix * vec4(a_texCoord, 0., 1.)).st;\n}\n\n\n' :
- 'varying vec2 a;attribute vec2 b;attribute vec2 c;uniform mat4 d;uniform mat4 e;void main(void){gl_Position=e*vec4(b,0.,1.);a=(d*vec4(c,0.,1.)).st;}');
- // This file is automatically generated, do not edit
- goog.provide('ol.renderer.webgl.defaultmapshader.Locations');
- goog.require('ol');
- /**
- * @constructor
- * @param {WebGLRenderingContext} gl GL.
- * @param {WebGLProgram} program Program.
- * @struct
- */
- ol.renderer.webgl.defaultmapshader.Locations = function(gl, program) {
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_texCoordMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_texCoordMatrix' : 'd');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_projectionMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'e');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_opacity = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_opacity' : 'f');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_texture = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_texture' : 'g');
- /**
- * @type {number}
- */
- this.a_position = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_position' : 'b');
- /**
- * @type {number}
- */
- this.a_texCoord = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_texCoord' : 'c');
- };
- goog.provide('ol.renderer.webgl.Layer');
- goog.require('ol');
- goog.require('ol.render.Event');
- goog.require('ol.render.EventType');
- goog.require('ol.render.webgl.Immediate');
- goog.require('ol.renderer.Layer');
- goog.require('ol.renderer.webgl.defaultmapshader');
- goog.require('ol.renderer.webgl.defaultmapshader.Locations');
- goog.require('ol.transform');
- goog.require('ol.vec.Mat4');
- goog.require('ol.webgl');
- goog.require('ol.webgl.Buffer');
- goog.require('ol.webgl.Context');
- /**
- * @constructor
- * @abstract
- * @extends {ol.renderer.Layer}
- * @param {ol.renderer.webgl.Map} mapRenderer Map renderer.
- * @param {ol.layer.Layer} layer Layer.
- */
- ol.renderer.webgl.Layer = function(mapRenderer, layer) {
- ol.renderer.Layer.call(this, layer);
- /**
- * @protected
- * @type {ol.renderer.webgl.Map}
- */
- this.mapRenderer = mapRenderer;
- /**
- * @private
- * @type {ol.webgl.Buffer}
- */
- this.arrayBuffer_ = new ol.webgl.Buffer([
- -1, -1, 0, 0,
- 1, -1, 1, 0,
- -1, 1, 0, 1,
- 1, 1, 1, 1
- ]);
- /**
- * @protected
- * @type {WebGLTexture}
- */
- this.texture = null;
- /**
- * @protected
- * @type {WebGLFramebuffer}
- */
- this.framebuffer = null;
- /**
- * @protected
- * @type {number|undefined}
- */
- this.framebufferDimension = undefined;
- /**
- * @protected
- * @type {ol.Transform}
- */
- this.texCoordMatrix = ol.transform.create();
- /**
- * @protected
- * @type {ol.Transform}
- */
- this.projectionMatrix = ol.transform.create();
- /**
- * @type {Array.<number>}
- * @private
- */
- this.tmpMat4_ = ol.vec.Mat4.create();
- /**
- * @private
- * @type {ol.renderer.webgl.defaultmapshader.Locations}
- */
- this.defaultLocations_ = null;
- };
- ol.inherits(ol.renderer.webgl.Layer, ol.renderer.Layer);
- /**
- * @param {olx.FrameState} frameState Frame state.
- * @param {number} framebufferDimension Framebuffer dimension.
- * @protected
- */
- ol.renderer.webgl.Layer.prototype.bindFramebuffer = function(frameState, framebufferDimension) {
- var gl = this.mapRenderer.getGL();
- if (this.framebufferDimension === undefined ||
- this.framebufferDimension != framebufferDimension) {
- /**
- * @param {WebGLRenderingContext} gl GL.
- * @param {WebGLFramebuffer} framebuffer Framebuffer.
- * @param {WebGLTexture} texture Texture.
- */
- var postRenderFunction = function(gl, framebuffer, texture) {
- if (!gl.isContextLost()) {
- gl.deleteFramebuffer(framebuffer);
- gl.deleteTexture(texture);
- }
- }.bind(null, gl, this.framebuffer, this.texture);
- frameState.postRenderFunctions.push(
- /** @type {ol.PostRenderFunction} */ (postRenderFunction)
- );
- var texture = ol.webgl.Context.createEmptyTexture(
- gl, framebufferDimension, framebufferDimension);
- var framebuffer = gl.createFramebuffer();
- gl.bindFramebuffer(ol.webgl.FRAMEBUFFER, framebuffer);
- gl.framebufferTexture2D(ol.webgl.FRAMEBUFFER,
- ol.webgl.COLOR_ATTACHMENT0, ol.webgl.TEXTURE_2D, texture, 0);
- this.texture = texture;
- this.framebuffer = framebuffer;
- this.framebufferDimension = framebufferDimension;
- } else {
- gl.bindFramebuffer(ol.webgl.FRAMEBUFFER, this.framebuffer);
- }
- };
- /**
- * @param {olx.FrameState} frameState Frame state.
- * @param {ol.LayerState} layerState Layer state.
- * @param {ol.webgl.Context} context Context.
- */
- ol.renderer.webgl.Layer.prototype.composeFrame = function(frameState, layerState, context) {
- this.dispatchComposeEvent_(
- ol.render.EventType.PRECOMPOSE, context, frameState);
- context.bindBuffer(ol.webgl.ARRAY_BUFFER, this.arrayBuffer_);
- var gl = context.getGL();
- var fragmentShader = ol.renderer.webgl.defaultmapshader.fragment;
- var vertexShader = ol.renderer.webgl.defaultmapshader.vertex;
- var program = context.getProgram(fragmentShader, vertexShader);
- var locations;
- if (!this.defaultLocations_) {
- locations = new ol.renderer.webgl.defaultmapshader.Locations(gl, program);
- this.defaultLocations_ = locations;
- } else {
- locations = this.defaultLocations_;
- }
- if (context.useProgram(program)) {
- gl.enableVertexAttribArray(locations.a_position);
- gl.vertexAttribPointer(
- locations.a_position, 2, ol.webgl.FLOAT, false, 16, 0);
- gl.enableVertexAttribArray(locations.a_texCoord);
- gl.vertexAttribPointer(
- locations.a_texCoord, 2, ol.webgl.FLOAT, false, 16, 8);
- gl.uniform1i(locations.u_texture, 0);
- }
- gl.uniformMatrix4fv(locations.u_texCoordMatrix, false,
- ol.vec.Mat4.fromTransform(this.tmpMat4_, this.getTexCoordMatrix()));
- gl.uniformMatrix4fv(locations.u_projectionMatrix, false,
- ol.vec.Mat4.fromTransform(this.tmpMat4_, this.getProjectionMatrix()));
- gl.uniform1f(locations.u_opacity, layerState.opacity);
- gl.bindTexture(ol.webgl.TEXTURE_2D, this.getTexture());
- gl.drawArrays(ol.webgl.TRIANGLE_STRIP, 0, 4);
- this.dispatchComposeEvent_(
- ol.render.EventType.POSTCOMPOSE, context, frameState);
- };
- /**
- * @param {ol.render.EventType} type Event type.
- * @param {ol.webgl.Context} context WebGL context.
- * @param {olx.FrameState} frameState Frame state.
- * @private
- */
- ol.renderer.webgl.Layer.prototype.dispatchComposeEvent_ = function(type, context, frameState) {
- var layer = this.getLayer();
- if (layer.hasListener(type)) {
- var viewState = frameState.viewState;
- var resolution = viewState.resolution;
- var pixelRatio = frameState.pixelRatio;
- var extent = frameState.extent;
- var center = viewState.center;
- var rotation = viewState.rotation;
- var size = frameState.size;
- var render = new ol.render.webgl.Immediate(
- context, center, resolution, rotation, size, extent, pixelRatio);
- var composeEvent = new ol.render.Event(
- type, render, frameState, null, context);
- layer.dispatchEvent(composeEvent);
- }
- };
- /**
- * @return {!ol.Transform} Matrix.
- */
- ol.renderer.webgl.Layer.prototype.getTexCoordMatrix = function() {
- return this.texCoordMatrix;
- };
- /**
- * @return {WebGLTexture} Texture.
- */
- ol.renderer.webgl.Layer.prototype.getTexture = function() {
- return this.texture;
- };
- /**
- * @return {!ol.Transform} Matrix.
- */
- ol.renderer.webgl.Layer.prototype.getProjectionMatrix = function() {
- return this.projectionMatrix;
- };
- /**
- * Handle webglcontextlost.
- */
- ol.renderer.webgl.Layer.prototype.handleWebGLContextLost = function() {
- this.texture = null;
- this.framebuffer = null;
- this.framebufferDimension = undefined;
- };
- /**
- * @abstract
- * @param {olx.FrameState} frameState Frame state.
- * @param {ol.LayerState} layerState Layer state.
- * @param {ol.webgl.Context} context Context.
- * @return {boolean} whether composeFrame should be called.
- */
- ol.renderer.webgl.Layer.prototype.prepareFrame = function(frameState, layerState, context) {};
- /**
- * @abstract
- * @param {ol.Pixel} pixel Pixel.
- * @param {olx.FrameState} frameState FrameState.
- * @param {function(this: S, ol.layer.Layer, (Uint8ClampedArray|Uint8Array)): T} callback Layer
- * callback.
- * @param {S} thisArg Value to use as `this` when executing `callback`.
- * @return {T|undefined} Callback result.
- * @template S,T,U
- */
- ol.renderer.webgl.Layer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) {};
- goog.provide('ol.renderer.webgl.ImageLayer');
- goog.require('ol');
- goog.require('ol.LayerType');
- goog.require('ol.ViewHint');
- goog.require('ol.dom');
- goog.require('ol.extent');
- goog.require('ol.functions');
- goog.require('ol.renderer.Type');
- goog.require('ol.renderer.webgl.Layer');
- goog.require('ol.transform');
- goog.require('ol.webgl');
- goog.require('ol.webgl.Context');
- /**
- * @constructor
- * @extends {ol.renderer.webgl.Layer}
- * @param {ol.renderer.webgl.Map} mapRenderer Map renderer.
- * @param {ol.layer.Image} imageLayer Tile layer.
- * @api
- */
- ol.renderer.webgl.ImageLayer = function(mapRenderer, imageLayer) {
- ol.renderer.webgl.Layer.call(this, mapRenderer, imageLayer);
- /**
- * The last rendered image.
- * @private
- * @type {?ol.ImageBase}
- */
- this.image_ = null;
- /**
- * @private
- * @type {CanvasRenderingContext2D}
- */
- this.hitCanvasContext_ = null;
- /**
- * @private
- * @type {?ol.Transform}
- */
- this.hitTransformationMatrix_ = null;
- };
- ol.inherits(ol.renderer.webgl.ImageLayer, ol.renderer.webgl.Layer);
- /**
- * Determine if this renderer handles the provided layer.
- * @param {ol.renderer.Type} type The renderer type.
- * @param {ol.layer.Layer} layer The candidate layer.
- * @return {boolean} The renderer can render the layer.
- */
- ol.renderer.webgl.ImageLayer['handles'] = function(type, layer) {
- return type === ol.renderer.Type.WEBGL && layer.getType() === ol.LayerType.IMAGE;
- };
- /**
- * Create a layer renderer.
- * @param {ol.renderer.Map} mapRenderer The map renderer.
- * @param {ol.layer.Layer} layer The layer to be rendererd.
- * @return {ol.renderer.webgl.ImageLayer} The layer renderer.
- */
- ol.renderer.webgl.ImageLayer['create'] = function(mapRenderer, layer) {
- return new ol.renderer.webgl.ImageLayer(
- /** @type {ol.renderer.webgl.Map} */ (mapRenderer),
- /** @type {ol.layer.Image} */ (layer)
- );
- };
- /**
- * @param {ol.ImageBase} image Image.
- * @private
- * @return {WebGLTexture} Texture.
- */
- ol.renderer.webgl.ImageLayer.prototype.createTexture_ = function(image) {
- // We meet the conditions to work with non-power of two textures.
- // http://www.khronos.org/webgl/wiki/WebGL_and_OpenGL_Differences#Non-Power_of_Two_Texture_Support
- // http://learningwebgl.com/blog/?p=2101
- var imageElement = image.getImage();
- var gl = this.mapRenderer.getGL();
- return ol.webgl.Context.createTexture(
- gl, imageElement, ol.webgl.CLAMP_TO_EDGE, ol.webgl.CLAMP_TO_EDGE);
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.ImageLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, hitTolerance, callback, thisArg) {
- var layer = this.getLayer();
- var source = layer.getSource();
- var resolution = frameState.viewState.resolution;
- var rotation = frameState.viewState.rotation;
- var skippedFeatureUids = frameState.skippedFeatureUids;
- return source.forEachFeatureAtCoordinate(
- coordinate, resolution, rotation, hitTolerance, skippedFeatureUids,
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @return {?} Callback result.
- */
- function(feature) {
- return callback.call(thisArg, feature, layer);
- });
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.ImageLayer.prototype.prepareFrame = function(frameState, layerState, context) {
- var gl = this.mapRenderer.getGL();
- var pixelRatio = frameState.pixelRatio;
- var viewState = frameState.viewState;
- var viewCenter = viewState.center;
- var viewResolution = viewState.resolution;
- var viewRotation = viewState.rotation;
- var image = this.image_;
- var texture = this.texture;
- var imageLayer = /** @type {ol.layer.Image} */ (this.getLayer());
- var imageSource = imageLayer.getSource();
- var hints = frameState.viewHints;
- var renderedExtent = frameState.extent;
- if (layerState.extent !== undefined) {
- renderedExtent = ol.extent.getIntersection(
- renderedExtent, layerState.extent);
- }
- if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.INTERACTING] &&
- !ol.extent.isEmpty(renderedExtent)) {
- var projection = viewState.projection;
- if (!ol.ENABLE_RASTER_REPROJECTION) {
- var sourceProjection = imageSource.getProjection();
- if (sourceProjection) {
- projection = sourceProjection;
- }
- }
- var image_ = imageSource.getImage(renderedExtent, viewResolution,
- pixelRatio, projection);
- if (image_) {
- var loaded = this.loadImage(image_);
- if (loaded) {
- image = image_;
- texture = this.createTexture_(image_);
- if (this.texture) {
- /**
- * @param {WebGLRenderingContext} gl GL.
- * @param {WebGLTexture} texture Texture.
- */
- var postRenderFunction = function(gl, texture) {
- if (!gl.isContextLost()) {
- gl.deleteTexture(texture);
- }
- }.bind(null, gl, this.texture);
- frameState.postRenderFunctions.push(
- /** @type {ol.PostRenderFunction} */ (postRenderFunction)
- );
- }
- }
- }
- }
- if (image) {
- var canvas = this.mapRenderer.getContext().getCanvas();
- this.updateProjectionMatrix_(canvas.width, canvas.height,
- pixelRatio, viewCenter, viewResolution, viewRotation,
- image.getExtent());
- this.hitTransformationMatrix_ = null;
- // Translate and scale to flip the Y coord.
- var texCoordMatrix = this.texCoordMatrix;
- ol.transform.reset(texCoordMatrix);
- ol.transform.scale(texCoordMatrix, 1, -1);
- ol.transform.translate(texCoordMatrix, 0, -1);
- this.image_ = image;
- this.texture = texture;
- this.updateLogos(frameState, imageSource);
- }
- return !!image;
- };
- /**
- * @param {number} canvasWidth Canvas width.
- * @param {number} canvasHeight Canvas height.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.Coordinate} viewCenter View center.
- * @param {number} viewResolution View resolution.
- * @param {number} viewRotation View rotation.
- * @param {ol.Extent} imageExtent Image extent.
- * @private
- */
- ol.renderer.webgl.ImageLayer.prototype.updateProjectionMatrix_ = function(canvasWidth, canvasHeight, pixelRatio,
- viewCenter, viewResolution, viewRotation, imageExtent) {
- var canvasExtentWidth = canvasWidth * viewResolution;
- var canvasExtentHeight = canvasHeight * viewResolution;
- var projectionMatrix = this.projectionMatrix;
- ol.transform.reset(projectionMatrix);
- ol.transform.scale(projectionMatrix,
- pixelRatio * 2 / canvasExtentWidth,
- pixelRatio * 2 / canvasExtentHeight);
- ol.transform.rotate(projectionMatrix, -viewRotation);
- ol.transform.translate(projectionMatrix,
- imageExtent[0] - viewCenter[0],
- imageExtent[1] - viewCenter[1]);
- ol.transform.scale(projectionMatrix,
- (imageExtent[2] - imageExtent[0]) / 2,
- (imageExtent[3] - imageExtent[1]) / 2);
- ol.transform.translate(projectionMatrix, 1, 1);
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.ImageLayer.prototype.hasFeatureAtCoordinate = function(coordinate, frameState) {
- var hasFeature = this.forEachFeatureAtCoordinate(
- coordinate, frameState, 0, ol.functions.TRUE, this);
- return hasFeature !== undefined;
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.ImageLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) {
- if (!this.image_ || !this.image_.getImage()) {
- return undefined;
- }
- if (this.getLayer().getSource().forEachFeatureAtCoordinate !== ol.nullFunction) {
- // for ImageCanvas sources use the original hit-detection logic,
- // so that for example also transparent polygons are detected
- var coordinate = ol.transform.apply(
- frameState.pixelToCoordinateTransform, pixel.slice());
- var hasFeature = this.forEachFeatureAtCoordinate(
- coordinate, frameState, 0, ol.functions.TRUE, this);
- if (hasFeature) {
- return callback.call(thisArg, this.getLayer(), null);
- } else {
- return undefined;
- }
- } else {
- var imageSize =
- [this.image_.getImage().width, this.image_.getImage().height];
- if (!this.hitTransformationMatrix_) {
- this.hitTransformationMatrix_ = this.getHitTransformationMatrix_(
- frameState.size, imageSize);
- }
- var pixelOnFrameBuffer = ol.transform.apply(
- this.hitTransformationMatrix_, pixel.slice());
- if (pixelOnFrameBuffer[0] < 0 || pixelOnFrameBuffer[0] > imageSize[0] ||
- pixelOnFrameBuffer[1] < 0 || pixelOnFrameBuffer[1] > imageSize[1]) {
- // outside the image, no need to check
- return undefined;
- }
- if (!this.hitCanvasContext_) {
- this.hitCanvasContext_ = ol.dom.createCanvasContext2D(1, 1);
- }
- this.hitCanvasContext_.clearRect(0, 0, 1, 1);
- this.hitCanvasContext_.drawImage(this.image_.getImage(),
- pixelOnFrameBuffer[0], pixelOnFrameBuffer[1], 1, 1, 0, 0, 1, 1);
- var imageData = this.hitCanvasContext_.getImageData(0, 0, 1, 1).data;
- if (imageData[3] > 0) {
- return callback.call(thisArg, this.getLayer(), imageData);
- } else {
- return undefined;
- }
- }
- };
- /**
- * The transformation matrix to get the pixel on the image for a
- * pixel on the map.
- * @param {ol.Size} mapSize The map size.
- * @param {ol.Size} imageSize The image size.
- * @return {ol.Transform} The transformation matrix.
- * @private
- */
- ol.renderer.webgl.ImageLayer.prototype.getHitTransformationMatrix_ = function(mapSize, imageSize) {
- // the first matrix takes a map pixel, flips the y-axis and scales to
- // a range between -1 ... 1
- var mapCoordTransform = ol.transform.create();
- ol.transform.translate(mapCoordTransform, -1, -1);
- ol.transform.scale(mapCoordTransform, 2 / mapSize[0], 2 / mapSize[1]);
- ol.transform.translate(mapCoordTransform, 0, mapSize[1]);
- ol.transform.scale(mapCoordTransform, 1, -1);
- // the second matrix is the inverse of the projection matrix used in the
- // shader for drawing
- var projectionMatrixInv = ol.transform.invert(this.projectionMatrix.slice());
- // the third matrix scales to the image dimensions and flips the y-axis again
- var transform = ol.transform.create();
- ol.transform.translate(transform, 0, imageSize[1]);
- ol.transform.scale(transform, 1, -1);
- ol.transform.scale(transform, imageSize[0] / 2, imageSize[1] / 2);
- ol.transform.translate(transform, 1, 1);
- ol.transform.multiply(transform, projectionMatrixInv);
- ol.transform.multiply(transform, mapCoordTransform);
- return transform;
- };
- // FIXME check against gl.getParameter(webgl.MAX_TEXTURE_SIZE)
- goog.provide('ol.renderer.webgl.Map');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.css');
- goog.require('ol.dom');
- goog.require('ol.events');
- goog.require('ol.has');
- goog.require('ol.layer.Layer');
- goog.require('ol.render.Event');
- goog.require('ol.render.EventType');
- goog.require('ol.render.webgl.Immediate');
- goog.require('ol.renderer.Map');
- goog.require('ol.renderer.Type');
- goog.require('ol.source.State');
- goog.require('ol.structs.LRUCache');
- goog.require('ol.structs.PriorityQueue');
- goog.require('ol.webgl');
- goog.require('ol.webgl.Context');
- goog.require('ol.webgl.ContextEventType');
- /**
- * @constructor
- * @extends {ol.renderer.Map}
- * @param {Element} container Container.
- * @param {ol.PluggableMap} map Map.
- * @api
- */
- ol.renderer.webgl.Map = function(container, map) {
- ol.renderer.Map.call(this, container, map);
- /**
- * @private
- * @type {HTMLCanvasElement}
- */
- this.canvas_ = /** @type {HTMLCanvasElement} */
- (document.createElement('CANVAS'));
- this.canvas_.style.width = '100%';
- this.canvas_.style.height = '100%';
- this.canvas_.style.display = 'block';
- this.canvas_.className = ol.css.CLASS_UNSELECTABLE;
- container.insertBefore(this.canvas_, container.childNodes[0] || null);
- /**
- * @private
- * @type {number}
- */
- this.clipTileCanvasWidth_ = 0;
- /**
- * @private
- * @type {number}
- */
- this.clipTileCanvasHeight_ = 0;
- /**
- * @private
- * @type {CanvasRenderingContext2D}
- */
- this.clipTileContext_ = ol.dom.createCanvasContext2D();
- /**
- * @private
- * @type {boolean}
- */
- this.renderedVisible_ = true;
- /**
- * @private
- * @type {WebGLRenderingContext}
- */
- this.gl_ = ol.webgl.getContext(this.canvas_, {
- antialias: true,
- depth: true,
- failIfMajorPerformanceCaveat: true,
- preserveDrawingBuffer: false,
- stencil: true
- });
- /**
- * @private
- * @type {ol.webgl.Context}
- */
- this.context_ = new ol.webgl.Context(this.canvas_, this.gl_);
- ol.events.listen(this.canvas_, ol.webgl.ContextEventType.LOST,
- this.handleWebGLContextLost, this);
- ol.events.listen(this.canvas_, ol.webgl.ContextEventType.RESTORED,
- this.handleWebGLContextRestored, this);
- /**
- * @private
- * @type {ol.structs.LRUCache.<ol.WebglTextureCacheEntry|null>}
- */
- this.textureCache_ = new ol.structs.LRUCache();
- /**
- * @private
- * @type {ol.Coordinate}
- */
- this.focus_ = null;
- /**
- * @private
- * @type {ol.structs.PriorityQueue.<Array>}
- */
- this.tileTextureQueue_ = new ol.structs.PriorityQueue(
- /**
- * @param {Array.<*>} element Element.
- * @return {number} Priority.
- * @this {ol.renderer.webgl.Map}
- */
- (function(element) {
- var tileCenter = /** @type {ol.Coordinate} */ (element[1]);
- var tileResolution = /** @type {number} */ (element[2]);
- var deltaX = tileCenter[0] - this.focus_[0];
- var deltaY = tileCenter[1] - this.focus_[1];
- return 65536 * Math.log(tileResolution) +
- Math.sqrt(deltaX * deltaX + deltaY * deltaY) / tileResolution;
- }).bind(this),
- /**
- * @param {Array.<*>} element Element.
- * @return {string} Key.
- */
- function(element) {
- return /** @type {ol.Tile} */ (element[0]).getKey();
- });
- /**
- * @param {ol.PluggableMap} map Map.
- * @param {?olx.FrameState} frameState Frame state.
- * @return {boolean} false.
- * @this {ol.renderer.webgl.Map}
- */
- this.loadNextTileTexture_ =
- function(map, frameState) {
- if (!this.tileTextureQueue_.isEmpty()) {
- this.tileTextureQueue_.reprioritize();
- var element = this.tileTextureQueue_.dequeue();
- var tile = /** @type {ol.Tile} */ (element[0]);
- var tileSize = /** @type {ol.Size} */ (element[3]);
- var tileGutter = /** @type {number} */ (element[4]);
- this.bindTileTexture(
- tile, tileSize, tileGutter, ol.webgl.LINEAR, ol.webgl.LINEAR);
- }
- return false;
- }.bind(this);
- /**
- * @private
- * @type {number}
- */
- this.textureCacheFrameMarkerCount_ = 0;
- this.initializeGL_();
- };
- ol.inherits(ol.renderer.webgl.Map, ol.renderer.Map);
- /**
- * Determine if this renderer handles the provided layer.
- * @param {ol.renderer.Type} type The renderer type.
- * @return {boolean} The renderer can render the layer.
- */
- ol.renderer.webgl.Map['handles'] = function(type) {
- return ol.has.WEBGL && type === ol.renderer.Type.WEBGL;
- };
- /**
- * Create the map renderer.
- * @param {Element} container Container.
- * @param {ol.PluggableMap} map Map.
- * @return {ol.renderer.webgl.Map} The map renderer.
- */
- ol.renderer.webgl.Map['create'] = function(container, map) {
- return new ol.renderer.webgl.Map(container, map);
- };
- /**
- * @param {ol.Tile} tile Tile.
- * @param {ol.Size} tileSize Tile size.
- * @param {number} tileGutter Tile gutter.
- * @param {number} magFilter Mag filter.
- * @param {number} minFilter Min filter.
- */
- ol.renderer.webgl.Map.prototype.bindTileTexture = function(tile, tileSize, tileGutter, magFilter, minFilter) {
- var gl = this.getGL();
- var tileKey = tile.getKey();
- if (this.textureCache_.containsKey(tileKey)) {
- var textureCacheEntry = this.textureCache_.get(tileKey);
- gl.bindTexture(ol.webgl.TEXTURE_2D, textureCacheEntry.texture);
- if (textureCacheEntry.magFilter != magFilter) {
- gl.texParameteri(
- ol.webgl.TEXTURE_2D, ol.webgl.TEXTURE_MAG_FILTER, magFilter);
- textureCacheEntry.magFilter = magFilter;
- }
- if (textureCacheEntry.minFilter != minFilter) {
- gl.texParameteri(
- ol.webgl.TEXTURE_2D, ol.webgl.TEXTURE_MIN_FILTER, minFilter);
- textureCacheEntry.minFilter = minFilter;
- }
- } else {
- var texture = gl.createTexture();
- gl.bindTexture(ol.webgl.TEXTURE_2D, texture);
- if (tileGutter > 0) {
- var clipTileCanvas = this.clipTileContext_.canvas;
- var clipTileContext = this.clipTileContext_;
- if (this.clipTileCanvasWidth_ !== tileSize[0] ||
- this.clipTileCanvasHeight_ !== tileSize[1]) {
- clipTileCanvas.width = tileSize[0];
- clipTileCanvas.height = tileSize[1];
- this.clipTileCanvasWidth_ = tileSize[0];
- this.clipTileCanvasHeight_ = tileSize[1];
- } else {
- clipTileContext.clearRect(0, 0, tileSize[0], tileSize[1]);
- }
- clipTileContext.drawImage(tile.getImage(), tileGutter, tileGutter,
- tileSize[0], tileSize[1], 0, 0, tileSize[0], tileSize[1]);
- gl.texImage2D(ol.webgl.TEXTURE_2D, 0,
- ol.webgl.RGBA, ol.webgl.RGBA,
- ol.webgl.UNSIGNED_BYTE, clipTileCanvas);
- } else {
- gl.texImage2D(ol.webgl.TEXTURE_2D, 0,
- ol.webgl.RGBA, ol.webgl.RGBA,
- ol.webgl.UNSIGNED_BYTE, tile.getImage());
- }
- gl.texParameteri(
- ol.webgl.TEXTURE_2D, ol.webgl.TEXTURE_MAG_FILTER, magFilter);
- gl.texParameteri(
- ol.webgl.TEXTURE_2D, ol.webgl.TEXTURE_MIN_FILTER, minFilter);
- gl.texParameteri(ol.webgl.TEXTURE_2D, ol.webgl.TEXTURE_WRAP_S,
- ol.webgl.CLAMP_TO_EDGE);
- gl.texParameteri(ol.webgl.TEXTURE_2D, ol.webgl.TEXTURE_WRAP_T,
- ol.webgl.CLAMP_TO_EDGE);
- this.textureCache_.set(tileKey, {
- texture: texture,
- magFilter: magFilter,
- minFilter: minFilter
- });
- }
- };
- /**
- * @param {ol.render.EventType} type Event type.
- * @param {olx.FrameState} frameState Frame state.
- * @private
- */
- ol.renderer.webgl.Map.prototype.dispatchComposeEvent_ = function(type, frameState) {
- var map = this.getMap();
- if (map.hasListener(type)) {
- var context = this.context_;
- var extent = frameState.extent;
- var size = frameState.size;
- var viewState = frameState.viewState;
- var pixelRatio = frameState.pixelRatio;
- var resolution = viewState.resolution;
- var center = viewState.center;
- var rotation = viewState.rotation;
- var vectorContext = new ol.render.webgl.Immediate(context,
- center, resolution, rotation, size, extent, pixelRatio);
- var composeEvent = new ol.render.Event(type, vectorContext,
- frameState, null, context);
- map.dispatchEvent(composeEvent);
- }
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.Map.prototype.disposeInternal = function() {
- var gl = this.getGL();
- if (!gl.isContextLost()) {
- this.textureCache_.forEach(
- /**
- * @param {?ol.WebglTextureCacheEntry} textureCacheEntry
- * Texture cache entry.
- */
- function(textureCacheEntry) {
- if (textureCacheEntry) {
- gl.deleteTexture(textureCacheEntry.texture);
- }
- });
- }
- this.context_.dispose();
- ol.renderer.Map.prototype.disposeInternal.call(this);
- };
- /**
- * @param {ol.PluggableMap} map Map.
- * @param {olx.FrameState} frameState Frame state.
- * @private
- */
- ol.renderer.webgl.Map.prototype.expireCache_ = function(map, frameState) {
- var gl = this.getGL();
- var textureCacheEntry;
- while (this.textureCache_.getCount() - this.textureCacheFrameMarkerCount_ >
- ol.WEBGL_TEXTURE_CACHE_HIGH_WATER_MARK) {
- textureCacheEntry = this.textureCache_.peekLast();
- if (!textureCacheEntry) {
- if (+this.textureCache_.peekLastKey() == frameState.index) {
- break;
- } else {
- --this.textureCacheFrameMarkerCount_;
- }
- } else {
- gl.deleteTexture(textureCacheEntry.texture);
- }
- this.textureCache_.pop();
- }
- };
- /**
- * @return {ol.webgl.Context} The context.
- */
- ol.renderer.webgl.Map.prototype.getContext = function() {
- return this.context_;
- };
- /**
- * @return {WebGLRenderingContext} GL.
- */
- ol.renderer.webgl.Map.prototype.getGL = function() {
- return this.gl_;
- };
- /**
- * @return {ol.structs.PriorityQueue.<Array>} Tile texture queue.
- */
- ol.renderer.webgl.Map.prototype.getTileTextureQueue = function() {
- return this.tileTextureQueue_;
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.Map.prototype.getType = function() {
- return ol.renderer.Type.WEBGL;
- };
- /**
- * @param {ol.events.Event} event Event.
- * @protected
- */
- ol.renderer.webgl.Map.prototype.handleWebGLContextLost = function(event) {
- event.preventDefault();
- this.textureCache_.clear();
- this.textureCacheFrameMarkerCount_ = 0;
- var renderers = this.getLayerRenderers();
- for (var id in renderers) {
- var renderer = /** @type {ol.renderer.webgl.Layer} */ (renderers[id]);
- renderer.handleWebGLContextLost();
- }
- };
- /**
- * @protected
- */
- ol.renderer.webgl.Map.prototype.handleWebGLContextRestored = function() {
- this.initializeGL_();
- this.getMap().render();
- };
- /**
- * @private
- */
- ol.renderer.webgl.Map.prototype.initializeGL_ = function() {
- var gl = this.gl_;
- gl.activeTexture(ol.webgl.TEXTURE0);
- gl.blendFuncSeparate(
- ol.webgl.SRC_ALPHA, ol.webgl.ONE_MINUS_SRC_ALPHA,
- ol.webgl.ONE, ol.webgl.ONE_MINUS_SRC_ALPHA);
- gl.disable(ol.webgl.CULL_FACE);
- gl.disable(ol.webgl.DEPTH_TEST);
- gl.disable(ol.webgl.SCISSOR_TEST);
- gl.disable(ol.webgl.STENCIL_TEST);
- };
- /**
- * @param {ol.Tile} tile Tile.
- * @return {boolean} Is tile texture loaded.
- */
- ol.renderer.webgl.Map.prototype.isTileTextureLoaded = function(tile) {
- return this.textureCache_.containsKey(tile.getKey());
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) {
- var context = this.getContext();
- var gl = this.getGL();
- if (gl.isContextLost()) {
- return false;
- }
- if (!frameState) {
- if (this.renderedVisible_) {
- this.canvas_.style.display = 'none';
- this.renderedVisible_ = false;
- }
- return false;
- }
- this.focus_ = frameState.focus;
- this.textureCache_.set((-frameState.index).toString(), null);
- ++this.textureCacheFrameMarkerCount_;
- this.dispatchComposeEvent_(ol.render.EventType.PRECOMPOSE, frameState);
- /** @type {Array.<ol.LayerState>} */
- var layerStatesToDraw = [];
- var layerStatesArray = frameState.layerStatesArray;
- ol.array.stableSort(layerStatesArray, ol.renderer.Map.sortByZIndex);
- var viewResolution = frameState.viewState.resolution;
- var i, ii, layerRenderer, layerState;
- for (i = 0, ii = layerStatesArray.length; i < ii; ++i) {
- layerState = layerStatesArray[i];
- if (ol.layer.Layer.visibleAtResolution(layerState, viewResolution) &&
- layerState.sourceState == ol.source.State.READY) {
- layerRenderer = /** @type {ol.renderer.webgl.Layer} */ (this.getLayerRenderer(layerState.layer));
- if (layerRenderer.prepareFrame(frameState, layerState, context)) {
- layerStatesToDraw.push(layerState);
- }
- }
- }
- var width = frameState.size[0] * frameState.pixelRatio;
- var height = frameState.size[1] * frameState.pixelRatio;
- if (this.canvas_.width != width || this.canvas_.height != height) {
- this.canvas_.width = width;
- this.canvas_.height = height;
- }
- gl.bindFramebuffer(ol.webgl.FRAMEBUFFER, null);
- gl.clearColor(0, 0, 0, 0);
- gl.clear(ol.webgl.COLOR_BUFFER_BIT);
- gl.enable(ol.webgl.BLEND);
- gl.viewport(0, 0, this.canvas_.width, this.canvas_.height);
- for (i = 0, ii = layerStatesToDraw.length; i < ii; ++i) {
- layerState = layerStatesToDraw[i];
- layerRenderer = /** @type {ol.renderer.webgl.Layer} */ (this.getLayerRenderer(layerState.layer));
- layerRenderer.composeFrame(frameState, layerState, context);
- }
- if (!this.renderedVisible_) {
- this.canvas_.style.display = '';
- this.renderedVisible_ = true;
- }
- this.calculateMatrices2D(frameState);
- if (this.textureCache_.getCount() - this.textureCacheFrameMarkerCount_ >
- ol.WEBGL_TEXTURE_CACHE_HIGH_WATER_MARK) {
- frameState.postRenderFunctions.push(
- /** @type {ol.PostRenderFunction} */ (this.expireCache_.bind(this))
- );
- }
- if (!this.tileTextureQueue_.isEmpty()) {
- frameState.postRenderFunctions.push(this.loadNextTileTexture_);
- frameState.animate = true;
- }
- this.dispatchComposeEvent_(ol.render.EventType.POSTCOMPOSE, frameState);
- this.scheduleRemoveUnusedLayerRenderers(frameState);
- this.scheduleExpireIconCache(frameState);
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.Map.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, hitTolerance, callback, thisArg,
- layerFilter, thisArg2) {
- var result;
- if (this.getGL().isContextLost()) {
- return false;
- }
- var viewState = frameState.viewState;
- var layerStates = frameState.layerStatesArray;
- var numLayers = layerStates.length;
- var i;
- for (i = numLayers - 1; i >= 0; --i) {
- var layerState = layerStates[i];
- var layer = layerState.layer;
- if (ol.layer.Layer.visibleAtResolution(layerState, viewState.resolution) &&
- layerFilter.call(thisArg2, layer)) {
- var layerRenderer = this.getLayerRenderer(layer);
- result = layerRenderer.forEachFeatureAtCoordinate(
- coordinate, frameState, hitTolerance, callback, thisArg);
- if (result) {
- return result;
- }
- }
- }
- return undefined;
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.Map.prototype.hasFeatureAtCoordinate = function(coordinate, frameState, hitTolerance, layerFilter, thisArg) {
- var hasFeature = false;
- if (this.getGL().isContextLost()) {
- return false;
- }
- var viewState = frameState.viewState;
- var layerStates = frameState.layerStatesArray;
- var numLayers = layerStates.length;
- var i;
- for (i = numLayers - 1; i >= 0; --i) {
- var layerState = layerStates[i];
- var layer = layerState.layer;
- if (ol.layer.Layer.visibleAtResolution(layerState, viewState.resolution) &&
- layerFilter.call(thisArg, layer)) {
- var layerRenderer = this.getLayerRenderer(layer);
- hasFeature =
- layerRenderer.hasFeatureAtCoordinate(coordinate, frameState);
- if (hasFeature) {
- return true;
- }
- }
- }
- return hasFeature;
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.Map.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg,
- layerFilter, thisArg2) {
- if (this.getGL().isContextLost()) {
- return false;
- }
- var viewState = frameState.viewState;
- var result;
- var layerStates = frameState.layerStatesArray;
- var numLayers = layerStates.length;
- var i;
- for (i = numLayers - 1; i >= 0; --i) {
- var layerState = layerStates[i];
- var layer = layerState.layer;
- if (ol.layer.Layer.visibleAtResolution(layerState, viewState.resolution) &&
- layerFilter.call(thisArg, layer)) {
- var layerRenderer = /** @type {ol.renderer.webgl.Layer} */ (this.getLayerRenderer(layer));
- result = layerRenderer.forEachLayerAtPixel(
- pixel, frameState, callback, thisArg);
- if (result) {
- return result;
- }
- }
- }
- return undefined;
- };
- // This file is automatically generated, do not edit
- goog.provide('ol.renderer.webgl.tilelayershader');
- goog.require('ol');
- goog.require('ol.webgl.Fragment');
- goog.require('ol.webgl.Vertex');
- ol.renderer.webgl.tilelayershader.fragment = new ol.webgl.Fragment(ol.DEBUG_WEBGL ?
- 'precision mediump float;\nvarying vec2 v_texCoord;\n\n\nuniform sampler2D u_texture;\n\nvoid main(void) {\n gl_FragColor = texture2D(u_texture, v_texCoord);\n}\n' :
- 'precision mediump float;varying vec2 a;uniform sampler2D e;void main(void){gl_FragColor=texture2D(e,a);}');
- ol.renderer.webgl.tilelayershader.vertex = new ol.webgl.Vertex(ol.DEBUG_WEBGL ?
- 'varying vec2 v_texCoord;\n\n\nattribute vec2 a_position;\nattribute vec2 a_texCoord;\nuniform vec4 u_tileOffset;\n\nvoid main(void) {\n gl_Position = vec4(a_position * u_tileOffset.xy + u_tileOffset.zw, 0., 1.);\n v_texCoord = a_texCoord;\n}\n\n\n' :
- 'varying vec2 a;attribute vec2 b;attribute vec2 c;uniform vec4 d;void main(void){gl_Position=vec4(b*d.xy+d.zw,0.,1.);a=c;}');
- // This file is automatically generated, do not edit
- goog.provide('ol.renderer.webgl.tilelayershader.Locations');
- goog.require('ol');
- /**
- * @constructor
- * @param {WebGLRenderingContext} gl GL.
- * @param {WebGLProgram} program Program.
- * @struct
- */
- ol.renderer.webgl.tilelayershader.Locations = function(gl, program) {
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_tileOffset = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_tileOffset' : 'd');
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_texture = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_texture' : 'e');
- /**
- * @type {number}
- */
- this.a_position = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_position' : 'b');
- /**
- * @type {number}
- */
- this.a_texCoord = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_texCoord' : 'c');
- };
- // FIXME large resolutions lead to too large framebuffers :-(
- // FIXME animated shaders! check in redraw
- goog.provide('ol.renderer.webgl.TileLayer');
- goog.require('ol');
- goog.require('ol.LayerType');
- goog.require('ol.TileRange');
- goog.require('ol.TileState');
- goog.require('ol.array');
- goog.require('ol.extent');
- goog.require('ol.math');
- goog.require('ol.renderer.Type');
- goog.require('ol.renderer.webgl.Layer');
- goog.require('ol.renderer.webgl.tilelayershader');
- goog.require('ol.renderer.webgl.tilelayershader.Locations');
- goog.require('ol.size');
- goog.require('ol.transform');
- goog.require('ol.webgl');
- goog.require('ol.webgl.Buffer');
- /**
- * @constructor
- * @extends {ol.renderer.webgl.Layer}
- * @param {ol.renderer.webgl.Map} mapRenderer Map renderer.
- * @param {ol.layer.Tile} tileLayer Tile layer.
- * @api
- */
- ol.renderer.webgl.TileLayer = function(mapRenderer, tileLayer) {
- ol.renderer.webgl.Layer.call(this, mapRenderer, tileLayer);
- /**
- * @private
- * @type {ol.webgl.Fragment}
- */
- this.fragmentShader_ = ol.renderer.webgl.tilelayershader.fragment;
- /**
- * @private
- * @type {ol.webgl.Vertex}
- */
- this.vertexShader_ = ol.renderer.webgl.tilelayershader.vertex;
- /**
- * @private
- * @type {ol.renderer.webgl.tilelayershader.Locations}
- */
- this.locations_ = null;
- /**
- * @private
- * @type {ol.webgl.Buffer}
- */
- this.renderArrayBuffer_ = new ol.webgl.Buffer([
- 0, 0, 0, 1,
- 1, 0, 1, 1,
- 0, 1, 0, 0,
- 1, 1, 1, 0
- ]);
- /**
- * @private
- * @type {ol.TileRange}
- */
- this.renderedTileRange_ = null;
- /**
- * @private
- * @type {ol.Extent}
- */
- this.renderedFramebufferExtent_ = null;
- /**
- * @private
- * @type {number}
- */
- this.renderedRevision_ = -1;
- /**
- * @private
- * @type {ol.Size}
- */
- this.tmpSize_ = [0, 0];
- };
- ol.inherits(ol.renderer.webgl.TileLayer, ol.renderer.webgl.Layer);
- /**
- * Determine if this renderer handles the provided layer.
- * @param {ol.renderer.Type} type The renderer type.
- * @param {ol.layer.Layer} layer The candidate layer.
- * @return {boolean} The renderer can render the layer.
- */
- ol.renderer.webgl.TileLayer['handles'] = function(type, layer) {
- return type === ol.renderer.Type.WEBGL && layer.getType() === ol.LayerType.TILE;
- };
- /**
- * Create a layer renderer.
- * @param {ol.renderer.Map} mapRenderer The map renderer.
- * @param {ol.layer.Layer} layer The layer to be rendererd.
- * @return {ol.renderer.webgl.TileLayer} The layer renderer.
- */
- ol.renderer.webgl.TileLayer['create'] = function(mapRenderer, layer) {
- return new ol.renderer.webgl.TileLayer(
- /** @type {ol.renderer.webgl.Map} */ (mapRenderer),
- /** @type {ol.layer.Tile} */ (layer)
- );
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.TileLayer.prototype.disposeInternal = function() {
- var context = this.mapRenderer.getContext();
- context.deleteBuffer(this.renderArrayBuffer_);
- ol.renderer.webgl.Layer.prototype.disposeInternal.call(this);
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.TileLayer.prototype.createLoadedTileFinder = function(source, projection, tiles) {
- var mapRenderer = this.mapRenderer;
- return (
- /**
- * @param {number} zoom Zoom level.
- * @param {ol.TileRange} tileRange Tile range.
- * @return {boolean} The tile range is fully loaded.
- */
- function(zoom, tileRange) {
- function callback(tile) {
- var loaded = mapRenderer.isTileTextureLoaded(tile);
- if (loaded) {
- if (!tiles[zoom]) {
- tiles[zoom] = {};
- }
- tiles[zoom][tile.tileCoord.toString()] = tile;
- }
- return loaded;
- }
- return source.forEachLoadedTile(projection, zoom, tileRange, callback);
- });
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.TileLayer.prototype.handleWebGLContextLost = function() {
- ol.renderer.webgl.Layer.prototype.handleWebGLContextLost.call(this);
- this.locations_ = null;
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.TileLayer.prototype.prepareFrame = function(frameState, layerState, context) {
- var mapRenderer = this.mapRenderer;
- var gl = context.getGL();
- var viewState = frameState.viewState;
- var projection = viewState.projection;
- var tileLayer = /** @type {ol.layer.Tile} */ (this.getLayer());
- var tileSource = tileLayer.getSource();
- var tileGrid = tileSource.getTileGridForProjection(projection);
- var z = tileGrid.getZForResolution(viewState.resolution);
- var tileResolution = tileGrid.getResolution(z);
- var tilePixelSize =
- tileSource.getTilePixelSize(z, frameState.pixelRatio, projection);
- var pixelRatio = tilePixelSize[0] /
- ol.size.toSize(tileGrid.getTileSize(z), this.tmpSize_)[0];
- var tilePixelResolution = tileResolution / pixelRatio;
- var tileGutter = tileSource.getTilePixelRatio(pixelRatio) * tileSource.getGutter(projection);
- var center = viewState.center;
- var extent = frameState.extent;
- var tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
- var framebufferExtent;
- if (this.renderedTileRange_ &&
- this.renderedTileRange_.equals(tileRange) &&
- this.renderedRevision_ == tileSource.getRevision()) {
- framebufferExtent = this.renderedFramebufferExtent_;
- } else {
- var tileRangeSize = tileRange.getSize();
- var maxDimension = Math.max(
- tileRangeSize[0] * tilePixelSize[0],
- tileRangeSize[1] * tilePixelSize[1]);
- var framebufferDimension = ol.math.roundUpToPowerOfTwo(maxDimension);
- var framebufferExtentDimension = tilePixelResolution * framebufferDimension;
- var origin = tileGrid.getOrigin(z);
- var minX = origin[0] +
- tileRange.minX * tilePixelSize[0] * tilePixelResolution;
- var minY = origin[1] +
- tileRange.minY * tilePixelSize[1] * tilePixelResolution;
- framebufferExtent = [
- minX, minY,
- minX + framebufferExtentDimension, minY + framebufferExtentDimension
- ];
- this.bindFramebuffer(frameState, framebufferDimension);
- gl.viewport(0, 0, framebufferDimension, framebufferDimension);
- gl.clearColor(0, 0, 0, 0);
- gl.clear(ol.webgl.COLOR_BUFFER_BIT);
- gl.disable(ol.webgl.BLEND);
- var program = context.getProgram(this.fragmentShader_, this.vertexShader_);
- context.useProgram(program);
- if (!this.locations_) {
- this.locations_ = new ol.renderer.webgl.tilelayershader.Locations(gl, program);
- }
- context.bindBuffer(ol.webgl.ARRAY_BUFFER, this.renderArrayBuffer_);
- gl.enableVertexAttribArray(this.locations_.a_position);
- gl.vertexAttribPointer(
- this.locations_.a_position, 2, ol.webgl.FLOAT, false, 16, 0);
- gl.enableVertexAttribArray(this.locations_.a_texCoord);
- gl.vertexAttribPointer(
- this.locations_.a_texCoord, 2, ol.webgl.FLOAT, false, 16, 8);
- gl.uniform1i(this.locations_.u_texture, 0);
- /**
- * @type {Object.<number, Object.<string, ol.Tile>>}
- */
- var tilesToDrawByZ = {};
- tilesToDrawByZ[z] = {};
- var findLoadedTiles = this.createLoadedTileFinder(
- tileSource, projection, tilesToDrawByZ);
- var useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();
- var allTilesLoaded = true;
- var tmpExtent = ol.extent.createEmpty();
- var tmpTileRange = new ol.TileRange(0, 0, 0, 0);
- var childTileRange, drawable, fullyLoaded, tile, tileState;
- var x, y, tileExtent;
- for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
- for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
- tile = tileSource.getTile(z, x, y, pixelRatio, projection);
- if (layerState.extent !== undefined) {
- // ignore tiles outside layer extent
- tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord, tmpExtent);
- if (!ol.extent.intersects(tileExtent, layerState.extent)) {
- continue;
- }
- }
- tileState = tile.getState();
- drawable = tileState == ol.TileState.LOADED ||
- tileState == ol.TileState.EMPTY ||
- tileState == ol.TileState.ERROR && !useInterimTilesOnError;
- if (!drawable) {
- tile = tile.getInterimTile();
- }
- tileState = tile.getState();
- if (tileState == ol.TileState.LOADED) {
- if (mapRenderer.isTileTextureLoaded(tile)) {
- tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;
- continue;
- }
- } else if (tileState == ol.TileState.EMPTY ||
- (tileState == ol.TileState.ERROR &&
- !useInterimTilesOnError)) {
- continue;
- }
- allTilesLoaded = false;
- fullyLoaded = tileGrid.forEachTileCoordParentTileRange(
- tile.tileCoord, findLoadedTiles, null, tmpTileRange, tmpExtent);
- if (!fullyLoaded) {
- childTileRange = tileGrid.getTileCoordChildTileRange(
- tile.tileCoord, tmpTileRange, tmpExtent);
- if (childTileRange) {
- findLoadedTiles(z + 1, childTileRange);
- }
- }
- }
- }
- /** @type {Array.<number>} */
- var zs = Object.keys(tilesToDrawByZ).map(Number);
- zs.sort(ol.array.numberSafeCompareFunction);
- var u_tileOffset = new Float32Array(4);
- var i, ii, tileKey, tilesToDraw;
- for (i = 0, ii = zs.length; i < ii; ++i) {
- tilesToDraw = tilesToDrawByZ[zs[i]];
- for (tileKey in tilesToDraw) {
- tile = tilesToDraw[tileKey];
- tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord, tmpExtent);
- u_tileOffset[0] = 2 * (tileExtent[2] - tileExtent[0]) /
- framebufferExtentDimension;
- u_tileOffset[1] = 2 * (tileExtent[3] - tileExtent[1]) /
- framebufferExtentDimension;
- u_tileOffset[2] = 2 * (tileExtent[0] - framebufferExtent[0]) /
- framebufferExtentDimension - 1;
- u_tileOffset[3] = 2 * (tileExtent[1] - framebufferExtent[1]) /
- framebufferExtentDimension - 1;
- gl.uniform4fv(this.locations_.u_tileOffset, u_tileOffset);
- mapRenderer.bindTileTexture(tile, tilePixelSize,
- tileGutter * pixelRatio, ol.webgl.LINEAR, ol.webgl.LINEAR);
- gl.drawArrays(ol.webgl.TRIANGLE_STRIP, 0, 4);
- }
- }
- if (allTilesLoaded) {
- this.renderedTileRange_ = tileRange;
- this.renderedFramebufferExtent_ = framebufferExtent;
- this.renderedRevision_ = tileSource.getRevision();
- } else {
- this.renderedTileRange_ = null;
- this.renderedFramebufferExtent_ = null;
- this.renderedRevision_ = -1;
- frameState.animate = true;
- }
- }
- this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
- var tileTextureQueue = mapRenderer.getTileTextureQueue();
- this.manageTilePyramid(
- frameState, tileSource, tileGrid, pixelRatio, projection, extent, z,
- tileLayer.getPreload(),
- /**
- * @param {ol.Tile} tile Tile.
- */
- function(tile) {
- if (tile.getState() == ol.TileState.LOADED &&
- !mapRenderer.isTileTextureLoaded(tile) &&
- !tileTextureQueue.isKeyQueued(tile.getKey())) {
- tileTextureQueue.enqueue([
- tile,
- tileGrid.getTileCoordCenter(tile.tileCoord),
- tileGrid.getResolution(tile.tileCoord[0]),
- tilePixelSize, tileGutter * pixelRatio
- ]);
- }
- }, this);
- this.scheduleExpireCache(frameState, tileSource);
- this.updateLogos(frameState, tileSource);
- var texCoordMatrix = this.texCoordMatrix;
- ol.transform.reset(texCoordMatrix);
- ol.transform.translate(texCoordMatrix,
- (Math.round(center[0] / tileResolution) * tileResolution - framebufferExtent[0]) /
- (framebufferExtent[2] - framebufferExtent[0]),
- (Math.round(center[1] / tileResolution) * tileResolution - framebufferExtent[1]) /
- (framebufferExtent[3] - framebufferExtent[1]));
- if (viewState.rotation !== 0) {
- ol.transform.rotate(texCoordMatrix, viewState.rotation);
- }
- ol.transform.scale(texCoordMatrix,
- frameState.size[0] * viewState.resolution /
- (framebufferExtent[2] - framebufferExtent[0]),
- frameState.size[1] * viewState.resolution /
- (framebufferExtent[3] - framebufferExtent[1]));
- ol.transform.translate(texCoordMatrix, -0.5, -0.5);
- return true;
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.TileLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) {
- if (!this.framebuffer) {
- return undefined;
- }
- var pixelOnMapScaled = [
- pixel[0] / frameState.size[0],
- (frameState.size[1] - pixel[1]) / frameState.size[1]];
- var pixelOnFrameBufferScaled = ol.transform.apply(
- this.texCoordMatrix, pixelOnMapScaled.slice());
- var pixelOnFrameBuffer = [
- pixelOnFrameBufferScaled[0] * this.framebufferDimension,
- pixelOnFrameBufferScaled[1] * this.framebufferDimension];
- var gl = this.mapRenderer.getContext().getGL();
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
- var imageData = new Uint8Array(4);
- gl.readPixels(pixelOnFrameBuffer[0], pixelOnFrameBuffer[1], 1, 1,
- gl.RGBA, gl.UNSIGNED_BYTE, imageData);
- if (imageData[3] > 0) {
- return callback.call(thisArg, this.getLayer(), imageData);
- } else {
- return undefined;
- }
- };
- goog.provide('ol.renderer.webgl.VectorLayer');
- goog.require('ol');
- goog.require('ol.LayerType');
- goog.require('ol.ViewHint');
- goog.require('ol.extent');
- goog.require('ol.render.webgl.ReplayGroup');
- goog.require('ol.renderer.Type');
- goog.require('ol.renderer.vector');
- goog.require('ol.renderer.webgl.Layer');
- goog.require('ol.transform');
- /**
- * @constructor
- * @extends {ol.renderer.webgl.Layer}
- * @param {ol.renderer.webgl.Map} mapRenderer Map renderer.
- * @param {ol.layer.Vector} vectorLayer Vector layer.
- * @api
- */
- ol.renderer.webgl.VectorLayer = function(mapRenderer, vectorLayer) {
- ol.renderer.webgl.Layer.call(this, mapRenderer, vectorLayer);
- /**
- * @private
- * @type {boolean}
- */
- this.dirty_ = false;
- /**
- * @private
- * @type {number}
- */
- this.renderedRevision_ = -1;
- /**
- * @private
- * @type {number}
- */
- this.renderedResolution_ = NaN;
- /**
- * @private
- * @type {ol.Extent}
- */
- this.renderedExtent_ = ol.extent.createEmpty();
- /**
- * @private
- * @type {function(ol.Feature, ol.Feature): number|null}
- */
- this.renderedRenderOrder_ = null;
- /**
- * @private
- * @type {ol.render.webgl.ReplayGroup}
- */
- this.replayGroup_ = null;
- /**
- * The last layer state.
- * @private
- * @type {?ol.LayerState}
- */
- this.layerState_ = null;
- };
- ol.inherits(ol.renderer.webgl.VectorLayer, ol.renderer.webgl.Layer);
- /**
- * Determine if this renderer handles the provided layer.
- * @param {ol.renderer.Type} type The renderer type.
- * @param {ol.layer.Layer} layer The candidate layer.
- * @return {boolean} The renderer can render the layer.
- */
- ol.renderer.webgl.VectorLayer['handles'] = function(type, layer) {
- return type === ol.renderer.Type.WEBGL && layer.getType() === ol.LayerType.VECTOR;
- };
- /**
- * Create a layer renderer.
- * @param {ol.renderer.Map} mapRenderer The map renderer.
- * @param {ol.layer.Layer} layer The layer to be rendererd.
- * @return {ol.renderer.webgl.VectorLayer} The layer renderer.
- */
- ol.renderer.webgl.VectorLayer['create'] = function(mapRenderer, layer) {
- return new ol.renderer.webgl.VectorLayer(
- /** @type {ol.renderer.webgl.Map} */ (mapRenderer),
- /** @type {ol.layer.Vector} */ (layer)
- );
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.VectorLayer.prototype.composeFrame = function(frameState, layerState, context) {
- this.layerState_ = layerState;
- var viewState = frameState.viewState;
- var replayGroup = this.replayGroup_;
- var size = frameState.size;
- var pixelRatio = frameState.pixelRatio;
- var gl = this.mapRenderer.getGL();
- if (replayGroup && !replayGroup.isEmpty()) {
- gl.enable(gl.SCISSOR_TEST);
- gl.scissor(0, 0, size[0] * pixelRatio, size[1] * pixelRatio);
- replayGroup.replay(context,
- viewState.center, viewState.resolution, viewState.rotation,
- size, pixelRatio, layerState.opacity,
- layerState.managed ? frameState.skippedFeatureUids : {});
- gl.disable(gl.SCISSOR_TEST);
- }
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.VectorLayer.prototype.disposeInternal = function() {
- var replayGroup = this.replayGroup_;
- if (replayGroup) {
- var context = this.mapRenderer.getContext();
- replayGroup.getDeleteResourcesFunction(context)();
- this.replayGroup_ = null;
- }
- ol.renderer.webgl.Layer.prototype.disposeInternal.call(this);
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.VectorLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, hitTolerance, callback, thisArg) {
- if (!this.replayGroup_ || !this.layerState_) {
- return undefined;
- } else {
- var context = this.mapRenderer.getContext();
- var viewState = frameState.viewState;
- var layer = this.getLayer();
- var layerState = this.layerState_;
- /** @type {Object.<string, boolean>} */
- var features = {};
- return this.replayGroup_.forEachFeatureAtCoordinate(coordinate,
- context, viewState.center, viewState.resolution, viewState.rotation,
- frameState.size, frameState.pixelRatio, layerState.opacity,
- {},
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @return {?} Callback result.
- */
- function(feature) {
- var key = ol.getUid(feature).toString();
- if (!(key in features)) {
- features[key] = true;
- return callback.call(thisArg, feature, layer);
- }
- });
- }
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.VectorLayer.prototype.hasFeatureAtCoordinate = function(coordinate, frameState) {
- if (!this.replayGroup_ || !this.layerState_) {
- return false;
- } else {
- var context = this.mapRenderer.getContext();
- var viewState = frameState.viewState;
- var layerState = this.layerState_;
- return this.replayGroup_.hasFeatureAtCoordinate(coordinate,
- context, viewState.center, viewState.resolution, viewState.rotation,
- frameState.size, frameState.pixelRatio, layerState.opacity,
- frameState.skippedFeatureUids);
- }
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.VectorLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) {
- var coordinate = ol.transform.apply(
- frameState.pixelToCoordinateTransform, pixel.slice());
- var hasFeature = this.hasFeatureAtCoordinate(coordinate, frameState);
- if (hasFeature) {
- return callback.call(thisArg, this.getLayer(), null);
- } else {
- return undefined;
- }
- };
- /**
- * Handle changes in image style state.
- * @param {ol.events.Event} event Image style change event.
- * @private
- */
- ol.renderer.webgl.VectorLayer.prototype.handleStyleImageChange_ = function(event) {
- this.renderIfReadyAndVisible();
- };
- /**
- * @inheritDoc
- */
- ol.renderer.webgl.VectorLayer.prototype.prepareFrame = function(frameState, layerState, context) {
- var vectorLayer = /** @type {ol.layer.Vector} */ (this.getLayer());
- var vectorSource = vectorLayer.getSource();
- this.updateLogos(frameState, vectorSource);
- var animating = frameState.viewHints[ol.ViewHint.ANIMATING];
- var interacting = frameState.viewHints[ol.ViewHint.INTERACTING];
- var updateWhileAnimating = vectorLayer.getUpdateWhileAnimating();
- var updateWhileInteracting = vectorLayer.getUpdateWhileInteracting();
- if (!this.dirty_ && (!updateWhileAnimating && animating) ||
- (!updateWhileInteracting && interacting)) {
- return true;
- }
- var frameStateExtent = frameState.extent;
- var viewState = frameState.viewState;
- var projection = viewState.projection;
- var resolution = viewState.resolution;
- var pixelRatio = frameState.pixelRatio;
- var vectorLayerRevision = vectorLayer.getRevision();
- var vectorLayerRenderBuffer = vectorLayer.getRenderBuffer();
- var vectorLayerRenderOrder = vectorLayer.getRenderOrder();
- if (vectorLayerRenderOrder === undefined) {
- vectorLayerRenderOrder = ol.renderer.vector.defaultOrder;
- }
- var extent = ol.extent.buffer(frameStateExtent,
- vectorLayerRenderBuffer * resolution);
- if (!this.dirty_ &&
- this.renderedResolution_ == resolution &&
- this.renderedRevision_ == vectorLayerRevision &&
- this.renderedRenderOrder_ == vectorLayerRenderOrder &&
- ol.extent.containsExtent(this.renderedExtent_, extent)) {
- return true;
- }
- if (this.replayGroup_) {
- frameState.postRenderFunctions.push(
- this.replayGroup_.getDeleteResourcesFunction(context));
- }
- this.dirty_ = false;
- var replayGroup = new ol.render.webgl.ReplayGroup(
- ol.renderer.vector.getTolerance(resolution, pixelRatio),
- extent, vectorLayer.getRenderBuffer());
- vectorSource.loadFeatures(extent, resolution, projection);
- /**
- * @param {ol.Feature} feature Feature.
- * @this {ol.renderer.webgl.VectorLayer}
- */
- var renderFeature = function(feature) {
- var styles;
- var styleFunction = feature.getStyleFunction();
- if (styleFunction) {
- styles = styleFunction.call(feature, resolution);
- } else {
- styleFunction = vectorLayer.getStyleFunction();
- if (styleFunction) {
- styles = styleFunction(feature, resolution);
- }
- }
- if (styles) {
- var dirty = this.renderFeature(
- feature, resolution, pixelRatio, styles, replayGroup);
- this.dirty_ = this.dirty_ || dirty;
- }
- };
- if (vectorLayerRenderOrder) {
- /** @type {Array.<ol.Feature>} */
- var features = [];
- vectorSource.forEachFeatureInExtent(extent,
- /**
- * @param {ol.Feature} feature Feature.
- */
- function(feature) {
- features.push(feature);
- }, this);
- features.sort(vectorLayerRenderOrder);
- features.forEach(renderFeature, this);
- } else {
- vectorSource.forEachFeatureInExtent(extent, renderFeature, this);
- }
- replayGroup.finish(context);
- this.renderedResolution_ = resolution;
- this.renderedRevision_ = vectorLayerRevision;
- this.renderedRenderOrder_ = vectorLayerRenderOrder;
- this.renderedExtent_ = extent;
- this.replayGroup_ = replayGroup;
- return true;
- };
- /**
- * @param {ol.Feature} feature Feature.
- * @param {number} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @param {(ol.style.Style|Array.<ol.style.Style>)} styles The style or array of
- * styles.
- * @param {ol.render.webgl.ReplayGroup} replayGroup Replay group.
- * @return {boolean} `true` if an image is loading.
- */
- ol.renderer.webgl.VectorLayer.prototype.renderFeature = function(feature, resolution, pixelRatio, styles, replayGroup) {
- if (!styles) {
- return false;
- }
- var loading = false;
- if (Array.isArray(styles)) {
- for (var i = styles.length - 1, ii = 0; i >= ii; --i) {
- loading = ol.renderer.vector.renderFeature(
- replayGroup, feature, styles[i],
- ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
- this.handleStyleImageChange_, this) || loading;
- }
- } else {
- loading = ol.renderer.vector.renderFeature(
- replayGroup, feature, styles,
- ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
- this.handleStyleImageChange_, this) || loading;
- }
- return loading;
- };
- goog.provide('ol.Map');
- goog.require('ol');
- goog.require('ol.PluggableMap');
- goog.require('ol.PluginType');
- goog.require('ol.control');
- goog.require('ol.interaction');
- goog.require('ol.obj');
- goog.require('ol.plugins');
- goog.require('ol.renderer.canvas.ImageLayer');
- goog.require('ol.renderer.canvas.Map');
- goog.require('ol.renderer.canvas.TileLayer');
- goog.require('ol.renderer.canvas.VectorLayer');
- goog.require('ol.renderer.canvas.VectorTileLayer');
- goog.require('ol.renderer.webgl.ImageLayer');
- goog.require('ol.renderer.webgl.Map');
- goog.require('ol.renderer.webgl.TileLayer');
- goog.require('ol.renderer.webgl.VectorLayer');
- if (ol.ENABLE_CANVAS) {
- ol.plugins.register(ol.PluginType.MAP_RENDERER, ol.renderer.canvas.Map);
- ol.plugins.registerMultiple(ol.PluginType.LAYER_RENDERER, [
- ol.renderer.canvas.ImageLayer,
- ol.renderer.canvas.TileLayer,
- ol.renderer.canvas.VectorLayer,
- ol.renderer.canvas.VectorTileLayer
- ]);
- }
- if (ol.ENABLE_WEBGL) {
- ol.plugins.register(ol.PluginType.MAP_RENDERER, ol.renderer.webgl.Map);
- ol.plugins.registerMultiple(ol.PluginType.LAYER_RENDERER, [
- ol.renderer.webgl.ImageLayer,
- ol.renderer.webgl.TileLayer,
- ol.renderer.webgl.VectorLayer
- ]);
- }
- /**
- * @classdesc
- * The map is the core component of OpenLayers. For a map to render, a view,
- * one or more layers, and a target container are needed:
- *
- * var map = new ol.Map({
- * view: new ol.View({
- * center: [0, 0],
- * zoom: 1
- * }),
- * layers: [
- * new ol.layer.Tile({
- * source: new ol.source.OSM()
- * })
- * ],
- * target: 'map'
- * });
- *
- * The above snippet creates a map using a {@link ol.layer.Tile} to display
- * {@link ol.source.OSM} OSM data and render it to a DOM element with the
- * id `map`.
- *
- * The constructor places a viewport container (with CSS class name
- * `ol-viewport`) in the target element (see `getViewport()`), and then two
- * further elements within the viewport: one with CSS class name
- * `ol-overlaycontainer-stopevent` for controls and some overlays, and one with
- * CSS class name `ol-overlaycontainer` for other overlays (see the `stopEvent`
- * option of {@link ol.Overlay} for the difference). The map itself is placed in
- * a further element within the viewport.
- *
- * Layers are stored as a `ol.Collection` in layerGroups. A top-level group is
- * provided by the library. This is what is accessed by `getLayerGroup` and
- * `setLayerGroup`. Layers entered in the options are added to this group, and
- * `addLayer` and `removeLayer` change the layer collection in the group.
- * `getLayers` is a convenience function for `getLayerGroup().getLayers()`.
- * Note that `ol.layer.Group` is a subclass of `ol.layer.Base`, so layers
- * entered in the options or added with `addLayer` can be groups, which can
- * contain further groups, and so on.
- *
- * @constructor
- * @extends {ol.PluggableMap}
- * @param {olx.MapOptions} options Map options.
- * @fires ol.MapBrowserEvent
- * @fires ol.MapEvent
- * @fires ol.render.Event#postcompose
- * @fires ol.render.Event#precompose
- * @api
- */
- ol.Map = function(options) {
- options = ol.obj.assign({}, options);
- if (!options.controls) {
- options.controls = ol.control.defaults();
- }
- if (!options.interactions) {
- options.interactions = ol.interaction.defaults();
- }
- ol.PluggableMap.call(this, options);
- };
- ol.inherits(ol.Map, ol.PluggableMap);
- goog.provide('ol.net');
- goog.require('ol');
- /**
- * Simple JSONP helper. Supports error callbacks and a custom callback param.
- * The error callback will be called when no JSONP is executed after 10 seconds.
- *
- * @param {string} url Request url. A 'callback' query parameter will be
- * appended.
- * @param {Function} callback Callback on success.
- * @param {function()=} opt_errback Callback on error.
- * @param {string=} opt_callbackParam Custom query parameter for the JSONP
- * callback. Default is 'callback'.
- */
- ol.net.jsonp = function(url, callback, opt_errback, opt_callbackParam) {
- var script = document.createElement('script');
- var key = 'olc_' + ol.getUid(callback);
- function cleanup() {
- delete window[key];
- script.parentNode.removeChild(script);
- }
- script.async = true;
- script.src = url + (url.indexOf('?') == -1 ? '?' : '&') +
- (opt_callbackParam || 'callback') + '=' + key;
- var timer = setTimeout(function() {
- cleanup();
- if (opt_errback) {
- opt_errback();
- }
- }, 10000);
- window[key] = function(data) {
- clearTimeout(timer);
- cleanup();
- callback(data);
- };
- document.getElementsByTagName('head')[0].appendChild(script);
- };
- goog.provide('ol.proj.common');
- goog.require('ol.proj');
- /**
- * Deprecated. Transforms between EPSG:4326 and EPSG:3857 are now included by
- * default. There is no need to call this function in application code and it
- * will be removed in a future major release.
- * @deprecated This function is no longer necessary.
- * @api
- */
- ol.proj.common.add = ol.proj.addCommon;
- goog.provide('ol.render');
- goog.require('ol.has');
- goog.require('ol.transform');
- goog.require('ol.render.canvas.Immediate');
- /**
- * Binds a Canvas Immediate API to a canvas context, to allow drawing geometries
- * to the context's canvas.
- *
- * The units for geometry coordinates are css pixels relative to the top left
- * corner of the canvas element.
- * ```js
- * var canvas = document.createElement('canvas');
- * var render = ol.render.toContext(canvas.getContext('2d'),
- * { size: [100, 100] });
- * render.setFillStrokeStyle(new ol.style.Fill({ color: blue }));
- * render.drawPolygon(
- * new ol.geom.Polygon([[[0, 0], [100, 100], [100, 0], [0, 0]]]));
- * ```
- *
- * @param {CanvasRenderingContext2D} context Canvas context.
- * @param {olx.render.ToContextOptions=} opt_options Options.
- * @return {ol.render.canvas.Immediate} Canvas Immediate.
- * @api
- */
- ol.render.toContext = function(context, opt_options) {
- var canvas = context.canvas;
- var options = opt_options ? opt_options : {};
- var pixelRatio = options.pixelRatio || ol.has.DEVICE_PIXEL_RATIO;
- var size = options.size;
- if (size) {
- canvas.width = size[0] * pixelRatio;
- canvas.height = size[1] * pixelRatio;
- canvas.style.width = size[0] + 'px';
- canvas.style.height = size[1] + 'px';
- }
- var extent = [0, 0, canvas.width, canvas.height];
- var transform = ol.transform.scale(ol.transform.create(), pixelRatio, pixelRatio);
- return new ol.render.canvas.Immediate(context, pixelRatio, extent, transform,
- 0);
- };
- goog.provide('ol.reproj');
- goog.require('ol.dom');
- goog.require('ol.extent');
- goog.require('ol.math');
- goog.require('ol.proj');
- /**
- * Calculates ideal resolution to use from the source in order to achieve
- * pixel mapping as close as possible to 1:1 during reprojection.
- * The resolution is calculated regardless of what resolutions
- * are actually available in the dataset (TileGrid, Image, ...).
- *
- * @param {ol.proj.Projection} sourceProj Source projection.
- * @param {ol.proj.Projection} targetProj Target projection.
- * @param {ol.Coordinate} targetCenter Target center.
- * @param {number} targetResolution Target resolution.
- * @return {number} The best resolution to use. Can be +-Infinity, NaN or 0.
- */
- ol.reproj.calculateSourceResolution = function(sourceProj, targetProj,
- targetCenter, targetResolution) {
- var sourceCenter = ol.proj.transform(targetCenter, targetProj, sourceProj);
- // calculate the ideal resolution of the source data
- var sourceResolution =
- ol.proj.getPointResolution(targetProj, targetResolution, targetCenter);
- var targetMetersPerUnit = targetProj.getMetersPerUnit();
- if (targetMetersPerUnit !== undefined) {
- sourceResolution *= targetMetersPerUnit;
- }
- var sourceMetersPerUnit = sourceProj.getMetersPerUnit();
- if (sourceMetersPerUnit !== undefined) {
- sourceResolution /= sourceMetersPerUnit;
- }
- // Based on the projection properties, the point resolution at the specified
- // coordinates may be slightly different. We need to reverse-compensate this
- // in order to achieve optimal results.
- var sourceExtent = sourceProj.getExtent();
- if (!sourceExtent || ol.extent.containsCoordinate(sourceExtent, sourceCenter)) {
- var compensationFactor =
- ol.proj.getPointResolution(sourceProj, sourceResolution, sourceCenter) /
- sourceResolution;
- if (isFinite(compensationFactor) && compensationFactor > 0) {
- sourceResolution /= compensationFactor;
- }
- }
- return sourceResolution;
- };
- /**
- * Enlarge the clipping triangle point by 1 pixel to ensure the edges overlap
- * in order to mask gaps caused by antialiasing.
- *
- * @param {number} centroidX Centroid of the triangle (x coordinate in pixels).
- * @param {number} centroidY Centroid of the triangle (y coordinate in pixels).
- * @param {number} x X coordinate of the point (in pixels).
- * @param {number} y Y coordinate of the point (in pixels).
- * @return {ol.Coordinate} New point 1 px farther from the centroid.
- * @private
- */
- ol.reproj.enlargeClipPoint_ = function(centroidX, centroidY, x, y) {
- var dX = x - centroidX, dY = y - centroidY;
- var distance = Math.sqrt(dX * dX + dY * dY);
- return [Math.round(x + dX / distance), Math.round(y + dY / distance)];
- };
- /**
- * Renders the source data into new canvas based on the triangulation.
- *
- * @param {number} width Width of the canvas.
- * @param {number} height Height of the canvas.
- * @param {number} pixelRatio Pixel ratio.
- * @param {number} sourceResolution Source resolution.
- * @param {ol.Extent} sourceExtent Extent of the data source.
- * @param {number} targetResolution Target resolution.
- * @param {ol.Extent} targetExtent Target extent.
- * @param {ol.reproj.Triangulation} triangulation Calculated triangulation.
- * @param {Array.<{extent: ol.Extent,
- * image: (HTMLCanvasElement|Image|HTMLVideoElement)}>} sources
- * Array of sources.
- * @param {number} gutter Gutter of the sources.
- * @param {boolean=} opt_renderEdges Render reprojection edges.
- * @return {HTMLCanvasElement} Canvas with reprojected data.
- */
- ol.reproj.render = function(width, height, pixelRatio,
- sourceResolution, sourceExtent, targetResolution, targetExtent,
- triangulation, sources, gutter, opt_renderEdges) {
- var context = ol.dom.createCanvasContext2D(Math.round(pixelRatio * width),
- Math.round(pixelRatio * height));
- if (sources.length === 0) {
- return context.canvas;
- }
- context.scale(pixelRatio, pixelRatio);
- var sourceDataExtent = ol.extent.createEmpty();
- sources.forEach(function(src, i, arr) {
- ol.extent.extend(sourceDataExtent, src.extent);
- });
- var canvasWidthInUnits = ol.extent.getWidth(sourceDataExtent);
- var canvasHeightInUnits = ol.extent.getHeight(sourceDataExtent);
- var stitchContext = ol.dom.createCanvasContext2D(
- Math.round(pixelRatio * canvasWidthInUnits / sourceResolution),
- Math.round(pixelRatio * canvasHeightInUnits / sourceResolution));
- var stitchScale = pixelRatio / sourceResolution;
- sources.forEach(function(src, i, arr) {
- var xPos = src.extent[0] - sourceDataExtent[0];
- var yPos = -(src.extent[3] - sourceDataExtent[3]);
- var srcWidth = ol.extent.getWidth(src.extent);
- var srcHeight = ol.extent.getHeight(src.extent);
- stitchContext.drawImage(
- src.image,
- gutter, gutter,
- src.image.width - 2 * gutter, src.image.height - 2 * gutter,
- xPos * stitchScale, yPos * stitchScale,
- srcWidth * stitchScale, srcHeight * stitchScale);
- });
- var targetTopLeft = ol.extent.getTopLeft(targetExtent);
- triangulation.getTriangles().forEach(function(triangle, i, arr) {
- /* Calculate affine transform (src -> dst)
- * Resulting matrix can be used to transform coordinate
- * from `sourceProjection` to destination pixels.
- *
- * To optimize number of context calls and increase numerical stability,
- * we also do the following operations:
- * trans(-topLeftExtentCorner), scale(1 / targetResolution), scale(1, -1)
- * here before solving the linear system so [ui, vi] are pixel coordinates.
- *
- * Src points: xi, yi
- * Dst points: ui, vi
- * Affine coefficients: aij
- *
- * | x0 y0 1 0 0 0 | |a00| |u0|
- * | x1 y1 1 0 0 0 | |a01| |u1|
- * | x2 y2 1 0 0 0 | x |a02| = |u2|
- * | 0 0 0 x0 y0 1 | |a10| |v0|
- * | 0 0 0 x1 y1 1 | |a11| |v1|
- * | 0 0 0 x2 y2 1 | |a12| |v2|
- */
- var source = triangle.source, target = triangle.target;
- var x0 = source[0][0], y0 = source[0][1],
- x1 = source[1][0], y1 = source[1][1],
- x2 = source[2][0], y2 = source[2][1];
- var u0 = (target[0][0] - targetTopLeft[0]) / targetResolution,
- v0 = -(target[0][1] - targetTopLeft[1]) / targetResolution;
- var u1 = (target[1][0] - targetTopLeft[0]) / targetResolution,
- v1 = -(target[1][1] - targetTopLeft[1]) / targetResolution;
- var u2 = (target[2][0] - targetTopLeft[0]) / targetResolution,
- v2 = -(target[2][1] - targetTopLeft[1]) / targetResolution;
- // Shift all the source points to improve numerical stability
- // of all the subsequent calculations. The [x0, y0] is used here.
- // This is also used to simplify the linear system.
- var sourceNumericalShiftX = x0, sourceNumericalShiftY = y0;
- x0 = 0;
- y0 = 0;
- x1 -= sourceNumericalShiftX;
- y1 -= sourceNumericalShiftY;
- x2 -= sourceNumericalShiftX;
- y2 -= sourceNumericalShiftY;
- var augmentedMatrix = [
- [x1, y1, 0, 0, u1 - u0],
- [x2, y2, 0, 0, u2 - u0],
- [0, 0, x1, y1, v1 - v0],
- [0, 0, x2, y2, v2 - v0]
- ];
- var affineCoefs = ol.math.solveLinearSystem(augmentedMatrix);
- if (!affineCoefs) {
- return;
- }
- context.save();
- context.beginPath();
- var centroidX = (u0 + u1 + u2) / 3, centroidY = (v0 + v1 + v2) / 3;
- var p0 = ol.reproj.enlargeClipPoint_(centroidX, centroidY, u0, v0);
- var p1 = ol.reproj.enlargeClipPoint_(centroidX, centroidY, u1, v1);
- var p2 = ol.reproj.enlargeClipPoint_(centroidX, centroidY, u2, v2);
- context.moveTo(p1[0], p1[1]);
- context.lineTo(p0[0], p0[1]);
- context.lineTo(p2[0], p2[1]);
- context.clip();
- context.transform(
- affineCoefs[0], affineCoefs[2], affineCoefs[1], affineCoefs[3], u0, v0);
- context.translate(sourceDataExtent[0] - sourceNumericalShiftX,
- sourceDataExtent[3] - sourceNumericalShiftY);
- context.scale(sourceResolution / pixelRatio,
- -sourceResolution / pixelRatio);
- context.drawImage(stitchContext.canvas, 0, 0);
- context.restore();
- });
- if (opt_renderEdges) {
- context.save();
- context.strokeStyle = 'black';
- context.lineWidth = 1;
- triangulation.getTriangles().forEach(function(triangle, i, arr) {
- var target = triangle.target;
- var u0 = (target[0][0] - targetTopLeft[0]) / targetResolution,
- v0 = -(target[0][1] - targetTopLeft[1]) / targetResolution;
- var u1 = (target[1][0] - targetTopLeft[0]) / targetResolution,
- v1 = -(target[1][1] - targetTopLeft[1]) / targetResolution;
- var u2 = (target[2][0] - targetTopLeft[0]) / targetResolution,
- v2 = -(target[2][1] - targetTopLeft[1]) / targetResolution;
- context.beginPath();
- context.moveTo(u1, v1);
- context.lineTo(u0, v0);
- context.lineTo(u2, v2);
- context.closePath();
- context.stroke();
- });
- context.restore();
- }
- return context.canvas;
- };
- goog.provide('ol.reproj.Triangulation');
- goog.require('ol');
- goog.require('ol.extent');
- goog.require('ol.math');
- goog.require('ol.proj');
- /**
- * @classdesc
- * Class containing triangulation of the given target extent.
- * Used for determining source data and the reprojection itself.
- *
- * @param {ol.proj.Projection} sourceProj Source projection.
- * @param {ol.proj.Projection} targetProj Target projection.
- * @param {ol.Extent} targetExtent Target extent to triangulate.
- * @param {ol.Extent} maxSourceExtent Maximal source extent that can be used.
- * @param {number} errorThreshold Acceptable error (in source units).
- * @constructor
- */
- ol.reproj.Triangulation = function(sourceProj, targetProj, targetExtent,
- maxSourceExtent, errorThreshold) {
- /**
- * @type {ol.proj.Projection}
- * @private
- */
- this.sourceProj_ = sourceProj;
- /**
- * @type {ol.proj.Projection}
- * @private
- */
- this.targetProj_ = targetProj;
- /** @type {!Object.<string, ol.Coordinate>} */
- var transformInvCache = {};
- var transformInv = ol.proj.getTransform(this.targetProj_, this.sourceProj_);
- /**
- * @param {ol.Coordinate} c A coordinate.
- * @return {ol.Coordinate} Transformed coordinate.
- * @private
- */
- this.transformInv_ = function(c) {
- var key = c[0] + '/' + c[1];
- if (!transformInvCache[key]) {
- transformInvCache[key] = transformInv(c);
- }
- return transformInvCache[key];
- };
- /**
- * @type {ol.Extent}
- * @private
- */
- this.maxSourceExtent_ = maxSourceExtent;
- /**
- * @type {number}
- * @private
- */
- this.errorThresholdSquared_ = errorThreshold * errorThreshold;
- /**
- * @type {Array.<ol.ReprojTriangle>}
- * @private
- */
- this.triangles_ = [];
- /**
- * Indicates that the triangulation crosses edge of the source projection.
- * @type {boolean}
- * @private
- */
- this.wrapsXInSource_ = false;
- /**
- * @type {boolean}
- * @private
- */
- this.canWrapXInSource_ = this.sourceProj_.canWrapX() &&
- !!maxSourceExtent &&
- !!this.sourceProj_.getExtent() &&
- (ol.extent.getWidth(maxSourceExtent) ==
- ol.extent.getWidth(this.sourceProj_.getExtent()));
- /**
- * @type {?number}
- * @private
- */
- this.sourceWorldWidth_ = this.sourceProj_.getExtent() ?
- ol.extent.getWidth(this.sourceProj_.getExtent()) : null;
- /**
- * @type {?number}
- * @private
- */
- this.targetWorldWidth_ = this.targetProj_.getExtent() ?
- ol.extent.getWidth(this.targetProj_.getExtent()) : null;
- var destinationTopLeft = ol.extent.getTopLeft(targetExtent);
- var destinationTopRight = ol.extent.getTopRight(targetExtent);
- var destinationBottomRight = ol.extent.getBottomRight(targetExtent);
- var destinationBottomLeft = ol.extent.getBottomLeft(targetExtent);
- var sourceTopLeft = this.transformInv_(destinationTopLeft);
- var sourceTopRight = this.transformInv_(destinationTopRight);
- var sourceBottomRight = this.transformInv_(destinationBottomRight);
- var sourceBottomLeft = this.transformInv_(destinationBottomLeft);
- this.addQuad_(
- destinationTopLeft, destinationTopRight,
- destinationBottomRight, destinationBottomLeft,
- sourceTopLeft, sourceTopRight, sourceBottomRight, sourceBottomLeft,
- ol.RASTER_REPROJECTION_MAX_SUBDIVISION);
- if (this.wrapsXInSource_) {
- var leftBound = Infinity;
- this.triangles_.forEach(function(triangle, i, arr) {
- leftBound = Math.min(leftBound,
- triangle.source[0][0], triangle.source[1][0], triangle.source[2][0]);
- });
- // Shift triangles to be as close to `leftBound` as possible
- // (if the distance is more than `worldWidth / 2` it can be closer.
- this.triangles_.forEach(function(triangle) {
- if (Math.max(triangle.source[0][0], triangle.source[1][0],
- triangle.source[2][0]) - leftBound > this.sourceWorldWidth_ / 2) {
- var newTriangle = [[triangle.source[0][0], triangle.source[0][1]],
- [triangle.source[1][0], triangle.source[1][1]],
- [triangle.source[2][0], triangle.source[2][1]]];
- if ((newTriangle[0][0] - leftBound) > this.sourceWorldWidth_ / 2) {
- newTriangle[0][0] -= this.sourceWorldWidth_;
- }
- if ((newTriangle[1][0] - leftBound) > this.sourceWorldWidth_ / 2) {
- newTriangle[1][0] -= this.sourceWorldWidth_;
- }
- if ((newTriangle[2][0] - leftBound) > this.sourceWorldWidth_ / 2) {
- newTriangle[2][0] -= this.sourceWorldWidth_;
- }
- // Rarely (if the extent contains both the dateline and prime meridian)
- // the shift can in turn break some triangles.
- // Detect this here and don't shift in such cases.
- var minX = Math.min(
- newTriangle[0][0], newTriangle[1][0], newTriangle[2][0]);
- var maxX = Math.max(
- newTriangle[0][0], newTriangle[1][0], newTriangle[2][0]);
- if ((maxX - minX) < this.sourceWorldWidth_ / 2) {
- triangle.source = newTriangle;
- }
- }
- }, this);
- }
- transformInvCache = {};
- };
- /**
- * Adds triangle to the triangulation.
- * @param {ol.Coordinate} a The target a coordinate.
- * @param {ol.Coordinate} b The target b coordinate.
- * @param {ol.Coordinate} c The target c coordinate.
- * @param {ol.Coordinate} aSrc The source a coordinate.
- * @param {ol.Coordinate} bSrc The source b coordinate.
- * @param {ol.Coordinate} cSrc The source c coordinate.
- * @private
- */
- ol.reproj.Triangulation.prototype.addTriangle_ = function(a, b, c,
- aSrc, bSrc, cSrc) {
- this.triangles_.push({
- source: [aSrc, bSrc, cSrc],
- target: [a, b, c]
- });
- };
- /**
- * Adds quad (points in clock-wise order) to the triangulation
- * (and reprojects the vertices) if valid.
- * Performs quad subdivision if needed to increase precision.
- *
- * @param {ol.Coordinate} a The target a coordinate.
- * @param {ol.Coordinate} b The target b coordinate.
- * @param {ol.Coordinate} c The target c coordinate.
- * @param {ol.Coordinate} d The target d coordinate.
- * @param {ol.Coordinate} aSrc The source a coordinate.
- * @param {ol.Coordinate} bSrc The source b coordinate.
- * @param {ol.Coordinate} cSrc The source c coordinate.
- * @param {ol.Coordinate} dSrc The source d coordinate.
- * @param {number} maxSubdivision Maximal allowed subdivision of the quad.
- * @private
- */
- ol.reproj.Triangulation.prototype.addQuad_ = function(a, b, c, d,
- aSrc, bSrc, cSrc, dSrc, maxSubdivision) {
- var sourceQuadExtent = ol.extent.boundingExtent([aSrc, bSrc, cSrc, dSrc]);
- var sourceCoverageX = this.sourceWorldWidth_ ?
- ol.extent.getWidth(sourceQuadExtent) / this.sourceWorldWidth_ : null;
- var sourceWorldWidth = /** @type {number} */ (this.sourceWorldWidth_);
- // when the quad is wrapped in the source projection
- // it covers most of the projection extent, but not fully
- var wrapsX = this.sourceProj_.canWrapX() &&
- sourceCoverageX > 0.5 && sourceCoverageX < 1;
- var needsSubdivision = false;
- if (maxSubdivision > 0) {
- if (this.targetProj_.isGlobal() && this.targetWorldWidth_) {
- var targetQuadExtent = ol.extent.boundingExtent([a, b, c, d]);
- var targetCoverageX =
- ol.extent.getWidth(targetQuadExtent) / this.targetWorldWidth_;
- needsSubdivision |=
- targetCoverageX > ol.RASTER_REPROJECTION_MAX_TRIANGLE_WIDTH;
- }
- if (!wrapsX && this.sourceProj_.isGlobal() && sourceCoverageX) {
- needsSubdivision |=
- sourceCoverageX > ol.RASTER_REPROJECTION_MAX_TRIANGLE_WIDTH;
- }
- }
- if (!needsSubdivision && this.maxSourceExtent_) {
- if (!ol.extent.intersects(sourceQuadExtent, this.maxSourceExtent_)) {
- // whole quad outside source projection extent -> ignore
- return;
- }
- }
- if (!needsSubdivision) {
- if (!isFinite(aSrc[0]) || !isFinite(aSrc[1]) ||
- !isFinite(bSrc[0]) || !isFinite(bSrc[1]) ||
- !isFinite(cSrc[0]) || !isFinite(cSrc[1]) ||
- !isFinite(dSrc[0]) || !isFinite(dSrc[1])) {
- if (maxSubdivision > 0) {
- needsSubdivision = true;
- } else {
- return;
- }
- }
- }
- if (maxSubdivision > 0) {
- if (!needsSubdivision) {
- var center = [(a[0] + c[0]) / 2, (a[1] + c[1]) / 2];
- var centerSrc = this.transformInv_(center);
- var dx;
- if (wrapsX) {
- var centerSrcEstimX =
- (ol.math.modulo(aSrc[0], sourceWorldWidth) +
- ol.math.modulo(cSrc[0], sourceWorldWidth)) / 2;
- dx = centerSrcEstimX -
- ol.math.modulo(centerSrc[0], sourceWorldWidth);
- } else {
- dx = (aSrc[0] + cSrc[0]) / 2 - centerSrc[0];
- }
- var dy = (aSrc[1] + cSrc[1]) / 2 - centerSrc[1];
- var centerSrcErrorSquared = dx * dx + dy * dy;
- needsSubdivision = centerSrcErrorSquared > this.errorThresholdSquared_;
- }
- if (needsSubdivision) {
- if (Math.abs(a[0] - c[0]) <= Math.abs(a[1] - c[1])) {
- // split horizontally (top & bottom)
- var bc = [(b[0] + c[0]) / 2, (b[1] + c[1]) / 2];
- var bcSrc = this.transformInv_(bc);
- var da = [(d[0] + a[0]) / 2, (d[1] + a[1]) / 2];
- var daSrc = this.transformInv_(da);
- this.addQuad_(
- a, b, bc, da, aSrc, bSrc, bcSrc, daSrc, maxSubdivision - 1);
- this.addQuad_(
- da, bc, c, d, daSrc, bcSrc, cSrc, dSrc, maxSubdivision - 1);
- } else {
- // split vertically (left & right)
- var ab = [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2];
- var abSrc = this.transformInv_(ab);
- var cd = [(c[0] + d[0]) / 2, (c[1] + d[1]) / 2];
- var cdSrc = this.transformInv_(cd);
- this.addQuad_(
- a, ab, cd, d, aSrc, abSrc, cdSrc, dSrc, maxSubdivision - 1);
- this.addQuad_(
- ab, b, c, cd, abSrc, bSrc, cSrc, cdSrc, maxSubdivision - 1);
- }
- return;
- }
- }
- if (wrapsX) {
- if (!this.canWrapXInSource_) {
- return;
- }
- this.wrapsXInSource_ = true;
- }
- this.addTriangle_(a, c, d, aSrc, cSrc, dSrc);
- this.addTriangle_(a, b, c, aSrc, bSrc, cSrc);
- };
- /**
- * Calculates extent of the 'source' coordinates from all the triangles.
- *
- * @return {ol.Extent} Calculated extent.
- */
- ol.reproj.Triangulation.prototype.calculateSourceExtent = function() {
- var extent = ol.extent.createEmpty();
- this.triangles_.forEach(function(triangle, i, arr) {
- var src = triangle.source;
- ol.extent.extendCoordinate(extent, src[0]);
- ol.extent.extendCoordinate(extent, src[1]);
- ol.extent.extendCoordinate(extent, src[2]);
- });
- return extent;
- };
- /**
- * @return {Array.<ol.ReprojTriangle>} Array of the calculated triangles.
- */
- ol.reproj.Triangulation.prototype.getTriangles = function() {
- return this.triangles_;
- };
- goog.provide('ol.reproj.Image');
- goog.require('ol');
- goog.require('ol.ImageBase');
- goog.require('ol.ImageState');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.extent');
- goog.require('ol.reproj');
- goog.require('ol.reproj.Triangulation');
- /**
- * @classdesc
- * Class encapsulating single reprojected image.
- * See {@link ol.source.Image}.
- *
- * @constructor
- * @extends {ol.ImageBase}
- * @param {ol.proj.Projection} sourceProj Source projection (of the data).
- * @param {ol.proj.Projection} targetProj Target projection.
- * @param {ol.Extent} targetExtent Target extent.
- * @param {number} targetResolution Target resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.ReprojImageFunctionType} getImageFunction
- * Function returning source images (extent, resolution, pixelRatio).
- */
- ol.reproj.Image = function(sourceProj, targetProj,
- targetExtent, targetResolution, pixelRatio, getImageFunction) {
- /**
- * @private
- * @type {ol.proj.Projection}
- */
- this.targetProj_ = targetProj;
- /**
- * @private
- * @type {ol.Extent}
- */
- this.maxSourceExtent_ = sourceProj.getExtent();
- var maxTargetExtent = targetProj.getExtent();
- var limitedTargetExtent = maxTargetExtent ?
- ol.extent.getIntersection(targetExtent, maxTargetExtent) : targetExtent;
- var targetCenter = ol.extent.getCenter(limitedTargetExtent);
- var sourceResolution = ol.reproj.calculateSourceResolution(
- sourceProj, targetProj, targetCenter, targetResolution);
- var errorThresholdInPixels = ol.DEFAULT_RASTER_REPROJECTION_ERROR_THRESHOLD;
- /**
- * @private
- * @type {!ol.reproj.Triangulation}
- */
- this.triangulation_ = new ol.reproj.Triangulation(
- sourceProj, targetProj, limitedTargetExtent, this.maxSourceExtent_,
- sourceResolution * errorThresholdInPixels);
- /**
- * @private
- * @type {number}
- */
- this.targetResolution_ = targetResolution;
- /**
- * @private
- * @type {ol.Extent}
- */
- this.targetExtent_ = targetExtent;
- var sourceExtent = this.triangulation_.calculateSourceExtent();
- /**
- * @private
- * @type {ol.ImageBase}
- */
- this.sourceImage_ =
- getImageFunction(sourceExtent, sourceResolution, pixelRatio);
- /**
- * @private
- * @type {number}
- */
- this.sourcePixelRatio_ =
- this.sourceImage_ ? this.sourceImage_.getPixelRatio() : 1;
- /**
- * @private
- * @type {HTMLCanvasElement}
- */
- this.canvas_ = null;
- /**
- * @private
- * @type {?ol.EventsKey}
- */
- this.sourceListenerKey_ = null;
- var state = ol.ImageState.LOADED;
- if (this.sourceImage_) {
- state = ol.ImageState.IDLE;
- }
- ol.ImageBase.call(this, targetExtent, targetResolution, this.sourcePixelRatio_, state);
- };
- ol.inherits(ol.reproj.Image, ol.ImageBase);
- /**
- * @inheritDoc
- */
- ol.reproj.Image.prototype.disposeInternal = function() {
- if (this.state == ol.ImageState.LOADING) {
- this.unlistenSource_();
- }
- ol.ImageBase.prototype.disposeInternal.call(this);
- };
- /**
- * @inheritDoc
- */
- ol.reproj.Image.prototype.getImage = function() {
- return this.canvas_;
- };
- /**
- * @return {ol.proj.Projection} Projection.
- */
- ol.reproj.Image.prototype.getProjection = function() {
- return this.targetProj_;
- };
- /**
- * @private
- */
- ol.reproj.Image.prototype.reproject_ = function() {
- var sourceState = this.sourceImage_.getState();
- if (sourceState == ol.ImageState.LOADED) {
- var width = ol.extent.getWidth(this.targetExtent_) / this.targetResolution_;
- var height =
- ol.extent.getHeight(this.targetExtent_) / this.targetResolution_;
- this.canvas_ = ol.reproj.render(width, height, this.sourcePixelRatio_,
- this.sourceImage_.getResolution(), this.maxSourceExtent_,
- this.targetResolution_, this.targetExtent_, this.triangulation_, [{
- extent: this.sourceImage_.getExtent(),
- image: this.sourceImage_.getImage()
- }], 0);
- }
- this.state = sourceState;
- this.changed();
- };
- /**
- * @inheritDoc
- */
- ol.reproj.Image.prototype.load = function() {
- if (this.state == ol.ImageState.IDLE) {
- this.state = ol.ImageState.LOADING;
- this.changed();
- var sourceState = this.sourceImage_.getState();
- if (sourceState == ol.ImageState.LOADED ||
- sourceState == ol.ImageState.ERROR) {
- this.reproject_();
- } else {
- this.sourceListenerKey_ = ol.events.listen(this.sourceImage_,
- ol.events.EventType.CHANGE, function(e) {
- var sourceState = this.sourceImage_.getState();
- if (sourceState == ol.ImageState.LOADED ||
- sourceState == ol.ImageState.ERROR) {
- this.unlistenSource_();
- this.reproject_();
- }
- }, this);
- this.sourceImage_.load();
- }
- }
- };
- /**
- * @private
- */
- ol.reproj.Image.prototype.unlistenSource_ = function() {
- ol.events.unlistenByKey(/** @type {!ol.EventsKey} */ (this.sourceListenerKey_));
- this.sourceListenerKey_ = null;
- };
- goog.provide('ol.reproj.Tile');
- goog.require('ol');
- goog.require('ol.Tile');
- goog.require('ol.TileState');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.extent');
- goog.require('ol.math');
- goog.require('ol.reproj');
- goog.require('ol.reproj.Triangulation');
- /**
- * @classdesc
- * Class encapsulating single reprojected tile.
- * See {@link ol.source.TileImage}.
- *
- * @constructor
- * @extends {ol.Tile}
- * @param {ol.proj.Projection} sourceProj Source projection.
- * @param {ol.tilegrid.TileGrid} sourceTileGrid Source tile grid.
- * @param {ol.proj.Projection} targetProj Target projection.
- * @param {ol.tilegrid.TileGrid} targetTileGrid Target tile grid.
- * @param {ol.TileCoord} tileCoord Coordinate of the tile.
- * @param {ol.TileCoord} wrappedTileCoord Coordinate of the tile wrapped in X.
- * @param {number} pixelRatio Pixel ratio.
- * @param {number} gutter Gutter of the source tiles.
- * @param {ol.ReprojTileFunctionType} getTileFunction
- * Function returning source tiles (z, x, y, pixelRatio).
- * @param {number=} opt_errorThreshold Acceptable reprojection error (in px).
- * @param {boolean=} opt_renderEdges Render reprojection edges.
- */
- ol.reproj.Tile = function(sourceProj, sourceTileGrid,
- targetProj, targetTileGrid, tileCoord, wrappedTileCoord,
- pixelRatio, gutter, getTileFunction,
- opt_errorThreshold, opt_renderEdges) {
- ol.Tile.call(this, tileCoord, ol.TileState.IDLE);
- /**
- * @private
- * @type {boolean}
- */
- this.renderEdges_ = opt_renderEdges !== undefined ? opt_renderEdges : false;
- /**
- * @private
- * @type {number}
- */
- this.pixelRatio_ = pixelRatio;
- /**
- * @private
- * @type {number}
- */
- this.gutter_ = gutter;
- /**
- * @private
- * @type {HTMLCanvasElement}
- */
- this.canvas_ = null;
- /**
- * @private
- * @type {ol.tilegrid.TileGrid}
- */
- this.sourceTileGrid_ = sourceTileGrid;
- /**
- * @private
- * @type {ol.tilegrid.TileGrid}
- */
- this.targetTileGrid_ = targetTileGrid;
- /**
- * @private
- * @type {ol.TileCoord}
- */
- this.wrappedTileCoord_ = wrappedTileCoord ? wrappedTileCoord : tileCoord;
- /**
- * @private
- * @type {!Array.<ol.Tile>}
- */
- this.sourceTiles_ = [];
- /**
- * @private
- * @type {Array.<ol.EventsKey>}
- */
- this.sourcesListenerKeys_ = null;
- /**
- * @private
- * @type {number}
- */
- this.sourceZ_ = 0;
- var targetExtent = targetTileGrid.getTileCoordExtent(this.wrappedTileCoord_);
- var maxTargetExtent = this.targetTileGrid_.getExtent();
- var maxSourceExtent = this.sourceTileGrid_.getExtent();
- var limitedTargetExtent = maxTargetExtent ?
- ol.extent.getIntersection(targetExtent, maxTargetExtent) : targetExtent;
- if (ol.extent.getArea(limitedTargetExtent) === 0) {
- // Tile is completely outside range -> EMPTY
- // TODO: is it actually correct that the source even creates the tile ?
- this.state = ol.TileState.EMPTY;
- return;
- }
- var sourceProjExtent = sourceProj.getExtent();
- if (sourceProjExtent) {
- if (!maxSourceExtent) {
- maxSourceExtent = sourceProjExtent;
- } else {
- maxSourceExtent = ol.extent.getIntersection(
- maxSourceExtent, sourceProjExtent);
- }
- }
- var targetResolution = targetTileGrid.getResolution(
- this.wrappedTileCoord_[0]);
- var targetCenter = ol.extent.getCenter(limitedTargetExtent);
- var sourceResolution = ol.reproj.calculateSourceResolution(
- sourceProj, targetProj, targetCenter, targetResolution);
- if (!isFinite(sourceResolution) || sourceResolution <= 0) {
- // invalid sourceResolution -> EMPTY
- // probably edges of the projections when no extent is defined
- this.state = ol.TileState.EMPTY;
- return;
- }
- var errorThresholdInPixels = opt_errorThreshold !== undefined ?
- opt_errorThreshold : ol.DEFAULT_RASTER_REPROJECTION_ERROR_THRESHOLD;
- /**
- * @private
- * @type {!ol.reproj.Triangulation}
- */
- this.triangulation_ = new ol.reproj.Triangulation(
- sourceProj, targetProj, limitedTargetExtent, maxSourceExtent,
- sourceResolution * errorThresholdInPixels);
- if (this.triangulation_.getTriangles().length === 0) {
- // no valid triangles -> EMPTY
- this.state = ol.TileState.EMPTY;
- return;
- }
- this.sourceZ_ = sourceTileGrid.getZForResolution(sourceResolution);
- var sourceExtent = this.triangulation_.calculateSourceExtent();
- if (maxSourceExtent) {
- if (sourceProj.canWrapX()) {
- sourceExtent[1] = ol.math.clamp(
- sourceExtent[1], maxSourceExtent[1], maxSourceExtent[3]);
- sourceExtent[3] = ol.math.clamp(
- sourceExtent[3], maxSourceExtent[1], maxSourceExtent[3]);
- } else {
- sourceExtent = ol.extent.getIntersection(sourceExtent, maxSourceExtent);
- }
- }
- if (!ol.extent.getArea(sourceExtent)) {
- this.state = ol.TileState.EMPTY;
- } else {
- var sourceRange = sourceTileGrid.getTileRangeForExtentAndZ(
- sourceExtent, this.sourceZ_);
- for (var srcX = sourceRange.minX; srcX <= sourceRange.maxX; srcX++) {
- for (var srcY = sourceRange.minY; srcY <= sourceRange.maxY; srcY++) {
- var tile = getTileFunction(this.sourceZ_, srcX, srcY, pixelRatio);
- if (tile) {
- this.sourceTiles_.push(tile);
- }
- }
- }
- if (this.sourceTiles_.length === 0) {
- this.state = ol.TileState.EMPTY;
- }
- }
- };
- ol.inherits(ol.reproj.Tile, ol.Tile);
- /**
- * @inheritDoc
- */
- ol.reproj.Tile.prototype.disposeInternal = function() {
- if (this.state == ol.TileState.LOADING) {
- this.unlistenSources_();
- }
- ol.Tile.prototype.disposeInternal.call(this);
- };
- /**
- * Get the HTML Canvas element for this tile.
- * @return {HTMLCanvasElement} Canvas.
- */
- ol.reproj.Tile.prototype.getImage = function() {
- return this.canvas_;
- };
- /**
- * @private
- */
- ol.reproj.Tile.prototype.reproject_ = function() {
- var sources = [];
- this.sourceTiles_.forEach(function(tile, i, arr) {
- if (tile && tile.getState() == ol.TileState.LOADED) {
- sources.push({
- extent: this.sourceTileGrid_.getTileCoordExtent(tile.tileCoord),
- image: tile.getImage()
- });
- }
- }, this);
- this.sourceTiles_.length = 0;
- if (sources.length === 0) {
- this.state = ol.TileState.ERROR;
- } else {
- var z = this.wrappedTileCoord_[0];
- var size = this.targetTileGrid_.getTileSize(z);
- var width = typeof size === 'number' ? size : size[0];
- var height = typeof size === 'number' ? size : size[1];
- var targetResolution = this.targetTileGrid_.getResolution(z);
- var sourceResolution = this.sourceTileGrid_.getResolution(this.sourceZ_);
- var targetExtent = this.targetTileGrid_.getTileCoordExtent(
- this.wrappedTileCoord_);
- this.canvas_ = ol.reproj.render(width, height, this.pixelRatio_,
- sourceResolution, this.sourceTileGrid_.getExtent(),
- targetResolution, targetExtent, this.triangulation_, sources,
- this.gutter_, this.renderEdges_);
- this.state = ol.TileState.LOADED;
- }
- this.changed();
- };
- /**
- * @inheritDoc
- */
- ol.reproj.Tile.prototype.load = function() {
- if (this.state == ol.TileState.IDLE) {
- this.state = ol.TileState.LOADING;
- this.changed();
- var leftToLoad = 0;
- this.sourcesListenerKeys_ = [];
- this.sourceTiles_.forEach(function(tile, i, arr) {
- var state = tile.getState();
- if (state == ol.TileState.IDLE || state == ol.TileState.LOADING) {
- leftToLoad++;
- var sourceListenKey;
- sourceListenKey = ol.events.listen(tile, ol.events.EventType.CHANGE,
- function(e) {
- var state = tile.getState();
- if (state == ol.TileState.LOADED ||
- state == ol.TileState.ERROR ||
- state == ol.TileState.EMPTY) {
- ol.events.unlistenByKey(sourceListenKey);
- leftToLoad--;
- if (leftToLoad === 0) {
- this.unlistenSources_();
- this.reproject_();
- }
- }
- }, this);
- this.sourcesListenerKeys_.push(sourceListenKey);
- }
- }, this);
- this.sourceTiles_.forEach(function(tile, i, arr) {
- var state = tile.getState();
- if (state == ol.TileState.IDLE) {
- tile.load();
- }
- });
- if (leftToLoad === 0) {
- setTimeout(this.reproject_.bind(this), 0);
- }
- }
- };
- /**
- * @private
- */
- ol.reproj.Tile.prototype.unlistenSources_ = function() {
- this.sourcesListenerKeys_.forEach(ol.events.unlistenByKey);
- this.sourcesListenerKeys_ = null;
- };
- goog.provide('ol.TileUrlFunction');
- goog.require('ol.asserts');
- goog.require('ol.math');
- goog.require('ol.tilecoord');
- /**
- * @param {string} template Template.
- * @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
- * @return {ol.TileUrlFunctionType} Tile URL function.
- */
- ol.TileUrlFunction.createFromTemplate = function(template, tileGrid) {
- var zRegEx = /\{z\}/g;
- var xRegEx = /\{x\}/g;
- var yRegEx = /\{y\}/g;
- var dashYRegEx = /\{-y\}/g;
- return (
- /**
- * @param {ol.TileCoord} tileCoord Tile Coordinate.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.proj.Projection} projection Projection.
- * @return {string|undefined} Tile URL.
- */
- function(tileCoord, pixelRatio, projection) {
- if (!tileCoord) {
- return undefined;
- } else {
- return template.replace(zRegEx, tileCoord[0].toString())
- .replace(xRegEx, tileCoord[1].toString())
- .replace(yRegEx, function() {
- var y = -tileCoord[2] - 1;
- return y.toString();
- })
- .replace(dashYRegEx, function() {
- var z = tileCoord[0];
- var range = tileGrid.getFullTileRange(z);
- ol.asserts.assert(range, 55); // The {-y} placeholder requires a tile grid with extent
- var y = range.getHeight() + tileCoord[2];
- return y.toString();
- });
- }
- });
- };
- /**
- * @param {Array.<string>} templates Templates.
- * @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
- * @return {ol.TileUrlFunctionType} Tile URL function.
- */
- ol.TileUrlFunction.createFromTemplates = function(templates, tileGrid) {
- var len = templates.length;
- var tileUrlFunctions = new Array(len);
- for (var i = 0; i < len; ++i) {
- tileUrlFunctions[i] = ol.TileUrlFunction.createFromTemplate(
- templates[i], tileGrid);
- }
- return ol.TileUrlFunction.createFromTileUrlFunctions(tileUrlFunctions);
- };
- /**
- * @param {Array.<ol.TileUrlFunctionType>} tileUrlFunctions Tile URL Functions.
- * @return {ol.TileUrlFunctionType} Tile URL function.
- */
- ol.TileUrlFunction.createFromTileUrlFunctions = function(tileUrlFunctions) {
- if (tileUrlFunctions.length === 1) {
- return tileUrlFunctions[0];
- }
- return (
- /**
- * @param {ol.TileCoord} tileCoord Tile Coordinate.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.proj.Projection} projection Projection.
- * @return {string|undefined} Tile URL.
- */
- function(tileCoord, pixelRatio, projection) {
- if (!tileCoord) {
- return undefined;
- } else {
- var h = ol.tilecoord.hash(tileCoord);
- var index = ol.math.modulo(h, tileUrlFunctions.length);
- return tileUrlFunctions[index](tileCoord, pixelRatio, projection);
- }
- });
- };
- /**
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.proj.Projection} projection Projection.
- * @return {string|undefined} Tile URL.
- */
- ol.TileUrlFunction.nullTileUrlFunction = function(tileCoord, pixelRatio, projection) {
- return undefined;
- };
- /**
- * @param {string} url URL.
- * @return {Array.<string>} Array of urls.
- */
- ol.TileUrlFunction.expandUrl = function(url) {
- var urls = [];
- var match = /\{([a-z])-([a-z])\}/.exec(url);
- if (match) {
- // char range
- var startCharCode = match[1].charCodeAt(0);
- var stopCharCode = match[2].charCodeAt(0);
- var charCode;
- for (charCode = startCharCode; charCode <= stopCharCode; ++charCode) {
- urls.push(url.replace(match[0], String.fromCharCode(charCode)));
- }
- return urls;
- }
- match = match = /\{(\d+)-(\d+)\}/.exec(url);
- if (match) {
- // number range
- var stop = parseInt(match[2], 10);
- for (var i = parseInt(match[1], 10); i <= stop; i++) {
- urls.push(url.replace(match[0], i.toString()));
- }
- return urls;
- }
- urls.push(url);
- return urls;
- };
- goog.provide('ol.TileCache');
- goog.require('ol');
- goog.require('ol.structs.LRUCache');
- goog.require('ol.tilecoord');
- /**
- * @constructor
- * @extends {ol.structs.LRUCache.<ol.Tile>}
- * @param {number=} opt_highWaterMark High water mark.
- * @struct
- */
- ol.TileCache = function(opt_highWaterMark) {
- ol.structs.LRUCache.call(this, opt_highWaterMark);
- };
- ol.inherits(ol.TileCache, ol.structs.LRUCache);
- /**
- * @param {Object.<string, ol.TileRange>} usedTiles Used tiles.
- */
- ol.TileCache.prototype.expireCache = function(usedTiles) {
- var tile, zKey;
- while (this.canExpireCache()) {
- tile = this.peekLast();
- zKey = tile.tileCoord[0].toString();
- if (zKey in usedTiles && usedTiles[zKey].contains(tile.tileCoord)) {
- break;
- } else {
- this.pop().dispose();
- }
- }
- };
- /**
- * Prune all tiles from the cache that don't have the same z as the newest tile.
- */
- ol.TileCache.prototype.pruneExceptNewestZ = function() {
- if (this.getCount() === 0) {
- return;
- }
- var key = this.peekFirstKey();
- var tileCoord = ol.tilecoord.fromKey(key);
- var z = tileCoord[0];
- this.forEach(function(tile) {
- if (tile.tileCoord[0] !== z) {
- this.remove(ol.tilecoord.getKey(tile.tileCoord));
- tile.dispose();
- }
- }, this);
- };
- goog.provide('ol.source.Tile');
- goog.require('ol');
- goog.require('ol.TileCache');
- goog.require('ol.TileState');
- goog.require('ol.events.Event');
- goog.require('ol.proj');
- goog.require('ol.size');
- goog.require('ol.source.Source');
- goog.require('ol.tilecoord');
- goog.require('ol.tilegrid');
- /**
- * @classdesc
- * Abstract base class; normally only used for creating subclasses and not
- * instantiated in apps.
- * Base class for sources providing images divided into a tile grid.
- *
- * @constructor
- * @abstract
- * @extends {ol.source.Source}
- * @param {ol.SourceTileOptions} options Tile source options.
- * @api
- */
- ol.source.Tile = function(options) {
- ol.source.Source.call(this, {
- attributions: options.attributions,
- extent: options.extent,
- logo: options.logo,
- projection: options.projection,
- state: options.state,
- wrapX: options.wrapX
- });
- /**
- * @private
- * @type {boolean}
- */
- this.opaque_ = options.opaque !== undefined ? options.opaque : false;
- /**
- * @private
- * @type {number}
- */
- this.tilePixelRatio_ = options.tilePixelRatio !== undefined ?
- options.tilePixelRatio : 1;
- /**
- * @protected
- * @type {ol.tilegrid.TileGrid}
- */
- this.tileGrid = options.tileGrid !== undefined ? options.tileGrid : null;
- /**
- * @protected
- * @type {ol.TileCache}
- */
- this.tileCache = new ol.TileCache(options.cacheSize);
- /**
- * @protected
- * @type {ol.Size}
- */
- this.tmpSize = [0, 0];
- /**
- * @private
- * @type {string}
- */
- this.key_ = '';
- /**
- * @protected
- * @type {olx.TileOptions}
- */
- this.tileOptions = {transition: options.transition};
- };
- ol.inherits(ol.source.Tile, ol.source.Source);
- /**
- * @return {boolean} Can expire cache.
- */
- ol.source.Tile.prototype.canExpireCache = function() {
- return this.tileCache.canExpireCache();
- };
- /**
- * @param {ol.proj.Projection} projection Projection.
- * @param {Object.<string, ol.TileRange>} usedTiles Used tiles.
- */
- ol.source.Tile.prototype.expireCache = function(projection, usedTiles) {
- var tileCache = this.getTileCacheForProjection(projection);
- if (tileCache) {
- tileCache.expireCache(usedTiles);
- }
- };
- /**
- * @param {ol.proj.Projection} projection Projection.
- * @param {number} z Zoom level.
- * @param {ol.TileRange} tileRange Tile range.
- * @param {function(ol.Tile):(boolean|undefined)} callback Called with each
- * loaded tile. If the callback returns `false`, the tile will not be
- * considered loaded.
- * @return {boolean} The tile range is fully covered with loaded tiles.
- */
- ol.source.Tile.prototype.forEachLoadedTile = function(projection, z, tileRange, callback) {
- var tileCache = this.getTileCacheForProjection(projection);
- if (!tileCache) {
- return false;
- }
- var covered = true;
- var tile, tileCoordKey, loaded;
- for (var x = tileRange.minX; x <= tileRange.maxX; ++x) {
- for (var y = tileRange.minY; y <= tileRange.maxY; ++y) {
- tileCoordKey = ol.tilecoord.getKeyZXY(z, x, y);
- loaded = false;
- if (tileCache.containsKey(tileCoordKey)) {
- tile = /** @type {!ol.Tile} */ (tileCache.get(tileCoordKey));
- loaded = tile.getState() === ol.TileState.LOADED;
- if (loaded) {
- loaded = (callback(tile) !== false);
- }
- }
- if (!loaded) {
- covered = false;
- }
- }
- }
- return covered;
- };
- /**
- * @param {ol.proj.Projection} projection Projection.
- * @return {number} Gutter.
- */
- ol.source.Tile.prototype.getGutter = function(projection) {
- return 0;
- };
- /**
- * Return the key to be used for all tiles in the source.
- * @return {string} The key for all tiles.
- * @protected
- */
- ol.source.Tile.prototype.getKey = function() {
- return this.key_;
- };
- /**
- * Set the value to be used as the key for all tiles in the source.
- * @param {string} key The key for tiles.
- * @protected
- */
- ol.source.Tile.prototype.setKey = function(key) {
- if (this.key_ !== key) {
- this.key_ = key;
- this.changed();
- }
- };
- /**
- * @param {ol.proj.Projection} projection Projection.
- * @return {boolean} Opaque.
- */
- ol.source.Tile.prototype.getOpaque = function(projection) {
- return this.opaque_;
- };
- /**
- * @inheritDoc
- */
- ol.source.Tile.prototype.getResolutions = function() {
- return this.tileGrid.getResolutions();
- };
- /**
- * @abstract
- * @param {number} z Tile coordinate z.
- * @param {number} x Tile coordinate x.
- * @param {number} y Tile coordinate y.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.proj.Projection} projection Projection.
- * @return {!ol.Tile} Tile.
- */
- ol.source.Tile.prototype.getTile = function(z, x, y, pixelRatio, projection) {};
- /**
- * Return the tile grid of the tile source.
- * @return {ol.tilegrid.TileGrid} Tile grid.
- * @api
- */
- ol.source.Tile.prototype.getTileGrid = function() {
- return this.tileGrid;
- };
- /**
- * @param {ol.proj.Projection} projection Projection.
- * @return {!ol.tilegrid.TileGrid} Tile grid.
- */
- ol.source.Tile.prototype.getTileGridForProjection = function(projection) {
- if (!this.tileGrid) {
- return ol.tilegrid.getForProjection(projection);
- } else {
- return this.tileGrid;
- }
- };
- /**
- * @param {ol.proj.Projection} projection Projection.
- * @return {ol.TileCache} Tile cache.
- * @protected
- */
- ol.source.Tile.prototype.getTileCacheForProjection = function(projection) {
- var thisProj = this.getProjection();
- if (thisProj && !ol.proj.equivalent(thisProj, projection)) {
- return null;
- } else {
- return this.tileCache;
- }
- };
- /**
- * Get the tile pixel ratio for this source. Subclasses may override this
- * method, which is meant to return a supported pixel ratio that matches the
- * provided `pixelRatio` as close as possible.
- * @param {number} pixelRatio Pixel ratio.
- * @return {number} Tile pixel ratio.
- */
- ol.source.Tile.prototype.getTilePixelRatio = function(pixelRatio) {
- return this.tilePixelRatio_;
- };
- /**
- * @param {number} z Z.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.proj.Projection} projection Projection.
- * @return {ol.Size} Tile size.
- */
- ol.source.Tile.prototype.getTilePixelSize = function(z, pixelRatio, projection) {
- var tileGrid = this.getTileGridForProjection(projection);
- var tilePixelRatio = this.getTilePixelRatio(pixelRatio);
- var tileSize = ol.size.toSize(tileGrid.getTileSize(z), this.tmpSize);
- if (tilePixelRatio == 1) {
- return tileSize;
- } else {
- return ol.size.scale(tileSize, tilePixelRatio, this.tmpSize);
- }
- };
- /**
- * Returns a tile coordinate wrapped around the x-axis. When the tile coordinate
- * is outside the resolution and extent range of the tile grid, `null` will be
- * returned.
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {ol.proj.Projection=} opt_projection Projection.
- * @return {ol.TileCoord} Tile coordinate to be passed to the tileUrlFunction or
- * null if no tile URL should be created for the passed `tileCoord`.
- */
- ol.source.Tile.prototype.getTileCoordForTileUrlFunction = function(tileCoord, opt_projection) {
- var projection = opt_projection !== undefined ?
- opt_projection : this.getProjection();
- var tileGrid = this.getTileGridForProjection(projection);
- if (this.getWrapX() && projection.isGlobal()) {
- tileCoord = ol.tilegrid.wrapX(tileGrid, tileCoord, projection);
- }
- return ol.tilecoord.withinExtentAndZ(tileCoord, tileGrid) ? tileCoord : null;
- };
- /**
- * @inheritDoc
- */
- ol.source.Tile.prototype.refresh = function() {
- this.tileCache.clear();
- this.changed();
- };
- /**
- * Marks a tile coord as being used, without triggering a load.
- * @param {number} z Tile coordinate z.
- * @param {number} x Tile coordinate x.
- * @param {number} y Tile coordinate y.
- * @param {ol.proj.Projection} projection Projection.
- */
- ol.source.Tile.prototype.useTile = ol.nullFunction;
- /**
- * @classdesc
- * Events emitted by {@link ol.source.Tile} instances are instances of this
- * type.
- *
- * @constructor
- * @extends {ol.events.Event}
- * @implements {oli.source.Tile.Event}
- * @param {string} type Type.
- * @param {ol.Tile} tile The tile.
- */
- ol.source.Tile.Event = function(type, tile) {
- ol.events.Event.call(this, type);
- /**
- * The tile related to the event.
- * @type {ol.Tile}
- * @api
- */
- this.tile = tile;
- };
- ol.inherits(ol.source.Tile.Event, ol.events.Event);
- goog.provide('ol.source.TileEventType');
- /**
- * @enum {string}
- */
- ol.source.TileEventType = {
- /**
- * Triggered when a tile starts loading.
- * @event ol.source.Tile.Event#tileloadstart
- * @api
- */
- TILELOADSTART: 'tileloadstart',
- /**
- * Triggered when a tile finishes loading, either when its data is loaded,
- * or when loading was aborted because the tile is no longer needed.
- * @event ol.source.Tile.Event#tileloadend
- * @api
- */
- TILELOADEND: 'tileloadend',
- /**
- * Triggered if tile loading results in an error.
- * @event ol.source.Tile.Event#tileloaderror
- * @api
- */
- TILELOADERROR: 'tileloaderror'
- };
- goog.provide('ol.source.UrlTile');
- goog.require('ol');
- goog.require('ol.TileState');
- goog.require('ol.TileUrlFunction');
- goog.require('ol.source.Tile');
- goog.require('ol.source.TileEventType');
- goog.require('ol.tilecoord');
- /**
- * @classdesc
- * Base class for sources providing tiles divided into a tile grid over http.
- *
- * @constructor
- * @abstract
- * @fires ol.source.Tile.Event
- * @extends {ol.source.Tile}
- * @param {ol.SourceUrlTileOptions} options Image tile options.
- */
- ol.source.UrlTile = function(options) {
- ol.source.Tile.call(this, {
- attributions: options.attributions,
- cacheSize: options.cacheSize,
- extent: options.extent,
- logo: options.logo,
- opaque: options.opaque,
- projection: options.projection,
- state: options.state,
- tileGrid: options.tileGrid,
- tilePixelRatio: options.tilePixelRatio,
- wrapX: options.wrapX,
- transition: options.transition
- });
- /**
- * @protected
- * @type {ol.TileLoadFunctionType}
- */
- this.tileLoadFunction = options.tileLoadFunction;
- /**
- * @protected
- * @type {ol.TileUrlFunctionType}
- */
- this.tileUrlFunction = this.fixedTileUrlFunction ?
- this.fixedTileUrlFunction.bind(this) :
- ol.TileUrlFunction.nullTileUrlFunction;
- /**
- * @protected
- * @type {!Array.<string>|null}
- */
- this.urls = null;
- if (options.urls) {
- this.setUrls(options.urls);
- } else if (options.url) {
- this.setUrl(options.url);
- }
- if (options.tileUrlFunction) {
- this.setTileUrlFunction(options.tileUrlFunction);
- }
- /**
- * @private
- * @type {Object.<number, boolean>}
- */
- this.tileLoadingKeys_ = {};
- };
- ol.inherits(ol.source.UrlTile, ol.source.Tile);
- /**
- * @type {ol.TileUrlFunctionType|undefined}
- * @protected
- */
- ol.source.UrlTile.prototype.fixedTileUrlFunction;
- /**
- * Return the tile load function of the source.
- * @return {ol.TileLoadFunctionType} TileLoadFunction
- * @api
- */
- ol.source.UrlTile.prototype.getTileLoadFunction = function() {
- return this.tileLoadFunction;
- };
- /**
- * Return the tile URL function of the source.
- * @return {ol.TileUrlFunctionType} TileUrlFunction
- * @api
- */
- ol.source.UrlTile.prototype.getTileUrlFunction = function() {
- return this.tileUrlFunction;
- };
- /**
- * Return the URLs used for this source.
- * When a tileUrlFunction is used instead of url or urls,
- * null will be returned.
- * @return {!Array.<string>|null} URLs.
- * @api
- */
- ol.source.UrlTile.prototype.getUrls = function() {
- return this.urls;
- };
- /**
- * Handle tile change events.
- * @param {ol.events.Event} event Event.
- * @protected
- */
- ol.source.UrlTile.prototype.handleTileChange = function(event) {
- var tile = /** @type {ol.Tile} */ (event.target);
- var uid = ol.getUid(tile);
- var tileState = tile.getState();
- var type;
- if (tileState == ol.TileState.LOADING) {
- this.tileLoadingKeys_[uid] = true;
- type = ol.source.TileEventType.TILELOADSTART;
- } else if (uid in this.tileLoadingKeys_) {
- delete this.tileLoadingKeys_[uid];
- type = tileState == ol.TileState.ERROR ? ol.source.TileEventType.TILELOADERROR :
- (tileState == ol.TileState.LOADED || tileState == ol.TileState.ABORT) ?
- ol.source.TileEventType.TILELOADEND : undefined;
- }
- if (type != undefined) {
- this.dispatchEvent(new ol.source.Tile.Event(type, tile));
- }
- };
- /**
- * Set the tile load function of the source.
- * @param {ol.TileLoadFunctionType} tileLoadFunction Tile load function.
- * @api
- */
- ol.source.UrlTile.prototype.setTileLoadFunction = function(tileLoadFunction) {
- this.tileCache.clear();
- this.tileLoadFunction = tileLoadFunction;
- this.changed();
- };
- /**
- * Set the tile URL function of the source.
- * @param {ol.TileUrlFunctionType} tileUrlFunction Tile URL function.
- * @param {string=} opt_key Optional new tile key for the source.
- * @api
- */
- ol.source.UrlTile.prototype.setTileUrlFunction = function(tileUrlFunction, opt_key) {
- this.tileUrlFunction = tileUrlFunction;
- this.tileCache.pruneExceptNewestZ();
- if (typeof opt_key !== 'undefined') {
- this.setKey(opt_key);
- } else {
- this.changed();
- }
- };
- /**
- * Set the URL to use for requests.
- * @param {string} url URL.
- * @api
- */
- ol.source.UrlTile.prototype.setUrl = function(url) {
- var urls = this.urls = ol.TileUrlFunction.expandUrl(url);
- this.setTileUrlFunction(this.fixedTileUrlFunction ?
- this.fixedTileUrlFunction.bind(this) :
- ol.TileUrlFunction.createFromTemplates(urls, this.tileGrid), url);
- };
- /**
- * Set the URLs to use for requests.
- * @param {Array.<string>} urls URLs.
- * @api
- */
- ol.source.UrlTile.prototype.setUrls = function(urls) {
- this.urls = urls;
- var key = urls.join('\n');
- this.setTileUrlFunction(this.fixedTileUrlFunction ?
- this.fixedTileUrlFunction.bind(this) :
- ol.TileUrlFunction.createFromTemplates(urls, this.tileGrid), key);
- };
- /**
- * @inheritDoc
- */
- ol.source.UrlTile.prototype.useTile = function(z, x, y) {
- var tileCoordKey = ol.tilecoord.getKeyZXY(z, x, y);
- if (this.tileCache.containsKey(tileCoordKey)) {
- this.tileCache.get(tileCoordKey);
- }
- };
- goog.provide('ol.source.TileImage');
- goog.require('ol');
- goog.require('ol.ImageTile');
- goog.require('ol.TileCache');
- goog.require('ol.TileState');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.proj');
- goog.require('ol.reproj.Tile');
- goog.require('ol.source.UrlTile');
- goog.require('ol.tilecoord');
- goog.require('ol.tilegrid');
- /**
- * @classdesc
- * Base class for sources providing images divided into a tile grid.
- *
- * @constructor
- * @fires ol.source.Tile.Event
- * @extends {ol.source.UrlTile}
- * @param {olx.source.TileImageOptions} options Image tile options.
- * @api
- */
- ol.source.TileImage = function(options) {
- ol.source.UrlTile.call(this, {
- attributions: options.attributions,
- cacheSize: options.cacheSize,
- extent: options.extent,
- logo: options.logo,
- opaque: options.opaque,
- projection: options.projection,
- state: options.state,
- tileGrid: options.tileGrid,
- tileLoadFunction: options.tileLoadFunction ?
- options.tileLoadFunction : ol.source.TileImage.defaultTileLoadFunction,
- tilePixelRatio: options.tilePixelRatio,
- tileUrlFunction: options.tileUrlFunction,
- url: options.url,
- urls: options.urls,
- wrapX: options.wrapX,
- transition: options.transition
- });
- /**
- * @protected
- * @type {?string}
- */
- this.crossOrigin =
- options.crossOrigin !== undefined ? options.crossOrigin : null;
- /**
- * @protected
- * @type {function(new: ol.ImageTile, ol.TileCoord, ol.TileState, string,
- * ?string, ol.TileLoadFunctionType, olx.TileOptions=)}
- */
- this.tileClass = options.tileClass !== undefined ?
- options.tileClass : ol.ImageTile;
- /**
- * @protected
- * @type {Object.<string, ol.TileCache>}
- */
- this.tileCacheForProjection = {};
- /**
- * @protected
- * @type {Object.<string, ol.tilegrid.TileGrid>}
- */
- this.tileGridForProjection = {};
- /**
- * @private
- * @type {number|undefined}
- */
- this.reprojectionErrorThreshold_ = options.reprojectionErrorThreshold;
- /**
- * @private
- * @type {boolean}
- */
- this.renderReprojectionEdges_ = false;
- };
- ol.inherits(ol.source.TileImage, ol.source.UrlTile);
- /**
- * @inheritDoc
- */
- ol.source.TileImage.prototype.canExpireCache = function() {
- if (!ol.ENABLE_RASTER_REPROJECTION) {
- return ol.source.UrlTile.prototype.canExpireCache.call(this);
- }
- if (this.tileCache.canExpireCache()) {
- return true;
- } else {
- for (var key in this.tileCacheForProjection) {
- if (this.tileCacheForProjection[key].canExpireCache()) {
- return true;
- }
- }
- }
- return false;
- };
- /**
- * @inheritDoc
- */
- ol.source.TileImage.prototype.expireCache = function(projection, usedTiles) {
- if (!ol.ENABLE_RASTER_REPROJECTION) {
- ol.source.UrlTile.prototype.expireCache.call(this, projection, usedTiles);
- return;
- }
- var usedTileCache = this.getTileCacheForProjection(projection);
- this.tileCache.expireCache(this.tileCache == usedTileCache ? usedTiles : {});
- for (var id in this.tileCacheForProjection) {
- var tileCache = this.tileCacheForProjection[id];
- tileCache.expireCache(tileCache == usedTileCache ? usedTiles : {});
- }
- };
- /**
- * @inheritDoc
- */
- ol.source.TileImage.prototype.getGutter = function(projection) {
- if (ol.ENABLE_RASTER_REPROJECTION &&
- this.getProjection() && projection &&
- !ol.proj.equivalent(this.getProjection(), projection)) {
- return 0;
- } else {
- return this.getGutterInternal();
- }
- };
- /**
- * @protected
- * @return {number} Gutter.
- */
- ol.source.TileImage.prototype.getGutterInternal = function() {
- return 0;
- };
- /**
- * @inheritDoc
- */
- ol.source.TileImage.prototype.getOpaque = function(projection) {
- if (ol.ENABLE_RASTER_REPROJECTION &&
- this.getProjection() && projection &&
- !ol.proj.equivalent(this.getProjection(), projection)) {
- return false;
- } else {
- return ol.source.UrlTile.prototype.getOpaque.call(this, projection);
- }
- };
- /**
- * @inheritDoc
- */
- ol.source.TileImage.prototype.getTileGridForProjection = function(projection) {
- if (!ol.ENABLE_RASTER_REPROJECTION) {
- return ol.source.UrlTile.prototype.getTileGridForProjection.call(this, projection);
- }
- var thisProj = this.getProjection();
- if (this.tileGrid &&
- (!thisProj || ol.proj.equivalent(thisProj, projection))) {
- return this.tileGrid;
- } else {
- var projKey = ol.getUid(projection).toString();
- if (!(projKey in this.tileGridForProjection)) {
- this.tileGridForProjection[projKey] =
- ol.tilegrid.getForProjection(projection);
- }
- return /** @type {!ol.tilegrid.TileGrid} */ (this.tileGridForProjection[projKey]);
- }
- };
- /**
- * @inheritDoc
- */
- ol.source.TileImage.prototype.getTileCacheForProjection = function(projection) {
- if (!ol.ENABLE_RASTER_REPROJECTION) {
- return ol.source.UrlTile.prototype.getTileCacheForProjection.call(this, projection);
- }
- var thisProj = this.getProjection();
- if (!thisProj || ol.proj.equivalent(thisProj, projection)) {
- return this.tileCache;
- } else {
- var projKey = ol.getUid(projection).toString();
- if (!(projKey in this.tileCacheForProjection)) {
- this.tileCacheForProjection[projKey] = new ol.TileCache(this.tileCache.highWaterMark);
- }
- return this.tileCacheForProjection[projKey];
- }
- };
- /**
- * @param {number} z Tile coordinate z.
- * @param {number} x Tile coordinate x.
- * @param {number} y Tile coordinate y.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.proj.Projection} projection Projection.
- * @param {string} key The key set on the tile.
- * @return {!ol.Tile} Tile.
- * @private
- */
- ol.source.TileImage.prototype.createTile_ = function(z, x, y, pixelRatio, projection, key) {
- var tileCoord = [z, x, y];
- var urlTileCoord = this.getTileCoordForTileUrlFunction(
- tileCoord, projection);
- var tileUrl = urlTileCoord ?
- this.tileUrlFunction(urlTileCoord, pixelRatio, projection) : undefined;
- var tile = new this.tileClass(
- tileCoord,
- tileUrl !== undefined ? ol.TileState.IDLE : ol.TileState.EMPTY,
- tileUrl !== undefined ? tileUrl : '',
- this.crossOrigin,
- this.tileLoadFunction,
- this.tileOptions);
- tile.key = key;
- ol.events.listen(tile, ol.events.EventType.CHANGE,
- this.handleTileChange, this);
- return tile;
- };
- /**
- * @inheritDoc
- */
- ol.source.TileImage.prototype.getTile = function(z, x, y, pixelRatio, projection) {
- var sourceProjection = /** @type {!ol.proj.Projection} */ (this.getProjection());
- if (!ol.ENABLE_RASTER_REPROJECTION ||
- !sourceProjection || !projection ||
- ol.proj.equivalent(sourceProjection, projection)) {
- return this.getTileInternal(z, x, y, pixelRatio, sourceProjection || projection);
- } else {
- var cache = this.getTileCacheForProjection(projection);
- var tileCoord = [z, x, y];
- var tile;
- var tileCoordKey = ol.tilecoord.getKey(tileCoord);
- if (cache.containsKey(tileCoordKey)) {
- tile = /** @type {!ol.Tile} */ (cache.get(tileCoordKey));
- }
- var key = this.getKey();
- if (tile && tile.key == key) {
- return tile;
- } else {
- var sourceTileGrid = this.getTileGridForProjection(sourceProjection);
- var targetTileGrid = this.getTileGridForProjection(projection);
- var wrappedTileCoord =
- this.getTileCoordForTileUrlFunction(tileCoord, projection);
- var newTile = new ol.reproj.Tile(
- sourceProjection, sourceTileGrid,
- projection, targetTileGrid,
- tileCoord, wrappedTileCoord, this.getTilePixelRatio(pixelRatio),
- this.getGutterInternal(),
- function(z, x, y, pixelRatio) {
- return this.getTileInternal(z, x, y, pixelRatio, sourceProjection);
- }.bind(this), this.reprojectionErrorThreshold_,
- this.renderReprojectionEdges_);
- newTile.key = key;
- if (tile) {
- newTile.interimTile = tile;
- newTile.refreshInterimChain();
- cache.replace(tileCoordKey, newTile);
- } else {
- cache.set(tileCoordKey, newTile);
- }
- return newTile;
- }
- }
- };
- /**
- * @param {number} z Tile coordinate z.
- * @param {number} x Tile coordinate x.
- * @param {number} y Tile coordinate y.
- * @param {number} pixelRatio Pixel ratio.
- * @param {!ol.proj.Projection} projection Projection.
- * @return {!ol.Tile} Tile.
- * @protected
- */
- ol.source.TileImage.prototype.getTileInternal = function(z, x, y, pixelRatio, projection) {
- var tile = null;
- var tileCoordKey = ol.tilecoord.getKeyZXY(z, x, y);
- var key = this.getKey();
- if (!this.tileCache.containsKey(tileCoordKey)) {
- tile = this.createTile_(z, x, y, pixelRatio, projection, key);
- this.tileCache.set(tileCoordKey, tile);
- } else {
- tile = this.tileCache.get(tileCoordKey);
- if (tile.key != key) {
- // The source's params changed. If the tile has an interim tile and if we
- // can use it then we use it. Otherwise we create a new tile. In both
- // cases we attempt to assign an interim tile to the new tile.
- var interimTile = tile;
- tile = this.createTile_(z, x, y, pixelRatio, projection, key);
- //make the new tile the head of the list,
- if (interimTile.getState() == ol.TileState.IDLE) {
- //the old tile hasn't begun loading yet, and is now outdated, so we can simply discard it
- tile.interimTile = interimTile.interimTile;
- } else {
- tile.interimTile = interimTile;
- }
- tile.refreshInterimChain();
- this.tileCache.replace(tileCoordKey, tile);
- }
- }
- return tile;
- };
- /**
- * Sets whether to render reprojection edges or not (usually for debugging).
- * @param {boolean} render Render the edges.
- * @api
- */
- ol.source.TileImage.prototype.setRenderReprojectionEdges = function(render) {
- if (!ol.ENABLE_RASTER_REPROJECTION ||
- this.renderReprojectionEdges_ == render) {
- return;
- }
- this.renderReprojectionEdges_ = render;
- for (var id in this.tileCacheForProjection) {
- this.tileCacheForProjection[id].clear();
- }
- this.changed();
- };
- /**
- * Sets the tile grid to use when reprojecting the tiles to the given
- * projection instead of the default tile grid for the projection.
- *
- * This can be useful when the default tile grid cannot be created
- * (e.g. projection has no extent defined) or
- * for optimization reasons (custom tile size, resolutions, ...).
- *
- * @param {ol.ProjectionLike} projection Projection.
- * @param {ol.tilegrid.TileGrid} tilegrid Tile grid to use for the projection.
- * @api
- */
- ol.source.TileImage.prototype.setTileGridForProjection = function(projection, tilegrid) {
- if (ol.ENABLE_RASTER_REPROJECTION) {
- var proj = ol.proj.get(projection);
- if (proj) {
- var projKey = ol.getUid(proj).toString();
- if (!(projKey in this.tileGridForProjection)) {
- this.tileGridForProjection[projKey] = tilegrid;
- }
- }
- }
- };
- /**
- * @param {ol.ImageTile} imageTile Image tile.
- * @param {string} src Source.
- */
- ol.source.TileImage.defaultTileLoadFunction = function(imageTile, src) {
- imageTile.getImage().src = src;
- };
- goog.provide('ol.source.BingMaps');
- goog.require('ol');
- goog.require('ol.TileUrlFunction');
- goog.require('ol.extent');
- goog.require('ol.net');
- goog.require('ol.proj');
- goog.require('ol.source.State');
- goog.require('ol.source.TileImage');
- goog.require('ol.tilecoord');
- goog.require('ol.tilegrid');
- /**
- * @classdesc
- * Layer source for Bing Maps tile data.
- *
- * @constructor
- * @extends {ol.source.TileImage}
- * @param {olx.source.BingMapsOptions} options Bing Maps options.
- * @api
- */
- ol.source.BingMaps = function(options) {
- /**
- * @private
- * @type {boolean}
- */
- this.hidpi_ = options.hidpi !== undefined ? options.hidpi : false;
- ol.source.TileImage.call(this, {
- cacheSize: options.cacheSize,
- crossOrigin: 'anonymous',
- opaque: true,
- projection: ol.proj.get('EPSG:3857'),
- reprojectionErrorThreshold: options.reprojectionErrorThreshold,
- state: ol.source.State.LOADING,
- tileLoadFunction: options.tileLoadFunction,
- tilePixelRatio: this.hidpi_ ? 2 : 1,
- wrapX: options.wrapX !== undefined ? options.wrapX : true,
- transition: options.transition
- });
- /**
- * @private
- * @type {string}
- */
- this.culture_ = options.culture !== undefined ? options.culture : 'en-us';
- /**
- * @private
- * @type {number}
- */
- this.maxZoom_ = options.maxZoom !== undefined ? options.maxZoom : -1;
- /**
- * @private
- * @type {string}
- */
- this.apiKey_ = options.key;
- /**
- * @private
- * @type {string}
- */
- this.imagerySet_ = options.imagerySet;
- var url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/' +
- this.imagerySet_ +
- '?uriScheme=https&include=ImageryProviders&key=' + this.apiKey_ +
- '&c=' + this.culture_;
- ol.net.jsonp(url, this.handleImageryMetadataResponse.bind(this), undefined,
- 'jsonp');
- };
- ol.inherits(ol.source.BingMaps, ol.source.TileImage);
- /**
- * The attribution containing a link to the Microsoft® Bing™ Maps Platform APIs’
- * Terms Of Use.
- * @const
- * @type {string}
- * @api
- */
- ol.source.BingMaps.TOS_ATTRIBUTION = '<a class="ol-attribution-bing-tos" ' +
- 'href="https://www.microsoft.com/maps/product/terms.html">' +
- 'Terms of Use</a>';
- /**
- * Get the api key used for this source.
- *
- * @return {string} The api key.
- * @api
- */
- ol.source.BingMaps.prototype.getApiKey = function() {
- return this.apiKey_;
- };
- /**
- * Get the imagery set associated with this source.
- *
- * @return {string} The imagery set.
- * @api
- */
- ol.source.BingMaps.prototype.getImagerySet = function() {
- return this.imagerySet_;
- };
- /**
- * @param {BingMapsImageryMetadataResponse} response Response.
- */
- ol.source.BingMaps.prototype.handleImageryMetadataResponse = function(response) {
- if (response.statusCode != 200 ||
- response.statusDescription != 'OK' ||
- response.authenticationResultCode != 'ValidCredentials' ||
- response.resourceSets.length != 1 ||
- response.resourceSets[0].resources.length != 1) {
- this.setState(ol.source.State.ERROR);
- return;
- }
- var brandLogoUri = response.brandLogoUri;
- if (brandLogoUri.indexOf('https') == -1) {
- brandLogoUri = brandLogoUri.replace('http', 'https');
- }
- //var copyright = response.copyright; // FIXME do we need to display this?
- var resource = response.resourceSets[0].resources[0];
- var maxZoom = this.maxZoom_ == -1 ? resource.zoomMax : this.maxZoom_;
- var sourceProjection = this.getProjection();
- var extent = ol.tilegrid.extentFromProjection(sourceProjection);
- var tileSize = resource.imageWidth == resource.imageHeight ?
- resource.imageWidth : [resource.imageWidth, resource.imageHeight];
- var tileGrid = ol.tilegrid.createXYZ({
- extent: extent,
- minZoom: resource.zoomMin,
- maxZoom: maxZoom,
- tileSize: tileSize / (this.hidpi_ ? 2 : 1)
- });
- this.tileGrid = tileGrid;
- var culture = this.culture_;
- var hidpi = this.hidpi_;
- this.tileUrlFunction = ol.TileUrlFunction.createFromTileUrlFunctions(
- resource.imageUrlSubdomains.map(function(subdomain) {
- var quadKeyTileCoord = [0, 0, 0];
- var imageUrl = resource.imageUrl
- .replace('{subdomain}', subdomain)
- .replace('{culture}', culture);
- return (
- /**
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.proj.Projection} projection Projection.
- * @return {string|undefined} Tile URL.
- */
- function(tileCoord, pixelRatio, projection) {
- if (!tileCoord) {
- return undefined;
- } else {
- ol.tilecoord.createOrUpdate(tileCoord[0], tileCoord[1],
- -tileCoord[2] - 1, quadKeyTileCoord);
- var url = imageUrl;
- if (hidpi) {
- url += '&dpi=d1&device=mobile';
- }
- return url.replace('{quadkey}', ol.tilecoord.quadKey(
- quadKeyTileCoord));
- }
- });
- }));
- if (resource.imageryProviders) {
- var transform = ol.proj.getTransformFromProjections(
- ol.proj.get('EPSG:4326'), this.getProjection());
- this.setAttributions(function(frameState) {
- var attributions = [];
- var zoom = frameState.viewState.zoom;
- resource.imageryProviders.map(function(imageryProvider) {
- var intersects = false;
- var coverageAreas = imageryProvider.coverageAreas;
- for (var i = 0, ii = coverageAreas.length; i < ii; ++i) {
- var coverageArea = coverageAreas[i];
- if (zoom >= coverageArea.zoomMin && zoom <= coverageArea.zoomMax) {
- var bbox = coverageArea.bbox;
- var epsg4326Extent = [bbox[1], bbox[0], bbox[3], bbox[2]];
- var extent = ol.extent.applyTransform(epsg4326Extent, transform);
- if (ol.extent.intersects(extent, frameState.extent)) {
- intersects = true;
- break;
- }
- }
- }
- if (intersects) {
- attributions.push(imageryProvider.attribution);
- }
- });
- attributions.push(ol.source.BingMaps.TOS_ATTRIBUTION);
- return attributions;
- });
- }
- this.setLogo(brandLogoUri);
- this.setState(ol.source.State.READY);
- };
- goog.provide('ol.source.XYZ');
- goog.require('ol');
- goog.require('ol.source.TileImage');
- goog.require('ol.tilegrid');
- /**
- * @classdesc
- * Layer source for tile data with URLs in a set XYZ format that are
- * defined in a URL template. By default, this follows the widely-used
- * Google grid where `x` 0 and `y` 0 are in the top left. Grids like
- * TMS where `x` 0 and `y` 0 are in the bottom left can be used by
- * using the `{-y}` placeholder in the URL template, so long as the
- * source does not have a custom tile grid. In this case,
- * {@link ol.source.TileImage} can be used with a `tileUrlFunction`
- * such as:
- *
- * tileUrlFunction: function(coordinate) {
- * return 'http://mapserver.com/' + coordinate[0] + '/' +
- * coordinate[1] + '/' + coordinate[2] + '.png';
- * }
- *
- *
- * @constructor
- * @extends {ol.source.TileImage}
- * @param {olx.source.XYZOptions=} opt_options XYZ options.
- * @api
- */
- ol.source.XYZ = function(opt_options) {
- var options = opt_options || {};
- var projection = options.projection !== undefined ?
- options.projection : 'EPSG:3857';
- var tileGrid = options.tileGrid !== undefined ? options.tileGrid :
- ol.tilegrid.createXYZ({
- extent: ol.tilegrid.extentFromProjection(projection),
- maxZoom: options.maxZoom,
- minZoom: options.minZoom,
- tileSize: options.tileSize
- });
- ol.source.TileImage.call(this, {
- attributions: options.attributions,
- cacheSize: options.cacheSize,
- crossOrigin: options.crossOrigin,
- logo: options.logo,
- opaque: options.opaque,
- projection: projection,
- reprojectionErrorThreshold: options.reprojectionErrorThreshold,
- tileGrid: tileGrid,
- tileLoadFunction: options.tileLoadFunction,
- tilePixelRatio: options.tilePixelRatio,
- tileUrlFunction: options.tileUrlFunction,
- url: options.url,
- urls: options.urls,
- wrapX: options.wrapX !== undefined ? options.wrapX : true,
- transition: options.transition
- });
- };
- ol.inherits(ol.source.XYZ, ol.source.TileImage);
- goog.provide('ol.source.CartoDB');
- goog.require('ol');
- goog.require('ol.obj');
- goog.require('ol.source.State');
- goog.require('ol.source.XYZ');
- /**
- * @classdesc
- * Layer source for the CartoDB Maps API.
- *
- * @constructor
- * @extends {ol.source.XYZ}
- * @param {olx.source.CartoDBOptions} options CartoDB options.
- * @api
- */
- ol.source.CartoDB = function(options) {
- /**
- * @type {string}
- * @private
- */
- this.account_ = options.account;
- /**
- * @type {string}
- * @private
- */
- this.mapId_ = options.map || '';
- /**
- * @type {!Object}
- * @private
- */
- this.config_ = options.config || {};
- /**
- * @type {!Object.<string, CartoDBLayerInfo>}
- * @private
- */
- this.templateCache_ = {};
- ol.source.XYZ.call(this, {
- attributions: options.attributions,
- cacheSize: options.cacheSize,
- crossOrigin: options.crossOrigin,
- logo: options.logo,
- maxZoom: options.maxZoom !== undefined ? options.maxZoom : 18,
- minZoom: options.minZoom,
- projection: options.projection,
- state: ol.source.State.LOADING,
- wrapX: options.wrapX
- });
- this.initializeMap_();
- };
- ol.inherits(ol.source.CartoDB, ol.source.XYZ);
- /**
- * Returns the current config.
- * @return {!Object} The current configuration.
- * @api
- */
- ol.source.CartoDB.prototype.getConfig = function() {
- return this.config_;
- };
- /**
- * Updates the carto db config.
- * @param {Object} config a key-value lookup. Values will replace current values
- * in the config.
- * @api
- */
- ol.source.CartoDB.prototype.updateConfig = function(config) {
- ol.obj.assign(this.config_, config);
- this.initializeMap_();
- };
- /**
- * Sets the CartoDB config
- * @param {Object} config In the case of anonymous maps, a CartoDB configuration
- * object.
- * If using named maps, a key-value lookup with the template parameters.
- * @api
- */
- ol.source.CartoDB.prototype.setConfig = function(config) {
- this.config_ = config || {};
- this.initializeMap_();
- };
- /**
- * Issue a request to initialize the CartoDB map.
- * @private
- */
- ol.source.CartoDB.prototype.initializeMap_ = function() {
- var paramHash = JSON.stringify(this.config_);
- if (this.templateCache_[paramHash]) {
- this.applyTemplate_(this.templateCache_[paramHash]);
- return;
- }
- var mapUrl = 'https://' + this.account_ + '.carto.com/api/v1/map';
- if (this.mapId_) {
- mapUrl += '/named/' + this.mapId_;
- }
- var client = new XMLHttpRequest();
- client.addEventListener('load', this.handleInitResponse_.bind(this, paramHash));
- client.addEventListener('error', this.handleInitError_.bind(this));
- client.open('POST', mapUrl);
- client.setRequestHeader('Content-type', 'application/json');
- client.send(JSON.stringify(this.config_));
- };
- /**
- * Handle map initialization response.
- * @param {string} paramHash a hash representing the parameter set that was used
- * for the request
- * @param {Event} event Event.
- * @private
- */
- ol.source.CartoDB.prototype.handleInitResponse_ = function(paramHash, event) {
- var client = /** @type {XMLHttpRequest} */ (event.target);
- // status will be 0 for file:// urls
- if (!client.status || client.status >= 200 && client.status < 300) {
- var response;
- try {
- response = /** @type {CartoDBLayerInfo} */(JSON.parse(client.responseText));
- } catch (err) {
- this.setState(ol.source.State.ERROR);
- return;
- }
- this.applyTemplate_(response);
- this.templateCache_[paramHash] = response;
- this.setState(ol.source.State.READY);
- } else {
- this.setState(ol.source.State.ERROR);
- }
- };
- /**
- * @private
- * @param {Event} event Event.
- */
- ol.source.CartoDB.prototype.handleInitError_ = function(event) {
- this.setState(ol.source.State.ERROR);
- };
- /**
- * Apply the new tile urls returned by carto db
- * @param {CartoDBLayerInfo} data Result of carto db call.
- * @private
- */
- ol.source.CartoDB.prototype.applyTemplate_ = function(data) {
- var tilesUrl = 'https://' + data.cdn_url.https + '/' + this.account_ +
- '/api/v1/map/' + data.layergroupid + '/{z}/{x}/{y}.png';
- this.setUrl(tilesUrl);
- };
- // FIXME keep cluster cache by resolution ?
- // FIXME distance not respected because of the centroid
- goog.provide('ol.source.Cluster');
- goog.require('ol');
- goog.require('ol.asserts');
- goog.require('ol.Feature');
- goog.require('ol.coordinate');
- goog.require('ol.events.EventType');
- goog.require('ol.extent');
- goog.require('ol.geom.Point');
- goog.require('ol.source.Vector');
- /**
- * @classdesc
- * Layer source to cluster vector data. Works out of the box with point
- * geometries. For other geometry types, or if not all geometries should be
- * considered for clustering, a custom `geometryFunction` can be defined.
- *
- * @constructor
- * @param {olx.source.ClusterOptions} options Constructor options.
- * @extends {ol.source.Vector}
- * @api
- */
- ol.source.Cluster = function(options) {
- ol.source.Vector.call(this, {
- attributions: options.attributions,
- extent: options.extent,
- logo: options.logo,
- projection: options.projection,
- wrapX: options.wrapX
- });
- /**
- * @type {number|undefined}
- * @protected
- */
- this.resolution = undefined;
- /**
- * @type {number}
- * @protected
- */
- this.distance = options.distance !== undefined ? options.distance : 20;
- /**
- * @type {Array.<ol.Feature>}
- * @protected
- */
- this.features = [];
- /**
- * @param {ol.Feature} feature Feature.
- * @return {ol.geom.Point} Cluster calculation point.
- * @protected
- */
- this.geometryFunction = options.geometryFunction || function(feature) {
- var geometry = /** @type {ol.geom.Point} */ (feature.getGeometry());
- ol.asserts.assert(geometry instanceof ol.geom.Point,
- 10); // The default `geometryFunction` can only handle `ol.geom.Point` geometries
- return geometry;
- };
- /**
- * @type {ol.source.Vector}
- * @protected
- */
- this.source = options.source;
- this.source.on(ol.events.EventType.CHANGE,
- ol.source.Cluster.prototype.refresh, this);
- };
- ol.inherits(ol.source.Cluster, ol.source.Vector);
- /**
- * Get the distance in pixels between clusters.
- * @return {number} Distance.
- * @api
- */
- ol.source.Cluster.prototype.getDistance = function() {
- return this.distance;
- };
- /**
- * Get a reference to the wrapped source.
- * @return {ol.source.Vector} Source.
- * @api
- */
- ol.source.Cluster.prototype.getSource = function() {
- return this.source;
- };
- /**
- * @inheritDoc
- */
- ol.source.Cluster.prototype.loadFeatures = function(extent, resolution,
- projection) {
- this.source.loadFeatures(extent, resolution, projection);
- if (resolution !== this.resolution) {
- this.clear();
- this.resolution = resolution;
- this.cluster();
- this.addFeatures(this.features);
- }
- };
- /**
- * Set the distance in pixels between clusters.
- * @param {number} distance The distance in pixels.
- * @api
- */
- ol.source.Cluster.prototype.setDistance = function(distance) {
- this.distance = distance;
- this.refresh();
- };
- /**
- * handle the source changing
- * @override
- */
- ol.source.Cluster.prototype.refresh = function() {
- this.clear();
- this.cluster();
- this.addFeatures(this.features);
- ol.source.Vector.prototype.refresh.call(this);
- };
- /**
- * @protected
- */
- ol.source.Cluster.prototype.cluster = function() {
- if (this.resolution === undefined) {
- return;
- }
- this.features.length = 0;
- var extent = ol.extent.createEmpty();
- var mapDistance = this.distance * this.resolution;
- var features = this.source.getFeatures();
- /**
- * @type {!Object.<string, boolean>}
- */
- var clustered = {};
- for (var i = 0, ii = features.length; i < ii; i++) {
- var feature = features[i];
- if (!(ol.getUid(feature).toString() in clustered)) {
- var geometry = this.geometryFunction(feature);
- if (geometry) {
- var coordinates = geometry.getCoordinates();
- ol.extent.createOrUpdateFromCoordinate(coordinates, extent);
- ol.extent.buffer(extent, mapDistance, extent);
- var neighbors = this.source.getFeaturesInExtent(extent);
- neighbors = neighbors.filter(function(neighbor) {
- var uid = ol.getUid(neighbor).toString();
- if (!(uid in clustered)) {
- clustered[uid] = true;
- return true;
- } else {
- return false;
- }
- });
- this.features.push(this.createCluster(neighbors));
- }
- }
- }
- };
- /**
- * @param {Array.<ol.Feature>} features Features
- * @return {ol.Feature} The cluster feature.
- * @protected
- */
- ol.source.Cluster.prototype.createCluster = function(features) {
- var centroid = [0, 0];
- for (var i = features.length - 1; i >= 0; --i) {
- var geometry = this.geometryFunction(features[i]);
- if (geometry) {
- ol.coordinate.add(centroid, geometry.getCoordinates());
- } else {
- features.splice(i, 1);
- }
- }
- ol.coordinate.scale(centroid, 1 / features.length);
- var cluster = new ol.Feature(new ol.geom.Point(centroid));
- cluster.set('features', features);
- return cluster;
- };
- goog.provide('ol.source.Image');
- goog.require('ol');
- goog.require('ol.ImageState');
- goog.require('ol.array');
- goog.require('ol.events.Event');
- goog.require('ol.extent');
- goog.require('ol.proj');
- goog.require('ol.reproj.Image');
- goog.require('ol.source.Source');
- /**
- * @classdesc
- * Abstract base class; normally only used for creating subclasses and not
- * instantiated in apps.
- * Base class for sources providing a single image.
- *
- * @constructor
- * @abstract
- * @extends {ol.source.Source}
- * @param {ol.SourceImageOptions} options Single image source options.
- * @api
- */
- ol.source.Image = function(options) {
- ol.source.Source.call(this, {
- attributions: options.attributions,
- extent: options.extent,
- logo: options.logo,
- projection: options.projection,
- state: options.state
- });
- /**
- * @private
- * @type {Array.<number>}
- */
- this.resolutions_ = options.resolutions !== undefined ?
- options.resolutions : null;
- /**
- * @private
- * @type {ol.reproj.Image}
- */
- this.reprojectedImage_ = null;
- /**
- * @private
- * @type {number}
- */
- this.reprojectedRevision_ = 0;
- };
- ol.inherits(ol.source.Image, ol.source.Source);
- /**
- * @return {Array.<number>} Resolutions.
- * @override
- */
- ol.source.Image.prototype.getResolutions = function() {
- return this.resolutions_;
- };
- /**
- * @protected
- * @param {number} resolution Resolution.
- * @return {number} Resolution.
- */
- ol.source.Image.prototype.findNearestResolution = function(resolution) {
- if (this.resolutions_) {
- var idx = ol.array.linearFindNearest(this.resolutions_, resolution, 0);
- resolution = this.resolutions_[idx];
- }
- return resolution;
- };
- /**
- * @param {ol.Extent} extent Extent.
- * @param {number} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.proj.Projection} projection Projection.
- * @return {ol.ImageBase} Single image.
- */
- ol.source.Image.prototype.getImage = function(extent, resolution, pixelRatio, projection) {
- var sourceProjection = this.getProjection();
- if (!ol.ENABLE_RASTER_REPROJECTION ||
- !sourceProjection ||
- !projection ||
- ol.proj.equivalent(sourceProjection, projection)) {
- if (sourceProjection) {
- projection = sourceProjection;
- }
- return this.getImageInternal(extent, resolution, pixelRatio, projection);
- } else {
- if (this.reprojectedImage_) {
- if (this.reprojectedRevision_ == this.getRevision() &&
- ol.proj.equivalent(
- this.reprojectedImage_.getProjection(), projection) &&
- this.reprojectedImage_.getResolution() == resolution &&
- ol.extent.equals(this.reprojectedImage_.getExtent(), extent)) {
- return this.reprojectedImage_;
- }
- this.reprojectedImage_.dispose();
- this.reprojectedImage_ = null;
- }
- this.reprojectedImage_ = new ol.reproj.Image(
- sourceProjection, projection, extent, resolution, pixelRatio,
- function(extent, resolution, pixelRatio) {
- return this.getImageInternal(extent, resolution,
- pixelRatio, sourceProjection);
- }.bind(this));
- this.reprojectedRevision_ = this.getRevision();
- return this.reprojectedImage_;
- }
- };
- /**
- * @abstract
- * @param {ol.Extent} extent Extent.
- * @param {number} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.proj.Projection} projection Projection.
- * @return {ol.ImageBase} Single image.
- * @protected
- */
- ol.source.Image.prototype.getImageInternal = function(extent, resolution, pixelRatio, projection) {};
- /**
- * Handle image change events.
- * @param {ol.events.Event} event Event.
- * @protected
- */
- ol.source.Image.prototype.handleImageChange = function(event) {
- var image = /** @type {ol.Image} */ (event.target);
- switch (image.getState()) {
- case ol.ImageState.LOADING:
- this.dispatchEvent(
- new ol.source.Image.Event(ol.source.Image.EventType_.IMAGELOADSTART,
- image));
- break;
- case ol.ImageState.LOADED:
- this.dispatchEvent(
- new ol.source.Image.Event(ol.source.Image.EventType_.IMAGELOADEND,
- image));
- break;
- case ol.ImageState.ERROR:
- this.dispatchEvent(
- new ol.source.Image.Event(ol.source.Image.EventType_.IMAGELOADERROR,
- image));
- break;
- default:
- // pass
- }
- };
- /**
- * Default image load function for image sources that use ol.Image image
- * instances.
- * @param {ol.Image} image Image.
- * @param {string} src Source.
- */
- ol.source.Image.defaultImageLoadFunction = function(image, src) {
- image.getImage().src = src;
- };
- /**
- * @classdesc
- * Events emitted by {@link ol.source.Image} instances are instances of this
- * type.
- *
- * @constructor
- * @extends {ol.events.Event}
- * @implements {oli.source.ImageEvent}
- * @param {string} type Type.
- * @param {ol.Image} image The image.
- */
- ol.source.Image.Event = function(type, image) {
- ol.events.Event.call(this, type);
- /**
- * The image related to the event.
- * @type {ol.Image}
- * @api
- */
- this.image = image;
- };
- ol.inherits(ol.source.Image.Event, ol.events.Event);
- /**
- * @enum {string}
- * @private
- */
- ol.source.Image.EventType_ = {
- /**
- * Triggered when an image starts loading.
- * @event ol.source.Image.Event#imageloadstart
- * @api
- */
- IMAGELOADSTART: 'imageloadstart',
- /**
- * Triggered when an image finishes loading.
- * @event ol.source.Image.Event#imageloadend
- * @api
- */
- IMAGELOADEND: 'imageloadend',
- /**
- * Triggered if image loading results in an error.
- * @event ol.source.Image.Event#imageloaderror
- * @api
- */
- IMAGELOADERROR: 'imageloaderror'
- };
- goog.provide('ol.uri');
- /**
- * Appends query parameters to a URI.
- *
- * @param {string} uri The original URI, which may already have query data.
- * @param {!Object} params An object where keys are URI-encoded parameter keys,
- * and the values are arbitrary types or arrays.
- * @return {string} The new URI.
- */
- ol.uri.appendParams = function(uri, params) {
- var keyParams = [];
- // Skip any null or undefined parameter values
- Object.keys(params).forEach(function(k) {
- if (params[k] !== null && params[k] !== undefined) {
- keyParams.push(k + '=' + encodeURIComponent(params[k]));
- }
- });
- var qs = keyParams.join('&');
- // remove any trailing ? or &
- uri = uri.replace(/[?&]$/, '');
- // append ? or & depending on whether uri has existing parameters
- uri = uri.indexOf('?') === -1 ? uri + '?' : uri + '&';
- return uri + qs;
- };
- goog.provide('ol.source.ImageArcGISRest');
- goog.require('ol');
- goog.require('ol.Image');
- goog.require('ol.asserts');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.extent');
- goog.require('ol.obj');
- goog.require('ol.source.Image');
- goog.require('ol.uri');
- /**
- * @classdesc
- * Source for data from ArcGIS Rest services providing single, untiled images.
- * Useful when underlying map service has labels.
- *
- * If underlying map service is not using labels,
- * take advantage of ol image caching and use
- * {@link ol.source.TileArcGISRest} data source.
- *
- * @constructor
- * @fires ol.source.Image.Event
- * @extends {ol.source.Image}
- * @param {olx.source.ImageArcGISRestOptions=} opt_options Image ArcGIS Rest Options.
- * @api
- */
- ol.source.ImageArcGISRest = function(opt_options) {
- var options = opt_options || {};
- ol.source.Image.call(this, {
- attributions: options.attributions,
- logo: options.logo,
- projection: options.projection,
- resolutions: options.resolutions
- });
- /**
- * @private
- * @type {?string}
- */
- this.crossOrigin_ =
- options.crossOrigin !== undefined ? options.crossOrigin : null;
- /**
- * @private
- * @type {boolean}
- */
- this.hidpi_ = options.hidpi !== undefined ? options.hidpi : true;
- /**
- * @private
- * @type {string|undefined}
- */
- this.url_ = options.url;
- /**
- * @private
- * @type {ol.ImageLoadFunctionType}
- */
- this.imageLoadFunction_ = options.imageLoadFunction !== undefined ?
- options.imageLoadFunction : ol.source.Image.defaultImageLoadFunction;
- /**
- * @private
- * @type {!Object}
- */
- this.params_ = options.params || {};
- /**
- * @private
- * @type {ol.Image}
- */
- this.image_ = null;
- /**
- * @private
- * @type {ol.Size}
- */
- this.imageSize_ = [0, 0];
- /**
- * @private
- * @type {number}
- */
- this.renderedRevision_ = 0;
- /**
- * @private
- * @type {number}
- */
- this.ratio_ = options.ratio !== undefined ? options.ratio : 1.5;
- };
- ol.inherits(ol.source.ImageArcGISRest, ol.source.Image);
- /**
- * Get the user-provided params, i.e. those passed to the constructor through
- * the "params" option, and possibly updated using the updateParams method.
- * @return {Object} Params.
- * @api
- */
- ol.source.ImageArcGISRest.prototype.getParams = function() {
- return this.params_;
- };
- /**
- * @inheritDoc
- */
- ol.source.ImageArcGISRest.prototype.getImageInternal = function(extent, resolution, pixelRatio, projection) {
- if (this.url_ === undefined) {
- return null;
- }
- resolution = this.findNearestResolution(resolution);
- pixelRatio = this.hidpi_ ? pixelRatio : 1;
- var image = this.image_;
- if (image &&
- this.renderedRevision_ == this.getRevision() &&
- image.getResolution() == resolution &&
- image.getPixelRatio() == pixelRatio &&
- ol.extent.containsExtent(image.getExtent(), extent)) {
- return image;
- }
- var params = {
- 'F': 'image',
- 'FORMAT': 'PNG32',
- 'TRANSPARENT': true
- };
- ol.obj.assign(params, this.params_);
- extent = extent.slice();
- var centerX = (extent[0] + extent[2]) / 2;
- var centerY = (extent[1] + extent[3]) / 2;
- if (this.ratio_ != 1) {
- var halfWidth = this.ratio_ * ol.extent.getWidth(extent) / 2;
- var halfHeight = this.ratio_ * ol.extent.getHeight(extent) / 2;
- extent[0] = centerX - halfWidth;
- extent[1] = centerY - halfHeight;
- extent[2] = centerX + halfWidth;
- extent[3] = centerY + halfHeight;
- }
- var imageResolution = resolution / pixelRatio;
- // Compute an integer width and height.
- var width = Math.ceil(ol.extent.getWidth(extent) / imageResolution);
- var height = Math.ceil(ol.extent.getHeight(extent) / imageResolution);
- // Modify the extent to match the integer width and height.
- extent[0] = centerX - imageResolution * width / 2;
- extent[2] = centerX + imageResolution * width / 2;
- extent[1] = centerY - imageResolution * height / 2;
- extent[3] = centerY + imageResolution * height / 2;
- this.imageSize_[0] = width;
- this.imageSize_[1] = height;
- var url = this.getRequestUrl_(extent, this.imageSize_, pixelRatio,
- projection, params);
- this.image_ = new ol.Image(extent, resolution, pixelRatio,
- url, this.crossOrigin_, this.imageLoadFunction_);
- this.renderedRevision_ = this.getRevision();
- ol.events.listen(this.image_, ol.events.EventType.CHANGE,
- this.handleImageChange, this);
- return this.image_;
- };
- /**
- * Return the image load function of the source.
- * @return {ol.ImageLoadFunctionType} The image load function.
- * @api
- */
- ol.source.ImageArcGISRest.prototype.getImageLoadFunction = function() {
- return this.imageLoadFunction_;
- };
- /**
- * @param {ol.Extent} extent Extent.
- * @param {ol.Size} size Size.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.proj.Projection} projection Projection.
- * @param {Object} params Params.
- * @return {string} Request URL.
- * @private
- */
- ol.source.ImageArcGISRest.prototype.getRequestUrl_ = function(extent, size, pixelRatio, projection, params) {
- // ArcGIS Server only wants the numeric portion of the projection ID.
- var srid = projection.getCode().split(':').pop();
- params['SIZE'] = size[0] + ',' + size[1];
- params['BBOX'] = extent.join(',');
- params['BBOXSR'] = srid;
- params['IMAGESR'] = srid;
- params['DPI'] = Math.round(90 * pixelRatio);
- var url = this.url_;
- var modifiedUrl = url
- .replace(/MapServer\/?$/, 'MapServer/export')
- .replace(/ImageServer\/?$/, 'ImageServer/exportImage');
- if (modifiedUrl == url) {
- ol.asserts.assert(false, 50); // `options.featureTypes` should be an Array
- }
- return ol.uri.appendParams(modifiedUrl, params);
- };
- /**
- * Return the URL used for this ArcGIS source.
- * @return {string|undefined} URL.
- * @api
- */
- ol.source.ImageArcGISRest.prototype.getUrl = function() {
- return this.url_;
- };
- /**
- * Set the image load function of the source.
- * @param {ol.ImageLoadFunctionType} imageLoadFunction Image load function.
- * @api
- */
- ol.source.ImageArcGISRest.prototype.setImageLoadFunction = function(imageLoadFunction) {
- this.image_ = null;
- this.imageLoadFunction_ = imageLoadFunction;
- this.changed();
- };
- /**
- * Set the URL to use for requests.
- * @param {string|undefined} url URL.
- * @api
- */
- ol.source.ImageArcGISRest.prototype.setUrl = function(url) {
- if (url != this.url_) {
- this.url_ = url;
- this.image_ = null;
- this.changed();
- }
- };
- /**
- * Update the user-provided params.
- * @param {Object} params Params.
- * @api
- */
- ol.source.ImageArcGISRest.prototype.updateParams = function(params) {
- ol.obj.assign(this.params_, params);
- this.image_ = null;
- this.changed();
- };
- goog.provide('ol.source.ImageCanvas');
- goog.require('ol');
- goog.require('ol.ImageCanvas');
- goog.require('ol.extent');
- goog.require('ol.source.Image');
- /**
- * @classdesc
- * Base class for image sources where a canvas element is the image.
- *
- * @constructor
- * @extends {ol.source.Image}
- * @param {olx.source.ImageCanvasOptions} options Constructor options.
- * @api
- */
- ol.source.ImageCanvas = function(options) {
- ol.source.Image.call(this, {
- attributions: options.attributions,
- logo: options.logo,
- projection: options.projection,
- resolutions: options.resolutions,
- state: options.state
- });
- /**
- * @private
- * @type {ol.CanvasFunctionType}
- */
- this.canvasFunction_ = options.canvasFunction;
- /**
- * @private
- * @type {ol.ImageCanvas}
- */
- this.canvas_ = null;
- /**
- * @private
- * @type {number}
- */
- this.renderedRevision_ = 0;
- /**
- * @private
- * @type {number}
- */
- this.ratio_ = options.ratio !== undefined ?
- options.ratio : 1.5;
- };
- ol.inherits(ol.source.ImageCanvas, ol.source.Image);
- /**
- * @inheritDoc
- */
- ol.source.ImageCanvas.prototype.getImageInternal = function(extent, resolution, pixelRatio, projection) {
- resolution = this.findNearestResolution(resolution);
- var canvas = this.canvas_;
- if (canvas &&
- this.renderedRevision_ == this.getRevision() &&
- canvas.getResolution() == resolution &&
- canvas.getPixelRatio() == pixelRatio &&
- ol.extent.containsExtent(canvas.getExtent(), extent)) {
- return canvas;
- }
- extent = extent.slice();
- ol.extent.scaleFromCenter(extent, this.ratio_);
- var width = ol.extent.getWidth(extent) / resolution;
- var height = ol.extent.getHeight(extent) / resolution;
- var size = [width * pixelRatio, height * pixelRatio];
- var canvasElement = this.canvasFunction_(
- extent, resolution, pixelRatio, size, projection);
- if (canvasElement) {
- canvas = new ol.ImageCanvas(extent, resolution, pixelRatio, canvasElement);
- }
- this.canvas_ = canvas;
- this.renderedRevision_ = this.getRevision();
- return canvas;
- };
- goog.provide('ol.source.ImageMapGuide');
- goog.require('ol');
- goog.require('ol.Image');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.extent');
- goog.require('ol.obj');
- goog.require('ol.source.Image');
- goog.require('ol.uri');
- /**
- * @classdesc
- * Source for images from Mapguide servers
- *
- * @constructor
- * @fires ol.source.Image.Event
- * @extends {ol.source.Image}
- * @param {olx.source.ImageMapGuideOptions} options Options.
- * @api
- */
- ol.source.ImageMapGuide = function(options) {
- ol.source.Image.call(this, {
- projection: options.projection,
- resolutions: options.resolutions
- });
- /**
- * @private
- * @type {?string}
- */
- this.crossOrigin_ =
- options.crossOrigin !== undefined ? options.crossOrigin : null;
- /**
- * @private
- * @type {number}
- */
- this.displayDpi_ = options.displayDpi !== undefined ?
- options.displayDpi : 96;
- /**
- * @private
- * @type {!Object}
- */
- this.params_ = options.params || {};
- /**
- * @private
- * @type {string|undefined}
- */
- this.url_ = options.url;
- /**
- * @private
- * @type {ol.ImageLoadFunctionType}
- */
- this.imageLoadFunction_ = options.imageLoadFunction !== undefined ?
- options.imageLoadFunction : ol.source.Image.defaultImageLoadFunction;
- /**
- * @private
- * @type {boolean}
- */
- this.hidpi_ = options.hidpi !== undefined ? options.hidpi : true;
- /**
- * @private
- * @type {number}
- */
- this.metersPerUnit_ = options.metersPerUnit !== undefined ?
- options.metersPerUnit : 1;
- /**
- * @private
- * @type {number}
- */
- this.ratio_ = options.ratio !== undefined ? options.ratio : 1;
- /**
- * @private
- * @type {boolean}
- */
- this.useOverlay_ = options.useOverlay !== undefined ?
- options.useOverlay : false;
- /**
- * @private
- * @type {ol.Image}
- */
- this.image_ = null;
- /**
- * @private
- * @type {number}
- */
- this.renderedRevision_ = 0;
- };
- ol.inherits(ol.source.ImageMapGuide, ol.source.Image);
- /**
- * Get the user-provided params, i.e. those passed to the constructor through
- * the "params" option, and possibly updated using the updateParams method.
- * @return {Object} Params.
- * @api
- */
- ol.source.ImageMapGuide.prototype.getParams = function() {
- return this.params_;
- };
- /**
- * @inheritDoc
- */
- ol.source.ImageMapGuide.prototype.getImageInternal = function(extent, resolution, pixelRatio, projection) {
- resolution = this.findNearestResolution(resolution);
- pixelRatio = this.hidpi_ ? pixelRatio : 1;
- var image = this.image_;
- if (image &&
- this.renderedRevision_ == this.getRevision() &&
- image.getResolution() == resolution &&
- image.getPixelRatio() == pixelRatio &&
- ol.extent.containsExtent(image.getExtent(), extent)) {
- return image;
- }
- if (this.ratio_ != 1) {
- extent = extent.slice();
- ol.extent.scaleFromCenter(extent, this.ratio_);
- }
- var width = ol.extent.getWidth(extent) / resolution;
- var height = ol.extent.getHeight(extent) / resolution;
- var size = [width * pixelRatio, height * pixelRatio];
- if (this.url_ !== undefined) {
- var imageUrl = this.getUrl(this.url_, this.params_, extent, size,
- projection);
- image = new ol.Image(extent, resolution, pixelRatio,
- imageUrl, this.crossOrigin_,
- this.imageLoadFunction_);
- ol.events.listen(image, ol.events.EventType.CHANGE,
- this.handleImageChange, this);
- } else {
- image = null;
- }
- this.image_ = image;
- this.renderedRevision_ = this.getRevision();
- return image;
- };
- /**
- * Return the image load function of the source.
- * @return {ol.ImageLoadFunctionType} The image load function.
- * @api
- */
- ol.source.ImageMapGuide.prototype.getImageLoadFunction = function() {
- return this.imageLoadFunction_;
- };
- /**
- * @param {ol.Extent} extent The map extents.
- * @param {ol.Size} size The viewport size.
- * @param {number} metersPerUnit The meters-per-unit value.
- * @param {number} dpi The display resolution.
- * @return {number} The computed map scale.
- */
- ol.source.ImageMapGuide.getScale = function(extent, size, metersPerUnit, dpi) {
- var mcsW = ol.extent.getWidth(extent);
- var mcsH = ol.extent.getHeight(extent);
- var devW = size[0];
- var devH = size[1];
- var mpp = 0.0254 / dpi;
- if (devH * mcsW > devW * mcsH) {
- return mcsW * metersPerUnit / (devW * mpp); // width limited
- } else {
- return mcsH * metersPerUnit / (devH * mpp); // height limited
- }
- };
- /**
- * Update the user-provided params.
- * @param {Object} params Params.
- * @api
- */
- ol.source.ImageMapGuide.prototype.updateParams = function(params) {
- ol.obj.assign(this.params_, params);
- this.changed();
- };
- /**
- * @param {string} baseUrl The mapagent url.
- * @param {Object.<string, string|number>} params Request parameters.
- * @param {ol.Extent} extent Extent.
- * @param {ol.Size} size Size.
- * @param {ol.proj.Projection} projection Projection.
- * @return {string} The mapagent map image request URL.
- */
- ol.source.ImageMapGuide.prototype.getUrl = function(baseUrl, params, extent, size, projection) {
- var scale = ol.source.ImageMapGuide.getScale(extent, size,
- this.metersPerUnit_, this.displayDpi_);
- var center = ol.extent.getCenter(extent);
- var baseParams = {
- 'OPERATION': this.useOverlay_ ? 'GETDYNAMICMAPOVERLAYIMAGE' : 'GETMAPIMAGE',
- 'VERSION': '2.0.0',
- 'LOCALE': 'en',
- 'CLIENTAGENT': 'ol.source.ImageMapGuide source',
- 'CLIP': '1',
- 'SETDISPLAYDPI': this.displayDpi_,
- 'SETDISPLAYWIDTH': Math.round(size[0]),
- 'SETDISPLAYHEIGHT': Math.round(size[1]),
- 'SETVIEWSCALE': scale,
- 'SETVIEWCENTERX': center[0],
- 'SETVIEWCENTERY': center[1]
- };
- ol.obj.assign(baseParams, params);
- return ol.uri.appendParams(baseUrl, baseParams);
- };
- /**
- * Set the image load function of the MapGuide source.
- * @param {ol.ImageLoadFunctionType} imageLoadFunction Image load function.
- * @api
- */
- ol.source.ImageMapGuide.prototype.setImageLoadFunction = function(
- imageLoadFunction) {
- this.image_ = null;
- this.imageLoadFunction_ = imageLoadFunction;
- this.changed();
- };
- goog.provide('ol.source.ImageStatic');
- goog.require('ol');
- goog.require('ol.Image');
- goog.require('ol.ImageState');
- goog.require('ol.dom');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.extent');
- goog.require('ol.proj');
- goog.require('ol.source.Image');
- /**
- * @classdesc
- * A layer source for displaying a single, static image.
- *
- * @constructor
- * @extends {ol.source.Image}
- * @param {olx.source.ImageStaticOptions} options Options.
- * @api
- */
- ol.source.ImageStatic = function(options) {
- var imageExtent = options.imageExtent;
- var crossOrigin = options.crossOrigin !== undefined ?
- options.crossOrigin : null;
- var /** @type {ol.ImageLoadFunctionType} */ imageLoadFunction =
- options.imageLoadFunction !== undefined ?
- options.imageLoadFunction : ol.source.Image.defaultImageLoadFunction;
- ol.source.Image.call(this, {
- attributions: options.attributions,
- logo: options.logo,
- projection: ol.proj.get(options.projection)
- });
- /**
- * @private
- * @type {ol.Image}
- */
- this.image_ = new ol.Image(imageExtent, undefined, 1, options.url, crossOrigin, imageLoadFunction);
- /**
- * @private
- * @type {ol.Size}
- */
- this.imageSize_ = options.imageSize ? options.imageSize : null;
- ol.events.listen(this.image_, ol.events.EventType.CHANGE,
- this.handleImageChange, this);
- };
- ol.inherits(ol.source.ImageStatic, ol.source.Image);
- /**
- * @inheritDoc
- */
- ol.source.ImageStatic.prototype.getImageInternal = function(extent, resolution, pixelRatio, projection) {
- if (ol.extent.intersects(extent, this.image_.getExtent())) {
- return this.image_;
- }
- return null;
- };
- /**
- * @inheritDoc
- */
- ol.source.ImageStatic.prototype.handleImageChange = function(evt) {
- if (this.image_.getState() == ol.ImageState.LOADED) {
- var imageExtent = this.image_.getExtent();
- var image = this.image_.getImage();
- var imageWidth, imageHeight;
- if (this.imageSize_) {
- imageWidth = this.imageSize_[0];
- imageHeight = this.imageSize_[1];
- } else {
- imageWidth = image.width;
- imageHeight = image.height;
- }
- var resolution = ol.extent.getHeight(imageExtent) / imageHeight;
- var targetWidth = Math.ceil(ol.extent.getWidth(imageExtent) / resolution);
- if (targetWidth != imageWidth) {
- var context = ol.dom.createCanvasContext2D(targetWidth, imageHeight);
- var canvas = context.canvas;
- context.drawImage(image, 0, 0, imageWidth, imageHeight,
- 0, 0, canvas.width, canvas.height);
- this.image_.setImage(canvas);
- }
- }
- ol.source.Image.prototype.handleImageChange.call(this, evt);
- };
- goog.provide('ol.source.ImageVector');
- goog.require('ol');
- goog.require('ol.dom');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.ext.rbush');
- goog.require('ol.extent');
- goog.require('ol.render.canvas.ReplayGroup');
- goog.require('ol.renderer.vector');
- goog.require('ol.source.ImageCanvas');
- goog.require('ol.style.Style');
- goog.require('ol.transform');
- /**
- * @deprecated
- * @classdesc
- * **Deprecated**. Use an `ol.layer.Vector` with `renderMode: 'image'` and an
- * `ol.source.Vector` instead.
- *
- * An image source whose images are canvas elements into which vector features
- * read from a vector source (`ol.source.Vector`) are drawn. An
- * `ol.source.ImageVector` object is to be used as the `source` of an image
- * layer (`ol.layer.Image`). Image layers are rotated, scaled, and translated,
- * as opposed to being re-rendered, during animations and interactions. So, like
- * any other image layer, an image layer configured with an
- * `ol.source.ImageVector` will exhibit this behaviour. This is in contrast to a
- * vector layer, where vector features are re-drawn during animations and
- * interactions.
- *
- * @constructor
- * @extends {ol.source.ImageCanvas}
- * @param {olx.source.ImageVectorOptions} options Options.
- * @api
- */
- ol.source.ImageVector = function(options) {
- /**
- * @private
- * @type {ol.source.Vector}
- */
- this.source_ = options.source;
- /**
- * @private
- * @type {ol.Transform}
- */
- this.transform_ = ol.transform.create();
- /**
- * @private
- * @type {CanvasRenderingContext2D}
- */
- this.canvasContext_ = ol.dom.createCanvasContext2D();
- /**
- * @private
- * @type {ol.Size}
- */
- this.canvasSize_ = [0, 0];
- /**
- * Declutter tree.
- * @private
- */
- this.declutterTree_ = ol.ext.rbush(9);
- /**
- * @private
- * @type {number}
- */
- this.renderBuffer_ = options.renderBuffer == undefined ? 100 : options.renderBuffer;
- /**
- * @private
- * @type {ol.render.canvas.ReplayGroup}
- */
- this.replayGroup_ = null;
- ol.source.ImageCanvas.call(this, {
- attributions: options.attributions,
- canvasFunction: this.canvasFunctionInternal_.bind(this),
- logo: options.logo,
- projection: options.projection,
- ratio: options.ratio,
- resolutions: options.resolutions,
- state: this.source_.getState()
- });
- /**
- * User provided style.
- * @type {ol.style.Style|Array.<ol.style.Style>|ol.StyleFunction}
- * @private
- */
- this.style_ = null;
- /**
- * Style function for use within the library.
- * @type {ol.StyleFunction|undefined}
- * @private
- */
- this.styleFunction_ = undefined;
- this.setStyle(options.style);
- ol.events.listen(this.source_, ol.events.EventType.CHANGE,
- this.handleSourceChange_, this);
- };
- ol.inherits(ol.source.ImageVector, ol.source.ImageCanvas);
- /**
- * @param {ol.Extent} extent Extent.
- * @param {number} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.Size} size Size.
- * @param {ol.proj.Projection} projection Projection;
- * @return {HTMLCanvasElement} Canvas element.
- * @private
- */
- ol.source.ImageVector.prototype.canvasFunctionInternal_ = function(extent, resolution, pixelRatio, size, projection) {
- var replayGroup = new ol.render.canvas.ReplayGroup(
- ol.renderer.vector.getTolerance(resolution, pixelRatio), extent,
- resolution, pixelRatio, this.source_.getOverlaps(), this.declutterTree_, this.renderBuffer_);
- this.source_.loadFeatures(extent, resolution, projection);
- var loading = false;
- this.source_.forEachFeatureInExtent(extent,
- /**
- * @param {ol.Feature} feature Feature.
- */
- function(feature) {
- loading = loading ||
- this.renderFeature_(feature, resolution, pixelRatio, replayGroup);
- }, this);
- replayGroup.finish();
- if (loading) {
- return null;
- }
- if (this.canvasSize_[0] != size[0] || this.canvasSize_[1] != size[1]) {
- this.canvasContext_.canvas.width = size[0];
- this.canvasContext_.canvas.height = size[1];
- this.canvasSize_[0] = size[0];
- this.canvasSize_[1] = size[1];
- } else {
- this.canvasContext_.clearRect(0, 0, size[0], size[1]);
- }
- this.declutterTree_.clear();
- var transform = this.getTransform_(ol.extent.getCenter(extent),
- resolution, pixelRatio, size);
- replayGroup.replay(this.canvasContext_, transform, 0, {});
- this.replayGroup_ = replayGroup;
- return this.canvasContext_.canvas;
- };
- /**
- * @inheritDoc
- */
- ol.source.ImageVector.prototype.forEachFeatureAtCoordinate = function(
- coordinate, resolution, rotation, hitTolerance, skippedFeatureUids, callback) {
- if (!this.replayGroup_) {
- return undefined;
- } else {
- /** @type {Object.<string, boolean>} */
- var features = {};
- var result = this.replayGroup_.forEachFeatureAtCoordinate(
- coordinate, resolution, 0, hitTolerance, skippedFeatureUids,
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @return {?} Callback result.
- */
- function(feature) {
- var key = ol.getUid(feature).toString();
- if (!(key in features)) {
- features[key] = true;
- return callback(feature);
- }
- }, null);
- return result;
- }
- };
- /**
- * Get a reference to the wrapped source.
- * @return {ol.source.Vector} Source.
- * @api
- */
- ol.source.ImageVector.prototype.getSource = function() {
- return this.source_;
- };
- /**
- * Get the style for features. This returns whatever was passed to the `style`
- * option at construction or to the `setStyle` method.
- * @return {ol.style.Style|Array.<ol.style.Style>|ol.StyleFunction}
- * Layer style.
- * @api
- */
- ol.source.ImageVector.prototype.getStyle = function() {
- return this.style_;
- };
- /**
- * Get the style function.
- * @return {ol.StyleFunction|undefined} Layer style function.
- * @api
- */
- ol.source.ImageVector.prototype.getStyleFunction = function() {
- return this.styleFunction_;
- };
- /**
- * @param {ol.Coordinate} center Center.
- * @param {number} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.Size} size Size.
- * @return {!ol.Transform} Transform.
- * @private
- */
- ol.source.ImageVector.prototype.getTransform_ = function(center, resolution, pixelRatio, size) {
- var dx1 = size[0] / 2;
- var dy1 = size[1] / 2;
- var sx = pixelRatio / resolution;
- var sy = -sx;
- var dx2 = -center[0];
- var dy2 = -center[1];
- return ol.transform.compose(this.transform_, dx1, dy1, sx, sy, 0, dx2, dy2);
- };
- /**
- * Handle changes in image style state.
- * @param {ol.events.Event} event Image style change event.
- * @private
- */
- ol.source.ImageVector.prototype.handleImageChange_ = function(event) {
- this.changed();
- };
- /**
- * @private
- */
- ol.source.ImageVector.prototype.handleSourceChange_ = function() {
- // setState will trigger a CHANGE event, so we always rely
- // change events by calling setState.
- this.setState(this.source_.getState());
- };
- /**
- * @param {ol.Feature} feature Feature.
- * @param {number} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.render.canvas.ReplayGroup} replayGroup Replay group.
- * @return {boolean} `true` if an image is loading.
- * @private
- */
- ol.source.ImageVector.prototype.renderFeature_ = function(feature, resolution, pixelRatio, replayGroup) {
- var styles;
- var styleFunction = feature.getStyleFunction();
- if (styleFunction) {
- styles = styleFunction.call(feature, resolution);
- } else if (this.styleFunction_) {
- styles = this.styleFunction_(feature, resolution);
- }
- if (!styles) {
- return false;
- }
- var i, ii, loading = false;
- if (!Array.isArray(styles)) {
- styles = [styles];
- }
- for (i = 0, ii = styles.length; i < ii; ++i) {
- loading = ol.renderer.vector.renderFeature(
- replayGroup, feature, styles[i],
- ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
- this.handleImageChange_, this) || loading;
- }
- return loading;
- };
- /**
- * Set the style for features. This can be a single style object, an array
- * of styles, or a function that takes a feature and resolution and returns
- * an array of styles. If it is `undefined` the default style is used. If
- * it is `null` the layer has no style (a `null` style), so only features
- * that have their own styles will be rendered in the layer. See
- * {@link ol.style} for information on the default style.
- * @param {ol.style.Style|Array.<ol.style.Style>|ol.StyleFunction|undefined}
- * style Layer style.
- * @api
- */
- ol.source.ImageVector.prototype.setStyle = function(style) {
- this.style_ = style !== undefined ? style : ol.style.Style.defaultFunction;
- this.styleFunction_ = !style ?
- undefined : ol.style.Style.createFunction(this.style_);
- this.changed();
- };
- goog.provide('ol.source.WMSServerType');
- /**
- * Available server types: `'carmentaserver'`, `'geoserver'`, `'mapserver'`,
- * `'qgis'`. These are servers that have vendor parameters beyond the WMS
- * specification that OpenLayers can make use of.
- * @enum {string}
- */
- ol.source.WMSServerType = {
- CARMENTA_SERVER: 'carmentaserver',
- GEOSERVER: 'geoserver',
- MAPSERVER: 'mapserver',
- QGIS: 'qgis'
- };
- // FIXME cannot be shared between maps with different projections
- goog.provide('ol.source.ImageWMS');
- goog.require('ol');
- goog.require('ol.Image');
- goog.require('ol.asserts');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.extent');
- goog.require('ol.obj');
- goog.require('ol.proj');
- goog.require('ol.reproj');
- goog.require('ol.source.Image');
- goog.require('ol.source.WMSServerType');
- goog.require('ol.string');
- goog.require('ol.uri');
- /**
- * @classdesc
- * Source for WMS servers providing single, untiled images.
- *
- * @constructor
- * @fires ol.source.Image.Event
- * @extends {ol.source.Image}
- * @param {olx.source.ImageWMSOptions=} opt_options Options.
- * @api
- */
- ol.source.ImageWMS = function(opt_options) {
- var options = opt_options || {};
- ol.source.Image.call(this, {
- attributions: options.attributions,
- logo: options.logo,
- projection: options.projection,
- resolutions: options.resolutions
- });
- /**
- * @private
- * @type {?string}
- */
- this.crossOrigin_ =
- options.crossOrigin !== undefined ? options.crossOrigin : null;
- /**
- * @private
- * @type {string|undefined}
- */
- this.url_ = options.url;
- /**
- * @private
- * @type {ol.ImageLoadFunctionType}
- */
- this.imageLoadFunction_ = options.imageLoadFunction !== undefined ?
- options.imageLoadFunction : ol.source.Image.defaultImageLoadFunction;
- /**
- * @private
- * @type {!Object}
- */
- this.params_ = options.params || {};
- /**
- * @private
- * @type {boolean}
- */
- this.v13_ = true;
- this.updateV13_();
- /**
- * @private
- * @type {ol.source.WMSServerType|undefined}
- */
- this.serverType_ = /** @type {ol.source.WMSServerType|undefined} */ (options.serverType);
- /**
- * @private
- * @type {boolean}
- */
- this.hidpi_ = options.hidpi !== undefined ? options.hidpi : true;
- /**
- * @private
- * @type {ol.Image}
- */
- this.image_ = null;
- /**
- * @private
- * @type {ol.Size}
- */
- this.imageSize_ = [0, 0];
- /**
- * @private
- * @type {number}
- */
- this.renderedRevision_ = 0;
- /**
- * @private
- * @type {number}
- */
- this.ratio_ = options.ratio !== undefined ? options.ratio : 1.5;
- };
- ol.inherits(ol.source.ImageWMS, ol.source.Image);
- /**
- * @const
- * @type {ol.Size}
- * @private
- */
- ol.source.ImageWMS.GETFEATUREINFO_IMAGE_SIZE_ = [101, 101];
- /**
- * Return the GetFeatureInfo URL for the passed coordinate, resolution, and
- * projection. Return `undefined` if the GetFeatureInfo URL cannot be
- * constructed.
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {number} resolution Resolution.
- * @param {ol.ProjectionLike} projection Projection.
- * @param {!Object} params GetFeatureInfo params. `INFO_FORMAT` at least should
- * be provided. If `QUERY_LAYERS` is not provided then the layers specified
- * in the `LAYERS` parameter will be used. `VERSION` should not be
- * specified here.
- * @return {string|undefined} GetFeatureInfo URL.
- * @api
- */
- ol.source.ImageWMS.prototype.getGetFeatureInfoUrl = function(coordinate, resolution, projection, params) {
- if (this.url_ === undefined) {
- return undefined;
- }
- var projectionObj = ol.proj.get(projection);
- var sourceProjectionObj = this.getProjection();
- if (sourceProjectionObj && sourceProjectionObj !== projectionObj) {
- resolution = ol.reproj.calculateSourceResolution(sourceProjectionObj, projectionObj, coordinate, resolution);
- coordinate = ol.proj.transform(coordinate, projectionObj, sourceProjectionObj);
- }
- var extent = ol.extent.getForViewAndSize(
- coordinate, resolution, 0,
- ol.source.ImageWMS.GETFEATUREINFO_IMAGE_SIZE_);
- var baseParams = {
- 'SERVICE': 'WMS',
- 'VERSION': ol.DEFAULT_WMS_VERSION,
- 'REQUEST': 'GetFeatureInfo',
- 'FORMAT': 'image/png',
- 'TRANSPARENT': true,
- 'QUERY_LAYERS': this.params_['LAYERS']
- };
- ol.obj.assign(baseParams, this.params_, params);
- var x = Math.floor((coordinate[0] - extent[0]) / resolution);
- var y = Math.floor((extent[3] - coordinate[1]) / resolution);
- baseParams[this.v13_ ? 'I' : 'X'] = x;
- baseParams[this.v13_ ? 'J' : 'Y'] = y;
- return this.getRequestUrl_(
- extent, ol.source.ImageWMS.GETFEATUREINFO_IMAGE_SIZE_,
- 1, sourceProjectionObj || projectionObj, baseParams);
- };
- /**
- * Get the user-provided params, i.e. those passed to the constructor through
- * the "params" option, and possibly updated using the updateParams method.
- * @return {Object} Params.
- * @api
- */
- ol.source.ImageWMS.prototype.getParams = function() {
- return this.params_;
- };
- /**
- * @inheritDoc
- */
- ol.source.ImageWMS.prototype.getImageInternal = function(extent, resolution, pixelRatio, projection) {
- if (this.url_ === undefined) {
- return null;
- }
- resolution = this.findNearestResolution(resolution);
- if (pixelRatio != 1 && (!this.hidpi_ || this.serverType_ === undefined)) {
- pixelRatio = 1;
- }
- var imageResolution = resolution / pixelRatio;
- var center = ol.extent.getCenter(extent);
- var viewWidth = Math.ceil(ol.extent.getWidth(extent) / imageResolution);
- var viewHeight = Math.ceil(ol.extent.getHeight(extent) / imageResolution);
- var viewExtent = ol.extent.getForViewAndSize(center, imageResolution, 0,
- [viewWidth, viewHeight]);
- var requestWidth = Math.ceil(this.ratio_ * ol.extent.getWidth(extent) / imageResolution);
- var requestHeight = Math.ceil(this.ratio_ * ol.extent.getHeight(extent) / imageResolution);
- var requestExtent = ol.extent.getForViewAndSize(center, imageResolution, 0,
- [requestWidth, requestHeight]);
- var image = this.image_;
- if (image &&
- this.renderedRevision_ == this.getRevision() &&
- image.getResolution() == resolution &&
- image.getPixelRatio() == pixelRatio &&
- ol.extent.containsExtent(image.getExtent(), viewExtent)) {
- return image;
- }
- var params = {
- 'SERVICE': 'WMS',
- 'VERSION': ol.DEFAULT_WMS_VERSION,
- 'REQUEST': 'GetMap',
- 'FORMAT': 'image/png',
- 'TRANSPARENT': true
- };
- ol.obj.assign(params, this.params_);
- this.imageSize_[0] = Math.round(ol.extent.getWidth(requestExtent) / imageResolution);
- this.imageSize_[1] = Math.round(ol.extent.getHeight(requestExtent) / imageResolution);
- var url = this.getRequestUrl_(requestExtent, this.imageSize_, pixelRatio,
- projection, params);
- this.image_ = new ol.Image(requestExtent, resolution, pixelRatio,
- url, this.crossOrigin_, this.imageLoadFunction_);
- this.renderedRevision_ = this.getRevision();
- ol.events.listen(this.image_, ol.events.EventType.CHANGE,
- this.handleImageChange, this);
- return this.image_;
- };
- /**
- * Return the image load function of the source.
- * @return {ol.ImageLoadFunctionType} The image load function.
- * @api
- */
- ol.source.ImageWMS.prototype.getImageLoadFunction = function() {
- return this.imageLoadFunction_;
- };
- /**
- * @param {ol.Extent} extent Extent.
- * @param {ol.Size} size Size.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.proj.Projection} projection Projection.
- * @param {Object} params Params.
- * @return {string} Request URL.
- * @private
- */
- ol.source.ImageWMS.prototype.getRequestUrl_ = function(extent, size, pixelRatio, projection, params) {
- ol.asserts.assert(this.url_ !== undefined, 9); // `url` must be configured or set using `#setUrl()`
- params[this.v13_ ? 'CRS' : 'SRS'] = projection.getCode();
- if (!('STYLES' in this.params_)) {
- params['STYLES'] = '';
- }
- if (pixelRatio != 1) {
- switch (this.serverType_) {
- case ol.source.WMSServerType.GEOSERVER:
- var dpi = (90 * pixelRatio + 0.5) | 0;
- if ('FORMAT_OPTIONS' in params) {
- params['FORMAT_OPTIONS'] += ';dpi:' + dpi;
- } else {
- params['FORMAT_OPTIONS'] = 'dpi:' + dpi;
- }
- break;
- case ol.source.WMSServerType.MAPSERVER:
- params['MAP_RESOLUTION'] = 90 * pixelRatio;
- break;
- case ol.source.WMSServerType.CARMENTA_SERVER:
- case ol.source.WMSServerType.QGIS:
- params['DPI'] = 90 * pixelRatio;
- break;
- default:
- ol.asserts.assert(false, 8); // Unknown `serverType` configured
- break;
- }
- }
- params['WIDTH'] = size[0];
- params['HEIGHT'] = size[1];
- var axisOrientation = projection.getAxisOrientation();
- var bbox;
- if (this.v13_ && axisOrientation.substr(0, 2) == 'ne') {
- bbox = [extent[1], extent[0], extent[3], extent[2]];
- } else {
- bbox = extent;
- }
- params['BBOX'] = bbox.join(',');
- return ol.uri.appendParams(/** @type {string} */ (this.url_), params);
- };
- /**
- * Return the URL used for this WMS source.
- * @return {string|undefined} URL.
- * @api
- */
- ol.source.ImageWMS.prototype.getUrl = function() {
- return this.url_;
- };
- /**
- * Set the image load function of the source.
- * @param {ol.ImageLoadFunctionType} imageLoadFunction Image load function.
- * @api
- */
- ol.source.ImageWMS.prototype.setImageLoadFunction = function(
- imageLoadFunction) {
- this.image_ = null;
- this.imageLoadFunction_ = imageLoadFunction;
- this.changed();
- };
- /**
- * Set the URL to use for requests.
- * @param {string|undefined} url URL.
- * @api
- */
- ol.source.ImageWMS.prototype.setUrl = function(url) {
- if (url != this.url_) {
- this.url_ = url;
- this.image_ = null;
- this.changed();
- }
- };
- /**
- * Update the user-provided params.
- * @param {Object} params Params.
- * @api
- */
- ol.source.ImageWMS.prototype.updateParams = function(params) {
- ol.obj.assign(this.params_, params);
- this.updateV13_();
- this.image_ = null;
- this.changed();
- };
- /**
- * @private
- */
- ol.source.ImageWMS.prototype.updateV13_ = function() {
- var version = this.params_['VERSION'] || ol.DEFAULT_WMS_VERSION;
- this.v13_ = ol.string.compareVersions(version, '1.3') >= 0;
- };
- goog.provide('ol.source.OSM');
- goog.require('ol');
- goog.require('ol.source.XYZ');
- /**
- * @classdesc
- * Layer source for the OpenStreetMap tile server.
- *
- * @constructor
- * @extends {ol.source.XYZ}
- * @param {olx.source.OSMOptions=} opt_options Open Street Map options.
- * @api
- */
- ol.source.OSM = function(opt_options) {
- var options = opt_options || {};
- var attributions;
- if (options.attributions !== undefined) {
- attributions = options.attributions;
- } else {
- attributions = [ol.source.OSM.ATTRIBUTION];
- }
- var crossOrigin = options.crossOrigin !== undefined ?
- options.crossOrigin : 'anonymous';
- var url = options.url !== undefined ?
- options.url : 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png';
- ol.source.XYZ.call(this, {
- attributions: attributions,
- cacheSize: options.cacheSize,
- crossOrigin: crossOrigin,
- opaque: options.opaque !== undefined ? options.opaque : true,
- maxZoom: options.maxZoom !== undefined ? options.maxZoom : 19,
- reprojectionErrorThreshold: options.reprojectionErrorThreshold,
- tileLoadFunction: options.tileLoadFunction,
- url: url,
- wrapX: options.wrapX
- });
- };
- ol.inherits(ol.source.OSM, ol.source.XYZ);
- /**
- * The attribution containing a link to the OpenStreetMap Copyright and License
- * page.
- * @const
- * @type {string}
- * @api
- */
- ol.source.OSM.ATTRIBUTION = '© ' +
- '<a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> ' +
- 'contributors.';
- /**
- * @fileoverview
- * @suppress {accessControls, ambiguousFunctionDecl, checkDebuggerStatement, checkRegExp, checkTypes, checkVars, const, constantProperty, deprecated, duplicate, es5Strict, fileoverviewTags, missingProperties, nonStandardJsDocs, strictModuleDepCheck, suspiciousCode, undefinedNames, undefinedVars, unknownDefines, unusedLocalVariables, uselessCode, visibility}
- */
- goog.provide('ol.ext.pixelworks.Processor');
- /** @typedef {function(*)} */
- ol.ext.pixelworks.Processor = function() {};
- (function() {(function (exports) {
- 'use strict';
- var hasImageData = true;
- try {
- new ImageData(10, 10);
- } catch (_) {
- hasImageData = false;
- }
- var context = document.createElement('canvas').getContext('2d');
- function newImageData$1(data, width, height) {
- if (hasImageData) {
- return new ImageData(data, width, height);
- } else {
- var imageData = context.createImageData(width, height);
- imageData.data.set(data);
- return imageData;
- }
- }
- var newImageData_1 = newImageData$1;
- var util = {
- newImageData: newImageData_1
- };
- var newImageData = util.newImageData;
- function createMinion(operation) {
- var workerHasImageData = true;
- try {
- new ImageData(10, 10);
- } catch (_) {
- workerHasImageData = false;
- }
- function newWorkerImageData(data, width, height) {
- if (workerHasImageData) {
- return new ImageData(data, width, height);
- } else {
- return {data: data, width: width, height: height};
- }
- }
- return function(data) {
- var buffers = data['buffers'];
- var meta = data['meta'];
- var imageOps = data['imageOps'];
- var width = data['width'];
- var height = data['height'];
- var numBuffers = buffers.length;
- var numBytes = buffers[0].byteLength;
- var output, b;
- if (imageOps) {
- var images = new Array(numBuffers);
- for (b = 0; b < numBuffers; ++b) {
- images[b] = newWorkerImageData(
- new Uint8ClampedArray(buffers[b]), width, height);
- }
- output = operation(images, meta).data;
- } else {
- output = new Uint8ClampedArray(numBytes);
- var arrays = new Array(numBuffers);
- var pixels = new Array(numBuffers);
- for (b = 0; b < numBuffers; ++b) {
- arrays[b] = new Uint8ClampedArray(buffers[b]);
- pixels[b] = [0, 0, 0, 0];
- }
- for (var i = 0; i < numBytes; i += 4) {
- for (var j = 0; j < numBuffers; ++j) {
- var array = arrays[j];
- pixels[j][0] = array[i];
- pixels[j][1] = array[i + 1];
- pixels[j][2] = array[i + 2];
- pixels[j][3] = array[i + 3];
- }
- var pixel = operation(pixels, meta);
- output[i] = pixel[0];
- output[i + 1] = pixel[1];
- output[i + 2] = pixel[2];
- output[i + 3] = pixel[3];
- }
- }
- return output.buffer;
- };
- }
- function createWorker(config, onMessage) {
- var lib = Object.keys(config.lib || {}).map(function(name) {
- return 'var ' + name + ' = ' + config.lib[name].toString() + ';';
- });
- var lines = lib.concat([
- 'var __minion__ = (' + createMinion.toString() + ')(', config.operation.toString(), ');',
- 'self.addEventListener("message", function(event) {',
- ' var buffer = __minion__(event.data);',
- ' self.postMessage({buffer: buffer, meta: event.data.meta}, [buffer]);',
- '});'
- ]);
- var blob = new Blob(lines, {type: 'text/javascript'});
- var source = URL.createObjectURL(blob);
- var worker = new Worker(source);
- worker.addEventListener('message', onMessage);
- return worker;
- }
- function createFauxWorker(config, onMessage) {
- var minion = createMinion(config.operation);
- return {
- postMessage: function(data) {
- setTimeout(function() {
- onMessage({'data': {'buffer': minion(data), 'meta': data['meta']}});
- }, 0);
- }
- };
- }
- function Processor(config) {
- this._imageOps = !!config.imageOps;
- var threads;
- if (config.threads === 0) {
- threads = 0;
- } else if (this._imageOps) {
- threads = 1;
- } else {
- threads = config.threads || 1;
- }
- var workers = [];
- if (threads) {
- for (var i = 0; i < threads; ++i) {
- workers[i] = createWorker(config, this._onWorkerMessage.bind(this, i));
- }
- } else {
- workers[0] = createFauxWorker(config, this._onWorkerMessage.bind(this, 0));
- }
- this._workers = workers;
- this._queue = [];
- this._maxQueueLength = config.queue || Infinity;
- this._running = 0;
- this._dataLookup = {};
- this._job = null;
- }
- Processor.prototype.process = function(inputs, meta, callback) {
- this._enqueue({
- inputs: inputs,
- meta: meta,
- callback: callback
- });
- this._dispatch();
- };
- Processor.prototype.destroy = function() {
- for (var key in this) {
- this[key] = null;
- }
- this._destroyed = true;
- };
- Processor.prototype._enqueue = function(job) {
- this._queue.push(job);
- while (this._queue.length > this._maxQueueLength) {
- this._queue.shift().callback(null, null);
- }
- };
- Processor.prototype._dispatch = function() {
- if (this._running === 0 && this._queue.length > 0) {
- var job = this._job = this._queue.shift();
- var width = job.inputs[0].width;
- var height = job.inputs[0].height;
- var buffers = job.inputs.map(function(input) {
- return input.data.buffer;
- });
- var threads = this._workers.length;
- this._running = threads;
- if (threads === 1) {
- this._workers[0].postMessage({
- 'buffers': buffers,
- 'meta': job.meta,
- 'imageOps': this._imageOps,
- 'width': width,
- 'height': height
- }, buffers);
- } else {
- var length = job.inputs[0].data.length;
- var segmentLength = 4 * Math.ceil(length / 4 / threads);
- for (var i = 0; i < threads; ++i) {
- var offset = i * segmentLength;
- var slices = [];
- for (var j = 0, jj = buffers.length; j < jj; ++j) {
- slices.push(buffers[i].slice(offset, offset + segmentLength));
- }
- this._workers[i].postMessage({
- 'buffers': slices,
- 'meta': job.meta,
- 'imageOps': this._imageOps,
- 'width': width,
- 'height': height
- }, slices);
- }
- }
- }
- };
- Processor.prototype._onWorkerMessage = function(index, event) {
- if (this._destroyed) {
- return;
- }
- this._dataLookup[index] = event.data;
- --this._running;
- if (this._running === 0) {
- this._resolveJob();
- }
- };
- Processor.prototype._resolveJob = function() {
- var job = this._job;
- var threads = this._workers.length;
- var data, meta;
- if (threads === 1) {
- data = new Uint8ClampedArray(this._dataLookup[0]['buffer']);
- meta = this._dataLookup[0]['meta'];
- } else {
- var length = job.inputs[0].data.length;
- data = new Uint8ClampedArray(length);
- meta = new Array(length);
- var segmentLength = 4 * Math.ceil(length / 4 / threads);
- for (var i = 0; i < threads; ++i) {
- var buffer = this._dataLookup[i]['buffer'];
- var offset = i * segmentLength;
- data.set(new Uint8ClampedArray(buffer), offset);
- meta[i] = this._dataLookup[i]['meta'];
- }
- }
- this._job = null;
- this._dataLookup = {};
- job.callback(null,
- newImageData(data, job.inputs[0].width, job.inputs[0].height), meta);
- this._dispatch();
- };
- var processor = Processor;
- var Processor_1 = processor;
- var lib = {
- Processor: Processor_1
- };
- exports['default'] = lib;
- exports.Processor = Processor_1;
- }((this.pixelworks = this.pixelworks || {})));}).call(ol.ext);
- goog.provide('ol.source.RasterOperationType');
- /**
- * Raster operation type. Supported values are `'pixel'` and `'image'`.
- * @enum {string}
- */
- ol.source.RasterOperationType = {
- PIXEL: 'pixel',
- IMAGE: 'image'
- };
- goog.provide('ol.source.Raster');
- goog.require('ol');
- goog.require('ol.ImageCanvas');
- goog.require('ol.TileQueue');
- goog.require('ol.dom');
- goog.require('ol.events');
- goog.require('ol.events.Event');
- goog.require('ol.events.EventType');
- goog.require('ol.ext.pixelworks.Processor');
- goog.require('ol.extent');
- goog.require('ol.layer.Image');
- goog.require('ol.layer.Tile');
- goog.require('ol.obj');
- goog.require('ol.renderer.canvas.ImageLayer');
- goog.require('ol.renderer.canvas.TileLayer');
- goog.require('ol.source.Image');
- goog.require('ol.source.RasterOperationType');
- goog.require('ol.source.State');
- goog.require('ol.source.Tile');
- goog.require('ol.transform');
- /**
- * @classdesc
- * A source that transforms data from any number of input sources using an
- * {@link ol.RasterOperation} function to transform input pixel values into
- * output pixel values.
- *
- * @constructor
- * @extends {ol.source.Image}
- * @fires ol.source.Raster.Event
- * @param {olx.source.RasterOptions} options Options.
- * @api
- */
- ol.source.Raster = function(options) {
- /**
- * @private
- * @type {*}
- */
- this.worker_ = null;
- /**
- * @private
- * @type {ol.source.RasterOperationType}
- */
- this.operationType_ = options.operationType !== undefined ?
- options.operationType : ol.source.RasterOperationType.PIXEL;
- /**
- * @private
- * @type {number}
- */
- this.threads_ = options.threads !== undefined ? options.threads : 1;
- /**
- * @private
- * @type {Array.<ol.renderer.canvas.Layer>}
- */
- this.renderers_ = ol.source.Raster.createRenderers_(options.sources);
- for (var r = 0, rr = this.renderers_.length; r < rr; ++r) {
- ol.events.listen(this.renderers_[r], ol.events.EventType.CHANGE,
- this.changed, this);
- }
- /**
- * @private
- * @type {ol.TileQueue}
- */
- this.tileQueue_ = new ol.TileQueue(
- function() {
- return 1;
- },
- this.changed.bind(this));
- var layerStatesArray = ol.source.Raster.getLayerStatesArray_(this.renderers_);
- var layerStates = {};
- for (var i = 0, ii = layerStatesArray.length; i < ii; ++i) {
- layerStates[ol.getUid(layerStatesArray[i].layer)] = layerStatesArray[i];
- }
- /**
- * The most recently requested frame state.
- * @type {olx.FrameState}
- * @private
- */
- this.requestedFrameState_;
- /**
- * The most recently rendered image canvas.
- * @type {ol.ImageCanvas}
- * @private
- */
- this.renderedImageCanvas_ = null;
- /**
- * The most recently rendered revision.
- * @type {number}
- */
- this.renderedRevision_;
- /**
- * @private
- * @type {olx.FrameState}
- */
- this.frameState_ = {
- animate: false,
- coordinateToPixelTransform: ol.transform.create(),
- extent: null,
- focus: null,
- index: 0,
- layerStates: layerStates,
- layerStatesArray: layerStatesArray,
- logos: {},
- pixelRatio: 1,
- pixelToCoordinateTransform: ol.transform.create(),
- postRenderFunctions: [],
- size: [0, 0],
- skippedFeatureUids: {},
- tileQueue: this.tileQueue_,
- time: Date.now(),
- usedTiles: {},
- viewState: /** @type {olx.ViewState} */ ({
- rotation: 0
- }),
- viewHints: [],
- wantedTiles: {}
- };
- ol.source.Image.call(this, {});
- if (options.operation !== undefined) {
- this.setOperation(options.operation, options.lib);
- }
- };
- ol.inherits(ol.source.Raster, ol.source.Image);
- /**
- * Set the operation.
- * @param {ol.RasterOperation} operation New operation.
- * @param {Object=} opt_lib Functions that will be available to operations run
- * in a worker.
- * @api
- */
- ol.source.Raster.prototype.setOperation = function(operation, opt_lib) {
- this.worker_ = new ol.ext.pixelworks.Processor({
- operation: operation,
- imageOps: this.operationType_ === ol.source.RasterOperationType.IMAGE,
- queue: 1,
- lib: opt_lib,
- threads: this.threads_
- });
- this.changed();
- };
- /**
- * Update the stored frame state.
- * @param {ol.Extent} extent The view extent (in map units).
- * @param {number} resolution The view resolution.
- * @param {ol.proj.Projection} projection The view projection.
- * @return {olx.FrameState} The updated frame state.
- * @private
- */
- ol.source.Raster.prototype.updateFrameState_ = function(extent, resolution, projection) {
- var frameState = /** @type {olx.FrameState} */ (
- ol.obj.assign({}, this.frameState_));
- frameState.viewState = /** @type {olx.ViewState} */ (
- ol.obj.assign({}, frameState.viewState));
- var center = ol.extent.getCenter(extent);
- frameState.extent = extent.slice();
- frameState.focus = center;
- frameState.size[0] = Math.round(ol.extent.getWidth(extent) / resolution);
- frameState.size[1] = Math.round(ol.extent.getHeight(extent) / resolution);
- frameState.time = Date.now();
- frameState.animate = false;
- var viewState = frameState.viewState;
- viewState.center = center;
- viewState.projection = projection;
- viewState.resolution = resolution;
- return frameState;
- };
- /**
- * Determine if all sources are ready.
- * @return {boolean} All sources are ready.
- * @private
- */
- ol.source.Raster.prototype.allSourcesReady_ = function() {
- var ready = true;
- var source;
- for (var i = 0, ii = this.renderers_.length; i < ii; ++i) {
- source = this.renderers_[i].getLayer().getSource();
- if (source.getState() !== ol.source.State.READY) {
- ready = false;
- break;
- }
- }
- return ready;
- };
- /**
- * @inheritDoc
- */
- ol.source.Raster.prototype.getImage = function(extent, resolution, pixelRatio, projection) {
- if (!this.allSourcesReady_()) {
- return null;
- }
- var frameState = this.updateFrameState_(extent, resolution, projection);
- this.requestedFrameState_ = frameState;
- // check if we can't reuse the existing ol.ImageCanvas
- if (this.renderedImageCanvas_) {
- var renderedResolution = this.renderedImageCanvas_.getResolution();
- var renderedExtent = this.renderedImageCanvas_.getExtent();
- if (resolution !== renderedResolution || !ol.extent.equals(extent, renderedExtent)) {
- this.renderedImageCanvas_ = null;
- }
- }
- if (!this.renderedImageCanvas_ || this.getRevision() !== this.renderedRevision_) {
- this.processSources_();
- }
- frameState.tileQueue.loadMoreTiles(16, 16);
- if (frameState.animate) {
- requestAnimationFrame(this.changed.bind(this));
- }
- return this.renderedImageCanvas_;
- };
- /**
- * Start processing source data.
- * @private
- */
- ol.source.Raster.prototype.processSources_ = function() {
- var frameState = this.requestedFrameState_;
- var len = this.renderers_.length;
- var imageDatas = new Array(len);
- for (var i = 0; i < len; ++i) {
- var imageData = ol.source.Raster.getImageData_(
- this.renderers_[i], frameState, frameState.layerStatesArray[i]);
- if (imageData) {
- imageDatas[i] = imageData;
- } else {
- return;
- }
- }
- var data = {};
- this.dispatchEvent(new ol.source.Raster.Event(
- ol.source.Raster.EventType_.BEFOREOPERATIONS, frameState, data));
- this.worker_.process(imageDatas, data,
- this.onWorkerComplete_.bind(this, frameState));
- };
- /**
- * Called when pixel processing is complete.
- * @param {olx.FrameState} frameState The frame state.
- * @param {Error} err Any error during processing.
- * @param {ImageData} output The output image data.
- * @param {Object} data The user data.
- * @private
- */
- ol.source.Raster.prototype.onWorkerComplete_ = function(frameState, err, output, data) {
- if (err || !output) {
- return;
- }
- // do nothing if extent or resolution changed
- var extent = frameState.extent;
- var resolution = frameState.viewState.resolution;
- if (resolution !== this.requestedFrameState_.viewState.resolution ||
- !ol.extent.equals(extent, this.requestedFrameState_.extent)) {
- return;
- }
- var context;
- if (this.renderedImageCanvas_) {
- context = this.renderedImageCanvas_.getImage().getContext('2d');
- } else {
- var width = Math.round(ol.extent.getWidth(extent) / resolution);
- var height = Math.round(ol.extent.getHeight(extent) / resolution);
- context = ol.dom.createCanvasContext2D(width, height);
- this.renderedImageCanvas_ = new ol.ImageCanvas(extent, resolution, 1, context.canvas);
- }
- context.putImageData(output, 0, 0);
- this.changed();
- this.renderedRevision_ = this.getRevision();
- this.dispatchEvent(new ol.source.Raster.Event(
- ol.source.Raster.EventType_.AFTEROPERATIONS, frameState, data));
- };
- /**
- * Get image data from a renderer.
- * @param {ol.renderer.canvas.Layer} renderer Layer renderer.
- * @param {olx.FrameState} frameState The frame state.
- * @param {ol.LayerState} layerState The layer state.
- * @return {ImageData} The image data.
- * @private
- */
- ol.source.Raster.getImageData_ = function(renderer, frameState, layerState) {
- if (!renderer.prepareFrame(frameState, layerState)) {
- return null;
- }
- var width = frameState.size[0];
- var height = frameState.size[1];
- if (!ol.source.Raster.context_) {
- ol.source.Raster.context_ = ol.dom.createCanvasContext2D(width, height);
- } else {
- var canvas = ol.source.Raster.context_.canvas;
- if (canvas.width !== width || canvas.height !== height) {
- ol.source.Raster.context_ = ol.dom.createCanvasContext2D(width, height);
- } else {
- ol.source.Raster.context_.clearRect(0, 0, width, height);
- }
- }
- renderer.composeFrame(frameState, layerState, ol.source.Raster.context_);
- return ol.source.Raster.context_.getImageData(0, 0, width, height);
- };
- /**
- * A reusable canvas context.
- * @type {CanvasRenderingContext2D}
- * @private
- */
- ol.source.Raster.context_ = null;
- /**
- * Get a list of layer states from a list of renderers.
- * @param {Array.<ol.renderer.canvas.Layer>} renderers Layer renderers.
- * @return {Array.<ol.LayerState>} The layer states.
- * @private
- */
- ol.source.Raster.getLayerStatesArray_ = function(renderers) {
- return renderers.map(function(renderer) {
- return renderer.getLayer().getLayerState();
- });
- };
- /**
- * Create renderers for all sources.
- * @param {Array.<ol.source.Source>} sources The sources.
- * @return {Array.<ol.renderer.canvas.Layer>} Array of layer renderers.
- * @private
- */
- ol.source.Raster.createRenderers_ = function(sources) {
- var len = sources.length;
- var renderers = new Array(len);
- for (var i = 0; i < len; ++i) {
- renderers[i] = ol.source.Raster.createRenderer_(sources[i]);
- }
- return renderers;
- };
- /**
- * Create a renderer for the provided source.
- * @param {ol.source.Source} source The source.
- * @return {ol.renderer.canvas.Layer} The renderer.
- * @private
- */
- ol.source.Raster.createRenderer_ = function(source) {
- var renderer = null;
- if (source instanceof ol.source.Tile) {
- renderer = ol.source.Raster.createTileRenderer_(source);
- } else if (source instanceof ol.source.Image) {
- renderer = ol.source.Raster.createImageRenderer_(source);
- }
- return renderer;
- };
- /**
- * Create an image renderer for the provided source.
- * @param {ol.source.Image} source The source.
- * @return {ol.renderer.canvas.Layer} The renderer.
- * @private
- */
- ol.source.Raster.createImageRenderer_ = function(source) {
- var layer = new ol.layer.Image({source: source});
- return new ol.renderer.canvas.ImageLayer(layer);
- };
- /**
- * Create a tile renderer for the provided source.
- * @param {ol.source.Tile} source The source.
- * @return {ol.renderer.canvas.Layer} The renderer.
- * @private
- */
- ol.source.Raster.createTileRenderer_ = function(source) {
- var layer = new ol.layer.Tile({source: source});
- return new ol.renderer.canvas.TileLayer(layer);
- };
- /**
- * @classdesc
- * Events emitted by {@link ol.source.Raster} instances are instances of this
- * type.
- *
- * @constructor
- * @extends {ol.events.Event}
- * @implements {oli.source.RasterEvent}
- * @param {string} type Type.
- * @param {olx.FrameState} frameState The frame state.
- * @param {Object} data An object made available to operations.
- */
- ol.source.Raster.Event = function(type, frameState, data) {
- ol.events.Event.call(this, type);
- /**
- * The raster extent.
- * @type {ol.Extent}
- * @api
- */
- this.extent = frameState.extent;
- /**
- * The pixel resolution (map units per pixel).
- * @type {number}
- * @api
- */
- this.resolution = frameState.viewState.resolution / frameState.pixelRatio;
- /**
- * An object made available to all operations. This can be used by operations
- * as a storage object (e.g. for calculating statistics).
- * @type {Object}
- * @api
- */
- this.data = data;
- };
- ol.inherits(ol.source.Raster.Event, ol.events.Event);
- /**
- * @override
- */
- ol.source.Raster.prototype.getImageInternal = function() {
- return null; // not implemented
- };
- /**
- * @enum {string}
- * @private
- */
- ol.source.Raster.EventType_ = {
- /**
- * Triggered before operations are run.
- * @event ol.source.Raster.Event#beforeoperations
- * @api
- */
- BEFOREOPERATIONS: 'beforeoperations',
- /**
- * Triggered after operations are run.
- * @event ol.source.Raster.Event#afteroperations
- * @api
- */
- AFTEROPERATIONS: 'afteroperations'
- };
- goog.provide('ol.source.Stamen');
- goog.require('ol');
- goog.require('ol.source.OSM');
- goog.require('ol.source.XYZ');
- /**
- * @classdesc
- * Layer source for the Stamen tile server.
- *
- * @constructor
- * @extends {ol.source.XYZ}
- * @param {olx.source.StamenOptions} options Stamen options.
- * @api
- */
- ol.source.Stamen = function(options) {
- var i = options.layer.indexOf('-');
- var provider = i == -1 ? options.layer : options.layer.slice(0, i);
- var providerConfig = ol.source.Stamen.ProviderConfig[provider];
- var layerConfig = ol.source.Stamen.LayerConfig[options.layer];
- var url = options.url !== undefined ? options.url :
- 'https://stamen-tiles-{a-d}.a.ssl.fastly.net/' + options.layer +
- '/{z}/{x}/{y}.' + layerConfig.extension;
- ol.source.XYZ.call(this, {
- attributions: ol.source.Stamen.ATTRIBUTIONS,
- cacheSize: options.cacheSize,
- crossOrigin: 'anonymous',
- maxZoom: options.maxZoom != undefined ? options.maxZoom : providerConfig.maxZoom,
- minZoom: options.minZoom != undefined ? options.minZoom : providerConfig.minZoom,
- opaque: layerConfig.opaque,
- reprojectionErrorThreshold: options.reprojectionErrorThreshold,
- tileLoadFunction: options.tileLoadFunction,
- url: url,
- wrapX: options.wrapX
- });
- };
- ol.inherits(ol.source.Stamen, ol.source.XYZ);
- /**
- * @const
- * @type {Array.<string>}
- */
- ol.source.Stamen.ATTRIBUTIONS = [
- 'Map tiles by <a href="https://stamen.com/">Stamen Design</a>, ' +
- 'under <a href="https://creativecommons.org/licenses/by/3.0/">CC BY' +
- ' 3.0</a>.',
- ol.source.OSM.ATTRIBUTION
- ];
- /**
- * @type {Object.<string, {extension: string, opaque: boolean}>}
- */
- ol.source.Stamen.LayerConfig = {
- 'terrain': {
- extension: 'jpg',
- opaque: true
- },
- 'terrain-background': {
- extension: 'jpg',
- opaque: true
- },
- 'terrain-labels': {
- extension: 'png',
- opaque: false
- },
- 'terrain-lines': {
- extension: 'png',
- opaque: false
- },
- 'toner-background': {
- extension: 'png',
- opaque: true
- },
- 'toner': {
- extension: 'png',
- opaque: true
- },
- 'toner-hybrid': {
- extension: 'png',
- opaque: false
- },
- 'toner-labels': {
- extension: 'png',
- opaque: false
- },
- 'toner-lines': {
- extension: 'png',
- opaque: false
- },
- 'toner-lite': {
- extension: 'png',
- opaque: true
- },
- 'watercolor': {
- extension: 'jpg',
- opaque: true
- }
- };
- /**
- * @type {Object.<string, {minZoom: number, maxZoom: number}>}
- */
- ol.source.Stamen.ProviderConfig = {
- 'terrain': {
- minZoom: 4,
- maxZoom: 18
- },
- 'toner': {
- minZoom: 0,
- maxZoom: 20
- },
- 'watercolor': {
- minZoom: 1,
- maxZoom: 16
- }
- };
- goog.provide('ol.source.TileArcGISRest');
- goog.require('ol');
- goog.require('ol.extent');
- goog.require('ol.math');
- goog.require('ol.obj');
- goog.require('ol.size');
- goog.require('ol.source.TileImage');
- goog.require('ol.tilecoord');
- goog.require('ol.uri');
- /**
- * @classdesc
- * Layer source for tile data from ArcGIS Rest services. Map and Image
- * Services are supported.
- *
- * For cached ArcGIS services, better performance is available using the
- * {@link ol.source.XYZ} data source.
- *
- * @constructor
- * @extends {ol.source.TileImage}
- * @param {olx.source.TileArcGISRestOptions=} opt_options Tile ArcGIS Rest
- * options.
- * @api
- */
- ol.source.TileArcGISRest = function(opt_options) {
- var options = opt_options || {};
- ol.source.TileImage.call(this, {
- attributions: options.attributions,
- cacheSize: options.cacheSize,
- crossOrigin: options.crossOrigin,
- logo: options.logo,
- projection: options.projection,
- reprojectionErrorThreshold: options.reprojectionErrorThreshold,
- tileGrid: options.tileGrid,
- tileLoadFunction: options.tileLoadFunction,
- url: options.url,
- urls: options.urls,
- wrapX: options.wrapX !== undefined ? options.wrapX : true,
- transition: options.transition
- });
- /**
- * @private
- * @type {!Object}
- */
- this.params_ = options.params || {};
- /**
- * @private
- * @type {ol.Extent}
- */
- this.tmpExtent_ = ol.extent.createEmpty();
- this.setKey(this.getKeyForParams_());
- };
- ol.inherits(ol.source.TileArcGISRest, ol.source.TileImage);
- /**
- * @private
- * @return {string} The key for the current params.
- */
- ol.source.TileArcGISRest.prototype.getKeyForParams_ = function() {
- var i = 0;
- var res = [];
- for (var key in this.params_) {
- res[i++] = key + '-' + this.params_[key];
- }
- return res.join('/');
- };
- /**
- * Get the user-provided params, i.e. those passed to the constructor through
- * the "params" option, and possibly updated using the updateParams method.
- * @return {Object} Params.
- * @api
- */
- ol.source.TileArcGISRest.prototype.getParams = function() {
- return this.params_;
- };
- /**
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {ol.Size} tileSize Tile size.
- * @param {ol.Extent} tileExtent Tile extent.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.proj.Projection} projection Projection.
- * @param {Object} params Params.
- * @return {string|undefined} Request URL.
- * @private
- */
- ol.source.TileArcGISRest.prototype.getRequestUrl_ = function(tileCoord, tileSize, tileExtent,
- pixelRatio, projection, params) {
- var urls = this.urls;
- if (!urls) {
- return undefined;
- }
- // ArcGIS Server only wants the numeric portion of the projection ID.
- var srid = projection.getCode().split(':').pop();
- params['SIZE'] = tileSize[0] + ',' + tileSize[1];
- params['BBOX'] = tileExtent.join(',');
- params['BBOXSR'] = srid;
- params['IMAGESR'] = srid;
- params['DPI'] = Math.round(
- params['DPI'] ? params['DPI'] * pixelRatio : 90 * pixelRatio
- );
- var url;
- if (urls.length == 1) {
- url = urls[0];
- } else {
- var index = ol.math.modulo(ol.tilecoord.hash(tileCoord), urls.length);
- url = urls[index];
- }
- var modifiedUrl = url
- .replace(/MapServer\/?$/, 'MapServer/export')
- .replace(/ImageServer\/?$/, 'ImageServer/exportImage');
- return ol.uri.appendParams(modifiedUrl, params);
- };
- /**
- * @inheritDoc
- */
- ol.source.TileArcGISRest.prototype.getTilePixelRatio = function(pixelRatio) {
- return /** @type {number} */ (pixelRatio);
- };
- /**
- * @inheritDoc
- */
- ol.source.TileArcGISRest.prototype.fixedTileUrlFunction = function(tileCoord, pixelRatio, projection) {
- var tileGrid = this.getTileGrid();
- if (!tileGrid) {
- tileGrid = this.getTileGridForProjection(projection);
- }
- if (tileGrid.getResolutions().length <= tileCoord[0]) {
- return undefined;
- }
- var tileExtent = tileGrid.getTileCoordExtent(
- tileCoord, this.tmpExtent_);
- var tileSize = ol.size.toSize(
- tileGrid.getTileSize(tileCoord[0]), this.tmpSize);
- if (pixelRatio != 1) {
- tileSize = ol.size.scale(tileSize, pixelRatio, this.tmpSize);
- }
- // Apply default params and override with user specified values.
- var baseParams = {
- 'F': 'image',
- 'FORMAT': 'PNG32',
- 'TRANSPARENT': true
- };
- ol.obj.assign(baseParams, this.params_);
- return this.getRequestUrl_(tileCoord, tileSize, tileExtent,
- pixelRatio, projection, baseParams);
- };
- /**
- * Update the user-provided params.
- * @param {Object} params Params.
- * @api
- */
- ol.source.TileArcGISRest.prototype.updateParams = function(params) {
- ol.obj.assign(this.params_, params);
- this.setKey(this.getKeyForParams_());
- };
- goog.provide('ol.source.TileDebug');
- goog.require('ol');
- goog.require('ol.Tile');
- goog.require('ol.TileState');
- goog.require('ol.dom');
- goog.require('ol.size');
- goog.require('ol.source.Tile');
- goog.require('ol.tilecoord');
- /**
- * @classdesc
- * A pseudo tile source, which does not fetch tiles from a server, but renders
- * a grid outline for the tile grid/projection along with the coordinates for
- * each tile. See examples/canvas-tiles for an example.
- *
- * Uses Canvas context2d, so requires Canvas support.
- *
- * @constructor
- * @extends {ol.source.Tile}
- * @param {olx.source.TileDebugOptions} options Debug tile options.
- * @api
- */
- ol.source.TileDebug = function(options) {
- ol.source.Tile.call(this, {
- opaque: false,
- projection: options.projection,
- tileGrid: options.tileGrid,
- wrapX: options.wrapX !== undefined ? options.wrapX : true
- });
- };
- ol.inherits(ol.source.TileDebug, ol.source.Tile);
- /**
- * @inheritDoc
- */
- ol.source.TileDebug.prototype.getTile = function(z, x, y) {
- var tileCoordKey = ol.tilecoord.getKeyZXY(z, x, y);
- if (this.tileCache.containsKey(tileCoordKey)) {
- return /** @type {!ol.source.TileDebug.Tile_} */ (this.tileCache.get(tileCoordKey));
- } else {
- var tileSize = ol.size.toSize(this.tileGrid.getTileSize(z));
- var tileCoord = [z, x, y];
- var textTileCoord = this.getTileCoordForTileUrlFunction(tileCoord);
- var text = !textTileCoord ? '' :
- this.getTileCoordForTileUrlFunction(textTileCoord).toString();
- var tile = new ol.source.TileDebug.Tile_(tileCoord, tileSize, text);
- this.tileCache.set(tileCoordKey, tile);
- return tile;
- }
- };
- /**
- * @constructor
- * @extends {ol.Tile}
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {ol.Size} tileSize Tile size.
- * @param {string} text Text.
- * @private
- */
- ol.source.TileDebug.Tile_ = function(tileCoord, tileSize, text) {
- ol.Tile.call(this, tileCoord, ol.TileState.LOADED);
- /**
- * @private
- * @type {ol.Size}
- */
- this.tileSize_ = tileSize;
- /**
- * @private
- * @type {string}
- */
- this.text_ = text;
- /**
- * @private
- * @type {HTMLCanvasElement}
- */
- this.canvas_ = null;
- };
- ol.inherits(ol.source.TileDebug.Tile_, ol.Tile);
- /**
- * Get the image element for this tile.
- * @return {HTMLCanvasElement} Image.
- */
- ol.source.TileDebug.Tile_.prototype.getImage = function() {
- if (this.canvas_) {
- return this.canvas_;
- } else {
- var tileSize = this.tileSize_;
- var context = ol.dom.createCanvasContext2D(tileSize[0], tileSize[1]);
- context.strokeStyle = 'black';
- context.strokeRect(0.5, 0.5, tileSize[0] + 0.5, tileSize[1] + 0.5);
- context.fillStyle = 'black';
- context.textAlign = 'center';
- context.textBaseline = 'middle';
- context.font = '24px sans-serif';
- context.fillText(this.text_, tileSize[0] / 2, tileSize[1] / 2);
- this.canvas_ = context.canvas;
- return context.canvas;
- }
- };
- /**
- * @override
- */
- ol.source.TileDebug.Tile_.prototype.load = function() {};
- // FIXME check order of async callbacks
- /**
- * @see http://mapbox.com/developers/api/
- */
- goog.provide('ol.source.TileJSON');
- goog.require('ol');
- goog.require('ol.TileUrlFunction');
- goog.require('ol.asserts');
- goog.require('ol.extent');
- goog.require('ol.net');
- goog.require('ol.proj');
- goog.require('ol.source.State');
- goog.require('ol.source.TileImage');
- goog.require('ol.tilegrid');
- /**
- * @classdesc
- * Layer source for tile data in TileJSON format.
- *
- * @constructor
- * @extends {ol.source.TileImage}
- * @param {olx.source.TileJSONOptions} options TileJSON options.
- * @api
- */
- ol.source.TileJSON = function(options) {
- /**
- * @type {TileJSON}
- * @private
- */
- this.tileJSON_ = null;
- ol.source.TileImage.call(this, {
- attributions: options.attributions,
- cacheSize: options.cacheSize,
- crossOrigin: options.crossOrigin,
- projection: ol.proj.get('EPSG:3857'),
- reprojectionErrorThreshold: options.reprojectionErrorThreshold,
- state: ol.source.State.LOADING,
- tileLoadFunction: options.tileLoadFunction,
- wrapX: options.wrapX !== undefined ? options.wrapX : true,
- transition: options.transition
- });
- if (options.url) {
- if (options.jsonp) {
- ol.net.jsonp(options.url, this.handleTileJSONResponse.bind(this),
- this.handleTileJSONError.bind(this));
- } else {
- var client = new XMLHttpRequest();
- client.addEventListener('load', this.onXHRLoad_.bind(this));
- client.addEventListener('error', this.onXHRError_.bind(this));
- client.open('GET', options.url);
- client.send();
- }
- } else if (options.tileJSON) {
- this.handleTileJSONResponse(options.tileJSON);
- } else {
- ol.asserts.assert(false, 51); // Either `url` or `tileJSON` options must be provided
- }
- };
- ol.inherits(ol.source.TileJSON, ol.source.TileImage);
- /**
- * @private
- * @param {Event} event The load event.
- */
- ol.source.TileJSON.prototype.onXHRLoad_ = function(event) {
- var client = /** @type {XMLHttpRequest} */ (event.target);
- // status will be 0 for file:// urls
- if (!client.status || client.status >= 200 && client.status < 300) {
- var response;
- try {
- response = /** @type {TileJSON} */(JSON.parse(client.responseText));
- } catch (err) {
- this.handleTileJSONError();
- return;
- }
- this.handleTileJSONResponse(response);
- } else {
- this.handleTileJSONError();
- }
- };
- /**
- * @private
- * @param {Event} event The error event.
- */
- ol.source.TileJSON.prototype.onXHRError_ = function(event) {
- this.handleTileJSONError();
- };
- /**
- * @return {TileJSON} The tilejson object.
- * @api
- */
- ol.source.TileJSON.prototype.getTileJSON = function() {
- return this.tileJSON_;
- };
- /**
- * @protected
- * @param {TileJSON} tileJSON Tile JSON.
- */
- ol.source.TileJSON.prototype.handleTileJSONResponse = function(tileJSON) {
- var epsg4326Projection = ol.proj.get('EPSG:4326');
- var sourceProjection = this.getProjection();
- var extent;
- if (tileJSON.bounds !== undefined) {
- var transform = ol.proj.getTransformFromProjections(
- epsg4326Projection, sourceProjection);
- extent = ol.extent.applyTransform(tileJSON.bounds, transform);
- }
- var minZoom = tileJSON.minzoom || 0;
- var maxZoom = tileJSON.maxzoom || 22;
- var tileGrid = ol.tilegrid.createXYZ({
- extent: ol.tilegrid.extentFromProjection(sourceProjection),
- maxZoom: maxZoom,
- minZoom: minZoom
- });
- this.tileGrid = tileGrid;
- this.tileUrlFunction =
- ol.TileUrlFunction.createFromTemplates(tileJSON.tiles, tileGrid);
- if (tileJSON.attribution !== undefined && !this.getAttributions2()) {
- var attributionExtent = extent !== undefined ?
- extent : epsg4326Projection.getExtent();
- this.setAttributions(function(frameState) {
- if (ol.extent.intersects(attributionExtent, frameState.extent)) {
- return [tileJSON.attribution];
- }
- return null;
- });
- }
- this.tileJSON_ = tileJSON;
- this.setState(ol.source.State.READY);
- };
- /**
- * @protected
- */
- ol.source.TileJSON.prototype.handleTileJSONError = function() {
- this.setState(ol.source.State.ERROR);
- };
- goog.provide('ol.source.TileUTFGrid');
- goog.require('ol');
- goog.require('ol.Tile');
- goog.require('ol.TileState');
- goog.require('ol.TileUrlFunction');
- goog.require('ol.asserts');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- goog.require('ol.extent');
- goog.require('ol.net');
- goog.require('ol.proj');
- goog.require('ol.source.State');
- goog.require('ol.source.Tile');
- goog.require('ol.tilecoord');
- goog.require('ol.tilegrid');
- /**
- * @classdesc
- * Layer source for UTFGrid interaction data loaded from TileJSON format.
- *
- * @constructor
- * @extends {ol.source.Tile}
- * @param {olx.source.TileUTFGridOptions} options Source options.
- * @api
- */
- ol.source.TileUTFGrid = function(options) {
- ol.source.Tile.call(this, {
- projection: ol.proj.get('EPSG:3857'),
- state: ol.source.State.LOADING
- });
- /**
- * @private
- * @type {boolean}
- */
- this.preemptive_ = options.preemptive !== undefined ?
- options.preemptive : true;
- /**
- * @private
- * @type {!ol.TileUrlFunctionType}
- */
- this.tileUrlFunction_ = ol.TileUrlFunction.nullTileUrlFunction;
- /**
- * @private
- * @type {string|undefined}
- */
- this.template_ = undefined;
- /**
- * @private
- * @type {boolean}
- */
- this.jsonp_ = options.jsonp || false;
- if (options.url) {
- if (this.jsonp_) {
- ol.net.jsonp(options.url, this.handleTileJSONResponse.bind(this),
- this.handleTileJSONError.bind(this));
- } else {
- var client = new XMLHttpRequest();
- client.addEventListener('load', this.onXHRLoad_.bind(this));
- client.addEventListener('error', this.onXHRError_.bind(this));
- client.open('GET', options.url);
- client.send();
- }
- } else if (options.tileJSON) {
- this.handleTileJSONResponse(options.tileJSON);
- } else {
- ol.asserts.assert(false, 51); // Either `url` or `tileJSON` options must be provided
- }
- };
- ol.inherits(ol.source.TileUTFGrid, ol.source.Tile);
- /**
- * @private
- * @param {Event} event The load event.
- */
- ol.source.TileUTFGrid.prototype.onXHRLoad_ = function(event) {
- var client = /** @type {XMLHttpRequest} */ (event.target);
- // status will be 0 for file:// urls
- if (!client.status || client.status >= 200 && client.status < 300) {
- var response;
- try {
- response = /** @type {TileJSON} */(JSON.parse(client.responseText));
- } catch (err) {
- this.handleTileJSONError();
- return;
- }
- this.handleTileJSONResponse(response);
- } else {
- this.handleTileJSONError();
- }
- };
- /**
- * @private
- * @param {Event} event The error event.
- */
- ol.source.TileUTFGrid.prototype.onXHRError_ = function(event) {
- this.handleTileJSONError();
- };
- /**
- * Return the template from TileJSON.
- * @return {string|undefined} The template from TileJSON.
- * @api
- */
- ol.source.TileUTFGrid.prototype.getTemplate = function() {
- return this.template_;
- };
- /**
- * Calls the callback (synchronously by default) with the available data
- * for given coordinate and resolution (or `null` if not yet loaded or
- * in case of an error).
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {number} resolution Resolution.
- * @param {function(this: T, *)} callback Callback.
- * @param {T=} opt_this The object to use as `this` in the callback.
- * @param {boolean=} opt_request If `true` the callback is always async.
- * The tile data is requested if not yet loaded.
- * @template T
- * @api
- */
- ol.source.TileUTFGrid.prototype.forDataAtCoordinateAndResolution = function(
- coordinate, resolution, callback, opt_this, opt_request) {
- if (this.tileGrid) {
- var tileCoord = this.tileGrid.getTileCoordForCoordAndResolution(
- coordinate, resolution);
- var tile = /** @type {!ol.source.TileUTFGrid.Tile_} */(this.getTile(
- tileCoord[0], tileCoord[1], tileCoord[2], 1, this.getProjection()));
- tile.forDataAtCoordinate(coordinate, callback, opt_this, opt_request);
- } else {
- if (opt_request === true) {
- setTimeout(function() {
- callback.call(opt_this, null);
- }, 0);
- } else {
- callback.call(opt_this, null);
- }
- }
- };
- /**
- * @protected
- */
- ol.source.TileUTFGrid.prototype.handleTileJSONError = function() {
- this.setState(ol.source.State.ERROR);
- };
- /**
- * TODO: very similar to ol.source.TileJSON#handleTileJSONResponse
- * @protected
- * @param {TileJSON} tileJSON Tile JSON.
- */
- ol.source.TileUTFGrid.prototype.handleTileJSONResponse = function(tileJSON) {
- var epsg4326Projection = ol.proj.get('EPSG:4326');
- var sourceProjection = this.getProjection();
- var extent;
- if (tileJSON.bounds !== undefined) {
- var transform = ol.proj.getTransformFromProjections(
- epsg4326Projection, sourceProjection);
- extent = ol.extent.applyTransform(tileJSON.bounds, transform);
- }
- var minZoom = tileJSON.minzoom || 0;
- var maxZoom = tileJSON.maxzoom || 22;
- var tileGrid = ol.tilegrid.createXYZ({
- extent: ol.tilegrid.extentFromProjection(sourceProjection),
- maxZoom: maxZoom,
- minZoom: minZoom
- });
- this.tileGrid = tileGrid;
- this.template_ = tileJSON.template;
- var grids = tileJSON.grids;
- if (!grids) {
- this.setState(ol.source.State.ERROR);
- return;
- }
- this.tileUrlFunction_ =
- ol.TileUrlFunction.createFromTemplates(grids, tileGrid);
- if (tileJSON.attribution !== undefined) {
- var attributionExtent = extent !== undefined ?
- extent : epsg4326Projection.getExtent();
- this.setAttributions(function(frameState) {
- if (ol.extent.intersects(attributionExtent, frameState.extent)) {
- return [tileJSON.attribution];
- }
- return null;
- });
- }
- this.setState(ol.source.State.READY);
- };
- /**
- * @inheritDoc
- */
- ol.source.TileUTFGrid.prototype.getTile = function(z, x, y, pixelRatio, projection) {
- var tileCoordKey = ol.tilecoord.getKeyZXY(z, x, y);
- if (this.tileCache.containsKey(tileCoordKey)) {
- return /** @type {!ol.Tile} */ (this.tileCache.get(tileCoordKey));
- } else {
- var tileCoord = [z, x, y];
- var urlTileCoord =
- this.getTileCoordForTileUrlFunction(tileCoord, projection);
- var tileUrl = this.tileUrlFunction_(urlTileCoord, pixelRatio, projection);
- var tile = new ol.source.TileUTFGrid.Tile_(
- tileCoord,
- tileUrl !== undefined ? ol.TileState.IDLE : ol.TileState.EMPTY,
- tileUrl !== undefined ? tileUrl : '',
- this.tileGrid.getTileCoordExtent(tileCoord),
- this.preemptive_,
- this.jsonp_);
- this.tileCache.set(tileCoordKey, tile);
- return tile;
- }
- };
- /**
- * @inheritDoc
- */
- ol.source.TileUTFGrid.prototype.useTile = function(z, x, y) {
- var tileCoordKey = ol.tilecoord.getKeyZXY(z, x, y);
- if (this.tileCache.containsKey(tileCoordKey)) {
- this.tileCache.get(tileCoordKey);
- }
- };
- /**
- * @constructor
- * @extends {ol.Tile}
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {ol.TileState} state State.
- * @param {string} src Image source URI.
- * @param {ol.Extent} extent Extent of the tile.
- * @param {boolean} preemptive Load the tile when visible (before it's needed).
- * @param {boolean} jsonp Load the tile as a script.
- * @private
- */
- ol.source.TileUTFGrid.Tile_ = function(tileCoord, state, src, extent, preemptive, jsonp) {
- ol.Tile.call(this, tileCoord, state);
- /**
- * @private
- * @type {string}
- */
- this.src_ = src;
- /**
- * @private
- * @type {ol.Extent}
- */
- this.extent_ = extent;
- /**
- * @private
- * @type {boolean}
- */
- this.preemptive_ = preemptive;
- /**
- * @private
- * @type {Array.<string>}
- */
- this.grid_ = null;
- /**
- * @private
- * @type {Array.<string>}
- */
- this.keys_ = null;
- /**
- * @private
- * @type {Object.<string, Object>|undefined}
- */
- this.data_ = null;
- /**
- * @private
- * @type {boolean}
- */
- this.jsonp_ = jsonp;
- };
- ol.inherits(ol.source.TileUTFGrid.Tile_, ol.Tile);
- /**
- * Get the image element for this tile.
- * @return {Image} Image.
- */
- ol.source.TileUTFGrid.Tile_.prototype.getImage = function() {
- return null;
- };
- /**
- * Synchronously returns data at given coordinate (if available).
- * @param {ol.Coordinate} coordinate Coordinate.
- * @return {*} The data.
- */
- ol.source.TileUTFGrid.Tile_.prototype.getData = function(coordinate) {
- if (!this.grid_ || !this.keys_) {
- return null;
- }
- var xRelative = (coordinate[0] - this.extent_[0]) /
- (this.extent_[2] - this.extent_[0]);
- var yRelative = (coordinate[1] - this.extent_[1]) /
- (this.extent_[3] - this.extent_[1]);
- var row = this.grid_[Math.floor((1 - yRelative) * this.grid_.length)];
- if (typeof row !== 'string') {
- return null;
- }
- var code = row.charCodeAt(Math.floor(xRelative * row.length));
- if (code >= 93) {
- code--;
- }
- if (code >= 35) {
- code--;
- }
- code -= 32;
- var data = null;
- if (code in this.keys_) {
- var id = this.keys_[code];
- if (this.data_ && id in this.data_) {
- data = this.data_[id];
- } else {
- data = id;
- }
- }
- return data;
- };
- /**
- * Calls the callback (synchronously by default) with the available data
- * for given coordinate (or `null` if not yet loaded).
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {function(this: T, *)} callback Callback.
- * @param {T=} opt_this The object to use as `this` in the callback.
- * @param {boolean=} opt_request If `true` the callback is always async.
- * The tile data is requested if not yet loaded.
- * @template T
- */
- ol.source.TileUTFGrid.Tile_.prototype.forDataAtCoordinate = function(coordinate, callback, opt_this, opt_request) {
- if (this.state == ol.TileState.IDLE && opt_request === true) {
- ol.events.listenOnce(this, ol.events.EventType.CHANGE, function(e) {
- callback.call(opt_this, this.getData(coordinate));
- }, this);
- this.loadInternal_();
- } else {
- if (opt_request === true) {
- setTimeout(function() {
- callback.call(opt_this, this.getData(coordinate));
- }.bind(this), 0);
- } else {
- callback.call(opt_this, this.getData(coordinate));
- }
- }
- };
- /**
- * @inheritDoc
- */
- ol.source.TileUTFGrid.Tile_.prototype.getKey = function() {
- return this.src_;
- };
- /**
- * @private
- */
- ol.source.TileUTFGrid.Tile_.prototype.handleError_ = function() {
- this.state = ol.TileState.ERROR;
- this.changed();
- };
- /**
- * @param {!UTFGridJSON} json UTFGrid data.
- * @private
- */
- ol.source.TileUTFGrid.Tile_.prototype.handleLoad_ = function(json) {
- this.grid_ = json.grid;
- this.keys_ = json.keys;
- this.data_ = json.data;
- this.state = ol.TileState.EMPTY;
- this.changed();
- };
- /**
- * @private
- */
- ol.source.TileUTFGrid.Tile_.prototype.loadInternal_ = function() {
- if (this.state == ol.TileState.IDLE) {
- this.state = ol.TileState.LOADING;
- if (this.jsonp_) {
- ol.net.jsonp(this.src_, this.handleLoad_.bind(this),
- this.handleError_.bind(this));
- } else {
- var client = new XMLHttpRequest();
- client.addEventListener('load', this.onXHRLoad_.bind(this));
- client.addEventListener('error', this.onXHRError_.bind(this));
- client.open('GET', this.src_);
- client.send();
- }
- }
- };
- /**
- * @private
- * @param {Event} event The load event.
- */
- ol.source.TileUTFGrid.Tile_.prototype.onXHRLoad_ = function(event) {
- var client = /** @type {XMLHttpRequest} */ (event.target);
- // status will be 0 for file:// urls
- if (!client.status || client.status >= 200 && client.status < 300) {
- var response;
- try {
- response = /** @type {!UTFGridJSON} */(JSON.parse(client.responseText));
- } catch (err) {
- this.handleError_();
- return;
- }
- this.handleLoad_(response);
- } else {
- this.handleError_();
- }
- };
- /**
- * @private
- * @param {Event} event The error event.
- */
- ol.source.TileUTFGrid.Tile_.prototype.onXHRError_ = function(event) {
- this.handleError_();
- };
- /**
- * @override
- */
- ol.source.TileUTFGrid.Tile_.prototype.load = function() {
- if (this.preemptive_) {
- this.loadInternal_();
- }
- };
- // FIXME add minZoom support
- // FIXME add date line wrap (tile coord transform)
- // FIXME cannot be shared between maps with different projections
- goog.provide('ol.source.TileWMS');
- goog.require('ol');
- goog.require('ol.asserts');
- goog.require('ol.extent');
- goog.require('ol.obj');
- goog.require('ol.math');
- goog.require('ol.proj');
- goog.require('ol.reproj');
- goog.require('ol.size');
- goog.require('ol.source.TileImage');
- goog.require('ol.source.WMSServerType');
- goog.require('ol.tilecoord');
- goog.require('ol.string');
- goog.require('ol.uri');
- /**
- * @classdesc
- * Layer source for tile data from WMS servers.
- *
- * @constructor
- * @extends {ol.source.TileImage}
- * @param {olx.source.TileWMSOptions=} opt_options Tile WMS options.
- * @api
- */
- ol.source.TileWMS = function(opt_options) {
- var options = opt_options || {};
- var params = options.params || {};
- var transparent = 'TRANSPARENT' in params ? params['TRANSPARENT'] : true;
- ol.source.TileImage.call(this, {
- attributions: options.attributions,
- cacheSize: options.cacheSize,
- crossOrigin: options.crossOrigin,
- logo: options.logo,
- opaque: !transparent,
- projection: options.projection,
- reprojectionErrorThreshold: options.reprojectionErrorThreshold,
- tileClass: options.tileClass,
- tileGrid: options.tileGrid,
- tileLoadFunction: options.tileLoadFunction,
- url: options.url,
- urls: options.urls,
- wrapX: options.wrapX !== undefined ? options.wrapX : true,
- transition: options.transition
- });
- /**
- * @private
- * @type {number}
- */
- this.gutter_ = options.gutter !== undefined ? options.gutter : 0;
- /**
- * @private
- * @type {!Object}
- */
- this.params_ = params;
- /**
- * @private
- * @type {boolean}
- */
- this.v13_ = true;
- /**
- * @private
- * @type {ol.source.WMSServerType|undefined}
- */
- this.serverType_ = /** @type {ol.source.WMSServerType|undefined} */ (options.serverType);
- /**
- * @private
- * @type {boolean}
- */
- this.hidpi_ = options.hidpi !== undefined ? options.hidpi : true;
- /**
- * @private
- * @type {ol.Extent}
- */
- this.tmpExtent_ = ol.extent.createEmpty();
- this.updateV13_();
- this.setKey(this.getKeyForParams_());
- };
- ol.inherits(ol.source.TileWMS, ol.source.TileImage);
- /**
- * Return the GetFeatureInfo URL for the passed coordinate, resolution, and
- * projection. Return `undefined` if the GetFeatureInfo URL cannot be
- * constructed.
- * @param {ol.Coordinate} coordinate Coordinate.
- * @param {number} resolution Resolution.
- * @param {ol.ProjectionLike} projection Projection.
- * @param {!Object} params GetFeatureInfo params. `INFO_FORMAT` at least should
- * be provided. If `QUERY_LAYERS` is not provided then the layers specified
- * in the `LAYERS` parameter will be used. `VERSION` should not be
- * specified here.
- * @return {string|undefined} GetFeatureInfo URL.
- * @api
- */
- ol.source.TileWMS.prototype.getGetFeatureInfoUrl = function(coordinate, resolution, projection, params) {
- var projectionObj = ol.proj.get(projection);
- var sourceProjectionObj = this.getProjection();
- var tileGrid = this.getTileGrid();
- if (!tileGrid) {
- tileGrid = this.getTileGridForProjection(projectionObj);
- }
- var tileCoord = tileGrid.getTileCoordForCoordAndResolution(coordinate, resolution);
- if (tileGrid.getResolutions().length <= tileCoord[0]) {
- return undefined;
- }
- var tileResolution = tileGrid.getResolution(tileCoord[0]);
- var tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent_);
- var tileSize = ol.size.toSize(tileGrid.getTileSize(tileCoord[0]), this.tmpSize);
- var gutter = this.gutter_;
- if (gutter !== 0) {
- tileSize = ol.size.buffer(tileSize, gutter, this.tmpSize);
- tileExtent = ol.extent.buffer(tileExtent, tileResolution * gutter, tileExtent);
- }
- if (sourceProjectionObj && sourceProjectionObj !== projectionObj) {
- tileResolution = ol.reproj.calculateSourceResolution(sourceProjectionObj, projectionObj, coordinate, tileResolution);
- tileExtent = ol.proj.transformExtent(tileExtent, projectionObj, sourceProjectionObj);
- coordinate = ol.proj.transform(coordinate, projectionObj, sourceProjectionObj);
- }
- var baseParams = {
- 'SERVICE': 'WMS',
- 'VERSION': ol.DEFAULT_WMS_VERSION,
- 'REQUEST': 'GetFeatureInfo',
- 'FORMAT': 'image/png',
- 'TRANSPARENT': true,
- 'QUERY_LAYERS': this.params_['LAYERS']
- };
- ol.obj.assign(baseParams, this.params_, params);
- var x = Math.floor((coordinate[0] - tileExtent[0]) / tileResolution);
- var y = Math.floor((tileExtent[3] - coordinate[1]) / tileResolution);
- baseParams[this.v13_ ? 'I' : 'X'] = x;
- baseParams[this.v13_ ? 'J' : 'Y'] = y;
- return this.getRequestUrl_(tileCoord, tileSize, tileExtent,
- 1, sourceProjectionObj || projectionObj, baseParams);
- };
- /**
- * @inheritDoc
- */
- ol.source.TileWMS.prototype.getGutterInternal = function() {
- return this.gutter_;
- };
- /**
- * Get the user-provided params, i.e. those passed to the constructor through
- * the "params" option, and possibly updated using the updateParams method.
- * @return {Object} Params.
- * @api
- */
- ol.source.TileWMS.prototype.getParams = function() {
- return this.params_;
- };
- /**
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {ol.Size} tileSize Tile size.
- * @param {ol.Extent} tileExtent Tile extent.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.proj.Projection} projection Projection.
- * @param {Object} params Params.
- * @return {string|undefined} Request URL.
- * @private
- */
- ol.source.TileWMS.prototype.getRequestUrl_ = function(tileCoord, tileSize, tileExtent,
- pixelRatio, projection, params) {
- var urls = this.urls;
- if (!urls) {
- return undefined;
- }
- params['WIDTH'] = tileSize[0];
- params['HEIGHT'] = tileSize[1];
- params[this.v13_ ? 'CRS' : 'SRS'] = projection.getCode();
- if (!('STYLES' in this.params_)) {
- params['STYLES'] = '';
- }
- if (pixelRatio != 1) {
- switch (this.serverType_) {
- case ol.source.WMSServerType.GEOSERVER:
- var dpi = (90 * pixelRatio + 0.5) | 0;
- if ('FORMAT_OPTIONS' in params) {
- params['FORMAT_OPTIONS'] += ';dpi:' + dpi;
- } else {
- params['FORMAT_OPTIONS'] = 'dpi:' + dpi;
- }
- break;
- case ol.source.WMSServerType.MAPSERVER:
- params['MAP_RESOLUTION'] = 90 * pixelRatio;
- break;
- case ol.source.WMSServerType.CARMENTA_SERVER:
- case ol.source.WMSServerType.QGIS:
- params['DPI'] = 90 * pixelRatio;
- break;
- default:
- ol.asserts.assert(false, 52); // Unknown `serverType` configured
- break;
- }
- }
- var axisOrientation = projection.getAxisOrientation();
- var bbox = tileExtent;
- if (this.v13_ && axisOrientation.substr(0, 2) == 'ne') {
- var tmp;
- tmp = tileExtent[0];
- bbox[0] = tileExtent[1];
- bbox[1] = tmp;
- tmp = tileExtent[2];
- bbox[2] = tileExtent[3];
- bbox[3] = tmp;
- }
- params['BBOX'] = bbox.join(',');
- var url;
- if (urls.length == 1) {
- url = urls[0];
- } else {
- var index = ol.math.modulo(ol.tilecoord.hash(tileCoord), urls.length);
- url = urls[index];
- }
- return ol.uri.appendParams(url, params);
- };
- /**
- * @inheritDoc
- */
- ol.source.TileWMS.prototype.getTilePixelRatio = function(pixelRatio) {
- return (!this.hidpi_ || this.serverType_ === undefined) ? 1 :
- /** @type {number} */ (pixelRatio);
- };
- /**
- * @private
- * @return {string} The key for the current params.
- */
- ol.source.TileWMS.prototype.getKeyForParams_ = function() {
- var i = 0;
- var res = [];
- for (var key in this.params_) {
- res[i++] = key + '-' + this.params_[key];
- }
- return res.join('/');
- };
- /**
- * @inheritDoc
- */
- ol.source.TileWMS.prototype.fixedTileUrlFunction = function(tileCoord, pixelRatio, projection) {
- var tileGrid = this.getTileGrid();
- if (!tileGrid) {
- tileGrid = this.getTileGridForProjection(projection);
- }
- if (tileGrid.getResolutions().length <= tileCoord[0]) {
- return undefined;
- }
- if (pixelRatio != 1 && (!this.hidpi_ || this.serverType_ === undefined)) {
- pixelRatio = 1;
- }
- var tileResolution = tileGrid.getResolution(tileCoord[0]);
- var tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent_);
- var tileSize = ol.size.toSize(
- tileGrid.getTileSize(tileCoord[0]), this.tmpSize);
- var gutter = this.gutter_;
- if (gutter !== 0) {
- tileSize = ol.size.buffer(tileSize, gutter, this.tmpSize);
- tileExtent = ol.extent.buffer(tileExtent,
- tileResolution * gutter, tileExtent);
- }
- if (pixelRatio != 1) {
- tileSize = ol.size.scale(tileSize, pixelRatio, this.tmpSize);
- }
- var baseParams = {
- 'SERVICE': 'WMS',
- 'VERSION': ol.DEFAULT_WMS_VERSION,
- 'REQUEST': 'GetMap',
- 'FORMAT': 'image/png',
- 'TRANSPARENT': true
- };
- ol.obj.assign(baseParams, this.params_);
- return this.getRequestUrl_(tileCoord, tileSize, tileExtent,
- pixelRatio, projection, baseParams);
- };
- /**
- * Update the user-provided params.
- * @param {Object} params Params.
- * @api
- */
- ol.source.TileWMS.prototype.updateParams = function(params) {
- ol.obj.assign(this.params_, params);
- this.updateV13_();
- this.setKey(this.getKeyForParams_());
- };
- /**
- * @private
- */
- ol.source.TileWMS.prototype.updateV13_ = function() {
- var version = this.params_['VERSION'] || ol.DEFAULT_WMS_VERSION;
- this.v13_ = ol.string.compareVersions(version, '1.3') >= 0;
- };
- goog.provide('ol.VectorImageTile');
- goog.require('ol');
- goog.require('ol.Tile');
- goog.require('ol.TileState');
- goog.require('ol.dom');
- goog.require('ol.events');
- goog.require('ol.extent');
- goog.require('ol.events.EventType');
- goog.require('ol.featureloader');
- /**
- * @constructor
- * @extends {ol.Tile}
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {ol.TileState} state State.
- * @param {number} sourceRevision Source revision.
- * @param {ol.format.Feature} format Feature format.
- * @param {ol.TileLoadFunctionType} tileLoadFunction Tile load function.
- * @param {ol.TileCoord} urlTileCoord Wrapped tile coordinate for source urls.
- * @param {ol.TileUrlFunctionType} tileUrlFunction Tile url function.
- * @param {ol.tilegrid.TileGrid} sourceTileGrid Tile grid of the source.
- * @param {ol.tilegrid.TileGrid} tileGrid Tile grid of the renderer.
- * @param {Object.<string,ol.VectorTile>} sourceTiles Source tiles.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.proj.Projection} projection Projection.
- * @param {function(new: ol.VectorTile, ol.TileCoord, ol.TileState, string,
- * ol.format.Feature, ol.TileLoadFunctionType)} tileClass Class to
- * instantiate for source tiles.
- * @param {function(this: ol.source.VectorTile, ol.events.Event)} handleTileChange
- * Function to call when a source tile's state changes.
- * @param {olx.TileOptions=} opt_options Tile options.
- */
- ol.VectorImageTile = function(tileCoord, state, sourceRevision, format,
- tileLoadFunction, urlTileCoord, tileUrlFunction, sourceTileGrid, tileGrid,
- sourceTiles, pixelRatio, projection, tileClass, handleTileChange, opt_options) {
- ol.Tile.call(this, tileCoord, state, opt_options);
- /**
- * @private
- * @type {Object.<string, CanvasRenderingContext2D>}
- */
- this.context_ = {};
- /**
- * @private
- * @type {ol.FeatureLoader}
- */
- this.loader_;
- /**
- * @private
- * @type {Object.<string, ol.TileReplayState>}
- */
- this.replayState_ = {};
- /**
- * @private
- * @type {Object.<string,ol.VectorTile>}
- */
- this.sourceTiles_ = sourceTiles;
- /**
- * Keys of source tiles used by this tile. Use with {@link #getTile}.
- * @type {Array.<string>}
- */
- this.tileKeys = [];
- /**
- * @type {number}
- */
- this.sourceRevision_ = sourceRevision;
- /**
- * @type {ol.TileCoord}
- */
- this.wrappedTileCoord = urlTileCoord;
- /**
- * @type {Array.<ol.EventsKey>}
- */
- this.loadListenerKeys_ = [];
- /**
- * @type {Array.<ol.EventsKey>}
- */
- this.sourceTileListenerKeys_ = [];
- if (urlTileCoord) {
- var extent = tileGrid.getTileCoordExtent(urlTileCoord);
- var resolution = tileGrid.getResolution(tileCoord[0]);
- var sourceZ = sourceTileGrid.getZForResolution(resolution);
- sourceTileGrid.forEachTileCoord(extent, sourceZ, function(sourceTileCoord) {
- var sharedExtent = ol.extent.getIntersection(extent,
- sourceTileGrid.getTileCoordExtent(sourceTileCoord));
- var sourceExtent = sourceTileGrid.getExtent();
- if (sourceExtent) {
- sharedExtent = ol.extent.getIntersection(sharedExtent, sourceExtent);
- }
- if (ol.extent.getWidth(sharedExtent) / resolution >= 0.5 &&
- ol.extent.getHeight(sharedExtent) / resolution >= 0.5) {
- // only include source tile if overlap is at least 1 pixel
- var sourceTileKey = sourceTileCoord.toString();
- var sourceTile = sourceTiles[sourceTileKey];
- if (!sourceTile) {
- var tileUrl = tileUrlFunction(sourceTileCoord, pixelRatio, projection);
- sourceTile = sourceTiles[sourceTileKey] = new tileClass(sourceTileCoord,
- tileUrl == undefined ? ol.TileState.EMPTY : ol.TileState.IDLE,
- tileUrl == undefined ? '' : tileUrl,
- format, tileLoadFunction);
- this.sourceTileListenerKeys_.push(
- ol.events.listen(sourceTile, ol.events.EventType.CHANGE, handleTileChange));
- }
- sourceTile.consumers++;
- this.tileKeys.push(sourceTileKey);
- }
- }.bind(this));
- }
- };
- ol.inherits(ol.VectorImageTile, ol.Tile);
- /**
- * @inheritDoc
- */
- ol.VectorImageTile.prototype.disposeInternal = function() {
- for (var i = 0, ii = this.tileKeys.length; i < ii; ++i) {
- var sourceTileKey = this.tileKeys[i];
- var sourceTile = this.getTile(sourceTileKey);
- sourceTile.consumers--;
- if (sourceTile.consumers == 0) {
- delete this.sourceTiles_[sourceTileKey];
- sourceTile.dispose();
- }
- }
- this.tileKeys.length = 0;
- this.sourceTiles_ = null;
- this.loadListenerKeys_.forEach(ol.events.unlistenByKey);
- this.loadListenerKeys_.length = 0;
- if (this.interimTile) {
- this.interimTile.dispose();
- }
- this.state = ol.TileState.ABORT;
- this.changed();
- this.sourceTileListenerKeys_.forEach(ol.events.unlistenByKey);
- this.sourceTileListenerKeys_.length = 0;
- ol.Tile.prototype.disposeInternal.call(this);
- };
- /**
- * @param {ol.layer.Layer} layer Layer.
- * @return {CanvasRenderingContext2D} The rendering context.
- */
- ol.VectorImageTile.prototype.getContext = function(layer) {
- var key = ol.getUid(layer).toString();
- if (!(key in this.context_)) {
- this.context_[key] = ol.dom.createCanvasContext2D();
- }
- return this.context_[key];
- };
- /**
- * Get the Canvas for this tile.
- * @param {ol.layer.Layer} layer Layer.
- * @return {HTMLCanvasElement} Canvas.
- */
- ol.VectorImageTile.prototype.getImage = function(layer) {
- return this.getReplayState(layer).renderedTileRevision == -1 ?
- null : this.getContext(layer).canvas;
- };
- /**
- * @param {ol.layer.Layer} layer Layer.
- * @return {ol.TileReplayState} The replay state.
- */
- ol.VectorImageTile.prototype.getReplayState = function(layer) {
- var key = ol.getUid(layer).toString();
- if (!(key in this.replayState_)) {
- this.replayState_[key] = {
- dirty: false,
- renderedRenderOrder: null,
- renderedRevision: -1,
- renderedTileRevision: -1
- };
- }
- return this.replayState_[key];
- };
- /**
- * @inheritDoc
- */
- ol.VectorImageTile.prototype.getKey = function() {
- return this.tileKeys.join('/') + '-' + this.sourceRevision_;
- };
- /**
- * @param {string} tileKey Key (tileCoord) of the source tile.
- * @return {ol.VectorTile} Source tile.
- */
- ol.VectorImageTile.prototype.getTile = function(tileKey) {
- return this.sourceTiles_[tileKey];
- };
- /**
- * @inheritDoc
- */
- ol.VectorImageTile.prototype.load = function() {
- // Source tiles with LOADED state - we just count them because once they are
- // loaded, we're no longer listening to state changes.
- var leftToLoad = 0;
- // Source tiles with ERROR state - we track them because they can still have
- // an ERROR state after another load attempt.
- var errorSourceTiles = {};
- if (this.state == ol.TileState.IDLE) {
- this.setState(ol.TileState.LOADING);
- }
- if (this.state == ol.TileState.LOADING) {
- this.tileKeys.forEach(function(sourceTileKey) {
- var sourceTile = this.getTile(sourceTileKey);
- if (sourceTile.state == ol.TileState.IDLE) {
- sourceTile.setLoader(this.loader_);
- sourceTile.load();
- }
- if (sourceTile.state == ol.TileState.LOADING) {
- var key = ol.events.listen(sourceTile, ol.events.EventType.CHANGE, function(e) {
- var state = sourceTile.getState();
- if (state == ol.TileState.LOADED ||
- state == ol.TileState.ERROR) {
- var uid = ol.getUid(sourceTile);
- if (state == ol.TileState.ERROR) {
- errorSourceTiles[uid] = true;
- } else {
- --leftToLoad;
- delete errorSourceTiles[uid];
- }
- if (leftToLoad - Object.keys(errorSourceTiles).length == 0) {
- this.finishLoading_();
- }
- }
- }.bind(this));
- this.loadListenerKeys_.push(key);
- ++leftToLoad;
- }
- }.bind(this));
- }
- if (leftToLoad - Object.keys(errorSourceTiles).length == 0) {
- setTimeout(this.finishLoading_.bind(this), 0);
- }
- };
- /**
- * @private
- */
- ol.VectorImageTile.prototype.finishLoading_ = function() {
- var loaded = this.tileKeys.length;
- var empty = 0;
- for (var i = loaded - 1; i >= 0; --i) {
- var state = this.getTile(this.tileKeys[i]).getState();
- if (state != ol.TileState.LOADED) {
- --loaded;
- }
- if (state == ol.TileState.EMPTY) {
- ++empty;
- }
- }
- if (loaded == this.tileKeys.length) {
- this.loadListenerKeys_.forEach(ol.events.unlistenByKey);
- this.loadListenerKeys_.length = 0;
- this.setState(ol.TileState.LOADED);
- } else {
- this.setState(empty == this.tileKeys.length ? ol.TileState.EMPTY : ol.TileState.ERROR);
- }
- };
- /**
- * Sets the loader for a tile.
- * @param {ol.VectorTile} tile Vector tile.
- * @param {string} url URL.
- */
- ol.VectorImageTile.defaultLoadFunction = function(tile, url) {
- var loader = ol.featureloader.loadFeaturesXhr(
- url, tile.getFormat(), tile.onLoad.bind(tile), tile.onError.bind(tile));
- tile.setLoader(loader);
- };
- goog.provide('ol.VectorTile');
- goog.require('ol');
- goog.require('ol.Tile');
- goog.require('ol.TileState');
- /**
- * @constructor
- * @extends {ol.Tile}
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {ol.TileState} state State.
- * @param {string} src Data source url.
- * @param {ol.format.Feature} format Feature format.
- * @param {ol.TileLoadFunctionType} tileLoadFunction Tile load function.
- * @param {olx.TileOptions=} opt_options Tile options.
- */
- ol.VectorTile = function(tileCoord, state, src, format, tileLoadFunction, opt_options) {
- ol.Tile.call(this, tileCoord, state, opt_options);
- /**
- * @type {number}
- */
- this.consumers = 0;
- /**
- * @private
- * @type {ol.Extent}
- */
- this.extent_ = null;
- /**
- * @private
- * @type {ol.format.Feature}
- */
- this.format_ = format;
- /**
- * @private
- * @type {Array.<ol.Feature>}
- */
- this.features_ = null;
- /**
- * @private
- * @type {ol.FeatureLoader}
- */
- this.loader_;
- /**
- * Data projection
- * @private
- * @type {ol.proj.Projection}
- */
- this.projection_;
- /**
- * @private
- * @type {Object.<string, ol.render.ReplayGroup>}
- */
- this.replayGroups_ = {};
- /**
- * @private
- * @type {ol.TileLoadFunctionType}
- */
- this.tileLoadFunction_ = tileLoadFunction;
- /**
- * @private
- * @type {string}
- */
- this.url_ = src;
- };
- ol.inherits(ol.VectorTile, ol.Tile);
- /**
- * @inheritDoc
- */
- ol.VectorTile.prototype.disposeInternal = function() {
- this.features_ = null;
- this.replayGroups_ = {};
- this.state = ol.TileState.ABORT;
- this.changed();
- ol.Tile.prototype.disposeInternal.call(this);
- };
- /**
- * Gets the extent of the vector tile.
- * @return {ol.Extent} The extent.
- * @api
- */
- ol.VectorTile.prototype.getExtent = function() {
- return this.extent_ || ol.VectorTile.DEFAULT_EXTENT;
- };
- /**
- * Get the feature format assigned for reading this tile's features.
- * @return {ol.format.Feature} Feature format.
- * @api
- */
- ol.VectorTile.prototype.getFormat = function() {
- return this.format_;
- };
- /**
- * Get the features for this tile. Geometries will be in the projection returned
- * by {@link ol.VectorTile#getProjection}.
- * @return {Array.<ol.Feature|ol.render.Feature>} Features.
- * @api
- */
- ol.VectorTile.prototype.getFeatures = function() {
- return this.features_;
- };
- /**
- * @inheritDoc
- */
- ol.VectorTile.prototype.getKey = function() {
- return this.url_;
- };
- /**
- * Get the feature projection of features returned by
- * {@link ol.VectorTile#getFeatures}.
- * @return {ol.proj.Projection} Feature projection.
- * @api
- */
- ol.VectorTile.prototype.getProjection = function() {
- return this.projection_;
- };
- /**
- * @param {ol.layer.Layer} layer Layer.
- * @param {string} key Key.
- * @return {ol.render.ReplayGroup} Replay group.
- */
- ol.VectorTile.prototype.getReplayGroup = function(layer, key) {
- return this.replayGroups_[ol.getUid(layer) + ',' + key];
- };
- /**
- * @inheritDoc
- */
- ol.VectorTile.prototype.load = function() {
- if (this.state == ol.TileState.IDLE) {
- this.setState(ol.TileState.LOADING);
- this.tileLoadFunction_(this, this.url_);
- this.loader_(null, NaN, null);
- }
- };
- /**
- * Handler for successful tile load.
- * @param {Array.<ol.Feature>} features The loaded features.
- * @param {ol.proj.Projection} dataProjection Data projection.
- * @param {ol.Extent} extent Extent.
- */
- ol.VectorTile.prototype.onLoad = function(features, dataProjection, extent) {
- this.setProjection(dataProjection);
- this.setFeatures(features);
- this.setExtent(extent);
- };
- /**
- * Handler for tile load errors.
- */
- ol.VectorTile.prototype.onError = function() {
- this.setState(ol.TileState.ERROR);
- };
- /**
- * Function for use in an {@link ol.source.VectorTile}'s `tileLoadFunction`.
- * Sets the extent of the vector tile. This is only required for tiles in
- * projections with `tile-pixels` as units. The extent should be set to
- * `[0, 0, tilePixelSize, tilePixelSize]`, where `tilePixelSize` is calculated
- * by multiplying the tile size with the tile pixel ratio. For sources using
- * {@link ol.format.MVT} as feature format, the
- * {@link ol.format.MVT#getLastExtent} method will return the correct extent.
- * The default is `[0, 0, 4096, 4096]`.
- * @param {ol.Extent} extent The extent.
- * @api
- */
- ol.VectorTile.prototype.setExtent = function(extent) {
- this.extent_ = extent;
- };
- /**
- * Function for use in an {@link ol.source.VectorTile}'s `tileLoadFunction`.
- * Sets the features for the tile.
- * @param {Array.<ol.Feature>} features Features.
- * @api
- */
- ol.VectorTile.prototype.setFeatures = function(features) {
- this.features_ = features;
- this.setState(ol.TileState.LOADED);
- };
- /**
- * Function for use in an {@link ol.source.VectorTile}'s `tileLoadFunction`.
- * Sets the projection of the features that were added with
- * {@link ol.VectorTile#setFeatures}.
- * @param {ol.proj.Projection} projection Feature projection.
- * @api
- */
- ol.VectorTile.prototype.setProjection = function(projection) {
- this.projection_ = projection;
- };
- /**
- * @param {ol.layer.Layer} layer Layer.
- * @param {string} key Key.
- * @param {ol.render.ReplayGroup} replayGroup Replay group.
- */
- ol.VectorTile.prototype.setReplayGroup = function(layer, key, replayGroup) {
- this.replayGroups_[ol.getUid(layer) + ',' + key] = replayGroup;
- };
- /**
- * Set the feature loader for reading this tile's features.
- * @param {ol.FeatureLoader} loader Feature loader.
- * @api
- */
- ol.VectorTile.prototype.setLoader = function(loader) {
- this.loader_ = loader;
- };
- /**
- * @const
- * @type {ol.Extent}
- */
- ol.VectorTile.DEFAULT_EXTENT = [0, 0, 4096, 4096];
- goog.provide('ol.source.VectorTile');
- goog.require('ol');
- goog.require('ol.TileState');
- goog.require('ol.VectorImageTile');
- goog.require('ol.VectorTile');
- goog.require('ol.size');
- goog.require('ol.source.UrlTile');
- goog.require('ol.tilecoord');
- goog.require('ol.tilegrid');
- /**
- * @classdesc
- * Class for layer sources providing vector data divided into a tile grid, to be
- * used with {@link ol.layer.VectorTile}. Although this source receives tiles
- * with vector features from the server, it is not meant for feature editing.
- * Features are optimized for rendering, their geometries are clipped at or near
- * tile boundaries and simplified for a view resolution. See
- * {@link ol.source.Vector} for vector sources that are suitable for feature
- * editing.
- *
- * @constructor
- * @fires ol.source.Tile.Event
- * @extends {ol.source.UrlTile}
- * @param {olx.source.VectorTileOptions} options Vector tile options.
- * @api
- */
- ol.source.VectorTile = function(options) {
- var projection = options.projection || 'EPSG:3857';
- var extent = options.extent || ol.tilegrid.extentFromProjection(projection);
- var tileGrid = options.tileGrid || ol.tilegrid.createXYZ({
- extent: extent,
- maxZoom: options.maxZoom || 22,
- minZoom: options.minZoom,
- tileSize: options.tileSize || 512
- });
- ol.source.UrlTile.call(this, {
- attributions: options.attributions,
- cacheSize: options.cacheSize !== undefined ? options.cacheSize : 128,
- extent: extent,
- logo: options.logo,
- opaque: false,
- projection: projection,
- state: options.state,
- tileGrid: tileGrid,
- tileLoadFunction: options.tileLoadFunction ?
- options.tileLoadFunction : ol.VectorImageTile.defaultLoadFunction,
- tileUrlFunction: options.tileUrlFunction,
- url: options.url,
- urls: options.urls,
- wrapX: options.wrapX === undefined ? true : options.wrapX,
- transition: options.transition
- });
- /**
- * @private
- * @type {ol.format.Feature}
- */
- this.format_ = options.format ? options.format : null;
- /**
- * @private
- * @type {Object.<string,ol.VectorTile>}
- */
- this.sourceTiles_ = {};
- /**
- * @private
- * @type {boolean}
- */
- this.overlaps_ = options.overlaps == undefined ? true : options.overlaps;
- /**
- * @protected
- * @type {function(new: ol.VectorTile, ol.TileCoord, ol.TileState, string,
- * ol.format.Feature, ol.TileLoadFunctionType)}
- */
- this.tileClass = options.tileClass ? options.tileClass : ol.VectorTile;
- /**
- * @private
- * @type {Object.<string,ol.tilegrid.TileGrid>}
- */
- this.tileGrids_ = {};
- };
- ol.inherits(ol.source.VectorTile, ol.source.UrlTile);
- /**
- * @return {boolean} The source can have overlapping geometries.
- */
- ol.source.VectorTile.prototype.getOverlaps = function() {
- return this.overlaps_;
- };
- /**
- * clear {@link ol.TileCache} and delete all source tiles
- * @api
- */
- ol.source.VectorTile.prototype.clear = function() {
- this.tileCache.clear();
- this.sourceTiles_ = {};
- };
- /**
- * @inheritDoc
- */
- ol.source.VectorTile.prototype.getTile = function(z, x, y, pixelRatio, projection) {
- var tileCoordKey = ol.tilecoord.getKeyZXY(z, x, y);
- if (this.tileCache.containsKey(tileCoordKey)) {
- return /** @type {!ol.Tile} */ (this.tileCache.get(tileCoordKey));
- } else {
- var tileCoord = [z, x, y];
- var urlTileCoord = this.getTileCoordForTileUrlFunction(
- tileCoord, projection);
- var tile = new ol.VectorImageTile(
- tileCoord,
- urlTileCoord !== null ? ol.TileState.IDLE : ol.TileState.EMPTY,
- this.getRevision(),
- this.format_, this.tileLoadFunction, urlTileCoord, this.tileUrlFunction,
- this.tileGrid, this.getTileGridForProjection(projection),
- this.sourceTiles_, pixelRatio, projection, this.tileClass,
- this.handleTileChange.bind(this),
- this.tileOptions);
- this.tileCache.set(tileCoordKey, tile);
- return tile;
- }
- };
- /**
- * @inheritDoc
- */
- ol.source.VectorTile.prototype.getTileGridForProjection = function(projection) {
- var code = projection.getCode();
- var tileGrid = this.tileGrids_[code];
- if (!tileGrid) {
- // A tile grid that matches the tile size of the source tile grid is more
- // likely to have 1:1 relationships between source tiles and rendered tiles.
- var sourceTileGrid = this.tileGrid;
- tileGrid = this.tileGrids_[code] = ol.tilegrid.createForProjection(projection, undefined,
- sourceTileGrid ? sourceTileGrid.getTileSize(sourceTileGrid.getMinZoom()) : undefined);
- }
- return tileGrid;
- };
- /**
- * @inheritDoc
- */
- ol.source.VectorTile.prototype.getTilePixelRatio = function(pixelRatio) {
- return pixelRatio;
- };
- /**
- * @inheritDoc
- */
- ol.source.VectorTile.prototype.getTilePixelSize = function(z, pixelRatio, projection) {
- var tileSize = ol.size.toSize(this.getTileGridForProjection(projection).getTileSize(z));
- return [Math.round(tileSize[0] * pixelRatio), Math.round(tileSize[1] * pixelRatio)];
- };
- goog.provide('ol.source.WMTSRequestEncoding');
- /**
- * Request encoding. One of 'KVP', 'REST'.
- * @enum {string}
- */
- ol.source.WMTSRequestEncoding = {
- KVP: 'KVP', // see spec §8
- REST: 'REST' // see spec §10
- };
- goog.provide('ol.tilegrid.WMTS');
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.proj');
- goog.require('ol.tilegrid.TileGrid');
- /**
- * @classdesc
- * Set the grid pattern for sources accessing WMTS tiled-image servers.
- *
- * @constructor
- * @extends {ol.tilegrid.TileGrid}
- * @param {olx.tilegrid.WMTSOptions} options WMTS options.
- * @struct
- * @api
- */
- ol.tilegrid.WMTS = function(options) {
- /**
- * @private
- * @type {!Array.<string>}
- */
- this.matrixIds_ = options.matrixIds;
- // FIXME: should the matrixIds become optional?
- ol.tilegrid.TileGrid.call(this, {
- extent: options.extent,
- origin: options.origin,
- origins: options.origins,
- resolutions: options.resolutions,
- tileSize: options.tileSize,
- tileSizes: options.tileSizes,
- sizes: options.sizes
- });
- };
- ol.inherits(ol.tilegrid.WMTS, ol.tilegrid.TileGrid);
- /**
- * @param {number} z Z.
- * @return {string} MatrixId..
- */
- ol.tilegrid.WMTS.prototype.getMatrixId = function(z) {
- return this.matrixIds_[z];
- };
- /**
- * Get the list of matrix identifiers.
- * @return {Array.<string>} MatrixIds.
- * @api
- */
- ol.tilegrid.WMTS.prototype.getMatrixIds = function() {
- return this.matrixIds_;
- };
- /**
- * Create a tile grid from a WMTS capabilities matrix set and an
- * optional TileMatrixSetLimits.
- * @param {Object} matrixSet An object representing a matrixSet in the
- * capabilities document.
- * @param {ol.Extent=} opt_extent An optional extent to restrict the tile
- * ranges the server provides.
- * @param {Array.<Object>=} opt_matrixLimits An optional object representing
- * the available matrices for tileGrid.
- * @return {ol.tilegrid.WMTS} WMTS tileGrid instance.
- * @api
- */
- ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet = function(matrixSet, opt_extent,
- opt_matrixLimits) {
- /** @type {!Array.<number>} */
- var resolutions = [];
- /** @type {!Array.<string>} */
- var matrixIds = [];
- /** @type {!Array.<ol.Coordinate>} */
- var origins = [];
- /** @type {!Array.<ol.Size>} */
- var tileSizes = [];
- /** @type {!Array.<ol.Size>} */
- var sizes = [];
- var matrixLimits = opt_matrixLimits !== undefined ? opt_matrixLimits : [];
- var supportedCRSPropName = 'SupportedCRS';
- var matrixIdsPropName = 'TileMatrix';
- var identifierPropName = 'Identifier';
- var scaleDenominatorPropName = 'ScaleDenominator';
- var topLeftCornerPropName = 'TopLeftCorner';
- var tileWidthPropName = 'TileWidth';
- var tileHeightPropName = 'TileHeight';
- var code = matrixSet[supportedCRSPropName];
- var projection = ol.proj.get(code.replace(/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/, '$1:$3')) ||
- ol.proj.get(code);
- var metersPerUnit = projection.getMetersPerUnit();
- // swap origin x and y coordinates if axis orientation is lat/long
- var switchOriginXY = projection.getAxisOrientation().substr(0, 2) == 'ne';
- matrixSet[matrixIdsPropName].sort(function(a, b) {
- return b[scaleDenominatorPropName] - a[scaleDenominatorPropName];
- });
- matrixSet[matrixIdsPropName].forEach(function(elt, index, array) {
- var matrixAvailable;
- // use of matrixLimits to filter TileMatrices from GetCapabilities
- // TileMatrixSet from unavailable matrix levels.
- if (matrixLimits.length > 0) {
- matrixAvailable = ol.array.find(matrixLimits,
- function(elt_ml, index_ml, array_ml) {
- return elt[identifierPropName] == elt_ml[matrixIdsPropName];
- });
- } else {
- matrixAvailable = true;
- }
- if (matrixAvailable) {
- matrixIds.push(elt[identifierPropName]);
- var resolution = elt[scaleDenominatorPropName] * 0.28E-3 / metersPerUnit;
- var tileWidth = elt[tileWidthPropName];
- var tileHeight = elt[tileHeightPropName];
- if (switchOriginXY) {
- origins.push([elt[topLeftCornerPropName][1],
- elt[topLeftCornerPropName][0]]);
- } else {
- origins.push(elt[topLeftCornerPropName]);
- }
- resolutions.push(resolution);
- tileSizes.push(tileWidth == tileHeight ?
- tileWidth : [tileWidth, tileHeight]);
- // top-left origin, so height is negative
- sizes.push([elt['MatrixWidth'], -elt['MatrixHeight']]);
- }
- });
- return new ol.tilegrid.WMTS({
- extent: opt_extent,
- origins: origins,
- resolutions: resolutions,
- matrixIds: matrixIds,
- tileSizes: tileSizes,
- sizes: sizes
- });
- };
- goog.provide('ol.source.WMTS');
- goog.require('ol');
- goog.require('ol.TileUrlFunction');
- goog.require('ol.array');
- goog.require('ol.extent');
- goog.require('ol.obj');
- goog.require('ol.proj');
- goog.require('ol.source.TileImage');
- goog.require('ol.source.WMTSRequestEncoding');
- goog.require('ol.tilegrid.WMTS');
- goog.require('ol.uri');
- /**
- * @classdesc
- * Layer source for tile data from WMTS servers.
- *
- * @constructor
- * @extends {ol.source.TileImage}
- * @param {olx.source.WMTSOptions} options WMTS options.
- * @api
- */
- ol.source.WMTS = function(options) {
- // TODO: add support for TileMatrixLimits
- /**
- * @private
- * @type {string}
- */
- this.version_ = options.version !== undefined ? options.version : '1.0.0';
- /**
- * @private
- * @type {string}
- */
- this.format_ = options.format !== undefined ? options.format : 'image/jpeg';
- /**
- * @private
- * @type {!Object}
- */
- this.dimensions_ = options.dimensions !== undefined ? options.dimensions : {};
- /**
- * @private
- * @type {string}
- */
- this.layer_ = options.layer;
- /**
- * @private
- * @type {string}
- */
- this.matrixSet_ = options.matrixSet;
- /**
- * @private
- * @type {string}
- */
- this.style_ = options.style;
- var urls = options.urls;
- if (urls === undefined && options.url !== undefined) {
- urls = ol.TileUrlFunction.expandUrl(options.url);
- }
- // FIXME: should we guess this requestEncoding from options.url(s)
- // structure? that would mean KVP only if a template is not provided.
- /**
- * @private
- * @type {ol.source.WMTSRequestEncoding}
- */
- this.requestEncoding_ = options.requestEncoding !== undefined ?
- /** @type {ol.source.WMTSRequestEncoding} */ (options.requestEncoding) :
- ol.source.WMTSRequestEncoding.KVP;
- var requestEncoding = this.requestEncoding_;
- // FIXME: should we create a default tileGrid?
- // we could issue a getCapabilities xhr to retrieve missing configuration
- var tileGrid = options.tileGrid;
- // context property names are lower case to allow for a case insensitive
- // replacement as some services use different naming conventions
- var context = {
- 'layer': this.layer_,
- 'style': this.style_,
- 'tilematrixset': this.matrixSet_
- };
- if (requestEncoding == ol.source.WMTSRequestEncoding.KVP) {
- ol.obj.assign(context, {
- 'Service': 'WMTS',
- 'Request': 'GetTile',
- 'Version': this.version_,
- 'Format': this.format_
- });
- }
- var dimensions = this.dimensions_;
- /**
- * @param {string} template Template.
- * @return {ol.TileUrlFunctionType} Tile URL function.
- * @private
- */
- this.createFromWMTSTemplate_ = function(template) {
- // TODO: we may want to create our own appendParams function so that params
- // order conforms to wmts spec guidance, and so that we can avoid to escape
- // special template params
- template = (requestEncoding == ol.source.WMTSRequestEncoding.KVP) ?
- ol.uri.appendParams(template, context) :
- template.replace(/\{(\w+?)\}/g, function(m, p) {
- return (p.toLowerCase() in context) ? context[p.toLowerCase()] : m;
- });
- return (
- /**
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.proj.Projection} projection Projection.
- * @return {string|undefined} Tile URL.
- */
- function(tileCoord, pixelRatio, projection) {
- if (!tileCoord) {
- return undefined;
- } else {
- var localContext = {
- 'TileMatrix': tileGrid.getMatrixId(tileCoord[0]),
- 'TileCol': tileCoord[1],
- 'TileRow': -tileCoord[2] - 1
- };
- ol.obj.assign(localContext, dimensions);
- var url = template;
- if (requestEncoding == ol.source.WMTSRequestEncoding.KVP) {
- url = ol.uri.appendParams(url, localContext);
- } else {
- url = url.replace(/\{(\w+?)\}/g, function(m, p) {
- return localContext[p];
- });
- }
- return url;
- }
- });
- };
- var tileUrlFunction = (urls && urls.length > 0) ?
- ol.TileUrlFunction.createFromTileUrlFunctions(
- urls.map(this.createFromWMTSTemplate_)) :
- ol.TileUrlFunction.nullTileUrlFunction;
- ol.source.TileImage.call(this, {
- attributions: options.attributions,
- cacheSize: options.cacheSize,
- crossOrigin: options.crossOrigin,
- logo: options.logo,
- projection: options.projection,
- reprojectionErrorThreshold: options.reprojectionErrorThreshold,
- tileClass: options.tileClass,
- tileGrid: tileGrid,
- tileLoadFunction: options.tileLoadFunction,
- tilePixelRatio: options.tilePixelRatio,
- tileUrlFunction: tileUrlFunction,
- urls: urls,
- wrapX: options.wrapX !== undefined ? options.wrapX : false,
- transition: options.transition
- });
- this.setKey(this.getKeyForDimensions_());
- };
- ol.inherits(ol.source.WMTS, ol.source.TileImage);
- /**
- * Set the URLs to use for requests.
- * URLs may contain OCG conform URL Template Variables: {TileMatrix}, {TileRow}, {TileCol}.
- * @override
- */
- ol.source.WMTS.prototype.setUrls = function(urls) {
- this.urls = urls;
- var key = urls.join('\n');
- this.setTileUrlFunction(this.fixedTileUrlFunction ?
- this.fixedTileUrlFunction.bind(this) :
- ol.TileUrlFunction.createFromTileUrlFunctions(urls.map(this.createFromWMTSTemplate_.bind(this))), key);
- };
- /**
- * Get the dimensions, i.e. those passed to the constructor through the
- * "dimensions" option, and possibly updated using the updateDimensions
- * method.
- * @return {!Object} Dimensions.
- * @api
- */
- ol.source.WMTS.prototype.getDimensions = function() {
- return this.dimensions_;
- };
- /**
- * Return the image format of the WMTS source.
- * @return {string} Format.
- * @api
- */
- ol.source.WMTS.prototype.getFormat = function() {
- return this.format_;
- };
- /**
- * Return the layer of the WMTS source.
- * @return {string} Layer.
- * @api
- */
- ol.source.WMTS.prototype.getLayer = function() {
- return this.layer_;
- };
- /**
- * Return the matrix set of the WMTS source.
- * @return {string} MatrixSet.
- * @api
- */
- ol.source.WMTS.prototype.getMatrixSet = function() {
- return this.matrixSet_;
- };
- /**
- * Return the request encoding, either "KVP" or "REST".
- * @return {ol.source.WMTSRequestEncoding} Request encoding.
- * @api
- */
- ol.source.WMTS.prototype.getRequestEncoding = function() {
- return this.requestEncoding_;
- };
- /**
- * Return the style of the WMTS source.
- * @return {string} Style.
- * @api
- */
- ol.source.WMTS.prototype.getStyle = function() {
- return this.style_;
- };
- /**
- * Return the version of the WMTS source.
- * @return {string} Version.
- * @api
- */
- ol.source.WMTS.prototype.getVersion = function() {
- return this.version_;
- };
- /**
- * @private
- * @return {string} The key for the current dimensions.
- */
- ol.source.WMTS.prototype.getKeyForDimensions_ = function() {
- var i = 0;
- var res = [];
- for (var key in this.dimensions_) {
- res[i++] = key + '-' + this.dimensions_[key];
- }
- return res.join('/');
- };
- /**
- * Update the dimensions.
- * @param {Object} dimensions Dimensions.
- * @api
- */
- ol.source.WMTS.prototype.updateDimensions = function(dimensions) {
- ol.obj.assign(this.dimensions_, dimensions);
- this.setKey(this.getKeyForDimensions_());
- };
- /**
- * Generate source options from a capabilities object.
- * @param {Object} wmtsCap An object representing the capabilities document.
- * @param {Object} config Configuration properties for the layer. Defaults for
- * the layer will apply if not provided.
- *
- * Required config properties:
- * - layer - {string} The layer identifier.
- *
- * Optional config properties:
- * - matrixSet - {string} The matrix set identifier, required if there is
- * more than one matrix set in the layer capabilities.
- * - projection - {string} The desired CRS when no matrixSet is specified.
- * eg: "EPSG:3857". If the desired projection is not available,
- * an error is thrown.
- * - requestEncoding - {string} url encoding format for the layer. Default is
- * the first tile url format found in the GetCapabilities response.
- * - style - {string} The name of the style
- * - format - {string} Image format for the layer. Default is the first
- * format returned in the GetCapabilities response.
- * - crossOrigin - {string|null|undefined} Cross origin. Default is `undefined`.
- * @return {?olx.source.WMTSOptions} WMTS source options object or `null` if the layer was not found.
- * @api
- */
- ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) {
- var layers = wmtsCap['Contents']['Layer'];
- var l = ol.array.find(layers, function(elt, index, array) {
- return elt['Identifier'] == config['layer'];
- });
- if (l === null) {
- return null;
- }
- var tileMatrixSets = wmtsCap['Contents']['TileMatrixSet'];
- var idx, matrixSet, matrixLimits;
- if (l['TileMatrixSetLink'].length > 1) {
- if ('projection' in config) {
- idx = ol.array.findIndex(l['TileMatrixSetLink'],
- function(elt, index, array) {
- var tileMatrixSet = ol.array.find(tileMatrixSets, function(el) {
- return el['Identifier'] == elt['TileMatrixSet'];
- });
- var supportedCRS = tileMatrixSet['SupportedCRS'];
- var proj1 = ol.proj.get(supportedCRS.replace(/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/, '$1:$3')) ||
- ol.proj.get(supportedCRS);
- var proj2 = ol.proj.get(config['projection']);
- if (proj1 && proj2) {
- return ol.proj.equivalent(proj1, proj2);
- } else {
- return supportedCRS == config['projection'];
- }
- });
- } else {
- idx = ol.array.findIndex(l['TileMatrixSetLink'],
- function(elt, index, array) {
- return elt['TileMatrixSet'] == config['matrixSet'];
- });
- }
- } else {
- idx = 0;
- }
- if (idx < 0) {
- idx = 0;
- }
- matrixSet = /** @type {string} */
- (l['TileMatrixSetLink'][idx]['TileMatrixSet']);
- matrixLimits = /** @type {Array.<Object>} */
- (l['TileMatrixSetLink'][idx]['TileMatrixSetLimits']);
- var format = /** @type {string} */ (l['Format'][0]);
- if ('format' in config) {
- format = config['format'];
- }
- idx = ol.array.findIndex(l['Style'], function(elt, index, array) {
- if ('style' in config) {
- return elt['Title'] == config['style'];
- } else {
- return elt['isDefault'];
- }
- });
- if (idx < 0) {
- idx = 0;
- }
- var style = /** @type {string} */ (l['Style'][idx]['Identifier']);
- var dimensions = {};
- if ('Dimension' in l) {
- l['Dimension'].forEach(function(elt, index, array) {
- var key = elt['Identifier'];
- var value = elt['Default'];
- if (value === undefined) {
- value = elt['Value'][0];
- }
- dimensions[key] = value;
- });
- }
- var matrixSets = wmtsCap['Contents']['TileMatrixSet'];
- var matrixSetObj = ol.array.find(matrixSets, function(elt, index, array) {
- return elt['Identifier'] == matrixSet;
- });
- var projection;
- var code = matrixSetObj['SupportedCRS'];
- if (code) {
- projection = ol.proj.get(code.replace(/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/, '$1:$3')) ||
- ol.proj.get(code);
- }
- if ('projection' in config) {
- var projConfig = ol.proj.get(config['projection']);
- if (projConfig) {
- if (!projection || ol.proj.equivalent(projConfig, projection)) {
- projection = projConfig;
- }
- }
- }
- var wgs84BoundingBox = l['WGS84BoundingBox'];
- var extent, wrapX;
- if (wgs84BoundingBox !== undefined) {
- var wgs84ProjectionExtent = ol.proj.get('EPSG:4326').getExtent();
- wrapX = (wgs84BoundingBox[0] == wgs84ProjectionExtent[0] &&
- wgs84BoundingBox[2] == wgs84ProjectionExtent[2]);
- extent = ol.proj.transformExtent(
- wgs84BoundingBox, 'EPSG:4326', projection);
- var projectionExtent = projection.getExtent();
- if (projectionExtent) {
- // If possible, do a sanity check on the extent - it should never be
- // bigger than the validity extent of the projection of a matrix set.
- if (!ol.extent.containsExtent(projectionExtent, extent)) {
- extent = undefined;
- }
- }
- }
- var tileGrid = ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet(
- matrixSetObj, extent, matrixLimits);
- /** @type {!Array.<string>} */
- var urls = [];
- var requestEncoding = config['requestEncoding'];
- requestEncoding = requestEncoding !== undefined ? requestEncoding : '';
- if ('OperationsMetadata' in wmtsCap && 'GetTile' in wmtsCap['OperationsMetadata']) {
- var gets = wmtsCap['OperationsMetadata']['GetTile']['DCP']['HTTP']['Get'];
- for (var i = 0, ii = gets.length; i < ii; ++i) {
- if (gets[i]['Constraint']) {
- var constraint = ol.array.find(gets[i]['Constraint'], function(element) {
- return element['name'] == 'GetEncoding';
- });
- var encodings = constraint['AllowedValues']['Value'];
- if (requestEncoding === '') {
- // requestEncoding not provided, use the first encoding from the list
- requestEncoding = encodings[0];
- }
- if (requestEncoding === ol.source.WMTSRequestEncoding.KVP) {
- if (ol.array.includes(encodings, ol.source.WMTSRequestEncoding.KVP)) {
- urls.push(/** @type {string} */ (gets[i]['href']));
- }
- } else {
- break;
- }
- } else if (gets[i]['href']) {
- requestEncoding = ol.source.WMTSRequestEncoding.KVP;
- urls.push(/** @type {string} */ (gets[i]['href']));
- }
- }
- }
- if (urls.length === 0) {
- requestEncoding = ol.source.WMTSRequestEncoding.REST;
- l['ResourceURL'].forEach(function(element) {
- if (element['resourceType'] === 'tile') {
- format = element['format'];
- urls.push(/** @type {string} */ (element['template']));
- }
- });
- }
- return {
- urls: urls,
- layer: config['layer'],
- matrixSet: matrixSet,
- format: format,
- projection: projection,
- requestEncoding: requestEncoding,
- tileGrid: tileGrid,
- style: style,
- dimensions: dimensions,
- wrapX: wrapX,
- crossOrigin: config['crossOrigin']
- };
- };
- goog.provide('ol.source.Zoomify');
- goog.require('ol');
- goog.require('ol.ImageTile');
- goog.require('ol.TileState');
- goog.require('ol.TileUrlFunction');
- goog.require('ol.asserts');
- goog.require('ol.dom');
- goog.require('ol.extent');
- goog.require('ol.size');
- goog.require('ol.source.TileImage');
- goog.require('ol.tilegrid.TileGrid');
- /**
- * @classdesc
- * Layer source for tile data in Zoomify format (both Zoomify and Internet
- * Imaging Protocol are supported).
- *
- * @constructor
- * @extends {ol.source.TileImage}
- * @param {olx.source.ZoomifyOptions=} opt_options Options.
- * @api
- */
- ol.source.Zoomify = function(opt_options) {
- var options = opt_options || {};
- var size = options.size;
- var tierSizeCalculation = options.tierSizeCalculation !== undefined ?
- options.tierSizeCalculation :
- ol.source.Zoomify.TierSizeCalculation_.DEFAULT;
- var imageWidth = size[0];
- var imageHeight = size[1];
- var extent = options.extent || [0, -size[1], size[0], 0];
- var tierSizeInTiles = [];
- var tileSize = options.tileSize || ol.DEFAULT_TILE_SIZE;
- var tileSizeForTierSizeCalculation = tileSize;
- switch (tierSizeCalculation) {
- case ol.source.Zoomify.TierSizeCalculation_.DEFAULT:
- while (imageWidth > tileSizeForTierSizeCalculation || imageHeight > tileSizeForTierSizeCalculation) {
- tierSizeInTiles.push([
- Math.ceil(imageWidth / tileSizeForTierSizeCalculation),
- Math.ceil(imageHeight / tileSizeForTierSizeCalculation)
- ]);
- tileSizeForTierSizeCalculation += tileSizeForTierSizeCalculation;
- }
- break;
- case ol.source.Zoomify.TierSizeCalculation_.TRUNCATED:
- var width = imageWidth;
- var height = imageHeight;
- while (width > tileSizeForTierSizeCalculation || height > tileSizeForTierSizeCalculation) {
- tierSizeInTiles.push([
- Math.ceil(width / tileSizeForTierSizeCalculation),
- Math.ceil(height / tileSizeForTierSizeCalculation)
- ]);
- width >>= 1;
- height >>= 1;
- }
- break;
- default:
- ol.asserts.assert(false, 53); // Unknown `tierSizeCalculation` configured
- break;
- }
- tierSizeInTiles.push([1, 1]);
- tierSizeInTiles.reverse();
- var resolutions = [1];
- var tileCountUpToTier = [0];
- var i, ii;
- for (i = 1, ii = tierSizeInTiles.length; i < ii; i++) {
- resolutions.push(1 << i);
- tileCountUpToTier.push(
- tierSizeInTiles[i - 1][0] * tierSizeInTiles[i - 1][1] +
- tileCountUpToTier[i - 1]
- );
- }
- resolutions.reverse();
- var tileGrid = new ol.tilegrid.TileGrid({
- tileSize: tileSize,
- extent: extent,
- origin: ol.extent.getTopLeft(extent),
- resolutions: resolutions
- });
- var url = options.url;
- if (url && url.indexOf('{TileGroup}') == -1 && url.indexOf('{tileIndex}') == -1) {
- url += '{TileGroup}/{z}-{x}-{y}.jpg';
- }
- var urls = ol.TileUrlFunction.expandUrl(url);
- /**
- * @param {string} template Template.
- * @return {ol.TileUrlFunctionType} Tile URL function.
- */
- function createFromTemplate(template) {
- return (
- /**
- * @param {ol.TileCoord} tileCoord Tile Coordinate.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.proj.Projection} projection Projection.
- * @return {string|undefined} Tile URL.
- */
- function(tileCoord, pixelRatio, projection) {
- if (!tileCoord) {
- return undefined;
- } else {
- var tileCoordZ = tileCoord[0];
- var tileCoordX = tileCoord[1];
- var tileCoordY = -tileCoord[2] - 1;
- var tileIndex =
- tileCoordX +
- tileCoordY * tierSizeInTiles[tileCoordZ][0];
- var tileSize = tileGrid.getTileSize(tileCoordZ);
- var tileGroup = ((tileIndex + tileCountUpToTier[tileCoordZ]) / tileSize) | 0;
- var localContext = {
- 'z': tileCoordZ,
- 'x': tileCoordX,
- 'y': tileCoordY,
- 'tileIndex': tileIndex,
- 'TileGroup': 'TileGroup' + tileGroup
- };
- return template.replace(/\{(\w+?)\}/g, function(m, p) {
- return localContext[p];
- });
- }
- });
- }
- var tileUrlFunction = ol.TileUrlFunction.createFromTileUrlFunctions(urls.map(createFromTemplate));
- var ZoomifyTileClass = ol.source.Zoomify.Tile_.bind(null, tileGrid);
- ol.source.TileImage.call(this, {
- attributions: options.attributions,
- cacheSize: options.cacheSize,
- crossOrigin: options.crossOrigin,
- logo: options.logo,
- projection: options.projection,
- reprojectionErrorThreshold: options.reprojectionErrorThreshold,
- tileClass: ZoomifyTileClass,
- tileGrid: tileGrid,
- tileUrlFunction: tileUrlFunction,
- transition: options.transition
- });
- };
- ol.inherits(ol.source.Zoomify, ol.source.TileImage);
- /**
- * @constructor
- * @extends {ol.ImageTile}
- * @param {ol.tilegrid.TileGrid} tileGrid TileGrid that the tile belongs to.
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {ol.TileState} state State.
- * @param {string} src Image source URI.
- * @param {?string} crossOrigin Cross origin.
- * @param {ol.TileLoadFunctionType} tileLoadFunction Tile load function.
- * @param {olx.TileOptions=} opt_options Tile options.
- * @private
- */
- ol.source.Zoomify.Tile_ = function(
- tileGrid, tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options) {
- ol.ImageTile.call(this, tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options);
- /**
- * @private
- * @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement}
- */
- this.zoomifyImage_ = null;
- /**
- * @private
- * @type {ol.Size}
- */
- this.tileSize_ = ol.size.toSize(tileGrid.getTileSize(tileCoord[0]));
- };
- ol.inherits(ol.source.Zoomify.Tile_, ol.ImageTile);
- /**
- * @inheritDoc
- */
- ol.source.Zoomify.Tile_.prototype.getImage = function() {
- if (this.zoomifyImage_) {
- return this.zoomifyImage_;
- }
- var image = ol.ImageTile.prototype.getImage.call(this);
- if (this.state == ol.TileState.LOADED) {
- var tileSize = this.tileSize_;
- if (image.width == tileSize[0] && image.height == tileSize[1]) {
- this.zoomifyImage_ = image;
- return image;
- } else {
- var context = ol.dom.createCanvasContext2D(tileSize[0], tileSize[1]);
- context.drawImage(image, 0, 0);
- this.zoomifyImage_ = context.canvas;
- return context.canvas;
- }
- } else {
- return image;
- }
- };
- /**
- * @enum {string}
- * @private
- */
- ol.source.Zoomify.TierSizeCalculation_ = {
- DEFAULT: 'default',
- TRUNCATED: 'truncated'
- };
- // Copyright 2009 The Closure Library Authors.
- // All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS-IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- //
- // This file has been auto-generated by GenJsDeps, please do not edit.
- goog.addDependency(
- 'demos/editor/equationeditor.js', ['goog.demos.editor.EquationEditor'],
- ['goog.ui.equation.EquationEditorDialog']);
- goog.addDependency(
- 'demos/editor/helloworld.js', ['goog.demos.editor.HelloWorld'],
- ['goog.dom', 'goog.dom.TagName', 'goog.editor.Plugin']);
- goog.addDependency(
- 'demos/editor/helloworlddialog.js',
- [
- 'goog.demos.editor.HelloWorldDialog',
- 'goog.demos.editor.HelloWorldDialog.OkEvent'
- ],
- [
- 'goog.dom.TagName', 'goog.events.Event', 'goog.string',
- 'goog.ui.editor.AbstractDialog', 'goog.ui.editor.AbstractDialog.Builder',
- 'goog.ui.editor.AbstractDialog.EventType'
- ]);
- goog.addDependency(
- 'demos/editor/helloworlddialogplugin.js',
- [
- 'goog.demos.editor.HelloWorldDialogPlugin',
- 'goog.demos.editor.HelloWorldDialogPlugin.Command'
- ],
- [
- 'goog.demos.editor.HelloWorldDialog', 'goog.dom.TagName',
- 'goog.editor.plugins.AbstractDialogPlugin', 'goog.editor.range',
- 'goog.functions', 'goog.ui.editor.AbstractDialog.EventType'
- ]);
- /**
- * @fileoverview Custom exports file.
- * @suppress {checkVars,extraRequire}
- */
- goog.require('ol');
- goog.require('ol.AssertionError');
- goog.require('ol.Attribution');
- goog.require('ol.CanvasMap');
- goog.require('ol.Collection');
- goog.require('ol.DeviceOrientation');
- goog.require('ol.Feature');
- goog.require('ol.Geolocation');
- goog.require('ol.Graticule');
- goog.require('ol.Image');
- goog.require('ol.ImageTile');
- goog.require('ol.Kinetic');
- goog.require('ol.Map');
- goog.require('ol.MapBrowserEvent');
- goog.require('ol.MapEvent');
- goog.require('ol.Object');
- goog.require('ol.Observable');
- goog.require('ol.Overlay');
- goog.require('ol.PluggableMap');
- goog.require('ol.Sphere');
- goog.require('ol.Tile');
- goog.require('ol.VectorTile');
- goog.require('ol.View');
- goog.require('ol.color');
- goog.require('ol.colorlike');
- goog.require('ol.control');
- goog.require('ol.control.Attribution');
- goog.require('ol.control.Control');
- goog.require('ol.control.FullScreen');
- goog.require('ol.control.MousePosition');
- goog.require('ol.control.OverviewMap');
- goog.require('ol.control.Rotate');
- goog.require('ol.control.ScaleLine');
- goog.require('ol.control.Zoom');
- goog.require('ol.control.ZoomSlider');
- goog.require('ol.control.ZoomToExtent');
- goog.require('ol.coordinate');
- goog.require('ol.easing');
- goog.require('ol.events.Event');
- goog.require('ol.events.condition');
- goog.require('ol.extent');
- goog.require('ol.featureloader');
- goog.require('ol.format.EsriJSON');
- goog.require('ol.format.Feature');
- goog.require('ol.format.GML');
- goog.require('ol.format.GML2');
- goog.require('ol.format.GML3');
- goog.require('ol.format.GMLBase');
- goog.require('ol.format.GPX');
- goog.require('ol.format.GeoJSON');
- goog.require('ol.format.IGC');
- goog.require('ol.format.KML');
- goog.require('ol.format.MVT');
- goog.require('ol.format.OSMXML');
- goog.require('ol.format.Polyline');
- goog.require('ol.format.TopoJSON');
- goog.require('ol.format.WFS');
- goog.require('ol.format.WKT');
- goog.require('ol.format.WMSCapabilities');
- goog.require('ol.format.WMSGetFeatureInfo');
- goog.require('ol.format.WMTSCapabilities');
- goog.require('ol.format.filter');
- goog.require('ol.format.filter.And');
- goog.require('ol.format.filter.Bbox');
- goog.require('ol.format.filter.Comparison');
- goog.require('ol.format.filter.ComparisonBinary');
- goog.require('ol.format.filter.Contains');
- goog.require('ol.format.filter.During');
- goog.require('ol.format.filter.EqualTo');
- goog.require('ol.format.filter.Filter');
- goog.require('ol.format.filter.GreaterThan');
- goog.require('ol.format.filter.GreaterThanOrEqualTo');
- goog.require('ol.format.filter.Intersects');
- goog.require('ol.format.filter.IsBetween');
- goog.require('ol.format.filter.IsLike');
- goog.require('ol.format.filter.IsNull');
- goog.require('ol.format.filter.LessThan');
- goog.require('ol.format.filter.LessThanOrEqualTo');
- goog.require('ol.format.filter.Not');
- goog.require('ol.format.filter.NotEqualTo');
- goog.require('ol.format.filter.Or');
- goog.require('ol.format.filter.Spatial');
- goog.require('ol.format.filter.Within');
- goog.require('ol.geom.Circle');
- goog.require('ol.geom.Geometry');
- goog.require('ol.geom.GeometryCollection');
- goog.require('ol.geom.LineString');
- goog.require('ol.geom.LinearRing');
- goog.require('ol.geom.MultiLineString');
- goog.require('ol.geom.MultiPoint');
- goog.require('ol.geom.MultiPolygon');
- goog.require('ol.geom.Point');
- goog.require('ol.geom.Polygon');
- goog.require('ol.geom.SimpleGeometry');
- goog.require('ol.has');
- goog.require('ol.interaction');
- goog.require('ol.interaction.DoubleClickZoom');
- goog.require('ol.interaction.DragAndDrop');
- goog.require('ol.interaction.DragBox');
- goog.require('ol.interaction.DragPan');
- goog.require('ol.interaction.DragRotate');
- goog.require('ol.interaction.DragRotateAndZoom');
- goog.require('ol.interaction.DragZoom');
- goog.require('ol.interaction.Draw');
- goog.require('ol.interaction.Extent');
- goog.require('ol.interaction.Interaction');
- goog.require('ol.interaction.KeyboardPan');
- goog.require('ol.interaction.KeyboardZoom');
- goog.require('ol.interaction.Modify');
- goog.require('ol.interaction.MouseWheelZoom');
- goog.require('ol.interaction.PinchRotate');
- goog.require('ol.interaction.PinchZoom');
- goog.require('ol.interaction.Pointer');
- goog.require('ol.interaction.Select');
- goog.require('ol.interaction.Snap');
- goog.require('ol.interaction.Translate');
- goog.require('ol.layer.Base');
- goog.require('ol.layer.Group');
- goog.require('ol.layer.Heatmap');
- goog.require('ol.layer.Image');
- goog.require('ol.layer.Layer');
- goog.require('ol.layer.Tile');
- goog.require('ol.layer.Vector');
- goog.require('ol.layer.VectorTile');
- goog.require('ol.loadingstrategy');
- goog.require('ol.proj');
- goog.require('ol.proj.Projection');
- goog.require('ol.proj.Units');
- goog.require('ol.proj.common');
- goog.require('ol.render');
- goog.require('ol.render.Event');
- goog.require('ol.render.Feature');
- goog.require('ol.render.VectorContext');
- goog.require('ol.render.canvas.Immediate');
- goog.require('ol.render.webgl.Immediate');
- goog.require('ol.renderer.canvas.ImageLayer');
- goog.require('ol.renderer.canvas.Map');
- goog.require('ol.renderer.canvas.TileLayer');
- goog.require('ol.renderer.canvas.VectorLayer');
- goog.require('ol.renderer.canvas.VectorTileLayer');
- goog.require('ol.renderer.webgl.ImageLayer');
- goog.require('ol.renderer.webgl.Map');
- goog.require('ol.renderer.webgl.TileLayer');
- goog.require('ol.renderer.webgl.VectorLayer');
- goog.require('ol.size');
- goog.require('ol.source.BingMaps');
- goog.require('ol.source.CartoDB');
- goog.require('ol.source.Cluster');
- goog.require('ol.source.Image');
- goog.require('ol.source.ImageArcGISRest');
- goog.require('ol.source.ImageCanvas');
- goog.require('ol.source.ImageMapGuide');
- goog.require('ol.source.ImageStatic');
- goog.require('ol.source.ImageVector');
- goog.require('ol.source.ImageWMS');
- goog.require('ol.source.OSM');
- goog.require('ol.source.Raster');
- goog.require('ol.source.Source');
- goog.require('ol.source.Stamen');
- goog.require('ol.source.Tile');
- goog.require('ol.source.TileArcGISRest');
- goog.require('ol.source.TileDebug');
- goog.require('ol.source.TileImage');
- goog.require('ol.source.TileJSON');
- goog.require('ol.source.TileUTFGrid');
- goog.require('ol.source.TileWMS');
- goog.require('ol.source.UrlTile');
- goog.require('ol.source.Vector');
- goog.require('ol.source.VectorTile');
- goog.require('ol.source.WMTS');
- goog.require('ol.source.XYZ');
- goog.require('ol.source.Zoomify');
- goog.require('ol.style');
- goog.require('ol.style.AtlasManager');
- goog.require('ol.style.Circle');
- goog.require('ol.style.Fill');
- goog.require('ol.style.Icon');
- goog.require('ol.style.IconImageCache');
- goog.require('ol.style.Image');
- goog.require('ol.style.RegularShape');
- goog.require('ol.style.Stroke');
- goog.require('ol.style.Style');
- goog.require('ol.style.Text');
- goog.require('ol.tilegrid');
- goog.require('ol.tilegrid.TileGrid');
- goog.require('ol.tilegrid.WMTS');
- goog.require('ol.webgl.Context');
- goog.require('ol.xml');
- goog.exportProperty(
- ol.AssertionError.prototype,
- 'code',
- ol.AssertionError.prototype.code);
- goog.exportSymbol(
- 'ol.Attribution',
- ol.Attribution,
- OPENLAYERS);
- goog.exportProperty(
- ol.Attribution.prototype,
- 'getHTML',
- ol.Attribution.prototype.getHTML);
- goog.exportSymbol(
- 'ol.CanvasMap',
- ol.CanvasMap,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.Collection',
- ol.Collection,
- OPENLAYERS);
- goog.exportProperty(
- ol.Collection.prototype,
- 'clear',
- ol.Collection.prototype.clear);
- goog.exportProperty(
- ol.Collection.prototype,
- 'extend',
- ol.Collection.prototype.extend);
- goog.exportProperty(
- ol.Collection.prototype,
- 'forEach',
- ol.Collection.prototype.forEach);
- goog.exportProperty(
- ol.Collection.prototype,
- 'getArray',
- ol.Collection.prototype.getArray);
- goog.exportProperty(
- ol.Collection.prototype,
- 'item',
- ol.Collection.prototype.item);
- goog.exportProperty(
- ol.Collection.prototype,
- 'getLength',
- ol.Collection.prototype.getLength);
- goog.exportProperty(
- ol.Collection.prototype,
- 'insertAt',
- ol.Collection.prototype.insertAt);
- goog.exportProperty(
- ol.Collection.prototype,
- 'pop',
- ol.Collection.prototype.pop);
- goog.exportProperty(
- ol.Collection.prototype,
- 'push',
- ol.Collection.prototype.push);
- goog.exportProperty(
- ol.Collection.prototype,
- 'remove',
- ol.Collection.prototype.remove);
- goog.exportProperty(
- ol.Collection.prototype,
- 'removeAt',
- ol.Collection.prototype.removeAt);
- goog.exportProperty(
- ol.Collection.prototype,
- 'setAt',
- ol.Collection.prototype.setAt);
- goog.exportProperty(
- ol.Collection.Event.prototype,
- 'element',
- ol.Collection.Event.prototype.element);
- goog.exportSymbol(
- 'ol.color.asArray',
- ol.color.asArray,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.color.asString',
- ol.color.asString,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.colorlike.asColorLike',
- ol.colorlike.asColorLike,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.control.defaults',
- ol.control.defaults,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.coordinate.add',
- ol.coordinate.add,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.coordinate.createStringXY',
- ol.coordinate.createStringXY,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.coordinate.format',
- ol.coordinate.format,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.coordinate.rotate',
- ol.coordinate.rotate,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.coordinate.toStringHDMS',
- ol.coordinate.toStringHDMS,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.coordinate.toStringXY',
- ol.coordinate.toStringXY,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.DeviceOrientation',
- ol.DeviceOrientation,
- OPENLAYERS);
- goog.exportProperty(
- ol.DeviceOrientation.prototype,
- 'getAlpha',
- ol.DeviceOrientation.prototype.getAlpha);
- goog.exportProperty(
- ol.DeviceOrientation.prototype,
- 'getBeta',
- ol.DeviceOrientation.prototype.getBeta);
- goog.exportProperty(
- ol.DeviceOrientation.prototype,
- 'getGamma',
- ol.DeviceOrientation.prototype.getGamma);
- goog.exportProperty(
- ol.DeviceOrientation.prototype,
- 'getHeading',
- ol.DeviceOrientation.prototype.getHeading);
- goog.exportProperty(
- ol.DeviceOrientation.prototype,
- 'getTracking',
- ol.DeviceOrientation.prototype.getTracking);
- goog.exportProperty(
- ol.DeviceOrientation.prototype,
- 'setTracking',
- ol.DeviceOrientation.prototype.setTracking);
- goog.exportSymbol(
- 'ol.easing.easeIn',
- ol.easing.easeIn,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.easing.easeOut',
- ol.easing.easeOut,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.easing.inAndOut',
- ol.easing.inAndOut,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.easing.linear',
- ol.easing.linear,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.easing.upAndDown',
- ol.easing.upAndDown,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.boundingExtent',
- ol.extent.boundingExtent,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.buffer',
- ol.extent.buffer,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.containsCoordinate',
- ol.extent.containsCoordinate,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.containsExtent',
- ol.extent.containsExtent,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.containsXY',
- ol.extent.containsXY,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.createEmpty',
- ol.extent.createEmpty,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.equals',
- ol.extent.equals,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.extend',
- ol.extent.extend,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.getArea',
- ol.extent.getArea,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.getBottomLeft',
- ol.extent.getBottomLeft,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.getBottomRight',
- ol.extent.getBottomRight,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.getCenter',
- ol.extent.getCenter,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.getHeight',
- ol.extent.getHeight,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.getIntersection',
- ol.extent.getIntersection,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.getSize',
- ol.extent.getSize,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.getTopLeft',
- ol.extent.getTopLeft,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.getTopRight',
- ol.extent.getTopRight,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.getWidth',
- ol.extent.getWidth,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.intersects',
- ol.extent.intersects,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.isEmpty',
- ol.extent.isEmpty,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.extent.applyTransform',
- ol.extent.applyTransform,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.Feature',
- ol.Feature,
- OPENLAYERS);
- goog.exportProperty(
- ol.Feature.prototype,
- 'clone',
- ol.Feature.prototype.clone);
- goog.exportProperty(
- ol.Feature.prototype,
- 'getGeometry',
- ol.Feature.prototype.getGeometry);
- goog.exportProperty(
- ol.Feature.prototype,
- 'getId',
- ol.Feature.prototype.getId);
- goog.exportProperty(
- ol.Feature.prototype,
- 'getGeometryName',
- ol.Feature.prototype.getGeometryName);
- goog.exportProperty(
- ol.Feature.prototype,
- 'getStyle',
- ol.Feature.prototype.getStyle);
- goog.exportProperty(
- ol.Feature.prototype,
- 'getStyleFunction',
- ol.Feature.prototype.getStyleFunction);
- goog.exportProperty(
- ol.Feature.prototype,
- 'setGeometry',
- ol.Feature.prototype.setGeometry);
- goog.exportProperty(
- ol.Feature.prototype,
- 'setStyle',
- ol.Feature.prototype.setStyle);
- goog.exportProperty(
- ol.Feature.prototype,
- 'setId',
- ol.Feature.prototype.setId);
- goog.exportProperty(
- ol.Feature.prototype,
- 'setGeometryName',
- ol.Feature.prototype.setGeometryName);
- goog.exportSymbol(
- 'ol.featureloader.xhr',
- ol.featureloader.xhr,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.Geolocation',
- ol.Geolocation,
- OPENLAYERS);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'getAccuracy',
- ol.Geolocation.prototype.getAccuracy);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'getAccuracyGeometry',
- ol.Geolocation.prototype.getAccuracyGeometry);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'getAltitude',
- ol.Geolocation.prototype.getAltitude);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'getAltitudeAccuracy',
- ol.Geolocation.prototype.getAltitudeAccuracy);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'getHeading',
- ol.Geolocation.prototype.getHeading);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'getPosition',
- ol.Geolocation.prototype.getPosition);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'getProjection',
- ol.Geolocation.prototype.getProjection);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'getSpeed',
- ol.Geolocation.prototype.getSpeed);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'getTracking',
- ol.Geolocation.prototype.getTracking);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'getTrackingOptions',
- ol.Geolocation.prototype.getTrackingOptions);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'setProjection',
- ol.Geolocation.prototype.setProjection);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'setTracking',
- ol.Geolocation.prototype.setTracking);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'setTrackingOptions',
- ol.Geolocation.prototype.setTrackingOptions);
- goog.exportSymbol(
- 'ol.Graticule',
- ol.Graticule,
- OPENLAYERS);
- goog.exportProperty(
- ol.Graticule.prototype,
- 'getMap',
- ol.Graticule.prototype.getMap);
- goog.exportProperty(
- ol.Graticule.prototype,
- 'getMeridians',
- ol.Graticule.prototype.getMeridians);
- goog.exportProperty(
- ol.Graticule.prototype,
- 'getParallels',
- ol.Graticule.prototype.getParallels);
- goog.exportProperty(
- ol.Graticule.prototype,
- 'setMap',
- ol.Graticule.prototype.setMap);
- goog.exportSymbol(
- 'ol.has.DEVICE_PIXEL_RATIO',
- ol.has.DEVICE_PIXEL_RATIO,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.has.CANVAS',
- ol.has.CANVAS,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.has.DEVICE_ORIENTATION',
- ol.has.DEVICE_ORIENTATION,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.has.GEOLOCATION',
- ol.has.GEOLOCATION,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.has.TOUCH',
- ol.has.TOUCH,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.has.WEBGL',
- ol.has.WEBGL,
- OPENLAYERS);
- goog.exportProperty(
- ol.Image.prototype,
- 'getImage',
- ol.Image.prototype.getImage);
- goog.exportProperty(
- ol.Image.prototype,
- 'load',
- ol.Image.prototype.load);
- goog.exportProperty(
- ol.ImageTile.prototype,
- 'getImage',
- ol.ImageTile.prototype.getImage);
- goog.exportSymbol(
- 'ol.inherits',
- ol.inherits,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.defaults',
- ol.interaction.defaults,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.Kinetic',
- ol.Kinetic,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.loadingstrategy.all',
- ol.loadingstrategy.all,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.loadingstrategy.bbox',
- ol.loadingstrategy.bbox,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.loadingstrategy.tile',
- ol.loadingstrategy.tile,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.Map',
- ol.Map,
- OPENLAYERS);
- goog.exportProperty(
- ol.MapBrowserEvent.prototype,
- 'originalEvent',
- ol.MapBrowserEvent.prototype.originalEvent);
- goog.exportProperty(
- ol.MapBrowserEvent.prototype,
- 'pixel',
- ol.MapBrowserEvent.prototype.pixel);
- goog.exportProperty(
- ol.MapBrowserEvent.prototype,
- 'coordinate',
- ol.MapBrowserEvent.prototype.coordinate);
- goog.exportProperty(
- ol.MapBrowserEvent.prototype,
- 'dragging',
- ol.MapBrowserEvent.prototype.dragging);
- goog.exportProperty(
- ol.MapEvent.prototype,
- 'map',
- ol.MapEvent.prototype.map);
- goog.exportProperty(
- ol.MapEvent.prototype,
- 'frameState',
- ol.MapEvent.prototype.frameState);
- goog.exportSymbol(
- 'ol.Object',
- ol.Object,
- OPENLAYERS);
- goog.exportProperty(
- ol.Object.prototype,
- 'get',
- ol.Object.prototype.get);
- goog.exportProperty(
- ol.Object.prototype,
- 'getKeys',
- ol.Object.prototype.getKeys);
- goog.exportProperty(
- ol.Object.prototype,
- 'getProperties',
- ol.Object.prototype.getProperties);
- goog.exportProperty(
- ol.Object.prototype,
- 'set',
- ol.Object.prototype.set);
- goog.exportProperty(
- ol.Object.prototype,
- 'setProperties',
- ol.Object.prototype.setProperties);
- goog.exportProperty(
- ol.Object.prototype,
- 'unset',
- ol.Object.prototype.unset);
- goog.exportProperty(
- ol.Object.Event.prototype,
- 'key',
- ol.Object.Event.prototype.key);
- goog.exportProperty(
- ol.Object.Event.prototype,
- 'oldValue',
- ol.Object.Event.prototype.oldValue);
- goog.exportSymbol(
- 'ol.Observable',
- ol.Observable,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.Observable.unByKey',
- ol.Observable.unByKey,
- OPENLAYERS);
- goog.exportProperty(
- ol.Observable.prototype,
- 'changed',
- ol.Observable.prototype.changed);
- goog.exportProperty(
- ol.Observable.prototype,
- 'dispatchEvent',
- ol.Observable.prototype.dispatchEvent);
- goog.exportProperty(
- ol.Observable.prototype,
- 'getRevision',
- ol.Observable.prototype.getRevision);
- goog.exportProperty(
- ol.Observable.prototype,
- 'on',
- ol.Observable.prototype.on);
- goog.exportProperty(
- ol.Observable.prototype,
- 'once',
- ol.Observable.prototype.once);
- goog.exportProperty(
- ol.Observable.prototype,
- 'un',
- ol.Observable.prototype.un);
- goog.exportSymbol(
- 'ol.Overlay',
- ol.Overlay,
- OPENLAYERS);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'getElement',
- ol.Overlay.prototype.getElement);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'getId',
- ol.Overlay.prototype.getId);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'getMap',
- ol.Overlay.prototype.getMap);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'getOffset',
- ol.Overlay.prototype.getOffset);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'getPosition',
- ol.Overlay.prototype.getPosition);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'getPositioning',
- ol.Overlay.prototype.getPositioning);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'setElement',
- ol.Overlay.prototype.setElement);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'setMap',
- ol.Overlay.prototype.setMap);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'setOffset',
- ol.Overlay.prototype.setOffset);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'setPosition',
- ol.Overlay.prototype.setPosition);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'setPositioning',
- ol.Overlay.prototype.setPositioning);
- goog.exportSymbol(
- 'ol.PluggableMap',
- ol.PluggableMap,
- OPENLAYERS);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'addControl',
- ol.PluggableMap.prototype.addControl);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'addInteraction',
- ol.PluggableMap.prototype.addInteraction);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'addLayer',
- ol.PluggableMap.prototype.addLayer);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'addOverlay',
- ol.PluggableMap.prototype.addOverlay);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'forEachFeatureAtPixel',
- ol.PluggableMap.prototype.forEachFeatureAtPixel);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getFeaturesAtPixel',
- ol.PluggableMap.prototype.getFeaturesAtPixel);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'forEachLayerAtPixel',
- ol.PluggableMap.prototype.forEachLayerAtPixel);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'hasFeatureAtPixel',
- ol.PluggableMap.prototype.hasFeatureAtPixel);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getEventCoordinate',
- ol.PluggableMap.prototype.getEventCoordinate);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getEventPixel',
- ol.PluggableMap.prototype.getEventPixel);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getTarget',
- ol.PluggableMap.prototype.getTarget);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getTargetElement',
- ol.PluggableMap.prototype.getTargetElement);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getCoordinateFromPixel',
- ol.PluggableMap.prototype.getCoordinateFromPixel);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getControls',
- ol.PluggableMap.prototype.getControls);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getOverlays',
- ol.PluggableMap.prototype.getOverlays);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getOverlayById',
- ol.PluggableMap.prototype.getOverlayById);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getInteractions',
- ol.PluggableMap.prototype.getInteractions);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getLayerGroup',
- ol.PluggableMap.prototype.getLayerGroup);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getLayers',
- ol.PluggableMap.prototype.getLayers);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getPixelFromCoordinate',
- ol.PluggableMap.prototype.getPixelFromCoordinate);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getSize',
- ol.PluggableMap.prototype.getSize);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getView',
- ol.PluggableMap.prototype.getView);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getViewport',
- ol.PluggableMap.prototype.getViewport);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'renderSync',
- ol.PluggableMap.prototype.renderSync);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'render',
- ol.PluggableMap.prototype.render);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'removeControl',
- ol.PluggableMap.prototype.removeControl);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'removeInteraction',
- ol.PluggableMap.prototype.removeInteraction);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'removeLayer',
- ol.PluggableMap.prototype.removeLayer);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'removeOverlay',
- ol.PluggableMap.prototype.removeOverlay);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'setLayerGroup',
- ol.PluggableMap.prototype.setLayerGroup);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'setSize',
- ol.PluggableMap.prototype.setSize);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'setTarget',
- ol.PluggableMap.prototype.setTarget);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'setView',
- ol.PluggableMap.prototype.setView);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'updateSize',
- ol.PluggableMap.prototype.updateSize);
- goog.exportSymbol(
- 'ol.proj.METERS_PER_UNIT',
- ol.proj.METERS_PER_UNIT,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.proj.setProj4',
- ol.proj.setProj4,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.proj.getPointResolution',
- ol.proj.getPointResolution,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.proj.addEquivalentProjections',
- ol.proj.addEquivalentProjections,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.proj.addProjection',
- ol.proj.addProjection,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.proj.addCoordinateTransforms',
- ol.proj.addCoordinateTransforms,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.proj.fromLonLat',
- ol.proj.fromLonLat,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.proj.toLonLat',
- ol.proj.toLonLat,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.proj.get',
- ol.proj.get,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.proj.equivalent',
- ol.proj.equivalent,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.proj.getTransform',
- ol.proj.getTransform,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.proj.transform',
- ol.proj.transform,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.proj.transformExtent',
- ol.proj.transformExtent,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.render.toContext',
- ol.render.toContext,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.size.toSize',
- ol.size.toSize,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.Sphere',
- ol.Sphere,
- OPENLAYERS);
- goog.exportProperty(
- ol.Sphere.prototype,
- 'geodesicArea',
- ol.Sphere.prototype.geodesicArea);
- goog.exportProperty(
- ol.Sphere.prototype,
- 'haversineDistance',
- ol.Sphere.prototype.haversineDistance);
- goog.exportSymbol(
- 'ol.Sphere.getLength',
- ol.Sphere.getLength,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.Sphere.getArea',
- ol.Sphere.getArea,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.style.iconImageCache',
- ol.style.iconImageCache,
- OPENLAYERS);
- goog.exportProperty(
- ol.Tile.prototype,
- 'getTileCoord',
- ol.Tile.prototype.getTileCoord);
- goog.exportProperty(
- ol.Tile.prototype,
- 'load',
- ol.Tile.prototype.load);
- goog.exportSymbol(
- 'ol.tilegrid.createXYZ',
- ol.tilegrid.createXYZ,
- OPENLAYERS);
- goog.exportProperty(
- ol.VectorTile.prototype,
- 'getExtent',
- ol.VectorTile.prototype.getExtent);
- goog.exportProperty(
- ol.VectorTile.prototype,
- 'getFormat',
- ol.VectorTile.prototype.getFormat);
- goog.exportProperty(
- ol.VectorTile.prototype,
- 'getFeatures',
- ol.VectorTile.prototype.getFeatures);
- goog.exportProperty(
- ol.VectorTile.prototype,
- 'getProjection',
- ol.VectorTile.prototype.getProjection);
- goog.exportProperty(
- ol.VectorTile.prototype,
- 'setExtent',
- ol.VectorTile.prototype.setExtent);
- goog.exportProperty(
- ol.VectorTile.prototype,
- 'setFeatures',
- ol.VectorTile.prototype.setFeatures);
- goog.exportProperty(
- ol.VectorTile.prototype,
- 'setProjection',
- ol.VectorTile.prototype.setProjection);
- goog.exportProperty(
- ol.VectorTile.prototype,
- 'setLoader',
- ol.VectorTile.prototype.setLoader);
- goog.exportSymbol(
- 'ol.View',
- ol.View,
- OPENLAYERS);
- goog.exportProperty(
- ol.View.prototype,
- 'animate',
- ol.View.prototype.animate);
- goog.exportProperty(
- ol.View.prototype,
- 'getAnimating',
- ol.View.prototype.getAnimating);
- goog.exportProperty(
- ol.View.prototype,
- 'getInteracting',
- ol.View.prototype.getInteracting);
- goog.exportProperty(
- ol.View.prototype,
- 'cancelAnimations',
- ol.View.prototype.cancelAnimations);
- goog.exportProperty(
- ol.View.prototype,
- 'constrainCenter',
- ol.View.prototype.constrainCenter);
- goog.exportProperty(
- ol.View.prototype,
- 'constrainResolution',
- ol.View.prototype.constrainResolution);
- goog.exportProperty(
- ol.View.prototype,
- 'constrainRotation',
- ol.View.prototype.constrainRotation);
- goog.exportProperty(
- ol.View.prototype,
- 'getCenter',
- ol.View.prototype.getCenter);
- goog.exportProperty(
- ol.View.prototype,
- 'calculateExtent',
- ol.View.prototype.calculateExtent);
- goog.exportProperty(
- ol.View.prototype,
- 'getMaxResolution',
- ol.View.prototype.getMaxResolution);
- goog.exportProperty(
- ol.View.prototype,
- 'getMinResolution',
- ol.View.prototype.getMinResolution);
- goog.exportProperty(
- ol.View.prototype,
- 'getMaxZoom',
- ol.View.prototype.getMaxZoom);
- goog.exportProperty(
- ol.View.prototype,
- 'setMaxZoom',
- ol.View.prototype.setMaxZoom);
- goog.exportProperty(
- ol.View.prototype,
- 'getMinZoom',
- ol.View.prototype.getMinZoom);
- goog.exportProperty(
- ol.View.prototype,
- 'setMinZoom',
- ol.View.prototype.setMinZoom);
- goog.exportProperty(
- ol.View.prototype,
- 'getProjection',
- ol.View.prototype.getProjection);
- goog.exportProperty(
- ol.View.prototype,
- 'getResolution',
- ol.View.prototype.getResolution);
- goog.exportProperty(
- ol.View.prototype,
- 'getResolutions',
- ol.View.prototype.getResolutions);
- goog.exportProperty(
- ol.View.prototype,
- 'getResolutionForExtent',
- ol.View.prototype.getResolutionForExtent);
- goog.exportProperty(
- ol.View.prototype,
- 'getRotation',
- ol.View.prototype.getRotation);
- goog.exportProperty(
- ol.View.prototype,
- 'getZoom',
- ol.View.prototype.getZoom);
- goog.exportProperty(
- ol.View.prototype,
- 'getZoomForResolution',
- ol.View.prototype.getZoomForResolution);
- goog.exportProperty(
- ol.View.prototype,
- 'getResolutionForZoom',
- ol.View.prototype.getResolutionForZoom);
- goog.exportProperty(
- ol.View.prototype,
- 'fit',
- ol.View.prototype.fit);
- goog.exportProperty(
- ol.View.prototype,
- 'centerOn',
- ol.View.prototype.centerOn);
- goog.exportProperty(
- ol.View.prototype,
- 'rotate',
- ol.View.prototype.rotate);
- goog.exportProperty(
- ol.View.prototype,
- 'setCenter',
- ol.View.prototype.setCenter);
- goog.exportProperty(
- ol.View.prototype,
- 'setResolution',
- ol.View.prototype.setResolution);
- goog.exportProperty(
- ol.View.prototype,
- 'setRotation',
- ol.View.prototype.setRotation);
- goog.exportProperty(
- ol.View.prototype,
- 'setZoom',
- ol.View.prototype.setZoom);
- goog.exportSymbol(
- 'ol.xml.getAllTextContent',
- ol.xml.getAllTextContent,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.xml.parse',
- ol.xml.parse,
- OPENLAYERS);
- goog.exportProperty(
- ol.webgl.Context.prototype,
- 'getGL',
- ol.webgl.Context.prototype.getGL);
- goog.exportProperty(
- ol.webgl.Context.prototype,
- 'useProgram',
- ol.webgl.Context.prototype.useProgram);
- goog.exportSymbol(
- 'ol.tilegrid.TileGrid',
- ol.tilegrid.TileGrid,
- OPENLAYERS);
- goog.exportProperty(
- ol.tilegrid.TileGrid.prototype,
- 'forEachTileCoord',
- ol.tilegrid.TileGrid.prototype.forEachTileCoord);
- goog.exportProperty(
- ol.tilegrid.TileGrid.prototype,
- 'getMaxZoom',
- ol.tilegrid.TileGrid.prototype.getMaxZoom);
- goog.exportProperty(
- ol.tilegrid.TileGrid.prototype,
- 'getMinZoom',
- ol.tilegrid.TileGrid.prototype.getMinZoom);
- goog.exportProperty(
- ol.tilegrid.TileGrid.prototype,
- 'getOrigin',
- ol.tilegrid.TileGrid.prototype.getOrigin);
- goog.exportProperty(
- ol.tilegrid.TileGrid.prototype,
- 'getResolution',
- ol.tilegrid.TileGrid.prototype.getResolution);
- goog.exportProperty(
- ol.tilegrid.TileGrid.prototype,
- 'getResolutions',
- ol.tilegrid.TileGrid.prototype.getResolutions);
- goog.exportProperty(
- ol.tilegrid.TileGrid.prototype,
- 'getTileCoordExtent',
- ol.tilegrid.TileGrid.prototype.getTileCoordExtent);
- goog.exportProperty(
- ol.tilegrid.TileGrid.prototype,
- 'getTileCoordForCoordAndResolution',
- ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndResolution);
- goog.exportProperty(
- ol.tilegrid.TileGrid.prototype,
- 'getTileCoordForCoordAndZ',
- ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndZ);
- goog.exportProperty(
- ol.tilegrid.TileGrid.prototype,
- 'getTileSize',
- ol.tilegrid.TileGrid.prototype.getTileSize);
- goog.exportProperty(
- ol.tilegrid.TileGrid.prototype,
- 'getZForResolution',
- ol.tilegrid.TileGrid.prototype.getZForResolution);
- goog.exportSymbol(
- 'ol.tilegrid.WMTS',
- ol.tilegrid.WMTS,
- OPENLAYERS);
- goog.exportProperty(
- ol.tilegrid.WMTS.prototype,
- 'getMatrixIds',
- ol.tilegrid.WMTS.prototype.getMatrixIds);
- goog.exportSymbol(
- 'ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet',
- ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.style.AtlasManager',
- ol.style.AtlasManager,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.style.Circle',
- ol.style.Circle,
- OPENLAYERS);
- goog.exportProperty(
- ol.style.Circle.prototype,
- 'setRadius',
- ol.style.Circle.prototype.setRadius);
- goog.exportSymbol(
- 'ol.style.Fill',
- ol.style.Fill,
- OPENLAYERS);
- goog.exportProperty(
- ol.style.Fill.prototype,
- 'clone',
- ol.style.Fill.prototype.clone);
- goog.exportProperty(
- ol.style.Fill.prototype,
- 'getColor',
- ol.style.Fill.prototype.getColor);
- goog.exportProperty(
- ol.style.Fill.prototype,
- 'setColor',
- ol.style.Fill.prototype.setColor);
- goog.exportSymbol(
- 'ol.style.Icon',
- ol.style.Icon,
- OPENLAYERS);
- goog.exportProperty(
- ol.style.Icon.prototype,
- 'clone',
- ol.style.Icon.prototype.clone);
- goog.exportProperty(
- ol.style.Icon.prototype,
- 'getAnchor',
- ol.style.Icon.prototype.getAnchor);
- goog.exportProperty(
- ol.style.Icon.prototype,
- 'getColor',
- ol.style.Icon.prototype.getColor);
- goog.exportProperty(
- ol.style.Icon.prototype,
- 'getImage',
- ol.style.Icon.prototype.getImage);
- goog.exportProperty(
- ol.style.Icon.prototype,
- 'getOrigin',
- ol.style.Icon.prototype.getOrigin);
- goog.exportProperty(
- ol.style.Icon.prototype,
- 'getSrc',
- ol.style.Icon.prototype.getSrc);
- goog.exportProperty(
- ol.style.Icon.prototype,
- 'getSize',
- ol.style.Icon.prototype.getSize);
- goog.exportProperty(
- ol.style.Icon.prototype,
- 'load',
- ol.style.Icon.prototype.load);
- goog.exportProperty(
- ol.style.IconImageCache.prototype,
- 'setSize',
- ol.style.IconImageCache.prototype.setSize);
- goog.exportSymbol(
- 'ol.style.Image',
- ol.style.Image,
- OPENLAYERS);
- goog.exportProperty(
- ol.style.Image.prototype,
- 'getOpacity',
- ol.style.Image.prototype.getOpacity);
- goog.exportProperty(
- ol.style.Image.prototype,
- 'getRotateWithView',
- ol.style.Image.prototype.getRotateWithView);
- goog.exportProperty(
- ol.style.Image.prototype,
- 'getRotation',
- ol.style.Image.prototype.getRotation);
- goog.exportProperty(
- ol.style.Image.prototype,
- 'getScale',
- ol.style.Image.prototype.getScale);
- goog.exportProperty(
- ol.style.Image.prototype,
- 'getSnapToPixel',
- ol.style.Image.prototype.getSnapToPixel);
- goog.exportProperty(
- ol.style.Image.prototype,
- 'setOpacity',
- ol.style.Image.prototype.setOpacity);
- goog.exportProperty(
- ol.style.Image.prototype,
- 'setRotation',
- ol.style.Image.prototype.setRotation);
- goog.exportProperty(
- ol.style.Image.prototype,
- 'setScale',
- ol.style.Image.prototype.setScale);
- goog.exportSymbol(
- 'ol.style.RegularShape',
- ol.style.RegularShape,
- OPENLAYERS);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'clone',
- ol.style.RegularShape.prototype.clone);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'getAnchor',
- ol.style.RegularShape.prototype.getAnchor);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'getAngle',
- ol.style.RegularShape.prototype.getAngle);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'getFill',
- ol.style.RegularShape.prototype.getFill);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'getImage',
- ol.style.RegularShape.prototype.getImage);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'getOrigin',
- ol.style.RegularShape.prototype.getOrigin);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'getPoints',
- ol.style.RegularShape.prototype.getPoints);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'getRadius',
- ol.style.RegularShape.prototype.getRadius);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'getRadius2',
- ol.style.RegularShape.prototype.getRadius2);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'getSize',
- ol.style.RegularShape.prototype.getSize);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'getStroke',
- ol.style.RegularShape.prototype.getStroke);
- goog.exportSymbol(
- 'ol.style.Stroke',
- ol.style.Stroke,
- OPENLAYERS);
- goog.exportProperty(
- ol.style.Stroke.prototype,
- 'clone',
- ol.style.Stroke.prototype.clone);
- goog.exportProperty(
- ol.style.Stroke.prototype,
- 'getColor',
- ol.style.Stroke.prototype.getColor);
- goog.exportProperty(
- ol.style.Stroke.prototype,
- 'getLineCap',
- ol.style.Stroke.prototype.getLineCap);
- goog.exportProperty(
- ol.style.Stroke.prototype,
- 'getLineDash',
- ol.style.Stroke.prototype.getLineDash);
- goog.exportProperty(
- ol.style.Stroke.prototype,
- 'getLineDashOffset',
- ol.style.Stroke.prototype.getLineDashOffset);
- goog.exportProperty(
- ol.style.Stroke.prototype,
- 'getLineJoin',
- ol.style.Stroke.prototype.getLineJoin);
- goog.exportProperty(
- ol.style.Stroke.prototype,
- 'getMiterLimit',
- ol.style.Stroke.prototype.getMiterLimit);
- goog.exportProperty(
- ol.style.Stroke.prototype,
- 'getWidth',
- ol.style.Stroke.prototype.getWidth);
- goog.exportProperty(
- ol.style.Stroke.prototype,
- 'setColor',
- ol.style.Stroke.prototype.setColor);
- goog.exportProperty(
- ol.style.Stroke.prototype,
- 'setLineCap',
- ol.style.Stroke.prototype.setLineCap);
- goog.exportProperty(
- ol.style.Stroke.prototype,
- 'setLineDash',
- ol.style.Stroke.prototype.setLineDash);
- goog.exportProperty(
- ol.style.Stroke.prototype,
- 'setLineDashOffset',
- ol.style.Stroke.prototype.setLineDashOffset);
- goog.exportProperty(
- ol.style.Stroke.prototype,
- 'setLineJoin',
- ol.style.Stroke.prototype.setLineJoin);
- goog.exportProperty(
- ol.style.Stroke.prototype,
- 'setMiterLimit',
- ol.style.Stroke.prototype.setMiterLimit);
- goog.exportProperty(
- ol.style.Stroke.prototype,
- 'setWidth',
- ol.style.Stroke.prototype.setWidth);
- goog.exportSymbol(
- 'ol.style.Style',
- ol.style.Style,
- OPENLAYERS);
- goog.exportProperty(
- ol.style.Style.prototype,
- 'clone',
- ol.style.Style.prototype.clone);
- goog.exportProperty(
- ol.style.Style.prototype,
- 'getRenderer',
- ol.style.Style.prototype.getRenderer);
- goog.exportProperty(
- ol.style.Style.prototype,
- 'setRenderer',
- ol.style.Style.prototype.setRenderer);
- goog.exportProperty(
- ol.style.Style.prototype,
- 'getGeometry',
- ol.style.Style.prototype.getGeometry);
- goog.exportProperty(
- ol.style.Style.prototype,
- 'getGeometryFunction',
- ol.style.Style.prototype.getGeometryFunction);
- goog.exportProperty(
- ol.style.Style.prototype,
- 'getFill',
- ol.style.Style.prototype.getFill);
- goog.exportProperty(
- ol.style.Style.prototype,
- 'setFill',
- ol.style.Style.prototype.setFill);
- goog.exportProperty(
- ol.style.Style.prototype,
- 'getImage',
- ol.style.Style.prototype.getImage);
- goog.exportProperty(
- ol.style.Style.prototype,
- 'setImage',
- ol.style.Style.prototype.setImage);
- goog.exportProperty(
- ol.style.Style.prototype,
- 'getStroke',
- ol.style.Style.prototype.getStroke);
- goog.exportProperty(
- ol.style.Style.prototype,
- 'setStroke',
- ol.style.Style.prototype.setStroke);
- goog.exportProperty(
- ol.style.Style.prototype,
- 'getText',
- ol.style.Style.prototype.getText);
- goog.exportProperty(
- ol.style.Style.prototype,
- 'setText',
- ol.style.Style.prototype.setText);
- goog.exportProperty(
- ol.style.Style.prototype,
- 'getZIndex',
- ol.style.Style.prototype.getZIndex);
- goog.exportProperty(
- ol.style.Style.prototype,
- 'setGeometry',
- ol.style.Style.prototype.setGeometry);
- goog.exportProperty(
- ol.style.Style.prototype,
- 'setZIndex',
- ol.style.Style.prototype.setZIndex);
- goog.exportSymbol(
- 'ol.style.Text',
- ol.style.Text,
- OPENLAYERS);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'clone',
- ol.style.Text.prototype.clone);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'getOverflow',
- ol.style.Text.prototype.getOverflow);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'getFont',
- ol.style.Text.prototype.getFont);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'getMaxAngle',
- ol.style.Text.prototype.getMaxAngle);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'getPlacement',
- ol.style.Text.prototype.getPlacement);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'getOffsetX',
- ol.style.Text.prototype.getOffsetX);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'getOffsetY',
- ol.style.Text.prototype.getOffsetY);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'getFill',
- ol.style.Text.prototype.getFill);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'getRotateWithView',
- ol.style.Text.prototype.getRotateWithView);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'getRotation',
- ol.style.Text.prototype.getRotation);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'getScale',
- ol.style.Text.prototype.getScale);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'getStroke',
- ol.style.Text.prototype.getStroke);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'getText',
- ol.style.Text.prototype.getText);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'getTextAlign',
- ol.style.Text.prototype.getTextAlign);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'getTextBaseline',
- ol.style.Text.prototype.getTextBaseline);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'getBackgroundFill',
- ol.style.Text.prototype.getBackgroundFill);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'getBackgroundStroke',
- ol.style.Text.prototype.getBackgroundStroke);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'getPadding',
- ol.style.Text.prototype.getPadding);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'setOverflow',
- ol.style.Text.prototype.setOverflow);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'setFont',
- ol.style.Text.prototype.setFont);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'setMaxAngle',
- ol.style.Text.prototype.setMaxAngle);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'setOffsetX',
- ol.style.Text.prototype.setOffsetX);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'setOffsetY',
- ol.style.Text.prototype.setOffsetY);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'setPlacement',
- ol.style.Text.prototype.setPlacement);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'setFill',
- ol.style.Text.prototype.setFill);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'setRotation',
- ol.style.Text.prototype.setRotation);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'setScale',
- ol.style.Text.prototype.setScale);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'setStroke',
- ol.style.Text.prototype.setStroke);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'setText',
- ol.style.Text.prototype.setText);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'setTextAlign',
- ol.style.Text.prototype.setTextAlign);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'setTextBaseline',
- ol.style.Text.prototype.setTextBaseline);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'setBackgroundFill',
- ol.style.Text.prototype.setBackgroundFill);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'setBackgroundStroke',
- ol.style.Text.prototype.setBackgroundStroke);
- goog.exportProperty(
- ol.style.Text.prototype,
- 'setPadding',
- ol.style.Text.prototype.setPadding);
- goog.exportSymbol(
- 'ol.source.BingMaps',
- ol.source.BingMaps,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.source.BingMaps.TOS_ATTRIBUTION',
- ol.source.BingMaps.TOS_ATTRIBUTION,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'getApiKey',
- ol.source.BingMaps.prototype.getApiKey);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'getImagerySet',
- ol.source.BingMaps.prototype.getImagerySet);
- goog.exportSymbol(
- 'ol.source.CartoDB',
- ol.source.CartoDB,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'getConfig',
- ol.source.CartoDB.prototype.getConfig);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'updateConfig',
- ol.source.CartoDB.prototype.updateConfig);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'setConfig',
- ol.source.CartoDB.prototype.setConfig);
- goog.exportSymbol(
- 'ol.source.Cluster',
- ol.source.Cluster,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'getDistance',
- ol.source.Cluster.prototype.getDistance);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'getSource',
- ol.source.Cluster.prototype.getSource);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'setDistance',
- ol.source.Cluster.prototype.setDistance);
- goog.exportSymbol(
- 'ol.source.Image',
- ol.source.Image,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.Image.Event.prototype,
- 'image',
- ol.source.Image.Event.prototype.image);
- goog.exportSymbol(
- 'ol.source.ImageArcGISRest',
- ol.source.ImageArcGISRest,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'getParams',
- ol.source.ImageArcGISRest.prototype.getParams);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'getImageLoadFunction',
- ol.source.ImageArcGISRest.prototype.getImageLoadFunction);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'getUrl',
- ol.source.ImageArcGISRest.prototype.getUrl);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'setImageLoadFunction',
- ol.source.ImageArcGISRest.prototype.setImageLoadFunction);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'setUrl',
- ol.source.ImageArcGISRest.prototype.setUrl);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'updateParams',
- ol.source.ImageArcGISRest.prototype.updateParams);
- goog.exportSymbol(
- 'ol.source.ImageCanvas',
- ol.source.ImageCanvas,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.source.ImageMapGuide',
- ol.source.ImageMapGuide,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'getParams',
- ol.source.ImageMapGuide.prototype.getParams);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'getImageLoadFunction',
- ol.source.ImageMapGuide.prototype.getImageLoadFunction);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'updateParams',
- ol.source.ImageMapGuide.prototype.updateParams);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'setImageLoadFunction',
- ol.source.ImageMapGuide.prototype.setImageLoadFunction);
- goog.exportSymbol(
- 'ol.source.ImageStatic',
- ol.source.ImageStatic,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.source.ImageVector',
- ol.source.ImageVector,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'getSource',
- ol.source.ImageVector.prototype.getSource);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'getStyle',
- ol.source.ImageVector.prototype.getStyle);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'getStyleFunction',
- ol.source.ImageVector.prototype.getStyleFunction);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'setStyle',
- ol.source.ImageVector.prototype.setStyle);
- goog.exportSymbol(
- 'ol.source.ImageWMS',
- ol.source.ImageWMS,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'getGetFeatureInfoUrl',
- ol.source.ImageWMS.prototype.getGetFeatureInfoUrl);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'getParams',
- ol.source.ImageWMS.prototype.getParams);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'getImageLoadFunction',
- ol.source.ImageWMS.prototype.getImageLoadFunction);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'getUrl',
- ol.source.ImageWMS.prototype.getUrl);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'setImageLoadFunction',
- ol.source.ImageWMS.prototype.setImageLoadFunction);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'setUrl',
- ol.source.ImageWMS.prototype.setUrl);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'updateParams',
- ol.source.ImageWMS.prototype.updateParams);
- goog.exportSymbol(
- 'ol.source.OSM',
- ol.source.OSM,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.source.OSM.ATTRIBUTION',
- ol.source.OSM.ATTRIBUTION,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.source.Raster',
- ol.source.Raster,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'setOperation',
- ol.source.Raster.prototype.setOperation);
- goog.exportProperty(
- ol.source.Raster.Event.prototype,
- 'extent',
- ol.source.Raster.Event.prototype.extent);
- goog.exportProperty(
- ol.source.Raster.Event.prototype,
- 'resolution',
- ol.source.Raster.Event.prototype.resolution);
- goog.exportProperty(
- ol.source.Raster.Event.prototype,
- 'data',
- ol.source.Raster.Event.prototype.data);
- goog.exportSymbol(
- 'ol.source.Source',
- ol.source.Source,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.Source.prototype,
- 'getAttributions',
- ol.source.Source.prototype.getAttributions);
- goog.exportProperty(
- ol.source.Source.prototype,
- 'getLogo',
- ol.source.Source.prototype.getLogo);
- goog.exportProperty(
- ol.source.Source.prototype,
- 'getProjection',
- ol.source.Source.prototype.getProjection);
- goog.exportProperty(
- ol.source.Source.prototype,
- 'getState',
- ol.source.Source.prototype.getState);
- goog.exportProperty(
- ol.source.Source.prototype,
- 'refresh',
- ol.source.Source.prototype.refresh);
- goog.exportProperty(
- ol.source.Source.prototype,
- 'setAttributions',
- ol.source.Source.prototype.setAttributions);
- goog.exportSymbol(
- 'ol.source.Stamen',
- ol.source.Stamen,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.source.Tile',
- ol.source.Tile,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'getTileGrid',
- ol.source.Tile.prototype.getTileGrid);
- goog.exportProperty(
- ol.source.Tile.Event.prototype,
- 'tile',
- ol.source.Tile.Event.prototype.tile);
- goog.exportSymbol(
- 'ol.source.TileArcGISRest',
- ol.source.TileArcGISRest,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'getParams',
- ol.source.TileArcGISRest.prototype.getParams);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'updateParams',
- ol.source.TileArcGISRest.prototype.updateParams);
- goog.exportSymbol(
- 'ol.source.TileDebug',
- ol.source.TileDebug,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.source.TileImage',
- ol.source.TileImage,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'setRenderReprojectionEdges',
- ol.source.TileImage.prototype.setRenderReprojectionEdges);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'setTileGridForProjection',
- ol.source.TileImage.prototype.setTileGridForProjection);
- goog.exportSymbol(
- 'ol.source.TileJSON',
- ol.source.TileJSON,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'getTileJSON',
- ol.source.TileJSON.prototype.getTileJSON);
- goog.exportSymbol(
- 'ol.source.TileUTFGrid',
- ol.source.TileUTFGrid,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'getTemplate',
- ol.source.TileUTFGrid.prototype.getTemplate);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'forDataAtCoordinateAndResolution',
- ol.source.TileUTFGrid.prototype.forDataAtCoordinateAndResolution);
- goog.exportSymbol(
- 'ol.source.TileWMS',
- ol.source.TileWMS,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'getGetFeatureInfoUrl',
- ol.source.TileWMS.prototype.getGetFeatureInfoUrl);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'getParams',
- ol.source.TileWMS.prototype.getParams);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'updateParams',
- ol.source.TileWMS.prototype.updateParams);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'getTileLoadFunction',
- ol.source.UrlTile.prototype.getTileLoadFunction);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'getTileUrlFunction',
- ol.source.UrlTile.prototype.getTileUrlFunction);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'getUrls',
- ol.source.UrlTile.prototype.getUrls);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'setTileLoadFunction',
- ol.source.UrlTile.prototype.setTileLoadFunction);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'setTileUrlFunction',
- ol.source.UrlTile.prototype.setTileUrlFunction);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'setUrl',
- ol.source.UrlTile.prototype.setUrl);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'setUrls',
- ol.source.UrlTile.prototype.setUrls);
- goog.exportSymbol(
- 'ol.source.Vector',
- ol.source.Vector,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'addFeature',
- ol.source.Vector.prototype.addFeature);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'addFeatures',
- ol.source.Vector.prototype.addFeatures);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'clear',
- ol.source.Vector.prototype.clear);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'forEachFeature',
- ol.source.Vector.prototype.forEachFeature);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'forEachFeatureInExtent',
- ol.source.Vector.prototype.forEachFeatureInExtent);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'forEachFeatureIntersectingExtent',
- ol.source.Vector.prototype.forEachFeatureIntersectingExtent);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'getFeaturesCollection',
- ol.source.Vector.prototype.getFeaturesCollection);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'getFeatures',
- ol.source.Vector.prototype.getFeatures);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'getFeaturesAtCoordinate',
- ol.source.Vector.prototype.getFeaturesAtCoordinate);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'getFeaturesInExtent',
- ol.source.Vector.prototype.getFeaturesInExtent);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'getClosestFeatureToCoordinate',
- ol.source.Vector.prototype.getClosestFeatureToCoordinate);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'getExtent',
- ol.source.Vector.prototype.getExtent);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'getFeatureById',
- ol.source.Vector.prototype.getFeatureById);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'getFormat',
- ol.source.Vector.prototype.getFormat);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'getUrl',
- ol.source.Vector.prototype.getUrl);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'removeLoadedExtent',
- ol.source.Vector.prototype.removeLoadedExtent);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'removeFeature',
- ol.source.Vector.prototype.removeFeature);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'setLoader',
- ol.source.Vector.prototype.setLoader);
- goog.exportProperty(
- ol.source.Vector.Event.prototype,
- 'feature',
- ol.source.Vector.Event.prototype.feature);
- goog.exportSymbol(
- 'ol.source.VectorTile',
- ol.source.VectorTile,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'clear',
- ol.source.VectorTile.prototype.clear);
- goog.exportSymbol(
- 'ol.source.WMTS',
- ol.source.WMTS,
- OPENLAYERS);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'getDimensions',
- ol.source.WMTS.prototype.getDimensions);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'getFormat',
- ol.source.WMTS.prototype.getFormat);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'getLayer',
- ol.source.WMTS.prototype.getLayer);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'getMatrixSet',
- ol.source.WMTS.prototype.getMatrixSet);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'getRequestEncoding',
- ol.source.WMTS.prototype.getRequestEncoding);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'getStyle',
- ol.source.WMTS.prototype.getStyle);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'getVersion',
- ol.source.WMTS.prototype.getVersion);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'updateDimensions',
- ol.source.WMTS.prototype.updateDimensions);
- goog.exportSymbol(
- 'ol.source.WMTS.optionsFromCapabilities',
- ol.source.WMTS.optionsFromCapabilities,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.source.XYZ',
- ol.source.XYZ,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.source.Zoomify',
- ol.source.Zoomify,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.renderer.webgl.ImageLayer',
- ol.renderer.webgl.ImageLayer,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.renderer.webgl.Map',
- ol.renderer.webgl.Map,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.renderer.webgl.TileLayer',
- ol.renderer.webgl.TileLayer,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.renderer.webgl.VectorLayer',
- ol.renderer.webgl.VectorLayer,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.renderer.canvas.ImageLayer',
- ol.renderer.canvas.ImageLayer,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.renderer.canvas.Map',
- ol.renderer.canvas.Map,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.renderer.canvas.TileLayer',
- ol.renderer.canvas.TileLayer,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.renderer.canvas.VectorLayer',
- ol.renderer.canvas.VectorLayer,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.renderer.canvas.VectorTileLayer',
- ol.renderer.canvas.VectorTileLayer,
- OPENLAYERS);
- goog.exportProperty(
- ol.render.Event.prototype,
- 'vectorContext',
- ol.render.Event.prototype.vectorContext);
- goog.exportProperty(
- ol.render.Event.prototype,
- 'frameState',
- ol.render.Event.prototype.frameState);
- goog.exportProperty(
- ol.render.Event.prototype,
- 'context',
- ol.render.Event.prototype.context);
- goog.exportProperty(
- ol.render.Event.prototype,
- 'glContext',
- ol.render.Event.prototype.glContext);
- goog.exportProperty(
- ol.render.Feature.prototype,
- 'get',
- ol.render.Feature.prototype.get);
- goog.exportProperty(
- ol.render.Feature.prototype,
- 'getExtent',
- ol.render.Feature.prototype.getExtent);
- goog.exportProperty(
- ol.render.Feature.prototype,
- 'getId',
- ol.render.Feature.prototype.getId);
- goog.exportProperty(
- ol.render.Feature.prototype,
- 'getGeometry',
- ol.render.Feature.prototype.getGeometry);
- goog.exportProperty(
- ol.render.Feature.prototype,
- 'getProperties',
- ol.render.Feature.prototype.getProperties);
- goog.exportProperty(
- ol.render.Feature.prototype,
- 'getType',
- ol.render.Feature.prototype.getType);
- goog.exportSymbol(
- 'ol.render.VectorContext',
- ol.render.VectorContext,
- OPENLAYERS);
- goog.exportProperty(
- ol.render.webgl.Immediate.prototype,
- 'setStyle',
- ol.render.webgl.Immediate.prototype.setStyle);
- goog.exportProperty(
- ol.render.webgl.Immediate.prototype,
- 'drawGeometry',
- ol.render.webgl.Immediate.prototype.drawGeometry);
- goog.exportProperty(
- ol.render.webgl.Immediate.prototype,
- 'drawFeature',
- ol.render.webgl.Immediate.prototype.drawFeature);
- goog.exportProperty(
- ol.render.canvas.Immediate.prototype,
- 'drawCircle',
- ol.render.canvas.Immediate.prototype.drawCircle);
- goog.exportProperty(
- ol.render.canvas.Immediate.prototype,
- 'setStyle',
- ol.render.canvas.Immediate.prototype.setStyle);
- goog.exportProperty(
- ol.render.canvas.Immediate.prototype,
- 'drawGeometry',
- ol.render.canvas.Immediate.prototype.drawGeometry);
- goog.exportProperty(
- ol.render.canvas.Immediate.prototype,
- 'drawFeature',
- ol.render.canvas.Immediate.prototype.drawFeature);
- goog.exportSymbol(
- 'ol.proj.common.add',
- ol.proj.common.add,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.proj.Projection',
- ol.proj.Projection,
- OPENLAYERS);
- goog.exportProperty(
- ol.proj.Projection.prototype,
- 'getCode',
- ol.proj.Projection.prototype.getCode);
- goog.exportProperty(
- ol.proj.Projection.prototype,
- 'getExtent',
- ol.proj.Projection.prototype.getExtent);
- goog.exportProperty(
- ol.proj.Projection.prototype,
- 'getUnits',
- ol.proj.Projection.prototype.getUnits);
- goog.exportProperty(
- ol.proj.Projection.prototype,
- 'getMetersPerUnit',
- ol.proj.Projection.prototype.getMetersPerUnit);
- goog.exportProperty(
- ol.proj.Projection.prototype,
- 'getWorldExtent',
- ol.proj.Projection.prototype.getWorldExtent);
- goog.exportProperty(
- ol.proj.Projection.prototype,
- 'getAxisOrientation',
- ol.proj.Projection.prototype.getAxisOrientation);
- goog.exportProperty(
- ol.proj.Projection.prototype,
- 'isGlobal',
- ol.proj.Projection.prototype.isGlobal);
- goog.exportProperty(
- ol.proj.Projection.prototype,
- 'setGlobal',
- ol.proj.Projection.prototype.setGlobal);
- goog.exportProperty(
- ol.proj.Projection.prototype,
- 'setExtent',
- ol.proj.Projection.prototype.setExtent);
- goog.exportProperty(
- ol.proj.Projection.prototype,
- 'setWorldExtent',
- ol.proj.Projection.prototype.setWorldExtent);
- goog.exportProperty(
- ol.proj.Projection.prototype,
- 'setGetPointResolution',
- ol.proj.Projection.prototype.setGetPointResolution);
- goog.exportSymbol(
- 'ol.proj.Units.METERS_PER_UNIT',
- ol.proj.Units.METERS_PER_UNIT,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.layer.Base',
- ol.layer.Base,
- OPENLAYERS);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'getExtent',
- ol.layer.Base.prototype.getExtent);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'getMaxResolution',
- ol.layer.Base.prototype.getMaxResolution);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'getMinResolution',
- ol.layer.Base.prototype.getMinResolution);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'getOpacity',
- ol.layer.Base.prototype.getOpacity);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'getVisible',
- ol.layer.Base.prototype.getVisible);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'getZIndex',
- ol.layer.Base.prototype.getZIndex);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'setExtent',
- ol.layer.Base.prototype.setExtent);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'setMaxResolution',
- ol.layer.Base.prototype.setMaxResolution);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'setMinResolution',
- ol.layer.Base.prototype.setMinResolution);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'setOpacity',
- ol.layer.Base.prototype.setOpacity);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'setVisible',
- ol.layer.Base.prototype.setVisible);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'setZIndex',
- ol.layer.Base.prototype.setZIndex);
- goog.exportSymbol(
- 'ol.layer.Group',
- ol.layer.Group,
- OPENLAYERS);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'getLayers',
- ol.layer.Group.prototype.getLayers);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'setLayers',
- ol.layer.Group.prototype.setLayers);
- goog.exportSymbol(
- 'ol.layer.Heatmap',
- ol.layer.Heatmap,
- OPENLAYERS);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'getBlur',
- ol.layer.Heatmap.prototype.getBlur);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'getGradient',
- ol.layer.Heatmap.prototype.getGradient);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'getRadius',
- ol.layer.Heatmap.prototype.getRadius);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'setBlur',
- ol.layer.Heatmap.prototype.setBlur);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'setGradient',
- ol.layer.Heatmap.prototype.setGradient);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'setRadius',
- ol.layer.Heatmap.prototype.setRadius);
- goog.exportSymbol(
- 'ol.layer.Image',
- ol.layer.Image,
- OPENLAYERS);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'getSource',
- ol.layer.Image.prototype.getSource);
- goog.exportSymbol(
- 'ol.layer.Layer',
- ol.layer.Layer,
- OPENLAYERS);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'getSource',
- ol.layer.Layer.prototype.getSource);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'setMap',
- ol.layer.Layer.prototype.setMap);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'setSource',
- ol.layer.Layer.prototype.setSource);
- goog.exportSymbol(
- 'ol.layer.Tile',
- ol.layer.Tile,
- OPENLAYERS);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'getPreload',
- ol.layer.Tile.prototype.getPreload);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'getSource',
- ol.layer.Tile.prototype.getSource);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'setPreload',
- ol.layer.Tile.prototype.setPreload);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'getUseInterimTilesOnError',
- ol.layer.Tile.prototype.getUseInterimTilesOnError);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'setUseInterimTilesOnError',
- ol.layer.Tile.prototype.setUseInterimTilesOnError);
- goog.exportSymbol(
- 'ol.layer.Vector',
- ol.layer.Vector,
- OPENLAYERS);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'getSource',
- ol.layer.Vector.prototype.getSource);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'getStyle',
- ol.layer.Vector.prototype.getStyle);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'getStyleFunction',
- ol.layer.Vector.prototype.getStyleFunction);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'setStyle',
- ol.layer.Vector.prototype.setStyle);
- goog.exportSymbol(
- 'ol.layer.VectorTile',
- ol.layer.VectorTile,
- OPENLAYERS);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'getPreload',
- ol.layer.VectorTile.prototype.getPreload);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'getUseInterimTilesOnError',
- ol.layer.VectorTile.prototype.getUseInterimTilesOnError);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'setPreload',
- ol.layer.VectorTile.prototype.setPreload);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'setUseInterimTilesOnError',
- ol.layer.VectorTile.prototype.setUseInterimTilesOnError);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'getSource',
- ol.layer.VectorTile.prototype.getSource);
- goog.exportSymbol(
- 'ol.interaction.DoubleClickZoom',
- ol.interaction.DoubleClickZoom,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.DoubleClickZoom.handleEvent',
- ol.interaction.DoubleClickZoom.handleEvent,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.DragAndDrop',
- ol.interaction.DragAndDrop,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.DragAndDrop.handleEvent',
- ol.interaction.DragAndDrop.handleEvent,
- OPENLAYERS);
- goog.exportProperty(
- ol.interaction.DragAndDrop.Event.prototype,
- 'features',
- ol.interaction.DragAndDrop.Event.prototype.features);
- goog.exportProperty(
- ol.interaction.DragAndDrop.Event.prototype,
- 'file',
- ol.interaction.DragAndDrop.Event.prototype.file);
- goog.exportProperty(
- ol.interaction.DragAndDrop.Event.prototype,
- 'projection',
- ol.interaction.DragAndDrop.Event.prototype.projection);
- goog.exportSymbol(
- 'ol.interaction.DragBox',
- ol.interaction.DragBox,
- OPENLAYERS);
- goog.exportProperty(
- ol.interaction.DragBox.prototype,
- 'getGeometry',
- ol.interaction.DragBox.prototype.getGeometry);
- goog.exportProperty(
- ol.interaction.DragBox.Event.prototype,
- 'coordinate',
- ol.interaction.DragBox.Event.prototype.coordinate);
- goog.exportProperty(
- ol.interaction.DragBox.Event.prototype,
- 'mapBrowserEvent',
- ol.interaction.DragBox.Event.prototype.mapBrowserEvent);
- goog.exportSymbol(
- 'ol.interaction.DragPan',
- ol.interaction.DragPan,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.DragRotate',
- ol.interaction.DragRotate,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.DragRotateAndZoom',
- ol.interaction.DragRotateAndZoom,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.DragZoom',
- ol.interaction.DragZoom,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.Draw',
- ol.interaction.Draw,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.Draw.handleEvent',
- ol.interaction.Draw.handleEvent,
- OPENLAYERS);
- goog.exportProperty(
- ol.interaction.Draw.prototype,
- 'removeLastPoint',
- ol.interaction.Draw.prototype.removeLastPoint);
- goog.exportProperty(
- ol.interaction.Draw.prototype,
- 'finishDrawing',
- ol.interaction.Draw.prototype.finishDrawing);
- goog.exportProperty(
- ol.interaction.Draw.prototype,
- 'extend',
- ol.interaction.Draw.prototype.extend);
- goog.exportSymbol(
- 'ol.interaction.Draw.createRegularPolygon',
- ol.interaction.Draw.createRegularPolygon,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.Draw.createBox',
- ol.interaction.Draw.createBox,
- OPENLAYERS);
- goog.exportProperty(
- ol.interaction.Draw.Event.prototype,
- 'feature',
- ol.interaction.Draw.Event.prototype.feature);
- goog.exportSymbol(
- 'ol.interaction.Extent',
- ol.interaction.Extent,
- OPENLAYERS);
- goog.exportProperty(
- ol.interaction.Extent.prototype,
- 'getExtent',
- ol.interaction.Extent.prototype.getExtent);
- goog.exportProperty(
- ol.interaction.Extent.prototype,
- 'setExtent',
- ol.interaction.Extent.prototype.setExtent);
- goog.exportProperty(
- ol.interaction.Extent.Event.prototype,
- 'extent',
- ol.interaction.Extent.Event.prototype.extent);
- goog.exportSymbol(
- 'ol.interaction.Interaction',
- ol.interaction.Interaction,
- OPENLAYERS);
- goog.exportProperty(
- ol.interaction.Interaction.prototype,
- 'getActive',
- ol.interaction.Interaction.prototype.getActive);
- goog.exportProperty(
- ol.interaction.Interaction.prototype,
- 'getMap',
- ol.interaction.Interaction.prototype.getMap);
- goog.exportProperty(
- ol.interaction.Interaction.prototype,
- 'setActive',
- ol.interaction.Interaction.prototype.setActive);
- goog.exportSymbol(
- 'ol.interaction.KeyboardPan',
- ol.interaction.KeyboardPan,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.KeyboardPan.handleEvent',
- ol.interaction.KeyboardPan.handleEvent,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.KeyboardZoom',
- ol.interaction.KeyboardZoom,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.KeyboardZoom.handleEvent',
- ol.interaction.KeyboardZoom.handleEvent,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.Modify',
- ol.interaction.Modify,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.Modify.handleEvent',
- ol.interaction.Modify.handleEvent,
- OPENLAYERS);
- goog.exportProperty(
- ol.interaction.Modify.prototype,
- 'removePoint',
- ol.interaction.Modify.prototype.removePoint);
- goog.exportProperty(
- ol.interaction.Modify.Event.prototype,
- 'features',
- ol.interaction.Modify.Event.prototype.features);
- goog.exportProperty(
- ol.interaction.Modify.Event.prototype,
- 'mapBrowserEvent',
- ol.interaction.Modify.Event.prototype.mapBrowserEvent);
- goog.exportSymbol(
- 'ol.interaction.MouseWheelZoom',
- ol.interaction.MouseWheelZoom,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.MouseWheelZoom.handleEvent',
- ol.interaction.MouseWheelZoom.handleEvent,
- OPENLAYERS);
- goog.exportProperty(
- ol.interaction.MouseWheelZoom.prototype,
- 'setMouseAnchor',
- ol.interaction.MouseWheelZoom.prototype.setMouseAnchor);
- goog.exportSymbol(
- 'ol.interaction.PinchRotate',
- ol.interaction.PinchRotate,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.PinchZoom',
- ol.interaction.PinchZoom,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.Pointer',
- ol.interaction.Pointer,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.Pointer.handleEvent',
- ol.interaction.Pointer.handleEvent,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.interaction.Select',
- ol.interaction.Select,
- OPENLAYERS);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'getFeatures',
- ol.interaction.Select.prototype.getFeatures);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'getHitTolerance',
- ol.interaction.Select.prototype.getHitTolerance);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'getLayer',
- ol.interaction.Select.prototype.getLayer);
- goog.exportSymbol(
- 'ol.interaction.Select.handleEvent',
- ol.interaction.Select.handleEvent,
- OPENLAYERS);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'setHitTolerance',
- ol.interaction.Select.prototype.setHitTolerance);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'setMap',
- ol.interaction.Select.prototype.setMap);
- goog.exportProperty(
- ol.interaction.Select.Event.prototype,
- 'selected',
- ol.interaction.Select.Event.prototype.selected);
- goog.exportProperty(
- ol.interaction.Select.Event.prototype,
- 'deselected',
- ol.interaction.Select.Event.prototype.deselected);
- goog.exportProperty(
- ol.interaction.Select.Event.prototype,
- 'mapBrowserEvent',
- ol.interaction.Select.Event.prototype.mapBrowserEvent);
- goog.exportSymbol(
- 'ol.interaction.Snap',
- ol.interaction.Snap,
- OPENLAYERS);
- goog.exportProperty(
- ol.interaction.Snap.prototype,
- 'addFeature',
- ol.interaction.Snap.prototype.addFeature);
- goog.exportProperty(
- ol.interaction.Snap.prototype,
- 'removeFeature',
- ol.interaction.Snap.prototype.removeFeature);
- goog.exportSymbol(
- 'ol.interaction.Translate',
- ol.interaction.Translate,
- OPENLAYERS);
- goog.exportProperty(
- ol.interaction.Translate.prototype,
- 'getHitTolerance',
- ol.interaction.Translate.prototype.getHitTolerance);
- goog.exportProperty(
- ol.interaction.Translate.prototype,
- 'setHitTolerance',
- ol.interaction.Translate.prototype.setHitTolerance);
- goog.exportProperty(
- ol.interaction.Translate.Event.prototype,
- 'features',
- ol.interaction.Translate.Event.prototype.features);
- goog.exportProperty(
- ol.interaction.Translate.Event.prototype,
- 'coordinate',
- ol.interaction.Translate.Event.prototype.coordinate);
- goog.exportSymbol(
- 'ol.geom.Circle',
- ol.geom.Circle,
- OPENLAYERS);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'clone',
- ol.geom.Circle.prototype.clone);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'getCenter',
- ol.geom.Circle.prototype.getCenter);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'getRadius',
- ol.geom.Circle.prototype.getRadius);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'getType',
- ol.geom.Circle.prototype.getType);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'intersectsExtent',
- ol.geom.Circle.prototype.intersectsExtent);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'setCenter',
- ol.geom.Circle.prototype.setCenter);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'setCenterAndRadius',
- ol.geom.Circle.prototype.setCenterAndRadius);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'setRadius',
- ol.geom.Circle.prototype.setRadius);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'transform',
- ol.geom.Circle.prototype.transform);
- goog.exportSymbol(
- 'ol.geom.Geometry',
- ol.geom.Geometry,
- OPENLAYERS);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'getClosestPoint',
- ol.geom.Geometry.prototype.getClosestPoint);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'intersectsCoordinate',
- ol.geom.Geometry.prototype.intersectsCoordinate);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'getExtent',
- ol.geom.Geometry.prototype.getExtent);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'rotate',
- ol.geom.Geometry.prototype.rotate);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'scale',
- ol.geom.Geometry.prototype.scale);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'simplify',
- ol.geom.Geometry.prototype.simplify);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'transform',
- ol.geom.Geometry.prototype.transform);
- goog.exportSymbol(
- 'ol.geom.GeometryCollection',
- ol.geom.GeometryCollection,
- OPENLAYERS);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'clone',
- ol.geom.GeometryCollection.prototype.clone);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'getGeometries',
- ol.geom.GeometryCollection.prototype.getGeometries);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'getType',
- ol.geom.GeometryCollection.prototype.getType);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'intersectsExtent',
- ol.geom.GeometryCollection.prototype.intersectsExtent);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'setGeometries',
- ol.geom.GeometryCollection.prototype.setGeometries);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'applyTransform',
- ol.geom.GeometryCollection.prototype.applyTransform);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'translate',
- ol.geom.GeometryCollection.prototype.translate);
- goog.exportSymbol(
- 'ol.geom.LinearRing',
- ol.geom.LinearRing,
- OPENLAYERS);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'clone',
- ol.geom.LinearRing.prototype.clone);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'getArea',
- ol.geom.LinearRing.prototype.getArea);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'getCoordinates',
- ol.geom.LinearRing.prototype.getCoordinates);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'getType',
- ol.geom.LinearRing.prototype.getType);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'setCoordinates',
- ol.geom.LinearRing.prototype.setCoordinates);
- goog.exportSymbol(
- 'ol.geom.LineString',
- ol.geom.LineString,
- OPENLAYERS);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'appendCoordinate',
- ol.geom.LineString.prototype.appendCoordinate);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'clone',
- ol.geom.LineString.prototype.clone);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'forEachSegment',
- ol.geom.LineString.prototype.forEachSegment);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'getCoordinateAtM',
- ol.geom.LineString.prototype.getCoordinateAtM);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'getCoordinates',
- ol.geom.LineString.prototype.getCoordinates);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'getCoordinateAt',
- ol.geom.LineString.prototype.getCoordinateAt);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'getLength',
- ol.geom.LineString.prototype.getLength);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'getType',
- ol.geom.LineString.prototype.getType);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'intersectsExtent',
- ol.geom.LineString.prototype.intersectsExtent);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'setCoordinates',
- ol.geom.LineString.prototype.setCoordinates);
- goog.exportSymbol(
- 'ol.geom.MultiLineString',
- ol.geom.MultiLineString,
- OPENLAYERS);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'appendLineString',
- ol.geom.MultiLineString.prototype.appendLineString);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'clone',
- ol.geom.MultiLineString.prototype.clone);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'getCoordinateAtM',
- ol.geom.MultiLineString.prototype.getCoordinateAtM);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'getCoordinates',
- ol.geom.MultiLineString.prototype.getCoordinates);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'getLineString',
- ol.geom.MultiLineString.prototype.getLineString);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'getLineStrings',
- ol.geom.MultiLineString.prototype.getLineStrings);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'getType',
- ol.geom.MultiLineString.prototype.getType);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'intersectsExtent',
- ol.geom.MultiLineString.prototype.intersectsExtent);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'setCoordinates',
- ol.geom.MultiLineString.prototype.setCoordinates);
- goog.exportSymbol(
- 'ol.geom.MultiPoint',
- ol.geom.MultiPoint,
- OPENLAYERS);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'appendPoint',
- ol.geom.MultiPoint.prototype.appendPoint);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'clone',
- ol.geom.MultiPoint.prototype.clone);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'getCoordinates',
- ol.geom.MultiPoint.prototype.getCoordinates);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'getPoint',
- ol.geom.MultiPoint.prototype.getPoint);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'getPoints',
- ol.geom.MultiPoint.prototype.getPoints);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'getType',
- ol.geom.MultiPoint.prototype.getType);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'intersectsExtent',
- ol.geom.MultiPoint.prototype.intersectsExtent);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'setCoordinates',
- ol.geom.MultiPoint.prototype.setCoordinates);
- goog.exportSymbol(
- 'ol.geom.MultiPolygon',
- ol.geom.MultiPolygon,
- OPENLAYERS);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'appendPolygon',
- ol.geom.MultiPolygon.prototype.appendPolygon);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'clone',
- ol.geom.MultiPolygon.prototype.clone);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'getArea',
- ol.geom.MultiPolygon.prototype.getArea);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'getCoordinates',
- ol.geom.MultiPolygon.prototype.getCoordinates);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'getInteriorPoints',
- ol.geom.MultiPolygon.prototype.getInteriorPoints);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'getPolygon',
- ol.geom.MultiPolygon.prototype.getPolygon);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'getPolygons',
- ol.geom.MultiPolygon.prototype.getPolygons);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'getType',
- ol.geom.MultiPolygon.prototype.getType);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'intersectsExtent',
- ol.geom.MultiPolygon.prototype.intersectsExtent);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'setCoordinates',
- ol.geom.MultiPolygon.prototype.setCoordinates);
- goog.exportSymbol(
- 'ol.geom.Point',
- ol.geom.Point,
- OPENLAYERS);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'clone',
- ol.geom.Point.prototype.clone);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'getCoordinates',
- ol.geom.Point.prototype.getCoordinates);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'getType',
- ol.geom.Point.prototype.getType);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'intersectsExtent',
- ol.geom.Point.prototype.intersectsExtent);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'setCoordinates',
- ol.geom.Point.prototype.setCoordinates);
- goog.exportSymbol(
- 'ol.geom.Polygon',
- ol.geom.Polygon,
- OPENLAYERS);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'appendLinearRing',
- ol.geom.Polygon.prototype.appendLinearRing);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'clone',
- ol.geom.Polygon.prototype.clone);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'getArea',
- ol.geom.Polygon.prototype.getArea);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'getCoordinates',
- ol.geom.Polygon.prototype.getCoordinates);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'getInteriorPoint',
- ol.geom.Polygon.prototype.getInteriorPoint);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'getLinearRingCount',
- ol.geom.Polygon.prototype.getLinearRingCount);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'getLinearRing',
- ol.geom.Polygon.prototype.getLinearRing);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'getLinearRings',
- ol.geom.Polygon.prototype.getLinearRings);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'getType',
- ol.geom.Polygon.prototype.getType);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'intersectsExtent',
- ol.geom.Polygon.prototype.intersectsExtent);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'setCoordinates',
- ol.geom.Polygon.prototype.setCoordinates);
- goog.exportSymbol(
- 'ol.geom.Polygon.circular',
- ol.geom.Polygon.circular,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.geom.Polygon.fromExtent',
- ol.geom.Polygon.fromExtent,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.geom.Polygon.fromCircle',
- ol.geom.Polygon.fromCircle,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.geom.SimpleGeometry',
- ol.geom.SimpleGeometry,
- OPENLAYERS);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'getFirstCoordinate',
- ol.geom.SimpleGeometry.prototype.getFirstCoordinate);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'getLastCoordinate',
- ol.geom.SimpleGeometry.prototype.getLastCoordinate);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'getLayout',
- ol.geom.SimpleGeometry.prototype.getLayout);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'applyTransform',
- ol.geom.SimpleGeometry.prototype.applyTransform);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'translate',
- ol.geom.SimpleGeometry.prototype.translate);
- goog.exportSymbol(
- 'ol.format.EsriJSON',
- ol.format.EsriJSON,
- OPENLAYERS);
- goog.exportProperty(
- ol.format.EsriJSON.prototype,
- 'readFeature',
- ol.format.EsriJSON.prototype.readFeature);
- goog.exportProperty(
- ol.format.EsriJSON.prototype,
- 'readFeatures',
- ol.format.EsriJSON.prototype.readFeatures);
- goog.exportProperty(
- ol.format.EsriJSON.prototype,
- 'readGeometry',
- ol.format.EsriJSON.prototype.readGeometry);
- goog.exportProperty(
- ol.format.EsriJSON.prototype,
- 'readProjection',
- ol.format.EsriJSON.prototype.readProjection);
- goog.exportProperty(
- ol.format.EsriJSON.prototype,
- 'writeGeometry',
- ol.format.EsriJSON.prototype.writeGeometry);
- goog.exportProperty(
- ol.format.EsriJSON.prototype,
- 'writeGeometryObject',
- ol.format.EsriJSON.prototype.writeGeometryObject);
- goog.exportProperty(
- ol.format.EsriJSON.prototype,
- 'writeFeature',
- ol.format.EsriJSON.prototype.writeFeature);
- goog.exportProperty(
- ol.format.EsriJSON.prototype,
- 'writeFeatureObject',
- ol.format.EsriJSON.prototype.writeFeatureObject);
- goog.exportProperty(
- ol.format.EsriJSON.prototype,
- 'writeFeatures',
- ol.format.EsriJSON.prototype.writeFeatures);
- goog.exportProperty(
- ol.format.EsriJSON.prototype,
- 'writeFeaturesObject',
- ol.format.EsriJSON.prototype.writeFeaturesObject);
- goog.exportSymbol(
- 'ol.format.Feature',
- ol.format.Feature,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.and',
- ol.format.filter.and,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.or',
- ol.format.filter.or,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.not',
- ol.format.filter.not,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.bbox',
- ol.format.filter.bbox,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.contains',
- ol.format.filter.contains,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.intersects',
- ol.format.filter.intersects,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.within',
- ol.format.filter.within,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.equalTo',
- ol.format.filter.equalTo,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.notEqualTo',
- ol.format.filter.notEqualTo,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.lessThan',
- ol.format.filter.lessThan,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.lessThanOrEqualTo',
- ol.format.filter.lessThanOrEqualTo,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.greaterThan',
- ol.format.filter.greaterThan,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.greaterThanOrEqualTo',
- ol.format.filter.greaterThanOrEqualTo,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.isNull',
- ol.format.filter.isNull,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.between',
- ol.format.filter.between,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.like',
- ol.format.filter.like,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.during',
- ol.format.filter.during,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.GeoJSON',
- ol.format.GeoJSON,
- OPENLAYERS);
- goog.exportProperty(
- ol.format.GeoJSON.prototype,
- 'readFeature',
- ol.format.GeoJSON.prototype.readFeature);
- goog.exportProperty(
- ol.format.GeoJSON.prototype,
- 'readFeatures',
- ol.format.GeoJSON.prototype.readFeatures);
- goog.exportProperty(
- ol.format.GeoJSON.prototype,
- 'readGeometry',
- ol.format.GeoJSON.prototype.readGeometry);
- goog.exportProperty(
- ol.format.GeoJSON.prototype,
- 'readProjection',
- ol.format.GeoJSON.prototype.readProjection);
- goog.exportProperty(
- ol.format.GeoJSON.prototype,
- 'writeFeature',
- ol.format.GeoJSON.prototype.writeFeature);
- goog.exportProperty(
- ol.format.GeoJSON.prototype,
- 'writeFeatureObject',
- ol.format.GeoJSON.prototype.writeFeatureObject);
- goog.exportProperty(
- ol.format.GeoJSON.prototype,
- 'writeFeatures',
- ol.format.GeoJSON.prototype.writeFeatures);
- goog.exportProperty(
- ol.format.GeoJSON.prototype,
- 'writeFeaturesObject',
- ol.format.GeoJSON.prototype.writeFeaturesObject);
- goog.exportProperty(
- ol.format.GeoJSON.prototype,
- 'writeGeometry',
- ol.format.GeoJSON.prototype.writeGeometry);
- goog.exportProperty(
- ol.format.GeoJSON.prototype,
- 'writeGeometryObject',
- ol.format.GeoJSON.prototype.writeGeometryObject);
- goog.exportSymbol(
- 'ol.format.GML',
- ol.format.GML,
- OPENLAYERS);
- goog.exportProperty(
- ol.format.GML.prototype,
- 'writeFeatures',
- ol.format.GML.prototype.writeFeatures);
- goog.exportProperty(
- ol.format.GML.prototype,
- 'writeFeaturesNode',
- ol.format.GML.prototype.writeFeaturesNode);
- goog.exportSymbol(
- 'ol.format.GML2',
- ol.format.GML2,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.GML3',
- ol.format.GML3,
- OPENLAYERS);
- goog.exportProperty(
- ol.format.GML3.prototype,
- 'writeGeometryNode',
- ol.format.GML3.prototype.writeGeometryNode);
- goog.exportProperty(
- ol.format.GML3.prototype,
- 'writeFeatures',
- ol.format.GML3.prototype.writeFeatures);
- goog.exportProperty(
- ol.format.GML3.prototype,
- 'writeFeaturesNode',
- ol.format.GML3.prototype.writeFeaturesNode);
- goog.exportProperty(
- ol.format.GMLBase.prototype,
- 'readFeatures',
- ol.format.GMLBase.prototype.readFeatures);
- goog.exportSymbol(
- 'ol.format.GPX',
- ol.format.GPX,
- OPENLAYERS);
- goog.exportProperty(
- ol.format.GPX.prototype,
- 'readFeature',
- ol.format.GPX.prototype.readFeature);
- goog.exportProperty(
- ol.format.GPX.prototype,
- 'readFeatures',
- ol.format.GPX.prototype.readFeatures);
- goog.exportProperty(
- ol.format.GPX.prototype,
- 'readProjection',
- ol.format.GPX.prototype.readProjection);
- goog.exportProperty(
- ol.format.GPX.prototype,
- 'writeFeatures',
- ol.format.GPX.prototype.writeFeatures);
- goog.exportProperty(
- ol.format.GPX.prototype,
- 'writeFeaturesNode',
- ol.format.GPX.prototype.writeFeaturesNode);
- goog.exportSymbol(
- 'ol.format.IGC',
- ol.format.IGC,
- OPENLAYERS);
- goog.exportProperty(
- ol.format.IGC.prototype,
- 'readFeature',
- ol.format.IGC.prototype.readFeature);
- goog.exportProperty(
- ol.format.IGC.prototype,
- 'readFeatures',
- ol.format.IGC.prototype.readFeatures);
- goog.exportProperty(
- ol.format.IGC.prototype,
- 'readProjection',
- ol.format.IGC.prototype.readProjection);
- goog.exportSymbol(
- 'ol.format.KML',
- ol.format.KML,
- OPENLAYERS);
- goog.exportProperty(
- ol.format.KML.prototype,
- 'readFeature',
- ol.format.KML.prototype.readFeature);
- goog.exportProperty(
- ol.format.KML.prototype,
- 'readFeatures',
- ol.format.KML.prototype.readFeatures);
- goog.exportProperty(
- ol.format.KML.prototype,
- 'readName',
- ol.format.KML.prototype.readName);
- goog.exportProperty(
- ol.format.KML.prototype,
- 'readNetworkLinks',
- ol.format.KML.prototype.readNetworkLinks);
- goog.exportProperty(
- ol.format.KML.prototype,
- 'readRegion',
- ol.format.KML.prototype.readRegion);
- goog.exportProperty(
- ol.format.KML.prototype,
- 'readRegionFromNode',
- ol.format.KML.prototype.readRegionFromNode);
- goog.exportProperty(
- ol.format.KML.prototype,
- 'readProjection',
- ol.format.KML.prototype.readProjection);
- goog.exportProperty(
- ol.format.KML.prototype,
- 'writeFeatures',
- ol.format.KML.prototype.writeFeatures);
- goog.exportProperty(
- ol.format.KML.prototype,
- 'writeFeaturesNode',
- ol.format.KML.prototype.writeFeaturesNode);
- goog.exportSymbol(
- 'ol.format.MVT',
- ol.format.MVT,
- OPENLAYERS);
- goog.exportProperty(
- ol.format.MVT.prototype,
- 'getLastExtent',
- ol.format.MVT.prototype.getLastExtent);
- goog.exportProperty(
- ol.format.MVT.prototype,
- 'readFeatures',
- ol.format.MVT.prototype.readFeatures);
- goog.exportProperty(
- ol.format.MVT.prototype,
- 'readProjection',
- ol.format.MVT.prototype.readProjection);
- goog.exportProperty(
- ol.format.MVT.prototype,
- 'setLayers',
- ol.format.MVT.prototype.setLayers);
- goog.exportSymbol(
- 'ol.format.OSMXML',
- ol.format.OSMXML,
- OPENLAYERS);
- goog.exportProperty(
- ol.format.OSMXML.prototype,
- 'readFeatures',
- ol.format.OSMXML.prototype.readFeatures);
- goog.exportProperty(
- ol.format.OSMXML.prototype,
- 'readProjection',
- ol.format.OSMXML.prototype.readProjection);
- goog.exportSymbol(
- 'ol.format.Polyline',
- ol.format.Polyline,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.Polyline.encodeDeltas',
- ol.format.Polyline.encodeDeltas,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.Polyline.decodeDeltas',
- ol.format.Polyline.decodeDeltas,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.Polyline.encodeFloats',
- ol.format.Polyline.encodeFloats,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.Polyline.decodeFloats',
- ol.format.Polyline.decodeFloats,
- OPENLAYERS);
- goog.exportProperty(
- ol.format.Polyline.prototype,
- 'readFeature',
- ol.format.Polyline.prototype.readFeature);
- goog.exportProperty(
- ol.format.Polyline.prototype,
- 'readFeatures',
- ol.format.Polyline.prototype.readFeatures);
- goog.exportProperty(
- ol.format.Polyline.prototype,
- 'readGeometry',
- ol.format.Polyline.prototype.readGeometry);
- goog.exportProperty(
- ol.format.Polyline.prototype,
- 'readProjection',
- ol.format.Polyline.prototype.readProjection);
- goog.exportProperty(
- ol.format.Polyline.prototype,
- 'writeGeometry',
- ol.format.Polyline.prototype.writeGeometry);
- goog.exportSymbol(
- 'ol.format.TopoJSON',
- ol.format.TopoJSON,
- OPENLAYERS);
- goog.exportProperty(
- ol.format.TopoJSON.prototype,
- 'readFeatures',
- ol.format.TopoJSON.prototype.readFeatures);
- goog.exportProperty(
- ol.format.TopoJSON.prototype,
- 'readProjection',
- ol.format.TopoJSON.prototype.readProjection);
- goog.exportSymbol(
- 'ol.format.WFS',
- ol.format.WFS,
- OPENLAYERS);
- goog.exportProperty(
- ol.format.WFS.prototype,
- 'readFeatures',
- ol.format.WFS.prototype.readFeatures);
- goog.exportProperty(
- ol.format.WFS.prototype,
- 'readTransactionResponse',
- ol.format.WFS.prototype.readTransactionResponse);
- goog.exportProperty(
- ol.format.WFS.prototype,
- 'readFeatureCollectionMetadata',
- ol.format.WFS.prototype.readFeatureCollectionMetadata);
- goog.exportSymbol(
- 'ol.format.WFS.writeFilter',
- ol.format.WFS.writeFilter,
- OPENLAYERS);
- goog.exportProperty(
- ol.format.WFS.prototype,
- 'writeGetFeature',
- ol.format.WFS.prototype.writeGetFeature);
- goog.exportProperty(
- ol.format.WFS.prototype,
- 'writeTransaction',
- ol.format.WFS.prototype.writeTransaction);
- goog.exportProperty(
- ol.format.WFS.prototype,
- 'readProjection',
- ol.format.WFS.prototype.readProjection);
- goog.exportSymbol(
- 'ol.format.WKT',
- ol.format.WKT,
- OPENLAYERS);
- goog.exportProperty(
- ol.format.WKT.prototype,
- 'readFeature',
- ol.format.WKT.prototype.readFeature);
- goog.exportProperty(
- ol.format.WKT.prototype,
- 'readFeatures',
- ol.format.WKT.prototype.readFeatures);
- goog.exportProperty(
- ol.format.WKT.prototype,
- 'readGeometry',
- ol.format.WKT.prototype.readGeometry);
- goog.exportProperty(
- ol.format.WKT.prototype,
- 'writeFeature',
- ol.format.WKT.prototype.writeFeature);
- goog.exportProperty(
- ol.format.WKT.prototype,
- 'writeFeatures',
- ol.format.WKT.prototype.writeFeatures);
- goog.exportProperty(
- ol.format.WKT.prototype,
- 'writeGeometry',
- ol.format.WKT.prototype.writeGeometry);
- goog.exportSymbol(
- 'ol.format.WMSCapabilities',
- ol.format.WMSCapabilities,
- OPENLAYERS);
- goog.exportProperty(
- ol.format.WMSCapabilities.prototype,
- 'read',
- ol.format.WMSCapabilities.prototype.read);
- goog.exportSymbol(
- 'ol.format.WMSGetFeatureInfo',
- ol.format.WMSGetFeatureInfo,
- OPENLAYERS);
- goog.exportProperty(
- ol.format.WMSGetFeatureInfo.prototype,
- 'readFeatures',
- ol.format.WMSGetFeatureInfo.prototype.readFeatures);
- goog.exportSymbol(
- 'ol.format.WMTSCapabilities',
- ol.format.WMTSCapabilities,
- OPENLAYERS);
- goog.exportProperty(
- ol.format.WMTSCapabilities.prototype,
- 'read',
- ol.format.WMTSCapabilities.prototype.read);
- goog.exportSymbol(
- 'ol.format.filter.And',
- ol.format.filter.And,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.Bbox',
- ol.format.filter.Bbox,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.Comparison',
- ol.format.filter.Comparison,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.ComparisonBinary',
- ol.format.filter.ComparisonBinary,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.Contains',
- ol.format.filter.Contains,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.During',
- ol.format.filter.During,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.EqualTo',
- ol.format.filter.EqualTo,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.Filter',
- ol.format.filter.Filter,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.GreaterThan',
- ol.format.filter.GreaterThan,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.GreaterThanOrEqualTo',
- ol.format.filter.GreaterThanOrEqualTo,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.Intersects',
- ol.format.filter.Intersects,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.IsBetween',
- ol.format.filter.IsBetween,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.IsLike',
- ol.format.filter.IsLike,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.IsNull',
- ol.format.filter.IsNull,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.LessThan',
- ol.format.filter.LessThan,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.LessThanOrEqualTo',
- ol.format.filter.LessThanOrEqualTo,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.Not',
- ol.format.filter.Not,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.NotEqualTo',
- ol.format.filter.NotEqualTo,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.Or',
- ol.format.filter.Or,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.Spatial',
- ol.format.filter.Spatial,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.format.filter.Within',
- ol.format.filter.Within,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.events.condition.altKeyOnly',
- ol.events.condition.altKeyOnly,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.events.condition.altShiftKeysOnly',
- ol.events.condition.altShiftKeysOnly,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.events.condition.always',
- ol.events.condition.always,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.events.condition.click',
- ol.events.condition.click,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.events.condition.never',
- ol.events.condition.never,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.events.condition.pointerMove',
- ol.events.condition.pointerMove,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.events.condition.singleClick',
- ol.events.condition.singleClick,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.events.condition.doubleClick',
- ol.events.condition.doubleClick,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.events.condition.noModifierKeys',
- ol.events.condition.noModifierKeys,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.events.condition.platformModifierKeyOnly',
- ol.events.condition.platformModifierKeyOnly,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.events.condition.shiftKeyOnly',
- ol.events.condition.shiftKeyOnly,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.events.condition.targetNotEditable',
- ol.events.condition.targetNotEditable,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.events.condition.mouseOnly',
- ol.events.condition.mouseOnly,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.events.condition.primaryAction',
- ol.events.condition.primaryAction,
- OPENLAYERS);
- goog.exportProperty(
- ol.events.Event.prototype,
- 'type',
- ol.events.Event.prototype.type);
- goog.exportProperty(
- ol.events.Event.prototype,
- 'target',
- ol.events.Event.prototype.target);
- goog.exportProperty(
- ol.events.Event.prototype,
- 'preventDefault',
- ol.events.Event.prototype.preventDefault);
- goog.exportProperty(
- ol.events.Event.prototype,
- 'stopPropagation',
- ol.events.Event.prototype.stopPropagation);
- goog.exportSymbol(
- 'ol.control.Attribution',
- ol.control.Attribution,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.control.Attribution.render',
- ol.control.Attribution.render,
- OPENLAYERS);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'getCollapsible',
- ol.control.Attribution.prototype.getCollapsible);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'setCollapsible',
- ol.control.Attribution.prototype.setCollapsible);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'setCollapsed',
- ol.control.Attribution.prototype.setCollapsed);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'getCollapsed',
- ol.control.Attribution.prototype.getCollapsed);
- goog.exportSymbol(
- 'ol.control.Control',
- ol.control.Control,
- OPENLAYERS);
- goog.exportProperty(
- ol.control.Control.prototype,
- 'getMap',
- ol.control.Control.prototype.getMap);
- goog.exportProperty(
- ol.control.Control.prototype,
- 'setMap',
- ol.control.Control.prototype.setMap);
- goog.exportProperty(
- ol.control.Control.prototype,
- 'setTarget',
- ol.control.Control.prototype.setTarget);
- goog.exportSymbol(
- 'ol.control.FullScreen',
- ol.control.FullScreen,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.control.MousePosition',
- ol.control.MousePosition,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.control.MousePosition.render',
- ol.control.MousePosition.render,
- OPENLAYERS);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'getCoordinateFormat',
- ol.control.MousePosition.prototype.getCoordinateFormat);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'getProjection',
- ol.control.MousePosition.prototype.getProjection);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'setCoordinateFormat',
- ol.control.MousePosition.prototype.setCoordinateFormat);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'setProjection',
- ol.control.MousePosition.prototype.setProjection);
- goog.exportSymbol(
- 'ol.control.OverviewMap',
- ol.control.OverviewMap,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.control.OverviewMap.render',
- ol.control.OverviewMap.render,
- OPENLAYERS);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'getCollapsible',
- ol.control.OverviewMap.prototype.getCollapsible);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'setCollapsible',
- ol.control.OverviewMap.prototype.setCollapsible);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'setCollapsed',
- ol.control.OverviewMap.prototype.setCollapsed);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'getCollapsed',
- ol.control.OverviewMap.prototype.getCollapsed);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'getOverviewMap',
- ol.control.OverviewMap.prototype.getOverviewMap);
- goog.exportSymbol(
- 'ol.control.Rotate',
- ol.control.Rotate,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.control.Rotate.render',
- ol.control.Rotate.render,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.control.ScaleLine',
- ol.control.ScaleLine,
- OPENLAYERS);
- goog.exportProperty(
- ol.control.ScaleLine.prototype,
- 'getUnits',
- ol.control.ScaleLine.prototype.getUnits);
- goog.exportSymbol(
- 'ol.control.ScaleLine.render',
- ol.control.ScaleLine.render,
- OPENLAYERS);
- goog.exportProperty(
- ol.control.ScaleLine.prototype,
- 'setUnits',
- ol.control.ScaleLine.prototype.setUnits);
- goog.exportSymbol(
- 'ol.control.Zoom',
- ol.control.Zoom,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.control.ZoomSlider',
- ol.control.ZoomSlider,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.control.ZoomSlider.render',
- ol.control.ZoomSlider.render,
- OPENLAYERS);
- goog.exportSymbol(
- 'ol.control.ZoomToExtent',
- ol.control.ZoomToExtent,
- OPENLAYERS);
- goog.exportProperty(
- ol.Object.prototype,
- 'changed',
- ol.Object.prototype.changed);
- goog.exportProperty(
- ol.Object.prototype,
- 'dispatchEvent',
- ol.Object.prototype.dispatchEvent);
- goog.exportProperty(
- ol.Object.prototype,
- 'getRevision',
- ol.Object.prototype.getRevision);
- goog.exportProperty(
- ol.Object.prototype,
- 'on',
- ol.Object.prototype.on);
- goog.exportProperty(
- ol.Object.prototype,
- 'once',
- ol.Object.prototype.once);
- goog.exportProperty(
- ol.Object.prototype,
- 'un',
- ol.Object.prototype.un);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'get',
- ol.PluggableMap.prototype.get);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getKeys',
- ol.PluggableMap.prototype.getKeys);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getProperties',
- ol.PluggableMap.prototype.getProperties);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'set',
- ol.PluggableMap.prototype.set);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'setProperties',
- ol.PluggableMap.prototype.setProperties);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'unset',
- ol.PluggableMap.prototype.unset);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'changed',
- ol.PluggableMap.prototype.changed);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'dispatchEvent',
- ol.PluggableMap.prototype.dispatchEvent);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'getRevision',
- ol.PluggableMap.prototype.getRevision);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'on',
- ol.PluggableMap.prototype.on);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'once',
- ol.PluggableMap.prototype.once);
- goog.exportProperty(
- ol.PluggableMap.prototype,
- 'un',
- ol.PluggableMap.prototype.un);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'addControl',
- ol.CanvasMap.prototype.addControl);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'addInteraction',
- ol.CanvasMap.prototype.addInteraction);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'addLayer',
- ol.CanvasMap.prototype.addLayer);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'addOverlay',
- ol.CanvasMap.prototype.addOverlay);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'forEachFeatureAtPixel',
- ol.CanvasMap.prototype.forEachFeatureAtPixel);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getFeaturesAtPixel',
- ol.CanvasMap.prototype.getFeaturesAtPixel);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'forEachLayerAtPixel',
- ol.CanvasMap.prototype.forEachLayerAtPixel);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'hasFeatureAtPixel',
- ol.CanvasMap.prototype.hasFeatureAtPixel);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getEventCoordinate',
- ol.CanvasMap.prototype.getEventCoordinate);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getEventPixel',
- ol.CanvasMap.prototype.getEventPixel);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getTarget',
- ol.CanvasMap.prototype.getTarget);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getTargetElement',
- ol.CanvasMap.prototype.getTargetElement);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getCoordinateFromPixel',
- ol.CanvasMap.prototype.getCoordinateFromPixel);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getControls',
- ol.CanvasMap.prototype.getControls);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getOverlays',
- ol.CanvasMap.prototype.getOverlays);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getOverlayById',
- ol.CanvasMap.prototype.getOverlayById);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getInteractions',
- ol.CanvasMap.prototype.getInteractions);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getLayerGroup',
- ol.CanvasMap.prototype.getLayerGroup);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getLayers',
- ol.CanvasMap.prototype.getLayers);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getPixelFromCoordinate',
- ol.CanvasMap.prototype.getPixelFromCoordinate);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getSize',
- ol.CanvasMap.prototype.getSize);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getView',
- ol.CanvasMap.prototype.getView);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getViewport',
- ol.CanvasMap.prototype.getViewport);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'renderSync',
- ol.CanvasMap.prototype.renderSync);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'render',
- ol.CanvasMap.prototype.render);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'removeControl',
- ol.CanvasMap.prototype.removeControl);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'removeInteraction',
- ol.CanvasMap.prototype.removeInteraction);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'removeLayer',
- ol.CanvasMap.prototype.removeLayer);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'removeOverlay',
- ol.CanvasMap.prototype.removeOverlay);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'setLayerGroup',
- ol.CanvasMap.prototype.setLayerGroup);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'setSize',
- ol.CanvasMap.prototype.setSize);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'setTarget',
- ol.CanvasMap.prototype.setTarget);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'setView',
- ol.CanvasMap.prototype.setView);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'updateSize',
- ol.CanvasMap.prototype.updateSize);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'get',
- ol.CanvasMap.prototype.get);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getKeys',
- ol.CanvasMap.prototype.getKeys);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getProperties',
- ol.CanvasMap.prototype.getProperties);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'set',
- ol.CanvasMap.prototype.set);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'setProperties',
- ol.CanvasMap.prototype.setProperties);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'unset',
- ol.CanvasMap.prototype.unset);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'changed',
- ol.CanvasMap.prototype.changed);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'dispatchEvent',
- ol.CanvasMap.prototype.dispatchEvent);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'getRevision',
- ol.CanvasMap.prototype.getRevision);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'on',
- ol.CanvasMap.prototype.on);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'once',
- ol.CanvasMap.prototype.once);
- goog.exportProperty(
- ol.CanvasMap.prototype,
- 'un',
- ol.CanvasMap.prototype.un);
- goog.exportProperty(
- ol.Collection.prototype,
- 'get',
- ol.Collection.prototype.get);
- goog.exportProperty(
- ol.Collection.prototype,
- 'getKeys',
- ol.Collection.prototype.getKeys);
- goog.exportProperty(
- ol.Collection.prototype,
- 'getProperties',
- ol.Collection.prototype.getProperties);
- goog.exportProperty(
- ol.Collection.prototype,
- 'set',
- ol.Collection.prototype.set);
- goog.exportProperty(
- ol.Collection.prototype,
- 'setProperties',
- ol.Collection.prototype.setProperties);
- goog.exportProperty(
- ol.Collection.prototype,
- 'unset',
- ol.Collection.prototype.unset);
- goog.exportProperty(
- ol.Collection.prototype,
- 'changed',
- ol.Collection.prototype.changed);
- goog.exportProperty(
- ol.Collection.prototype,
- 'dispatchEvent',
- ol.Collection.prototype.dispatchEvent);
- goog.exportProperty(
- ol.Collection.prototype,
- 'getRevision',
- ol.Collection.prototype.getRevision);
- goog.exportProperty(
- ol.Collection.prototype,
- 'on',
- ol.Collection.prototype.on);
- goog.exportProperty(
- ol.Collection.prototype,
- 'once',
- ol.Collection.prototype.once);
- goog.exportProperty(
- ol.Collection.prototype,
- 'un',
- ol.Collection.prototype.un);
- goog.exportProperty(
- ol.Collection.Event.prototype,
- 'type',
- ol.Collection.Event.prototype.type);
- goog.exportProperty(
- ol.Collection.Event.prototype,
- 'target',
- ol.Collection.Event.prototype.target);
- goog.exportProperty(
- ol.Collection.Event.prototype,
- 'preventDefault',
- ol.Collection.Event.prototype.preventDefault);
- goog.exportProperty(
- ol.Collection.Event.prototype,
- 'stopPropagation',
- ol.Collection.Event.prototype.stopPropagation);
- goog.exportProperty(
- ol.DeviceOrientation.prototype,
- 'get',
- ol.DeviceOrientation.prototype.get);
- goog.exportProperty(
- ol.DeviceOrientation.prototype,
- 'getKeys',
- ol.DeviceOrientation.prototype.getKeys);
- goog.exportProperty(
- ol.DeviceOrientation.prototype,
- 'getProperties',
- ol.DeviceOrientation.prototype.getProperties);
- goog.exportProperty(
- ol.DeviceOrientation.prototype,
- 'set',
- ol.DeviceOrientation.prototype.set);
- goog.exportProperty(
- ol.DeviceOrientation.prototype,
- 'setProperties',
- ol.DeviceOrientation.prototype.setProperties);
- goog.exportProperty(
- ol.DeviceOrientation.prototype,
- 'unset',
- ol.DeviceOrientation.prototype.unset);
- goog.exportProperty(
- ol.DeviceOrientation.prototype,
- 'changed',
- ol.DeviceOrientation.prototype.changed);
- goog.exportProperty(
- ol.DeviceOrientation.prototype,
- 'dispatchEvent',
- ol.DeviceOrientation.prototype.dispatchEvent);
- goog.exportProperty(
- ol.DeviceOrientation.prototype,
- 'getRevision',
- ol.DeviceOrientation.prototype.getRevision);
- goog.exportProperty(
- ol.DeviceOrientation.prototype,
- 'on',
- ol.DeviceOrientation.prototype.on);
- goog.exportProperty(
- ol.DeviceOrientation.prototype,
- 'once',
- ol.DeviceOrientation.prototype.once);
- goog.exportProperty(
- ol.DeviceOrientation.prototype,
- 'un',
- ol.DeviceOrientation.prototype.un);
- goog.exportProperty(
- ol.Feature.prototype,
- 'get',
- ol.Feature.prototype.get);
- goog.exportProperty(
- ol.Feature.prototype,
- 'getKeys',
- ol.Feature.prototype.getKeys);
- goog.exportProperty(
- ol.Feature.prototype,
- 'getProperties',
- ol.Feature.prototype.getProperties);
- goog.exportProperty(
- ol.Feature.prototype,
- 'set',
- ol.Feature.prototype.set);
- goog.exportProperty(
- ol.Feature.prototype,
- 'setProperties',
- ol.Feature.prototype.setProperties);
- goog.exportProperty(
- ol.Feature.prototype,
- 'unset',
- ol.Feature.prototype.unset);
- goog.exportProperty(
- ol.Feature.prototype,
- 'changed',
- ol.Feature.prototype.changed);
- goog.exportProperty(
- ol.Feature.prototype,
- 'dispatchEvent',
- ol.Feature.prototype.dispatchEvent);
- goog.exportProperty(
- ol.Feature.prototype,
- 'getRevision',
- ol.Feature.prototype.getRevision);
- goog.exportProperty(
- ol.Feature.prototype,
- 'on',
- ol.Feature.prototype.on);
- goog.exportProperty(
- ol.Feature.prototype,
- 'once',
- ol.Feature.prototype.once);
- goog.exportProperty(
- ol.Feature.prototype,
- 'un',
- ol.Feature.prototype.un);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'get',
- ol.Geolocation.prototype.get);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'getKeys',
- ol.Geolocation.prototype.getKeys);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'getProperties',
- ol.Geolocation.prototype.getProperties);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'set',
- ol.Geolocation.prototype.set);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'setProperties',
- ol.Geolocation.prototype.setProperties);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'unset',
- ol.Geolocation.prototype.unset);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'changed',
- ol.Geolocation.prototype.changed);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'dispatchEvent',
- ol.Geolocation.prototype.dispatchEvent);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'getRevision',
- ol.Geolocation.prototype.getRevision);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'on',
- ol.Geolocation.prototype.on);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'once',
- ol.Geolocation.prototype.once);
- goog.exportProperty(
- ol.Geolocation.prototype,
- 'un',
- ol.Geolocation.prototype.un);
- goog.exportProperty(
- ol.ImageTile.prototype,
- 'getTileCoord',
- ol.ImageTile.prototype.getTileCoord);
- goog.exportProperty(
- ol.ImageTile.prototype,
- 'load',
- ol.ImageTile.prototype.load);
- goog.exportProperty(
- ol.Map.prototype,
- 'addControl',
- ol.Map.prototype.addControl);
- goog.exportProperty(
- ol.Map.prototype,
- 'addInteraction',
- ol.Map.prototype.addInteraction);
- goog.exportProperty(
- ol.Map.prototype,
- 'addLayer',
- ol.Map.prototype.addLayer);
- goog.exportProperty(
- ol.Map.prototype,
- 'addOverlay',
- ol.Map.prototype.addOverlay);
- goog.exportProperty(
- ol.Map.prototype,
- 'forEachFeatureAtPixel',
- ol.Map.prototype.forEachFeatureAtPixel);
- goog.exportProperty(
- ol.Map.prototype,
- 'getFeaturesAtPixel',
- ol.Map.prototype.getFeaturesAtPixel);
- goog.exportProperty(
- ol.Map.prototype,
- 'forEachLayerAtPixel',
- ol.Map.prototype.forEachLayerAtPixel);
- goog.exportProperty(
- ol.Map.prototype,
- 'hasFeatureAtPixel',
- ol.Map.prototype.hasFeatureAtPixel);
- goog.exportProperty(
- ol.Map.prototype,
- 'getEventCoordinate',
- ol.Map.prototype.getEventCoordinate);
- goog.exportProperty(
- ol.Map.prototype,
- 'getEventPixel',
- ol.Map.prototype.getEventPixel);
- goog.exportProperty(
- ol.Map.prototype,
- 'getTarget',
- ol.Map.prototype.getTarget);
- goog.exportProperty(
- ol.Map.prototype,
- 'getTargetElement',
- ol.Map.prototype.getTargetElement);
- goog.exportProperty(
- ol.Map.prototype,
- 'getCoordinateFromPixel',
- ol.Map.prototype.getCoordinateFromPixel);
- goog.exportProperty(
- ol.Map.prototype,
- 'getControls',
- ol.Map.prototype.getControls);
- goog.exportProperty(
- ol.Map.prototype,
- 'getOverlays',
- ol.Map.prototype.getOverlays);
- goog.exportProperty(
- ol.Map.prototype,
- 'getOverlayById',
- ol.Map.prototype.getOverlayById);
- goog.exportProperty(
- ol.Map.prototype,
- 'getInteractions',
- ol.Map.prototype.getInteractions);
- goog.exportProperty(
- ol.Map.prototype,
- 'getLayerGroup',
- ol.Map.prototype.getLayerGroup);
- goog.exportProperty(
- ol.Map.prototype,
- 'getLayers',
- ol.Map.prototype.getLayers);
- goog.exportProperty(
- ol.Map.prototype,
- 'getPixelFromCoordinate',
- ol.Map.prototype.getPixelFromCoordinate);
- goog.exportProperty(
- ol.Map.prototype,
- 'getSize',
- ol.Map.prototype.getSize);
- goog.exportProperty(
- ol.Map.prototype,
- 'getView',
- ol.Map.prototype.getView);
- goog.exportProperty(
- ol.Map.prototype,
- 'getViewport',
- ol.Map.prototype.getViewport);
- goog.exportProperty(
- ol.Map.prototype,
- 'renderSync',
- ol.Map.prototype.renderSync);
- goog.exportProperty(
- ol.Map.prototype,
- 'render',
- ol.Map.prototype.render);
- goog.exportProperty(
- ol.Map.prototype,
- 'removeControl',
- ol.Map.prototype.removeControl);
- goog.exportProperty(
- ol.Map.prototype,
- 'removeInteraction',
- ol.Map.prototype.removeInteraction);
- goog.exportProperty(
- ol.Map.prototype,
- 'removeLayer',
- ol.Map.prototype.removeLayer);
- goog.exportProperty(
- ol.Map.prototype,
- 'removeOverlay',
- ol.Map.prototype.removeOverlay);
- goog.exportProperty(
- ol.Map.prototype,
- 'setLayerGroup',
- ol.Map.prototype.setLayerGroup);
- goog.exportProperty(
- ol.Map.prototype,
- 'setSize',
- ol.Map.prototype.setSize);
- goog.exportProperty(
- ol.Map.prototype,
- 'setTarget',
- ol.Map.prototype.setTarget);
- goog.exportProperty(
- ol.Map.prototype,
- 'setView',
- ol.Map.prototype.setView);
- goog.exportProperty(
- ol.Map.prototype,
- 'updateSize',
- ol.Map.prototype.updateSize);
- goog.exportProperty(
- ol.Map.prototype,
- 'get',
- ol.Map.prototype.get);
- goog.exportProperty(
- ol.Map.prototype,
- 'getKeys',
- ol.Map.prototype.getKeys);
- goog.exportProperty(
- ol.Map.prototype,
- 'getProperties',
- ol.Map.prototype.getProperties);
- goog.exportProperty(
- ol.Map.prototype,
- 'set',
- ol.Map.prototype.set);
- goog.exportProperty(
- ol.Map.prototype,
- 'setProperties',
- ol.Map.prototype.setProperties);
- goog.exportProperty(
- ol.Map.prototype,
- 'unset',
- ol.Map.prototype.unset);
- goog.exportProperty(
- ol.Map.prototype,
- 'changed',
- ol.Map.prototype.changed);
- goog.exportProperty(
- ol.Map.prototype,
- 'dispatchEvent',
- ol.Map.prototype.dispatchEvent);
- goog.exportProperty(
- ol.Map.prototype,
- 'getRevision',
- ol.Map.prototype.getRevision);
- goog.exportProperty(
- ol.Map.prototype,
- 'on',
- ol.Map.prototype.on);
- goog.exportProperty(
- ol.Map.prototype,
- 'once',
- ol.Map.prototype.once);
- goog.exportProperty(
- ol.Map.prototype,
- 'un',
- ol.Map.prototype.un);
- goog.exportProperty(
- ol.MapEvent.prototype,
- 'type',
- ol.MapEvent.prototype.type);
- goog.exportProperty(
- ol.MapEvent.prototype,
- 'target',
- ol.MapEvent.prototype.target);
- goog.exportProperty(
- ol.MapEvent.prototype,
- 'preventDefault',
- ol.MapEvent.prototype.preventDefault);
- goog.exportProperty(
- ol.MapEvent.prototype,
- 'stopPropagation',
- ol.MapEvent.prototype.stopPropagation);
- goog.exportProperty(
- ol.MapBrowserEvent.prototype,
- 'map',
- ol.MapBrowserEvent.prototype.map);
- goog.exportProperty(
- ol.MapBrowserEvent.prototype,
- 'frameState',
- ol.MapBrowserEvent.prototype.frameState);
- goog.exportProperty(
- ol.MapBrowserEvent.prototype,
- 'type',
- ol.MapBrowserEvent.prototype.type);
- goog.exportProperty(
- ol.MapBrowserEvent.prototype,
- 'target',
- ol.MapBrowserEvent.prototype.target);
- goog.exportProperty(
- ol.MapBrowserEvent.prototype,
- 'preventDefault',
- ol.MapBrowserEvent.prototype.preventDefault);
- goog.exportProperty(
- ol.MapBrowserEvent.prototype,
- 'stopPropagation',
- ol.MapBrowserEvent.prototype.stopPropagation);
- goog.exportProperty(
- ol.MapBrowserPointerEvent.prototype,
- 'originalEvent',
- ol.MapBrowserPointerEvent.prototype.originalEvent);
- goog.exportProperty(
- ol.MapBrowserPointerEvent.prototype,
- 'pixel',
- ol.MapBrowserPointerEvent.prototype.pixel);
- goog.exportProperty(
- ol.MapBrowserPointerEvent.prototype,
- 'coordinate',
- ol.MapBrowserPointerEvent.prototype.coordinate);
- goog.exportProperty(
- ol.MapBrowserPointerEvent.prototype,
- 'dragging',
- ol.MapBrowserPointerEvent.prototype.dragging);
- goog.exportProperty(
- ol.MapBrowserPointerEvent.prototype,
- 'preventDefault',
- ol.MapBrowserPointerEvent.prototype.preventDefault);
- goog.exportProperty(
- ol.MapBrowserPointerEvent.prototype,
- 'stopPropagation',
- ol.MapBrowserPointerEvent.prototype.stopPropagation);
- goog.exportProperty(
- ol.MapBrowserPointerEvent.prototype,
- 'map',
- ol.MapBrowserPointerEvent.prototype.map);
- goog.exportProperty(
- ol.MapBrowserPointerEvent.prototype,
- 'frameState',
- ol.MapBrowserPointerEvent.prototype.frameState);
- goog.exportProperty(
- ol.MapBrowserPointerEvent.prototype,
- 'type',
- ol.MapBrowserPointerEvent.prototype.type);
- goog.exportProperty(
- ol.MapBrowserPointerEvent.prototype,
- 'target',
- ol.MapBrowserPointerEvent.prototype.target);
- goog.exportProperty(
- ol.Object.Event.prototype,
- 'type',
- ol.Object.Event.prototype.type);
- goog.exportProperty(
- ol.Object.Event.prototype,
- 'target',
- ol.Object.Event.prototype.target);
- goog.exportProperty(
- ol.Object.Event.prototype,
- 'preventDefault',
- ol.Object.Event.prototype.preventDefault);
- goog.exportProperty(
- ol.Object.Event.prototype,
- 'stopPropagation',
- ol.Object.Event.prototype.stopPropagation);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'get',
- ol.Overlay.prototype.get);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'getKeys',
- ol.Overlay.prototype.getKeys);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'getProperties',
- ol.Overlay.prototype.getProperties);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'set',
- ol.Overlay.prototype.set);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'setProperties',
- ol.Overlay.prototype.setProperties);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'unset',
- ol.Overlay.prototype.unset);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'changed',
- ol.Overlay.prototype.changed);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'dispatchEvent',
- ol.Overlay.prototype.dispatchEvent);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'getRevision',
- ol.Overlay.prototype.getRevision);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'on',
- ol.Overlay.prototype.on);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'once',
- ol.Overlay.prototype.once);
- goog.exportProperty(
- ol.Overlay.prototype,
- 'un',
- ol.Overlay.prototype.un);
- goog.exportProperty(
- ol.VectorImageTile.prototype,
- 'getTileCoord',
- ol.VectorImageTile.prototype.getTileCoord);
- goog.exportProperty(
- ol.VectorImageTile.prototype,
- 'load',
- ol.VectorImageTile.prototype.load);
- goog.exportProperty(
- ol.VectorTile.prototype,
- 'getTileCoord',
- ol.VectorTile.prototype.getTileCoord);
- goog.exportProperty(
- ol.VectorTile.prototype,
- 'load',
- ol.VectorTile.prototype.load);
- goog.exportProperty(
- ol.View.prototype,
- 'get',
- ol.View.prototype.get);
- goog.exportProperty(
- ol.View.prototype,
- 'getKeys',
- ol.View.prototype.getKeys);
- goog.exportProperty(
- ol.View.prototype,
- 'getProperties',
- ol.View.prototype.getProperties);
- goog.exportProperty(
- ol.View.prototype,
- 'set',
- ol.View.prototype.set);
- goog.exportProperty(
- ol.View.prototype,
- 'setProperties',
- ol.View.prototype.setProperties);
- goog.exportProperty(
- ol.View.prototype,
- 'unset',
- ol.View.prototype.unset);
- goog.exportProperty(
- ol.View.prototype,
- 'changed',
- ol.View.prototype.changed);
- goog.exportProperty(
- ol.View.prototype,
- 'dispatchEvent',
- ol.View.prototype.dispatchEvent);
- goog.exportProperty(
- ol.View.prototype,
- 'getRevision',
- ol.View.prototype.getRevision);
- goog.exportProperty(
- ol.View.prototype,
- 'on',
- ol.View.prototype.on);
- goog.exportProperty(
- ol.View.prototype,
- 'once',
- ol.View.prototype.once);
- goog.exportProperty(
- ol.View.prototype,
- 'un',
- ol.View.prototype.un);
- goog.exportProperty(
- ol.tilegrid.WMTS.prototype,
- 'forEachTileCoord',
- ol.tilegrid.WMTS.prototype.forEachTileCoord);
- goog.exportProperty(
- ol.tilegrid.WMTS.prototype,
- 'getMaxZoom',
- ol.tilegrid.WMTS.prototype.getMaxZoom);
- goog.exportProperty(
- ol.tilegrid.WMTS.prototype,
- 'getMinZoom',
- ol.tilegrid.WMTS.prototype.getMinZoom);
- goog.exportProperty(
- ol.tilegrid.WMTS.prototype,
- 'getOrigin',
- ol.tilegrid.WMTS.prototype.getOrigin);
- goog.exportProperty(
- ol.tilegrid.WMTS.prototype,
- 'getResolution',
- ol.tilegrid.WMTS.prototype.getResolution);
- goog.exportProperty(
- ol.tilegrid.WMTS.prototype,
- 'getResolutions',
- ol.tilegrid.WMTS.prototype.getResolutions);
- goog.exportProperty(
- ol.tilegrid.WMTS.prototype,
- 'getTileCoordExtent',
- ol.tilegrid.WMTS.prototype.getTileCoordExtent);
- goog.exportProperty(
- ol.tilegrid.WMTS.prototype,
- 'getTileCoordForCoordAndResolution',
- ol.tilegrid.WMTS.prototype.getTileCoordForCoordAndResolution);
- goog.exportProperty(
- ol.tilegrid.WMTS.prototype,
- 'getTileCoordForCoordAndZ',
- ol.tilegrid.WMTS.prototype.getTileCoordForCoordAndZ);
- goog.exportProperty(
- ol.tilegrid.WMTS.prototype,
- 'getTileSize',
- ol.tilegrid.WMTS.prototype.getTileSize);
- goog.exportProperty(
- ol.tilegrid.WMTS.prototype,
- 'getZForResolution',
- ol.tilegrid.WMTS.prototype.getZForResolution);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'getOpacity',
- ol.style.RegularShape.prototype.getOpacity);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'getRotateWithView',
- ol.style.RegularShape.prototype.getRotateWithView);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'getRotation',
- ol.style.RegularShape.prototype.getRotation);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'getScale',
- ol.style.RegularShape.prototype.getScale);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'getSnapToPixel',
- ol.style.RegularShape.prototype.getSnapToPixel);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'setOpacity',
- ol.style.RegularShape.prototype.setOpacity);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'setRotation',
- ol.style.RegularShape.prototype.setRotation);
- goog.exportProperty(
- ol.style.RegularShape.prototype,
- 'setScale',
- ol.style.RegularShape.prototype.setScale);
- goog.exportProperty(
- ol.style.Circle.prototype,
- 'clone',
- ol.style.Circle.prototype.clone);
- goog.exportProperty(
- ol.style.Circle.prototype,
- 'getAngle',
- ol.style.Circle.prototype.getAngle);
- goog.exportProperty(
- ol.style.Circle.prototype,
- 'getFill',
- ol.style.Circle.prototype.getFill);
- goog.exportProperty(
- ol.style.Circle.prototype,
- 'getPoints',
- ol.style.Circle.prototype.getPoints);
- goog.exportProperty(
- ol.style.Circle.prototype,
- 'getRadius',
- ol.style.Circle.prototype.getRadius);
- goog.exportProperty(
- ol.style.Circle.prototype,
- 'getRadius2',
- ol.style.Circle.prototype.getRadius2);
- goog.exportProperty(
- ol.style.Circle.prototype,
- 'getStroke',
- ol.style.Circle.prototype.getStroke);
- goog.exportProperty(
- ol.style.Circle.prototype,
- 'getOpacity',
- ol.style.Circle.prototype.getOpacity);
- goog.exportProperty(
- ol.style.Circle.prototype,
- 'getRotateWithView',
- ol.style.Circle.prototype.getRotateWithView);
- goog.exportProperty(
- ol.style.Circle.prototype,
- 'getRotation',
- ol.style.Circle.prototype.getRotation);
- goog.exportProperty(
- ol.style.Circle.prototype,
- 'getScale',
- ol.style.Circle.prototype.getScale);
- goog.exportProperty(
- ol.style.Circle.prototype,
- 'getSnapToPixel',
- ol.style.Circle.prototype.getSnapToPixel);
- goog.exportProperty(
- ol.style.Circle.prototype,
- 'setOpacity',
- ol.style.Circle.prototype.setOpacity);
- goog.exportProperty(
- ol.style.Circle.prototype,
- 'setRotation',
- ol.style.Circle.prototype.setRotation);
- goog.exportProperty(
- ol.style.Circle.prototype,
- 'setScale',
- ol.style.Circle.prototype.setScale);
- goog.exportProperty(
- ol.style.Icon.prototype,
- 'getOpacity',
- ol.style.Icon.prototype.getOpacity);
- goog.exportProperty(
- ol.style.Icon.prototype,
- 'getRotateWithView',
- ol.style.Icon.prototype.getRotateWithView);
- goog.exportProperty(
- ol.style.Icon.prototype,
- 'getRotation',
- ol.style.Icon.prototype.getRotation);
- goog.exportProperty(
- ol.style.Icon.prototype,
- 'getScale',
- ol.style.Icon.prototype.getScale);
- goog.exportProperty(
- ol.style.Icon.prototype,
- 'getSnapToPixel',
- ol.style.Icon.prototype.getSnapToPixel);
- goog.exportProperty(
- ol.style.Icon.prototype,
- 'setOpacity',
- ol.style.Icon.prototype.setOpacity);
- goog.exportProperty(
- ol.style.Icon.prototype,
- 'setRotation',
- ol.style.Icon.prototype.setRotation);
- goog.exportProperty(
- ol.style.Icon.prototype,
- 'setScale',
- ol.style.Icon.prototype.setScale);
- goog.exportProperty(
- ol.source.Source.prototype,
- 'get',
- ol.source.Source.prototype.get);
- goog.exportProperty(
- ol.source.Source.prototype,
- 'getKeys',
- ol.source.Source.prototype.getKeys);
- goog.exportProperty(
- ol.source.Source.prototype,
- 'getProperties',
- ol.source.Source.prototype.getProperties);
- goog.exportProperty(
- ol.source.Source.prototype,
- 'set',
- ol.source.Source.prototype.set);
- goog.exportProperty(
- ol.source.Source.prototype,
- 'setProperties',
- ol.source.Source.prototype.setProperties);
- goog.exportProperty(
- ol.source.Source.prototype,
- 'unset',
- ol.source.Source.prototype.unset);
- goog.exportProperty(
- ol.source.Source.prototype,
- 'changed',
- ol.source.Source.prototype.changed);
- goog.exportProperty(
- ol.source.Source.prototype,
- 'dispatchEvent',
- ol.source.Source.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.Source.prototype,
- 'getRevision',
- ol.source.Source.prototype.getRevision);
- goog.exportProperty(
- ol.source.Source.prototype,
- 'on',
- ol.source.Source.prototype.on);
- goog.exportProperty(
- ol.source.Source.prototype,
- 'once',
- ol.source.Source.prototype.once);
- goog.exportProperty(
- ol.source.Source.prototype,
- 'un',
- ol.source.Source.prototype.un);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'getAttributions',
- ol.source.Tile.prototype.getAttributions);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'getLogo',
- ol.source.Tile.prototype.getLogo);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'getProjection',
- ol.source.Tile.prototype.getProjection);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'getState',
- ol.source.Tile.prototype.getState);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'refresh',
- ol.source.Tile.prototype.refresh);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'setAttributions',
- ol.source.Tile.prototype.setAttributions);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'get',
- ol.source.Tile.prototype.get);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'getKeys',
- ol.source.Tile.prototype.getKeys);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'getProperties',
- ol.source.Tile.prototype.getProperties);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'set',
- ol.source.Tile.prototype.set);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'setProperties',
- ol.source.Tile.prototype.setProperties);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'unset',
- ol.source.Tile.prototype.unset);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'changed',
- ol.source.Tile.prototype.changed);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'dispatchEvent',
- ol.source.Tile.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'getRevision',
- ol.source.Tile.prototype.getRevision);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'on',
- ol.source.Tile.prototype.on);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'once',
- ol.source.Tile.prototype.once);
- goog.exportProperty(
- ol.source.Tile.prototype,
- 'un',
- ol.source.Tile.prototype.un);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'getTileGrid',
- ol.source.UrlTile.prototype.getTileGrid);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'refresh',
- ol.source.UrlTile.prototype.refresh);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'getAttributions',
- ol.source.UrlTile.prototype.getAttributions);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'getLogo',
- ol.source.UrlTile.prototype.getLogo);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'getProjection',
- ol.source.UrlTile.prototype.getProjection);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'getState',
- ol.source.UrlTile.prototype.getState);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'setAttributions',
- ol.source.UrlTile.prototype.setAttributions);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'get',
- ol.source.UrlTile.prototype.get);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'getKeys',
- ol.source.UrlTile.prototype.getKeys);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'getProperties',
- ol.source.UrlTile.prototype.getProperties);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'set',
- ol.source.UrlTile.prototype.set);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'setProperties',
- ol.source.UrlTile.prototype.setProperties);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'unset',
- ol.source.UrlTile.prototype.unset);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'changed',
- ol.source.UrlTile.prototype.changed);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'dispatchEvent',
- ol.source.UrlTile.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'getRevision',
- ol.source.UrlTile.prototype.getRevision);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'on',
- ol.source.UrlTile.prototype.on);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'once',
- ol.source.UrlTile.prototype.once);
- goog.exportProperty(
- ol.source.UrlTile.prototype,
- 'un',
- ol.source.UrlTile.prototype.un);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'getTileLoadFunction',
- ol.source.TileImage.prototype.getTileLoadFunction);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'getTileUrlFunction',
- ol.source.TileImage.prototype.getTileUrlFunction);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'getUrls',
- ol.source.TileImage.prototype.getUrls);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'setTileLoadFunction',
- ol.source.TileImage.prototype.setTileLoadFunction);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'setTileUrlFunction',
- ol.source.TileImage.prototype.setTileUrlFunction);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'setUrl',
- ol.source.TileImage.prototype.setUrl);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'setUrls',
- ol.source.TileImage.prototype.setUrls);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'getTileGrid',
- ol.source.TileImage.prototype.getTileGrid);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'refresh',
- ol.source.TileImage.prototype.refresh);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'getAttributions',
- ol.source.TileImage.prototype.getAttributions);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'getLogo',
- ol.source.TileImage.prototype.getLogo);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'getProjection',
- ol.source.TileImage.prototype.getProjection);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'getState',
- ol.source.TileImage.prototype.getState);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'setAttributions',
- ol.source.TileImage.prototype.setAttributions);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'get',
- ol.source.TileImage.prototype.get);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'getKeys',
- ol.source.TileImage.prototype.getKeys);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'getProperties',
- ol.source.TileImage.prototype.getProperties);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'set',
- ol.source.TileImage.prototype.set);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'setProperties',
- ol.source.TileImage.prototype.setProperties);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'unset',
- ol.source.TileImage.prototype.unset);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'changed',
- ol.source.TileImage.prototype.changed);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'dispatchEvent',
- ol.source.TileImage.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'getRevision',
- ol.source.TileImage.prototype.getRevision);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'on',
- ol.source.TileImage.prototype.on);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'once',
- ol.source.TileImage.prototype.once);
- goog.exportProperty(
- ol.source.TileImage.prototype,
- 'un',
- ol.source.TileImage.prototype.un);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'setRenderReprojectionEdges',
- ol.source.BingMaps.prototype.setRenderReprojectionEdges);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'setTileGridForProjection',
- ol.source.BingMaps.prototype.setTileGridForProjection);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'getTileLoadFunction',
- ol.source.BingMaps.prototype.getTileLoadFunction);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'getTileUrlFunction',
- ol.source.BingMaps.prototype.getTileUrlFunction);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'getUrls',
- ol.source.BingMaps.prototype.getUrls);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'setTileLoadFunction',
- ol.source.BingMaps.prototype.setTileLoadFunction);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'setTileUrlFunction',
- ol.source.BingMaps.prototype.setTileUrlFunction);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'setUrl',
- ol.source.BingMaps.prototype.setUrl);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'setUrls',
- ol.source.BingMaps.prototype.setUrls);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'getTileGrid',
- ol.source.BingMaps.prototype.getTileGrid);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'refresh',
- ol.source.BingMaps.prototype.refresh);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'getAttributions',
- ol.source.BingMaps.prototype.getAttributions);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'getLogo',
- ol.source.BingMaps.prototype.getLogo);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'getProjection',
- ol.source.BingMaps.prototype.getProjection);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'getState',
- ol.source.BingMaps.prototype.getState);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'setAttributions',
- ol.source.BingMaps.prototype.setAttributions);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'get',
- ol.source.BingMaps.prototype.get);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'getKeys',
- ol.source.BingMaps.prototype.getKeys);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'getProperties',
- ol.source.BingMaps.prototype.getProperties);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'set',
- ol.source.BingMaps.prototype.set);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'setProperties',
- ol.source.BingMaps.prototype.setProperties);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'unset',
- ol.source.BingMaps.prototype.unset);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'changed',
- ol.source.BingMaps.prototype.changed);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'dispatchEvent',
- ol.source.BingMaps.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'getRevision',
- ol.source.BingMaps.prototype.getRevision);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'on',
- ol.source.BingMaps.prototype.on);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'once',
- ol.source.BingMaps.prototype.once);
- goog.exportProperty(
- ol.source.BingMaps.prototype,
- 'un',
- ol.source.BingMaps.prototype.un);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'setRenderReprojectionEdges',
- ol.source.XYZ.prototype.setRenderReprojectionEdges);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'setTileGridForProjection',
- ol.source.XYZ.prototype.setTileGridForProjection);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'getTileLoadFunction',
- ol.source.XYZ.prototype.getTileLoadFunction);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'getTileUrlFunction',
- ol.source.XYZ.prototype.getTileUrlFunction);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'getUrls',
- ol.source.XYZ.prototype.getUrls);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'setTileLoadFunction',
- ol.source.XYZ.prototype.setTileLoadFunction);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'setTileUrlFunction',
- ol.source.XYZ.prototype.setTileUrlFunction);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'setUrl',
- ol.source.XYZ.prototype.setUrl);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'setUrls',
- ol.source.XYZ.prototype.setUrls);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'getTileGrid',
- ol.source.XYZ.prototype.getTileGrid);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'refresh',
- ol.source.XYZ.prototype.refresh);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'getAttributions',
- ol.source.XYZ.prototype.getAttributions);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'getLogo',
- ol.source.XYZ.prototype.getLogo);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'getProjection',
- ol.source.XYZ.prototype.getProjection);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'getState',
- ol.source.XYZ.prototype.getState);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'setAttributions',
- ol.source.XYZ.prototype.setAttributions);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'get',
- ol.source.XYZ.prototype.get);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'getKeys',
- ol.source.XYZ.prototype.getKeys);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'getProperties',
- ol.source.XYZ.prototype.getProperties);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'set',
- ol.source.XYZ.prototype.set);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'setProperties',
- ol.source.XYZ.prototype.setProperties);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'unset',
- ol.source.XYZ.prototype.unset);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'changed',
- ol.source.XYZ.prototype.changed);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'dispatchEvent',
- ol.source.XYZ.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'getRevision',
- ol.source.XYZ.prototype.getRevision);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'on',
- ol.source.XYZ.prototype.on);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'once',
- ol.source.XYZ.prototype.once);
- goog.exportProperty(
- ol.source.XYZ.prototype,
- 'un',
- ol.source.XYZ.prototype.un);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'setRenderReprojectionEdges',
- ol.source.CartoDB.prototype.setRenderReprojectionEdges);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'setTileGridForProjection',
- ol.source.CartoDB.prototype.setTileGridForProjection);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'getTileLoadFunction',
- ol.source.CartoDB.prototype.getTileLoadFunction);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'getTileUrlFunction',
- ol.source.CartoDB.prototype.getTileUrlFunction);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'getUrls',
- ol.source.CartoDB.prototype.getUrls);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'setTileLoadFunction',
- ol.source.CartoDB.prototype.setTileLoadFunction);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'setTileUrlFunction',
- ol.source.CartoDB.prototype.setTileUrlFunction);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'setUrl',
- ol.source.CartoDB.prototype.setUrl);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'setUrls',
- ol.source.CartoDB.prototype.setUrls);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'getTileGrid',
- ol.source.CartoDB.prototype.getTileGrid);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'refresh',
- ol.source.CartoDB.prototype.refresh);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'getAttributions',
- ol.source.CartoDB.prototype.getAttributions);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'getLogo',
- ol.source.CartoDB.prototype.getLogo);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'getProjection',
- ol.source.CartoDB.prototype.getProjection);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'getState',
- ol.source.CartoDB.prototype.getState);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'setAttributions',
- ol.source.CartoDB.prototype.setAttributions);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'get',
- ol.source.CartoDB.prototype.get);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'getKeys',
- ol.source.CartoDB.prototype.getKeys);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'getProperties',
- ol.source.CartoDB.prototype.getProperties);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'set',
- ol.source.CartoDB.prototype.set);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'setProperties',
- ol.source.CartoDB.prototype.setProperties);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'unset',
- ol.source.CartoDB.prototype.unset);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'changed',
- ol.source.CartoDB.prototype.changed);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'dispatchEvent',
- ol.source.CartoDB.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'getRevision',
- ol.source.CartoDB.prototype.getRevision);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'on',
- ol.source.CartoDB.prototype.on);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'once',
- ol.source.CartoDB.prototype.once);
- goog.exportProperty(
- ol.source.CartoDB.prototype,
- 'un',
- ol.source.CartoDB.prototype.un);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'getAttributions',
- ol.source.Vector.prototype.getAttributions);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'getLogo',
- ol.source.Vector.prototype.getLogo);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'getProjection',
- ol.source.Vector.prototype.getProjection);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'getState',
- ol.source.Vector.prototype.getState);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'refresh',
- ol.source.Vector.prototype.refresh);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'setAttributions',
- ol.source.Vector.prototype.setAttributions);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'get',
- ol.source.Vector.prototype.get);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'getKeys',
- ol.source.Vector.prototype.getKeys);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'getProperties',
- ol.source.Vector.prototype.getProperties);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'set',
- ol.source.Vector.prototype.set);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'setProperties',
- ol.source.Vector.prototype.setProperties);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'unset',
- ol.source.Vector.prototype.unset);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'changed',
- ol.source.Vector.prototype.changed);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'dispatchEvent',
- ol.source.Vector.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'getRevision',
- ol.source.Vector.prototype.getRevision);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'on',
- ol.source.Vector.prototype.on);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'once',
- ol.source.Vector.prototype.once);
- goog.exportProperty(
- ol.source.Vector.prototype,
- 'un',
- ol.source.Vector.prototype.un);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'addFeature',
- ol.source.Cluster.prototype.addFeature);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'addFeatures',
- ol.source.Cluster.prototype.addFeatures);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'clear',
- ol.source.Cluster.prototype.clear);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'forEachFeature',
- ol.source.Cluster.prototype.forEachFeature);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'forEachFeatureInExtent',
- ol.source.Cluster.prototype.forEachFeatureInExtent);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'forEachFeatureIntersectingExtent',
- ol.source.Cluster.prototype.forEachFeatureIntersectingExtent);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'getFeaturesCollection',
- ol.source.Cluster.prototype.getFeaturesCollection);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'getFeatures',
- ol.source.Cluster.prototype.getFeatures);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'getFeaturesAtCoordinate',
- ol.source.Cluster.prototype.getFeaturesAtCoordinate);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'getFeaturesInExtent',
- ol.source.Cluster.prototype.getFeaturesInExtent);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'getClosestFeatureToCoordinate',
- ol.source.Cluster.prototype.getClosestFeatureToCoordinate);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'getExtent',
- ol.source.Cluster.prototype.getExtent);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'getFeatureById',
- ol.source.Cluster.prototype.getFeatureById);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'getFormat',
- ol.source.Cluster.prototype.getFormat);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'getUrl',
- ol.source.Cluster.prototype.getUrl);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'removeLoadedExtent',
- ol.source.Cluster.prototype.removeLoadedExtent);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'removeFeature',
- ol.source.Cluster.prototype.removeFeature);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'setLoader',
- ol.source.Cluster.prototype.setLoader);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'getAttributions',
- ol.source.Cluster.prototype.getAttributions);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'getLogo',
- ol.source.Cluster.prototype.getLogo);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'getProjection',
- ol.source.Cluster.prototype.getProjection);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'getState',
- ol.source.Cluster.prototype.getState);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'refresh',
- ol.source.Cluster.prototype.refresh);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'setAttributions',
- ol.source.Cluster.prototype.setAttributions);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'get',
- ol.source.Cluster.prototype.get);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'getKeys',
- ol.source.Cluster.prototype.getKeys);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'getProperties',
- ol.source.Cluster.prototype.getProperties);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'set',
- ol.source.Cluster.prototype.set);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'setProperties',
- ol.source.Cluster.prototype.setProperties);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'unset',
- ol.source.Cluster.prototype.unset);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'changed',
- ol.source.Cluster.prototype.changed);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'dispatchEvent',
- ol.source.Cluster.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'getRevision',
- ol.source.Cluster.prototype.getRevision);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'on',
- ol.source.Cluster.prototype.on);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'once',
- ol.source.Cluster.prototype.once);
- goog.exportProperty(
- ol.source.Cluster.prototype,
- 'un',
- ol.source.Cluster.prototype.un);
- goog.exportProperty(
- ol.source.Image.prototype,
- 'getAttributions',
- ol.source.Image.prototype.getAttributions);
- goog.exportProperty(
- ol.source.Image.prototype,
- 'getLogo',
- ol.source.Image.prototype.getLogo);
- goog.exportProperty(
- ol.source.Image.prototype,
- 'getProjection',
- ol.source.Image.prototype.getProjection);
- goog.exportProperty(
- ol.source.Image.prototype,
- 'getState',
- ol.source.Image.prototype.getState);
- goog.exportProperty(
- ol.source.Image.prototype,
- 'refresh',
- ol.source.Image.prototype.refresh);
- goog.exportProperty(
- ol.source.Image.prototype,
- 'setAttributions',
- ol.source.Image.prototype.setAttributions);
- goog.exportProperty(
- ol.source.Image.prototype,
- 'get',
- ol.source.Image.prototype.get);
- goog.exportProperty(
- ol.source.Image.prototype,
- 'getKeys',
- ol.source.Image.prototype.getKeys);
- goog.exportProperty(
- ol.source.Image.prototype,
- 'getProperties',
- ol.source.Image.prototype.getProperties);
- goog.exportProperty(
- ol.source.Image.prototype,
- 'set',
- ol.source.Image.prototype.set);
- goog.exportProperty(
- ol.source.Image.prototype,
- 'setProperties',
- ol.source.Image.prototype.setProperties);
- goog.exportProperty(
- ol.source.Image.prototype,
- 'unset',
- ol.source.Image.prototype.unset);
- goog.exportProperty(
- ol.source.Image.prototype,
- 'changed',
- ol.source.Image.prototype.changed);
- goog.exportProperty(
- ol.source.Image.prototype,
- 'dispatchEvent',
- ol.source.Image.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.Image.prototype,
- 'getRevision',
- ol.source.Image.prototype.getRevision);
- goog.exportProperty(
- ol.source.Image.prototype,
- 'on',
- ol.source.Image.prototype.on);
- goog.exportProperty(
- ol.source.Image.prototype,
- 'once',
- ol.source.Image.prototype.once);
- goog.exportProperty(
- ol.source.Image.prototype,
- 'un',
- ol.source.Image.prototype.un);
- goog.exportProperty(
- ol.source.Image.Event.prototype,
- 'type',
- ol.source.Image.Event.prototype.type);
- goog.exportProperty(
- ol.source.Image.Event.prototype,
- 'target',
- ol.source.Image.Event.prototype.target);
- goog.exportProperty(
- ol.source.Image.Event.prototype,
- 'preventDefault',
- ol.source.Image.Event.prototype.preventDefault);
- goog.exportProperty(
- ol.source.Image.Event.prototype,
- 'stopPropagation',
- ol.source.Image.Event.prototype.stopPropagation);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'getAttributions',
- ol.source.ImageArcGISRest.prototype.getAttributions);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'getLogo',
- ol.source.ImageArcGISRest.prototype.getLogo);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'getProjection',
- ol.source.ImageArcGISRest.prototype.getProjection);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'getState',
- ol.source.ImageArcGISRest.prototype.getState);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'refresh',
- ol.source.ImageArcGISRest.prototype.refresh);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'setAttributions',
- ol.source.ImageArcGISRest.prototype.setAttributions);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'get',
- ol.source.ImageArcGISRest.prototype.get);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'getKeys',
- ol.source.ImageArcGISRest.prototype.getKeys);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'getProperties',
- ol.source.ImageArcGISRest.prototype.getProperties);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'set',
- ol.source.ImageArcGISRest.prototype.set);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'setProperties',
- ol.source.ImageArcGISRest.prototype.setProperties);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'unset',
- ol.source.ImageArcGISRest.prototype.unset);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'changed',
- ol.source.ImageArcGISRest.prototype.changed);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'dispatchEvent',
- ol.source.ImageArcGISRest.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'getRevision',
- ol.source.ImageArcGISRest.prototype.getRevision);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'on',
- ol.source.ImageArcGISRest.prototype.on);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'once',
- ol.source.ImageArcGISRest.prototype.once);
- goog.exportProperty(
- ol.source.ImageArcGISRest.prototype,
- 'un',
- ol.source.ImageArcGISRest.prototype.un);
- goog.exportProperty(
- ol.source.ImageCanvas.prototype,
- 'getAttributions',
- ol.source.ImageCanvas.prototype.getAttributions);
- goog.exportProperty(
- ol.source.ImageCanvas.prototype,
- 'getLogo',
- ol.source.ImageCanvas.prototype.getLogo);
- goog.exportProperty(
- ol.source.ImageCanvas.prototype,
- 'getProjection',
- ol.source.ImageCanvas.prototype.getProjection);
- goog.exportProperty(
- ol.source.ImageCanvas.prototype,
- 'getState',
- ol.source.ImageCanvas.prototype.getState);
- goog.exportProperty(
- ol.source.ImageCanvas.prototype,
- 'refresh',
- ol.source.ImageCanvas.prototype.refresh);
- goog.exportProperty(
- ol.source.ImageCanvas.prototype,
- 'setAttributions',
- ol.source.ImageCanvas.prototype.setAttributions);
- goog.exportProperty(
- ol.source.ImageCanvas.prototype,
- 'get',
- ol.source.ImageCanvas.prototype.get);
- goog.exportProperty(
- ol.source.ImageCanvas.prototype,
- 'getKeys',
- ol.source.ImageCanvas.prototype.getKeys);
- goog.exportProperty(
- ol.source.ImageCanvas.prototype,
- 'getProperties',
- ol.source.ImageCanvas.prototype.getProperties);
- goog.exportProperty(
- ol.source.ImageCanvas.prototype,
- 'set',
- ol.source.ImageCanvas.prototype.set);
- goog.exportProperty(
- ol.source.ImageCanvas.prototype,
- 'setProperties',
- ol.source.ImageCanvas.prototype.setProperties);
- goog.exportProperty(
- ol.source.ImageCanvas.prototype,
- 'unset',
- ol.source.ImageCanvas.prototype.unset);
- goog.exportProperty(
- ol.source.ImageCanvas.prototype,
- 'changed',
- ol.source.ImageCanvas.prototype.changed);
- goog.exportProperty(
- ol.source.ImageCanvas.prototype,
- 'dispatchEvent',
- ol.source.ImageCanvas.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.ImageCanvas.prototype,
- 'getRevision',
- ol.source.ImageCanvas.prototype.getRevision);
- goog.exportProperty(
- ol.source.ImageCanvas.prototype,
- 'on',
- ol.source.ImageCanvas.prototype.on);
- goog.exportProperty(
- ol.source.ImageCanvas.prototype,
- 'once',
- ol.source.ImageCanvas.prototype.once);
- goog.exportProperty(
- ol.source.ImageCanvas.prototype,
- 'un',
- ol.source.ImageCanvas.prototype.un);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'getAttributions',
- ol.source.ImageMapGuide.prototype.getAttributions);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'getLogo',
- ol.source.ImageMapGuide.prototype.getLogo);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'getProjection',
- ol.source.ImageMapGuide.prototype.getProjection);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'getState',
- ol.source.ImageMapGuide.prototype.getState);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'refresh',
- ol.source.ImageMapGuide.prototype.refresh);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'setAttributions',
- ol.source.ImageMapGuide.prototype.setAttributions);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'get',
- ol.source.ImageMapGuide.prototype.get);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'getKeys',
- ol.source.ImageMapGuide.prototype.getKeys);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'getProperties',
- ol.source.ImageMapGuide.prototype.getProperties);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'set',
- ol.source.ImageMapGuide.prototype.set);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'setProperties',
- ol.source.ImageMapGuide.prototype.setProperties);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'unset',
- ol.source.ImageMapGuide.prototype.unset);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'changed',
- ol.source.ImageMapGuide.prototype.changed);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'dispatchEvent',
- ol.source.ImageMapGuide.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'getRevision',
- ol.source.ImageMapGuide.prototype.getRevision);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'on',
- ol.source.ImageMapGuide.prototype.on);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'once',
- ol.source.ImageMapGuide.prototype.once);
- goog.exportProperty(
- ol.source.ImageMapGuide.prototype,
- 'un',
- ol.source.ImageMapGuide.prototype.un);
- goog.exportProperty(
- ol.source.ImageStatic.prototype,
- 'getAttributions',
- ol.source.ImageStatic.prototype.getAttributions);
- goog.exportProperty(
- ol.source.ImageStatic.prototype,
- 'getLogo',
- ol.source.ImageStatic.prototype.getLogo);
- goog.exportProperty(
- ol.source.ImageStatic.prototype,
- 'getProjection',
- ol.source.ImageStatic.prototype.getProjection);
- goog.exportProperty(
- ol.source.ImageStatic.prototype,
- 'getState',
- ol.source.ImageStatic.prototype.getState);
- goog.exportProperty(
- ol.source.ImageStatic.prototype,
- 'refresh',
- ol.source.ImageStatic.prototype.refresh);
- goog.exportProperty(
- ol.source.ImageStatic.prototype,
- 'setAttributions',
- ol.source.ImageStatic.prototype.setAttributions);
- goog.exportProperty(
- ol.source.ImageStatic.prototype,
- 'get',
- ol.source.ImageStatic.prototype.get);
- goog.exportProperty(
- ol.source.ImageStatic.prototype,
- 'getKeys',
- ol.source.ImageStatic.prototype.getKeys);
- goog.exportProperty(
- ol.source.ImageStatic.prototype,
- 'getProperties',
- ol.source.ImageStatic.prototype.getProperties);
- goog.exportProperty(
- ol.source.ImageStatic.prototype,
- 'set',
- ol.source.ImageStatic.prototype.set);
- goog.exportProperty(
- ol.source.ImageStatic.prototype,
- 'setProperties',
- ol.source.ImageStatic.prototype.setProperties);
- goog.exportProperty(
- ol.source.ImageStatic.prototype,
- 'unset',
- ol.source.ImageStatic.prototype.unset);
- goog.exportProperty(
- ol.source.ImageStatic.prototype,
- 'changed',
- ol.source.ImageStatic.prototype.changed);
- goog.exportProperty(
- ol.source.ImageStatic.prototype,
- 'dispatchEvent',
- ol.source.ImageStatic.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.ImageStatic.prototype,
- 'getRevision',
- ol.source.ImageStatic.prototype.getRevision);
- goog.exportProperty(
- ol.source.ImageStatic.prototype,
- 'on',
- ol.source.ImageStatic.prototype.on);
- goog.exportProperty(
- ol.source.ImageStatic.prototype,
- 'once',
- ol.source.ImageStatic.prototype.once);
- goog.exportProperty(
- ol.source.ImageStatic.prototype,
- 'un',
- ol.source.ImageStatic.prototype.un);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'getAttributions',
- ol.source.ImageVector.prototype.getAttributions);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'getLogo',
- ol.source.ImageVector.prototype.getLogo);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'getProjection',
- ol.source.ImageVector.prototype.getProjection);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'getState',
- ol.source.ImageVector.prototype.getState);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'refresh',
- ol.source.ImageVector.prototype.refresh);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'setAttributions',
- ol.source.ImageVector.prototype.setAttributions);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'get',
- ol.source.ImageVector.prototype.get);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'getKeys',
- ol.source.ImageVector.prototype.getKeys);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'getProperties',
- ol.source.ImageVector.prototype.getProperties);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'set',
- ol.source.ImageVector.prototype.set);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'setProperties',
- ol.source.ImageVector.prototype.setProperties);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'unset',
- ol.source.ImageVector.prototype.unset);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'changed',
- ol.source.ImageVector.prototype.changed);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'dispatchEvent',
- ol.source.ImageVector.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'getRevision',
- ol.source.ImageVector.prototype.getRevision);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'on',
- ol.source.ImageVector.prototype.on);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'once',
- ol.source.ImageVector.prototype.once);
- goog.exportProperty(
- ol.source.ImageVector.prototype,
- 'un',
- ol.source.ImageVector.prototype.un);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'getAttributions',
- ol.source.ImageWMS.prototype.getAttributions);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'getLogo',
- ol.source.ImageWMS.prototype.getLogo);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'getProjection',
- ol.source.ImageWMS.prototype.getProjection);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'getState',
- ol.source.ImageWMS.prototype.getState);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'refresh',
- ol.source.ImageWMS.prototype.refresh);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'setAttributions',
- ol.source.ImageWMS.prototype.setAttributions);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'get',
- ol.source.ImageWMS.prototype.get);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'getKeys',
- ol.source.ImageWMS.prototype.getKeys);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'getProperties',
- ol.source.ImageWMS.prototype.getProperties);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'set',
- ol.source.ImageWMS.prototype.set);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'setProperties',
- ol.source.ImageWMS.prototype.setProperties);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'unset',
- ol.source.ImageWMS.prototype.unset);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'changed',
- ol.source.ImageWMS.prototype.changed);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'dispatchEvent',
- ol.source.ImageWMS.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'getRevision',
- ol.source.ImageWMS.prototype.getRevision);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'on',
- ol.source.ImageWMS.prototype.on);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'once',
- ol.source.ImageWMS.prototype.once);
- goog.exportProperty(
- ol.source.ImageWMS.prototype,
- 'un',
- ol.source.ImageWMS.prototype.un);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'setRenderReprojectionEdges',
- ol.source.OSM.prototype.setRenderReprojectionEdges);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'setTileGridForProjection',
- ol.source.OSM.prototype.setTileGridForProjection);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'getTileLoadFunction',
- ol.source.OSM.prototype.getTileLoadFunction);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'getTileUrlFunction',
- ol.source.OSM.prototype.getTileUrlFunction);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'getUrls',
- ol.source.OSM.prototype.getUrls);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'setTileLoadFunction',
- ol.source.OSM.prototype.setTileLoadFunction);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'setTileUrlFunction',
- ol.source.OSM.prototype.setTileUrlFunction);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'setUrl',
- ol.source.OSM.prototype.setUrl);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'setUrls',
- ol.source.OSM.prototype.setUrls);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'getTileGrid',
- ol.source.OSM.prototype.getTileGrid);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'refresh',
- ol.source.OSM.prototype.refresh);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'getAttributions',
- ol.source.OSM.prototype.getAttributions);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'getLogo',
- ol.source.OSM.prototype.getLogo);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'getProjection',
- ol.source.OSM.prototype.getProjection);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'getState',
- ol.source.OSM.prototype.getState);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'setAttributions',
- ol.source.OSM.prototype.setAttributions);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'get',
- ol.source.OSM.prototype.get);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'getKeys',
- ol.source.OSM.prototype.getKeys);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'getProperties',
- ol.source.OSM.prototype.getProperties);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'set',
- ol.source.OSM.prototype.set);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'setProperties',
- ol.source.OSM.prototype.setProperties);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'unset',
- ol.source.OSM.prototype.unset);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'changed',
- ol.source.OSM.prototype.changed);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'dispatchEvent',
- ol.source.OSM.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'getRevision',
- ol.source.OSM.prototype.getRevision);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'on',
- ol.source.OSM.prototype.on);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'once',
- ol.source.OSM.prototype.once);
- goog.exportProperty(
- ol.source.OSM.prototype,
- 'un',
- ol.source.OSM.prototype.un);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'getAttributions',
- ol.source.Raster.prototype.getAttributions);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'getLogo',
- ol.source.Raster.prototype.getLogo);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'getProjection',
- ol.source.Raster.prototype.getProjection);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'getState',
- ol.source.Raster.prototype.getState);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'refresh',
- ol.source.Raster.prototype.refresh);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'setAttributions',
- ol.source.Raster.prototype.setAttributions);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'get',
- ol.source.Raster.prototype.get);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'getKeys',
- ol.source.Raster.prototype.getKeys);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'getProperties',
- ol.source.Raster.prototype.getProperties);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'set',
- ol.source.Raster.prototype.set);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'setProperties',
- ol.source.Raster.prototype.setProperties);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'unset',
- ol.source.Raster.prototype.unset);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'changed',
- ol.source.Raster.prototype.changed);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'dispatchEvent',
- ol.source.Raster.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'getRevision',
- ol.source.Raster.prototype.getRevision);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'on',
- ol.source.Raster.prototype.on);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'once',
- ol.source.Raster.prototype.once);
- goog.exportProperty(
- ol.source.Raster.prototype,
- 'un',
- ol.source.Raster.prototype.un);
- goog.exportProperty(
- ol.source.Raster.Event.prototype,
- 'type',
- ol.source.Raster.Event.prototype.type);
- goog.exportProperty(
- ol.source.Raster.Event.prototype,
- 'target',
- ol.source.Raster.Event.prototype.target);
- goog.exportProperty(
- ol.source.Raster.Event.prototype,
- 'preventDefault',
- ol.source.Raster.Event.prototype.preventDefault);
- goog.exportProperty(
- ol.source.Raster.Event.prototype,
- 'stopPropagation',
- ol.source.Raster.Event.prototype.stopPropagation);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'setRenderReprojectionEdges',
- ol.source.Stamen.prototype.setRenderReprojectionEdges);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'setTileGridForProjection',
- ol.source.Stamen.prototype.setTileGridForProjection);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'getTileLoadFunction',
- ol.source.Stamen.prototype.getTileLoadFunction);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'getTileUrlFunction',
- ol.source.Stamen.prototype.getTileUrlFunction);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'getUrls',
- ol.source.Stamen.prototype.getUrls);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'setTileLoadFunction',
- ol.source.Stamen.prototype.setTileLoadFunction);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'setTileUrlFunction',
- ol.source.Stamen.prototype.setTileUrlFunction);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'setUrl',
- ol.source.Stamen.prototype.setUrl);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'setUrls',
- ol.source.Stamen.prototype.setUrls);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'getTileGrid',
- ol.source.Stamen.prototype.getTileGrid);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'refresh',
- ol.source.Stamen.prototype.refresh);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'getAttributions',
- ol.source.Stamen.prototype.getAttributions);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'getLogo',
- ol.source.Stamen.prototype.getLogo);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'getProjection',
- ol.source.Stamen.prototype.getProjection);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'getState',
- ol.source.Stamen.prototype.getState);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'setAttributions',
- ol.source.Stamen.prototype.setAttributions);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'get',
- ol.source.Stamen.prototype.get);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'getKeys',
- ol.source.Stamen.prototype.getKeys);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'getProperties',
- ol.source.Stamen.prototype.getProperties);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'set',
- ol.source.Stamen.prototype.set);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'setProperties',
- ol.source.Stamen.prototype.setProperties);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'unset',
- ol.source.Stamen.prototype.unset);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'changed',
- ol.source.Stamen.prototype.changed);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'dispatchEvent',
- ol.source.Stamen.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'getRevision',
- ol.source.Stamen.prototype.getRevision);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'on',
- ol.source.Stamen.prototype.on);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'once',
- ol.source.Stamen.prototype.once);
- goog.exportProperty(
- ol.source.Stamen.prototype,
- 'un',
- ol.source.Stamen.prototype.un);
- goog.exportProperty(
- ol.source.Tile.Event.prototype,
- 'type',
- ol.source.Tile.Event.prototype.type);
- goog.exportProperty(
- ol.source.Tile.Event.prototype,
- 'target',
- ol.source.Tile.Event.prototype.target);
- goog.exportProperty(
- ol.source.Tile.Event.prototype,
- 'preventDefault',
- ol.source.Tile.Event.prototype.preventDefault);
- goog.exportProperty(
- ol.source.Tile.Event.prototype,
- 'stopPropagation',
- ol.source.Tile.Event.prototype.stopPropagation);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'setRenderReprojectionEdges',
- ol.source.TileArcGISRest.prototype.setRenderReprojectionEdges);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'setTileGridForProjection',
- ol.source.TileArcGISRest.prototype.setTileGridForProjection);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'getTileLoadFunction',
- ol.source.TileArcGISRest.prototype.getTileLoadFunction);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'getTileUrlFunction',
- ol.source.TileArcGISRest.prototype.getTileUrlFunction);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'getUrls',
- ol.source.TileArcGISRest.prototype.getUrls);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'setTileLoadFunction',
- ol.source.TileArcGISRest.prototype.setTileLoadFunction);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'setTileUrlFunction',
- ol.source.TileArcGISRest.prototype.setTileUrlFunction);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'setUrl',
- ol.source.TileArcGISRest.prototype.setUrl);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'setUrls',
- ol.source.TileArcGISRest.prototype.setUrls);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'getTileGrid',
- ol.source.TileArcGISRest.prototype.getTileGrid);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'refresh',
- ol.source.TileArcGISRest.prototype.refresh);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'getAttributions',
- ol.source.TileArcGISRest.prototype.getAttributions);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'getLogo',
- ol.source.TileArcGISRest.prototype.getLogo);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'getProjection',
- ol.source.TileArcGISRest.prototype.getProjection);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'getState',
- ol.source.TileArcGISRest.prototype.getState);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'setAttributions',
- ol.source.TileArcGISRest.prototype.setAttributions);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'get',
- ol.source.TileArcGISRest.prototype.get);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'getKeys',
- ol.source.TileArcGISRest.prototype.getKeys);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'getProperties',
- ol.source.TileArcGISRest.prototype.getProperties);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'set',
- ol.source.TileArcGISRest.prototype.set);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'setProperties',
- ol.source.TileArcGISRest.prototype.setProperties);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'unset',
- ol.source.TileArcGISRest.prototype.unset);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'changed',
- ol.source.TileArcGISRest.prototype.changed);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'dispatchEvent',
- ol.source.TileArcGISRest.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'getRevision',
- ol.source.TileArcGISRest.prototype.getRevision);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'on',
- ol.source.TileArcGISRest.prototype.on);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'once',
- ol.source.TileArcGISRest.prototype.once);
- goog.exportProperty(
- ol.source.TileArcGISRest.prototype,
- 'un',
- ol.source.TileArcGISRest.prototype.un);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'getTileGrid',
- ol.source.TileDebug.prototype.getTileGrid);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'refresh',
- ol.source.TileDebug.prototype.refresh);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'getAttributions',
- ol.source.TileDebug.prototype.getAttributions);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'getLogo',
- ol.source.TileDebug.prototype.getLogo);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'getProjection',
- ol.source.TileDebug.prototype.getProjection);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'getState',
- ol.source.TileDebug.prototype.getState);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'setAttributions',
- ol.source.TileDebug.prototype.setAttributions);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'get',
- ol.source.TileDebug.prototype.get);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'getKeys',
- ol.source.TileDebug.prototype.getKeys);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'getProperties',
- ol.source.TileDebug.prototype.getProperties);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'set',
- ol.source.TileDebug.prototype.set);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'setProperties',
- ol.source.TileDebug.prototype.setProperties);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'unset',
- ol.source.TileDebug.prototype.unset);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'changed',
- ol.source.TileDebug.prototype.changed);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'dispatchEvent',
- ol.source.TileDebug.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'getRevision',
- ol.source.TileDebug.prototype.getRevision);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'on',
- ol.source.TileDebug.prototype.on);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'once',
- ol.source.TileDebug.prototype.once);
- goog.exportProperty(
- ol.source.TileDebug.prototype,
- 'un',
- ol.source.TileDebug.prototype.un);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'setRenderReprojectionEdges',
- ol.source.TileJSON.prototype.setRenderReprojectionEdges);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'setTileGridForProjection',
- ol.source.TileJSON.prototype.setTileGridForProjection);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'getTileLoadFunction',
- ol.source.TileJSON.prototype.getTileLoadFunction);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'getTileUrlFunction',
- ol.source.TileJSON.prototype.getTileUrlFunction);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'getUrls',
- ol.source.TileJSON.prototype.getUrls);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'setTileLoadFunction',
- ol.source.TileJSON.prototype.setTileLoadFunction);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'setTileUrlFunction',
- ol.source.TileJSON.prototype.setTileUrlFunction);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'setUrl',
- ol.source.TileJSON.prototype.setUrl);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'setUrls',
- ol.source.TileJSON.prototype.setUrls);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'getTileGrid',
- ol.source.TileJSON.prototype.getTileGrid);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'refresh',
- ol.source.TileJSON.prototype.refresh);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'getAttributions',
- ol.source.TileJSON.prototype.getAttributions);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'getLogo',
- ol.source.TileJSON.prototype.getLogo);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'getProjection',
- ol.source.TileJSON.prototype.getProjection);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'getState',
- ol.source.TileJSON.prototype.getState);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'setAttributions',
- ol.source.TileJSON.prototype.setAttributions);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'get',
- ol.source.TileJSON.prototype.get);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'getKeys',
- ol.source.TileJSON.prototype.getKeys);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'getProperties',
- ol.source.TileJSON.prototype.getProperties);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'set',
- ol.source.TileJSON.prototype.set);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'setProperties',
- ol.source.TileJSON.prototype.setProperties);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'unset',
- ol.source.TileJSON.prototype.unset);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'changed',
- ol.source.TileJSON.prototype.changed);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'dispatchEvent',
- ol.source.TileJSON.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'getRevision',
- ol.source.TileJSON.prototype.getRevision);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'on',
- ol.source.TileJSON.prototype.on);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'once',
- ol.source.TileJSON.prototype.once);
- goog.exportProperty(
- ol.source.TileJSON.prototype,
- 'un',
- ol.source.TileJSON.prototype.un);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'getTileGrid',
- ol.source.TileUTFGrid.prototype.getTileGrid);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'refresh',
- ol.source.TileUTFGrid.prototype.refresh);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'getAttributions',
- ol.source.TileUTFGrid.prototype.getAttributions);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'getLogo',
- ol.source.TileUTFGrid.prototype.getLogo);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'getProjection',
- ol.source.TileUTFGrid.prototype.getProjection);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'getState',
- ol.source.TileUTFGrid.prototype.getState);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'setAttributions',
- ol.source.TileUTFGrid.prototype.setAttributions);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'get',
- ol.source.TileUTFGrid.prototype.get);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'getKeys',
- ol.source.TileUTFGrid.prototype.getKeys);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'getProperties',
- ol.source.TileUTFGrid.prototype.getProperties);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'set',
- ol.source.TileUTFGrid.prototype.set);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'setProperties',
- ol.source.TileUTFGrid.prototype.setProperties);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'unset',
- ol.source.TileUTFGrid.prototype.unset);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'changed',
- ol.source.TileUTFGrid.prototype.changed);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'dispatchEvent',
- ol.source.TileUTFGrid.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'getRevision',
- ol.source.TileUTFGrid.prototype.getRevision);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'on',
- ol.source.TileUTFGrid.prototype.on);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'once',
- ol.source.TileUTFGrid.prototype.once);
- goog.exportProperty(
- ol.source.TileUTFGrid.prototype,
- 'un',
- ol.source.TileUTFGrid.prototype.un);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'setRenderReprojectionEdges',
- ol.source.TileWMS.prototype.setRenderReprojectionEdges);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'setTileGridForProjection',
- ol.source.TileWMS.prototype.setTileGridForProjection);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'getTileLoadFunction',
- ol.source.TileWMS.prototype.getTileLoadFunction);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'getTileUrlFunction',
- ol.source.TileWMS.prototype.getTileUrlFunction);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'getUrls',
- ol.source.TileWMS.prototype.getUrls);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'setTileLoadFunction',
- ol.source.TileWMS.prototype.setTileLoadFunction);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'setTileUrlFunction',
- ol.source.TileWMS.prototype.setTileUrlFunction);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'setUrl',
- ol.source.TileWMS.prototype.setUrl);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'setUrls',
- ol.source.TileWMS.prototype.setUrls);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'getTileGrid',
- ol.source.TileWMS.prototype.getTileGrid);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'refresh',
- ol.source.TileWMS.prototype.refresh);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'getAttributions',
- ol.source.TileWMS.prototype.getAttributions);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'getLogo',
- ol.source.TileWMS.prototype.getLogo);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'getProjection',
- ol.source.TileWMS.prototype.getProjection);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'getState',
- ol.source.TileWMS.prototype.getState);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'setAttributions',
- ol.source.TileWMS.prototype.setAttributions);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'get',
- ol.source.TileWMS.prototype.get);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'getKeys',
- ol.source.TileWMS.prototype.getKeys);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'getProperties',
- ol.source.TileWMS.prototype.getProperties);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'set',
- ol.source.TileWMS.prototype.set);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'setProperties',
- ol.source.TileWMS.prototype.setProperties);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'unset',
- ol.source.TileWMS.prototype.unset);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'changed',
- ol.source.TileWMS.prototype.changed);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'dispatchEvent',
- ol.source.TileWMS.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'getRevision',
- ol.source.TileWMS.prototype.getRevision);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'on',
- ol.source.TileWMS.prototype.on);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'once',
- ol.source.TileWMS.prototype.once);
- goog.exportProperty(
- ol.source.TileWMS.prototype,
- 'un',
- ol.source.TileWMS.prototype.un);
- goog.exportProperty(
- ol.source.Vector.Event.prototype,
- 'type',
- ol.source.Vector.Event.prototype.type);
- goog.exportProperty(
- ol.source.Vector.Event.prototype,
- 'target',
- ol.source.Vector.Event.prototype.target);
- goog.exportProperty(
- ol.source.Vector.Event.prototype,
- 'preventDefault',
- ol.source.Vector.Event.prototype.preventDefault);
- goog.exportProperty(
- ol.source.Vector.Event.prototype,
- 'stopPropagation',
- ol.source.Vector.Event.prototype.stopPropagation);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'getTileLoadFunction',
- ol.source.VectorTile.prototype.getTileLoadFunction);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'getTileUrlFunction',
- ol.source.VectorTile.prototype.getTileUrlFunction);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'getUrls',
- ol.source.VectorTile.prototype.getUrls);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'setTileLoadFunction',
- ol.source.VectorTile.prototype.setTileLoadFunction);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'setTileUrlFunction',
- ol.source.VectorTile.prototype.setTileUrlFunction);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'setUrl',
- ol.source.VectorTile.prototype.setUrl);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'setUrls',
- ol.source.VectorTile.prototype.setUrls);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'getTileGrid',
- ol.source.VectorTile.prototype.getTileGrid);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'refresh',
- ol.source.VectorTile.prototype.refresh);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'getAttributions',
- ol.source.VectorTile.prototype.getAttributions);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'getLogo',
- ol.source.VectorTile.prototype.getLogo);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'getProjection',
- ol.source.VectorTile.prototype.getProjection);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'getState',
- ol.source.VectorTile.prototype.getState);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'setAttributions',
- ol.source.VectorTile.prototype.setAttributions);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'get',
- ol.source.VectorTile.prototype.get);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'getKeys',
- ol.source.VectorTile.prototype.getKeys);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'getProperties',
- ol.source.VectorTile.prototype.getProperties);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'set',
- ol.source.VectorTile.prototype.set);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'setProperties',
- ol.source.VectorTile.prototype.setProperties);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'unset',
- ol.source.VectorTile.prototype.unset);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'changed',
- ol.source.VectorTile.prototype.changed);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'dispatchEvent',
- ol.source.VectorTile.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'getRevision',
- ol.source.VectorTile.prototype.getRevision);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'on',
- ol.source.VectorTile.prototype.on);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'once',
- ol.source.VectorTile.prototype.once);
- goog.exportProperty(
- ol.source.VectorTile.prototype,
- 'un',
- ol.source.VectorTile.prototype.un);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'setRenderReprojectionEdges',
- ol.source.WMTS.prototype.setRenderReprojectionEdges);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'setTileGridForProjection',
- ol.source.WMTS.prototype.setTileGridForProjection);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'getTileLoadFunction',
- ol.source.WMTS.prototype.getTileLoadFunction);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'getTileUrlFunction',
- ol.source.WMTS.prototype.getTileUrlFunction);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'getUrls',
- ol.source.WMTS.prototype.getUrls);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'setTileLoadFunction',
- ol.source.WMTS.prototype.setTileLoadFunction);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'setTileUrlFunction',
- ol.source.WMTS.prototype.setTileUrlFunction);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'setUrl',
- ol.source.WMTS.prototype.setUrl);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'setUrls',
- ol.source.WMTS.prototype.setUrls);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'getTileGrid',
- ol.source.WMTS.prototype.getTileGrid);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'refresh',
- ol.source.WMTS.prototype.refresh);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'getAttributions',
- ol.source.WMTS.prototype.getAttributions);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'getLogo',
- ol.source.WMTS.prototype.getLogo);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'getProjection',
- ol.source.WMTS.prototype.getProjection);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'getState',
- ol.source.WMTS.prototype.getState);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'setAttributions',
- ol.source.WMTS.prototype.setAttributions);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'get',
- ol.source.WMTS.prototype.get);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'getKeys',
- ol.source.WMTS.prototype.getKeys);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'getProperties',
- ol.source.WMTS.prototype.getProperties);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'set',
- ol.source.WMTS.prototype.set);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'setProperties',
- ol.source.WMTS.prototype.setProperties);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'unset',
- ol.source.WMTS.prototype.unset);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'changed',
- ol.source.WMTS.prototype.changed);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'dispatchEvent',
- ol.source.WMTS.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'getRevision',
- ol.source.WMTS.prototype.getRevision);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'on',
- ol.source.WMTS.prototype.on);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'once',
- ol.source.WMTS.prototype.once);
- goog.exportProperty(
- ol.source.WMTS.prototype,
- 'un',
- ol.source.WMTS.prototype.un);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'setRenderReprojectionEdges',
- ol.source.Zoomify.prototype.setRenderReprojectionEdges);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'setTileGridForProjection',
- ol.source.Zoomify.prototype.setTileGridForProjection);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'getTileLoadFunction',
- ol.source.Zoomify.prototype.getTileLoadFunction);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'getTileUrlFunction',
- ol.source.Zoomify.prototype.getTileUrlFunction);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'getUrls',
- ol.source.Zoomify.prototype.getUrls);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'setTileLoadFunction',
- ol.source.Zoomify.prototype.setTileLoadFunction);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'setTileUrlFunction',
- ol.source.Zoomify.prototype.setTileUrlFunction);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'setUrl',
- ol.source.Zoomify.prototype.setUrl);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'setUrls',
- ol.source.Zoomify.prototype.setUrls);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'getTileGrid',
- ol.source.Zoomify.prototype.getTileGrid);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'refresh',
- ol.source.Zoomify.prototype.refresh);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'getAttributions',
- ol.source.Zoomify.prototype.getAttributions);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'getLogo',
- ol.source.Zoomify.prototype.getLogo);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'getProjection',
- ol.source.Zoomify.prototype.getProjection);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'getState',
- ol.source.Zoomify.prototype.getState);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'setAttributions',
- ol.source.Zoomify.prototype.setAttributions);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'get',
- ol.source.Zoomify.prototype.get);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'getKeys',
- ol.source.Zoomify.prototype.getKeys);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'getProperties',
- ol.source.Zoomify.prototype.getProperties);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'set',
- ol.source.Zoomify.prototype.set);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'setProperties',
- ol.source.Zoomify.prototype.setProperties);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'unset',
- ol.source.Zoomify.prototype.unset);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'changed',
- ol.source.Zoomify.prototype.changed);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'dispatchEvent',
- ol.source.Zoomify.prototype.dispatchEvent);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'getRevision',
- ol.source.Zoomify.prototype.getRevision);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'on',
- ol.source.Zoomify.prototype.on);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'once',
- ol.source.Zoomify.prototype.once);
- goog.exportProperty(
- ol.source.Zoomify.prototype,
- 'un',
- ol.source.Zoomify.prototype.un);
- goog.exportProperty(
- ol.reproj.Tile.prototype,
- 'getTileCoord',
- ol.reproj.Tile.prototype.getTileCoord);
- goog.exportProperty(
- ol.reproj.Tile.prototype,
- 'load',
- ol.reproj.Tile.prototype.load);
- goog.exportProperty(
- ol.renderer.Layer.prototype,
- 'changed',
- ol.renderer.Layer.prototype.changed);
- goog.exportProperty(
- ol.renderer.Layer.prototype,
- 'dispatchEvent',
- ol.renderer.Layer.prototype.dispatchEvent);
- goog.exportProperty(
- ol.renderer.Layer.prototype,
- 'getRevision',
- ol.renderer.Layer.prototype.getRevision);
- goog.exportProperty(
- ol.renderer.Layer.prototype,
- 'on',
- ol.renderer.Layer.prototype.on);
- goog.exportProperty(
- ol.renderer.Layer.prototype,
- 'once',
- ol.renderer.Layer.prototype.once);
- goog.exportProperty(
- ol.renderer.Layer.prototype,
- 'un',
- ol.renderer.Layer.prototype.un);
- goog.exportProperty(
- ol.renderer.webgl.Layer.prototype,
- 'changed',
- ol.renderer.webgl.Layer.prototype.changed);
- goog.exportProperty(
- ol.renderer.webgl.Layer.prototype,
- 'dispatchEvent',
- ol.renderer.webgl.Layer.prototype.dispatchEvent);
- goog.exportProperty(
- ol.renderer.webgl.Layer.prototype,
- 'getRevision',
- ol.renderer.webgl.Layer.prototype.getRevision);
- goog.exportProperty(
- ol.renderer.webgl.Layer.prototype,
- 'on',
- ol.renderer.webgl.Layer.prototype.on);
- goog.exportProperty(
- ol.renderer.webgl.Layer.prototype,
- 'once',
- ol.renderer.webgl.Layer.prototype.once);
- goog.exportProperty(
- ol.renderer.webgl.Layer.prototype,
- 'un',
- ol.renderer.webgl.Layer.prototype.un);
- goog.exportProperty(
- ol.renderer.webgl.ImageLayer.prototype,
- 'changed',
- ol.renderer.webgl.ImageLayer.prototype.changed);
- goog.exportProperty(
- ol.renderer.webgl.ImageLayer.prototype,
- 'dispatchEvent',
- ol.renderer.webgl.ImageLayer.prototype.dispatchEvent);
- goog.exportProperty(
- ol.renderer.webgl.ImageLayer.prototype,
- 'getRevision',
- ol.renderer.webgl.ImageLayer.prototype.getRevision);
- goog.exportProperty(
- ol.renderer.webgl.ImageLayer.prototype,
- 'on',
- ol.renderer.webgl.ImageLayer.prototype.on);
- goog.exportProperty(
- ol.renderer.webgl.ImageLayer.prototype,
- 'once',
- ol.renderer.webgl.ImageLayer.prototype.once);
- goog.exportProperty(
- ol.renderer.webgl.ImageLayer.prototype,
- 'un',
- ol.renderer.webgl.ImageLayer.prototype.un);
- goog.exportProperty(
- ol.renderer.webgl.TileLayer.prototype,
- 'changed',
- ol.renderer.webgl.TileLayer.prototype.changed);
- goog.exportProperty(
- ol.renderer.webgl.TileLayer.prototype,
- 'dispatchEvent',
- ol.renderer.webgl.TileLayer.prototype.dispatchEvent);
- goog.exportProperty(
- ol.renderer.webgl.TileLayer.prototype,
- 'getRevision',
- ol.renderer.webgl.TileLayer.prototype.getRevision);
- goog.exportProperty(
- ol.renderer.webgl.TileLayer.prototype,
- 'on',
- ol.renderer.webgl.TileLayer.prototype.on);
- goog.exportProperty(
- ol.renderer.webgl.TileLayer.prototype,
- 'once',
- ol.renderer.webgl.TileLayer.prototype.once);
- goog.exportProperty(
- ol.renderer.webgl.TileLayer.prototype,
- 'un',
- ol.renderer.webgl.TileLayer.prototype.un);
- goog.exportProperty(
- ol.renderer.webgl.VectorLayer.prototype,
- 'changed',
- ol.renderer.webgl.VectorLayer.prototype.changed);
- goog.exportProperty(
- ol.renderer.webgl.VectorLayer.prototype,
- 'dispatchEvent',
- ol.renderer.webgl.VectorLayer.prototype.dispatchEvent);
- goog.exportProperty(
- ol.renderer.webgl.VectorLayer.prototype,
- 'getRevision',
- ol.renderer.webgl.VectorLayer.prototype.getRevision);
- goog.exportProperty(
- ol.renderer.webgl.VectorLayer.prototype,
- 'on',
- ol.renderer.webgl.VectorLayer.prototype.on);
- goog.exportProperty(
- ol.renderer.webgl.VectorLayer.prototype,
- 'once',
- ol.renderer.webgl.VectorLayer.prototype.once);
- goog.exportProperty(
- ol.renderer.webgl.VectorLayer.prototype,
- 'un',
- ol.renderer.webgl.VectorLayer.prototype.un);
- goog.exportProperty(
- ol.renderer.canvas.Layer.prototype,
- 'changed',
- ol.renderer.canvas.Layer.prototype.changed);
- goog.exportProperty(
- ol.renderer.canvas.Layer.prototype,
- 'dispatchEvent',
- ol.renderer.canvas.Layer.prototype.dispatchEvent);
- goog.exportProperty(
- ol.renderer.canvas.Layer.prototype,
- 'getRevision',
- ol.renderer.canvas.Layer.prototype.getRevision);
- goog.exportProperty(
- ol.renderer.canvas.Layer.prototype,
- 'on',
- ol.renderer.canvas.Layer.prototype.on);
- goog.exportProperty(
- ol.renderer.canvas.Layer.prototype,
- 'once',
- ol.renderer.canvas.Layer.prototype.once);
- goog.exportProperty(
- ol.renderer.canvas.Layer.prototype,
- 'un',
- ol.renderer.canvas.Layer.prototype.un);
- goog.exportProperty(
- ol.renderer.canvas.IntermediateCanvas.prototype,
- 'changed',
- ol.renderer.canvas.IntermediateCanvas.prototype.changed);
- goog.exportProperty(
- ol.renderer.canvas.IntermediateCanvas.prototype,
- 'dispatchEvent',
- ol.renderer.canvas.IntermediateCanvas.prototype.dispatchEvent);
- goog.exportProperty(
- ol.renderer.canvas.IntermediateCanvas.prototype,
- 'getRevision',
- ol.renderer.canvas.IntermediateCanvas.prototype.getRevision);
- goog.exportProperty(
- ol.renderer.canvas.IntermediateCanvas.prototype,
- 'on',
- ol.renderer.canvas.IntermediateCanvas.prototype.on);
- goog.exportProperty(
- ol.renderer.canvas.IntermediateCanvas.prototype,
- 'once',
- ol.renderer.canvas.IntermediateCanvas.prototype.once);
- goog.exportProperty(
- ol.renderer.canvas.IntermediateCanvas.prototype,
- 'un',
- ol.renderer.canvas.IntermediateCanvas.prototype.un);
- goog.exportProperty(
- ol.renderer.canvas.ImageLayer.prototype,
- 'changed',
- ol.renderer.canvas.ImageLayer.prototype.changed);
- goog.exportProperty(
- ol.renderer.canvas.ImageLayer.prototype,
- 'dispatchEvent',
- ol.renderer.canvas.ImageLayer.prototype.dispatchEvent);
- goog.exportProperty(
- ol.renderer.canvas.ImageLayer.prototype,
- 'getRevision',
- ol.renderer.canvas.ImageLayer.prototype.getRevision);
- goog.exportProperty(
- ol.renderer.canvas.ImageLayer.prototype,
- 'on',
- ol.renderer.canvas.ImageLayer.prototype.on);
- goog.exportProperty(
- ol.renderer.canvas.ImageLayer.prototype,
- 'once',
- ol.renderer.canvas.ImageLayer.prototype.once);
- goog.exportProperty(
- ol.renderer.canvas.ImageLayer.prototype,
- 'un',
- ol.renderer.canvas.ImageLayer.prototype.un);
- goog.exportProperty(
- ol.renderer.canvas.TileLayer.prototype,
- 'changed',
- ol.renderer.canvas.TileLayer.prototype.changed);
- goog.exportProperty(
- ol.renderer.canvas.TileLayer.prototype,
- 'dispatchEvent',
- ol.renderer.canvas.TileLayer.prototype.dispatchEvent);
- goog.exportProperty(
- ol.renderer.canvas.TileLayer.prototype,
- 'getRevision',
- ol.renderer.canvas.TileLayer.prototype.getRevision);
- goog.exportProperty(
- ol.renderer.canvas.TileLayer.prototype,
- 'on',
- ol.renderer.canvas.TileLayer.prototype.on);
- goog.exportProperty(
- ol.renderer.canvas.TileLayer.prototype,
- 'once',
- ol.renderer.canvas.TileLayer.prototype.once);
- goog.exportProperty(
- ol.renderer.canvas.TileLayer.prototype,
- 'un',
- ol.renderer.canvas.TileLayer.prototype.un);
- goog.exportProperty(
- ol.renderer.canvas.VectorLayer.prototype,
- 'changed',
- ol.renderer.canvas.VectorLayer.prototype.changed);
- goog.exportProperty(
- ol.renderer.canvas.VectorLayer.prototype,
- 'dispatchEvent',
- ol.renderer.canvas.VectorLayer.prototype.dispatchEvent);
- goog.exportProperty(
- ol.renderer.canvas.VectorLayer.prototype,
- 'getRevision',
- ol.renderer.canvas.VectorLayer.prototype.getRevision);
- goog.exportProperty(
- ol.renderer.canvas.VectorLayer.prototype,
- 'on',
- ol.renderer.canvas.VectorLayer.prototype.on);
- goog.exportProperty(
- ol.renderer.canvas.VectorLayer.prototype,
- 'once',
- ol.renderer.canvas.VectorLayer.prototype.once);
- goog.exportProperty(
- ol.renderer.canvas.VectorLayer.prototype,
- 'un',
- ol.renderer.canvas.VectorLayer.prototype.un);
- goog.exportProperty(
- ol.renderer.canvas.VectorTileLayer.prototype,
- 'changed',
- ol.renderer.canvas.VectorTileLayer.prototype.changed);
- goog.exportProperty(
- ol.renderer.canvas.VectorTileLayer.prototype,
- 'dispatchEvent',
- ol.renderer.canvas.VectorTileLayer.prototype.dispatchEvent);
- goog.exportProperty(
- ol.renderer.canvas.VectorTileLayer.prototype,
- 'getRevision',
- ol.renderer.canvas.VectorTileLayer.prototype.getRevision);
- goog.exportProperty(
- ol.renderer.canvas.VectorTileLayer.prototype,
- 'on',
- ol.renderer.canvas.VectorTileLayer.prototype.on);
- goog.exportProperty(
- ol.renderer.canvas.VectorTileLayer.prototype,
- 'once',
- ol.renderer.canvas.VectorTileLayer.prototype.once);
- goog.exportProperty(
- ol.renderer.canvas.VectorTileLayer.prototype,
- 'un',
- ol.renderer.canvas.VectorTileLayer.prototype.un);
- goog.exportProperty(
- ol.render.Event.prototype,
- 'type',
- ol.render.Event.prototype.type);
- goog.exportProperty(
- ol.render.Event.prototype,
- 'target',
- ol.render.Event.prototype.target);
- goog.exportProperty(
- ol.render.Event.prototype,
- 'preventDefault',
- ol.render.Event.prototype.preventDefault);
- goog.exportProperty(
- ol.render.Event.prototype,
- 'stopPropagation',
- ol.render.Event.prototype.stopPropagation);
- goog.exportProperty(
- ol.pointer.PointerEvent.prototype,
- 'type',
- ol.pointer.PointerEvent.prototype.type);
- goog.exportProperty(
- ol.pointer.PointerEvent.prototype,
- 'target',
- ol.pointer.PointerEvent.prototype.target);
- goog.exportProperty(
- ol.pointer.PointerEvent.prototype,
- 'preventDefault',
- ol.pointer.PointerEvent.prototype.preventDefault);
- goog.exportProperty(
- ol.pointer.PointerEvent.prototype,
- 'stopPropagation',
- ol.pointer.PointerEvent.prototype.stopPropagation);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'get',
- ol.layer.Base.prototype.get);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'getKeys',
- ol.layer.Base.prototype.getKeys);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'getProperties',
- ol.layer.Base.prototype.getProperties);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'set',
- ol.layer.Base.prototype.set);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'setProperties',
- ol.layer.Base.prototype.setProperties);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'unset',
- ol.layer.Base.prototype.unset);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'changed',
- ol.layer.Base.prototype.changed);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'dispatchEvent',
- ol.layer.Base.prototype.dispatchEvent);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'getRevision',
- ol.layer.Base.prototype.getRevision);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'on',
- ol.layer.Base.prototype.on);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'once',
- ol.layer.Base.prototype.once);
- goog.exportProperty(
- ol.layer.Base.prototype,
- 'un',
- ol.layer.Base.prototype.un);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'getExtent',
- ol.layer.Group.prototype.getExtent);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'getMaxResolution',
- ol.layer.Group.prototype.getMaxResolution);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'getMinResolution',
- ol.layer.Group.prototype.getMinResolution);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'getOpacity',
- ol.layer.Group.prototype.getOpacity);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'getVisible',
- ol.layer.Group.prototype.getVisible);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'getZIndex',
- ol.layer.Group.prototype.getZIndex);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'setExtent',
- ol.layer.Group.prototype.setExtent);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'setMaxResolution',
- ol.layer.Group.prototype.setMaxResolution);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'setMinResolution',
- ol.layer.Group.prototype.setMinResolution);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'setOpacity',
- ol.layer.Group.prototype.setOpacity);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'setVisible',
- ol.layer.Group.prototype.setVisible);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'setZIndex',
- ol.layer.Group.prototype.setZIndex);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'get',
- ol.layer.Group.prototype.get);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'getKeys',
- ol.layer.Group.prototype.getKeys);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'getProperties',
- ol.layer.Group.prototype.getProperties);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'set',
- ol.layer.Group.prototype.set);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'setProperties',
- ol.layer.Group.prototype.setProperties);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'unset',
- ol.layer.Group.prototype.unset);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'changed',
- ol.layer.Group.prototype.changed);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'dispatchEvent',
- ol.layer.Group.prototype.dispatchEvent);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'getRevision',
- ol.layer.Group.prototype.getRevision);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'on',
- ol.layer.Group.prototype.on);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'once',
- ol.layer.Group.prototype.once);
- goog.exportProperty(
- ol.layer.Group.prototype,
- 'un',
- ol.layer.Group.prototype.un);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'getExtent',
- ol.layer.Layer.prototype.getExtent);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'getMaxResolution',
- ol.layer.Layer.prototype.getMaxResolution);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'getMinResolution',
- ol.layer.Layer.prototype.getMinResolution);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'getOpacity',
- ol.layer.Layer.prototype.getOpacity);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'getVisible',
- ol.layer.Layer.prototype.getVisible);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'getZIndex',
- ol.layer.Layer.prototype.getZIndex);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'setExtent',
- ol.layer.Layer.prototype.setExtent);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'setMaxResolution',
- ol.layer.Layer.prototype.setMaxResolution);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'setMinResolution',
- ol.layer.Layer.prototype.setMinResolution);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'setOpacity',
- ol.layer.Layer.prototype.setOpacity);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'setVisible',
- ol.layer.Layer.prototype.setVisible);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'setZIndex',
- ol.layer.Layer.prototype.setZIndex);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'get',
- ol.layer.Layer.prototype.get);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'getKeys',
- ol.layer.Layer.prototype.getKeys);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'getProperties',
- ol.layer.Layer.prototype.getProperties);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'set',
- ol.layer.Layer.prototype.set);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'setProperties',
- ol.layer.Layer.prototype.setProperties);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'unset',
- ol.layer.Layer.prototype.unset);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'changed',
- ol.layer.Layer.prototype.changed);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'dispatchEvent',
- ol.layer.Layer.prototype.dispatchEvent);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'getRevision',
- ol.layer.Layer.prototype.getRevision);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'on',
- ol.layer.Layer.prototype.on);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'once',
- ol.layer.Layer.prototype.once);
- goog.exportProperty(
- ol.layer.Layer.prototype,
- 'un',
- ol.layer.Layer.prototype.un);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'setMap',
- ol.layer.Vector.prototype.setMap);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'setSource',
- ol.layer.Vector.prototype.setSource);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'getExtent',
- ol.layer.Vector.prototype.getExtent);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'getMaxResolution',
- ol.layer.Vector.prototype.getMaxResolution);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'getMinResolution',
- ol.layer.Vector.prototype.getMinResolution);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'getOpacity',
- ol.layer.Vector.prototype.getOpacity);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'getVisible',
- ol.layer.Vector.prototype.getVisible);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'getZIndex',
- ol.layer.Vector.prototype.getZIndex);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'setExtent',
- ol.layer.Vector.prototype.setExtent);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'setMaxResolution',
- ol.layer.Vector.prototype.setMaxResolution);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'setMinResolution',
- ol.layer.Vector.prototype.setMinResolution);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'setOpacity',
- ol.layer.Vector.prototype.setOpacity);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'setVisible',
- ol.layer.Vector.prototype.setVisible);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'setZIndex',
- ol.layer.Vector.prototype.setZIndex);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'get',
- ol.layer.Vector.prototype.get);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'getKeys',
- ol.layer.Vector.prototype.getKeys);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'getProperties',
- ol.layer.Vector.prototype.getProperties);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'set',
- ol.layer.Vector.prototype.set);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'setProperties',
- ol.layer.Vector.prototype.setProperties);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'unset',
- ol.layer.Vector.prototype.unset);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'changed',
- ol.layer.Vector.prototype.changed);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'dispatchEvent',
- ol.layer.Vector.prototype.dispatchEvent);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'getRevision',
- ol.layer.Vector.prototype.getRevision);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'on',
- ol.layer.Vector.prototype.on);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'once',
- ol.layer.Vector.prototype.once);
- goog.exportProperty(
- ol.layer.Vector.prototype,
- 'un',
- ol.layer.Vector.prototype.un);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'getSource',
- ol.layer.Heatmap.prototype.getSource);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'getStyle',
- ol.layer.Heatmap.prototype.getStyle);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'getStyleFunction',
- ol.layer.Heatmap.prototype.getStyleFunction);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'setStyle',
- ol.layer.Heatmap.prototype.setStyle);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'setMap',
- ol.layer.Heatmap.prototype.setMap);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'setSource',
- ol.layer.Heatmap.prototype.setSource);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'getExtent',
- ol.layer.Heatmap.prototype.getExtent);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'getMaxResolution',
- ol.layer.Heatmap.prototype.getMaxResolution);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'getMinResolution',
- ol.layer.Heatmap.prototype.getMinResolution);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'getOpacity',
- ol.layer.Heatmap.prototype.getOpacity);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'getVisible',
- ol.layer.Heatmap.prototype.getVisible);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'getZIndex',
- ol.layer.Heatmap.prototype.getZIndex);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'setExtent',
- ol.layer.Heatmap.prototype.setExtent);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'setMaxResolution',
- ol.layer.Heatmap.prototype.setMaxResolution);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'setMinResolution',
- ol.layer.Heatmap.prototype.setMinResolution);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'setOpacity',
- ol.layer.Heatmap.prototype.setOpacity);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'setVisible',
- ol.layer.Heatmap.prototype.setVisible);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'setZIndex',
- ol.layer.Heatmap.prototype.setZIndex);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'get',
- ol.layer.Heatmap.prototype.get);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'getKeys',
- ol.layer.Heatmap.prototype.getKeys);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'getProperties',
- ol.layer.Heatmap.prototype.getProperties);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'set',
- ol.layer.Heatmap.prototype.set);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'setProperties',
- ol.layer.Heatmap.prototype.setProperties);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'unset',
- ol.layer.Heatmap.prototype.unset);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'changed',
- ol.layer.Heatmap.prototype.changed);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'dispatchEvent',
- ol.layer.Heatmap.prototype.dispatchEvent);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'getRevision',
- ol.layer.Heatmap.prototype.getRevision);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'on',
- ol.layer.Heatmap.prototype.on);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'once',
- ol.layer.Heatmap.prototype.once);
- goog.exportProperty(
- ol.layer.Heatmap.prototype,
- 'un',
- ol.layer.Heatmap.prototype.un);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'setMap',
- ol.layer.Image.prototype.setMap);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'setSource',
- ol.layer.Image.prototype.setSource);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'getExtent',
- ol.layer.Image.prototype.getExtent);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'getMaxResolution',
- ol.layer.Image.prototype.getMaxResolution);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'getMinResolution',
- ol.layer.Image.prototype.getMinResolution);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'getOpacity',
- ol.layer.Image.prototype.getOpacity);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'getVisible',
- ol.layer.Image.prototype.getVisible);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'getZIndex',
- ol.layer.Image.prototype.getZIndex);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'setExtent',
- ol.layer.Image.prototype.setExtent);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'setMaxResolution',
- ol.layer.Image.prototype.setMaxResolution);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'setMinResolution',
- ol.layer.Image.prototype.setMinResolution);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'setOpacity',
- ol.layer.Image.prototype.setOpacity);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'setVisible',
- ol.layer.Image.prototype.setVisible);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'setZIndex',
- ol.layer.Image.prototype.setZIndex);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'get',
- ol.layer.Image.prototype.get);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'getKeys',
- ol.layer.Image.prototype.getKeys);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'getProperties',
- ol.layer.Image.prototype.getProperties);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'set',
- ol.layer.Image.prototype.set);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'setProperties',
- ol.layer.Image.prototype.setProperties);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'unset',
- ol.layer.Image.prototype.unset);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'changed',
- ol.layer.Image.prototype.changed);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'dispatchEvent',
- ol.layer.Image.prototype.dispatchEvent);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'getRevision',
- ol.layer.Image.prototype.getRevision);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'on',
- ol.layer.Image.prototype.on);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'once',
- ol.layer.Image.prototype.once);
- goog.exportProperty(
- ol.layer.Image.prototype,
- 'un',
- ol.layer.Image.prototype.un);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'setMap',
- ol.layer.Tile.prototype.setMap);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'setSource',
- ol.layer.Tile.prototype.setSource);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'getExtent',
- ol.layer.Tile.prototype.getExtent);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'getMaxResolution',
- ol.layer.Tile.prototype.getMaxResolution);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'getMinResolution',
- ol.layer.Tile.prototype.getMinResolution);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'getOpacity',
- ol.layer.Tile.prototype.getOpacity);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'getVisible',
- ol.layer.Tile.prototype.getVisible);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'getZIndex',
- ol.layer.Tile.prototype.getZIndex);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'setExtent',
- ol.layer.Tile.prototype.setExtent);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'setMaxResolution',
- ol.layer.Tile.prototype.setMaxResolution);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'setMinResolution',
- ol.layer.Tile.prototype.setMinResolution);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'setOpacity',
- ol.layer.Tile.prototype.setOpacity);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'setVisible',
- ol.layer.Tile.prototype.setVisible);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'setZIndex',
- ol.layer.Tile.prototype.setZIndex);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'get',
- ol.layer.Tile.prototype.get);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'getKeys',
- ol.layer.Tile.prototype.getKeys);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'getProperties',
- ol.layer.Tile.prototype.getProperties);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'set',
- ol.layer.Tile.prototype.set);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'setProperties',
- ol.layer.Tile.prototype.setProperties);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'unset',
- ol.layer.Tile.prototype.unset);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'changed',
- ol.layer.Tile.prototype.changed);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'dispatchEvent',
- ol.layer.Tile.prototype.dispatchEvent);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'getRevision',
- ol.layer.Tile.prototype.getRevision);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'on',
- ol.layer.Tile.prototype.on);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'once',
- ol.layer.Tile.prototype.once);
- goog.exportProperty(
- ol.layer.Tile.prototype,
- 'un',
- ol.layer.Tile.prototype.un);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'getStyle',
- ol.layer.VectorTile.prototype.getStyle);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'getStyleFunction',
- ol.layer.VectorTile.prototype.getStyleFunction);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'setStyle',
- ol.layer.VectorTile.prototype.setStyle);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'setMap',
- ol.layer.VectorTile.prototype.setMap);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'setSource',
- ol.layer.VectorTile.prototype.setSource);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'getExtent',
- ol.layer.VectorTile.prototype.getExtent);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'getMaxResolution',
- ol.layer.VectorTile.prototype.getMaxResolution);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'getMinResolution',
- ol.layer.VectorTile.prototype.getMinResolution);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'getOpacity',
- ol.layer.VectorTile.prototype.getOpacity);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'getVisible',
- ol.layer.VectorTile.prototype.getVisible);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'getZIndex',
- ol.layer.VectorTile.prototype.getZIndex);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'setExtent',
- ol.layer.VectorTile.prototype.setExtent);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'setMaxResolution',
- ol.layer.VectorTile.prototype.setMaxResolution);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'setMinResolution',
- ol.layer.VectorTile.prototype.setMinResolution);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'setOpacity',
- ol.layer.VectorTile.prototype.setOpacity);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'setVisible',
- ol.layer.VectorTile.prototype.setVisible);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'setZIndex',
- ol.layer.VectorTile.prototype.setZIndex);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'get',
- ol.layer.VectorTile.prototype.get);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'getKeys',
- ol.layer.VectorTile.prototype.getKeys);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'getProperties',
- ol.layer.VectorTile.prototype.getProperties);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'set',
- ol.layer.VectorTile.prototype.set);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'setProperties',
- ol.layer.VectorTile.prototype.setProperties);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'unset',
- ol.layer.VectorTile.prototype.unset);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'changed',
- ol.layer.VectorTile.prototype.changed);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'dispatchEvent',
- ol.layer.VectorTile.prototype.dispatchEvent);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'getRevision',
- ol.layer.VectorTile.prototype.getRevision);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'on',
- ol.layer.VectorTile.prototype.on);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'once',
- ol.layer.VectorTile.prototype.once);
- goog.exportProperty(
- ol.layer.VectorTile.prototype,
- 'un',
- ol.layer.VectorTile.prototype.un);
- goog.exportProperty(
- ol.interaction.Interaction.prototype,
- 'get',
- ol.interaction.Interaction.prototype.get);
- goog.exportProperty(
- ol.interaction.Interaction.prototype,
- 'getKeys',
- ol.interaction.Interaction.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.Interaction.prototype,
- 'getProperties',
- ol.interaction.Interaction.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.Interaction.prototype,
- 'set',
- ol.interaction.Interaction.prototype.set);
- goog.exportProperty(
- ol.interaction.Interaction.prototype,
- 'setProperties',
- ol.interaction.Interaction.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.Interaction.prototype,
- 'unset',
- ol.interaction.Interaction.prototype.unset);
- goog.exportProperty(
- ol.interaction.Interaction.prototype,
- 'changed',
- ol.interaction.Interaction.prototype.changed);
- goog.exportProperty(
- ol.interaction.Interaction.prototype,
- 'dispatchEvent',
- ol.interaction.Interaction.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.Interaction.prototype,
- 'getRevision',
- ol.interaction.Interaction.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.Interaction.prototype,
- 'on',
- ol.interaction.Interaction.prototype.on);
- goog.exportProperty(
- ol.interaction.Interaction.prototype,
- 'once',
- ol.interaction.Interaction.prototype.once);
- goog.exportProperty(
- ol.interaction.Interaction.prototype,
- 'un',
- ol.interaction.Interaction.prototype.un);
- goog.exportProperty(
- ol.interaction.DoubleClickZoom.prototype,
- 'getActive',
- ol.interaction.DoubleClickZoom.prototype.getActive);
- goog.exportProperty(
- ol.interaction.DoubleClickZoom.prototype,
- 'getMap',
- ol.interaction.DoubleClickZoom.prototype.getMap);
- goog.exportProperty(
- ol.interaction.DoubleClickZoom.prototype,
- 'setActive',
- ol.interaction.DoubleClickZoom.prototype.setActive);
- goog.exportProperty(
- ol.interaction.DoubleClickZoom.prototype,
- 'get',
- ol.interaction.DoubleClickZoom.prototype.get);
- goog.exportProperty(
- ol.interaction.DoubleClickZoom.prototype,
- 'getKeys',
- ol.interaction.DoubleClickZoom.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.DoubleClickZoom.prototype,
- 'getProperties',
- ol.interaction.DoubleClickZoom.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.DoubleClickZoom.prototype,
- 'set',
- ol.interaction.DoubleClickZoom.prototype.set);
- goog.exportProperty(
- ol.interaction.DoubleClickZoom.prototype,
- 'setProperties',
- ol.interaction.DoubleClickZoom.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.DoubleClickZoom.prototype,
- 'unset',
- ol.interaction.DoubleClickZoom.prototype.unset);
- goog.exportProperty(
- ol.interaction.DoubleClickZoom.prototype,
- 'changed',
- ol.interaction.DoubleClickZoom.prototype.changed);
- goog.exportProperty(
- ol.interaction.DoubleClickZoom.prototype,
- 'dispatchEvent',
- ol.interaction.DoubleClickZoom.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.DoubleClickZoom.prototype,
- 'getRevision',
- ol.interaction.DoubleClickZoom.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.DoubleClickZoom.prototype,
- 'on',
- ol.interaction.DoubleClickZoom.prototype.on);
- goog.exportProperty(
- ol.interaction.DoubleClickZoom.prototype,
- 'once',
- ol.interaction.DoubleClickZoom.prototype.once);
- goog.exportProperty(
- ol.interaction.DoubleClickZoom.prototype,
- 'un',
- ol.interaction.DoubleClickZoom.prototype.un);
- goog.exportProperty(
- ol.interaction.DragAndDrop.prototype,
- 'getActive',
- ol.interaction.DragAndDrop.prototype.getActive);
- goog.exportProperty(
- ol.interaction.DragAndDrop.prototype,
- 'getMap',
- ol.interaction.DragAndDrop.prototype.getMap);
- goog.exportProperty(
- ol.interaction.DragAndDrop.prototype,
- 'setActive',
- ol.interaction.DragAndDrop.prototype.setActive);
- goog.exportProperty(
- ol.interaction.DragAndDrop.prototype,
- 'get',
- ol.interaction.DragAndDrop.prototype.get);
- goog.exportProperty(
- ol.interaction.DragAndDrop.prototype,
- 'getKeys',
- ol.interaction.DragAndDrop.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.DragAndDrop.prototype,
- 'getProperties',
- ol.interaction.DragAndDrop.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.DragAndDrop.prototype,
- 'set',
- ol.interaction.DragAndDrop.prototype.set);
- goog.exportProperty(
- ol.interaction.DragAndDrop.prototype,
- 'setProperties',
- ol.interaction.DragAndDrop.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.DragAndDrop.prototype,
- 'unset',
- ol.interaction.DragAndDrop.prototype.unset);
- goog.exportProperty(
- ol.interaction.DragAndDrop.prototype,
- 'changed',
- ol.interaction.DragAndDrop.prototype.changed);
- goog.exportProperty(
- ol.interaction.DragAndDrop.prototype,
- 'dispatchEvent',
- ol.interaction.DragAndDrop.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.DragAndDrop.prototype,
- 'getRevision',
- ol.interaction.DragAndDrop.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.DragAndDrop.prototype,
- 'on',
- ol.interaction.DragAndDrop.prototype.on);
- goog.exportProperty(
- ol.interaction.DragAndDrop.prototype,
- 'once',
- ol.interaction.DragAndDrop.prototype.once);
- goog.exportProperty(
- ol.interaction.DragAndDrop.prototype,
- 'un',
- ol.interaction.DragAndDrop.prototype.un);
- goog.exportProperty(
- ol.interaction.DragAndDrop.Event.prototype,
- 'type',
- ol.interaction.DragAndDrop.Event.prototype.type);
- goog.exportProperty(
- ol.interaction.DragAndDrop.Event.prototype,
- 'target',
- ol.interaction.DragAndDrop.Event.prototype.target);
- goog.exportProperty(
- ol.interaction.DragAndDrop.Event.prototype,
- 'preventDefault',
- ol.interaction.DragAndDrop.Event.prototype.preventDefault);
- goog.exportProperty(
- ol.interaction.DragAndDrop.Event.prototype,
- 'stopPropagation',
- ol.interaction.DragAndDrop.Event.prototype.stopPropagation);
- goog.exportProperty(
- ol.interaction.Pointer.prototype,
- 'getActive',
- ol.interaction.Pointer.prototype.getActive);
- goog.exportProperty(
- ol.interaction.Pointer.prototype,
- 'getMap',
- ol.interaction.Pointer.prototype.getMap);
- goog.exportProperty(
- ol.interaction.Pointer.prototype,
- 'setActive',
- ol.interaction.Pointer.prototype.setActive);
- goog.exportProperty(
- ol.interaction.Pointer.prototype,
- 'get',
- ol.interaction.Pointer.prototype.get);
- goog.exportProperty(
- ol.interaction.Pointer.prototype,
- 'getKeys',
- ol.interaction.Pointer.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.Pointer.prototype,
- 'getProperties',
- ol.interaction.Pointer.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.Pointer.prototype,
- 'set',
- ol.interaction.Pointer.prototype.set);
- goog.exportProperty(
- ol.interaction.Pointer.prototype,
- 'setProperties',
- ol.interaction.Pointer.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.Pointer.prototype,
- 'unset',
- ol.interaction.Pointer.prototype.unset);
- goog.exportProperty(
- ol.interaction.Pointer.prototype,
- 'changed',
- ol.interaction.Pointer.prototype.changed);
- goog.exportProperty(
- ol.interaction.Pointer.prototype,
- 'dispatchEvent',
- ol.interaction.Pointer.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.Pointer.prototype,
- 'getRevision',
- ol.interaction.Pointer.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.Pointer.prototype,
- 'on',
- ol.interaction.Pointer.prototype.on);
- goog.exportProperty(
- ol.interaction.Pointer.prototype,
- 'once',
- ol.interaction.Pointer.prototype.once);
- goog.exportProperty(
- ol.interaction.Pointer.prototype,
- 'un',
- ol.interaction.Pointer.prototype.un);
- goog.exportProperty(
- ol.interaction.DragBox.prototype,
- 'getActive',
- ol.interaction.DragBox.prototype.getActive);
- goog.exportProperty(
- ol.interaction.DragBox.prototype,
- 'getMap',
- ol.interaction.DragBox.prototype.getMap);
- goog.exportProperty(
- ol.interaction.DragBox.prototype,
- 'setActive',
- ol.interaction.DragBox.prototype.setActive);
- goog.exportProperty(
- ol.interaction.DragBox.prototype,
- 'get',
- ol.interaction.DragBox.prototype.get);
- goog.exportProperty(
- ol.interaction.DragBox.prototype,
- 'getKeys',
- ol.interaction.DragBox.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.DragBox.prototype,
- 'getProperties',
- ol.interaction.DragBox.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.DragBox.prototype,
- 'set',
- ol.interaction.DragBox.prototype.set);
- goog.exportProperty(
- ol.interaction.DragBox.prototype,
- 'setProperties',
- ol.interaction.DragBox.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.DragBox.prototype,
- 'unset',
- ol.interaction.DragBox.prototype.unset);
- goog.exportProperty(
- ol.interaction.DragBox.prototype,
- 'changed',
- ol.interaction.DragBox.prototype.changed);
- goog.exportProperty(
- ol.interaction.DragBox.prototype,
- 'dispatchEvent',
- ol.interaction.DragBox.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.DragBox.prototype,
- 'getRevision',
- ol.interaction.DragBox.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.DragBox.prototype,
- 'on',
- ol.interaction.DragBox.prototype.on);
- goog.exportProperty(
- ol.interaction.DragBox.prototype,
- 'once',
- ol.interaction.DragBox.prototype.once);
- goog.exportProperty(
- ol.interaction.DragBox.prototype,
- 'un',
- ol.interaction.DragBox.prototype.un);
- goog.exportProperty(
- ol.interaction.DragBox.Event.prototype,
- 'type',
- ol.interaction.DragBox.Event.prototype.type);
- goog.exportProperty(
- ol.interaction.DragBox.Event.prototype,
- 'target',
- ol.interaction.DragBox.Event.prototype.target);
- goog.exportProperty(
- ol.interaction.DragBox.Event.prototype,
- 'preventDefault',
- ol.interaction.DragBox.Event.prototype.preventDefault);
- goog.exportProperty(
- ol.interaction.DragBox.Event.prototype,
- 'stopPropagation',
- ol.interaction.DragBox.Event.prototype.stopPropagation);
- goog.exportProperty(
- ol.interaction.DragPan.prototype,
- 'getActive',
- ol.interaction.DragPan.prototype.getActive);
- goog.exportProperty(
- ol.interaction.DragPan.prototype,
- 'getMap',
- ol.interaction.DragPan.prototype.getMap);
- goog.exportProperty(
- ol.interaction.DragPan.prototype,
- 'setActive',
- ol.interaction.DragPan.prototype.setActive);
- goog.exportProperty(
- ol.interaction.DragPan.prototype,
- 'get',
- ol.interaction.DragPan.prototype.get);
- goog.exportProperty(
- ol.interaction.DragPan.prototype,
- 'getKeys',
- ol.interaction.DragPan.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.DragPan.prototype,
- 'getProperties',
- ol.interaction.DragPan.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.DragPan.prototype,
- 'set',
- ol.interaction.DragPan.prototype.set);
- goog.exportProperty(
- ol.interaction.DragPan.prototype,
- 'setProperties',
- ol.interaction.DragPan.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.DragPan.prototype,
- 'unset',
- ol.interaction.DragPan.prototype.unset);
- goog.exportProperty(
- ol.interaction.DragPan.prototype,
- 'changed',
- ol.interaction.DragPan.prototype.changed);
- goog.exportProperty(
- ol.interaction.DragPan.prototype,
- 'dispatchEvent',
- ol.interaction.DragPan.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.DragPan.prototype,
- 'getRevision',
- ol.interaction.DragPan.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.DragPan.prototype,
- 'on',
- ol.interaction.DragPan.prototype.on);
- goog.exportProperty(
- ol.interaction.DragPan.prototype,
- 'once',
- ol.interaction.DragPan.prototype.once);
- goog.exportProperty(
- ol.interaction.DragPan.prototype,
- 'un',
- ol.interaction.DragPan.prototype.un);
- goog.exportProperty(
- ol.interaction.DragRotate.prototype,
- 'getActive',
- ol.interaction.DragRotate.prototype.getActive);
- goog.exportProperty(
- ol.interaction.DragRotate.prototype,
- 'getMap',
- ol.interaction.DragRotate.prototype.getMap);
- goog.exportProperty(
- ol.interaction.DragRotate.prototype,
- 'setActive',
- ol.interaction.DragRotate.prototype.setActive);
- goog.exportProperty(
- ol.interaction.DragRotate.prototype,
- 'get',
- ol.interaction.DragRotate.prototype.get);
- goog.exportProperty(
- ol.interaction.DragRotate.prototype,
- 'getKeys',
- ol.interaction.DragRotate.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.DragRotate.prototype,
- 'getProperties',
- ol.interaction.DragRotate.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.DragRotate.prototype,
- 'set',
- ol.interaction.DragRotate.prototype.set);
- goog.exportProperty(
- ol.interaction.DragRotate.prototype,
- 'setProperties',
- ol.interaction.DragRotate.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.DragRotate.prototype,
- 'unset',
- ol.interaction.DragRotate.prototype.unset);
- goog.exportProperty(
- ol.interaction.DragRotate.prototype,
- 'changed',
- ol.interaction.DragRotate.prototype.changed);
- goog.exportProperty(
- ol.interaction.DragRotate.prototype,
- 'dispatchEvent',
- ol.interaction.DragRotate.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.DragRotate.prototype,
- 'getRevision',
- ol.interaction.DragRotate.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.DragRotate.prototype,
- 'on',
- ol.interaction.DragRotate.prototype.on);
- goog.exportProperty(
- ol.interaction.DragRotate.prototype,
- 'once',
- ol.interaction.DragRotate.prototype.once);
- goog.exportProperty(
- ol.interaction.DragRotate.prototype,
- 'un',
- ol.interaction.DragRotate.prototype.un);
- goog.exportProperty(
- ol.interaction.DragRotateAndZoom.prototype,
- 'getActive',
- ol.interaction.DragRotateAndZoom.prototype.getActive);
- goog.exportProperty(
- ol.interaction.DragRotateAndZoom.prototype,
- 'getMap',
- ol.interaction.DragRotateAndZoom.prototype.getMap);
- goog.exportProperty(
- ol.interaction.DragRotateAndZoom.prototype,
- 'setActive',
- ol.interaction.DragRotateAndZoom.prototype.setActive);
- goog.exportProperty(
- ol.interaction.DragRotateAndZoom.prototype,
- 'get',
- ol.interaction.DragRotateAndZoom.prototype.get);
- goog.exportProperty(
- ol.interaction.DragRotateAndZoom.prototype,
- 'getKeys',
- ol.interaction.DragRotateAndZoom.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.DragRotateAndZoom.prototype,
- 'getProperties',
- ol.interaction.DragRotateAndZoom.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.DragRotateAndZoom.prototype,
- 'set',
- ol.interaction.DragRotateAndZoom.prototype.set);
- goog.exportProperty(
- ol.interaction.DragRotateAndZoom.prototype,
- 'setProperties',
- ol.interaction.DragRotateAndZoom.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.DragRotateAndZoom.prototype,
- 'unset',
- ol.interaction.DragRotateAndZoom.prototype.unset);
- goog.exportProperty(
- ol.interaction.DragRotateAndZoom.prototype,
- 'changed',
- ol.interaction.DragRotateAndZoom.prototype.changed);
- goog.exportProperty(
- ol.interaction.DragRotateAndZoom.prototype,
- 'dispatchEvent',
- ol.interaction.DragRotateAndZoom.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.DragRotateAndZoom.prototype,
- 'getRevision',
- ol.interaction.DragRotateAndZoom.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.DragRotateAndZoom.prototype,
- 'on',
- ol.interaction.DragRotateAndZoom.prototype.on);
- goog.exportProperty(
- ol.interaction.DragRotateAndZoom.prototype,
- 'once',
- ol.interaction.DragRotateAndZoom.prototype.once);
- goog.exportProperty(
- ol.interaction.DragRotateAndZoom.prototype,
- 'un',
- ol.interaction.DragRotateAndZoom.prototype.un);
- goog.exportProperty(
- ol.interaction.DragZoom.prototype,
- 'getGeometry',
- ol.interaction.DragZoom.prototype.getGeometry);
- goog.exportProperty(
- ol.interaction.DragZoom.prototype,
- 'getActive',
- ol.interaction.DragZoom.prototype.getActive);
- goog.exportProperty(
- ol.interaction.DragZoom.prototype,
- 'getMap',
- ol.interaction.DragZoom.prototype.getMap);
- goog.exportProperty(
- ol.interaction.DragZoom.prototype,
- 'setActive',
- ol.interaction.DragZoom.prototype.setActive);
- goog.exportProperty(
- ol.interaction.DragZoom.prototype,
- 'get',
- ol.interaction.DragZoom.prototype.get);
- goog.exportProperty(
- ol.interaction.DragZoom.prototype,
- 'getKeys',
- ol.interaction.DragZoom.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.DragZoom.prototype,
- 'getProperties',
- ol.interaction.DragZoom.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.DragZoom.prototype,
- 'set',
- ol.interaction.DragZoom.prototype.set);
- goog.exportProperty(
- ol.interaction.DragZoom.prototype,
- 'setProperties',
- ol.interaction.DragZoom.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.DragZoom.prototype,
- 'unset',
- ol.interaction.DragZoom.prototype.unset);
- goog.exportProperty(
- ol.interaction.DragZoom.prototype,
- 'changed',
- ol.interaction.DragZoom.prototype.changed);
- goog.exportProperty(
- ol.interaction.DragZoom.prototype,
- 'dispatchEvent',
- ol.interaction.DragZoom.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.DragZoom.prototype,
- 'getRevision',
- ol.interaction.DragZoom.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.DragZoom.prototype,
- 'on',
- ol.interaction.DragZoom.prototype.on);
- goog.exportProperty(
- ol.interaction.DragZoom.prototype,
- 'once',
- ol.interaction.DragZoom.prototype.once);
- goog.exportProperty(
- ol.interaction.DragZoom.prototype,
- 'un',
- ol.interaction.DragZoom.prototype.un);
- goog.exportProperty(
- ol.interaction.Draw.prototype,
- 'getActive',
- ol.interaction.Draw.prototype.getActive);
- goog.exportProperty(
- ol.interaction.Draw.prototype,
- 'getMap',
- ol.interaction.Draw.prototype.getMap);
- goog.exportProperty(
- ol.interaction.Draw.prototype,
- 'setActive',
- ol.interaction.Draw.prototype.setActive);
- goog.exportProperty(
- ol.interaction.Draw.prototype,
- 'get',
- ol.interaction.Draw.prototype.get);
- goog.exportProperty(
- ol.interaction.Draw.prototype,
- 'getKeys',
- ol.interaction.Draw.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.Draw.prototype,
- 'getProperties',
- ol.interaction.Draw.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.Draw.prototype,
- 'set',
- ol.interaction.Draw.prototype.set);
- goog.exportProperty(
- ol.interaction.Draw.prototype,
- 'setProperties',
- ol.interaction.Draw.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.Draw.prototype,
- 'unset',
- ol.interaction.Draw.prototype.unset);
- goog.exportProperty(
- ol.interaction.Draw.prototype,
- 'changed',
- ol.interaction.Draw.prototype.changed);
- goog.exportProperty(
- ol.interaction.Draw.prototype,
- 'dispatchEvent',
- ol.interaction.Draw.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.Draw.prototype,
- 'getRevision',
- ol.interaction.Draw.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.Draw.prototype,
- 'on',
- ol.interaction.Draw.prototype.on);
- goog.exportProperty(
- ol.interaction.Draw.prototype,
- 'once',
- ol.interaction.Draw.prototype.once);
- goog.exportProperty(
- ol.interaction.Draw.prototype,
- 'un',
- ol.interaction.Draw.prototype.un);
- goog.exportProperty(
- ol.interaction.Draw.Event.prototype,
- 'type',
- ol.interaction.Draw.Event.prototype.type);
- goog.exportProperty(
- ol.interaction.Draw.Event.prototype,
- 'target',
- ol.interaction.Draw.Event.prototype.target);
- goog.exportProperty(
- ol.interaction.Draw.Event.prototype,
- 'preventDefault',
- ol.interaction.Draw.Event.prototype.preventDefault);
- goog.exportProperty(
- ol.interaction.Draw.Event.prototype,
- 'stopPropagation',
- ol.interaction.Draw.Event.prototype.stopPropagation);
- goog.exportProperty(
- ol.interaction.Extent.prototype,
- 'getActive',
- ol.interaction.Extent.prototype.getActive);
- goog.exportProperty(
- ol.interaction.Extent.prototype,
- 'getMap',
- ol.interaction.Extent.prototype.getMap);
- goog.exportProperty(
- ol.interaction.Extent.prototype,
- 'setActive',
- ol.interaction.Extent.prototype.setActive);
- goog.exportProperty(
- ol.interaction.Extent.prototype,
- 'get',
- ol.interaction.Extent.prototype.get);
- goog.exportProperty(
- ol.interaction.Extent.prototype,
- 'getKeys',
- ol.interaction.Extent.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.Extent.prototype,
- 'getProperties',
- ol.interaction.Extent.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.Extent.prototype,
- 'set',
- ol.interaction.Extent.prototype.set);
- goog.exportProperty(
- ol.interaction.Extent.prototype,
- 'setProperties',
- ol.interaction.Extent.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.Extent.prototype,
- 'unset',
- ol.interaction.Extent.prototype.unset);
- goog.exportProperty(
- ol.interaction.Extent.prototype,
- 'changed',
- ol.interaction.Extent.prototype.changed);
- goog.exportProperty(
- ol.interaction.Extent.prototype,
- 'dispatchEvent',
- ol.interaction.Extent.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.Extent.prototype,
- 'getRevision',
- ol.interaction.Extent.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.Extent.prototype,
- 'on',
- ol.interaction.Extent.prototype.on);
- goog.exportProperty(
- ol.interaction.Extent.prototype,
- 'once',
- ol.interaction.Extent.prototype.once);
- goog.exportProperty(
- ol.interaction.Extent.prototype,
- 'un',
- ol.interaction.Extent.prototype.un);
- goog.exportProperty(
- ol.interaction.Extent.Event.prototype,
- 'type',
- ol.interaction.Extent.Event.prototype.type);
- goog.exportProperty(
- ol.interaction.Extent.Event.prototype,
- 'target',
- ol.interaction.Extent.Event.prototype.target);
- goog.exportProperty(
- ol.interaction.Extent.Event.prototype,
- 'preventDefault',
- ol.interaction.Extent.Event.prototype.preventDefault);
- goog.exportProperty(
- ol.interaction.Extent.Event.prototype,
- 'stopPropagation',
- ol.interaction.Extent.Event.prototype.stopPropagation);
- goog.exportProperty(
- ol.interaction.KeyboardPan.prototype,
- 'getActive',
- ol.interaction.KeyboardPan.prototype.getActive);
- goog.exportProperty(
- ol.interaction.KeyboardPan.prototype,
- 'getMap',
- ol.interaction.KeyboardPan.prototype.getMap);
- goog.exportProperty(
- ol.interaction.KeyboardPan.prototype,
- 'setActive',
- ol.interaction.KeyboardPan.prototype.setActive);
- goog.exportProperty(
- ol.interaction.KeyboardPan.prototype,
- 'get',
- ol.interaction.KeyboardPan.prototype.get);
- goog.exportProperty(
- ol.interaction.KeyboardPan.prototype,
- 'getKeys',
- ol.interaction.KeyboardPan.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.KeyboardPan.prototype,
- 'getProperties',
- ol.interaction.KeyboardPan.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.KeyboardPan.prototype,
- 'set',
- ol.interaction.KeyboardPan.prototype.set);
- goog.exportProperty(
- ol.interaction.KeyboardPan.prototype,
- 'setProperties',
- ol.interaction.KeyboardPan.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.KeyboardPan.prototype,
- 'unset',
- ol.interaction.KeyboardPan.prototype.unset);
- goog.exportProperty(
- ol.interaction.KeyboardPan.prototype,
- 'changed',
- ol.interaction.KeyboardPan.prototype.changed);
- goog.exportProperty(
- ol.interaction.KeyboardPan.prototype,
- 'dispatchEvent',
- ol.interaction.KeyboardPan.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.KeyboardPan.prototype,
- 'getRevision',
- ol.interaction.KeyboardPan.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.KeyboardPan.prototype,
- 'on',
- ol.interaction.KeyboardPan.prototype.on);
- goog.exportProperty(
- ol.interaction.KeyboardPan.prototype,
- 'once',
- ol.interaction.KeyboardPan.prototype.once);
- goog.exportProperty(
- ol.interaction.KeyboardPan.prototype,
- 'un',
- ol.interaction.KeyboardPan.prototype.un);
- goog.exportProperty(
- ol.interaction.KeyboardZoom.prototype,
- 'getActive',
- ol.interaction.KeyboardZoom.prototype.getActive);
- goog.exportProperty(
- ol.interaction.KeyboardZoom.prototype,
- 'getMap',
- ol.interaction.KeyboardZoom.prototype.getMap);
- goog.exportProperty(
- ol.interaction.KeyboardZoom.prototype,
- 'setActive',
- ol.interaction.KeyboardZoom.prototype.setActive);
- goog.exportProperty(
- ol.interaction.KeyboardZoom.prototype,
- 'get',
- ol.interaction.KeyboardZoom.prototype.get);
- goog.exportProperty(
- ol.interaction.KeyboardZoom.prototype,
- 'getKeys',
- ol.interaction.KeyboardZoom.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.KeyboardZoom.prototype,
- 'getProperties',
- ol.interaction.KeyboardZoom.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.KeyboardZoom.prototype,
- 'set',
- ol.interaction.KeyboardZoom.prototype.set);
- goog.exportProperty(
- ol.interaction.KeyboardZoom.prototype,
- 'setProperties',
- ol.interaction.KeyboardZoom.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.KeyboardZoom.prototype,
- 'unset',
- ol.interaction.KeyboardZoom.prototype.unset);
- goog.exportProperty(
- ol.interaction.KeyboardZoom.prototype,
- 'changed',
- ol.interaction.KeyboardZoom.prototype.changed);
- goog.exportProperty(
- ol.interaction.KeyboardZoom.prototype,
- 'dispatchEvent',
- ol.interaction.KeyboardZoom.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.KeyboardZoom.prototype,
- 'getRevision',
- ol.interaction.KeyboardZoom.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.KeyboardZoom.prototype,
- 'on',
- ol.interaction.KeyboardZoom.prototype.on);
- goog.exportProperty(
- ol.interaction.KeyboardZoom.prototype,
- 'once',
- ol.interaction.KeyboardZoom.prototype.once);
- goog.exportProperty(
- ol.interaction.KeyboardZoom.prototype,
- 'un',
- ol.interaction.KeyboardZoom.prototype.un);
- goog.exportProperty(
- ol.interaction.Modify.prototype,
- 'getActive',
- ol.interaction.Modify.prototype.getActive);
- goog.exportProperty(
- ol.interaction.Modify.prototype,
- 'getMap',
- ol.interaction.Modify.prototype.getMap);
- goog.exportProperty(
- ol.interaction.Modify.prototype,
- 'setActive',
- ol.interaction.Modify.prototype.setActive);
- goog.exportProperty(
- ol.interaction.Modify.prototype,
- 'get',
- ol.interaction.Modify.prototype.get);
- goog.exportProperty(
- ol.interaction.Modify.prototype,
- 'getKeys',
- ol.interaction.Modify.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.Modify.prototype,
- 'getProperties',
- ol.interaction.Modify.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.Modify.prototype,
- 'set',
- ol.interaction.Modify.prototype.set);
- goog.exportProperty(
- ol.interaction.Modify.prototype,
- 'setProperties',
- ol.interaction.Modify.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.Modify.prototype,
- 'unset',
- ol.interaction.Modify.prototype.unset);
- goog.exportProperty(
- ol.interaction.Modify.prototype,
- 'changed',
- ol.interaction.Modify.prototype.changed);
- goog.exportProperty(
- ol.interaction.Modify.prototype,
- 'dispatchEvent',
- ol.interaction.Modify.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.Modify.prototype,
- 'getRevision',
- ol.interaction.Modify.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.Modify.prototype,
- 'on',
- ol.interaction.Modify.prototype.on);
- goog.exportProperty(
- ol.interaction.Modify.prototype,
- 'once',
- ol.interaction.Modify.prototype.once);
- goog.exportProperty(
- ol.interaction.Modify.prototype,
- 'un',
- ol.interaction.Modify.prototype.un);
- goog.exportProperty(
- ol.interaction.Modify.Event.prototype,
- 'type',
- ol.interaction.Modify.Event.prototype.type);
- goog.exportProperty(
- ol.interaction.Modify.Event.prototype,
- 'target',
- ol.interaction.Modify.Event.prototype.target);
- goog.exportProperty(
- ol.interaction.Modify.Event.prototype,
- 'preventDefault',
- ol.interaction.Modify.Event.prototype.preventDefault);
- goog.exportProperty(
- ol.interaction.Modify.Event.prototype,
- 'stopPropagation',
- ol.interaction.Modify.Event.prototype.stopPropagation);
- goog.exportProperty(
- ol.interaction.MouseWheelZoom.prototype,
- 'getActive',
- ol.interaction.MouseWheelZoom.prototype.getActive);
- goog.exportProperty(
- ol.interaction.MouseWheelZoom.prototype,
- 'getMap',
- ol.interaction.MouseWheelZoom.prototype.getMap);
- goog.exportProperty(
- ol.interaction.MouseWheelZoom.prototype,
- 'setActive',
- ol.interaction.MouseWheelZoom.prototype.setActive);
- goog.exportProperty(
- ol.interaction.MouseWheelZoom.prototype,
- 'get',
- ol.interaction.MouseWheelZoom.prototype.get);
- goog.exportProperty(
- ol.interaction.MouseWheelZoom.prototype,
- 'getKeys',
- ol.interaction.MouseWheelZoom.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.MouseWheelZoom.prototype,
- 'getProperties',
- ol.interaction.MouseWheelZoom.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.MouseWheelZoom.prototype,
- 'set',
- ol.interaction.MouseWheelZoom.prototype.set);
- goog.exportProperty(
- ol.interaction.MouseWheelZoom.prototype,
- 'setProperties',
- ol.interaction.MouseWheelZoom.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.MouseWheelZoom.prototype,
- 'unset',
- ol.interaction.MouseWheelZoom.prototype.unset);
- goog.exportProperty(
- ol.interaction.MouseWheelZoom.prototype,
- 'changed',
- ol.interaction.MouseWheelZoom.prototype.changed);
- goog.exportProperty(
- ol.interaction.MouseWheelZoom.prototype,
- 'dispatchEvent',
- ol.interaction.MouseWheelZoom.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.MouseWheelZoom.prototype,
- 'getRevision',
- ol.interaction.MouseWheelZoom.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.MouseWheelZoom.prototype,
- 'on',
- ol.interaction.MouseWheelZoom.prototype.on);
- goog.exportProperty(
- ol.interaction.MouseWheelZoom.prototype,
- 'once',
- ol.interaction.MouseWheelZoom.prototype.once);
- goog.exportProperty(
- ol.interaction.MouseWheelZoom.prototype,
- 'un',
- ol.interaction.MouseWheelZoom.prototype.un);
- goog.exportProperty(
- ol.interaction.PinchRotate.prototype,
- 'getActive',
- ol.interaction.PinchRotate.prototype.getActive);
- goog.exportProperty(
- ol.interaction.PinchRotate.prototype,
- 'getMap',
- ol.interaction.PinchRotate.prototype.getMap);
- goog.exportProperty(
- ol.interaction.PinchRotate.prototype,
- 'setActive',
- ol.interaction.PinchRotate.prototype.setActive);
- goog.exportProperty(
- ol.interaction.PinchRotate.prototype,
- 'get',
- ol.interaction.PinchRotate.prototype.get);
- goog.exportProperty(
- ol.interaction.PinchRotate.prototype,
- 'getKeys',
- ol.interaction.PinchRotate.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.PinchRotate.prototype,
- 'getProperties',
- ol.interaction.PinchRotate.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.PinchRotate.prototype,
- 'set',
- ol.interaction.PinchRotate.prototype.set);
- goog.exportProperty(
- ol.interaction.PinchRotate.prototype,
- 'setProperties',
- ol.interaction.PinchRotate.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.PinchRotate.prototype,
- 'unset',
- ol.interaction.PinchRotate.prototype.unset);
- goog.exportProperty(
- ol.interaction.PinchRotate.prototype,
- 'changed',
- ol.interaction.PinchRotate.prototype.changed);
- goog.exportProperty(
- ol.interaction.PinchRotate.prototype,
- 'dispatchEvent',
- ol.interaction.PinchRotate.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.PinchRotate.prototype,
- 'getRevision',
- ol.interaction.PinchRotate.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.PinchRotate.prototype,
- 'on',
- ol.interaction.PinchRotate.prototype.on);
- goog.exportProperty(
- ol.interaction.PinchRotate.prototype,
- 'once',
- ol.interaction.PinchRotate.prototype.once);
- goog.exportProperty(
- ol.interaction.PinchRotate.prototype,
- 'un',
- ol.interaction.PinchRotate.prototype.un);
- goog.exportProperty(
- ol.interaction.PinchZoom.prototype,
- 'getActive',
- ol.interaction.PinchZoom.prototype.getActive);
- goog.exportProperty(
- ol.interaction.PinchZoom.prototype,
- 'getMap',
- ol.interaction.PinchZoom.prototype.getMap);
- goog.exportProperty(
- ol.interaction.PinchZoom.prototype,
- 'setActive',
- ol.interaction.PinchZoom.prototype.setActive);
- goog.exportProperty(
- ol.interaction.PinchZoom.prototype,
- 'get',
- ol.interaction.PinchZoom.prototype.get);
- goog.exportProperty(
- ol.interaction.PinchZoom.prototype,
- 'getKeys',
- ol.interaction.PinchZoom.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.PinchZoom.prototype,
- 'getProperties',
- ol.interaction.PinchZoom.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.PinchZoom.prototype,
- 'set',
- ol.interaction.PinchZoom.prototype.set);
- goog.exportProperty(
- ol.interaction.PinchZoom.prototype,
- 'setProperties',
- ol.interaction.PinchZoom.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.PinchZoom.prototype,
- 'unset',
- ol.interaction.PinchZoom.prototype.unset);
- goog.exportProperty(
- ol.interaction.PinchZoom.prototype,
- 'changed',
- ol.interaction.PinchZoom.prototype.changed);
- goog.exportProperty(
- ol.interaction.PinchZoom.prototype,
- 'dispatchEvent',
- ol.interaction.PinchZoom.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.PinchZoom.prototype,
- 'getRevision',
- ol.interaction.PinchZoom.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.PinchZoom.prototype,
- 'on',
- ol.interaction.PinchZoom.prototype.on);
- goog.exportProperty(
- ol.interaction.PinchZoom.prototype,
- 'once',
- ol.interaction.PinchZoom.prototype.once);
- goog.exportProperty(
- ol.interaction.PinchZoom.prototype,
- 'un',
- ol.interaction.PinchZoom.prototype.un);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'getActive',
- ol.interaction.Select.prototype.getActive);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'getMap',
- ol.interaction.Select.prototype.getMap);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'setActive',
- ol.interaction.Select.prototype.setActive);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'get',
- ol.interaction.Select.prototype.get);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'getKeys',
- ol.interaction.Select.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'getProperties',
- ol.interaction.Select.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'set',
- ol.interaction.Select.prototype.set);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'setProperties',
- ol.interaction.Select.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'unset',
- ol.interaction.Select.prototype.unset);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'changed',
- ol.interaction.Select.prototype.changed);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'dispatchEvent',
- ol.interaction.Select.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'getRevision',
- ol.interaction.Select.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'on',
- ol.interaction.Select.prototype.on);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'once',
- ol.interaction.Select.prototype.once);
- goog.exportProperty(
- ol.interaction.Select.prototype,
- 'un',
- ol.interaction.Select.prototype.un);
- goog.exportProperty(
- ol.interaction.Select.Event.prototype,
- 'type',
- ol.interaction.Select.Event.prototype.type);
- goog.exportProperty(
- ol.interaction.Select.Event.prototype,
- 'target',
- ol.interaction.Select.Event.prototype.target);
- goog.exportProperty(
- ol.interaction.Select.Event.prototype,
- 'preventDefault',
- ol.interaction.Select.Event.prototype.preventDefault);
- goog.exportProperty(
- ol.interaction.Select.Event.prototype,
- 'stopPropagation',
- ol.interaction.Select.Event.prototype.stopPropagation);
- goog.exportProperty(
- ol.interaction.Snap.prototype,
- 'getActive',
- ol.interaction.Snap.prototype.getActive);
- goog.exportProperty(
- ol.interaction.Snap.prototype,
- 'getMap',
- ol.interaction.Snap.prototype.getMap);
- goog.exportProperty(
- ol.interaction.Snap.prototype,
- 'setActive',
- ol.interaction.Snap.prototype.setActive);
- goog.exportProperty(
- ol.interaction.Snap.prototype,
- 'get',
- ol.interaction.Snap.prototype.get);
- goog.exportProperty(
- ol.interaction.Snap.prototype,
- 'getKeys',
- ol.interaction.Snap.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.Snap.prototype,
- 'getProperties',
- ol.interaction.Snap.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.Snap.prototype,
- 'set',
- ol.interaction.Snap.prototype.set);
- goog.exportProperty(
- ol.interaction.Snap.prototype,
- 'setProperties',
- ol.interaction.Snap.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.Snap.prototype,
- 'unset',
- ol.interaction.Snap.prototype.unset);
- goog.exportProperty(
- ol.interaction.Snap.prototype,
- 'changed',
- ol.interaction.Snap.prototype.changed);
- goog.exportProperty(
- ol.interaction.Snap.prototype,
- 'dispatchEvent',
- ol.interaction.Snap.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.Snap.prototype,
- 'getRevision',
- ol.interaction.Snap.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.Snap.prototype,
- 'on',
- ol.interaction.Snap.prototype.on);
- goog.exportProperty(
- ol.interaction.Snap.prototype,
- 'once',
- ol.interaction.Snap.prototype.once);
- goog.exportProperty(
- ol.interaction.Snap.prototype,
- 'un',
- ol.interaction.Snap.prototype.un);
- goog.exportProperty(
- ol.interaction.Translate.prototype,
- 'getActive',
- ol.interaction.Translate.prototype.getActive);
- goog.exportProperty(
- ol.interaction.Translate.prototype,
- 'getMap',
- ol.interaction.Translate.prototype.getMap);
- goog.exportProperty(
- ol.interaction.Translate.prototype,
- 'setActive',
- ol.interaction.Translate.prototype.setActive);
- goog.exportProperty(
- ol.interaction.Translate.prototype,
- 'get',
- ol.interaction.Translate.prototype.get);
- goog.exportProperty(
- ol.interaction.Translate.prototype,
- 'getKeys',
- ol.interaction.Translate.prototype.getKeys);
- goog.exportProperty(
- ol.interaction.Translate.prototype,
- 'getProperties',
- ol.interaction.Translate.prototype.getProperties);
- goog.exportProperty(
- ol.interaction.Translate.prototype,
- 'set',
- ol.interaction.Translate.prototype.set);
- goog.exportProperty(
- ol.interaction.Translate.prototype,
- 'setProperties',
- ol.interaction.Translate.prototype.setProperties);
- goog.exportProperty(
- ol.interaction.Translate.prototype,
- 'unset',
- ol.interaction.Translate.prototype.unset);
- goog.exportProperty(
- ol.interaction.Translate.prototype,
- 'changed',
- ol.interaction.Translate.prototype.changed);
- goog.exportProperty(
- ol.interaction.Translate.prototype,
- 'dispatchEvent',
- ol.interaction.Translate.prototype.dispatchEvent);
- goog.exportProperty(
- ol.interaction.Translate.prototype,
- 'getRevision',
- ol.interaction.Translate.prototype.getRevision);
- goog.exportProperty(
- ol.interaction.Translate.prototype,
- 'on',
- ol.interaction.Translate.prototype.on);
- goog.exportProperty(
- ol.interaction.Translate.prototype,
- 'once',
- ol.interaction.Translate.prototype.once);
- goog.exportProperty(
- ol.interaction.Translate.prototype,
- 'un',
- ol.interaction.Translate.prototype.un);
- goog.exportProperty(
- ol.interaction.Translate.Event.prototype,
- 'type',
- ol.interaction.Translate.Event.prototype.type);
- goog.exportProperty(
- ol.interaction.Translate.Event.prototype,
- 'target',
- ol.interaction.Translate.Event.prototype.target);
- goog.exportProperty(
- ol.interaction.Translate.Event.prototype,
- 'preventDefault',
- ol.interaction.Translate.Event.prototype.preventDefault);
- goog.exportProperty(
- ol.interaction.Translate.Event.prototype,
- 'stopPropagation',
- ol.interaction.Translate.Event.prototype.stopPropagation);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'get',
- ol.geom.Geometry.prototype.get);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'getKeys',
- ol.geom.Geometry.prototype.getKeys);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'getProperties',
- ol.geom.Geometry.prototype.getProperties);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'set',
- ol.geom.Geometry.prototype.set);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'setProperties',
- ol.geom.Geometry.prototype.setProperties);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'unset',
- ol.geom.Geometry.prototype.unset);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'changed',
- ol.geom.Geometry.prototype.changed);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'dispatchEvent',
- ol.geom.Geometry.prototype.dispatchEvent);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'getRevision',
- ol.geom.Geometry.prototype.getRevision);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'on',
- ol.geom.Geometry.prototype.on);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'once',
- ol.geom.Geometry.prototype.once);
- goog.exportProperty(
- ol.geom.Geometry.prototype,
- 'un',
- ol.geom.Geometry.prototype.un);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'getClosestPoint',
- ol.geom.SimpleGeometry.prototype.getClosestPoint);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'intersectsCoordinate',
- ol.geom.SimpleGeometry.prototype.intersectsCoordinate);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'getExtent',
- ol.geom.SimpleGeometry.prototype.getExtent);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'rotate',
- ol.geom.SimpleGeometry.prototype.rotate);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'scale',
- ol.geom.SimpleGeometry.prototype.scale);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'simplify',
- ol.geom.SimpleGeometry.prototype.simplify);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'transform',
- ol.geom.SimpleGeometry.prototype.transform);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'get',
- ol.geom.SimpleGeometry.prototype.get);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'getKeys',
- ol.geom.SimpleGeometry.prototype.getKeys);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'getProperties',
- ol.geom.SimpleGeometry.prototype.getProperties);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'set',
- ol.geom.SimpleGeometry.prototype.set);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'setProperties',
- ol.geom.SimpleGeometry.prototype.setProperties);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'unset',
- ol.geom.SimpleGeometry.prototype.unset);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'changed',
- ol.geom.SimpleGeometry.prototype.changed);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'dispatchEvent',
- ol.geom.SimpleGeometry.prototype.dispatchEvent);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'getRevision',
- ol.geom.SimpleGeometry.prototype.getRevision);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'on',
- ol.geom.SimpleGeometry.prototype.on);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'once',
- ol.geom.SimpleGeometry.prototype.once);
- goog.exportProperty(
- ol.geom.SimpleGeometry.prototype,
- 'un',
- ol.geom.SimpleGeometry.prototype.un);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'getFirstCoordinate',
- ol.geom.Circle.prototype.getFirstCoordinate);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'getLastCoordinate',
- ol.geom.Circle.prototype.getLastCoordinate);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'getLayout',
- ol.geom.Circle.prototype.getLayout);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'rotate',
- ol.geom.Circle.prototype.rotate);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'scale',
- ol.geom.Circle.prototype.scale);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'getClosestPoint',
- ol.geom.Circle.prototype.getClosestPoint);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'intersectsCoordinate',
- ol.geom.Circle.prototype.intersectsCoordinate);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'getExtent',
- ol.geom.Circle.prototype.getExtent);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'simplify',
- ol.geom.Circle.prototype.simplify);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'get',
- ol.geom.Circle.prototype.get);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'getKeys',
- ol.geom.Circle.prototype.getKeys);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'getProperties',
- ol.geom.Circle.prototype.getProperties);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'set',
- ol.geom.Circle.prototype.set);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'setProperties',
- ol.geom.Circle.prototype.setProperties);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'unset',
- ol.geom.Circle.prototype.unset);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'changed',
- ol.geom.Circle.prototype.changed);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'dispatchEvent',
- ol.geom.Circle.prototype.dispatchEvent);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'getRevision',
- ol.geom.Circle.prototype.getRevision);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'on',
- ol.geom.Circle.prototype.on);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'once',
- ol.geom.Circle.prototype.once);
- goog.exportProperty(
- ol.geom.Circle.prototype,
- 'un',
- ol.geom.Circle.prototype.un);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'getClosestPoint',
- ol.geom.GeometryCollection.prototype.getClosestPoint);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'intersectsCoordinate',
- ol.geom.GeometryCollection.prototype.intersectsCoordinate);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'getExtent',
- ol.geom.GeometryCollection.prototype.getExtent);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'rotate',
- ol.geom.GeometryCollection.prototype.rotate);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'scale',
- ol.geom.GeometryCollection.prototype.scale);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'simplify',
- ol.geom.GeometryCollection.prototype.simplify);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'transform',
- ol.geom.GeometryCollection.prototype.transform);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'get',
- ol.geom.GeometryCollection.prototype.get);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'getKeys',
- ol.geom.GeometryCollection.prototype.getKeys);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'getProperties',
- ol.geom.GeometryCollection.prototype.getProperties);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'set',
- ol.geom.GeometryCollection.prototype.set);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'setProperties',
- ol.geom.GeometryCollection.prototype.setProperties);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'unset',
- ol.geom.GeometryCollection.prototype.unset);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'changed',
- ol.geom.GeometryCollection.prototype.changed);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'dispatchEvent',
- ol.geom.GeometryCollection.prototype.dispatchEvent);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'getRevision',
- ol.geom.GeometryCollection.prototype.getRevision);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'on',
- ol.geom.GeometryCollection.prototype.on);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'once',
- ol.geom.GeometryCollection.prototype.once);
- goog.exportProperty(
- ol.geom.GeometryCollection.prototype,
- 'un',
- ol.geom.GeometryCollection.prototype.un);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'getFirstCoordinate',
- ol.geom.LinearRing.prototype.getFirstCoordinate);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'getLastCoordinate',
- ol.geom.LinearRing.prototype.getLastCoordinate);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'getLayout',
- ol.geom.LinearRing.prototype.getLayout);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'rotate',
- ol.geom.LinearRing.prototype.rotate);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'scale',
- ol.geom.LinearRing.prototype.scale);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'getClosestPoint',
- ol.geom.LinearRing.prototype.getClosestPoint);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'intersectsCoordinate',
- ol.geom.LinearRing.prototype.intersectsCoordinate);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'getExtent',
- ol.geom.LinearRing.prototype.getExtent);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'simplify',
- ol.geom.LinearRing.prototype.simplify);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'transform',
- ol.geom.LinearRing.prototype.transform);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'get',
- ol.geom.LinearRing.prototype.get);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'getKeys',
- ol.geom.LinearRing.prototype.getKeys);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'getProperties',
- ol.geom.LinearRing.prototype.getProperties);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'set',
- ol.geom.LinearRing.prototype.set);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'setProperties',
- ol.geom.LinearRing.prototype.setProperties);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'unset',
- ol.geom.LinearRing.prototype.unset);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'changed',
- ol.geom.LinearRing.prototype.changed);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'dispatchEvent',
- ol.geom.LinearRing.prototype.dispatchEvent);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'getRevision',
- ol.geom.LinearRing.prototype.getRevision);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'on',
- ol.geom.LinearRing.prototype.on);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'once',
- ol.geom.LinearRing.prototype.once);
- goog.exportProperty(
- ol.geom.LinearRing.prototype,
- 'un',
- ol.geom.LinearRing.prototype.un);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'getFirstCoordinate',
- ol.geom.LineString.prototype.getFirstCoordinate);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'getLastCoordinate',
- ol.geom.LineString.prototype.getLastCoordinate);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'getLayout',
- ol.geom.LineString.prototype.getLayout);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'rotate',
- ol.geom.LineString.prototype.rotate);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'scale',
- ol.geom.LineString.prototype.scale);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'getClosestPoint',
- ol.geom.LineString.prototype.getClosestPoint);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'intersectsCoordinate',
- ol.geom.LineString.prototype.intersectsCoordinate);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'getExtent',
- ol.geom.LineString.prototype.getExtent);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'simplify',
- ol.geom.LineString.prototype.simplify);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'transform',
- ol.geom.LineString.prototype.transform);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'get',
- ol.geom.LineString.prototype.get);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'getKeys',
- ol.geom.LineString.prototype.getKeys);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'getProperties',
- ol.geom.LineString.prototype.getProperties);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'set',
- ol.geom.LineString.prototype.set);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'setProperties',
- ol.geom.LineString.prototype.setProperties);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'unset',
- ol.geom.LineString.prototype.unset);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'changed',
- ol.geom.LineString.prototype.changed);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'dispatchEvent',
- ol.geom.LineString.prototype.dispatchEvent);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'getRevision',
- ol.geom.LineString.prototype.getRevision);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'on',
- ol.geom.LineString.prototype.on);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'once',
- ol.geom.LineString.prototype.once);
- goog.exportProperty(
- ol.geom.LineString.prototype,
- 'un',
- ol.geom.LineString.prototype.un);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'getFirstCoordinate',
- ol.geom.MultiLineString.prototype.getFirstCoordinate);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'getLastCoordinate',
- ol.geom.MultiLineString.prototype.getLastCoordinate);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'getLayout',
- ol.geom.MultiLineString.prototype.getLayout);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'rotate',
- ol.geom.MultiLineString.prototype.rotate);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'scale',
- ol.geom.MultiLineString.prototype.scale);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'getClosestPoint',
- ol.geom.MultiLineString.prototype.getClosestPoint);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'intersectsCoordinate',
- ol.geom.MultiLineString.prototype.intersectsCoordinate);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'getExtent',
- ol.geom.MultiLineString.prototype.getExtent);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'simplify',
- ol.geom.MultiLineString.prototype.simplify);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'transform',
- ol.geom.MultiLineString.prototype.transform);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'get',
- ol.geom.MultiLineString.prototype.get);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'getKeys',
- ol.geom.MultiLineString.prototype.getKeys);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'getProperties',
- ol.geom.MultiLineString.prototype.getProperties);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'set',
- ol.geom.MultiLineString.prototype.set);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'setProperties',
- ol.geom.MultiLineString.prototype.setProperties);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'unset',
- ol.geom.MultiLineString.prototype.unset);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'changed',
- ol.geom.MultiLineString.prototype.changed);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'dispatchEvent',
- ol.geom.MultiLineString.prototype.dispatchEvent);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'getRevision',
- ol.geom.MultiLineString.prototype.getRevision);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'on',
- ol.geom.MultiLineString.prototype.on);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'once',
- ol.geom.MultiLineString.prototype.once);
- goog.exportProperty(
- ol.geom.MultiLineString.prototype,
- 'un',
- ol.geom.MultiLineString.prototype.un);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'getFirstCoordinate',
- ol.geom.MultiPoint.prototype.getFirstCoordinate);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'getLastCoordinate',
- ol.geom.MultiPoint.prototype.getLastCoordinate);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'getLayout',
- ol.geom.MultiPoint.prototype.getLayout);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'rotate',
- ol.geom.MultiPoint.prototype.rotate);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'scale',
- ol.geom.MultiPoint.prototype.scale);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'getClosestPoint',
- ol.geom.MultiPoint.prototype.getClosestPoint);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'intersectsCoordinate',
- ol.geom.MultiPoint.prototype.intersectsCoordinate);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'getExtent',
- ol.geom.MultiPoint.prototype.getExtent);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'simplify',
- ol.geom.MultiPoint.prototype.simplify);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'transform',
- ol.geom.MultiPoint.prototype.transform);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'get',
- ol.geom.MultiPoint.prototype.get);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'getKeys',
- ol.geom.MultiPoint.prototype.getKeys);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'getProperties',
- ol.geom.MultiPoint.prototype.getProperties);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'set',
- ol.geom.MultiPoint.prototype.set);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'setProperties',
- ol.geom.MultiPoint.prototype.setProperties);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'unset',
- ol.geom.MultiPoint.prototype.unset);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'changed',
- ol.geom.MultiPoint.prototype.changed);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'dispatchEvent',
- ol.geom.MultiPoint.prototype.dispatchEvent);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'getRevision',
- ol.geom.MultiPoint.prototype.getRevision);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'on',
- ol.geom.MultiPoint.prototype.on);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'once',
- ol.geom.MultiPoint.prototype.once);
- goog.exportProperty(
- ol.geom.MultiPoint.prototype,
- 'un',
- ol.geom.MultiPoint.prototype.un);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'getFirstCoordinate',
- ol.geom.MultiPolygon.prototype.getFirstCoordinate);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'getLastCoordinate',
- ol.geom.MultiPolygon.prototype.getLastCoordinate);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'getLayout',
- ol.geom.MultiPolygon.prototype.getLayout);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'rotate',
- ol.geom.MultiPolygon.prototype.rotate);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'scale',
- ol.geom.MultiPolygon.prototype.scale);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'getClosestPoint',
- ol.geom.MultiPolygon.prototype.getClosestPoint);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'intersectsCoordinate',
- ol.geom.MultiPolygon.prototype.intersectsCoordinate);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'getExtent',
- ol.geom.MultiPolygon.prototype.getExtent);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'simplify',
- ol.geom.MultiPolygon.prototype.simplify);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'transform',
- ol.geom.MultiPolygon.prototype.transform);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'get',
- ol.geom.MultiPolygon.prototype.get);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'getKeys',
- ol.geom.MultiPolygon.prototype.getKeys);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'getProperties',
- ol.geom.MultiPolygon.prototype.getProperties);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'set',
- ol.geom.MultiPolygon.prototype.set);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'setProperties',
- ol.geom.MultiPolygon.prototype.setProperties);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'unset',
- ol.geom.MultiPolygon.prototype.unset);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'changed',
- ol.geom.MultiPolygon.prototype.changed);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'dispatchEvent',
- ol.geom.MultiPolygon.prototype.dispatchEvent);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'getRevision',
- ol.geom.MultiPolygon.prototype.getRevision);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'on',
- ol.geom.MultiPolygon.prototype.on);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'once',
- ol.geom.MultiPolygon.prototype.once);
- goog.exportProperty(
- ol.geom.MultiPolygon.prototype,
- 'un',
- ol.geom.MultiPolygon.prototype.un);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'getFirstCoordinate',
- ol.geom.Point.prototype.getFirstCoordinate);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'getLastCoordinate',
- ol.geom.Point.prototype.getLastCoordinate);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'getLayout',
- ol.geom.Point.prototype.getLayout);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'rotate',
- ol.geom.Point.prototype.rotate);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'scale',
- ol.geom.Point.prototype.scale);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'getClosestPoint',
- ol.geom.Point.prototype.getClosestPoint);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'intersectsCoordinate',
- ol.geom.Point.prototype.intersectsCoordinate);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'getExtent',
- ol.geom.Point.prototype.getExtent);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'simplify',
- ol.geom.Point.prototype.simplify);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'transform',
- ol.geom.Point.prototype.transform);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'get',
- ol.geom.Point.prototype.get);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'getKeys',
- ol.geom.Point.prototype.getKeys);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'getProperties',
- ol.geom.Point.prototype.getProperties);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'set',
- ol.geom.Point.prototype.set);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'setProperties',
- ol.geom.Point.prototype.setProperties);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'unset',
- ol.geom.Point.prototype.unset);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'changed',
- ol.geom.Point.prototype.changed);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'dispatchEvent',
- ol.geom.Point.prototype.dispatchEvent);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'getRevision',
- ol.geom.Point.prototype.getRevision);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'on',
- ol.geom.Point.prototype.on);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'once',
- ol.geom.Point.prototype.once);
- goog.exportProperty(
- ol.geom.Point.prototype,
- 'un',
- ol.geom.Point.prototype.un);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'getFirstCoordinate',
- ol.geom.Polygon.prototype.getFirstCoordinate);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'getLastCoordinate',
- ol.geom.Polygon.prototype.getLastCoordinate);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'getLayout',
- ol.geom.Polygon.prototype.getLayout);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'rotate',
- ol.geom.Polygon.prototype.rotate);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'scale',
- ol.geom.Polygon.prototype.scale);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'getClosestPoint',
- ol.geom.Polygon.prototype.getClosestPoint);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'intersectsCoordinate',
- ol.geom.Polygon.prototype.intersectsCoordinate);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'getExtent',
- ol.geom.Polygon.prototype.getExtent);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'simplify',
- ol.geom.Polygon.prototype.simplify);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'transform',
- ol.geom.Polygon.prototype.transform);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'get',
- ol.geom.Polygon.prototype.get);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'getKeys',
- ol.geom.Polygon.prototype.getKeys);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'getProperties',
- ol.geom.Polygon.prototype.getProperties);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'set',
- ol.geom.Polygon.prototype.set);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'setProperties',
- ol.geom.Polygon.prototype.setProperties);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'unset',
- ol.geom.Polygon.prototype.unset);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'changed',
- ol.geom.Polygon.prototype.changed);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'dispatchEvent',
- ol.geom.Polygon.prototype.dispatchEvent);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'getRevision',
- ol.geom.Polygon.prototype.getRevision);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'on',
- ol.geom.Polygon.prototype.on);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'once',
- ol.geom.Polygon.prototype.once);
- goog.exportProperty(
- ol.geom.Polygon.prototype,
- 'un',
- ol.geom.Polygon.prototype.un);
- goog.exportProperty(
- ol.format.GML.prototype,
- 'readFeatures',
- ol.format.GML.prototype.readFeatures);
- goog.exportProperty(
- ol.format.GML2.prototype,
- 'readFeatures',
- ol.format.GML2.prototype.readFeatures);
- goog.exportProperty(
- ol.format.GML3.prototype,
- 'readFeatures',
- ol.format.GML3.prototype.readFeatures);
- goog.exportProperty(
- ol.control.Control.prototype,
- 'get',
- ol.control.Control.prototype.get);
- goog.exportProperty(
- ol.control.Control.prototype,
- 'getKeys',
- ol.control.Control.prototype.getKeys);
- goog.exportProperty(
- ol.control.Control.prototype,
- 'getProperties',
- ol.control.Control.prototype.getProperties);
- goog.exportProperty(
- ol.control.Control.prototype,
- 'set',
- ol.control.Control.prototype.set);
- goog.exportProperty(
- ol.control.Control.prototype,
- 'setProperties',
- ol.control.Control.prototype.setProperties);
- goog.exportProperty(
- ol.control.Control.prototype,
- 'unset',
- ol.control.Control.prototype.unset);
- goog.exportProperty(
- ol.control.Control.prototype,
- 'changed',
- ol.control.Control.prototype.changed);
- goog.exportProperty(
- ol.control.Control.prototype,
- 'dispatchEvent',
- ol.control.Control.prototype.dispatchEvent);
- goog.exportProperty(
- ol.control.Control.prototype,
- 'getRevision',
- ol.control.Control.prototype.getRevision);
- goog.exportProperty(
- ol.control.Control.prototype,
- 'on',
- ol.control.Control.prototype.on);
- goog.exportProperty(
- ol.control.Control.prototype,
- 'once',
- ol.control.Control.prototype.once);
- goog.exportProperty(
- ol.control.Control.prototype,
- 'un',
- ol.control.Control.prototype.un);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'getMap',
- ol.control.Attribution.prototype.getMap);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'setMap',
- ol.control.Attribution.prototype.setMap);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'setTarget',
- ol.control.Attribution.prototype.setTarget);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'get',
- ol.control.Attribution.prototype.get);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'getKeys',
- ol.control.Attribution.prototype.getKeys);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'getProperties',
- ol.control.Attribution.prototype.getProperties);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'set',
- ol.control.Attribution.prototype.set);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'setProperties',
- ol.control.Attribution.prototype.setProperties);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'unset',
- ol.control.Attribution.prototype.unset);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'changed',
- ol.control.Attribution.prototype.changed);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'dispatchEvent',
- ol.control.Attribution.prototype.dispatchEvent);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'getRevision',
- ol.control.Attribution.prototype.getRevision);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'on',
- ol.control.Attribution.prototype.on);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'once',
- ol.control.Attribution.prototype.once);
- goog.exportProperty(
- ol.control.Attribution.prototype,
- 'un',
- ol.control.Attribution.prototype.un);
- goog.exportProperty(
- ol.control.FullScreen.prototype,
- 'getMap',
- ol.control.FullScreen.prototype.getMap);
- goog.exportProperty(
- ol.control.FullScreen.prototype,
- 'setMap',
- ol.control.FullScreen.prototype.setMap);
- goog.exportProperty(
- ol.control.FullScreen.prototype,
- 'setTarget',
- ol.control.FullScreen.prototype.setTarget);
- goog.exportProperty(
- ol.control.FullScreen.prototype,
- 'get',
- ol.control.FullScreen.prototype.get);
- goog.exportProperty(
- ol.control.FullScreen.prototype,
- 'getKeys',
- ol.control.FullScreen.prototype.getKeys);
- goog.exportProperty(
- ol.control.FullScreen.prototype,
- 'getProperties',
- ol.control.FullScreen.prototype.getProperties);
- goog.exportProperty(
- ol.control.FullScreen.prototype,
- 'set',
- ol.control.FullScreen.prototype.set);
- goog.exportProperty(
- ol.control.FullScreen.prototype,
- 'setProperties',
- ol.control.FullScreen.prototype.setProperties);
- goog.exportProperty(
- ol.control.FullScreen.prototype,
- 'unset',
- ol.control.FullScreen.prototype.unset);
- goog.exportProperty(
- ol.control.FullScreen.prototype,
- 'changed',
- ol.control.FullScreen.prototype.changed);
- goog.exportProperty(
- ol.control.FullScreen.prototype,
- 'dispatchEvent',
- ol.control.FullScreen.prototype.dispatchEvent);
- goog.exportProperty(
- ol.control.FullScreen.prototype,
- 'getRevision',
- ol.control.FullScreen.prototype.getRevision);
- goog.exportProperty(
- ol.control.FullScreen.prototype,
- 'on',
- ol.control.FullScreen.prototype.on);
- goog.exportProperty(
- ol.control.FullScreen.prototype,
- 'once',
- ol.control.FullScreen.prototype.once);
- goog.exportProperty(
- ol.control.FullScreen.prototype,
- 'un',
- ol.control.FullScreen.prototype.un);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'getMap',
- ol.control.MousePosition.prototype.getMap);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'setMap',
- ol.control.MousePosition.prototype.setMap);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'setTarget',
- ol.control.MousePosition.prototype.setTarget);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'get',
- ol.control.MousePosition.prototype.get);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'getKeys',
- ol.control.MousePosition.prototype.getKeys);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'getProperties',
- ol.control.MousePosition.prototype.getProperties);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'set',
- ol.control.MousePosition.prototype.set);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'setProperties',
- ol.control.MousePosition.prototype.setProperties);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'unset',
- ol.control.MousePosition.prototype.unset);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'changed',
- ol.control.MousePosition.prototype.changed);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'dispatchEvent',
- ol.control.MousePosition.prototype.dispatchEvent);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'getRevision',
- ol.control.MousePosition.prototype.getRevision);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'on',
- ol.control.MousePosition.prototype.on);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'once',
- ol.control.MousePosition.prototype.once);
- goog.exportProperty(
- ol.control.MousePosition.prototype,
- 'un',
- ol.control.MousePosition.prototype.un);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'getMap',
- ol.control.OverviewMap.prototype.getMap);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'setMap',
- ol.control.OverviewMap.prototype.setMap);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'setTarget',
- ol.control.OverviewMap.prototype.setTarget);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'get',
- ol.control.OverviewMap.prototype.get);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'getKeys',
- ol.control.OverviewMap.prototype.getKeys);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'getProperties',
- ol.control.OverviewMap.prototype.getProperties);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'set',
- ol.control.OverviewMap.prototype.set);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'setProperties',
- ol.control.OverviewMap.prototype.setProperties);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'unset',
- ol.control.OverviewMap.prototype.unset);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'changed',
- ol.control.OverviewMap.prototype.changed);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'dispatchEvent',
- ol.control.OverviewMap.prototype.dispatchEvent);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'getRevision',
- ol.control.OverviewMap.prototype.getRevision);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'on',
- ol.control.OverviewMap.prototype.on);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'once',
- ol.control.OverviewMap.prototype.once);
- goog.exportProperty(
- ol.control.OverviewMap.prototype,
- 'un',
- ol.control.OverviewMap.prototype.un);
- goog.exportProperty(
- ol.control.Rotate.prototype,
- 'getMap',
- ol.control.Rotate.prototype.getMap);
- goog.exportProperty(
- ol.control.Rotate.prototype,
- 'setMap',
- ol.control.Rotate.prototype.setMap);
- goog.exportProperty(
- ol.control.Rotate.prototype,
- 'setTarget',
- ol.control.Rotate.prototype.setTarget);
- goog.exportProperty(
- ol.control.Rotate.prototype,
- 'get',
- ol.control.Rotate.prototype.get);
- goog.exportProperty(
- ol.control.Rotate.prototype,
- 'getKeys',
- ol.control.Rotate.prototype.getKeys);
- goog.exportProperty(
- ol.control.Rotate.prototype,
- 'getProperties',
- ol.control.Rotate.prototype.getProperties);
- goog.exportProperty(
- ol.control.Rotate.prototype,
- 'set',
- ol.control.Rotate.prototype.set);
- goog.exportProperty(
- ol.control.Rotate.prototype,
- 'setProperties',
- ol.control.Rotate.prototype.setProperties);
- goog.exportProperty(
- ol.control.Rotate.prototype,
- 'unset',
- ol.control.Rotate.prototype.unset);
- goog.exportProperty(
- ol.control.Rotate.prototype,
- 'changed',
- ol.control.Rotate.prototype.changed);
- goog.exportProperty(
- ol.control.Rotate.prototype,
- 'dispatchEvent',
- ol.control.Rotate.prototype.dispatchEvent);
- goog.exportProperty(
- ol.control.Rotate.prototype,
- 'getRevision',
- ol.control.Rotate.prototype.getRevision);
- goog.exportProperty(
- ol.control.Rotate.prototype,
- 'on',
- ol.control.Rotate.prototype.on);
- goog.exportProperty(
- ol.control.Rotate.prototype,
- 'once',
- ol.control.Rotate.prototype.once);
- goog.exportProperty(
- ol.control.Rotate.prototype,
- 'un',
- ol.control.Rotate.prototype.un);
- goog.exportProperty(
- ol.control.ScaleLine.prototype,
- 'getMap',
- ol.control.ScaleLine.prototype.getMap);
- goog.exportProperty(
- ol.control.ScaleLine.prototype,
- 'setMap',
- ol.control.ScaleLine.prototype.setMap);
- goog.exportProperty(
- ol.control.ScaleLine.prototype,
- 'setTarget',
- ol.control.ScaleLine.prototype.setTarget);
- goog.exportProperty(
- ol.control.ScaleLine.prototype,
- 'get',
- ol.control.ScaleLine.prototype.get);
- goog.exportProperty(
- ol.control.ScaleLine.prototype,
- 'getKeys',
- ol.control.ScaleLine.prototype.getKeys);
- goog.exportProperty(
- ol.control.ScaleLine.prototype,
- 'getProperties',
- ol.control.ScaleLine.prototype.getProperties);
- goog.exportProperty(
- ol.control.ScaleLine.prototype,
- 'set',
- ol.control.ScaleLine.prototype.set);
- goog.exportProperty(
- ol.control.ScaleLine.prototype,
- 'setProperties',
- ol.control.ScaleLine.prototype.setProperties);
- goog.exportProperty(
- ol.control.ScaleLine.prototype,
- 'unset',
- ol.control.ScaleLine.prototype.unset);
- goog.exportProperty(
- ol.control.ScaleLine.prototype,
- 'changed',
- ol.control.ScaleLine.prototype.changed);
- goog.exportProperty(
- ol.control.ScaleLine.prototype,
- 'dispatchEvent',
- ol.control.ScaleLine.prototype.dispatchEvent);
- goog.exportProperty(
- ol.control.ScaleLine.prototype,
- 'getRevision',
- ol.control.ScaleLine.prototype.getRevision);
- goog.exportProperty(
- ol.control.ScaleLine.prototype,
- 'on',
- ol.control.ScaleLine.prototype.on);
- goog.exportProperty(
- ol.control.ScaleLine.prototype,
- 'once',
- ol.control.ScaleLine.prototype.once);
- goog.exportProperty(
- ol.control.ScaleLine.prototype,
- 'un',
- ol.control.ScaleLine.prototype.un);
- goog.exportProperty(
- ol.control.Zoom.prototype,
- 'getMap',
- ol.control.Zoom.prototype.getMap);
- goog.exportProperty(
- ol.control.Zoom.prototype,
- 'setMap',
- ol.control.Zoom.prototype.setMap);
- goog.exportProperty(
- ol.control.Zoom.prototype,
- 'setTarget',
- ol.control.Zoom.prototype.setTarget);
- goog.exportProperty(
- ol.control.Zoom.prototype,
- 'get',
- ol.control.Zoom.prototype.get);
- goog.exportProperty(
- ol.control.Zoom.prototype,
- 'getKeys',
- ol.control.Zoom.prototype.getKeys);
- goog.exportProperty(
- ol.control.Zoom.prototype,
- 'getProperties',
- ol.control.Zoom.prototype.getProperties);
- goog.exportProperty(
- ol.control.Zoom.prototype,
- 'set',
- ol.control.Zoom.prototype.set);
- goog.exportProperty(
- ol.control.Zoom.prototype,
- 'setProperties',
- ol.control.Zoom.prototype.setProperties);
- goog.exportProperty(
- ol.control.Zoom.prototype,
- 'unset',
- ol.control.Zoom.prototype.unset);
- goog.exportProperty(
- ol.control.Zoom.prototype,
- 'changed',
- ol.control.Zoom.prototype.changed);
- goog.exportProperty(
- ol.control.Zoom.prototype,
- 'dispatchEvent',
- ol.control.Zoom.prototype.dispatchEvent);
- goog.exportProperty(
- ol.control.Zoom.prototype,
- 'getRevision',
- ol.control.Zoom.prototype.getRevision);
- goog.exportProperty(
- ol.control.Zoom.prototype,
- 'on',
- ol.control.Zoom.prototype.on);
- goog.exportProperty(
- ol.control.Zoom.prototype,
- 'once',
- ol.control.Zoom.prototype.once);
- goog.exportProperty(
- ol.control.Zoom.prototype,
- 'un',
- ol.control.Zoom.prototype.un);
- goog.exportProperty(
- ol.control.ZoomSlider.prototype,
- 'getMap',
- ol.control.ZoomSlider.prototype.getMap);
- goog.exportProperty(
- ol.control.ZoomSlider.prototype,
- 'setMap',
- ol.control.ZoomSlider.prototype.setMap);
- goog.exportProperty(
- ol.control.ZoomSlider.prototype,
- 'setTarget',
- ol.control.ZoomSlider.prototype.setTarget);
- goog.exportProperty(
- ol.control.ZoomSlider.prototype,
- 'get',
- ol.control.ZoomSlider.prototype.get);
- goog.exportProperty(
- ol.control.ZoomSlider.prototype,
- 'getKeys',
- ol.control.ZoomSlider.prototype.getKeys);
- goog.exportProperty(
- ol.control.ZoomSlider.prototype,
- 'getProperties',
- ol.control.ZoomSlider.prototype.getProperties);
- goog.exportProperty(
- ol.control.ZoomSlider.prototype,
- 'set',
- ol.control.ZoomSlider.prototype.set);
- goog.exportProperty(
- ol.control.ZoomSlider.prototype,
- 'setProperties',
- ol.control.ZoomSlider.prototype.setProperties);
- goog.exportProperty(
- ol.control.ZoomSlider.prototype,
- 'unset',
- ol.control.ZoomSlider.prototype.unset);
- goog.exportProperty(
- ol.control.ZoomSlider.prototype,
- 'changed',
- ol.control.ZoomSlider.prototype.changed);
- goog.exportProperty(
- ol.control.ZoomSlider.prototype,
- 'dispatchEvent',
- ol.control.ZoomSlider.prototype.dispatchEvent);
- goog.exportProperty(
- ol.control.ZoomSlider.prototype,
- 'getRevision',
- ol.control.ZoomSlider.prototype.getRevision);
- goog.exportProperty(
- ol.control.ZoomSlider.prototype,
- 'on',
- ol.control.ZoomSlider.prototype.on);
- goog.exportProperty(
- ol.control.ZoomSlider.prototype,
- 'once',
- ol.control.ZoomSlider.prototype.once);
- goog.exportProperty(
- ol.control.ZoomSlider.prototype,
- 'un',
- ol.control.ZoomSlider.prototype.un);
- goog.exportProperty(
- ol.control.ZoomToExtent.prototype,
- 'getMap',
- ol.control.ZoomToExtent.prototype.getMap);
- goog.exportProperty(
- ol.control.ZoomToExtent.prototype,
- 'setMap',
- ol.control.ZoomToExtent.prototype.setMap);
- goog.exportProperty(
- ol.control.ZoomToExtent.prototype,
- 'setTarget',
- ol.control.ZoomToExtent.prototype.setTarget);
- goog.exportProperty(
- ol.control.ZoomToExtent.prototype,
- 'get',
- ol.control.ZoomToExtent.prototype.get);
- goog.exportProperty(
- ol.control.ZoomToExtent.prototype,
- 'getKeys',
- ol.control.ZoomToExtent.prototype.getKeys);
- goog.exportProperty(
- ol.control.ZoomToExtent.prototype,
- 'getProperties',
- ol.control.ZoomToExtent.prototype.getProperties);
- goog.exportProperty(
- ol.control.ZoomToExtent.prototype,
- 'set',
- ol.control.ZoomToExtent.prototype.set);
- goog.exportProperty(
- ol.control.ZoomToExtent.prototype,
- 'setProperties',
- ol.control.ZoomToExtent.prototype.setProperties);
- goog.exportProperty(
- ol.control.ZoomToExtent.prototype,
- 'unset',
- ol.control.ZoomToExtent.prototype.unset);
- goog.exportProperty(
- ol.control.ZoomToExtent.prototype,
- 'changed',
- ol.control.ZoomToExtent.prototype.changed);
- goog.exportProperty(
- ol.control.ZoomToExtent.prototype,
- 'dispatchEvent',
- ol.control.ZoomToExtent.prototype.dispatchEvent);
- goog.exportProperty(
- ol.control.ZoomToExtent.prototype,
- 'getRevision',
- ol.control.ZoomToExtent.prototype.getRevision);
- goog.exportProperty(
- ol.control.ZoomToExtent.prototype,
- 'on',
- ol.control.ZoomToExtent.prototype.on);
- goog.exportProperty(
- ol.control.ZoomToExtent.prototype,
- 'once',
- ol.control.ZoomToExtent.prototype.once);
- goog.exportProperty(
- ol.control.ZoomToExtent.prototype,
- 'un',
- ol.control.ZoomToExtent.prototype.un);
- ol.VERSION = 'v4.6.5';
- OPENLAYERS.ol = ol;
- return OPENLAYERS.ol;
- }));
|