| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149301503015130152301533015430155301563015730158301593016030161301623016330164301653016630167301683016930170301713017230173301743017530176301773017830179301803018130182301833018430185301863018730188301893019030191301923019330194301953019630197301983019930200302013020230203302043020530206302073020830209302103021130212302133021430215302163021730218302193022030221302223022330224302253022630227302283022930230302313023230233302343023530236302373023830239302403024130242302433024430245302463024730248302493025030251302523025330254302553025630257302583025930260302613026230263302643026530266302673026830269302703027130272302733027430275302763027730278302793028030281302823028330284302853028630287302883028930290302913029230293302943029530296302973029830299303003030130302303033030430305303063030730308303093031030311303123031330314303153031630317303183031930320303213032230323303243032530326303273032830329303303033130332303333033430335303363033730338303393034030341303423034330344303453034630347303483034930350303513035230353303543035530356303573035830359303603036130362303633036430365303663036730368303693037030371303723037330374303753037630377303783037930380303813038230383303843038530386303873038830389303903039130392303933039430395303963039730398303993040030401304023040330404304053040630407304083040930410304113041230413304143041530416304173041830419304203042130422304233042430425304263042730428304293043030431304323043330434304353043630437304383043930440304413044230443304443044530446304473044830449304503045130452304533045430455304563045730458304593046030461304623046330464304653046630467304683046930470304713047230473304743047530476304773047830479304803048130482304833048430485304863048730488304893049030491304923049330494304953049630497304983049930500305013050230503305043050530506305073050830509305103051130512305133051430515305163051730518305193052030521305223052330524305253052630527305283052930530305313053230533305343053530536305373053830539305403054130542305433054430545305463054730548305493055030551305523055330554305553055630557305583055930560305613056230563305643056530566305673056830569305703057130572305733057430575305763057730578305793058030581305823058330584305853058630587305883058930590305913059230593305943059530596305973059830599306003060130602306033060430605306063060730608306093061030611306123061330614306153061630617306183061930620306213062230623306243062530626306273062830629306303063130632306333063430635306363063730638306393064030641306423064330644306453064630647306483064930650306513065230653306543065530656306573065830659306603066130662306633066430665306663066730668306693067030671306723067330674306753067630677306783067930680306813068230683306843068530686306873068830689306903069130692306933069430695306963069730698306993070030701307023070330704307053070630707307083070930710307113071230713307143071530716307173071830719307203072130722307233072430725307263072730728307293073030731307323073330734307353073630737307383073930740307413074230743307443074530746307473074830749307503075130752307533075430755307563075730758307593076030761307623076330764307653076630767307683076930770307713077230773307743077530776307773077830779307803078130782307833078430785307863078730788307893079030791307923079330794307953079630797307983079930800308013080230803308043080530806308073080830809308103081130812308133081430815308163081730818308193082030821308223082330824308253082630827308283082930830308313083230833308343083530836308373083830839308403084130842308433084430845308463084730848308493085030851308523085330854308553085630857308583085930860308613086230863308643086530866308673086830869308703087130872308733087430875308763087730878308793088030881308823088330884308853088630887308883088930890308913089230893308943089530896308973089830899309003090130902309033090430905309063090730908309093091030911309123091330914309153091630917309183091930920309213092230923309243092530926309273092830929309303093130932309333093430935309363093730938309393094030941309423094330944309453094630947309483094930950309513095230953309543095530956309573095830959309603096130962309633096430965309663096730968309693097030971309723097330974309753097630977309783097930980309813098230983309843098530986309873098830989309903099130992309933099430995309963099730998309993100031001310023100331004310053100631007310083100931010310113101231013310143101531016310173101831019310203102131022310233102431025310263102731028310293103031031310323103331034310353103631037310383103931040310413104231043310443104531046310473104831049310503105131052310533105431055310563105731058310593106031061310623106331064310653106631067310683106931070310713107231073310743107531076310773107831079310803108131082310833108431085310863108731088310893109031091310923109331094310953109631097310983109931100311013110231103311043110531106311073110831109311103111131112311133111431115311163111731118311193112031121311223112331124311253112631127311283112931130311313113231133311343113531136311373113831139311403114131142311433114431145311463114731148311493115031151311523115331154311553115631157311583115931160311613116231163311643116531166311673116831169311703117131172311733117431175311763117731178311793118031181311823118331184311853118631187311883118931190311913119231193311943119531196311973119831199312003120131202312033120431205312063120731208312093121031211312123121331214312153121631217312183121931220312213122231223312243122531226312273122831229312303123131232312333123431235312363123731238312393124031241312423124331244312453124631247312483124931250312513125231253312543125531256312573125831259312603126131262312633126431265312663126731268312693127031271312723127331274312753127631277312783127931280312813128231283312843128531286312873128831289312903129131292312933129431295312963129731298312993130031301313023130331304313053130631307313083130931310313113131231313313143131531316313173131831319313203132131322313233132431325313263132731328313293133031331313323133331334313353133631337313383133931340313413134231343313443134531346313473134831349313503135131352313533135431355313563135731358313593136031361313623136331364313653136631367313683136931370313713137231373313743137531376313773137831379313803138131382313833138431385313863138731388313893139031391313923139331394313953139631397313983139931400314013140231403314043140531406314073140831409314103141131412314133141431415314163141731418314193142031421314223142331424314253142631427314283142931430314313143231433314343143531436314373143831439314403144131442314433144431445314463144731448314493145031451314523145331454314553145631457314583145931460314613146231463314643146531466314673146831469314703147131472314733147431475314763147731478314793148031481314823148331484314853148631487314883148931490314913149231493314943149531496314973149831499315003150131502315033150431505315063150731508315093151031511315123151331514315153151631517315183151931520315213152231523315243152531526315273152831529315303153131532315333153431535315363153731538315393154031541315423154331544315453154631547315483154931550315513155231553315543155531556315573155831559315603156131562315633156431565315663156731568315693157031571315723157331574315753157631577315783157931580315813158231583315843158531586315873158831589315903159131592315933159431595315963159731598315993160031601316023160331604316053160631607316083160931610316113161231613316143161531616316173161831619316203162131622316233162431625316263162731628316293163031631316323163331634316353163631637316383163931640316413164231643316443164531646316473164831649316503165131652316533165431655316563165731658316593166031661316623166331664316653166631667316683166931670316713167231673316743167531676316773167831679316803168131682316833168431685316863168731688316893169031691316923169331694316953169631697316983169931700317013170231703317043170531706317073170831709317103171131712317133171431715317163171731718317193172031721317223172331724317253172631727317283172931730317313173231733317343173531736317373173831739317403174131742317433174431745317463174731748317493175031751317523175331754317553175631757317583175931760317613176231763317643176531766317673176831769317703177131772317733177431775317763177731778317793178031781317823178331784317853178631787317883178931790317913179231793317943179531796317973179831799318003180131802318033180431805318063180731808318093181031811318123181331814318153181631817318183181931820318213182231823318243182531826318273182831829318303183131832318333183431835318363183731838318393184031841318423184331844318453184631847318483184931850318513185231853318543185531856318573185831859318603186131862318633186431865318663186731868318693187031871318723187331874318753187631877318783187931880318813188231883318843188531886318873188831889318903189131892318933189431895318963189731898318993190031901319023190331904319053190631907319083190931910319113191231913319143191531916319173191831919319203192131922319233192431925319263192731928319293193031931319323193331934319353193631937319383193931940319413194231943319443194531946319473194831949319503195131952319533195431955319563195731958319593196031961319623196331964319653196631967319683196931970319713197231973319743197531976319773197831979319803198131982319833198431985319863198731988319893199031991319923199331994319953199631997319983199932000320013200232003320043200532006320073200832009320103201132012320133201432015320163201732018320193202032021320223202332024320253202632027320283202932030320313203232033320343203532036320373203832039320403204132042320433204432045320463204732048320493205032051320523205332054320553205632057320583205932060320613206232063320643206532066320673206832069320703207132072320733207432075320763207732078320793208032081320823208332084320853208632087320883208932090320913209232093320943209532096320973209832099321003210132102321033210432105321063210732108321093211032111321123211332114321153211632117321183211932120321213212232123321243212532126321273212832129321303213132132321333213432135321363213732138321393214032141321423214332144321453214632147321483214932150321513215232153321543215532156321573215832159321603216132162321633216432165321663216732168321693217032171321723217332174321753217632177321783217932180321813218232183321843218532186321873218832189321903219132192321933219432195321963219732198321993220032201322023220332204322053220632207322083220932210322113221232213322143221532216322173221832219322203222132222322233222432225322263222732228322293223032231322323223332234322353223632237322383223932240322413224232243322443224532246322473224832249322503225132252322533225432255322563225732258322593226032261322623226332264322653226632267322683226932270322713227232273322743227532276322773227832279322803228132282322833228432285322863228732288322893229032291322923229332294322953229632297322983229932300323013230232303323043230532306323073230832309323103231132312323133231432315323163231732318323193232032321323223232332324323253232632327323283232932330323313233232333323343233532336323373233832339323403234132342323433234432345323463234732348323493235032351323523235332354323553235632357323583235932360323613236232363323643236532366323673236832369323703237132372323733237432375323763237732378323793238032381323823238332384323853238632387323883238932390323913239232393323943239532396323973239832399324003240132402324033240432405324063240732408324093241032411324123241332414324153241632417324183241932420324213242232423324243242532426324273242832429324303243132432324333243432435324363243732438324393244032441324423244332444324453244632447324483244932450324513245232453324543245532456324573245832459324603246132462324633246432465324663246732468324693247032471324723247332474324753247632477324783247932480324813248232483324843248532486324873248832489324903249132492324933249432495324963249732498324993250032501325023250332504325053250632507325083250932510325113251232513325143251532516325173251832519325203252132522325233252432525325263252732528325293253032531325323253332534325353253632537325383253932540325413254232543325443254532546325473254832549325503255132552325533255432555325563255732558325593256032561325623256332564325653256632567325683256932570325713257232573325743257532576325773257832579325803258132582325833258432585325863258732588325893259032591325923259332594325953259632597325983259932600326013260232603326043260532606326073260832609326103261132612326133261432615326163261732618326193262032621326223262332624326253262632627326283262932630326313263232633326343263532636326373263832639326403264132642326433264432645326463264732648326493265032651326523265332654326553265632657326583265932660326613266232663326643266532666326673266832669326703267132672326733267432675326763267732678326793268032681326823268332684326853268632687326883268932690326913269232693326943269532696326973269832699327003270132702327033270432705327063270732708327093271032711327123271332714327153271632717327183271932720327213272232723327243272532726327273272832729327303273132732327333273432735327363273732738327393274032741327423274332744327453274632747327483274932750327513275232753327543275532756327573275832759327603276132762327633276432765327663276732768327693277032771327723277332774327753277632777327783277932780327813278232783327843278532786327873278832789327903279132792327933279432795327963279732798327993280032801328023280332804328053280632807328083280932810328113281232813328143281532816328173281832819328203282132822328233282432825328263282732828328293283032831328323283332834328353283632837328383283932840328413284232843328443284532846328473284832849328503285132852328533285432855328563285732858328593286032861328623286332864328653286632867328683286932870328713287232873328743287532876328773287832879328803288132882328833288432885328863288732888328893289032891328923289332894328953289632897328983289932900329013290232903329043290532906329073290832909329103291132912329133291432915329163291732918329193292032921329223292332924329253292632927329283292932930329313293232933329343293532936329373293832939329403294132942329433294432945329463294732948329493295032951329523295332954329553295632957329583295932960329613296232963329643296532966329673296832969329703297132972329733297432975329763297732978329793298032981329823298332984329853298632987329883298932990329913299232993329943299532996329973299832999330003300133002330033300433005330063300733008330093301033011330123301333014330153301633017330183301933020330213302233023330243302533026330273302833029330303303133032330333303433035330363303733038330393304033041330423304333044330453304633047330483304933050330513305233053330543305533056330573305833059330603306133062330633306433065330663306733068330693307033071330723307333074330753307633077330783307933080330813308233083330843308533086330873308833089330903309133092330933309433095330963309733098330993310033101331023310333104331053310633107331083310933110331113311233113331143311533116331173311833119331203312133122331233312433125331263312733128331293313033131331323313333134331353313633137331383313933140331413314233143331443314533146331473314833149331503315133152331533315433155331563315733158331593316033161331623316333164331653316633167331683316933170331713317233173331743317533176331773317833179331803318133182331833318433185331863318733188331893319033191331923319333194331953319633197331983319933200332013320233203332043320533206332073320833209332103321133212332133321433215332163321733218332193322033221332223322333224332253322633227332283322933230332313323233233332343323533236332373323833239332403324133242332433324433245332463324733248332493325033251332523325333254332553325633257332583325933260332613326233263332643326533266332673326833269332703327133272332733327433275332763327733278332793328033281332823328333284332853328633287332883328933290332913329233293332943329533296332973329833299333003330133302333033330433305333063330733308333093331033311333123331333314333153331633317333183331933320333213332233323333243332533326333273332833329333303333133332333333333433335333363333733338333393334033341333423334333344333453334633347333483334933350333513335233353333543335533356333573335833359333603336133362333633336433365333663336733368333693337033371333723337333374333753337633377333783337933380333813338233383333843338533386333873338833389333903339133392333933339433395333963339733398333993340033401334023340333404334053340633407334083340933410334113341233413334143341533416334173341833419334203342133422334233342433425334263342733428334293343033431334323343333434334353343633437334383343933440334413344233443334443344533446334473344833449334503345133452334533345433455334563345733458334593346033461334623346333464334653346633467334683346933470334713347233473334743347533476334773347833479334803348133482334833348433485334863348733488334893349033491334923349333494334953349633497334983349933500335013350233503335043350533506335073350833509335103351133512335133351433515335163351733518335193352033521335223352333524335253352633527335283352933530335313353233533335343353533536335373353833539335403354133542335433354433545335463354733548335493355033551335523355333554335553355633557335583355933560335613356233563335643356533566335673356833569335703357133572335733357433575335763357733578335793358033581335823358333584335853358633587335883358933590335913359233593335943359533596335973359833599336003360133602336033360433605336063360733608336093361033611336123361333614336153361633617336183361933620336213362233623336243362533626336273362833629336303363133632336333363433635336363363733638336393364033641336423364333644336453364633647336483364933650336513365233653336543365533656336573365833659336603366133662336633366433665336663366733668336693367033671336723367333674336753367633677336783367933680336813368233683336843368533686336873368833689336903369133692336933369433695336963369733698336993370033701337023370333704337053370633707337083370933710337113371233713337143371533716337173371833719337203372133722337233372433725337263372733728337293373033731337323373333734337353373633737337383373933740337413374233743337443374533746337473374833749337503375133752337533375433755337563375733758337593376033761337623376333764337653376633767337683376933770337713377233773337743377533776337773377833779337803378133782337833378433785337863378733788337893379033791337923379333794337953379633797337983379933800338013380233803338043380533806338073380833809338103381133812338133381433815338163381733818338193382033821338223382333824338253382633827338283382933830338313383233833338343383533836338373383833839338403384133842338433384433845338463384733848338493385033851338523385333854338553385633857338583385933860338613386233863338643386533866338673386833869338703387133872338733387433875338763387733878338793388033881338823388333884338853388633887338883388933890338913389233893338943389533896338973389833899339003390133902339033390433905339063390733908339093391033911339123391333914339153391633917339183391933920339213392233923339243392533926339273392833929339303393133932339333393433935339363393733938339393394033941339423394333944339453394633947339483394933950339513395233953339543395533956339573395833959339603396133962339633396433965339663396733968339693397033971339723397333974339753397633977339783397933980339813398233983339843398533986339873398833989339903399133992339933399433995339963399733998339993400034001340023400334004340053400634007340083400934010340113401234013340143401534016340173401834019340203402134022340233402434025340263402734028340293403034031340323403334034340353403634037340383403934040340413404234043340443404534046340473404834049340503405134052340533405434055340563405734058340593406034061340623406334064340653406634067340683406934070340713407234073340743407534076340773407834079340803408134082340833408434085340863408734088340893409034091340923409334094340953409634097340983409934100341013410234103341043410534106341073410834109341103411134112341133411434115341163411734118341193412034121341223412334124341253412634127341283412934130341313413234133341343413534136341373413834139341403414134142341433414434145341463414734148341493415034151341523415334154341553415634157341583415934160341613416234163341643416534166341673416834169341703417134172341733417434175341763417734178341793418034181341823418334184341853418634187341883418934190341913419234193341943419534196341973419834199342003420134202342033420434205342063420734208342093421034211342123421334214342153421634217342183421934220342213422234223342243422534226342273422834229342303423134232342333423434235342363423734238342393424034241342423424334244342453424634247342483424934250342513425234253342543425534256342573425834259342603426134262342633426434265342663426734268342693427034271342723427334274342753427634277342783427934280342813428234283342843428534286342873428834289342903429134292342933429434295342963429734298342993430034301343023430334304343053430634307343083430934310343113431234313343143431534316343173431834319343203432134322343233432434325343263432734328343293433034331343323433334334343353433634337343383433934340343413434234343343443434534346343473434834349343503435134352343533435434355343563435734358343593436034361343623436334364343653436634367343683436934370343713437234373343743437534376343773437834379343803438134382343833438434385343863438734388343893439034391343923439334394343953439634397343983439934400344013440234403344043440534406344073440834409344103441134412344133441434415344163441734418344193442034421344223442334424344253442634427344283442934430344313443234433344343443534436344373443834439344403444134442344433444434445344463444734448344493445034451344523445334454344553445634457344583445934460344613446234463344643446534466344673446834469344703447134472344733447434475344763447734478344793448034481344823448334484344853448634487344883448934490344913449234493344943449534496344973449834499345003450134502345033450434505345063450734508345093451034511345123451334514345153451634517345183451934520345213452234523345243452534526345273452834529345303453134532345333453434535345363453734538345393454034541345423454334544345453454634547345483454934550345513455234553345543455534556345573455834559345603456134562345633456434565345663456734568345693457034571345723457334574345753457634577345783457934580345813458234583345843458534586345873458834589345903459134592345933459434595345963459734598345993460034601346023460334604346053460634607346083460934610346113461234613346143461534616346173461834619346203462134622346233462434625346263462734628346293463034631346323463334634346353463634637346383463934640346413464234643346443464534646346473464834649346503465134652346533465434655346563465734658346593466034661346623466334664346653466634667346683466934670346713467234673346743467534676346773467834679346803468134682346833468434685346863468734688346893469034691346923469334694346953469634697346983469934700347013470234703347043470534706347073470834709347103471134712347133471434715347163471734718347193472034721347223472334724347253472634727347283472934730347313473234733347343473534736347373473834739347403474134742347433474434745347463474734748347493475034751347523475334754347553475634757347583475934760347613476234763347643476534766347673476834769347703477134772347733477434775347763477734778347793478034781347823478334784347853478634787347883478934790347913479234793347943479534796347973479834799348003480134802348033480434805348063480734808348093481034811348123481334814348153481634817348183481934820348213482234823348243482534826348273482834829348303483134832348333483434835348363483734838348393484034841348423484334844348453484634847348483484934850348513485234853348543485534856348573485834859348603486134862348633486434865348663486734868348693487034871348723487334874348753487634877348783487934880348813488234883348843488534886348873488834889348903489134892348933489434895348963489734898348993490034901349023490334904349053490634907349083490934910349113491234913349143491534916349173491834919349203492134922349233492434925349263492734928349293493034931349323493334934349353493634937349383493934940349413494234943349443494534946349473494834949349503495134952349533495434955349563495734958349593496034961349623496334964349653496634967349683496934970349713497234973349743497534976349773497834979349803498134982349833498434985349863498734988349893499034991349923499334994349953499634997349983499935000350013500235003350043500535006350073500835009350103501135012350133501435015350163501735018350193502035021350223502335024350253502635027350283502935030350313503235033350343503535036350373503835039350403504135042350433504435045350463504735048350493505035051350523505335054350553505635057350583505935060350613506235063350643506535066350673506835069350703507135072350733507435075350763507735078350793508035081350823508335084350853508635087350883508935090350913509235093350943509535096350973509835099351003510135102351033510435105351063510735108351093511035111351123511335114351153511635117351183511935120351213512235123351243512535126351273512835129351303513135132351333513435135351363513735138351393514035141351423514335144351453514635147351483514935150351513515235153351543515535156351573515835159351603516135162351633516435165351663516735168351693517035171351723517335174351753517635177351783517935180351813518235183351843518535186351873518835189351903519135192351933519435195351963519735198351993520035201352023520335204352053520635207352083520935210352113521235213352143521535216352173521835219352203522135222352233522435225352263522735228352293523035231352323523335234352353523635237352383523935240352413524235243352443524535246352473524835249352503525135252352533525435255352563525735258352593526035261352623526335264352653526635267352683526935270352713527235273352743527535276352773527835279352803528135282352833528435285352863528735288352893529035291352923529335294352953529635297352983529935300353013530235303353043530535306353073530835309353103531135312353133531435315353163531735318353193532035321353223532335324353253532635327353283532935330353313533235333353343533535336353373533835339353403534135342353433534435345353463534735348353493535035351353523535335354353553535635357353583535935360353613536235363353643536535366353673536835369353703537135372353733537435375353763537735378353793538035381353823538335384353853538635387353883538935390353913539235393353943539535396353973539835399354003540135402354033540435405354063540735408354093541035411354123541335414354153541635417354183541935420354213542235423354243542535426354273542835429354303543135432354333543435435354363543735438354393544035441354423544335444354453544635447354483544935450354513545235453354543545535456354573545835459354603546135462354633546435465354663546735468354693547035471354723547335474354753547635477354783547935480354813548235483354843548535486354873548835489354903549135492354933549435495354963549735498354993550035501355023550335504355053550635507355083550935510355113551235513355143551535516355173551835519355203552135522355233552435525355263552735528355293553035531355323553335534355353553635537355383553935540355413554235543355443554535546355473554835549355503555135552355533555435555355563555735558355593556035561355623556335564355653556635567355683556935570355713557235573355743557535576355773557835579355803558135582355833558435585355863558735588355893559035591355923559335594355953559635597355983559935600356013560235603356043560535606356073560835609356103561135612356133561435615356163561735618356193562035621356223562335624356253562635627356283562935630356313563235633356343563535636356373563835639356403564135642356433564435645356463564735648356493565035651356523565335654356553565635657356583565935660356613566235663356643566535666356673566835669356703567135672356733567435675356763567735678356793568035681356823568335684356853568635687356883568935690356913569235693356943569535696356973569835699357003570135702357033570435705357063570735708357093571035711357123571335714357153571635717357183571935720357213572235723357243572535726357273572835729357303573135732357333573435735357363573735738357393574035741357423574335744357453574635747357483574935750357513575235753357543575535756357573575835759357603576135762357633576435765357663576735768357693577035771357723577335774357753577635777357783577935780357813578235783357843578535786357873578835789357903579135792357933579435795357963579735798357993580035801358023580335804358053580635807358083580935810358113581235813358143581535816358173581835819358203582135822358233582435825358263582735828358293583035831358323583335834358353583635837358383583935840358413584235843358443584535846358473584835849358503585135852358533585435855358563585735858358593586035861358623586335864358653586635867358683586935870358713587235873358743587535876358773587835879358803588135882358833588435885358863588735888358893589035891358923589335894358953589635897358983589935900359013590235903359043590535906359073590835909359103591135912359133591435915359163591735918359193592035921359223592335924359253592635927359283592935930359313593235933359343593535936359373593835939359403594135942359433594435945359463594735948359493595035951359523595335954359553595635957359583595935960359613596235963359643596535966359673596835969359703597135972359733597435975359763597735978359793598035981359823598335984359853598635987359883598935990359913599235993359943599535996359973599835999360003600136002360033600436005360063600736008360093601036011360123601336014360153601636017360183601936020360213602236023360243602536026360273602836029360303603136032360333603436035360363603736038360393604036041360423604336044360453604636047360483604936050360513605236053360543605536056360573605836059360603606136062360633606436065360663606736068360693607036071360723607336074360753607636077360783607936080360813608236083360843608536086360873608836089360903609136092360933609436095360963609736098360993610036101361023610336104361053610636107361083610936110361113611236113361143611536116361173611836119361203612136122361233612436125361263612736128361293613036131361323613336134361353613636137361383613936140361413614236143361443614536146361473614836149361503615136152361533615436155361563615736158361593616036161361623616336164361653616636167361683616936170361713617236173361743617536176361773617836179361803618136182361833618436185361863618736188361893619036191361923619336194361953619636197361983619936200362013620236203362043620536206362073620836209362103621136212362133621436215362163621736218362193622036221362223622336224362253622636227362283622936230362313623236233362343623536236362373623836239362403624136242362433624436245362463624736248362493625036251362523625336254362553625636257362583625936260362613626236263362643626536266362673626836269362703627136272362733627436275362763627736278362793628036281362823628336284362853628636287362883628936290362913629236293362943629536296362973629836299363003630136302363033630436305363063630736308363093631036311363123631336314363153631636317363183631936320363213632236323363243632536326363273632836329363303633136332363333633436335363363633736338363393634036341363423634336344363453634636347363483634936350363513635236353363543635536356363573635836359363603636136362363633636436365363663636736368363693637036371363723637336374363753637636377363783637936380363813638236383363843638536386363873638836389363903639136392363933639436395363963639736398363993640036401364023640336404364053640636407364083640936410364113641236413364143641536416364173641836419364203642136422364233642436425364263642736428364293643036431364323643336434364353643636437364383643936440364413644236443364443644536446364473644836449364503645136452364533645436455364563645736458364593646036461364623646336464364653646636467364683646936470364713647236473364743647536476364773647836479364803648136482364833648436485364863648736488364893649036491364923649336494364953649636497364983649936500365013650236503365043650536506365073650836509365103651136512365133651436515365163651736518365193652036521365223652336524365253652636527365283652936530365313653236533365343653536536365373653836539365403654136542365433654436545365463654736548365493655036551365523655336554365553655636557365583655936560365613656236563365643656536566365673656836569365703657136572365733657436575365763657736578365793658036581365823658336584365853658636587365883658936590365913659236593365943659536596365973659836599366003660136602366033660436605366063660736608366093661036611366123661336614366153661636617366183661936620366213662236623366243662536626366273662836629366303663136632366333663436635366363663736638366393664036641366423664336644366453664636647366483664936650366513665236653366543665536656366573665836659366603666136662366633666436665366663666736668366693667036671366723667336674366753667636677366783667936680366813668236683366843668536686366873668836689366903669136692366933669436695366963669736698366993670036701367023670336704367053670636707367083670936710367113671236713367143671536716367173671836719367203672136722367233672436725367263672736728367293673036731367323673336734367353673636737367383673936740367413674236743367443674536746367473674836749367503675136752367533675436755367563675736758367593676036761367623676336764367653676636767367683676936770367713677236773367743677536776367773677836779367803678136782367833678436785367863678736788367893679036791367923679336794367953679636797367983679936800368013680236803368043680536806368073680836809368103681136812368133681436815368163681736818368193682036821368223682336824368253682636827368283682936830368313683236833368343683536836368373683836839368403684136842368433684436845368463684736848368493685036851368523685336854368553685636857368583685936860368613686236863368643686536866368673686836869368703687136872368733687436875368763687736878368793688036881368823688336884368853688636887368883688936890368913689236893368943689536896368973689836899369003690136902369033690436905369063690736908369093691036911369123691336914369153691636917369183691936920369213692236923369243692536926369273692836929369303693136932369333693436935369363693736938369393694036941369423694336944369453694636947369483694936950369513695236953369543695536956369573695836959369603696136962369633696436965369663696736968369693697036971369723697336974369753697636977369783697936980369813698236983369843698536986369873698836989369903699136992369933699436995369963699736998369993700037001370023700337004370053700637007370083700937010370113701237013370143701537016370173701837019370203702137022370233702437025370263702737028370293703037031370323703337034370353703637037370383703937040370413704237043370443704537046370473704837049370503705137052370533705437055370563705737058370593706037061370623706337064370653706637067370683706937070370713707237073370743707537076370773707837079370803708137082370833708437085370863708737088370893709037091370923709337094370953709637097370983709937100371013710237103371043710537106371073710837109371103711137112371133711437115371163711737118371193712037121371223712337124371253712637127371283712937130371313713237133371343713537136371373713837139371403714137142371433714437145371463714737148371493715037151371523715337154371553715637157371583715937160371613716237163371643716537166371673716837169371703717137172371733717437175371763717737178371793718037181371823718337184371853718637187371883718937190371913719237193371943719537196371973719837199372003720137202372033720437205372063720737208372093721037211372123721337214372153721637217372183721937220372213722237223372243722537226372273722837229372303723137232372333723437235372363723737238372393724037241372423724337244372453724637247372483724937250372513725237253372543725537256372573725837259372603726137262372633726437265372663726737268372693727037271372723727337274372753727637277372783727937280372813728237283372843728537286372873728837289372903729137292372933729437295372963729737298372993730037301373023730337304373053730637307373083730937310373113731237313373143731537316373173731837319373203732137322373233732437325373263732737328373293733037331373323733337334373353733637337373383733937340373413734237343373443734537346373473734837349373503735137352373533735437355373563735737358373593736037361373623736337364373653736637367373683736937370373713737237373373743737537376373773737837379373803738137382373833738437385373863738737388373893739037391373923739337394373953739637397373983739937400374013740237403374043740537406374073740837409374103741137412374133741437415374163741737418374193742037421374223742337424374253742637427374283742937430374313743237433374343743537436374373743837439374403744137442374433744437445374463744737448374493745037451374523745337454374553745637457374583745937460374613746237463374643746537466374673746837469374703747137472374733747437475374763747737478374793748037481374823748337484374853748637487374883748937490374913749237493374943749537496374973749837499375003750137502375033750437505375063750737508375093751037511375123751337514375153751637517375183751937520375213752237523375243752537526375273752837529375303753137532375333753437535375363753737538375393754037541375423754337544375453754637547375483754937550375513755237553375543755537556375573755837559375603756137562375633756437565375663756737568375693757037571375723757337574375753757637577375783757937580375813758237583375843758537586375873758837589375903759137592375933759437595375963759737598375993760037601376023760337604376053760637607376083760937610376113761237613376143761537616376173761837619376203762137622376233762437625376263762737628376293763037631376323763337634376353763637637376383763937640376413764237643376443764537646376473764837649376503765137652376533765437655376563765737658376593766037661376623766337664376653766637667376683766937670376713767237673376743767537676376773767837679376803768137682376833768437685376863768737688376893769037691376923769337694376953769637697376983769937700377013770237703377043770537706377073770837709377103771137712377133771437715377163771737718377193772037721377223772337724377253772637727377283772937730377313773237733377343773537736377373773837739377403774137742377433774437745377463774737748377493775037751377523775337754377553775637757377583775937760377613776237763377643776537766377673776837769377703777137772377733777437775377763777737778377793778037781377823778337784377853778637787377883778937790377913779237793377943779537796377973779837799378003780137802378033780437805378063780737808378093781037811378123781337814378153781637817378183781937820378213782237823378243782537826378273782837829378303783137832378333783437835378363783737838378393784037841378423784337844378453784637847378483784937850378513785237853378543785537856378573785837859378603786137862378633786437865378663786737868378693787037871378723787337874378753787637877378783787937880378813788237883378843788537886378873788837889378903789137892378933789437895378963789737898378993790037901379023790337904379053790637907379083790937910379113791237913379143791537916379173791837919379203792137922379233792437925379263792737928379293793037931379323793337934379353793637937379383793937940379413794237943379443794537946379473794837949379503795137952379533795437955379563795737958379593796037961379623796337964379653796637967379683796937970379713797237973379743797537976379773797837979379803798137982379833798437985379863798737988379893799037991379923799337994379953799637997379983799938000380013800238003380043800538006380073800838009380103801138012380133801438015380163801738018380193802038021380223802338024380253802638027380283802938030380313803238033380343803538036380373803838039380403804138042380433804438045380463804738048380493805038051380523805338054380553805638057380583805938060380613806238063380643806538066380673806838069380703807138072380733807438075380763807738078380793808038081380823808338084380853808638087380883808938090380913809238093380943809538096380973809838099381003810138102381033810438105381063810738108381093811038111381123811338114381153811638117381183811938120381213812238123381243812538126381273812838129381303813138132381333813438135381363813738138381393814038141381423814338144381453814638147381483814938150381513815238153381543815538156381573815838159381603816138162381633816438165381663816738168381693817038171381723817338174381753817638177381783817938180381813818238183381843818538186381873818838189381903819138192381933819438195381963819738198381993820038201382023820338204382053820638207382083820938210382113821238213382143821538216382173821838219382203822138222382233822438225382263822738228382293823038231382323823338234382353823638237382383823938240382413824238243382443824538246382473824838249382503825138252382533825438255382563825738258382593826038261382623826338264382653826638267382683826938270382713827238273382743827538276382773827838279382803828138282382833828438285382863828738288382893829038291382923829338294382953829638297382983829938300383013830238303383043830538306383073830838309383103831138312383133831438315383163831738318383193832038321383223832338324383253832638327383283832938330383313833238333383343833538336383373833838339383403834138342383433834438345383463834738348383493835038351383523835338354383553835638357383583835938360383613836238363383643836538366383673836838369383703837138372383733837438375383763837738378383793838038381383823838338384383853838638387383883838938390383913839238393383943839538396383973839838399384003840138402384033840438405384063840738408384093841038411384123841338414384153841638417384183841938420384213842238423384243842538426384273842838429384303843138432384333843438435384363843738438384393844038441384423844338444384453844638447384483844938450384513845238453384543845538456384573845838459384603846138462384633846438465384663846738468384693847038471384723847338474384753847638477384783847938480384813848238483384843848538486384873848838489384903849138492384933849438495384963849738498384993850038501385023850338504385053850638507385083850938510385113851238513385143851538516385173851838519385203852138522385233852438525385263852738528385293853038531385323853338534385353853638537385383853938540385413854238543385443854538546385473854838549385503855138552385533855438555385563855738558385593856038561385623856338564385653856638567385683856938570385713857238573385743857538576385773857838579385803858138582385833858438585385863858738588385893859038591385923859338594385953859638597385983859938600386013860238603386043860538606386073860838609386103861138612386133861438615386163861738618386193862038621386223862338624386253862638627386283862938630386313863238633386343863538636386373863838639386403864138642386433864438645386463864738648386493865038651386523865338654386553865638657386583865938660386613866238663386643866538666386673866838669386703867138672386733867438675386763867738678386793868038681386823868338684386853868638687386883868938690386913869238693386943869538696386973869838699387003870138702387033870438705387063870738708387093871038711387123871338714387153871638717387183871938720387213872238723387243872538726387273872838729387303873138732387333873438735387363873738738387393874038741387423874338744387453874638747387483874938750387513875238753387543875538756387573875838759387603876138762387633876438765387663876738768387693877038771387723877338774387753877638777387783877938780387813878238783387843878538786387873878838789387903879138792387933879438795387963879738798387993880038801388023880338804388053880638807388083880938810388113881238813388143881538816388173881838819388203882138822388233882438825388263882738828388293883038831388323883338834388353883638837388383883938840388413884238843388443884538846388473884838849388503885138852388533885438855388563885738858388593886038861388623886338864388653886638867388683886938870388713887238873388743887538876388773887838879388803888138882388833888438885388863888738888388893889038891388923889338894388953889638897388983889938900389013890238903389043890538906389073890838909389103891138912389133891438915389163891738918389193892038921389223892338924389253892638927389283892938930389313893238933389343893538936389373893838939389403894138942389433894438945389463894738948389493895038951389523895338954389553895638957389583895938960389613896238963389643896538966389673896838969389703897138972389733897438975389763897738978389793898038981389823898338984389853898638987389883898938990389913899238993389943899538996389973899838999390003900139002390033900439005390063900739008390093901039011390123901339014390153901639017390183901939020390213902239023390243902539026390273902839029390303903139032390333903439035390363903739038390393904039041390423904339044390453904639047390483904939050390513905239053390543905539056390573905839059390603906139062390633906439065390663906739068390693907039071390723907339074390753907639077390783907939080390813908239083390843908539086390873908839089390903909139092390933909439095390963909739098390993910039101391023910339104391053910639107391083910939110391113911239113391143911539116391173911839119391203912139122391233912439125391263912739128391293913039131391323913339134391353913639137391383913939140391413914239143391443914539146391473914839149391503915139152391533915439155391563915739158391593916039161391623916339164391653916639167391683916939170391713917239173391743917539176391773917839179391803918139182391833918439185391863918739188391893919039191391923919339194391953919639197391983919939200392013920239203392043920539206392073920839209392103921139212392133921439215392163921739218392193922039221392223922339224392253922639227392283922939230392313923239233392343923539236392373923839239392403924139242392433924439245392463924739248392493925039251392523925339254392553925639257392583925939260392613926239263392643926539266392673926839269392703927139272392733927439275392763927739278392793928039281392823928339284392853928639287392883928939290392913929239293392943929539296392973929839299393003930139302393033930439305393063930739308393093931039311393123931339314393153931639317393183931939320393213932239323393243932539326393273932839329393303933139332393333933439335393363933739338393393934039341393423934339344393453934639347393483934939350393513935239353393543935539356393573935839359393603936139362393633936439365393663936739368393693937039371393723937339374393753937639377393783937939380393813938239383393843938539386393873938839389393903939139392393933939439395393963939739398393993940039401394023940339404394053940639407394083940939410394113941239413394143941539416394173941839419394203942139422394233942439425394263942739428394293943039431394323943339434394353943639437394383943939440394413944239443394443944539446394473944839449394503945139452394533945439455394563945739458394593946039461394623946339464394653946639467394683946939470394713947239473394743947539476394773947839479394803948139482394833948439485394863948739488394893949039491394923949339494394953949639497394983949939500395013950239503395043950539506395073950839509395103951139512395133951439515395163951739518395193952039521395223952339524395253952639527395283952939530395313953239533395343953539536395373953839539395403954139542395433954439545395463954739548395493955039551395523955339554395553955639557395583955939560395613956239563395643956539566395673956839569395703957139572395733957439575395763957739578395793958039581395823958339584395853958639587395883958939590395913959239593395943959539596395973959839599396003960139602396033960439605396063960739608396093961039611396123961339614396153961639617396183961939620396213962239623396243962539626396273962839629396303963139632396333963439635396363963739638396393964039641396423964339644396453964639647396483964939650396513965239653396543965539656396573965839659396603966139662396633966439665396663966739668396693967039671396723967339674396753967639677396783967939680396813968239683396843968539686396873968839689396903969139692396933969439695396963969739698396993970039701397023970339704397053970639707397083970939710397113971239713397143971539716397173971839719397203972139722397233972439725397263972739728397293973039731397323973339734397353973639737397383973939740397413974239743397443974539746397473974839749397503975139752397533975439755397563975739758397593976039761397623976339764397653976639767397683976939770397713977239773397743977539776397773977839779397803978139782397833978439785397863978739788397893979039791397923979339794397953979639797397983979939800398013980239803398043980539806398073980839809398103981139812398133981439815398163981739818398193982039821398223982339824398253982639827398283982939830398313983239833398343983539836398373983839839398403984139842398433984439845398463984739848398493985039851398523985339854398553985639857398583985939860398613986239863398643986539866398673986839869398703987139872398733987439875398763987739878398793988039881398823988339884398853988639887398883988939890398913989239893398943989539896398973989839899399003990139902399033990439905399063990739908399093991039911399123991339914399153991639917399183991939920399213992239923399243992539926399273992839929399303993139932399333993439935399363993739938399393994039941399423994339944399453994639947399483994939950399513995239953399543995539956399573995839959399603996139962399633996439965399663996739968399693997039971399723997339974399753997639977399783997939980399813998239983399843998539986399873998839989399903999139992399933999439995399963999739998399994000040001400024000340004400054000640007400084000940010400114001240013400144001540016400174001840019400204002140022400234002440025400264002740028400294003040031400324003340034400354003640037400384003940040400414004240043400444004540046400474004840049400504005140052400534005440055400564005740058400594006040061400624006340064400654006640067400684006940070400714007240073400744007540076400774007840079400804008140082400834008440085400864008740088400894009040091400924009340094400954009640097400984009940100401014010240103401044010540106401074010840109401104011140112401134011440115401164011740118401194012040121401224012340124401254012640127401284012940130401314013240133401344013540136401374013840139401404014140142401434014440145401464014740148401494015040151401524015340154401554015640157401584015940160401614016240163401644016540166401674016840169401704017140172401734017440175401764017740178401794018040181401824018340184401854018640187401884018940190401914019240193401944019540196401974019840199402004020140202402034020440205402064020740208402094021040211402124021340214402154021640217402184021940220402214022240223402244022540226402274022840229402304023140232402334023440235402364023740238402394024040241402424024340244402454024640247402484024940250402514025240253402544025540256402574025840259402604026140262402634026440265402664026740268402694027040271402724027340274402754027640277402784027940280402814028240283402844028540286402874028840289402904029140292402934029440295402964029740298402994030040301403024030340304403054030640307403084030940310403114031240313403144031540316403174031840319403204032140322403234032440325403264032740328403294033040331403324033340334403354033640337403384033940340403414034240343403444034540346403474034840349403504035140352403534035440355403564035740358403594036040361403624036340364403654036640367403684036940370403714037240373403744037540376403774037840379403804038140382403834038440385403864038740388403894039040391403924039340394403954039640397403984039940400404014040240403404044040540406404074040840409404104041140412404134041440415404164041740418404194042040421404224042340424404254042640427404284042940430404314043240433404344043540436404374043840439404404044140442404434044440445404464044740448404494045040451404524045340454404554045640457404584045940460404614046240463404644046540466404674046840469404704047140472404734047440475404764047740478404794048040481404824048340484404854048640487404884048940490404914049240493404944049540496404974049840499405004050140502405034050440505405064050740508405094051040511405124051340514405154051640517405184051940520405214052240523405244052540526405274052840529405304053140532405334053440535405364053740538405394054040541405424054340544405454054640547405484054940550405514055240553405544055540556405574055840559405604056140562405634056440565405664056740568405694057040571405724057340574405754057640577405784057940580405814058240583405844058540586405874058840589405904059140592405934059440595405964059740598405994060040601406024060340604406054060640607406084060940610406114061240613406144061540616406174061840619406204062140622406234062440625406264062740628406294063040631406324063340634406354063640637406384063940640406414064240643406444064540646406474064840649406504065140652406534065440655406564065740658406594066040661406624066340664406654066640667406684066940670406714067240673406744067540676406774067840679406804068140682406834068440685406864068740688406894069040691406924069340694406954069640697406984069940700407014070240703407044070540706407074070840709407104071140712407134071440715407164071740718407194072040721407224072340724407254072640727407284072940730407314073240733407344073540736407374073840739407404074140742407434074440745407464074740748407494075040751407524075340754407554075640757407584075940760407614076240763407644076540766407674076840769407704077140772407734077440775407764077740778407794078040781407824078340784407854078640787407884078940790407914079240793407944079540796407974079840799408004080140802408034080440805408064080740808408094081040811408124081340814408154081640817408184081940820408214082240823408244082540826408274082840829408304083140832408334083440835408364083740838408394084040841408424084340844408454084640847408484084940850408514085240853408544085540856408574085840859408604086140862408634086440865408664086740868408694087040871408724087340874408754087640877408784087940880408814088240883408844088540886408874088840889408904089140892408934089440895408964089740898408994090040901409024090340904409054090640907409084090940910409114091240913409144091540916409174091840919409204092140922409234092440925409264092740928409294093040931409324093340934409354093640937409384093940940409414094240943409444094540946409474094840949409504095140952409534095440955409564095740958409594096040961409624096340964409654096640967409684096940970409714097240973409744097540976409774097840979409804098140982409834098440985409864098740988409894099040991409924099340994409954099640997409984099941000410014100241003410044100541006410074100841009410104101141012410134101441015410164101741018410194102041021410224102341024410254102641027410284102941030410314103241033410344103541036410374103841039410404104141042410434104441045410464104741048410494105041051410524105341054410554105641057410584105941060410614106241063410644106541066410674106841069410704107141072410734107441075410764107741078410794108041081410824108341084410854108641087410884108941090410914109241093410944109541096410974109841099411004110141102411034110441105411064110741108411094111041111411124111341114411154111641117411184111941120411214112241123411244112541126411274112841129411304113141132411334113441135411364113741138411394114041141411424114341144411454114641147411484114941150411514115241153411544115541156411574115841159411604116141162411634116441165411664116741168411694117041171411724117341174411754117641177411784117941180411814118241183411844118541186411874118841189411904119141192411934119441195411964119741198411994120041201412024120341204412054120641207412084120941210412114121241213412144121541216412174121841219412204122141222412234122441225412264122741228412294123041231412324123341234412354123641237412384123941240412414124241243412444124541246412474124841249412504125141252412534125441255412564125741258412594126041261412624126341264412654126641267412684126941270412714127241273412744127541276412774127841279412804128141282412834128441285412864128741288412894129041291412924129341294412954129641297412984129941300413014130241303413044130541306413074130841309413104131141312413134131441315413164131741318413194132041321413224132341324413254132641327413284132941330413314133241333413344133541336413374133841339413404134141342413434134441345413464134741348413494135041351413524135341354413554135641357413584135941360413614136241363413644136541366413674136841369413704137141372413734137441375413764137741378413794138041381413824138341384413854138641387413884138941390413914139241393413944139541396413974139841399414004140141402414034140441405414064140741408414094141041411414124141341414414154141641417414184141941420414214142241423414244142541426414274142841429414304143141432414334143441435414364143741438414394144041441414424144341444414454144641447414484144941450414514145241453414544145541456414574145841459414604146141462414634146441465414664146741468414694147041471414724147341474414754147641477414784147941480414814148241483414844148541486414874148841489414904149141492414934149441495414964149741498414994150041501415024150341504415054150641507415084150941510415114151241513415144151541516415174151841519415204152141522415234152441525415264152741528415294153041531415324153341534415354153641537415384153941540415414154241543415444154541546415474154841549415504155141552415534155441555415564155741558415594156041561415624156341564415654156641567415684156941570415714157241573415744157541576415774157841579415804158141582415834158441585415864158741588415894159041591415924159341594415954159641597415984159941600416014160241603416044160541606416074160841609416104161141612416134161441615416164161741618416194162041621416224162341624416254162641627416284162941630416314163241633416344163541636416374163841639416404164141642416434164441645416464164741648416494165041651416524165341654416554165641657416584165941660416614166241663416644166541666416674166841669416704167141672416734167441675416764167741678416794168041681416824168341684416854168641687416884168941690416914169241693416944169541696416974169841699417004170141702417034170441705417064170741708417094171041711417124171341714417154171641717417184171941720417214172241723417244172541726417274172841729417304173141732417334173441735417364173741738417394174041741417424174341744417454174641747417484174941750417514175241753417544175541756417574175841759417604176141762417634176441765417664176741768417694177041771417724177341774417754177641777417784177941780417814178241783417844178541786417874178841789417904179141792417934179441795417964179741798417994180041801418024180341804418054180641807418084180941810418114181241813418144181541816418174181841819418204182141822418234182441825418264182741828418294183041831418324183341834418354183641837418384183941840418414184241843418444184541846418474184841849418504185141852418534185441855418564185741858418594186041861418624186341864418654186641867418684186941870418714187241873418744187541876418774187841879418804188141882418834188441885418864188741888418894189041891418924189341894418954189641897418984189941900419014190241903419044190541906419074190841909419104191141912419134191441915419164191741918419194192041921419224192341924419254192641927419284192941930419314193241933419344193541936419374193841939419404194141942419434194441945419464194741948419494195041951419524195341954419554195641957419584195941960419614196241963419644196541966419674196841969419704197141972419734197441975419764197741978419794198041981419824198341984419854198641987419884198941990419914199241993419944199541996419974199841999420004200142002420034200442005420064200742008420094201042011420124201342014420154201642017420184201942020420214202242023420244202542026420274202842029420304203142032420334203442035420364203742038420394204042041420424204342044420454204642047420484204942050420514205242053420544205542056420574205842059420604206142062420634206442065420664206742068420694207042071420724207342074420754207642077420784207942080420814208242083420844208542086420874208842089420904209142092420934209442095420964209742098420994210042101421024210342104421054210642107421084210942110421114211242113421144211542116421174211842119421204212142122421234212442125421264212742128421294213042131421324213342134421354213642137421384213942140421414214242143421444214542146421474214842149421504215142152421534215442155421564215742158421594216042161421624216342164421654216642167421684216942170421714217242173421744217542176421774217842179421804218142182421834218442185421864218742188421894219042191421924219342194421954219642197421984219942200422014220242203422044220542206422074220842209422104221142212422134221442215422164221742218422194222042221422224222342224422254222642227422284222942230422314223242233422344223542236422374223842239422404224142242422434224442245422464224742248422494225042251422524225342254422554225642257422584225942260422614226242263422644226542266422674226842269422704227142272422734227442275422764227742278422794228042281422824228342284422854228642287422884228942290422914229242293422944229542296422974229842299423004230142302423034230442305423064230742308423094231042311423124231342314423154231642317423184231942320423214232242323423244232542326423274232842329423304233142332423334233442335423364233742338423394234042341423424234342344423454234642347423484234942350423514235242353423544235542356423574235842359423604236142362423634236442365423664236742368423694237042371423724237342374423754237642377423784237942380423814238242383423844238542386423874238842389423904239142392423934239442395423964239742398423994240042401424024240342404424054240642407424084240942410424114241242413424144241542416424174241842419424204242142422424234242442425424264242742428424294243042431424324243342434424354243642437424384243942440424414244242443424444244542446424474244842449424504245142452424534245442455424564245742458424594246042461424624246342464424654246642467424684246942470424714247242473424744247542476424774247842479424804248142482424834248442485424864248742488424894249042491424924249342494424954249642497424984249942500425014250242503425044250542506425074250842509425104251142512425134251442515425164251742518425194252042521425224252342524425254252642527425284252942530425314253242533425344253542536425374253842539425404254142542425434254442545425464254742548425494255042551425524255342554425554255642557425584255942560425614256242563425644256542566425674256842569425704257142572425734257442575425764257742578425794258042581425824258342584425854258642587425884258942590425914259242593425944259542596425974259842599426004260142602426034260442605426064260742608426094261042611426124261342614426154261642617426184261942620426214262242623426244262542626426274262842629426304263142632426334263442635426364263742638426394264042641426424264342644426454264642647426484264942650426514265242653426544265542656426574265842659426604266142662426634266442665426664266742668426694267042671426724267342674426754267642677426784267942680426814268242683426844268542686426874268842689426904269142692426934269442695426964269742698426994270042701427024270342704427054270642707427084270942710427114271242713427144271542716427174271842719427204272142722427234272442725427264272742728427294273042731427324273342734427354273642737427384273942740427414274242743427444274542746427474274842749427504275142752427534275442755427564275742758427594276042761427624276342764427654276642767427684276942770427714277242773427744277542776427774277842779427804278142782427834278442785427864278742788427894279042791427924279342794427954279642797427984279942800428014280242803428044280542806428074280842809428104281142812428134281442815428164281742818428194282042821428224282342824428254282642827428284282942830428314283242833428344283542836428374283842839428404284142842428434284442845428464284742848428494285042851428524285342854428554285642857428584285942860428614286242863428644286542866428674286842869428704287142872428734287442875428764287742878428794288042881428824288342884428854288642887428884288942890428914289242893428944289542896428974289842899429004290142902429034290442905429064290742908429094291042911429124291342914429154291642917429184291942920429214292242923429244292542926429274292842929429304293142932429334293442935429364293742938429394294042941429424294342944429454294642947429484294942950429514295242953429544295542956429574295842959429604296142962429634296442965429664296742968429694297042971429724297342974429754297642977429784297942980429814298242983429844298542986429874298842989429904299142992429934299442995429964299742998429994300043001430024300343004430054300643007430084300943010430114301243013430144301543016430174301843019430204302143022430234302443025430264302743028430294303043031430324303343034430354303643037430384303943040430414304243043430444304543046430474304843049430504305143052430534305443055430564305743058430594306043061430624306343064430654306643067430684306943070430714307243073430744307543076430774307843079430804308143082430834308443085430864308743088430894309043091430924309343094430954309643097430984309943100431014310243103431044310543106431074310843109431104311143112431134311443115431164311743118431194312043121431224312343124431254312643127431284312943130431314313243133431344313543136431374313843139431404314143142431434314443145431464314743148431494315043151431524315343154431554315643157431584315943160431614316243163431644316543166431674316843169431704317143172431734317443175431764317743178431794318043181431824318343184431854318643187431884318943190431914319243193431944319543196431974319843199432004320143202432034320443205432064320743208432094321043211432124321343214432154321643217432184321943220432214322243223432244322543226432274322843229432304323143232432334323443235432364323743238432394324043241432424324343244432454324643247432484324943250432514325243253432544325543256432574325843259432604326143262432634326443265432664326743268432694327043271432724327343274432754327643277432784327943280432814328243283432844328543286432874328843289432904329143292432934329443295432964329743298432994330043301433024330343304433054330643307433084330943310433114331243313433144331543316433174331843319433204332143322433234332443325433264332743328433294333043331433324333343334433354333643337433384333943340433414334243343433444334543346433474334843349433504335143352433534335443355433564335743358433594336043361433624336343364433654336643367433684336943370433714337243373433744337543376433774337843379433804338143382433834338443385433864338743388433894339043391433924339343394433954339643397433984339943400434014340243403434044340543406434074340843409434104341143412434134341443415434164341743418434194342043421434224342343424434254342643427434284342943430434314343243433434344343543436434374343843439434404344143442434434344443445434464344743448434494345043451434524345343454434554345643457434584345943460434614346243463434644346543466434674346843469434704347143472434734347443475434764347743478434794348043481434824348343484434854348643487434884348943490434914349243493434944349543496434974349843499435004350143502435034350443505435064350743508435094351043511435124351343514435154351643517435184351943520435214352243523435244352543526435274352843529435304353143532435334353443535435364353743538435394354043541435424354343544435454354643547435484354943550435514355243553435544355543556435574355843559435604356143562435634356443565435664356743568435694357043571435724357343574435754357643577435784357943580435814358243583435844358543586435874358843589435904359143592435934359443595435964359743598435994360043601436024360343604436054360643607436084360943610436114361243613436144361543616436174361843619436204362143622436234362443625436264362743628436294363043631436324363343634436354363643637436384363943640436414364243643436444364543646436474364843649436504365143652436534365443655436564365743658436594366043661436624366343664436654366643667436684366943670436714367243673436744367543676436774367843679436804368143682436834368443685436864368743688436894369043691436924369343694436954369643697436984369943700437014370243703437044370543706437074370843709437104371143712437134371443715437164371743718437194372043721437224372343724437254372643727437284372943730437314373243733437344373543736437374373843739437404374143742437434374443745437464374743748437494375043751437524375343754437554375643757437584375943760437614376243763437644376543766437674376843769437704377143772437734377443775437764377743778437794378043781437824378343784437854378643787437884378943790437914379243793437944379543796437974379843799438004380143802438034380443805438064380743808438094381043811438124381343814438154381643817438184381943820438214382243823438244382543826438274382843829438304383143832438334383443835438364383743838438394384043841438424384343844438454384643847438484384943850438514385243853438544385543856438574385843859438604386143862438634386443865438664386743868438694387043871438724387343874438754387643877438784387943880438814388243883438844388543886438874388843889438904389143892438934389443895438964389743898438994390043901439024390343904439054390643907439084390943910439114391243913439144391543916439174391843919439204392143922439234392443925439264392743928439294393043931439324393343934439354393643937439384393943940439414394243943439444394543946439474394843949439504395143952439534395443955439564395743958439594396043961439624396343964439654396643967439684396943970439714397243973439744397543976439774397843979439804398143982439834398443985439864398743988439894399043991439924399343994439954399643997439984399944000440014400244003440044400544006440074400844009440104401144012440134401444015440164401744018440194402044021440224402344024440254402644027440284402944030440314403244033440344403544036440374403844039440404404144042440434404444045440464404744048440494405044051440524405344054440554405644057440584405944060440614406244063440644406544066440674406844069440704407144072440734407444075440764407744078440794408044081440824408344084440854408644087440884408944090440914409244093440944409544096440974409844099441004410144102441034410444105441064410744108441094411044111441124411344114441154411644117441184411944120441214412244123441244412544126441274412844129441304413144132441334413444135441364413744138441394414044141441424414344144441454414644147441484414944150441514415244153441544415544156441574415844159441604416144162441634416444165441664416744168441694417044171441724417344174441754417644177441784417944180441814418244183441844418544186441874418844189441904419144192441934419444195441964419744198441994420044201442024420344204442054420644207442084420944210442114421244213442144421544216442174421844219442204422144222442234422444225442264422744228442294423044231442324423344234442354423644237442384423944240442414424244243442444424544246442474424844249442504425144252442534425444255442564425744258442594426044261442624426344264442654426644267442684426944270442714427244273442744427544276442774427844279442804428144282442834428444285442864428744288442894429044291442924429344294442954429644297442984429944300443014430244303443044430544306443074430844309443104431144312443134431444315443164431744318443194432044321443224432344324443254432644327443284432944330443314433244333443344433544336443374433844339443404434144342443434434444345443464434744348443494435044351443524435344354443554435644357443584435944360443614436244363443644436544366443674436844369443704437144372443734437444375443764437744378443794438044381443824438344384443854438644387443884438944390443914439244393443944439544396443974439844399444004440144402444034440444405444064440744408444094441044411444124441344414444154441644417444184441944420444214442244423444244442544426444274442844429444304443144432444334443444435444364443744438444394444044441444424444344444444454444644447444484444944450444514445244453444544445544456444574445844459444604446144462444634446444465444664446744468444694447044471444724447344474444754447644477444784447944480444814448244483444844448544486444874448844489444904449144492444934449444495444964449744498444994450044501445024450344504445054450644507445084450944510445114451244513445144451544516445174451844519445204452144522445234452444525445264452744528445294453044531445324453344534445354453644537445384453944540445414454244543445444454544546445474454844549445504455144552445534455444555445564455744558445594456044561445624456344564445654456644567445684456944570445714457244573445744457544576445774457844579445804458144582445834458444585445864458744588445894459044591445924459344594445954459644597445984459944600446014460244603446044460544606446074460844609446104461144612446134461444615446164461744618446194462044621446224462344624446254462644627446284462944630446314463244633446344463544636446374463844639446404464144642446434464444645446464464744648446494465044651446524465344654446554465644657446584465944660446614466244663446644466544666446674466844669446704467144672446734467444675446764467744678446794468044681446824468344684446854468644687446884468944690446914469244693446944469544696446974469844699447004470144702447034470444705447064470744708447094471044711447124471344714447154471644717447184471944720447214472244723447244472544726447274472844729447304473144732447334473444735447364473744738447394474044741447424474344744447454474644747447484474944750447514475244753447544475544756447574475844759447604476144762447634476444765447664476744768447694477044771447724477344774447754477644777447784477944780447814478244783447844478544786447874478844789447904479144792447934479444795447964479744798447994480044801448024480344804448054480644807448084480944810448114481244813448144481544816448174481844819448204482144822448234482444825448264482744828448294483044831448324483344834448354483644837448384483944840448414484244843448444484544846448474484844849448504485144852448534485444855448564485744858448594486044861448624486344864448654486644867448684486944870448714487244873448744487544876448774487844879448804488144882448834488444885448864488744888448894489044891448924489344894448954489644897448984489944900449014490244903449044490544906449074490844909449104491144912449134491444915449164491744918449194492044921449224492344924449254492644927449284492944930449314493244933449344493544936449374493844939449404494144942449434494444945449464494744948449494495044951449524495344954449554495644957449584495944960449614496244963449644496544966449674496844969449704497144972449734497444975449764497744978449794498044981449824498344984449854498644987449884498944990449914499244993449944499544996449974499844999450004500145002450034500445005450064500745008450094501045011450124501345014450154501645017450184501945020450214502245023450244502545026450274502845029450304503145032450334503445035450364503745038450394504045041450424504345044450454504645047450484504945050450514505245053450544505545056450574505845059450604506145062450634506445065450664506745068450694507045071450724507345074450754507645077450784507945080450814508245083450844508545086450874508845089450904509145092450934509445095450964509745098450994510045101451024510345104451054510645107451084510945110451114511245113451144511545116451174511845119451204512145122451234512445125451264512745128451294513045131451324513345134451354513645137451384513945140451414514245143451444514545146451474514845149451504515145152451534515445155451564515745158451594516045161451624516345164451654516645167451684516945170451714517245173451744517545176451774517845179451804518145182451834518445185451864518745188451894519045191451924519345194451954519645197451984519945200452014520245203452044520545206452074520845209452104521145212452134521445215452164521745218452194522045221452224522345224452254522645227452284522945230452314523245233452344523545236452374523845239452404524145242452434524445245452464524745248452494525045251452524525345254452554525645257452584525945260452614526245263452644526545266452674526845269452704527145272452734527445275452764527745278452794528045281452824528345284452854528645287452884528945290452914529245293452944529545296452974529845299453004530145302453034530445305453064530745308453094531045311453124531345314453154531645317453184531945320453214532245323453244532545326453274532845329453304533145332453334533445335453364533745338453394534045341453424534345344453454534645347453484534945350453514535245353453544535545356453574535845359453604536145362453634536445365453664536745368453694537045371453724537345374453754537645377453784537945380453814538245383453844538545386453874538845389453904539145392453934539445395453964539745398453994540045401454024540345404454054540645407454084540945410454114541245413454144541545416454174541845419454204542145422454234542445425454264542745428454294543045431454324543345434454354543645437454384543945440454414544245443454444544545446454474544845449454504545145452454534545445455454564545745458454594546045461454624546345464454654546645467454684546945470454714547245473454744547545476454774547845479454804548145482454834548445485454864548745488454894549045491454924549345494454954549645497454984549945500455014550245503455044550545506455074550845509455104551145512455134551445515455164551745518455194552045521455224552345524455254552645527455284552945530455314553245533455344553545536455374553845539455404554145542455434554445545455464554745548455494555045551455524555345554455554555645557455584555945560455614556245563455644556545566455674556845569455704557145572455734557445575455764557745578455794558045581455824558345584455854558645587455884558945590455914559245593455944559545596455974559845599456004560145602456034560445605456064560745608456094561045611456124561345614456154561645617456184561945620456214562245623456244562545626456274562845629456304563145632456334563445635456364563745638456394564045641456424564345644456454564645647456484564945650456514565245653456544565545656456574565845659456604566145662456634566445665456664566745668456694567045671456724567345674456754567645677456784567945680456814568245683456844568545686456874568845689456904569145692456934569445695456964569745698456994570045701457024570345704457054570645707457084570945710457114571245713457144571545716457174571845719457204572145722457234572445725457264572745728457294573045731457324573345734457354573645737457384573945740457414574245743457444574545746457474574845749457504575145752457534575445755457564575745758457594576045761457624576345764457654576645767457684576945770457714577245773457744577545776457774577845779457804578145782457834578445785457864578745788457894579045791457924579345794457954579645797457984579945800458014580245803458044580545806458074580845809458104581145812458134581445815458164581745818458194582045821458224582345824458254582645827458284582945830458314583245833458344583545836458374583845839458404584145842458434584445845458464584745848458494585045851458524585345854458554585645857458584585945860458614586245863458644586545866458674586845869458704587145872458734587445875458764587745878458794588045881458824588345884458854588645887458884588945890458914589245893458944589545896458974589845899459004590145902459034590445905459064590745908459094591045911459124591345914459154591645917459184591945920459214592245923459244592545926459274592845929459304593145932459334593445935459364593745938459394594045941459424594345944459454594645947459484594945950459514595245953459544595545956459574595845959459604596145962459634596445965459664596745968459694597045971459724597345974459754597645977459784597945980459814598245983459844598545986459874598845989459904599145992459934599445995459964599745998459994600046001460024600346004460054600646007460084600946010460114601246013460144601546016460174601846019460204602146022460234602446025460264602746028460294603046031460324603346034460354603646037460384603946040460414604246043460444604546046460474604846049460504605146052460534605446055460564605746058460594606046061460624606346064460654606646067460684606946070460714607246073460744607546076460774607846079460804608146082460834608446085460864608746088460894609046091460924609346094460954609646097460984609946100461014610246103461044610546106461074610846109461104611146112461134611446115461164611746118461194612046121461224612346124461254612646127461284612946130461314613246133461344613546136461374613846139461404614146142461434614446145461464614746148461494615046151461524615346154461554615646157461584615946160461614616246163461644616546166461674616846169461704617146172461734617446175461764617746178461794618046181461824618346184461854618646187461884618946190461914619246193461944619546196461974619846199462004620146202462034620446205462064620746208462094621046211462124621346214462154621646217462184621946220462214622246223462244622546226462274622846229462304623146232462334623446235462364623746238462394624046241462424624346244462454624646247462484624946250462514625246253462544625546256462574625846259462604626146262462634626446265462664626746268462694627046271462724627346274462754627646277462784627946280462814628246283462844628546286462874628846289462904629146292462934629446295462964629746298462994630046301463024630346304463054630646307463084630946310463114631246313463144631546316463174631846319463204632146322463234632446325463264632746328463294633046331463324633346334463354633646337463384633946340463414634246343463444634546346463474634846349463504635146352463534635446355463564635746358463594636046361463624636346364463654636646367463684636946370463714637246373463744637546376463774637846379463804638146382463834638446385463864638746388463894639046391463924639346394463954639646397463984639946400464014640246403464044640546406464074640846409464104641146412464134641446415464164641746418464194642046421464224642346424464254642646427464284642946430464314643246433464344643546436464374643846439464404644146442464434644446445464464644746448464494645046451464524645346454464554645646457464584645946460464614646246463464644646546466464674646846469464704647146472464734647446475464764647746478464794648046481464824648346484464854648646487464884648946490464914649246493464944649546496464974649846499465004650146502465034650446505465064650746508465094651046511465124651346514465154651646517465184651946520465214652246523465244652546526465274652846529465304653146532465334653446535465364653746538465394654046541465424654346544465454654646547465484654946550465514655246553465544655546556465574655846559465604656146562465634656446565465664656746568465694657046571465724657346574465754657646577465784657946580465814658246583465844658546586465874658846589465904659146592465934659446595465964659746598465994660046601466024660346604466054660646607466084660946610466114661246613466144661546616466174661846619466204662146622466234662446625466264662746628466294663046631466324663346634466354663646637466384663946640466414664246643466444664546646466474664846649466504665146652466534665446655466564665746658466594666046661466624666346664466654666646667466684666946670466714667246673466744667546676466774667846679466804668146682466834668446685466864668746688466894669046691466924669346694466954669646697466984669946700467014670246703467044670546706467074670846709467104671146712467134671446715467164671746718467194672046721467224672346724467254672646727467284672946730467314673246733467344673546736467374673846739467404674146742467434674446745467464674746748467494675046751467524675346754467554675646757467584675946760467614676246763467644676546766467674676846769467704677146772467734677446775467764677746778467794678046781467824678346784467854678646787467884678946790467914679246793467944679546796467974679846799468004680146802468034680446805468064680746808468094681046811468124681346814468154681646817468184681946820468214682246823468244682546826468274682846829468304683146832468334683446835468364683746838468394684046841468424684346844468454684646847468484684946850468514685246853468544685546856468574685846859468604686146862468634686446865468664686746868468694687046871468724687346874468754687646877468784687946880468814688246883468844688546886468874688846889468904689146892468934689446895468964689746898468994690046901469024690346904469054690646907469084690946910469114691246913469144691546916469174691846919469204692146922469234692446925469264692746928469294693046931469324693346934469354693646937469384693946940469414694246943469444694546946469474694846949469504695146952469534695446955469564695746958469594696046961469624696346964469654696646967469684696946970469714697246973469744697546976469774697846979469804698146982469834698446985469864698746988469894699046991469924699346994469954699646997469984699947000470014700247003470044700547006470074700847009470104701147012470134701447015470164701747018470194702047021470224702347024470254702647027470284702947030470314703247033470344703547036470374703847039470404704147042470434704447045470464704747048470494705047051470524705347054470554705647057470584705947060470614706247063470644706547066470674706847069470704707147072470734707447075470764707747078470794708047081470824708347084470854708647087470884708947090470914709247093470944709547096470974709847099471004710147102471034710447105471064710747108471094711047111471124711347114471154711647117471184711947120471214712247123471244712547126471274712847129471304713147132471334713447135471364713747138471394714047141471424714347144471454714647147471484714947150471514715247153471544715547156471574715847159471604716147162471634716447165471664716747168471694717047171471724717347174471754717647177471784717947180471814718247183471844718547186471874718847189471904719147192471934719447195471964719747198471994720047201472024720347204472054720647207472084720947210472114721247213472144721547216472174721847219472204722147222472234722447225472264722747228472294723047231472324723347234472354723647237472384723947240472414724247243472444724547246472474724847249472504725147252472534725447255472564725747258472594726047261472624726347264472654726647267472684726947270472714727247273472744727547276472774727847279472804728147282472834728447285472864728747288472894729047291472924729347294472954729647297472984729947300473014730247303473044730547306473074730847309473104731147312473134731447315473164731747318473194732047321473224732347324473254732647327473284732947330473314733247333473344733547336473374733847339473404734147342473434734447345473464734747348473494735047351473524735347354473554735647357473584735947360473614736247363473644736547366473674736847369473704737147372473734737447375473764737747378473794738047381473824738347384473854738647387473884738947390473914739247393473944739547396473974739847399474004740147402474034740447405474064740747408474094741047411474124741347414474154741647417474184741947420474214742247423474244742547426474274742847429474304743147432474334743447435474364743747438474394744047441474424744347444474454744647447474484744947450474514745247453474544745547456474574745847459474604746147462474634746447465474664746747468474694747047471474724747347474474754747647477474784747947480474814748247483474844748547486474874748847489474904749147492474934749447495474964749747498474994750047501475024750347504475054750647507475084750947510475114751247513475144751547516475174751847519475204752147522475234752447525475264752747528475294753047531475324753347534475354753647537475384753947540475414754247543475444754547546475474754847549475504755147552475534755447555475564755747558475594756047561475624756347564475654756647567475684756947570475714757247573475744757547576475774757847579475804758147582475834758447585475864758747588475894759047591475924759347594475954759647597475984759947600476014760247603476044760547606476074760847609476104761147612476134761447615476164761747618476194762047621476224762347624476254762647627476284762947630476314763247633476344763547636476374763847639476404764147642476434764447645476464764747648476494765047651476524765347654476554765647657476584765947660476614766247663476644766547666476674766847669476704767147672476734767447675476764767747678476794768047681476824768347684476854768647687476884768947690476914769247693476944769547696476974769847699477004770147702477034770447705477064770747708477094771047711477124771347714477154771647717477184771947720477214772247723477244772547726477274772847729477304773147732477334773447735477364773747738477394774047741477424774347744477454774647747477484774947750477514775247753477544775547756477574775847759477604776147762477634776447765477664776747768477694777047771477724777347774477754777647777477784777947780477814778247783477844778547786477874778847789477904779147792477934779447795477964779747798477994780047801478024780347804478054780647807478084780947810478114781247813478144781547816478174781847819478204782147822478234782447825478264782747828478294783047831478324783347834478354783647837478384783947840478414784247843478444784547846478474784847849478504785147852478534785447855478564785747858478594786047861478624786347864478654786647867478684786947870478714787247873478744787547876478774787847879478804788147882478834788447885478864788747888478894789047891478924789347894478954789647897478984789947900479014790247903479044790547906479074790847909479104791147912479134791447915479164791747918479194792047921479224792347924479254792647927479284792947930479314793247933479344793547936479374793847939479404794147942479434794447945479464794747948479494795047951479524795347954479554795647957479584795947960479614796247963479644796547966479674796847969479704797147972479734797447975479764797747978479794798047981479824798347984479854798647987479884798947990479914799247993479944799547996479974799847999480004800148002480034800448005480064800748008480094801048011480124801348014480154801648017480184801948020480214802248023480244802548026480274802848029480304803148032480334803448035480364803748038480394804048041480424804348044480454804648047480484804948050480514805248053480544805548056480574805848059480604806148062480634806448065480664806748068480694807048071480724807348074480754807648077480784807948080480814808248083480844808548086480874808848089480904809148092480934809448095480964809748098480994810048101481024810348104481054810648107481084810948110481114811248113481144811548116481174811848119481204812148122481234812448125481264812748128481294813048131481324813348134481354813648137481384813948140481414814248143481444814548146481474814848149481504815148152481534815448155481564815748158481594816048161481624816348164481654816648167481684816948170481714817248173481744817548176481774817848179481804818148182481834818448185481864818748188481894819048191481924819348194481954819648197481984819948200482014820248203482044820548206482074820848209482104821148212482134821448215482164821748218482194822048221482224822348224482254822648227482284822948230482314823248233482344823548236482374823848239482404824148242482434824448245482464824748248482494825048251482524825348254482554825648257482584825948260482614826248263482644826548266482674826848269482704827148272482734827448275482764827748278482794828048281482824828348284482854828648287482884828948290482914829248293482944829548296482974829848299483004830148302483034830448305483064830748308483094831048311483124831348314483154831648317483184831948320483214832248323483244832548326483274832848329483304833148332483334833448335483364833748338483394834048341483424834348344483454834648347483484834948350483514835248353483544835548356483574835848359483604836148362483634836448365483664836748368483694837048371483724837348374483754837648377483784837948380483814838248383483844838548386483874838848389483904839148392483934839448395483964839748398483994840048401484024840348404484054840648407484084840948410484114841248413484144841548416484174841848419484204842148422484234842448425484264842748428484294843048431484324843348434484354843648437484384843948440484414844248443484444844548446484474844848449484504845148452484534845448455484564845748458484594846048461484624846348464484654846648467484684846948470484714847248473484744847548476484774847848479484804848148482484834848448485484864848748488484894849048491484924849348494484954849648497484984849948500485014850248503485044850548506485074850848509485104851148512485134851448515485164851748518485194852048521485224852348524485254852648527485284852948530485314853248533485344853548536485374853848539485404854148542485434854448545485464854748548485494855048551485524855348554485554855648557485584855948560485614856248563485644856548566485674856848569485704857148572485734857448575485764857748578485794858048581485824858348584485854858648587485884858948590485914859248593485944859548596485974859848599486004860148602486034860448605486064860748608486094861048611486124861348614486154861648617486184861948620486214862248623486244862548626486274862848629486304863148632486334863448635486364863748638486394864048641486424864348644486454864648647486484864948650486514865248653486544865548656486574865848659486604866148662486634866448665486664866748668486694867048671486724867348674486754867648677486784867948680486814868248683486844868548686486874868848689486904869148692486934869448695486964869748698486994870048701487024870348704487054870648707487084870948710487114871248713487144871548716487174871848719487204872148722487234872448725487264872748728487294873048731487324873348734487354873648737487384873948740487414874248743487444874548746487474874848749487504875148752487534875448755487564875748758487594876048761487624876348764487654876648767487684876948770487714877248773487744877548776487774877848779487804878148782487834878448785487864878748788487894879048791487924879348794487954879648797487984879948800488014880248803488044880548806488074880848809488104881148812488134881448815488164881748818488194882048821488224882348824488254882648827488284882948830488314883248833488344883548836488374883848839488404884148842488434884448845488464884748848488494885048851488524885348854488554885648857488584885948860488614886248863488644886548866488674886848869488704887148872488734887448875488764887748878488794888048881488824888348884488854888648887488884888948890488914889248893488944889548896488974889848899489004890148902489034890448905489064890748908489094891048911489124891348914489154891648917489184891948920489214892248923489244892548926489274892848929489304893148932489334893448935489364893748938489394894048941489424894348944489454894648947489484894948950489514895248953489544895548956489574895848959489604896148962489634896448965489664896748968489694897048971489724897348974489754897648977489784897948980489814898248983489844898548986489874898848989489904899148992489934899448995489964899748998489994900049001490024900349004490054900649007490084900949010490114901249013490144901549016490174901849019490204902149022490234902449025490264902749028490294903049031490324903349034490354903649037490384903949040490414904249043490444904549046490474904849049490504905149052490534905449055490564905749058490594906049061490624906349064490654906649067490684906949070490714907249073490744907549076490774907849079490804908149082490834908449085490864908749088490894909049091490924909349094490954909649097490984909949100491014910249103491044910549106491074910849109491104911149112491134911449115491164911749118491194912049121491224912349124491254912649127491284912949130491314913249133491344913549136491374913849139491404914149142491434914449145491464914749148491494915049151491524915349154491554915649157491584915949160491614916249163491644916549166491674916849169491704917149172491734917449175491764917749178491794918049181491824918349184491854918649187491884918949190491914919249193491944919549196491974919849199492004920149202492034920449205492064920749208492094921049211492124921349214492154921649217492184921949220492214922249223492244922549226492274922849229492304923149232492334923449235492364923749238492394924049241492424924349244492454924649247492484924949250492514925249253492544925549256492574925849259492604926149262492634926449265492664926749268492694927049271492724927349274492754927649277492784927949280492814928249283492844928549286492874928849289492904929149292492934929449295492964929749298492994930049301493024930349304493054930649307493084930949310493114931249313493144931549316493174931849319493204932149322493234932449325493264932749328493294933049331493324933349334493354933649337493384933949340493414934249343493444934549346493474934849349493504935149352493534935449355493564935749358493594936049361493624936349364493654936649367493684936949370493714937249373493744937549376493774937849379493804938149382493834938449385493864938749388493894939049391493924939349394493954939649397493984939949400494014940249403494044940549406494074940849409494104941149412494134941449415494164941749418494194942049421494224942349424494254942649427494284942949430494314943249433494344943549436494374943849439494404944149442494434944449445494464944749448494494945049451494524945349454494554945649457494584945949460494614946249463494644946549466494674946849469494704947149472494734947449475494764947749478494794948049481494824948349484494854948649487494884948949490494914949249493494944949549496494974949849499495004950149502495034950449505495064950749508495094951049511495124951349514495154951649517495184951949520495214952249523495244952549526495274952849529495304953149532495334953449535495364953749538495394954049541495424954349544495454954649547495484954949550495514955249553495544955549556495574955849559495604956149562495634956449565495664956749568495694957049571495724957349574495754957649577495784957949580495814958249583495844958549586495874958849589495904959149592495934959449595495964959749598495994960049601496024960349604496054960649607496084960949610496114961249613496144961549616496174961849619496204962149622496234962449625496264962749628496294963049631496324963349634496354963649637496384963949640496414964249643496444964549646496474964849649496504965149652496534965449655496564965749658496594966049661496624966349664496654966649667496684966949670496714967249673496744967549676496774967849679496804968149682496834968449685496864968749688496894969049691496924969349694496954969649697496984969949700497014970249703497044970549706497074970849709497104971149712497134971449715497164971749718497194972049721497224972349724497254972649727497284972949730497314973249733497344973549736497374973849739497404974149742497434974449745497464974749748497494975049751497524975349754497554975649757497584975949760497614976249763497644976549766497674976849769497704977149772497734977449775497764977749778497794978049781497824978349784497854978649787497884978949790497914979249793497944979549796497974979849799498004980149802498034980449805498064980749808498094981049811498124981349814498154981649817498184981949820498214982249823498244982549826498274982849829498304983149832498334983449835498364983749838498394984049841498424984349844498454984649847498484984949850498514985249853498544985549856498574985849859498604986149862498634986449865498664986749868498694987049871498724987349874498754987649877498784987949880498814988249883498844988549886498874988849889498904989149892498934989449895498964989749898498994990049901499024990349904499054990649907499084990949910499114991249913499144991549916499174991849919499204992149922499234992449925499264992749928499294993049931499324993349934499354993649937499384993949940499414994249943499444994549946499474994849949499504995149952499534995449955499564995749958499594996049961499624996349964499654996649967499684996949970499714997249973499744997549976499774997849979499804998149982499834998449985499864998749988499894999049991499924999349994499954999649997499984999950000500015000250003500045000550006500075000850009500105001150012500135001450015500165001750018500195002050021500225002350024500255002650027500285002950030500315003250033500345003550036500375003850039500405004150042500435004450045500465004750048500495005050051500525005350054500555005650057500585005950060500615006250063500645006550066500675006850069500705007150072500735007450075500765007750078500795008050081500825008350084500855008650087500885008950090500915009250093500945009550096500975009850099501005010150102501035010450105501065010750108501095011050111501125011350114501155011650117501185011950120501215012250123501245012550126501275012850129501305013150132501335013450135501365013750138501395014050141501425014350144501455014650147501485014950150501515015250153501545015550156501575015850159501605016150162501635016450165501665016750168501695017050171501725017350174501755017650177501785017950180501815018250183501845018550186501875018850189501905019150192501935019450195501965019750198501995020050201502025020350204502055020650207502085020950210502115021250213502145021550216502175021850219502205022150222502235022450225502265022750228502295023050231502325023350234502355023650237502385023950240502415024250243502445024550246502475024850249502505025150252502535025450255502565025750258502595026050261502625026350264502655026650267502685026950270502715027250273502745027550276502775027850279502805028150282502835028450285502865028750288502895029050291502925029350294502955029650297502985029950300503015030250303503045030550306503075030850309503105031150312503135031450315503165031750318503195032050321503225032350324503255032650327503285032950330503315033250333503345033550336503375033850339503405034150342503435034450345503465034750348503495035050351503525035350354503555035650357503585035950360503615036250363503645036550366503675036850369503705037150372503735037450375503765037750378503795038050381503825038350384503855038650387503885038950390503915039250393503945039550396503975039850399504005040150402504035040450405504065040750408504095041050411504125041350414504155041650417504185041950420504215042250423504245042550426504275042850429504305043150432504335043450435504365043750438504395044050441504425044350444504455044650447504485044950450504515045250453504545045550456504575045850459504605046150462504635046450465504665046750468504695047050471504725047350474504755047650477504785047950480504815048250483504845048550486504875048850489504905049150492504935049450495504965049750498504995050050501505025050350504505055050650507505085050950510505115051250513505145051550516505175051850519505205052150522505235052450525505265052750528505295053050531505325053350534505355053650537505385053950540505415054250543505445054550546505475054850549505505055150552505535055450555505565055750558505595056050561505625056350564505655056650567505685056950570505715057250573505745057550576505775057850579505805058150582505835058450585505865058750588505895059050591505925059350594505955059650597505985059950600506015060250603506045060550606506075060850609506105061150612506135061450615506165061750618506195062050621506225062350624506255062650627506285062950630506315063250633506345063550636506375063850639506405064150642506435064450645506465064750648506495065050651506525065350654506555065650657506585065950660506615066250663506645066550666506675066850669506705067150672506735067450675506765067750678506795068050681506825068350684506855068650687506885068950690506915069250693506945069550696506975069850699507005070150702507035070450705507065070750708507095071050711507125071350714507155071650717507185071950720507215072250723507245072550726507275072850729507305073150732507335073450735507365073750738507395074050741507425074350744507455074650747507485074950750507515075250753507545075550756507575075850759507605076150762507635076450765507665076750768507695077050771507725077350774507755077650777507785077950780507815078250783507845078550786507875078850789507905079150792507935079450795507965079750798507995080050801508025080350804508055080650807508085080950810508115081250813508145081550816508175081850819508205082150822508235082450825508265082750828508295083050831508325083350834508355083650837508385083950840508415084250843508445084550846508475084850849508505085150852508535085450855508565085750858508595086050861508625086350864508655086650867508685086950870508715087250873508745087550876508775087850879508805088150882508835088450885508865088750888508895089050891508925089350894508955089650897508985089950900509015090250903509045090550906509075090850909509105091150912509135091450915509165091750918509195092050921509225092350924509255092650927509285092950930509315093250933509345093550936509375093850939509405094150942509435094450945509465094750948509495095050951509525095350954509555095650957509585095950960509615096250963509645096550966509675096850969509705097150972509735097450975509765097750978509795098050981509825098350984509855098650987509885098950990509915099250993509945099550996509975099850999510005100151002510035100451005510065100751008510095101051011510125101351014510155101651017510185101951020510215102251023510245102551026510275102851029510305103151032510335103451035510365103751038510395104051041510425104351044510455104651047510485104951050510515105251053510545105551056510575105851059510605106151062510635106451065510665106751068510695107051071510725107351074510755107651077510785107951080510815108251083510845108551086510875108851089510905109151092510935109451095510965109751098510995110051101511025110351104511055110651107511085110951110511115111251113511145111551116511175111851119511205112151122511235112451125511265112751128511295113051131511325113351134511355113651137511385113951140511415114251143511445114551146511475114851149511505115151152511535115451155511565115751158511595116051161511625116351164511655116651167511685116951170511715117251173511745117551176511775117851179511805118151182511835118451185511865118751188511895119051191511925119351194511955119651197511985119951200512015120251203512045120551206512075120851209512105121151212512135121451215512165121751218512195122051221512225122351224512255122651227512285122951230512315123251233512345123551236512375123851239512405124151242512435124451245512465124751248512495125051251512525125351254512555125651257512585125951260512615126251263512645126551266512675126851269512705127151272512735127451275512765127751278512795128051281512825128351284512855128651287512885128951290512915129251293512945129551296512975129851299513005130151302513035130451305513065130751308513095131051311513125131351314513155131651317513185131951320513215132251323513245132551326513275132851329513305133151332513335133451335513365133751338513395134051341513425134351344513455134651347513485134951350513515135251353513545135551356513575135851359513605136151362513635136451365513665136751368513695137051371513725137351374513755137651377513785137951380513815138251383513845138551386513875138851389513905139151392513935139451395513965139751398513995140051401514025140351404514055140651407514085140951410514115141251413514145141551416514175141851419514205142151422514235142451425514265142751428514295143051431514325143351434514355143651437514385143951440514415144251443514445144551446514475144851449514505145151452514535145451455514565145751458514595146051461514625146351464514655146651467514685146951470514715147251473514745147551476514775147851479514805148151482514835148451485514865148751488514895149051491514925149351494514955149651497514985149951500515015150251503515045150551506515075150851509515105151151512515135151451515515165151751518515195152051521515225152351524515255152651527515285152951530515315153251533515345153551536515375153851539515405154151542515435154451545515465154751548515495155051551515525155351554515555155651557515585155951560515615156251563515645156551566515675156851569515705157151572515735157451575515765157751578515795158051581515825158351584515855158651587515885158951590515915159251593515945159551596515975159851599516005160151602516035160451605516065160751608516095161051611516125161351614516155161651617516185161951620516215162251623516245162551626516275162851629516305163151632516335163451635516365163751638516395164051641516425164351644516455164651647516485164951650516515165251653516545165551656516575165851659516605166151662516635166451665516665166751668516695167051671516725167351674516755167651677516785167951680516815168251683516845168551686516875168851689516905169151692516935169451695516965169751698516995170051701517025170351704517055170651707517085170951710517115171251713517145171551716517175171851719517205172151722517235172451725517265172751728517295173051731517325173351734517355173651737517385173951740517415174251743517445174551746517475174851749517505175151752517535175451755517565175751758517595176051761517625176351764517655176651767517685176951770517715177251773517745177551776517775177851779517805178151782517835178451785517865178751788517895179051791517925179351794517955179651797517985179951800518015180251803518045180551806518075180851809518105181151812518135181451815518165181751818518195182051821518225182351824518255182651827518285182951830518315183251833518345183551836518375183851839518405184151842518435184451845518465184751848518495185051851518525185351854518555185651857518585185951860518615186251863518645186551866518675186851869518705187151872518735187451875518765187751878518795188051881518825188351884518855188651887518885188951890518915189251893518945189551896518975189851899519005190151902519035190451905519065190751908519095191051911519125191351914519155191651917519185191951920519215192251923519245192551926519275192851929519305193151932519335193451935519365193751938519395194051941519425194351944519455194651947519485194951950519515195251953519545195551956519575195851959519605196151962519635196451965519665196751968519695197051971519725197351974519755197651977519785197951980519815198251983519845198551986519875198851989519905199151992519935199451995519965199751998519995200052001520025200352004520055200652007520085200952010520115201252013520145201552016520175201852019520205202152022520235202452025520265202752028520295203052031520325203352034520355203652037520385203952040520415204252043520445204552046520475204852049520505205152052520535205452055520565205752058520595206052061520625206352064520655206652067520685206952070520715207252073520745207552076520775207852079520805208152082520835208452085520865208752088520895209052091520925209352094520955209652097520985209952100521015210252103521045210552106521075210852109521105211152112521135211452115521165211752118521195212052121521225212352124521255212652127521285212952130521315213252133521345213552136521375213852139521405214152142521435214452145521465214752148521495215052151521525215352154521555215652157521585215952160521615216252163521645216552166521675216852169521705217152172521735217452175521765217752178521795218052181521825218352184521855218652187521885218952190521915219252193521945219552196521975219852199522005220152202522035220452205522065220752208522095221052211522125221352214522155221652217522185221952220522215222252223522245222552226522275222852229522305223152232522335223452235522365223752238522395224052241522425224352244522455224652247522485224952250522515225252253522545225552256522575225852259522605226152262522635226452265522665226752268522695227052271522725227352274522755227652277522785227952280522815228252283522845228552286522875228852289522905229152292522935229452295522965229752298522995230052301523025230352304523055230652307523085230952310523115231252313523145231552316523175231852319523205232152322523235232452325523265232752328523295233052331523325233352334523355233652337523385233952340523415234252343523445234552346523475234852349523505235152352523535235452355523565235752358523595236052361523625236352364523655236652367523685236952370523715237252373523745237552376523775237852379523805238152382523835238452385523865238752388523895239052391523925239352394523955239652397523985239952400524015240252403524045240552406524075240852409524105241152412524135241452415524165241752418524195242052421524225242352424524255242652427524285242952430524315243252433524345243552436524375243852439524405244152442524435244452445524465244752448524495245052451524525245352454524555245652457524585245952460524615246252463524645246552466524675246852469524705247152472524735247452475524765247752478524795248052481524825248352484524855248652487524885248952490524915249252493524945249552496524975249852499525005250152502525035250452505525065250752508525095251052511525125251352514525155251652517525185251952520525215252252523525245252552526525275252852529525305253152532525335253452535525365253752538525395254052541525425254352544525455254652547525485254952550525515255252553525545255552556525575255852559525605256152562525635256452565525665256752568525695257052571525725257352574525755257652577525785257952580525815258252583525845258552586525875258852589525905259152592525935259452595525965259752598525995260052601526025260352604526055260652607526085260952610526115261252613526145261552616526175261852619526205262152622526235262452625526265262752628526295263052631526325263352634526355263652637526385263952640526415264252643526445264552646526475264852649526505265152652526535265452655526565265752658526595266052661526625266352664526655266652667526685266952670526715267252673526745267552676526775267852679526805268152682526835268452685526865268752688526895269052691526925269352694526955269652697526985269952700527015270252703527045270552706527075270852709527105271152712527135271452715527165271752718527195272052721527225272352724527255272652727527285272952730527315273252733527345273552736527375273852739527405274152742527435274452745527465274752748527495275052751527525275352754527555275652757527585275952760527615276252763527645276552766527675276852769527705277152772527735277452775527765277752778527795278052781527825278352784527855278652787527885278952790527915279252793527945279552796527975279852799528005280152802528035280452805528065280752808528095281052811528125281352814528155281652817528185281952820528215282252823528245282552826528275282852829528305283152832528335283452835528365283752838528395284052841528425284352844528455284652847528485284952850528515285252853528545285552856528575285852859528605286152862528635286452865528665286752868528695287052871528725287352874528755287652877528785287952880528815288252883528845288552886528875288852889528905289152892528935289452895528965289752898528995290052901529025290352904529055290652907529085290952910529115291252913529145291552916529175291852919529205292152922529235292452925529265292752928529295293052931529325293352934529355293652937529385293952940529415294252943529445294552946529475294852949529505295152952529535295452955529565295752958529595296052961529625296352964529655296652967529685296952970529715297252973529745297552976529775297852979529805298152982529835298452985529865298752988529895299052991529925299352994529955299652997529985299953000530015300253003530045300553006530075300853009530105301153012530135301453015530165301753018530195302053021530225302353024530255302653027530285302953030530315303253033530345303553036530375303853039530405304153042530435304453045530465304753048530495305053051530525305353054530555305653057530585305953060530615306253063530645306553066530675306853069530705307153072530735307453075530765307753078530795308053081530825308353084530855308653087530885308953090530915309253093530945309553096530975309853099531005310153102531035310453105531065310753108531095311053111531125311353114531155311653117531185311953120531215312253123531245312553126531275312853129531305313153132531335313453135531365313753138531395314053141531425314353144531455314653147531485314953150531515315253153531545315553156531575315853159531605316153162531635316453165531665316753168531695317053171531725317353174531755317653177531785317953180531815318253183531845318553186531875318853189531905319153192531935319453195531965319753198531995320053201532025320353204532055320653207532085320953210532115321253213532145321553216532175321853219532205322153222532235322453225532265322753228532295323053231532325323353234532355323653237532385323953240532415324253243532445324553246532475324853249532505325153252532535325453255532565325753258532595326053261532625326353264532655326653267532685326953270532715327253273532745327553276532775327853279532805328153282532835328453285532865328753288532895329053291532925329353294532955329653297532985329953300533015330253303533045330553306533075330853309533105331153312533135331453315533165331753318533195332053321533225332353324533255332653327533285332953330533315333253333533345333553336533375333853339533405334153342533435334453345533465334753348533495335053351533525335353354533555335653357533585335953360533615336253363533645336553366533675336853369533705337153372533735337453375533765337753378533795338053381533825338353384533855338653387533885338953390533915339253393533945339553396533975339853399534005340153402534035340453405534065340753408534095341053411534125341353414534155341653417534185341953420534215342253423534245342553426534275342853429534305343153432534335343453435534365343753438534395344053441534425344353444534455344653447534485344953450534515345253453534545345553456534575345853459534605346153462534635346453465534665346753468534695347053471534725347353474534755347653477534785347953480534815348253483534845348553486534875348853489534905349153492534935349453495534965349753498534995350053501535025350353504535055350653507535085350953510535115351253513535145351553516535175351853519535205352153522535235352453525535265352753528535295353053531535325353353534535355353653537535385353953540535415354253543535445354553546535475354853549535505355153552535535355453555535565355753558535595356053561535625356353564535655356653567535685356953570535715357253573535745357553576535775357853579535805358153582535835358453585535865358753588535895359053591535925359353594535955359653597535985359953600536015360253603536045360553606536075360853609536105361153612536135361453615536165361753618536195362053621536225362353624536255362653627536285362953630536315363253633536345363553636536375363853639536405364153642536435364453645536465364753648536495365053651536525365353654536555365653657536585365953660536615366253663536645366553666536675366853669536705367153672536735367453675536765367753678536795368053681536825368353684536855368653687536885368953690536915369253693536945369553696536975369853699537005370153702537035370453705537065370753708537095371053711537125371353714537155371653717537185371953720537215372253723537245372553726537275372853729537305373153732537335373453735537365373753738537395374053741537425374353744537455374653747537485374953750537515375253753537545375553756537575375853759537605376153762537635376453765537665376753768537695377053771537725377353774537755377653777537785377953780537815378253783537845378553786537875378853789537905379153792537935379453795537965379753798537995380053801538025380353804538055380653807538085380953810538115381253813538145381553816538175381853819538205382153822538235382453825538265382753828538295383053831538325383353834538355383653837538385383953840538415384253843538445384553846538475384853849538505385153852538535385453855538565385753858538595386053861538625386353864538655386653867538685386953870538715387253873538745387553876538775387853879538805388153882538835388453885538865388753888538895389053891538925389353894538955389653897538985389953900539015390253903539045390553906539075390853909539105391153912539135391453915539165391753918539195392053921539225392353924539255392653927539285392953930539315393253933539345393553936539375393853939539405394153942539435394453945539465394753948539495395053951539525395353954539555395653957539585395953960539615396253963539645396553966539675396853969539705397153972539735397453975539765397753978539795398053981539825398353984539855398653987539885398953990539915399253993539945399553996539975399853999540005400154002540035400454005540065400754008540095401054011540125401354014540155401654017540185401954020540215402254023540245402554026540275402854029540305403154032540335403454035540365403754038540395404054041540425404354044540455404654047540485404954050540515405254053540545405554056540575405854059540605406154062540635406454065540665406754068540695407054071540725407354074540755407654077540785407954080540815408254083540845408554086540875408854089540905409154092540935409454095540965409754098540995410054101541025410354104541055410654107541085410954110541115411254113541145411554116541175411854119541205412154122541235412454125541265412754128541295413054131541325413354134541355413654137541385413954140541415414254143541445414554146541475414854149541505415154152541535415454155541565415754158541595416054161541625416354164541655416654167541685416954170541715417254173541745417554176541775417854179541805418154182541835418454185541865418754188541895419054191541925419354194541955419654197541985419954200542015420254203542045420554206542075420854209542105421154212542135421454215542165421754218542195422054221542225422354224542255422654227542285422954230542315423254233542345423554236542375423854239542405424154242542435424454245542465424754248542495425054251542525425354254542555425654257542585425954260542615426254263542645426554266542675426854269542705427154272542735427454275542765427754278542795428054281542825428354284542855428654287542885428954290542915429254293542945429554296542975429854299543005430154302543035430454305543065430754308543095431054311543125431354314543155431654317543185431954320543215432254323543245432554326543275432854329543305433154332543335433454335543365433754338543395434054341543425434354344543455434654347543485434954350543515435254353543545435554356543575435854359543605436154362543635436454365543665436754368543695437054371543725437354374543755437654377543785437954380543815438254383543845438554386543875438854389543905439154392543935439454395543965439754398543995440054401544025440354404544055440654407544085440954410544115441254413544145441554416544175441854419544205442154422544235442454425544265442754428544295443054431544325443354434544355443654437544385443954440544415444254443544445444554446544475444854449544505445154452544535445454455544565445754458544595446054461544625446354464544655446654467544685446954470544715447254473544745447554476544775447854479544805448154482544835448454485544865448754488544895449054491544925449354494544955449654497544985449954500545015450254503545045450554506545075450854509545105451154512545135451454515545165451754518545195452054521545225452354524545255452654527545285452954530545315453254533545345453554536545375453854539545405454154542545435454454545545465454754548545495455054551545525455354554545555455654557545585455954560545615456254563545645456554566545675456854569545705457154572545735457454575545765457754578545795458054581545825458354584545855458654587545885458954590545915459254593545945459554596545975459854599546005460154602546035460454605546065460754608546095461054611546125461354614546155461654617546185461954620546215462254623546245462554626546275462854629546305463154632546335463454635546365463754638546395464054641546425464354644546455464654647546485464954650546515465254653546545465554656546575465854659546605466154662546635466454665546665466754668546695467054671546725467354674546755467654677546785467954680546815468254683546845468554686546875468854689546905469154692546935469454695546965469754698546995470054701547025470354704547055470654707547085470954710547115471254713547145471554716547175471854719547205472154722547235472454725547265472754728547295473054731547325473354734547355473654737547385473954740547415474254743547445474554746547475474854749547505475154752547535475454755547565475754758547595476054761547625476354764547655476654767547685476954770547715477254773547745477554776547775477854779547805478154782547835478454785547865478754788547895479054791547925479354794547955479654797547985479954800548015480254803548045480554806548075480854809548105481154812548135481454815548165481754818548195482054821548225482354824548255482654827548285482954830548315483254833548345483554836548375483854839548405484154842548435484454845548465484754848548495485054851548525485354854548555485654857548585485954860548615486254863548645486554866548675486854869548705487154872548735487454875548765487754878548795488054881548825488354884548855488654887548885488954890548915489254893548945489554896548975489854899549005490154902549035490454905549065490754908549095491054911549125491354914549155491654917549185491954920549215492254923549245492554926549275492854929549305493154932549335493454935549365493754938549395494054941549425494354944549455494654947549485494954950549515495254953549545495554956549575495854959549605496154962549635496454965549665496754968549695497054971549725497354974549755497654977549785497954980549815498254983549845498554986549875498854989549905499154992549935499454995549965499754998549995500055001550025500355004550055500655007550085500955010550115501255013550145501555016550175501855019550205502155022550235502455025550265502755028550295503055031550325503355034550355503655037550385503955040550415504255043550445504555046550475504855049550505505155052550535505455055550565505755058550595506055061550625506355064550655506655067550685506955070550715507255073550745507555076550775507855079550805508155082550835508455085550865508755088550895509055091550925509355094550955509655097550985509955100551015510255103551045510555106551075510855109551105511155112551135511455115551165511755118551195512055121551225512355124551255512655127551285512955130551315513255133551345513555136551375513855139551405514155142551435514455145551465514755148551495515055151551525515355154551555515655157551585515955160551615516255163551645516555166551675516855169551705517155172551735517455175551765517755178551795518055181551825518355184551855518655187551885518955190551915519255193551945519555196551975519855199552005520155202552035520455205552065520755208552095521055211552125521355214552155521655217552185521955220552215522255223552245522555226552275522855229552305523155232552335523455235552365523755238552395524055241552425524355244552455524655247552485524955250552515525255253552545525555256552575525855259552605526155262552635526455265552665526755268552695527055271552725527355274552755527655277552785527955280552815528255283552845528555286552875528855289552905529155292552935529455295552965529755298552995530055301553025530355304553055530655307553085530955310553115531255313553145531555316553175531855319553205532155322553235532455325553265532755328553295533055331553325533355334553355533655337553385533955340553415534255343553445534555346553475534855349553505535155352553535535455355553565535755358553595536055361553625536355364553655536655367553685536955370553715537255373553745537555376553775537855379553805538155382553835538455385553865538755388553895539055391553925539355394553955539655397553985539955400554015540255403554045540555406554075540855409554105541155412554135541455415554165541755418554195542055421554225542355424554255542655427554285542955430554315543255433554345543555436554375543855439554405544155442554435544455445554465544755448554495545055451554525545355454554555545655457554585545955460554615546255463554645546555466554675546855469554705547155472554735547455475554765547755478554795548055481554825548355484554855548655487554885548955490554915549255493554945549555496554975549855499555005550155502555035550455505555065550755508555095551055511555125551355514555155551655517555185551955520555215552255523555245552555526555275552855529555305553155532555335553455535555365553755538555395554055541555425554355544555455554655547555485554955550555515555255553555545555555556555575555855559555605556155562555635556455565555665556755568555695557055571555725557355574555755557655577555785557955580555815558255583555845558555586555875558855589555905559155592555935559455595555965559755598555995560055601556025560355604556055560655607556085560955610556115561255613556145561555616556175561855619556205562155622556235562455625556265562755628556295563055631556325563355634556355563655637556385563955640556415564255643556445564555646556475564855649556505565155652556535565455655556565565755658556595566055661556625566355664556655566655667556685566955670556715567255673556745567555676556775567855679556805568155682556835568455685556865568755688556895569055691556925569355694556955569655697556985569955700557015570255703557045570555706557075570855709557105571155712557135571455715557165571755718557195572055721557225572355724557255572655727557285572955730557315573255733557345573555736557375573855739557405574155742557435574455745557465574755748557495575055751557525575355754557555575655757557585575955760557615576255763557645576555766557675576855769557705577155772557735577455775557765577755778557795578055781557825578355784557855578655787557885578955790557915579255793557945579555796557975579855799558005580155802558035580455805558065580755808558095581055811558125581355814558155581655817558185581955820558215582255823558245582555826558275582855829558305583155832558335583455835558365583755838558395584055841558425584355844558455584655847558485584955850558515585255853558545585555856558575585855859558605586155862558635586455865558665586755868558695587055871558725587355874558755587655877558785587955880558815588255883558845588555886558875588855889558905589155892558935589455895558965589755898558995590055901559025590355904559055590655907559085590955910559115591255913559145591555916559175591855919559205592155922559235592455925559265592755928559295593055931559325593355934559355593655937559385593955940559415594255943559445594555946559475594855949559505595155952559535595455955559565595755958559595596055961559625596355964559655596655967559685596955970559715597255973559745597555976559775597855979559805598155982559835598455985559865598755988559895599055991559925599355994559955599655997559985599956000560015600256003560045600556006560075600856009560105601156012560135601456015560165601756018560195602056021560225602356024560255602656027560285602956030560315603256033560345603556036560375603856039560405604156042560435604456045560465604756048560495605056051560525605356054560555605656057560585605956060560615606256063560645606556066560675606856069560705607156072560735607456075560765607756078560795608056081560825608356084560855608656087560885608956090560915609256093560945609556096560975609856099561005610156102561035610456105561065610756108561095611056111561125611356114561155611656117561185611956120561215612256123561245612556126561275612856129561305613156132561335613456135561365613756138561395614056141561425614356144561455614656147561485614956150561515615256153561545615556156561575615856159561605616156162561635616456165561665616756168561695617056171561725617356174561755617656177561785617956180561815618256183561845618556186561875618856189561905619156192561935619456195561965619756198561995620056201562025620356204562055620656207562085620956210562115621256213562145621556216562175621856219562205622156222562235622456225562265622756228562295623056231562325623356234562355623656237562385623956240562415624256243562445624556246562475624856249562505625156252562535625456255562565625756258562595626056261562625626356264562655626656267562685626956270562715627256273562745627556276562775627856279562805628156282562835628456285562865628756288562895629056291562925629356294562955629656297562985629956300563015630256303563045630556306563075630856309563105631156312563135631456315563165631756318563195632056321563225632356324563255632656327563285632956330563315633256333563345633556336563375633856339563405634156342563435634456345563465634756348563495635056351563525635356354563555635656357563585635956360563615636256363563645636556366563675636856369563705637156372563735637456375563765637756378563795638056381563825638356384563855638656387563885638956390563915639256393563945639556396563975639856399564005640156402564035640456405564065640756408564095641056411564125641356414564155641656417564185641956420564215642256423564245642556426564275642856429564305643156432564335643456435564365643756438564395644056441564425644356444564455644656447564485644956450564515645256453564545645556456564575645856459564605646156462564635646456465564665646756468564695647056471564725647356474564755647656477564785647956480564815648256483564845648556486564875648856489564905649156492564935649456495564965649756498564995650056501565025650356504565055650656507565085650956510565115651256513565145651556516565175651856519565205652156522565235652456525565265652756528565295653056531565325653356534565355653656537565385653956540565415654256543565445654556546565475654856549565505655156552565535655456555565565655756558565595656056561565625656356564565655656656567565685656956570565715657256573565745657556576565775657856579565805658156582565835658456585565865658756588565895659056591565925659356594565955659656597565985659956600566015660256603566045660556606566075660856609566105661156612566135661456615566165661756618566195662056621566225662356624566255662656627566285662956630566315663256633566345663556636566375663856639566405664156642566435664456645566465664756648566495665056651566525665356654566555665656657566585665956660566615666256663566645666556666566675666856669566705667156672566735667456675566765667756678566795668056681566825668356684566855668656687566885668956690566915669256693566945669556696566975669856699567005670156702567035670456705567065670756708567095671056711567125671356714567155671656717567185671956720567215672256723567245672556726567275672856729567305673156732567335673456735567365673756738567395674056741567425674356744567455674656747567485674956750567515675256753567545675556756567575675856759567605676156762567635676456765567665676756768567695677056771567725677356774567755677656777567785677956780567815678256783567845678556786567875678856789567905679156792567935679456795567965679756798567995680056801568025680356804568055680656807568085680956810568115681256813568145681556816568175681856819568205682156822568235682456825568265682756828568295683056831568325683356834568355683656837568385683956840568415684256843568445684556846568475684856849568505685156852568535685456855568565685756858568595686056861568625686356864568655686656867568685686956870568715687256873568745687556876568775687856879568805688156882568835688456885568865688756888568895689056891568925689356894568955689656897568985689956900569015690256903569045690556906569075690856909569105691156912569135691456915569165691756918569195692056921569225692356924569255692656927569285692956930569315693256933569345693556936569375693856939569405694156942569435694456945569465694756948569495695056951569525695356954569555695656957569585695956960569615696256963569645696556966569675696856969569705697156972569735697456975569765697756978569795698056981569825698356984569855698656987569885698956990569915699256993569945699556996569975699856999570005700157002570035700457005570065700757008570095701057011570125701357014570155701657017570185701957020570215702257023570245702557026570275702857029570305703157032570335703457035570365703757038570395704057041570425704357044570455704657047570485704957050570515705257053570545705557056570575705857059570605706157062570635706457065570665706757068570695707057071570725707357074570755707657077570785707957080570815708257083570845708557086570875708857089570905709157092570935709457095570965709757098570995710057101571025710357104571055710657107571085710957110571115711257113571145711557116571175711857119571205712157122571235712457125571265712757128571295713057131571325713357134571355713657137571385713957140571415714257143571445714557146571475714857149571505715157152571535715457155571565715757158571595716057161571625716357164571655716657167571685716957170571715717257173571745717557176571775717857179571805718157182571835718457185571865718757188571895719057191571925719357194571955719657197571985719957200572015720257203572045720557206572075720857209572105721157212572135721457215572165721757218572195722057221572225722357224572255722657227572285722957230572315723257233572345723557236572375723857239572405724157242572435724457245572465724757248572495725057251572525725357254572555725657257572585725957260572615726257263572645726557266572675726857269572705727157272572735727457275572765727757278572795728057281572825728357284572855728657287572885728957290572915729257293572945729557296572975729857299573005730157302573035730457305573065730757308573095731057311573125731357314573155731657317573185731957320573215732257323573245732557326573275732857329573305733157332573335733457335573365733757338573395734057341573425734357344573455734657347573485734957350573515735257353573545735557356573575735857359573605736157362573635736457365573665736757368573695737057371573725737357374573755737657377573785737957380573815738257383573845738557386573875738857389573905739157392573935739457395573965739757398573995740057401574025740357404574055740657407574085740957410574115741257413574145741557416574175741857419574205742157422574235742457425574265742757428574295743057431574325743357434574355743657437574385743957440574415744257443574445744557446574475744857449574505745157452574535745457455574565745757458574595746057461574625746357464574655746657467574685746957470574715747257473574745747557476574775747857479574805748157482574835748457485574865748757488574895749057491574925749357494574955749657497574985749957500575015750257503575045750557506575075750857509575105751157512575135751457515575165751757518575195752057521575225752357524575255752657527575285752957530575315753257533575345753557536575375753857539575405754157542575435754457545575465754757548575495755057551575525755357554575555755657557575585755957560575615756257563575645756557566575675756857569575705757157572575735757457575575765757757578575795758057581575825758357584575855758657587575885758957590575915759257593575945759557596575975759857599576005760157602576035760457605576065760757608576095761057611576125761357614576155761657617576185761957620576215762257623576245762557626576275762857629576305763157632576335763457635576365763757638576395764057641576425764357644576455764657647576485764957650576515765257653576545765557656576575765857659576605766157662576635766457665576665766757668576695767057671576725767357674576755767657677576785767957680576815768257683576845768557686576875768857689576905769157692576935769457695576965769757698576995770057701577025770357704577055770657707577085770957710577115771257713577145771557716577175771857719577205772157722577235772457725577265772757728577295773057731577325773357734577355773657737577385773957740577415774257743577445774557746577475774857749577505775157752577535775457755577565775757758577595776057761577625776357764577655776657767577685776957770577715777257773577745777557776577775777857779577805778157782577835778457785577865778757788577895779057791577925779357794577955779657797577985779957800578015780257803578045780557806578075780857809578105781157812578135781457815578165781757818578195782057821578225782357824578255782657827578285782957830578315783257833578345783557836578375783857839578405784157842578435784457845578465784757848578495785057851578525785357854578555785657857578585785957860578615786257863578645786557866578675786857869578705787157872578735787457875578765787757878578795788057881578825788357884578855788657887578885788957890578915789257893578945789557896578975789857899579005790157902579035790457905579065790757908579095791057911579125791357914579155791657917579185791957920579215792257923579245792557926579275792857929579305793157932579335793457935579365793757938579395794057941579425794357944579455794657947579485794957950579515795257953579545795557956579575795857959579605796157962579635796457965579665796757968579695797057971579725797357974579755797657977579785797957980579815798257983579845798557986579875798857989579905799157992579935799457995579965799757998579995800058001580025800358004580055800658007580085800958010580115801258013580145801558016580175801858019580205802158022580235802458025580265802758028580295803058031580325803358034580355803658037580385803958040580415804258043580445804558046580475804858049580505805158052580535805458055580565805758058580595806058061580625806358064580655806658067580685806958070580715807258073580745807558076580775807858079580805808158082580835808458085580865808758088580895809058091580925809358094580955809658097580985809958100581015810258103581045810558106581075810858109581105811158112581135811458115581165811758118581195812058121581225812358124581255812658127581285812958130581315813258133581345813558136581375813858139581405814158142581435814458145581465814758148581495815058151581525815358154581555815658157581585815958160581615816258163581645816558166581675816858169581705817158172581735817458175581765817758178581795818058181581825818358184581855818658187581885818958190581915819258193581945819558196581975819858199582005820158202582035820458205582065820758208582095821058211582125821358214582155821658217582185821958220582215822258223582245822558226582275822858229582305823158232582335823458235582365823758238582395824058241582425824358244582455824658247582485824958250582515825258253582545825558256582575825858259582605826158262582635826458265582665826758268582695827058271582725827358274582755827658277582785827958280582815828258283582845828558286582875828858289582905829158292582935829458295582965829758298582995830058301583025830358304583055830658307583085830958310583115831258313583145831558316583175831858319583205832158322583235832458325583265832758328583295833058331583325833358334583355833658337583385833958340583415834258343583445834558346583475834858349583505835158352583535835458355583565835758358583595836058361583625836358364583655836658367583685836958370583715837258373583745837558376583775837858379583805838158382583835838458385583865838758388583895839058391583925839358394583955839658397583985839958400584015840258403584045840558406584075840858409584105841158412584135841458415584165841758418584195842058421584225842358424584255842658427584285842958430584315843258433584345843558436584375843858439584405844158442584435844458445584465844758448584495845058451584525845358454584555845658457584585845958460584615846258463584645846558466584675846858469584705847158472584735847458475584765847758478584795848058481584825848358484584855848658487584885848958490584915849258493584945849558496584975849858499585005850158502585035850458505585065850758508585095851058511585125851358514585155851658517585185851958520585215852258523585245852558526585275852858529585305853158532585335853458535585365853758538585395854058541585425854358544585455854658547585485854958550585515855258553585545855558556585575855858559585605856158562585635856458565585665856758568585695857058571585725857358574585755857658577585785857958580585815858258583585845858558586585875858858589585905859158592585935859458595585965859758598585995860058601586025860358604586055860658607586085860958610586115861258613586145861558616586175861858619586205862158622586235862458625586265862758628586295863058631586325863358634586355863658637586385863958640586415864258643586445864558646586475864858649586505865158652586535865458655586565865758658586595866058661586625866358664586655866658667586685866958670586715867258673586745867558676586775867858679586805868158682586835868458685586865868758688586895869058691586925869358694586955869658697586985869958700587015870258703587045870558706587075870858709587105871158712587135871458715587165871758718587195872058721587225872358724587255872658727587285872958730587315873258733587345873558736587375873858739587405874158742587435874458745587465874758748587495875058751587525875358754587555875658757587585875958760587615876258763587645876558766587675876858769587705877158772587735877458775587765877758778587795878058781587825878358784587855878658787587885878958790587915879258793587945879558796587975879858799588005880158802588035880458805588065880758808588095881058811588125881358814588155881658817588185881958820588215882258823588245882558826588275882858829588305883158832588335883458835588365883758838588395884058841588425884358844588455884658847588485884958850588515885258853588545885558856588575885858859588605886158862588635886458865588665886758868588695887058871588725887358874588755887658877588785887958880588815888258883588845888558886588875888858889588905889158892588935889458895588965889758898588995890058901589025890358904589055890658907589085890958910589115891258913589145891558916589175891858919589205892158922589235892458925589265892758928589295893058931589325893358934589355893658937589385893958940589415894258943589445894558946589475894858949589505895158952589535895458955589565895758958589595896058961589625896358964589655896658967589685896958970589715897258973589745897558976589775897858979589805898158982589835898458985589865898758988589895899058991589925899358994589955899658997589985899959000590015900259003590045900559006590075900859009590105901159012590135901459015590165901759018590195902059021590225902359024590255902659027590285902959030590315903259033590345903559036590375903859039590405904159042590435904459045590465904759048590495905059051590525905359054590555905659057590585905959060590615906259063590645906559066590675906859069590705907159072590735907459075590765907759078590795908059081590825908359084590855908659087590885908959090590915909259093590945909559096590975909859099591005910159102591035910459105591065910759108591095911059111591125911359114591155911659117591185911959120591215912259123591245912559126591275912859129591305913159132591335913459135591365913759138591395914059141591425914359144591455914659147591485914959150591515915259153591545915559156591575915859159591605916159162591635916459165591665916759168591695917059171591725917359174591755917659177591785917959180591815918259183591845918559186591875918859189591905919159192591935919459195591965919759198591995920059201592025920359204592055920659207592085920959210592115921259213592145921559216592175921859219592205922159222592235922459225592265922759228592295923059231592325923359234592355923659237592385923959240592415924259243592445924559246592475924859249592505925159252592535925459255592565925759258592595926059261592625926359264592655926659267592685926959270592715927259273592745927559276592775927859279592805928159282592835928459285592865928759288592895929059291592925929359294592955929659297592985929959300593015930259303593045930559306593075930859309593105931159312593135931459315593165931759318593195932059321593225932359324593255932659327593285932959330593315933259333593345933559336593375933859339593405934159342593435934459345593465934759348593495935059351593525935359354593555935659357593585935959360593615936259363593645936559366593675936859369593705937159372593735937459375593765937759378593795938059381593825938359384593855938659387593885938959390593915939259393593945939559396593975939859399594005940159402594035940459405594065940759408594095941059411594125941359414594155941659417594185941959420594215942259423594245942559426594275942859429594305943159432594335943459435594365943759438594395944059441594425944359444594455944659447594485944959450594515945259453594545945559456594575945859459594605946159462594635946459465594665946759468594695947059471594725947359474594755947659477594785947959480594815948259483594845948559486594875948859489594905949159492594935949459495594965949759498594995950059501595025950359504595055950659507595085950959510595115951259513595145951559516595175951859519595205952159522595235952459525595265952759528595295953059531595325953359534595355953659537595385953959540595415954259543595445954559546595475954859549595505955159552595535955459555595565955759558595595956059561595625956359564595655956659567595685956959570595715957259573595745957559576595775957859579595805958159582595835958459585595865958759588595895959059591595925959359594595955959659597595985959959600596015960259603596045960559606596075960859609596105961159612596135961459615596165961759618596195962059621596225962359624596255962659627596285962959630596315963259633596345963559636596375963859639596405964159642596435964459645596465964759648596495965059651596525965359654596555965659657596585965959660596615966259663596645966559666596675966859669596705967159672596735967459675596765967759678596795968059681596825968359684596855968659687596885968959690596915969259693596945969559696596975969859699597005970159702597035970459705597065970759708597095971059711597125971359714597155971659717597185971959720597215972259723597245972559726597275972859729597305973159732597335973459735597365973759738597395974059741597425974359744597455974659747597485974959750597515975259753597545975559756597575975859759597605976159762597635976459765597665976759768597695977059771597725977359774597755977659777597785977959780597815978259783597845978559786597875978859789597905979159792597935979459795597965979759798597995980059801598025980359804598055980659807598085980959810598115981259813598145981559816598175981859819598205982159822598235982459825598265982759828598295983059831598325983359834598355983659837598385983959840598415984259843598445984559846598475984859849598505985159852598535985459855598565985759858598595986059861598625986359864598655986659867598685986959870598715987259873598745987559876598775987859879598805988159882598835988459885598865988759888598895989059891598925989359894598955989659897598985989959900599015990259903599045990559906599075990859909599105991159912599135991459915599165991759918599195992059921599225992359924599255992659927599285992959930599315993259933599345993559936599375993859939599405994159942599435994459945599465994759948599495995059951599525995359954599555995659957599585995959960599615996259963599645996559966599675996859969599705997159972599735997459975599765997759978599795998059981599825998359984599855998659987599885998959990599915999259993599945999559996599975999859999600006000160002600036000460005600066000760008600096001060011600126001360014600156001660017600186001960020600216002260023600246002560026600276002860029600306003160032600336003460035600366003760038600396004060041600426004360044600456004660047600486004960050600516005260053600546005560056600576005860059600606006160062600636006460065600666006760068600696007060071600726007360074600756007660077600786007960080600816008260083600846008560086600876008860089600906009160092600936009460095600966009760098600996010060101601026010360104601056010660107601086010960110601116011260113601146011560116601176011860119601206012160122601236012460125601266012760128601296013060131601326013360134601356013660137601386013960140601416014260143601446014560146601476014860149601506015160152601536015460155601566015760158601596016060161601626016360164601656016660167601686016960170601716017260173601746017560176601776017860179601806018160182601836018460185601866018760188601896019060191601926019360194601956019660197601986019960200602016020260203602046020560206602076020860209602106021160212602136021460215602166021760218602196022060221602226022360224602256022660227602286022960230602316023260233602346023560236602376023860239602406024160242602436024460245602466024760248602496025060251602526025360254602556025660257602586025960260602616026260263602646026560266602676026860269602706027160272602736027460275602766027760278602796028060281602826028360284602856028660287602886028960290602916029260293602946029560296602976029860299603006030160302603036030460305603066030760308603096031060311603126031360314603156031660317603186031960320603216032260323603246032560326603276032860329603306033160332603336033460335603366033760338603396034060341603426034360344603456034660347603486034960350603516035260353603546035560356603576035860359603606036160362603636036460365603666036760368603696037060371603726037360374603756037660377603786037960380603816038260383603846038560386603876038860389603906039160392603936039460395603966039760398603996040060401604026040360404604056040660407604086040960410604116041260413604146041560416604176041860419604206042160422604236042460425604266042760428604296043060431604326043360434604356043660437604386043960440604416044260443604446044560446604476044860449604506045160452604536045460455604566045760458604596046060461604626046360464604656046660467604686046960470604716047260473604746047560476604776047860479604806048160482604836048460485604866048760488604896049060491604926049360494604956049660497604986049960500605016050260503605046050560506605076050860509605106051160512605136051460515605166051760518605196052060521605226052360524605256052660527605286052960530605316053260533605346053560536605376053860539605406054160542605436054460545605466054760548605496055060551605526055360554605556055660557605586055960560605616056260563605646056560566605676056860569605706057160572605736057460575605766057760578605796058060581605826058360584605856058660587605886058960590605916059260593605946059560596605976059860599606006060160602606036060460605606066060760608606096061060611606126061360614606156061660617606186061960620606216062260623606246062560626606276062860629606306063160632606336063460635606366063760638606396064060641606426064360644606456064660647606486064960650606516065260653606546065560656606576065860659606606066160662606636066460665606666066760668606696067060671606726067360674606756067660677606786067960680606816068260683606846068560686606876068860689606906069160692606936069460695606966069760698606996070060701607026070360704607056070660707607086070960710607116071260713607146071560716607176071860719607206072160722607236072460725607266072760728607296073060731607326073360734607356073660737607386073960740607416074260743607446074560746607476074860749607506075160752607536075460755607566075760758607596076060761607626076360764607656076660767607686076960770607716077260773607746077560776607776077860779607806078160782607836078460785607866078760788607896079060791607926079360794607956079660797607986079960800608016080260803608046080560806608076080860809608106081160812608136081460815608166081760818608196082060821608226082360824608256082660827608286082960830608316083260833608346083560836608376083860839608406084160842608436084460845608466084760848608496085060851608526085360854608556085660857608586085960860608616086260863608646086560866608676086860869608706087160872608736087460875608766087760878608796088060881608826088360884608856088660887608886088960890608916089260893608946089560896608976089860899609006090160902609036090460905609066090760908609096091060911609126091360914609156091660917609186091960920609216092260923609246092560926609276092860929609306093160932609336093460935609366093760938609396094060941609426094360944609456094660947609486094960950609516095260953609546095560956609576095860959609606096160962609636096460965609666096760968609696097060971609726097360974609756097660977609786097960980609816098260983609846098560986609876098860989609906099160992609936099460995609966099760998609996100061001610026100361004610056100661007610086100961010610116101261013610146101561016610176101861019610206102161022610236102461025610266102761028610296103061031610326103361034610356103661037610386103961040610416104261043610446104561046610476104861049610506105161052610536105461055610566105761058610596106061061610626106361064610656106661067610686106961070610716107261073610746107561076610776107861079610806108161082610836108461085610866108761088610896109061091610926109361094610956109661097610986109961100611016110261103611046110561106611076110861109611106111161112611136111461115611166111761118611196112061121611226112361124611256112661127611286112961130611316113261133611346113561136611376113861139611406114161142611436114461145611466114761148611496115061151611526115361154611556115661157611586115961160611616116261163611646116561166611676116861169611706117161172611736117461175611766117761178611796118061181611826118361184611856118661187611886118961190611916119261193611946119561196611976119861199612006120161202612036120461205612066120761208612096121061211612126121361214612156121661217612186121961220612216122261223612246122561226612276122861229612306123161232612336123461235612366123761238612396124061241612426124361244612456124661247612486124961250612516125261253612546125561256612576125861259612606126161262612636126461265612666126761268612696127061271612726127361274612756127661277612786127961280612816128261283612846128561286612876128861289612906129161292612936129461295612966129761298612996130061301613026130361304613056130661307613086130961310613116131261313613146131561316613176131861319613206132161322613236132461325613266132761328613296133061331613326133361334613356133661337613386133961340613416134261343613446134561346613476134861349613506135161352613536135461355613566135761358613596136061361613626136361364613656136661367613686136961370613716137261373613746137561376613776137861379613806138161382613836138461385613866138761388613896139061391613926139361394613956139661397613986139961400614016140261403614046140561406614076140861409614106141161412614136141461415614166141761418614196142061421614226142361424614256142661427614286142961430614316143261433614346143561436614376143861439614406144161442614436144461445614466144761448614496145061451614526145361454614556145661457614586145961460614616146261463614646146561466614676146861469614706147161472614736147461475614766147761478614796148061481614826148361484614856148661487614886148961490614916149261493614946149561496614976149861499615006150161502615036150461505615066150761508615096151061511615126151361514615156151661517615186151961520615216152261523615246152561526615276152861529615306153161532615336153461535615366153761538615396154061541615426154361544615456154661547615486154961550615516155261553615546155561556615576155861559615606156161562615636156461565615666156761568615696157061571615726157361574615756157661577615786157961580615816158261583615846158561586615876158861589615906159161592615936159461595615966159761598615996160061601616026160361604616056160661607616086160961610616116161261613616146161561616616176161861619616206162161622616236162461625616266162761628616296163061631616326163361634616356163661637616386163961640616416164261643616446164561646616476164861649616506165161652616536165461655616566165761658616596166061661616626166361664616656166661667616686166961670616716167261673616746167561676616776167861679616806168161682616836168461685616866168761688616896169061691616926169361694616956169661697616986169961700617016170261703617046170561706617076170861709617106171161712617136171461715617166171761718617196172061721617226172361724617256172661727617286172961730617316173261733617346173561736617376173861739617406174161742617436174461745617466174761748617496175061751617526175361754617556175661757617586175961760617616176261763617646176561766617676176861769617706177161772617736177461775617766177761778617796178061781617826178361784617856178661787617886178961790617916179261793617946179561796617976179861799618006180161802618036180461805618066180761808618096181061811618126181361814618156181661817618186181961820618216182261823618246182561826618276182861829618306183161832618336183461835618366183761838618396184061841618426184361844618456184661847618486184961850618516185261853618546185561856618576185861859618606186161862618636186461865618666186761868618696187061871618726187361874618756187661877618786187961880618816188261883618846188561886618876188861889618906189161892618936189461895618966189761898618996190061901619026190361904619056190661907619086190961910619116191261913619146191561916619176191861919619206192161922619236192461925619266192761928619296193061931619326193361934619356193661937619386193961940619416194261943619446194561946619476194861949619506195161952619536195461955619566195761958619596196061961619626196361964619656196661967619686196961970619716197261973619746197561976619776197861979619806198161982619836198461985619866198761988619896199061991619926199361994619956199661997619986199962000620016200262003620046200562006620076200862009620106201162012620136201462015620166201762018620196202062021620226202362024620256202662027620286202962030620316203262033620346203562036620376203862039620406204162042620436204462045620466204762048620496205062051620526205362054620556205662057620586205962060620616206262063620646206562066620676206862069620706207162072620736207462075620766207762078620796208062081620826208362084620856208662087620886208962090620916209262093620946209562096620976209862099621006210162102621036210462105621066210762108621096211062111621126211362114621156211662117621186211962120621216212262123621246212562126621276212862129621306213162132621336213462135621366213762138621396214062141621426214362144621456214662147621486214962150621516215262153621546215562156621576215862159621606216162162621636216462165621666216762168621696217062171621726217362174621756217662177621786217962180621816218262183621846218562186621876218862189621906219162192621936219462195621966219762198621996220062201622026220362204622056220662207622086220962210622116221262213622146221562216622176221862219622206222162222622236222462225622266222762228622296223062231622326223362234622356223662237622386223962240622416224262243622446224562246622476224862249622506225162252622536225462255622566225762258622596226062261622626226362264622656226662267622686226962270622716227262273622746227562276622776227862279622806228162282622836228462285622866228762288622896229062291622926229362294622956229662297622986229962300623016230262303623046230562306623076230862309623106231162312623136231462315623166231762318623196232062321623226232362324623256232662327623286232962330623316233262333623346233562336623376233862339623406234162342623436234462345623466234762348623496235062351623526235362354623556235662357623586235962360623616236262363623646236562366623676236862369623706237162372623736237462375623766237762378623796238062381623826238362384623856238662387623886238962390623916239262393623946239562396623976239862399624006240162402624036240462405624066240762408624096241062411624126241362414624156241662417624186241962420624216242262423624246242562426624276242862429624306243162432624336243462435624366243762438624396244062441624426244362444624456244662447624486244962450624516245262453624546245562456624576245862459624606246162462624636246462465624666246762468624696247062471624726247362474624756247662477624786247962480624816248262483624846248562486624876248862489624906249162492624936249462495624966249762498624996250062501625026250362504625056250662507625086250962510625116251262513625146251562516625176251862519625206252162522625236252462525625266252762528625296253062531625326253362534625356253662537625386253962540625416254262543625446254562546625476254862549625506255162552625536255462555625566255762558625596256062561625626256362564625656256662567625686256962570625716257262573625746257562576625776257862579625806258162582625836258462585625866258762588625896259062591625926259362594625956259662597625986259962600626016260262603626046260562606626076260862609626106261162612626136261462615626166261762618626196262062621626226262362624626256262662627626286262962630626316263262633626346263562636626376263862639626406264162642626436264462645626466264762648626496265062651626526265362654626556265662657626586265962660626616266262663626646266562666626676266862669626706267162672626736267462675626766267762678626796268062681626826268362684626856268662687626886268962690626916269262693626946269562696626976269862699627006270162702627036270462705627066270762708627096271062711627126271362714627156271662717627186271962720627216272262723627246272562726627276272862729627306273162732627336273462735627366273762738627396274062741627426274362744627456274662747627486274962750627516275262753627546275562756627576275862759627606276162762627636276462765627666276762768627696277062771627726277362774627756277662777627786277962780627816278262783627846278562786627876278862789627906279162792627936279462795627966279762798627996280062801628026280362804628056280662807628086280962810628116281262813628146281562816628176281862819628206282162822628236282462825628266282762828628296283062831628326283362834628356283662837628386283962840628416284262843628446284562846628476284862849628506285162852628536285462855628566285762858628596286062861628626286362864628656286662867628686286962870628716287262873628746287562876628776287862879628806288162882628836288462885628866288762888628896289062891628926289362894628956289662897628986289962900629016290262903629046290562906629076290862909629106291162912629136291462915629166291762918629196292062921629226292362924629256292662927629286292962930629316293262933629346293562936629376293862939629406294162942629436294462945629466294762948629496295062951629526295362954629556295662957629586295962960629616296262963629646296562966629676296862969629706297162972629736297462975629766297762978629796298062981629826298362984629856298662987629886298962990629916299262993629946299562996629976299862999630006300163002630036300463005630066300763008630096301063011630126301363014630156301663017630186301963020630216302263023630246302563026630276302863029630306303163032630336303463035630366303763038630396304063041630426304363044630456304663047630486304963050630516305263053630546305563056630576305863059630606306163062630636306463065630666306763068630696307063071630726307363074630756307663077630786307963080630816308263083630846308563086630876308863089630906309163092630936309463095630966309763098630996310063101631026310363104631056310663107631086310963110631116311263113631146311563116631176311863119631206312163122631236312463125631266312763128631296313063131631326313363134631356313663137631386313963140631416314263143631446314563146631476314863149631506315163152631536315463155631566315763158631596316063161631626316363164631656316663167631686316963170631716317263173631746317563176631776317863179631806318163182631836318463185631866318763188631896319063191631926319363194631956319663197631986319963200632016320263203632046320563206632076320863209632106321163212632136321463215632166321763218632196322063221632226322363224632256322663227632286322963230632316323263233632346323563236632376323863239632406324163242632436324463245632466324763248632496325063251632526325363254632556325663257632586325963260632616326263263632646326563266632676326863269632706327163272632736327463275632766327763278632796328063281632826328363284632856328663287632886328963290632916329263293632946329563296632976329863299633006330163302633036330463305633066330763308633096331063311633126331363314633156331663317633186331963320633216332263323633246332563326633276332863329633306333163332633336333463335633366333763338633396334063341633426334363344633456334663347633486334963350633516335263353633546335563356633576335863359633606336163362633636336463365633666336763368633696337063371633726337363374633756337663377633786337963380633816338263383633846338563386633876338863389633906339163392633936339463395633966339763398633996340063401634026340363404634056340663407634086340963410634116341263413634146341563416634176341863419634206342163422634236342463425634266342763428634296343063431634326343363434634356343663437634386343963440634416344263443634446344563446634476344863449634506345163452634536345463455634566345763458634596346063461634626346363464634656346663467634686346963470634716347263473634746347563476634776347863479634806348163482634836348463485634866348763488634896349063491634926349363494634956349663497634986349963500635016350263503635046350563506635076350863509635106351163512635136351463515635166351763518635196352063521635226352363524635256352663527635286352963530635316353263533635346353563536635376353863539635406354163542635436354463545635466354763548635496355063551635526355363554635556355663557635586355963560635616356263563635646356563566635676356863569635706357163572635736357463575635766357763578635796358063581635826358363584635856358663587635886358963590635916359263593635946359563596635976359863599636006360163602636036360463605636066360763608636096361063611636126361363614636156361663617636186361963620636216362263623636246362563626636276362863629636306363163632636336363463635636366363763638636396364063641636426364363644636456364663647636486364963650636516365263653636546365563656636576365863659636606366163662636636366463665636666366763668636696367063671636726367363674636756367663677636786367963680636816368263683636846368563686636876368863689636906369163692636936369463695636966369763698636996370063701637026370363704637056370663707637086370963710637116371263713637146371563716637176371863719637206372163722637236372463725637266372763728637296373063731637326373363734637356373663737637386373963740637416374263743637446374563746637476374863749637506375163752637536375463755637566375763758637596376063761637626376363764637656376663767637686376963770637716377263773637746377563776637776377863779637806378163782637836378463785637866378763788637896379063791637926379363794637956379663797637986379963800638016380263803638046380563806638076380863809638106381163812638136381463815638166381763818638196382063821638226382363824638256382663827638286382963830638316383263833638346383563836638376383863839638406384163842638436384463845638466384763848638496385063851638526385363854638556385663857638586385963860638616386263863638646386563866638676386863869638706387163872638736387463875638766387763878638796388063881638826388363884638856388663887638886388963890638916389263893638946389563896638976389863899639006390163902639036390463905639066390763908639096391063911639126391363914639156391663917639186391963920639216392263923639246392563926639276392863929639306393163932639336393463935639366393763938639396394063941639426394363944639456394663947639486394963950639516395263953639546395563956639576395863959639606396163962639636396463965639666396763968639696397063971639726397363974639756397663977639786397963980639816398263983639846398563986639876398863989639906399163992639936399463995639966399763998639996400064001640026400364004640056400664007640086400964010640116401264013640146401564016640176401864019640206402164022640236402464025640266402764028640296403064031640326403364034640356403664037640386403964040640416404264043640446404564046640476404864049640506405164052640536405464055640566405764058640596406064061640626406364064640656406664067640686406964070640716407264073640746407564076640776407864079640806408164082640836408464085640866408764088640896409064091640926409364094640956409664097640986409964100641016410264103641046410564106641076410864109641106411164112641136411464115641166411764118641196412064121641226412364124641256412664127641286412964130641316413264133641346413564136641376413864139641406414164142641436414464145641466414764148641496415064151641526415364154641556415664157641586415964160641616416264163641646416564166641676416864169641706417164172641736417464175641766417764178641796418064181641826418364184641856418664187641886418964190641916419264193641946419564196641976419864199642006420164202642036420464205642066420764208642096421064211642126421364214642156421664217642186421964220642216422264223642246422564226642276422864229642306423164232642336423464235642366423764238642396424064241642426424364244642456424664247642486424964250642516425264253642546425564256642576425864259642606426164262642636426464265642666426764268642696427064271642726427364274642756427664277642786427964280642816428264283642846428564286642876428864289642906429164292642936429464295642966429764298642996430064301643026430364304643056430664307643086430964310643116431264313643146431564316643176431864319643206432164322643236432464325643266432764328643296433064331643326433364334643356433664337643386433964340643416434264343643446434564346643476434864349643506435164352643536435464355643566435764358643596436064361643626436364364643656436664367643686436964370643716437264373643746437564376643776437864379643806438164382643836438464385643866438764388643896439064391643926439364394643956439664397643986439964400644016440264403644046440564406644076440864409644106441164412644136441464415644166441764418644196442064421644226442364424644256442664427644286442964430644316443264433644346443564436644376443864439644406444164442644436444464445644466444764448644496445064451644526445364454644556445664457644586445964460644616446264463644646446564466644676446864469644706447164472644736447464475644766447764478644796448064481644826448364484644856448664487644886448964490644916449264493644946449564496644976449864499645006450164502645036450464505645066450764508645096451064511645126451364514645156451664517645186451964520645216452264523645246452564526645276452864529645306453164532645336453464535645366453764538645396454064541645426454364544645456454664547645486454964550645516455264553645546455564556645576455864559645606456164562645636456464565645666456764568645696457064571645726457364574645756457664577645786457964580645816458264583645846458564586645876458864589645906459164592645936459464595645966459764598645996460064601646026460364604646056460664607646086460964610646116461264613646146461564616646176461864619646206462164622646236462464625646266462764628646296463064631646326463364634646356463664637646386463964640646416464264643646446464564646646476464864649646506465164652646536465464655646566465764658646596466064661646626466364664646656466664667646686466964670646716467264673646746467564676646776467864679646806468164682646836468464685646866468764688646896469064691646926469364694646956469664697646986469964700647016470264703647046470564706647076470864709647106471164712647136471464715647166471764718647196472064721647226472364724647256472664727647286472964730647316473264733647346473564736647376473864739647406474164742647436474464745647466474764748647496475064751647526475364754647556475664757647586475964760647616476264763647646476564766647676476864769647706477164772647736477464775647766477764778647796478064781647826478364784647856478664787647886478964790647916479264793647946479564796647976479864799648006480164802648036480464805648066480764808648096481064811648126481364814648156481664817648186481964820648216482264823648246482564826648276482864829648306483164832648336483464835648366483764838648396484064841648426484364844648456484664847648486484964850648516485264853648546485564856648576485864859648606486164862648636486464865648666486764868648696487064871648726487364874648756487664877648786487964880648816488264883648846488564886648876488864889648906489164892648936489464895648966489764898648996490064901649026490364904649056490664907649086490964910649116491264913649146491564916649176491864919649206492164922649236492464925649266492764928649296493064931649326493364934649356493664937649386493964940649416494264943649446494564946649476494864949649506495164952649536495464955649566495764958649596496064961649626496364964649656496664967649686496964970649716497264973649746497564976649776497864979649806498164982649836498464985649866498764988649896499064991649926499364994649956499664997649986499965000650016500265003650046500565006650076500865009650106501165012650136501465015650166501765018650196502065021650226502365024650256502665027650286502965030650316503265033650346503565036650376503865039650406504165042650436504465045650466504765048650496505065051650526505365054650556505665057650586505965060650616506265063650646506565066650676506865069650706507165072650736507465075650766507765078650796508065081650826508365084650856508665087650886508965090650916509265093650946509565096650976509865099651006510165102651036510465105651066510765108651096511065111651126511365114651156511665117651186511965120651216512265123651246512565126651276512865129651306513165132651336513465135651366513765138651396514065141651426514365144651456514665147651486514965150651516515265153651546515565156651576515865159651606516165162651636516465165651666516765168651696517065171651726517365174651756517665177651786517965180651816518265183651846518565186651876518865189651906519165192651936519465195651966519765198651996520065201652026520365204652056520665207652086520965210652116521265213652146521565216652176521865219652206522165222652236522465225652266522765228652296523065231652326523365234652356523665237652386523965240652416524265243652446524565246652476524865249652506525165252652536525465255652566525765258652596526065261652626526365264652656526665267652686526965270652716527265273652746527565276652776527865279652806528165282652836528465285652866528765288652896529065291652926529365294652956529665297652986529965300653016530265303653046530565306653076530865309653106531165312653136531465315653166531765318653196532065321653226532365324653256532665327653286532965330653316533265333653346533565336653376533865339653406534165342653436534465345653466534765348653496535065351653526535365354653556535665357653586535965360653616536265363653646536565366653676536865369653706537165372653736537465375653766537765378653796538065381653826538365384653856538665387653886538965390653916539265393653946539565396653976539865399654006540165402654036540465405654066540765408654096541065411654126541365414654156541665417654186541965420654216542265423654246542565426654276542865429654306543165432654336543465435654366543765438654396544065441654426544365444654456544665447654486544965450654516545265453654546545565456654576545865459654606546165462654636546465465654666546765468654696547065471654726547365474654756547665477654786547965480654816548265483654846548565486654876548865489654906549165492654936549465495654966549765498654996550065501655026550365504655056550665507655086550965510655116551265513655146551565516655176551865519655206552165522655236552465525655266552765528655296553065531655326553365534655356553665537655386553965540655416554265543655446554565546655476554865549655506555165552655536555465555655566555765558655596556065561655626556365564655656556665567655686556965570655716557265573655746557565576655776557865579655806558165582655836558465585655866558765588655896559065591655926559365594655956559665597655986559965600656016560265603656046560565606656076560865609656106561165612656136561465615656166561765618656196562065621656226562365624656256562665627656286562965630656316563265633656346563565636656376563865639656406564165642656436564465645656466564765648656496565065651656526565365654656556565665657656586565965660656616566265663656646566565666656676566865669656706567165672656736567465675656766567765678656796568065681656826568365684656856568665687656886568965690656916569265693656946569565696656976569865699657006570165702657036570465705657066570765708657096571065711657126571365714657156571665717657186571965720657216572265723657246572565726657276572865729657306573165732657336573465735657366573765738657396574065741657426574365744657456574665747657486574965750657516575265753657546575565756657576575865759657606576165762657636576465765657666576765768657696577065771657726577365774657756577665777657786577965780657816578265783657846578565786657876578865789657906579165792657936579465795657966579765798657996580065801658026580365804658056580665807658086580965810658116581265813658146581565816658176581865819658206582165822658236582465825658266582765828658296583065831658326583365834658356583665837658386583965840658416584265843658446584565846658476584865849658506585165852658536585465855658566585765858658596586065861658626586365864658656586665867658686586965870658716587265873658746587565876658776587865879658806588165882658836588465885658866588765888658896589065891658926589365894658956589665897658986589965900659016590265903659046590565906659076590865909659106591165912659136591465915659166591765918659196592065921659226592365924659256592665927659286592965930659316593265933659346593565936659376593865939659406594165942659436594465945659466594765948659496595065951659526595365954659556595665957659586595965960659616596265963659646596565966659676596865969659706597165972659736597465975659766597765978659796598065981659826598365984659856598665987659886598965990659916599265993659946599565996659976599865999660006600166002660036600466005660066600766008660096601066011660126601366014660156601666017660186601966020660216602266023660246602566026660276602866029660306603166032660336603466035660366603766038660396604066041660426604366044660456604666047660486604966050660516605266053660546605566056660576605866059660606606166062660636606466065660666606766068660696607066071660726607366074660756607666077660786607966080660816608266083660846608566086660876608866089660906609166092660936609466095660966609766098660996610066101661026610366104661056610666107661086610966110661116611266113661146611566116661176611866119661206612166122661236612466125661266612766128661296613066131661326613366134661356613666137661386613966140661416614266143661446614566146661476614866149661506615166152661536615466155661566615766158661596616066161661626616366164661656616666167661686616966170661716617266173661746617566176661776617866179661806618166182661836618466185661866618766188661896619066191661926619366194661956619666197661986619966200662016620266203662046620566206662076620866209662106621166212662136621466215662166621766218662196622066221662226622366224662256622666227662286622966230662316623266233662346623566236662376623866239662406624166242662436624466245662466624766248662496625066251662526625366254662556625666257662586625966260662616626266263662646626566266662676626866269662706627166272662736627466275662766627766278662796628066281662826628366284662856628666287662886628966290662916629266293662946629566296662976629866299663006630166302663036630466305663066630766308663096631066311663126631366314663156631666317663186631966320663216632266323663246632566326663276632866329663306633166332663336633466335663366633766338663396634066341663426634366344663456634666347663486634966350663516635266353663546635566356663576635866359663606636166362663636636466365663666636766368663696637066371663726637366374663756637666377663786637966380663816638266383663846638566386663876638866389663906639166392663936639466395663966639766398663996640066401664026640366404664056640666407664086640966410664116641266413664146641566416664176641866419664206642166422664236642466425664266642766428664296643066431664326643366434664356643666437664386643966440664416644266443664446644566446664476644866449664506645166452664536645466455664566645766458664596646066461664626646366464664656646666467664686646966470664716647266473664746647566476664776647866479664806648166482664836648466485664866648766488664896649066491664926649366494664956649666497664986649966500665016650266503665046650566506665076650866509665106651166512665136651466515665166651766518665196652066521665226652366524665256652666527665286652966530665316653266533665346653566536665376653866539665406654166542665436654466545665466654766548665496655066551665526655366554665556655666557665586655966560665616656266563665646656566566665676656866569665706657166572665736657466575665766657766578665796658066581665826658366584665856658666587665886658966590665916659266593665946659566596665976659866599666006660166602666036660466605666066660766608666096661066611666126661366614666156661666617666186661966620666216662266623666246662566626666276662866629666306663166632666336663466635666366663766638666396664066641666426664366644666456664666647666486664966650666516665266653666546665566656666576665866659666606666166662666636666466665666666666766668666696667066671666726667366674666756667666677666786667966680666816668266683666846668566686666876668866689666906669166692666936669466695666966669766698666996670066701667026670366704667056670666707667086670966710667116671266713667146671566716667176671866719667206672166722667236672466725667266672766728667296673066731667326673366734667356673666737667386673966740667416674266743667446674566746667476674866749667506675166752667536675466755667566675766758667596676066761667626676366764667656676666767667686676966770667716677266773667746677566776667776677866779667806678166782667836678466785667866678766788667896679066791667926679366794667956679666797667986679966800668016680266803668046680566806668076680866809668106681166812668136681466815668166681766818668196682066821668226682366824668256682666827668286682966830668316683266833668346683566836668376683866839668406684166842668436684466845668466684766848668496685066851668526685366854668556685666857668586685966860668616686266863668646686566866668676686866869668706687166872668736687466875668766687766878668796688066881668826688366884668856688666887668886688966890668916689266893668946689566896668976689866899669006690166902669036690466905669066690766908669096691066911669126691366914669156691666917669186691966920669216692266923669246692566926669276692866929669306693166932669336693466935669366693766938669396694066941669426694366944669456694666947669486694966950669516695266953669546695566956669576695866959669606696166962669636696466965669666696766968669696697066971669726697366974669756697666977669786697966980669816698266983669846698566986669876698866989669906699166992669936699466995669966699766998669996700067001670026700367004670056700667007670086700967010670116701267013670146701567016670176701867019670206702167022670236702467025670266702767028670296703067031670326703367034670356703667037670386703967040670416704267043670446704567046670476704867049670506705167052670536705467055670566705767058670596706067061670626706367064670656706667067670686706967070670716707267073670746707567076670776707867079670806708167082670836708467085670866708767088670896709067091670926709367094670956709667097670986709967100671016710267103671046710567106671076710867109671106711167112671136711467115671166711767118671196712067121671226712367124671256712667127671286712967130671316713267133671346713567136671376713867139671406714167142671436714467145671466714767148671496715067151671526715367154671556715667157671586715967160671616716267163671646716567166671676716867169671706717167172671736717467175671766717767178671796718067181671826718367184671856718667187671886718967190671916719267193671946719567196671976719867199672006720167202672036720467205672066720767208672096721067211672126721367214672156721667217672186721967220672216722267223672246722567226672276722867229672306723167232672336723467235672366723767238672396724067241672426724367244672456724667247672486724967250672516725267253672546725567256672576725867259672606726167262672636726467265672666726767268672696727067271672726727367274672756727667277672786727967280672816728267283672846728567286672876728867289672906729167292672936729467295672966729767298672996730067301673026730367304673056730667307673086730967310673116731267313673146731567316673176731867319673206732167322673236732467325673266732767328673296733067331673326733367334673356733667337673386733967340673416734267343673446734567346673476734867349673506735167352673536735467355673566735767358673596736067361673626736367364673656736667367673686736967370673716737267373673746737567376673776737867379673806738167382673836738467385673866738767388673896739067391673926739367394673956739667397673986739967400674016740267403674046740567406674076740867409674106741167412674136741467415674166741767418674196742067421674226742367424674256742667427674286742967430674316743267433674346743567436674376743867439674406744167442674436744467445674466744767448674496745067451674526745367454674556745667457674586745967460674616746267463674646746567466674676746867469674706747167472674736747467475674766747767478674796748067481674826748367484674856748667487674886748967490674916749267493674946749567496674976749867499675006750167502675036750467505675066750767508675096751067511675126751367514675156751667517675186751967520675216752267523675246752567526675276752867529675306753167532675336753467535675366753767538675396754067541675426754367544675456754667547675486754967550675516755267553675546755567556675576755867559675606756167562675636756467565675666756767568675696757067571675726757367574675756757667577675786757967580675816758267583675846758567586675876758867589675906759167592675936759467595675966759767598675996760067601676026760367604676056760667607676086760967610676116761267613676146761567616676176761867619676206762167622676236762467625676266762767628676296763067631676326763367634676356763667637676386763967640676416764267643676446764567646676476764867649676506765167652676536765467655676566765767658676596766067661676626766367664676656766667667676686766967670676716767267673676746767567676676776767867679676806768167682676836768467685676866768767688676896769067691676926769367694676956769667697676986769967700677016770267703677046770567706677076770867709677106771167712677136771467715677166771767718677196772067721677226772367724677256772667727677286772967730677316773267733677346773567736677376773867739677406774167742677436774467745677466774767748677496775067751677526775367754677556775667757677586775967760677616776267763677646776567766677676776867769677706777167772677736777467775677766777767778677796778067781677826778367784677856778667787677886778967790677916779267793677946779567796677976779867799678006780167802678036780467805678066780767808678096781067811678126781367814678156781667817678186781967820678216782267823678246782567826678276782867829678306783167832678336783467835678366783767838678396784067841678426784367844678456784667847678486784967850678516785267853678546785567856678576785867859678606786167862678636786467865678666786767868678696787067871678726787367874678756787667877678786787967880678816788267883678846788567886678876788867889678906789167892678936789467895678966789767898678996790067901679026790367904679056790667907679086790967910679116791267913679146791567916679176791867919679206792167922679236792467925679266792767928679296793067931679326793367934679356793667937679386793967940679416794267943679446794567946679476794867949679506795167952679536795467955679566795767958679596796067961679626796367964679656796667967679686796967970679716797267973679746797567976679776797867979679806798167982679836798467985679866798767988679896799067991679926799367994679956799667997679986799968000680016800268003680046800568006680076800868009680106801168012680136801468015680166801768018680196802068021680226802368024680256802668027680286802968030680316803268033680346803568036680376803868039680406804168042680436804468045680466804768048680496805068051680526805368054680556805668057680586805968060680616806268063680646806568066680676806868069680706807168072680736807468075680766807768078680796808068081680826808368084680856808668087680886808968090680916809268093680946809568096680976809868099681006810168102681036810468105681066810768108681096811068111681126811368114681156811668117681186811968120681216812268123681246812568126681276812868129681306813168132681336813468135681366813768138681396814068141681426814368144681456814668147681486814968150681516815268153681546815568156681576815868159681606816168162681636816468165681666816768168681696817068171681726817368174681756817668177681786817968180681816818268183681846818568186681876818868189681906819168192681936819468195681966819768198681996820068201682026820368204682056820668207682086820968210682116821268213682146821568216682176821868219682206822168222682236822468225682266822768228682296823068231682326823368234682356823668237682386823968240682416824268243682446824568246682476824868249682506825168252682536825468255682566825768258682596826068261682626826368264682656826668267682686826968270682716827268273682746827568276682776827868279682806828168282682836828468285682866828768288682896829068291682926829368294682956829668297682986829968300683016830268303683046830568306683076830868309683106831168312683136831468315683166831768318683196832068321683226832368324683256832668327683286832968330683316833268333683346833568336683376833868339683406834168342683436834468345683466834768348683496835068351683526835368354683556835668357683586835968360683616836268363683646836568366683676836868369683706837168372683736837468375683766837768378683796838068381683826838368384683856838668387683886838968390683916839268393683946839568396683976839868399684006840168402684036840468405684066840768408684096841068411684126841368414684156841668417684186841968420684216842268423684246842568426684276842868429684306843168432684336843468435684366843768438684396844068441684426844368444684456844668447684486844968450684516845268453684546845568456684576845868459684606846168462684636846468465684666846768468684696847068471684726847368474684756847668477684786847968480684816848268483684846848568486684876848868489684906849168492684936849468495684966849768498684996850068501685026850368504685056850668507685086850968510685116851268513685146851568516685176851868519685206852168522685236852468525685266852768528685296853068531685326853368534685356853668537685386853968540685416854268543685446854568546685476854868549685506855168552685536855468555685566855768558685596856068561685626856368564685656856668567685686856968570685716857268573685746857568576685776857868579685806858168582685836858468585685866858768588685896859068591685926859368594685956859668597685986859968600686016860268603686046860568606686076860868609686106861168612686136861468615686166861768618686196862068621686226862368624686256862668627686286862968630686316863268633686346863568636686376863868639686406864168642686436864468645686466864768648686496865068651686526865368654686556865668657686586865968660686616866268663686646866568666686676866868669686706867168672686736867468675686766867768678686796868068681686826868368684686856868668687686886868968690686916869268693686946869568696686976869868699687006870168702687036870468705687066870768708687096871068711687126871368714687156871668717687186871968720687216872268723687246872568726687276872868729687306873168732687336873468735687366873768738687396874068741687426874368744687456874668747687486874968750687516875268753687546875568756687576875868759687606876168762687636876468765687666876768768687696877068771687726877368774687756877668777687786877968780687816878268783687846878568786687876878868789687906879168792687936879468795687966879768798687996880068801688026880368804688056880668807688086880968810688116881268813688146881568816688176881868819688206882168822688236882468825688266882768828688296883068831688326883368834688356883668837688386883968840688416884268843688446884568846688476884868849688506885168852688536885468855688566885768858688596886068861688626886368864688656886668867688686886968870688716887268873688746887568876688776887868879688806888168882688836888468885688866888768888688896889068891688926889368894688956889668897688986889968900689016890268903689046890568906689076890868909689106891168912689136891468915689166891768918689196892068921689226892368924689256892668927689286892968930689316893268933689346893568936689376893868939689406894168942689436894468945689466894768948689496895068951689526895368954689556895668957689586895968960689616896268963689646896568966689676896868969689706897168972689736897468975689766897768978689796898068981689826898368984689856898668987689886898968990689916899268993689946899568996689976899868999690006900169002690036900469005690066900769008690096901069011690126901369014690156901669017690186901969020690216902269023690246902569026690276902869029690306903169032690336903469035690366903769038690396904069041690426904369044690456904669047690486904969050690516905269053690546905569056690576905869059690606906169062690636906469065690666906769068690696907069071690726907369074690756907669077690786907969080690816908269083690846908569086690876908869089690906909169092690936909469095690966909769098690996910069101691026910369104691056910669107691086910969110691116911269113691146911569116691176911869119691206912169122691236912469125691266912769128691296913069131691326913369134691356913669137691386913969140691416914269143691446914569146691476914869149691506915169152691536915469155691566915769158691596916069161691626916369164691656916669167691686916969170691716917269173691746917569176691776917869179691806918169182691836918469185691866918769188691896919069191691926919369194691956919669197691986919969200692016920269203692046920569206692076920869209692106921169212692136921469215692166921769218692196922069221692226922369224692256922669227692286922969230692316923269233692346923569236692376923869239692406924169242692436924469245692466924769248692496925069251692526925369254692556925669257692586925969260692616926269263692646926569266692676926869269692706927169272692736927469275692766927769278692796928069281692826928369284692856928669287692886928969290692916929269293692946929569296692976929869299693006930169302693036930469305693066930769308693096931069311693126931369314693156931669317693186931969320693216932269323693246932569326693276932869329693306933169332693336933469335693366933769338693396934069341693426934369344693456934669347693486934969350693516935269353693546935569356693576935869359693606936169362693636936469365693666936769368693696937069371693726937369374693756937669377693786937969380693816938269383693846938569386693876938869389693906939169392693936939469395693966939769398693996940069401694026940369404694056940669407694086940969410694116941269413694146941569416694176941869419694206942169422694236942469425694266942769428694296943069431694326943369434694356943669437694386943969440694416944269443694446944569446694476944869449694506945169452694536945469455694566945769458694596946069461694626946369464694656946669467694686946969470694716947269473694746947569476694776947869479694806948169482694836948469485694866948769488694896949069491694926949369494694956949669497694986949969500695016950269503695046950569506695076950869509695106951169512695136951469515695166951769518695196952069521695226952369524695256952669527695286952969530695316953269533695346953569536695376953869539695406954169542695436954469545695466954769548695496955069551695526955369554695556955669557695586955969560695616956269563695646956569566695676956869569695706957169572695736957469575695766957769578695796958069581695826958369584695856958669587695886958969590695916959269593695946959569596695976959869599696006960169602696036960469605696066960769608696096961069611696126961369614696156961669617696186961969620696216962269623696246962569626696276962869629696306963169632696336963469635696366963769638696396964069641696426964369644696456964669647696486964969650696516965269653696546965569656696576965869659696606966169662696636966469665696666966769668696696967069671696726967369674696756967669677696786967969680696816968269683696846968569686696876968869689696906969169692696936969469695696966969769698696996970069701697026970369704697056970669707697086970969710697116971269713697146971569716697176971869719697206972169722697236972469725697266972769728697296973069731697326973369734697356973669737697386973969740697416974269743697446974569746697476974869749697506975169752697536975469755697566975769758697596976069761697626976369764697656976669767697686976969770697716977269773697746977569776697776977869779697806978169782697836978469785697866978769788697896979069791697926979369794697956979669797697986979969800698016980269803698046980569806698076980869809698106981169812698136981469815698166981769818698196982069821698226982369824698256982669827698286982969830698316983269833698346983569836698376983869839698406984169842698436984469845698466984769848698496985069851698526985369854698556985669857698586985969860698616986269863698646986569866698676986869869698706987169872698736987469875698766987769878698796988069881698826988369884698856988669887698886988969890698916989269893698946989569896698976989869899699006990169902699036990469905699066990769908699096991069911699126991369914699156991669917699186991969920699216992269923699246992569926699276992869929699306993169932699336993469935699366993769938699396994069941699426994369944699456994669947699486994969950699516995269953699546995569956699576995869959699606996169962699636996469965699666996769968699696997069971699726997369974699756997669977699786997969980699816998269983699846998569986699876998869989699906999169992699936999469995699966999769998699997000070001700027000370004700057000670007700087000970010700117001270013700147001570016700177001870019700207002170022700237002470025700267002770028700297003070031700327003370034700357003670037700387003970040700417004270043700447004570046700477004870049700507005170052700537005470055700567005770058700597006070061700627006370064700657006670067700687006970070700717007270073700747007570076700777007870079700807008170082700837008470085700867008770088700897009070091700927009370094700957009670097700987009970100701017010270103701047010570106701077010870109701107011170112701137011470115701167011770118701197012070121701227012370124701257012670127701287012970130701317013270133701347013570136701377013870139701407014170142701437014470145701467014770148701497015070151701527015370154701557015670157701587015970160701617016270163701647016570166701677016870169701707017170172701737017470175701767017770178701797018070181701827018370184701857018670187701887018970190701917019270193701947019570196701977019870199702007020170202702037020470205702067020770208702097021070211702127021370214702157021670217702187021970220702217022270223702247022570226702277022870229702307023170232702337023470235702367023770238702397024070241702427024370244702457024670247702487024970250702517025270253702547025570256702577025870259702607026170262702637026470265702667026770268702697027070271702727027370274702757027670277702787027970280702817028270283702847028570286702877028870289702907029170292702937029470295702967029770298702997030070301703027030370304703057030670307703087030970310703117031270313703147031570316703177031870319703207032170322703237032470325703267032770328703297033070331703327033370334703357033670337703387033970340703417034270343703447034570346703477034870349703507035170352703537035470355703567035770358703597036070361703627036370364703657036670367703687036970370703717037270373703747037570376703777037870379703807038170382703837038470385703867038770388703897039070391703927039370394703957039670397703987039970400704017040270403704047040570406704077040870409704107041170412704137041470415704167041770418704197042070421704227042370424704257042670427704287042970430704317043270433704347043570436704377043870439704407044170442704437044470445704467044770448704497045070451704527045370454704557045670457704587045970460704617046270463704647046570466704677046870469704707047170472704737047470475704767047770478704797048070481704827048370484704857048670487704887048970490704917049270493704947049570496704977049870499705007050170502705037050470505705067050770508705097051070511705127051370514705157051670517705187051970520705217052270523705247052570526705277052870529705307053170532705337053470535705367053770538705397054070541705427054370544705457054670547705487054970550705517055270553705547055570556705577055870559705607056170562705637056470565705667056770568705697057070571705727057370574705757057670577705787057970580705817058270583705847058570586705877058870589705907059170592705937059470595705967059770598705997060070601706027060370604706057060670607706087060970610706117061270613706147061570616706177061870619706207062170622706237062470625706267062770628706297063070631706327063370634706357063670637706387063970640706417064270643706447064570646706477064870649706507065170652706537065470655706567065770658706597066070661706627066370664706657066670667706687066970670706717067270673706747067570676706777067870679706807068170682706837068470685706867068770688706897069070691706927069370694706957069670697706987069970700707017070270703707047070570706707077070870709707107071170712707137071470715707167071770718707197072070721707227072370724707257072670727707287072970730707317073270733707347073570736707377073870739707407074170742707437074470745707467074770748707497075070751707527075370754707557075670757707587075970760707617076270763707647076570766707677076870769707707077170772707737077470775707767077770778707797078070781707827078370784707857078670787707887078970790707917079270793707947079570796707977079870799708007080170802708037080470805708067080770808708097081070811708127081370814708157081670817708187081970820708217082270823708247082570826708277082870829708307083170832708337083470835708367083770838708397084070841708427084370844708457084670847708487084970850708517085270853708547085570856708577085870859708607086170862708637086470865708667086770868708697087070871708727087370874708757087670877708787087970880708817088270883708847088570886708877088870889708907089170892708937089470895708967089770898708997090070901709027090370904709057090670907709087090970910709117091270913709147091570916709177091870919709207092170922709237092470925709267092770928709297093070931709327093370934709357093670937709387093970940709417094270943709447094570946709477094870949709507095170952709537095470955709567095770958709597096070961709627096370964709657096670967709687096970970709717097270973709747097570976709777097870979709807098170982709837098470985709867098770988709897099070991709927099370994709957099670997709987099971000710017100271003710047100571006710077100871009710107101171012710137101471015710167101771018710197102071021710227102371024710257102671027710287102971030710317103271033710347103571036710377103871039710407104171042710437104471045710467104771048710497105071051710527105371054710557105671057710587105971060710617106271063710647106571066710677106871069710707107171072710737107471075710767107771078710797108071081710827108371084710857108671087710887108971090710917109271093710947109571096710977109871099711007110171102711037110471105711067110771108711097111071111711127111371114711157111671117711187111971120711217112271123711247112571126711277112871129711307113171132711337113471135711367113771138711397114071141711427114371144711457114671147711487114971150711517115271153711547115571156711577115871159711607116171162711637116471165711667116771168711697117071171711727117371174711757117671177711787117971180711817118271183711847118571186711877118871189711907119171192711937119471195711967119771198711997120071201712027120371204712057120671207712087120971210712117121271213712147121571216712177121871219712207122171222712237122471225712267122771228712297123071231712327123371234712357123671237712387123971240712417124271243712447124571246712477124871249712507125171252712537125471255712567125771258712597126071261712627126371264712657126671267712687126971270712717127271273712747127571276712777127871279712807128171282712837128471285712867128771288712897129071291712927129371294712957129671297712987129971300713017130271303713047130571306713077130871309713107131171312713137131471315713167131771318713197132071321713227132371324713257132671327713287132971330713317133271333713347133571336713377133871339713407134171342713437134471345713467134771348713497135071351713527135371354713557135671357713587135971360713617136271363713647136571366713677136871369713707137171372713737137471375713767137771378713797138071381713827138371384713857138671387713887138971390713917139271393713947139571396713977139871399714007140171402714037140471405714067140771408714097141071411714127141371414714157141671417714187141971420714217142271423714247142571426714277142871429714307143171432714337143471435714367143771438714397144071441714427144371444714457144671447714487144971450714517145271453714547145571456714577145871459714607146171462714637146471465714667146771468714697147071471714727147371474714757147671477714787147971480714817148271483714847148571486714877148871489714907149171492714937149471495714967149771498714997150071501715027150371504715057150671507715087150971510715117151271513715147151571516715177151871519715207152171522715237152471525715267152771528715297153071531715327153371534715357153671537715387153971540715417154271543715447154571546715477154871549715507155171552715537155471555715567155771558715597156071561715627156371564715657156671567715687156971570715717157271573715747157571576715777157871579715807158171582715837158471585715867158771588715897159071591715927159371594715957159671597715987159971600716017160271603716047160571606716077160871609716107161171612716137161471615716167161771618716197162071621716227162371624716257162671627716287162971630716317163271633716347163571636716377163871639716407164171642716437164471645716467164771648716497165071651716527165371654716557165671657716587165971660716617166271663716647166571666716677166871669716707167171672716737167471675716767167771678716797168071681716827168371684716857168671687716887168971690716917169271693716947169571696716977169871699717007170171702717037170471705717067170771708717097171071711717127171371714717157171671717717187171971720717217172271723717247172571726717277172871729717307173171732717337173471735717367173771738717397174071741717427174371744717457174671747717487174971750717517175271753717547175571756717577175871759717607176171762717637176471765717667176771768717697177071771717727177371774717757177671777717787177971780717817178271783717847178571786717877178871789717907179171792717937179471795717967179771798717997180071801718027180371804718057180671807718087180971810718117181271813718147181571816718177181871819718207182171822718237182471825718267182771828718297183071831718327183371834718357183671837718387183971840718417184271843718447184571846718477184871849718507185171852718537185471855718567185771858718597186071861718627186371864718657186671867718687186971870718717187271873718747187571876718777187871879718807188171882718837188471885718867188771888718897189071891718927189371894718957189671897718987189971900719017190271903719047190571906719077190871909719107191171912719137191471915719167191771918719197192071921719227192371924719257192671927719287192971930719317193271933719347193571936719377193871939719407194171942719437194471945719467194771948719497195071951719527195371954719557195671957719587195971960719617196271963719647196571966719677196871969719707197171972719737197471975719767197771978719797198071981719827198371984719857198671987719887198971990719917199271993719947199571996719977199871999720007200172002720037200472005720067200772008720097201072011720127201372014720157201672017720187201972020720217202272023720247202572026720277202872029720307203172032720337203472035720367203772038720397204072041720427204372044720457204672047720487204972050720517205272053720547205572056720577205872059720607206172062720637206472065720667206772068720697207072071720727207372074720757207672077720787207972080720817208272083720847208572086720877208872089720907209172092720937209472095720967209772098720997210072101721027210372104721057210672107721087210972110721117211272113721147211572116721177211872119721207212172122721237212472125721267212772128721297213072131721327213372134721357213672137721387213972140721417214272143721447214572146721477214872149721507215172152721537215472155721567215772158721597216072161721627216372164721657216672167721687216972170721717217272173721747217572176721777217872179721807218172182721837218472185721867218772188721897219072191721927219372194721957219672197721987219972200722017220272203722047220572206722077220872209722107221172212722137221472215722167221772218722197222072221722227222372224722257222672227722287222972230722317223272233722347223572236722377223872239722407224172242722437224472245722467224772248722497225072251722527225372254722557225672257722587225972260722617226272263722647226572266722677226872269722707227172272722737227472275722767227772278722797228072281722827228372284722857228672287722887228972290722917229272293722947229572296722977229872299723007230172302723037230472305723067230772308723097231072311723127231372314723157231672317723187231972320723217232272323723247232572326723277232872329723307233172332723337233472335723367233772338723397234072341723427234372344723457234672347723487234972350723517235272353723547235572356723577235872359723607236172362723637236472365723667236772368723697237072371723727237372374723757237672377723787237972380723817238272383723847238572386723877238872389723907239172392723937239472395723967239772398723997240072401724027240372404724057240672407724087240972410724117241272413724147241572416724177241872419724207242172422724237242472425724267242772428724297243072431724327243372434724357243672437724387243972440724417244272443724447244572446724477244872449724507245172452724537245472455724567245772458724597246072461724627246372464724657246672467724687246972470724717247272473724747247572476724777247872479724807248172482724837248472485724867248772488724897249072491724927249372494724957249672497724987249972500725017250272503725047250572506725077250872509725107251172512725137251472515725167251772518725197252072521725227252372524725257252672527725287252972530725317253272533725347253572536725377253872539725407254172542725437254472545725467254772548725497255072551725527255372554725557255672557725587255972560725617256272563725647256572566725677256872569725707257172572725737257472575725767257772578725797258072581725827258372584725857258672587725887258972590725917259272593725947259572596725977259872599726007260172602726037260472605726067260772608726097261072611726127261372614726157261672617726187261972620726217262272623726247262572626726277262872629726307263172632726337263472635726367263772638726397264072641726427264372644726457264672647726487264972650726517265272653726547265572656726577265872659726607266172662726637266472665726667266772668726697267072671726727267372674726757267672677726787267972680726817268272683726847268572686726877268872689726907269172692726937269472695726967269772698726997270072701727027270372704727057270672707727087270972710727117271272713727147271572716727177271872719727207272172722727237272472725727267272772728727297273072731727327273372734727357273672737727387273972740727417274272743727447274572746727477274872749727507275172752727537275472755727567275772758727597276072761727627276372764727657276672767727687276972770727717277272773727747277572776727777277872779727807278172782727837278472785727867278772788727897279072791727927279372794727957279672797727987279972800728017280272803728047280572806728077280872809728107281172812728137281472815728167281772818728197282072821728227282372824728257282672827728287282972830728317283272833728347283572836728377283872839728407284172842728437284472845728467284772848728497285072851728527285372854728557285672857728587285972860728617286272863728647286572866728677286872869728707287172872728737287472875728767287772878728797288072881728827288372884728857288672887728887288972890728917289272893728947289572896728977289872899729007290172902729037290472905729067290772908729097291072911729127291372914729157291672917729187291972920729217292272923729247292572926729277292872929729307293172932729337293472935729367293772938729397294072941729427294372944729457294672947729487294972950729517295272953729547295572956729577295872959729607296172962729637296472965729667296772968729697297072971729727297372974729757297672977729787297972980729817298272983729847298572986729877298872989729907299172992729937299472995729967299772998729997300073001730027300373004730057300673007730087300973010730117301273013730147301573016730177301873019730207302173022730237302473025730267302773028730297303073031730327303373034730357303673037730387303973040730417304273043730447304573046730477304873049730507305173052730537305473055730567305773058730597306073061730627306373064730657306673067730687306973070730717307273073730747307573076730777307873079730807308173082730837308473085730867308773088730897309073091730927309373094730957309673097730987309973100731017310273103731047310573106731077310873109731107311173112731137311473115731167311773118731197312073121731227312373124731257312673127731287312973130731317313273133731347313573136731377313873139731407314173142731437314473145731467314773148731497315073151731527315373154731557315673157731587315973160731617316273163731647316573166731677316873169731707317173172731737317473175731767317773178731797318073181731827318373184731857318673187731887318973190731917319273193731947319573196731977319873199732007320173202732037320473205732067320773208732097321073211732127321373214732157321673217732187321973220732217322273223732247322573226732277322873229732307323173232732337323473235732367323773238732397324073241732427324373244732457324673247732487324973250732517325273253732547325573256732577325873259732607326173262732637326473265732667326773268732697327073271732727327373274732757327673277732787327973280732817328273283732847328573286732877328873289732907329173292732937329473295732967329773298732997330073301733027330373304733057330673307733087330973310733117331273313733147331573316733177331873319733207332173322733237332473325733267332773328733297333073331733327333373334733357333673337733387333973340733417334273343733447334573346733477334873349733507335173352733537335473355733567335773358733597336073361733627336373364733657336673367733687336973370733717337273373733747337573376733777337873379733807338173382733837338473385733867338773388733897339073391733927339373394733957339673397733987339973400734017340273403734047340573406734077340873409734107341173412734137341473415734167341773418734197342073421734227342373424734257342673427734287342973430734317343273433734347343573436734377343873439734407344173442734437344473445734467344773448734497345073451734527345373454734557345673457734587345973460734617346273463734647346573466734677346873469734707347173472734737347473475734767347773478734797348073481734827348373484734857348673487734887348973490734917349273493734947349573496734977349873499735007350173502735037350473505735067350773508735097351073511735127351373514735157351673517735187351973520735217352273523735247352573526735277352873529735307353173532735337353473535735367353773538735397354073541735427354373544735457354673547735487354973550735517355273553735547355573556735577355873559735607356173562735637356473565735667356773568735697357073571735727357373574735757357673577735787357973580735817358273583735847358573586735877358873589735907359173592735937359473595735967359773598735997360073601736027360373604736057360673607736087360973610736117361273613736147361573616736177361873619736207362173622736237362473625736267362773628736297363073631736327363373634736357363673637736387363973640736417364273643736447364573646736477364873649736507365173652736537365473655736567365773658736597366073661736627366373664736657366673667736687366973670736717367273673736747367573676736777367873679736807368173682736837368473685736867368773688736897369073691736927369373694736957369673697736987369973700737017370273703737047370573706737077370873709737107371173712737137371473715737167371773718737197372073721737227372373724737257372673727737287372973730737317373273733737347373573736737377373873739737407374173742737437374473745737467374773748737497375073751737527375373754737557375673757737587375973760737617376273763737647376573766737677376873769737707377173772737737377473775737767377773778737797378073781737827378373784737857378673787737887378973790737917379273793737947379573796737977379873799738007380173802738037380473805738067380773808738097381073811738127381373814738157381673817738187381973820738217382273823738247382573826738277382873829738307383173832738337383473835738367383773838738397384073841738427384373844738457384673847738487384973850738517385273853738547385573856738577385873859738607386173862738637386473865738667386773868738697387073871738727387373874738757387673877738787387973880738817388273883738847388573886738877388873889738907389173892738937389473895738967389773898738997390073901739027390373904739057390673907739087390973910739117391273913739147391573916739177391873919739207392173922739237392473925739267392773928739297393073931739327393373934739357393673937739387393973940739417394273943739447394573946739477394873949739507395173952739537395473955739567395773958739597396073961739627396373964739657396673967739687396973970739717397273973739747397573976739777397873979739807398173982739837398473985739867398773988739897399073991739927399373994739957399673997739987399974000740017400274003740047400574006740077400874009740107401174012740137401474015740167401774018740197402074021740227402374024740257402674027740287402974030740317403274033740347403574036740377403874039740407404174042740437404474045740467404774048740497405074051740527405374054740557405674057740587405974060740617406274063740647406574066740677406874069740707407174072740737407474075740767407774078740797408074081740827408374084740857408674087740887408974090740917409274093740947409574096740977409874099741007410174102741037410474105741067410774108741097411074111741127411374114741157411674117741187411974120741217412274123741247412574126741277412874129741307413174132741337413474135741367413774138741397414074141741427414374144741457414674147741487414974150741517415274153741547415574156741577415874159741607416174162741637416474165741667416774168741697417074171741727417374174741757417674177741787417974180741817418274183741847418574186741877418874189741907419174192741937419474195741967419774198741997420074201742027420374204742057420674207742087420974210742117421274213742147421574216742177421874219742207422174222742237422474225742267422774228742297423074231742327423374234742357423674237742387423974240742417424274243742447424574246742477424874249742507425174252742537425474255742567425774258742597426074261742627426374264742657426674267742687426974270742717427274273742747427574276742777427874279742807428174282742837428474285742867428774288742897429074291742927429374294742957429674297742987429974300743017430274303743047430574306743077430874309743107431174312743137431474315743167431774318743197432074321743227432374324743257432674327743287432974330743317433274333743347433574336743377433874339743407434174342743437434474345743467434774348743497435074351743527435374354743557435674357743587435974360743617436274363743647436574366743677436874369743707437174372743737437474375743767437774378743797438074381743827438374384743857438674387743887438974390743917439274393743947439574396743977439874399744007440174402744037440474405744067440774408744097441074411744127441374414744157441674417744187441974420744217442274423744247442574426744277442874429744307443174432744337443474435744367443774438744397444074441744427444374444744457444674447744487444974450744517445274453744547445574456744577445874459744607446174462744637446474465744667446774468744697447074471744727447374474744757447674477744787447974480744817448274483744847448574486744877448874489744907449174492744937449474495744967449774498744997450074501745027450374504745057450674507745087450974510745117451274513745147451574516745177451874519745207452174522745237452474525745267452774528745297453074531745327453374534745357453674537745387453974540745417454274543745447454574546745477454874549745507455174552745537455474555745567455774558745597456074561745627456374564745657456674567745687456974570745717457274573745747457574576745777457874579745807458174582745837458474585745867458774588745897459074591745927459374594745957459674597745987459974600746017460274603746047460574606746077460874609746107461174612746137461474615746167461774618746197462074621746227462374624746257462674627746287462974630746317463274633746347463574636746377463874639746407464174642746437464474645746467464774648746497465074651746527465374654746557465674657746587465974660746617466274663746647466574666746677466874669746707467174672746737467474675746767467774678746797468074681746827468374684746857468674687746887468974690746917469274693746947469574696746977469874699747007470174702747037470474705747067470774708747097471074711747127471374714747157471674717747187471974720747217472274723747247472574726747277472874729747307473174732747337473474735747367473774738747397474074741747427474374744747457474674747747487474974750747517475274753747547475574756747577475874759747607476174762747637476474765747667476774768747697477074771747727477374774747757477674777747787477974780747817478274783747847478574786747877478874789747907479174792747937479474795747967479774798747997480074801748027480374804748057480674807748087480974810748117481274813748147481574816748177481874819748207482174822748237482474825748267482774828748297483074831748327483374834748357483674837748387483974840748417484274843748447484574846748477484874849748507485174852748537485474855748567485774858748597486074861748627486374864748657486674867748687486974870748717487274873748747487574876748777487874879748807488174882748837488474885748867488774888748897489074891748927489374894748957489674897748987489974900749017490274903749047490574906749077490874909749107491174912749137491474915749167491774918749197492074921749227492374924749257492674927749287492974930749317493274933749347493574936749377493874939749407494174942749437494474945749467494774948749497495074951749527495374954749557495674957749587495974960749617496274963749647496574966749677496874969749707497174972749737497474975749767497774978749797498074981749827498374984749857498674987749887498974990749917499274993749947499574996749977499874999750007500175002750037500475005750067500775008750097501075011750127501375014750157501675017750187501975020750217502275023750247502575026750277502875029750307503175032750337503475035750367503775038750397504075041750427504375044750457504675047750487504975050750517505275053750547505575056750577505875059750607506175062750637506475065750667506775068750697507075071750727507375074750757507675077750787507975080750817508275083750847508575086750877508875089750907509175092750937509475095750967509775098750997510075101751027510375104751057510675107751087510975110751117511275113751147511575116751177511875119751207512175122751237512475125751267512775128751297513075131751327513375134751357513675137751387513975140751417514275143751447514575146751477514875149751507515175152751537515475155751567515775158751597516075161751627516375164751657516675167751687516975170751717517275173751747517575176751777517875179751807518175182751837518475185751867518775188751897519075191751927519375194751957519675197751987519975200752017520275203752047520575206752077520875209752107521175212752137521475215752167521775218752197522075221752227522375224752257522675227752287522975230752317523275233752347523575236752377523875239752407524175242752437524475245752467524775248752497525075251752527525375254752557525675257752587525975260752617526275263752647526575266752677526875269752707527175272752737527475275752767527775278752797528075281752827528375284752857528675287752887528975290752917529275293752947529575296752977529875299753007530175302753037530475305753067530775308753097531075311753127531375314753157531675317753187531975320753217532275323753247532575326753277532875329753307533175332753337533475335753367533775338753397534075341753427534375344753457534675347753487534975350753517535275353753547535575356753577535875359753607536175362753637536475365753667536775368753697537075371753727537375374753757537675377753787537975380753817538275383753847538575386753877538875389753907539175392753937539475395753967539775398753997540075401754027540375404754057540675407754087540975410754117541275413754147541575416754177541875419754207542175422754237542475425754267542775428754297543075431754327543375434754357543675437754387543975440754417544275443754447544575446754477544875449754507545175452754537545475455754567545775458754597546075461754627546375464754657546675467754687546975470754717547275473754747547575476754777547875479754807548175482754837548475485754867548775488754897549075491754927549375494754957549675497754987549975500755017550275503755047550575506755077550875509755107551175512755137551475515755167551775518755197552075521755227552375524755257552675527755287552975530755317553275533755347553575536755377553875539755407554175542755437554475545755467554775548755497555075551755527555375554755557555675557755587555975560755617556275563755647556575566755677556875569755707557175572755737557475575755767557775578755797558075581755827558375584755857558675587755887558975590755917559275593755947559575596755977559875599756007560175602756037560475605756067560775608756097561075611756127561375614756157561675617756187561975620756217562275623756247562575626756277562875629756307563175632756337563475635756367563775638756397564075641756427564375644756457564675647756487564975650756517565275653756547565575656756577565875659756607566175662756637566475665756667566775668756697567075671756727567375674756757567675677756787567975680756817568275683756847568575686756877568875689756907569175692756937569475695756967569775698756997570075701757027570375704757057570675707757087570975710757117571275713757147571575716757177571875719757207572175722757237572475725757267572775728757297573075731757327573375734757357573675737757387573975740757417574275743757447574575746757477574875749757507575175752757537575475755757567575775758757597576075761757627576375764757657576675767757687576975770757717577275773757747577575776757777577875779757807578175782757837578475785757867578775788757897579075791757927579375794757957579675797757987579975800758017580275803758047580575806758077580875809758107581175812758137581475815758167581775818758197582075821758227582375824758257582675827758287582975830758317583275833758347583575836758377583875839758407584175842758437584475845758467584775848758497585075851758527585375854758557585675857758587585975860758617586275863758647586575866758677586875869758707587175872758737587475875758767587775878758797588075881758827588375884758857588675887758887588975890758917589275893758947589575896758977589875899759007590175902759037590475905759067590775908759097591075911759127591375914759157591675917759187591975920759217592275923759247592575926759277592875929759307593175932759337593475935759367593775938759397594075941759427594375944759457594675947759487594975950759517595275953759547595575956759577595875959759607596175962759637596475965759667596775968759697597075971759727597375974759757597675977759787597975980759817598275983759847598575986759877598875989759907599175992759937599475995759967599775998759997600076001760027600376004760057600676007760087600976010760117601276013760147601576016760177601876019760207602176022760237602476025760267602776028760297603076031760327603376034760357603676037760387603976040760417604276043760447604576046760477604876049760507605176052760537605476055760567605776058760597606076061760627606376064760657606676067760687606976070760717607276073760747607576076760777607876079760807608176082760837608476085760867608776088760897609076091760927609376094760957609676097760987609976100761017610276103761047610576106761077610876109761107611176112761137611476115761167611776118761197612076121761227612376124761257612676127761287612976130761317613276133761347613576136761377613876139761407614176142761437614476145761467614776148761497615076151761527615376154761557615676157761587615976160761617616276163761647616576166761677616876169761707617176172761737617476175761767617776178761797618076181761827618376184761857618676187761887618976190761917619276193761947619576196761977619876199762007620176202762037620476205762067620776208762097621076211762127621376214762157621676217762187621976220762217622276223762247622576226762277622876229762307623176232762337623476235762367623776238762397624076241762427624376244762457624676247762487624976250762517625276253762547625576256762577625876259762607626176262762637626476265762667626776268762697627076271762727627376274762757627676277762787627976280762817628276283762847628576286762877628876289762907629176292762937629476295762967629776298762997630076301763027630376304763057630676307763087630976310763117631276313763147631576316763177631876319763207632176322763237632476325763267632776328763297633076331763327633376334763357633676337763387633976340763417634276343763447634576346763477634876349763507635176352763537635476355763567635776358763597636076361763627636376364763657636676367763687636976370763717637276373763747637576376763777637876379763807638176382763837638476385763867638776388763897639076391763927639376394763957639676397763987639976400764017640276403764047640576406764077640876409764107641176412764137641476415764167641776418764197642076421764227642376424764257642676427764287642976430764317643276433764347643576436764377643876439764407644176442764437644476445764467644776448764497645076451764527645376454764557645676457764587645976460764617646276463764647646576466764677646876469764707647176472764737647476475764767647776478764797648076481764827648376484764857648676487764887648976490764917649276493764947649576496764977649876499765007650176502765037650476505765067650776508765097651076511765127651376514765157651676517765187651976520765217652276523765247652576526765277652876529765307653176532765337653476535765367653776538765397654076541765427654376544765457654676547765487654976550765517655276553765547655576556765577655876559765607656176562765637656476565765667656776568765697657076571765727657376574765757657676577765787657976580765817658276583765847658576586765877658876589765907659176592765937659476595765967659776598765997660076601766027660376604766057660676607766087660976610766117661276613766147661576616766177661876619766207662176622766237662476625766267662776628766297663076631766327663376634766357663676637766387663976640766417664276643766447664576646766477664876649766507665176652766537665476655766567665776658766597666076661766627666376664766657666676667766687666976670766717667276673766747667576676766777667876679766807668176682766837668476685766867668776688766897669076691766927669376694766957669676697766987669976700767017670276703767047670576706767077670876709767107671176712767137671476715767167671776718767197672076721767227672376724767257672676727767287672976730767317673276733767347673576736767377673876739767407674176742767437674476745767467674776748767497675076751767527675376754767557675676757767587675976760767617676276763767647676576766767677676876769767707677176772767737677476775767767677776778767797678076781767827678376784767857678676787767887678976790767917679276793767947679576796767977679876799768007680176802768037680476805768067680776808768097681076811768127681376814768157681676817768187681976820768217682276823768247682576826768277682876829768307683176832768337683476835768367683776838768397684076841768427684376844768457684676847768487684976850768517685276853768547685576856768577685876859768607686176862768637686476865768667686776868768697687076871768727687376874768757687676877768787687976880768817688276883768847688576886768877688876889768907689176892768937689476895768967689776898768997690076901769027690376904769057690676907769087690976910769117691276913769147691576916769177691876919769207692176922769237692476925769267692776928769297693076931769327693376934769357693676937769387693976940769417694276943769447694576946769477694876949769507695176952769537695476955769567695776958769597696076961769627696376964769657696676967769687696976970769717697276973769747697576976769777697876979769807698176982769837698476985769867698776988769897699076991769927699376994769957699676997769987699977000770017700277003770047700577006770077700877009770107701177012770137701477015770167701777018770197702077021770227702377024770257702677027770287702977030770317703277033770347703577036770377703877039770407704177042770437704477045770467704777048770497705077051770527705377054770557705677057770587705977060770617706277063770647706577066770677706877069770707707177072770737707477075770767707777078770797708077081770827708377084770857708677087770887708977090770917709277093770947709577096770977709877099771007710177102771037710477105771067710777108771097711077111771127711377114771157711677117771187711977120771217712277123771247712577126771277712877129771307713177132771337713477135771367713777138771397714077141771427714377144771457714677147771487714977150771517715277153771547715577156771577715877159771607716177162771637716477165771667716777168771697717077171771727717377174771757717677177771787717977180771817718277183771847718577186771877718877189771907719177192771937719477195771967719777198771997720077201772027720377204772057720677207772087720977210772117721277213772147721577216772177721877219772207722177222772237722477225772267722777228772297723077231772327723377234772357723677237772387723977240772417724277243772447724577246772477724877249772507725177252772537725477255772567725777258772597726077261772627726377264772657726677267772687726977270772717727277273772747727577276772777727877279772807728177282772837728477285772867728777288772897729077291772927729377294772957729677297772987729977300773017730277303773047730577306773077730877309773107731177312773137731477315773167731777318773197732077321773227732377324773257732677327773287732977330773317733277333773347733577336773377733877339773407734177342773437734477345773467734777348773497735077351773527735377354773557735677357773587735977360773617736277363773647736577366773677736877369773707737177372773737737477375773767737777378773797738077381773827738377384773857738677387773887738977390773917739277393773947739577396773977739877399774007740177402774037740477405774067740777408774097741077411774127741377414774157741677417774187741977420774217742277423774247742577426774277742877429774307743177432774337743477435774367743777438774397744077441774427744377444774457744677447774487744977450774517745277453774547745577456774577745877459774607746177462774637746477465774667746777468774697747077471774727747377474774757747677477774787747977480774817748277483774847748577486774877748877489774907749177492774937749477495774967749777498774997750077501775027750377504775057750677507775087750977510775117751277513775147751577516775177751877519775207752177522775237752477525775267752777528775297753077531775327753377534775357753677537775387753977540775417754277543775447754577546775477754877549775507755177552775537755477555775567755777558775597756077561775627756377564775657756677567775687756977570775717757277573775747757577576775777757877579775807758177582775837758477585775867758777588775897759077591775927759377594775957759677597775987759977600776017760277603776047760577606776077760877609776107761177612776137761477615776167761777618776197762077621776227762377624776257762677627776287762977630776317763277633776347763577636776377763877639776407764177642776437764477645776467764777648776497765077651776527765377654776557765677657776587765977660776617766277663776647766577666776677766877669776707767177672776737767477675776767767777678776797768077681776827768377684776857768677687776887768977690776917769277693776947769577696776977769877699777007770177702777037770477705777067770777708777097771077711777127771377714777157771677717777187771977720777217772277723777247772577726777277772877729777307773177732777337773477735777367773777738777397774077741777427774377744777457774677747777487774977750777517775277753777547775577756777577775877759777607776177762777637776477765777667776777768777697777077771777727777377774777757777677777777787777977780777817778277783777847778577786777877778877789777907779177792777937779477795777967779777798777997780077801778027780377804778057780677807778087780977810778117781277813778147781577816778177781877819778207782177822778237782477825778267782777828778297783077831778327783377834778357783677837778387783977840778417784277843778447784577846778477784877849778507785177852778537785477855778567785777858778597786077861778627786377864778657786677867778687786977870778717787277873778747787577876778777787877879778807788177882778837788477885778867788777888778897789077891778927789377894778957789677897778987789977900779017790277903779047790577906779077790877909779107791177912779137791477915779167791777918779197792077921779227792377924779257792677927779287792977930779317793277933779347793577936779377793877939779407794177942779437794477945779467794777948779497795077951779527795377954779557795677957779587795977960779617796277963779647796577966779677796877969779707797177972779737797477975779767797777978779797798077981779827798377984779857798677987779887798977990779917799277993779947799577996779977799877999780007800178002780037800478005780067800778008780097801078011780127801378014780157801678017780187801978020780217802278023780247802578026780277802878029780307803178032780337803478035780367803778038780397804078041780427804378044780457804678047780487804978050780517805278053780547805578056780577805878059780607806178062780637806478065780667806778068780697807078071780727807378074780757807678077780787807978080780817808278083780847808578086780877808878089780907809178092780937809478095780967809778098780997810078101781027810378104781057810678107781087810978110781117811278113781147811578116781177811878119781207812178122781237812478125781267812778128781297813078131781327813378134781357813678137781387813978140781417814278143781447814578146781477814878149781507815178152781537815478155781567815778158781597816078161781627816378164781657816678167781687816978170781717817278173781747817578176781777817878179781807818178182781837818478185781867818778188781897819078191781927819378194781957819678197781987819978200782017820278203782047820578206782077820878209782107821178212782137821478215782167821778218782197822078221782227822378224782257822678227782287822978230782317823278233782347823578236782377823878239782407824178242782437824478245782467824778248782497825078251782527825378254782557825678257782587825978260782617826278263782647826578266782677826878269782707827178272782737827478275782767827778278782797828078281782827828378284782857828678287782887828978290782917829278293782947829578296782977829878299783007830178302783037830478305783067830778308783097831078311783127831378314783157831678317783187831978320783217832278323783247832578326783277832878329783307833178332783337833478335783367833778338783397834078341783427834378344783457834678347783487834978350783517835278353783547835578356783577835878359783607836178362783637836478365783667836778368783697837078371783727837378374783757837678377783787837978380783817838278383783847838578386783877838878389783907839178392783937839478395783967839778398783997840078401784027840378404784057840678407784087840978410784117841278413784147841578416784177841878419784207842178422784237842478425784267842778428784297843078431784327843378434784357843678437784387843978440784417844278443784447844578446784477844878449784507845178452784537845478455784567845778458784597846078461784627846378464784657846678467784687846978470784717847278473784747847578476784777847878479784807848178482784837848478485784867848778488784897849078491784927849378494784957849678497784987849978500785017850278503785047850578506785077850878509785107851178512785137851478515785167851778518785197852078521785227852378524785257852678527785287852978530785317853278533785347853578536785377853878539785407854178542785437854478545785467854778548785497855078551785527855378554785557855678557785587855978560785617856278563785647856578566785677856878569785707857178572785737857478575785767857778578785797858078581785827858378584785857858678587785887858978590785917859278593785947859578596785977859878599786007860178602786037860478605786067860778608786097861078611786127861378614786157861678617786187861978620786217862278623786247862578626786277862878629786307863178632786337863478635786367863778638786397864078641786427864378644786457864678647786487864978650786517865278653786547865578656786577865878659786607866178662786637866478665786667866778668786697867078671786727867378674786757867678677786787867978680786817868278683786847868578686786877868878689786907869178692786937869478695786967869778698786997870078701787027870378704787057870678707787087870978710787117871278713787147871578716787177871878719787207872178722787237872478725787267872778728787297873078731787327873378734787357873678737787387873978740787417874278743787447874578746787477874878749787507875178752787537875478755787567875778758787597876078761787627876378764787657876678767787687876978770787717877278773787747877578776787777877878779787807878178782787837878478785787867878778788787897879078791787927879378794787957879678797787987879978800788017880278803788047880578806788077880878809788107881178812788137881478815788167881778818788197882078821788227882378824788257882678827788287882978830788317883278833788347883578836788377883878839788407884178842788437884478845788467884778848788497885078851788527885378854788557885678857788587885978860788617886278863788647886578866788677886878869788707887178872788737887478875788767887778878788797888078881788827888378884788857888678887788887888978890788917889278893788947889578896788977889878899789007890178902789037890478905789067890778908789097891078911789127891378914789157891678917789187891978920789217892278923789247892578926789277892878929789307893178932789337893478935789367893778938789397894078941789427894378944789457894678947789487894978950789517895278953789547895578956789577895878959789607896178962789637896478965789667896778968789697897078971789727897378974789757897678977789787897978980789817898278983789847898578986789877898878989789907899178992789937899478995789967899778998789997900079001790027900379004790057900679007790087900979010790117901279013790147901579016790177901879019790207902179022790237902479025790267902779028790297903079031790327903379034790357903679037790387903979040790417904279043790447904579046790477904879049790507905179052790537905479055790567905779058790597906079061790627906379064790657906679067790687906979070790717907279073790747907579076790777907879079790807908179082790837908479085790867908779088790897909079091790927909379094790957909679097790987909979100791017910279103791047910579106791077910879109791107911179112791137911479115791167911779118791197912079121791227912379124791257912679127791287912979130791317913279133791347913579136791377913879139791407914179142791437914479145791467914779148791497915079151791527915379154791557915679157791587915979160791617916279163791647916579166791677916879169791707917179172791737917479175791767917779178791797918079181791827918379184791857918679187791887918979190791917919279193791947919579196791977919879199792007920179202792037920479205792067920779208792097921079211792127921379214792157921679217792187921979220792217922279223792247922579226792277922879229792307923179232792337923479235792367923779238792397924079241792427924379244792457924679247792487924979250792517925279253792547925579256792577925879259792607926179262792637926479265792667926779268792697927079271792727927379274792757927679277792787927979280792817928279283792847928579286792877928879289792907929179292792937929479295792967929779298792997930079301793027930379304793057930679307793087930979310793117931279313793147931579316793177931879319793207932179322793237932479325793267932779328793297933079331793327933379334793357933679337793387933979340793417934279343793447934579346793477934879349793507935179352793537935479355793567935779358793597936079361793627936379364793657936679367793687936979370793717937279373793747937579376793777937879379793807938179382793837938479385793867938779388793897939079391793927939379394793957939679397793987939979400794017940279403794047940579406794077940879409794107941179412794137941479415794167941779418794197942079421794227942379424794257942679427794287942979430794317943279433794347943579436794377943879439794407944179442794437944479445794467944779448794497945079451794527945379454794557945679457794587945979460794617946279463794647946579466794677946879469794707947179472794737947479475794767947779478794797948079481794827948379484794857948679487794887948979490794917949279493794947949579496794977949879499795007950179502795037950479505795067950779508795097951079511795127951379514795157951679517795187951979520795217952279523795247952579526795277952879529795307953179532795337953479535795367953779538795397954079541795427954379544795457954679547795487954979550795517955279553795547955579556795577955879559795607956179562795637956479565795667956779568795697957079571795727957379574795757957679577795787957979580795817958279583795847958579586795877958879589795907959179592795937959479595795967959779598795997960079601796027960379604796057960679607796087960979610796117961279613796147961579616796177961879619796207962179622796237962479625796267962779628796297963079631796327963379634796357963679637796387963979640796417964279643796447964579646796477964879649796507965179652796537965479655796567965779658796597966079661796627966379664796657966679667796687966979670796717967279673796747967579676796777967879679796807968179682796837968479685796867968779688796897969079691796927969379694796957969679697796987969979700797017970279703797047970579706797077970879709797107971179712797137971479715797167971779718797197972079721797227972379724797257972679727797287972979730797317973279733797347973579736797377973879739797407974179742797437974479745797467974779748797497975079751797527975379754797557975679757797587975979760797617976279763797647976579766797677976879769797707977179772797737977479775797767977779778797797978079781797827978379784797857978679787797887978979790797917979279793797947979579796797977979879799798007980179802798037980479805798067980779808798097981079811798127981379814798157981679817798187981979820798217982279823798247982579826798277982879829798307983179832798337983479835798367983779838798397984079841798427984379844798457984679847798487984979850798517985279853798547985579856798577985879859798607986179862798637986479865798667986779868798697987079871798727987379874798757987679877798787987979880798817988279883798847988579886798877988879889798907989179892798937989479895798967989779898798997990079901799027990379904799057990679907799087990979910799117991279913799147991579916799177991879919799207992179922799237992479925799267992779928799297993079931799327993379934799357993679937799387993979940799417994279943799447994579946799477994879949799507995179952799537995479955799567995779958799597996079961799627996379964799657996679967799687996979970799717997279973799747997579976799777997879979799807998179982799837998479985799867998779988799897999079991799927999379994799957999679997799987999980000800018000280003800048000580006800078000880009800108001180012800138001480015800168001780018800198002080021800228002380024800258002680027800288002980030800318003280033800348003580036800378003880039800408004180042800438004480045800468004780048800498005080051800528005380054800558005680057800588005980060800618006280063800648006580066800678006880069800708007180072800738007480075800768007780078800798008080081800828008380084800858008680087800888008980090800918009280093800948009580096800978009880099801008010180102801038010480105801068010780108801098011080111801128011380114801158011680117801188011980120801218012280123801248012580126801278012880129801308013180132801338013480135801368013780138801398014080141801428014380144801458014680147801488014980150801518015280153801548015580156801578015880159801608016180162801638016480165801668016780168801698017080171801728017380174801758017680177801788017980180801818018280183801848018580186801878018880189801908019180192801938019480195801968019780198801998020080201802028020380204802058020680207802088020980210802118021280213802148021580216802178021880219802208022180222802238022480225802268022780228802298023080231802328023380234802358023680237802388023980240802418024280243802448024580246802478024880249802508025180252802538025480255802568025780258802598026080261802628026380264802658026680267802688026980270802718027280273802748027580276802778027880279802808028180282802838028480285802868028780288802898029080291802928029380294802958029680297802988029980300803018030280303803048030580306803078030880309803108031180312803138031480315803168031780318803198032080321803228032380324803258032680327803288032980330803318033280333803348033580336803378033880339803408034180342803438034480345803468034780348803498035080351803528035380354803558035680357803588035980360803618036280363803648036580366803678036880369803708037180372803738037480375803768037780378803798038080381803828038380384803858038680387803888038980390803918039280393803948039580396803978039880399804008040180402804038040480405804068040780408804098041080411804128041380414804158041680417804188041980420804218042280423804248042580426804278042880429804308043180432804338043480435804368043780438804398044080441804428044380444804458044680447804488044980450804518045280453804548045580456804578045880459804608046180462804638046480465804668046780468804698047080471804728047380474804758047680477804788047980480804818048280483804848048580486804878048880489804908049180492804938049480495804968049780498804998050080501805028050380504805058050680507805088050980510805118051280513805148051580516805178051880519805208052180522805238052480525805268052780528805298053080531805328053380534805358053680537805388053980540805418054280543805448054580546805478054880549805508055180552805538055480555805568055780558805598056080561805628056380564805658056680567805688056980570805718057280573805748057580576805778057880579805808058180582805838058480585805868058780588805898059080591805928059380594805958059680597805988059980600806018060280603806048060580606806078060880609806108061180612806138061480615806168061780618806198062080621806228062380624806258062680627806288062980630806318063280633806348063580636806378063880639806408064180642806438064480645806468064780648806498065080651806528065380654806558065680657806588065980660806618066280663806648066580666806678066880669806708067180672806738067480675806768067780678806798068080681806828068380684806858068680687806888068980690806918069280693806948069580696806978069880699807008070180702807038070480705807068070780708807098071080711807128071380714807158071680717807188071980720807218072280723807248072580726807278072880729807308073180732807338073480735807368073780738807398074080741807428074380744807458074680747807488074980750807518075280753807548075580756807578075880759807608076180762807638076480765807668076780768807698077080771807728077380774807758077680777807788077980780807818078280783807848078580786807878078880789807908079180792807938079480795807968079780798807998080080801808028080380804808058080680807808088080980810808118081280813808148081580816808178081880819808208082180822808238082480825808268082780828808298083080831808328083380834808358083680837808388083980840808418084280843808448084580846808478084880849808508085180852808538085480855808568085780858808598086080861808628086380864808658086680867808688086980870808718087280873808748087580876808778087880879808808088180882808838088480885808868088780888808898089080891808928089380894808958089680897808988089980900809018090280903809048090580906809078090880909809108091180912809138091480915809168091780918809198092080921809228092380924809258092680927809288092980930809318093280933809348093580936809378093880939809408094180942809438094480945809468094780948809498095080951809528095380954809558095680957809588095980960809618096280963809648096580966809678096880969809708097180972809738097480975809768097780978809798098080981809828098380984809858098680987809888098980990809918099280993809948099580996809978099880999810008100181002810038100481005810068100781008810098101081011810128101381014810158101681017810188101981020810218102281023810248102581026810278102881029810308103181032810338103481035810368103781038810398104081041810428104381044810458104681047810488104981050810518105281053810548105581056810578105881059810608106181062810638106481065810668106781068810698107081071810728107381074810758107681077810788107981080810818108281083810848108581086810878108881089810908109181092810938109481095810968109781098810998110081101811028110381104811058110681107811088110981110811118111281113811148111581116811178111881119811208112181122811238112481125811268112781128811298113081131811328113381134811358113681137811388113981140811418114281143811448114581146811478114881149811508115181152811538115481155811568115781158811598116081161811628116381164811658116681167811688116981170811718117281173811748117581176811778117881179811808118181182811838118481185811868118781188811898119081191811928119381194811958119681197811988119981200812018120281203812048120581206812078120881209812108121181212812138121481215812168121781218812198122081221812228122381224812258122681227812288122981230812318123281233812348123581236812378123881239812408124181242812438124481245812468124781248812498125081251812528125381254812558125681257812588125981260812618126281263812648126581266812678126881269812708127181272812738127481275812768127781278812798128081281812828128381284812858128681287812888128981290812918129281293812948129581296812978129881299813008130181302813038130481305813068130781308813098131081311813128131381314813158131681317813188131981320813218132281323813248132581326813278132881329813308133181332813338133481335813368133781338813398134081341813428134381344813458134681347813488134981350813518135281353813548135581356813578135881359813608136181362813638136481365813668136781368813698137081371813728137381374813758137681377813788137981380813818138281383813848138581386813878138881389813908139181392813938139481395813968139781398813998140081401814028140381404814058140681407814088140981410814118141281413814148141581416814178141881419814208142181422814238142481425814268142781428814298143081431814328143381434814358143681437814388143981440814418144281443814448144581446814478144881449814508145181452814538145481455814568145781458814598146081461814628146381464814658146681467814688146981470814718147281473814748147581476814778147881479814808148181482814838148481485814868148781488814898149081491814928149381494814958149681497814988149981500815018150281503815048150581506815078150881509815108151181512815138151481515815168151781518815198152081521815228152381524815258152681527815288152981530815318153281533815348153581536815378153881539815408154181542815438154481545815468154781548815498155081551815528155381554815558155681557815588155981560815618156281563815648156581566815678156881569815708157181572815738157481575815768157781578815798158081581815828158381584815858158681587815888158981590815918159281593815948159581596815978159881599816008160181602816038160481605816068160781608816098161081611816128161381614816158161681617816188161981620816218162281623816248162581626816278162881629816308163181632816338163481635816368163781638816398164081641816428164381644816458164681647816488164981650816518165281653816548165581656816578165881659816608166181662816638166481665816668166781668816698167081671816728167381674816758167681677816788167981680816818168281683816848168581686816878168881689816908169181692816938169481695816968169781698816998170081701817028170381704817058170681707817088170981710817118171281713817148171581716817178171881719817208172181722817238172481725817268172781728817298173081731817328173381734817358173681737817388173981740817418174281743817448174581746817478174881749817508175181752817538175481755817568175781758817598176081761817628176381764817658176681767817688176981770817718177281773817748177581776817778177881779817808178181782817838178481785817868178781788817898179081791817928179381794817958179681797817988179981800818018180281803818048180581806818078180881809818108181181812818138181481815818168181781818818198182081821818228182381824818258182681827818288182981830818318183281833818348183581836818378183881839818408184181842818438184481845818468184781848818498185081851818528185381854818558185681857818588185981860818618186281863818648186581866818678186881869818708187181872818738187481875818768187781878818798188081881818828188381884818858188681887818888188981890818918189281893818948189581896818978189881899819008190181902819038190481905819068190781908819098191081911819128191381914819158191681917819188191981920819218192281923819248192581926819278192881929819308193181932819338193481935819368193781938819398194081941819428194381944819458194681947819488194981950819518195281953819548195581956819578195881959819608196181962819638196481965819668196781968819698197081971819728197381974819758197681977819788197981980819818198281983819848198581986819878198881989819908199181992819938199481995819968199781998819998200082001820028200382004820058200682007820088200982010820118201282013820148201582016820178201882019820208202182022820238202482025820268202782028820298203082031820328203382034820358203682037820388203982040820418204282043820448204582046820478204882049820508205182052820538205482055820568205782058820598206082061820628206382064820658206682067820688206982070820718207282073820748207582076820778207882079820808208182082820838208482085820868208782088820898209082091820928209382094820958209682097820988209982100821018210282103821048210582106821078210882109821108211182112821138211482115821168211782118821198212082121821228212382124821258212682127821288212982130821318213282133821348213582136821378213882139821408214182142821438214482145821468214782148821498215082151821528215382154821558215682157821588215982160821618216282163821648216582166821678216882169821708217182172821738217482175821768217782178821798218082181821828218382184821858218682187821888218982190821918219282193821948219582196821978219882199822008220182202822038220482205822068220782208822098221082211822128221382214822158221682217822188221982220822218222282223822248222582226822278222882229822308223182232822338223482235822368223782238822398224082241822428224382244822458224682247822488224982250822518225282253822548225582256822578225882259822608226182262822638226482265822668226782268822698227082271822728227382274822758227682277822788227982280822818228282283822848228582286822878228882289822908229182292822938229482295822968229782298822998230082301823028230382304823058230682307823088230982310823118231282313823148231582316823178231882319823208232182322823238232482325823268232782328823298233082331823328233382334823358233682337823388233982340823418234282343823448234582346823478234882349823508235182352823538235482355823568235782358823598236082361823628236382364823658236682367823688236982370823718237282373823748237582376823778237882379823808238182382823838238482385823868238782388823898239082391823928239382394823958239682397823988239982400824018240282403824048240582406824078240882409824108241182412824138241482415824168241782418824198242082421824228242382424824258242682427824288242982430824318243282433824348243582436824378243882439824408244182442824438244482445824468244782448824498245082451824528245382454824558245682457824588245982460824618246282463824648246582466824678246882469824708247182472824738247482475824768247782478824798248082481824828248382484824858248682487824888248982490824918249282493824948249582496824978249882499825008250182502825038250482505825068250782508825098251082511825128251382514825158251682517825188251982520825218252282523825248252582526825278252882529825308253182532825338253482535825368253782538825398254082541825428254382544825458254682547825488254982550825518255282553825548255582556825578255882559825608256182562825638256482565825668256782568825698257082571825728257382574825758257682577825788257982580825818258282583825848258582586825878258882589825908259182592825938259482595825968259782598825998260082601826028260382604826058260682607826088260982610826118261282613826148261582616826178261882619826208262182622826238262482625826268262782628826298263082631826328263382634826358263682637826388263982640826418264282643826448264582646826478264882649826508265182652826538265482655826568265782658826598266082661826628266382664826658266682667826688266982670826718267282673826748267582676826778267882679826808268182682826838268482685826868268782688826898269082691826928269382694826958269682697826988269982700827018270282703827048270582706827078270882709827108271182712827138271482715827168271782718827198272082721827228272382724827258272682727827288272982730827318273282733827348273582736827378273882739827408274182742827438274482745827468274782748827498275082751827528275382754827558275682757827588275982760827618276282763827648276582766827678276882769827708277182772827738277482775827768277782778827798278082781827828278382784827858278682787827888278982790827918279282793827948279582796827978279882799828008280182802828038280482805828068280782808828098281082811828128281382814828158281682817828188281982820828218282282823828248282582826828278282882829828308283182832828338283482835828368283782838828398284082841828428284382844828458284682847828488284982850828518285282853828548285582856828578285882859828608286182862828638286482865828668286782868828698287082871828728287382874828758287682877828788287982880828818288282883828848288582886828878288882889828908289182892828938289482895828968289782898828998290082901829028290382904829058290682907829088290982910829118291282913829148291582916829178291882919829208292182922829238292482925829268292782928829298293082931829328293382934829358293682937829388293982940829418294282943829448294582946829478294882949829508295182952829538295482955829568295782958829598296082961829628296382964829658296682967829688296982970829718297282973829748297582976829778297882979829808298182982829838298482985829868298782988829898299082991829928299382994829958299682997829988299983000830018300283003830048300583006830078300883009830108301183012830138301483015830168301783018830198302083021830228302383024830258302683027830288302983030830318303283033830348303583036830378303883039830408304183042830438304483045830468304783048830498305083051830528305383054830558305683057830588305983060830618306283063830648306583066830678306883069830708307183072830738307483075830768307783078830798308083081830828308383084830858308683087830888308983090830918309283093830948309583096830978309883099831008310183102831038310483105831068310783108831098311083111831128311383114831158311683117831188311983120831218312283123831248312583126831278312883129831308313183132831338313483135831368313783138831398314083141831428314383144831458314683147831488314983150831518315283153831548315583156831578315883159831608316183162831638316483165831668316783168831698317083171831728317383174831758317683177831788317983180831818318283183831848318583186831878318883189831908319183192831938319483195831968319783198831998320083201832028320383204832058320683207832088320983210832118321283213832148321583216832178321883219832208322183222832238322483225832268322783228832298323083231832328323383234832358323683237832388323983240832418324283243832448324583246832478324883249832508325183252832538325483255832568325783258832598326083261832628326383264832658326683267832688326983270832718327283273832748327583276832778327883279832808328183282832838328483285832868328783288832898329083291832928329383294832958329683297832988329983300833018330283303833048330583306833078330883309833108331183312833138331483315833168331783318833198332083321833228332383324833258332683327833288332983330833318333283333833348333583336833378333883339833408334183342833438334483345833468334783348833498335083351833528335383354833558335683357833588335983360833618336283363833648336583366833678336883369833708337183372833738337483375833768337783378833798338083381833828338383384833858338683387833888338983390833918339283393833948339583396833978339883399834008340183402834038340483405834068340783408834098341083411834128341383414834158341683417834188341983420834218342283423834248342583426834278342883429834308343183432834338343483435834368343783438834398344083441834428344383444834458344683447834488344983450834518345283453834548345583456834578345883459834608346183462834638346483465834668346783468834698347083471834728347383474834758347683477834788347983480834818348283483834848348583486834878348883489834908349183492834938349483495834968349783498834998350083501835028350383504835058350683507835088350983510835118351283513835148351583516835178351883519835208352183522835238352483525835268352783528835298353083531835328353383534835358353683537835388353983540835418354283543835448354583546835478354883549835508355183552835538355483555835568355783558835598356083561835628356383564835658356683567835688356983570835718357283573835748357583576835778357883579835808358183582835838358483585835868358783588835898359083591835928359383594835958359683597835988359983600836018360283603836048360583606836078360883609836108361183612836138361483615836168361783618836198362083621836228362383624836258362683627836288362983630836318363283633836348363583636836378363883639836408364183642836438364483645836468364783648836498365083651836528365383654836558365683657836588365983660836618366283663836648366583666836678366883669836708367183672836738367483675836768367783678836798368083681836828368383684836858368683687836888368983690836918369283693836948369583696836978369883699837008370183702837038370483705837068370783708837098371083711837128371383714837158371683717837188371983720837218372283723837248372583726837278372883729837308373183732837338373483735837368373783738837398374083741837428374383744837458374683747837488374983750837518375283753837548375583756837578375883759837608376183762837638376483765837668376783768837698377083771837728377383774837758377683777837788377983780837818378283783837848378583786837878378883789837908379183792837938379483795837968379783798837998380083801838028380383804838058380683807838088380983810838118381283813838148381583816838178381883819838208382183822838238382483825838268382783828838298383083831838328383383834838358383683837838388383983840838418384283843838448384583846838478384883849838508385183852838538385483855838568385783858838598386083861838628386383864838658386683867838688386983870838718387283873838748387583876838778387883879838808388183882838838388483885838868388783888838898389083891838928389383894838958389683897838988389983900839018390283903839048390583906839078390883909839108391183912839138391483915839168391783918839198392083921839228392383924839258392683927839288392983930839318393283933839348393583936839378393883939839408394183942839438394483945839468394783948839498395083951839528395383954839558395683957839588395983960839618396283963839648396583966839678396883969839708397183972839738397483975839768397783978839798398083981839828398383984839858398683987839888398983990839918399283993839948399583996839978399883999840008400184002840038400484005840068400784008840098401084011840128401384014840158401684017840188401984020840218402284023840248402584026840278402884029840308403184032840338403484035840368403784038840398404084041840428404384044840458404684047840488404984050840518405284053840548405584056840578405884059840608406184062840638406484065840668406784068840698407084071840728407384074840758407684077840788407984080840818408284083840848408584086840878408884089840908409184092840938409484095840968409784098840998410084101841028410384104841058410684107841088410984110841118411284113841148411584116841178411884119841208412184122841238412484125841268412784128841298413084131841328413384134841358413684137841388413984140841418414284143841448414584146841478414884149841508415184152841538415484155841568415784158841598416084161841628416384164841658416684167841688416984170841718417284173841748417584176841778417884179841808418184182841838418484185841868418784188841898419084191841928419384194841958419684197841988419984200842018420284203842048420584206842078420884209842108421184212842138421484215842168421784218842198422084221842228422384224842258422684227842288422984230842318423284233842348423584236842378423884239842408424184242842438424484245842468424784248842498425084251842528425384254842558425684257842588425984260842618426284263842648426584266842678426884269842708427184272842738427484275842768427784278842798428084281842828428384284842858428684287842888428984290842918429284293842948429584296842978429884299843008430184302843038430484305843068430784308843098431084311843128431384314843158431684317843188431984320843218432284323843248432584326843278432884329843308433184332843338433484335843368433784338843398434084341843428434384344843458434684347843488434984350843518435284353843548435584356843578435884359843608436184362843638436484365843668436784368843698437084371843728437384374843758437684377843788437984380843818438284383843848438584386843878438884389843908439184392843938439484395843968439784398843998440084401844028440384404844058440684407844088440984410844118441284413844148441584416844178441884419844208442184422844238442484425844268442784428844298443084431844328443384434844358443684437844388443984440844418444284443844448444584446844478444884449844508445184452844538445484455844568445784458844598446084461844628446384464844658446684467844688446984470844718447284473844748447584476844778447884479844808448184482844838448484485844868448784488844898449084491844928449384494844958449684497844988449984500845018450284503845048450584506845078450884509845108451184512845138451484515845168451784518845198452084521845228452384524845258452684527845288452984530845318453284533845348453584536845378453884539845408454184542845438454484545845468454784548845498455084551845528455384554845558455684557845588455984560845618456284563845648456584566845678456884569845708457184572845738457484575845768457784578845798458084581845828458384584845858458684587845888458984590845918459284593845948459584596845978459884599846008460184602846038460484605846068460784608846098461084611846128461384614846158461684617846188461984620846218462284623846248462584626846278462884629846308463184632846338463484635846368463784638846398464084641846428464384644846458464684647846488464984650846518465284653846548465584656846578465884659846608466184662846638466484665846668466784668846698467084671846728467384674846758467684677846788467984680846818468284683846848468584686846878468884689846908469184692846938469484695846968469784698846998470084701847028470384704847058470684707847088470984710847118471284713847148471584716847178471884719847208472184722847238472484725847268472784728847298473084731847328473384734847358473684737847388473984740847418474284743847448474584746847478474884749847508475184752847538475484755847568475784758847598476084761847628476384764847658476684767847688476984770847718477284773847748477584776847778477884779847808478184782847838478484785847868478784788847898479084791847928479384794847958479684797847988479984800848018480284803848048480584806848078480884809848108481184812848138481484815848168481784818848198482084821848228482384824848258482684827848288482984830848318483284833848348483584836848378483884839848408484184842848438484484845848468484784848848498485084851848528485384854848558485684857848588485984860848618486284863848648486584866848678486884869848708487184872848738487484875848768487784878848798488084881848828488384884848858488684887848888488984890848918489284893848948489584896848978489884899849008490184902849038490484905849068490784908849098491084911849128491384914849158491684917849188491984920849218492284923849248492584926849278492884929849308493184932849338493484935849368493784938849398494084941849428494384944849458494684947849488494984950849518495284953849548495584956849578495884959849608496184962849638496484965849668496784968849698497084971849728497384974849758497684977849788497984980849818498284983849848498584986849878498884989849908499184992849938499484995849968499784998849998500085001850028500385004850058500685007850088500985010850118501285013850148501585016850178501885019850208502185022850238502485025850268502785028850298503085031850328503385034850358503685037850388503985040850418504285043850448504585046850478504885049850508505185052850538505485055850568505785058850598506085061850628506385064850658506685067850688506985070850718507285073850748507585076850778507885079850808508185082850838508485085850868508785088850898509085091850928509385094850958509685097850988509985100851018510285103851048510585106851078510885109851108511185112851138511485115851168511785118851198512085121851228512385124851258512685127851288512985130851318513285133851348513585136851378513885139851408514185142851438514485145851468514785148851498515085151851528515385154851558515685157851588515985160851618516285163851648516585166851678516885169851708517185172851738517485175851768517785178851798518085181851828518385184851858518685187851888518985190851918519285193851948519585196851978519885199852008520185202852038520485205852068520785208852098521085211852128521385214852158521685217852188521985220852218522285223852248522585226852278522885229852308523185232852338523485235852368523785238852398524085241852428524385244852458524685247852488524985250852518525285253852548525585256852578525885259852608526185262852638526485265852668526785268852698527085271852728527385274852758527685277852788527985280852818528285283852848528585286852878528885289852908529185292852938529485295852968529785298852998530085301853028530385304853058530685307853088530985310853118531285313853148531585316853178531885319853208532185322853238532485325853268532785328853298533085331853328533385334853358533685337853388533985340853418534285343853448534585346853478534885349853508535185352853538535485355853568535785358853598536085361853628536385364853658536685367853688536985370853718537285373853748537585376853778537885379853808538185382853838538485385853868538785388853898539085391853928539385394853958539685397853988539985400854018540285403854048540585406854078540885409854108541185412854138541485415854168541785418854198542085421854228542385424854258542685427854288542985430854318543285433854348543585436854378543885439854408544185442854438544485445854468544785448854498545085451854528545385454854558545685457854588545985460854618546285463854648546585466854678546885469854708547185472854738547485475854768547785478854798548085481854828548385484854858548685487854888548985490854918549285493854948549585496854978549885499855008550185502855038550485505855068550785508855098551085511855128551385514855158551685517855188551985520855218552285523855248552585526855278552885529855308553185532855338553485535855368553785538855398554085541855428554385544855458554685547855488554985550855518555285553855548555585556855578555885559855608556185562855638556485565855668556785568855698557085571855728557385574855758557685577855788557985580855818558285583855848558585586855878558885589855908559185592855938559485595855968559785598855998560085601856028560385604856058560685607856088560985610856118561285613856148561585616856178561885619856208562185622856238562485625856268562785628856298563085631856328563385634856358563685637856388563985640856418564285643856448564585646856478564885649856508565185652856538565485655856568565785658856598566085661856628566385664856658566685667856688566985670856718567285673856748567585676856778567885679856808568185682856838568485685856868568785688856898569085691856928569385694856958569685697856988569985700857018570285703857048570585706857078570885709857108571185712857138571485715857168571785718857198572085721857228572385724857258572685727857288572985730857318573285733857348573585736857378573885739857408574185742857438574485745857468574785748857498575085751857528575385754857558575685757857588575985760857618576285763857648576585766857678576885769857708577185772857738577485775857768577785778857798578085781857828578385784857858578685787857888578985790857918579285793857948579585796857978579885799858008580185802858038580485805858068580785808858098581085811858128581385814858158581685817858188581985820858218582285823858248582585826858278582885829858308583185832858338583485835858368583785838858398584085841858428584385844858458584685847858488584985850858518585285853858548585585856858578585885859858608586185862858638586485865858668586785868858698587085871858728587385874858758587685877858788587985880858818588285883858848588585886858878588885889858908589185892858938589485895858968589785898858998590085901859028590385904859058590685907859088590985910859118591285913859148591585916859178591885919859208592185922859238592485925859268592785928859298593085931859328593385934859358593685937859388593985940859418594285943859448594585946859478594885949859508595185952859538595485955859568595785958859598596085961859628596385964859658596685967859688596985970859718597285973859748597585976859778597885979859808598185982859838598485985859868598785988859898599085991859928599385994859958599685997859988599986000860018600286003860048600586006860078600886009860108601186012860138601486015860168601786018860198602086021860228602386024860258602686027860288602986030860318603286033860348603586036860378603886039860408604186042860438604486045860468604786048860498605086051860528605386054860558605686057860588605986060860618606286063860648606586066860678606886069860708607186072860738607486075860768607786078860798608086081860828608386084860858608686087860888608986090860918609286093860948609586096860978609886099861008610186102861038610486105861068610786108861098611086111861128611386114861158611686117861188611986120861218612286123861248612586126861278612886129861308613186132861338613486135861368613786138861398614086141861428614386144861458614686147861488614986150861518615286153861548615586156861578615886159861608616186162861638616486165861668616786168861698617086171861728617386174861758617686177861788617986180861818618286183861848618586186861878618886189861908619186192861938619486195861968619786198861998620086201862028620386204862058620686207862088620986210862118621286213862148621586216862178621886219862208622186222862238622486225862268622786228862298623086231862328623386234862358623686237862388623986240862418624286243862448624586246862478624886249862508625186252862538625486255862568625786258862598626086261862628626386264862658626686267862688626986270862718627286273862748627586276862778627886279862808628186282862838628486285862868628786288862898629086291862928629386294862958629686297862988629986300863018630286303863048630586306863078630886309863108631186312863138631486315863168631786318863198632086321863228632386324863258632686327863288632986330863318633286333863348633586336863378633886339863408634186342863438634486345863468634786348863498635086351863528635386354863558635686357863588635986360863618636286363863648636586366863678636886369863708637186372863738637486375863768637786378863798638086381863828638386384863858638686387863888638986390863918639286393863948639586396863978639886399864008640186402864038640486405864068640786408864098641086411864128641386414864158641686417864188641986420864218642286423864248642586426864278642886429864308643186432864338643486435864368643786438864398644086441864428644386444864458644686447864488644986450864518645286453864548645586456864578645886459864608646186462864638646486465864668646786468864698647086471864728647386474864758647686477864788647986480864818648286483864848648586486864878648886489864908649186492864938649486495864968649786498864998650086501865028650386504865058650686507865088650986510865118651286513865148651586516865178651886519865208652186522865238652486525865268652786528865298653086531865328653386534865358653686537865388653986540865418654286543865448654586546865478654886549865508655186552865538655486555865568655786558865598656086561865628656386564865658656686567865688656986570865718657286573865748657586576865778657886579865808658186582865838658486585865868658786588865898659086591865928659386594865958659686597865988659986600866018660286603866048660586606866078660886609866108661186612866138661486615866168661786618866198662086621866228662386624866258662686627866288662986630866318663286633866348663586636866378663886639866408664186642866438664486645866468664786648866498665086651866528665386654866558665686657866588665986660866618666286663866648666586666866678666886669866708667186672866738667486675866768667786678866798668086681866828668386684866858668686687866888668986690866918669286693866948669586696866978669886699867008670186702867038670486705867068670786708867098671086711867128671386714867158671686717867188671986720867218672286723867248672586726867278672886729867308673186732867338673486735867368673786738867398674086741867428674386744867458674686747867488674986750867518675286753867548675586756867578675886759867608676186762867638676486765867668676786768867698677086771867728677386774867758677686777867788677986780867818678286783867848678586786867878678886789867908679186792867938679486795867968679786798867998680086801868028680386804868058680686807868088680986810868118681286813868148681586816868178681886819868208682186822868238682486825868268682786828868298683086831868328683386834868358683686837868388683986840868418684286843868448684586846868478684886849868508685186852868538685486855868568685786858868598686086861868628686386864868658686686867868688686986870868718687286873868748687586876868778687886879868808688186882868838688486885868868688786888868898689086891868928689386894868958689686897868988689986900869018690286903869048690586906869078690886909869108691186912869138691486915869168691786918869198692086921869228692386924869258692686927869288692986930869318693286933869348693586936869378693886939869408694186942869438694486945869468694786948869498695086951869528695386954869558695686957869588695986960869618696286963869648696586966869678696886969869708697186972869738697486975869768697786978869798698086981869828698386984869858698686987869888698986990869918699286993869948699586996869978699886999870008700187002870038700487005870068700787008870098701087011870128701387014870158701687017870188701987020870218702287023870248702587026870278702887029870308703187032870338703487035870368703787038870398704087041870428704387044870458704687047870488704987050870518705287053870548705587056870578705887059870608706187062870638706487065870668706787068870698707087071870728707387074870758707687077870788707987080870818708287083870848708587086870878708887089870908709187092870938709487095870968709787098870998710087101871028710387104871058710687107871088710987110871118711287113871148711587116871178711887119871208712187122871238712487125871268712787128871298713087131871328713387134871358713687137871388713987140871418714287143871448714587146871478714887149871508715187152871538715487155871568715787158871598716087161871628716387164871658716687167871688716987170871718717287173871748717587176871778717887179871808718187182871838718487185871868718787188871898719087191871928719387194871958719687197871988719987200872018720287203872048720587206872078720887209872108721187212872138721487215872168721787218872198722087221872228722387224872258722687227872288722987230872318723287233872348723587236872378723887239872408724187242872438724487245872468724787248872498725087251872528725387254872558725687257872588725987260872618726287263872648726587266872678726887269872708727187272872738727487275872768727787278872798728087281872828728387284872858728687287872888728987290872918729287293872948729587296872978729887299873008730187302873038730487305873068730787308873098731087311873128731387314873158731687317873188731987320873218732287323873248732587326873278732887329873308733187332873338733487335873368733787338873398734087341873428734387344873458734687347873488734987350873518735287353873548735587356873578735887359873608736187362873638736487365873668736787368873698737087371873728737387374873758737687377873788737987380873818738287383873848738587386873878738887389873908739187392873938739487395873968739787398873998740087401874028740387404874058740687407874088740987410874118741287413874148741587416874178741887419874208742187422874238742487425874268742787428874298743087431874328743387434874358743687437874388743987440874418744287443874448744587446874478744887449874508745187452874538745487455874568745787458874598746087461874628746387464874658746687467874688746987470874718747287473874748747587476874778747887479874808748187482874838748487485874868748787488874898749087491874928749387494874958749687497874988749987500875018750287503875048750587506875078750887509875108751187512875138751487515875168751787518875198752087521875228752387524875258752687527875288752987530875318753287533875348753587536875378753887539875408754187542875438754487545875468754787548875498755087551875528755387554875558755687557875588755987560875618756287563875648756587566875678756887569875708757187572875738757487575875768757787578875798758087581875828758387584875858758687587875888758987590875918759287593875948759587596875978759887599876008760187602876038760487605876068760787608876098761087611876128761387614876158761687617876188761987620876218762287623876248762587626876278762887629876308763187632876338763487635876368763787638876398764087641876428764387644876458764687647876488764987650876518765287653876548765587656876578765887659876608766187662876638766487665876668766787668876698767087671876728767387674876758767687677876788767987680876818768287683876848768587686876878768887689876908769187692876938769487695876968769787698876998770087701877028770387704877058770687707877088770987710877118771287713877148771587716877178771887719877208772187722877238772487725877268772787728877298773087731877328773387734877358773687737877388773987740877418774287743877448774587746877478774887749877508775187752877538775487755877568775787758877598776087761877628776387764877658776687767877688776987770877718777287773877748777587776877778777887779877808778187782877838778487785877868778787788877898779087791877928779387794877958779687797877988779987800878018780287803878048780587806878078780887809878108781187812878138781487815878168781787818878198782087821878228782387824878258782687827878288782987830878318783287833878348783587836878378783887839878408784187842878438784487845878468784787848878498785087851878528785387854878558785687857878588785987860878618786287863878648786587866878678786887869878708787187872878738787487875878768787787878878798788087881878828788387884878858788687887878888788987890878918789287893878948789587896878978789887899879008790187902879038790487905879068790787908879098791087911879128791387914879158791687917879188791987920879218792287923879248792587926879278792887929879308793187932879338793487935879368793787938879398794087941879428794387944879458794687947879488794987950879518795287953879548795587956879578795887959879608796187962879638796487965879668796787968879698797087971879728797387974879758797687977879788797987980879818798287983879848798587986879878798887989879908799187992879938799487995879968799787998879998800088001880028800388004880058800688007880088800988010880118801288013880148801588016880178801888019880208802188022880238802488025880268802788028880298803088031880328803388034880358803688037880388803988040880418804288043880448804588046880478804888049880508805188052880538805488055880568805788058880598806088061880628806388064880658806688067880688806988070880718807288073880748807588076880778807888079880808808188082880838808488085880868808788088880898809088091880928809388094880958809688097880988809988100881018810288103881048810588106881078810888109881108811188112881138811488115881168811788118881198812088121881228812388124881258812688127881288812988130881318813288133881348813588136881378813888139881408814188142881438814488145881468814788148881498815088151881528815388154881558815688157881588815988160881618816288163881648816588166881678816888169881708817188172881738817488175881768817788178881798818088181881828818388184881858818688187881888818988190881918819288193881948819588196881978819888199882008820188202882038820488205882068820788208882098821088211882128821388214882158821688217882188821988220882218822288223882248822588226882278822888229882308823188232882338823488235882368823788238882398824088241882428824388244882458824688247882488824988250882518825288253882548825588256882578825888259882608826188262882638826488265882668826788268882698827088271882728827388274882758827688277882788827988280882818828288283882848828588286882878828888289882908829188292882938829488295882968829788298882998830088301883028830388304883058830688307883088830988310883118831288313883148831588316883178831888319883208832188322883238832488325883268832788328883298833088331883328833388334883358833688337883388833988340883418834288343883448834588346883478834888349883508835188352883538835488355883568835788358883598836088361883628836388364883658836688367883688836988370883718837288373883748837588376883778837888379883808838188382883838838488385883868838788388883898839088391883928839388394883958839688397883988839988400884018840288403884048840588406884078840888409884108841188412884138841488415884168841788418884198842088421884228842388424884258842688427884288842988430884318843288433884348843588436884378843888439884408844188442884438844488445884468844788448884498845088451884528845388454884558845688457884588845988460884618846288463884648846588466884678846888469884708847188472884738847488475884768847788478884798848088481884828848388484884858848688487884888848988490884918849288493884948849588496884978849888499885008850188502885038850488505885068850788508885098851088511885128851388514885158851688517885188851988520885218852288523885248852588526885278852888529885308853188532885338853488535885368853788538885398854088541885428854388544885458854688547885488854988550885518855288553885548855588556885578855888559885608856188562885638856488565885668856788568885698857088571885728857388574885758857688577885788857988580885818858288583885848858588586885878858888589885908859188592885938859488595885968859788598885998860088601886028860388604886058860688607886088860988610886118861288613886148861588616886178861888619886208862188622886238862488625886268862788628886298863088631886328863388634886358863688637886388863988640886418864288643886448864588646886478864888649886508865188652886538865488655886568865788658886598866088661886628866388664886658866688667886688866988670886718867288673886748867588676886778867888679886808868188682886838868488685886868868788688886898869088691886928869388694886958869688697886988869988700887018870288703887048870588706887078870888709887108871188712887138871488715887168871788718887198872088721887228872388724887258872688727887288872988730887318873288733887348873588736887378873888739887408874188742887438874488745887468874788748887498875088751887528875388754887558875688757887588875988760887618876288763887648876588766887678876888769887708877188772887738877488775887768877788778887798878088781887828878388784887858878688787887888878988790887918879288793887948879588796887978879888799888008880188802888038880488805888068880788808888098881088811888128881388814888158881688817888188881988820888218882288823888248882588826888278882888829888308883188832888338883488835888368883788838888398884088841888428884388844888458884688847888488884988850888518885288853888548885588856888578885888859888608886188862888638886488865888668886788868888698887088871888728887388874888758887688877888788887988880888818888288883888848888588886888878888888889888908889188892888938889488895888968889788898888998890088901889028890388904889058890688907889088890988910889118891288913889148891588916889178891888919889208892188922889238892488925889268892788928889298893088931889328893388934889358893688937889388893988940889418894288943889448894588946889478894888949889508895188952889538895488955889568895788958889598896088961889628896388964889658896688967889688896988970889718897288973889748897588976889778897888979889808898188982889838898488985889868898788988889898899088991889928899388994889958899688997889988899989000890018900289003890048900589006890078900889009890108901189012890138901489015890168901789018890198902089021890228902389024890258902689027890288902989030890318903289033890348903589036890378903889039890408904189042890438904489045890468904789048890498905089051890528905389054890558905689057890588905989060890618906289063890648906589066890678906889069890708907189072890738907489075890768907789078890798908089081890828908389084890858908689087890888908989090890918909289093890948909589096890978909889099891008910189102891038910489105891068910789108891098911089111891128911389114891158911689117891188911989120891218912289123891248912589126891278912889129891308913189132891338913489135891368913789138891398914089141891428914389144891458914689147891488914989150891518915289153891548915589156891578915889159891608916189162891638916489165891668916789168891698917089171891728917389174891758917689177891788917989180891818918289183891848918589186891878918889189891908919189192891938919489195891968919789198891998920089201892028920389204892058920689207892088920989210892118921289213892148921589216892178921889219892208922189222892238922489225892268922789228892298923089231892328923389234892358923689237892388923989240892418924289243892448924589246892478924889249892508925189252892538925489255892568925789258892598926089261892628926389264892658926689267892688926989270892718927289273892748927589276892778927889279892808928189282892838928489285892868928789288892898929089291892928929389294892958929689297892988929989300893018930289303893048930589306893078930889309893108931189312893138931489315893168931789318893198932089321893228932389324893258932689327893288932989330893318933289333893348933589336893378933889339893408934189342893438934489345893468934789348893498935089351893528935389354893558935689357893588935989360893618936289363893648936589366893678936889369893708937189372893738937489375893768937789378893798938089381893828938389384893858938689387893888938989390893918939289393893948939589396893978939889399894008940189402894038940489405894068940789408894098941089411894128941389414894158941689417894188941989420894218942289423894248942589426894278942889429894308943189432894338943489435894368943789438894398944089441894428944389444894458944689447894488944989450894518945289453894548945589456894578945889459894608946189462894638946489465894668946789468894698947089471894728947389474894758947689477894788947989480894818948289483894848948589486894878948889489894908949189492894938949489495894968949789498894998950089501895028950389504895058950689507895088950989510895118951289513895148951589516895178951889519895208952189522895238952489525895268952789528895298953089531895328953389534895358953689537895388953989540895418954289543895448954589546895478954889549895508955189552895538955489555895568955789558895598956089561895628956389564895658956689567895688956989570895718957289573895748957589576895778957889579895808958189582895838958489585895868958789588895898959089591895928959389594895958959689597895988959989600896018960289603896048960589606896078960889609896108961189612896138961489615896168961789618896198962089621896228962389624896258962689627896288962989630896318963289633896348963589636896378963889639896408964189642896438964489645896468964789648896498965089651896528965389654896558965689657896588965989660896618966289663896648966589666896678966889669896708967189672896738967489675896768967789678896798968089681896828968389684896858968689687896888968989690896918969289693896948969589696896978969889699897008970189702897038970489705897068970789708897098971089711897128971389714897158971689717897188971989720897218972289723897248972589726897278972889729897308973189732897338973489735897368973789738897398974089741897428974389744897458974689747897488974989750897518975289753897548975589756897578975889759897608976189762897638976489765897668976789768897698977089771897728977389774897758977689777897788977989780897818978289783897848978589786897878978889789897908979189792897938979489795897968979789798897998980089801898028980389804898058980689807898088980989810898118981289813898148981589816898178981889819898208982189822898238982489825898268982789828898298983089831898328983389834898358983689837898388983989840898418984289843898448984589846898478984889849898508985189852898538985489855898568985789858898598986089861898628986389864898658986689867898688986989870898718987289873898748987589876898778987889879898808988189882898838988489885898868988789888898898989089891898928989389894898958989689897898988989989900899018990289903899048990589906899078990889909899108991189912899138991489915899168991789918899198992089921899228992389924899258992689927899288992989930899318993289933899348993589936899378993889939899408994189942899438994489945899468994789948899498995089951899528995389954899558995689957899588995989960899618996289963899648996589966899678996889969899708997189972899738997489975899768997789978899798998089981899828998389984899858998689987899888998989990899918999289993899948999589996899978999889999900009000190002900039000490005900069000790008900099001090011900129001390014900159001690017900189001990020900219002290023900249002590026900279002890029900309003190032900339003490035900369003790038900399004090041900429004390044900459004690047900489004990050900519005290053900549005590056900579005890059900609006190062900639006490065900669006790068900699007090071900729007390074900759007690077900789007990080900819008290083900849008590086900879008890089900909009190092900939009490095900969009790098900999010090101901029010390104901059010690107901089010990110901119011290113901149011590116901179011890119901209012190122901239012490125901269012790128901299013090131901329013390134901359013690137901389013990140901419014290143901449014590146901479014890149901509015190152901539015490155901569015790158901599016090161901629016390164901659016690167901689016990170901719017290173901749017590176901779017890179901809018190182901839018490185901869018790188901899019090191901929019390194901959019690197901989019990200902019020290203902049020590206902079020890209902109021190212902139021490215902169021790218902199022090221902229022390224902259022690227902289022990230902319023290233902349023590236902379023890239902409024190242902439024490245902469024790248902499025090251902529025390254902559025690257902589025990260902619026290263902649026590266902679026890269902709027190272902739027490275902769027790278902799028090281902829028390284902859028690287902889028990290902919029290293902949029590296902979029890299903009030190302903039030490305903069030790308903099031090311903129031390314903159031690317903189031990320903219032290323903249032590326903279032890329903309033190332903339033490335903369033790338903399034090341903429034390344903459034690347903489034990350903519035290353903549035590356903579035890359903609036190362903639036490365903669036790368903699037090371903729037390374903759037690377903789037990380903819038290383903849038590386903879038890389903909039190392903939039490395903969039790398903999040090401904029040390404904059040690407904089040990410904119041290413904149041590416904179041890419904209042190422904239042490425904269042790428904299043090431904329043390434904359043690437904389043990440904419044290443904449044590446904479044890449904509045190452904539045490455904569045790458904599046090461904629046390464904659046690467904689046990470904719047290473904749047590476904779047890479904809048190482904839048490485904869048790488904899049090491904929049390494904959049690497904989049990500905019050290503905049050590506905079050890509905109051190512905139051490515905169051790518905199052090521905229052390524905259052690527905289052990530905319053290533905349053590536905379053890539905409054190542905439054490545905469054790548905499055090551905529055390554905559055690557905589055990560905619056290563905649056590566905679056890569905709057190572905739057490575905769057790578905799058090581905829058390584905859058690587905889058990590905919059290593905949059590596905979059890599906009060190602906039060490605906069060790608906099061090611906129061390614906159061690617906189061990620906219062290623906249062590626906279062890629906309063190632906339063490635906369063790638906399064090641906429064390644906459064690647906489064990650906519065290653906549065590656906579065890659906609066190662906639066490665906669066790668906699067090671906729067390674906759067690677906789067990680906819068290683906849068590686906879068890689906909069190692906939069490695906969069790698906999070090701907029070390704907059070690707907089070990710907119071290713907149071590716907179071890719907209072190722907239072490725907269072790728907299073090731907329073390734907359073690737907389073990740907419074290743907449074590746907479074890749907509075190752907539075490755907569075790758907599076090761907629076390764907659076690767907689076990770907719077290773907749077590776907779077890779907809078190782907839078490785907869078790788907899079090791907929079390794907959079690797907989079990800908019080290803908049080590806908079080890809908109081190812908139081490815908169081790818908199082090821908229082390824908259082690827908289082990830908319083290833908349083590836908379083890839908409084190842908439084490845908469084790848908499085090851908529085390854908559085690857908589085990860908619086290863908649086590866908679086890869908709087190872908739087490875908769087790878908799088090881908829088390884908859088690887908889088990890908919089290893908949089590896908979089890899909009090190902909039090490905909069090790908909099091090911909129091390914909159091690917909189091990920909219092290923909249092590926909279092890929909309093190932909339093490935909369093790938909399094090941909429094390944909459094690947909489094990950909519095290953909549095590956909579095890959909609096190962909639096490965909669096790968909699097090971909729097390974909759097690977909789097990980909819098290983909849098590986909879098890989909909099190992909939099490995909969099790998909999100091001910029100391004910059100691007910089100991010910119101291013910149101591016910179101891019910209102191022910239102491025910269102791028910299103091031910329103391034910359103691037910389103991040910419104291043910449104591046910479104891049910509105191052910539105491055910569105791058910599106091061910629106391064910659106691067910689106991070910719107291073910749107591076910779107891079910809108191082910839108491085910869108791088910899109091091910929109391094910959109691097910989109991100911019110291103911049110591106911079110891109911109111191112911139111491115911169111791118911199112091121911229112391124911259112691127911289112991130911319113291133911349113591136911379113891139911409114191142911439114491145911469114791148911499115091151911529115391154911559115691157911589115991160911619116291163911649116591166911679116891169911709117191172911739117491175911769117791178911799118091181911829118391184911859118691187911889118991190911919119291193911949119591196911979119891199912009120191202912039120491205912069120791208912099121091211912129121391214912159121691217912189121991220912219122291223912249122591226912279122891229912309123191232912339123491235912369123791238912399124091241912429124391244912459124691247912489124991250912519125291253912549125591256912579125891259912609126191262912639126491265912669126791268912699127091271912729127391274912759127691277912789127991280912819128291283912849128591286912879128891289912909129191292912939129491295912969129791298912999130091301913029130391304913059130691307913089130991310913119131291313913149131591316913179131891319913209132191322913239132491325913269132791328913299133091331913329133391334913359133691337913389133991340913419134291343913449134591346913479134891349913509135191352913539135491355913569135791358913599136091361913629136391364913659136691367913689136991370913719137291373913749137591376913779137891379913809138191382913839138491385913869138791388913899139091391913929139391394913959139691397913989139991400914019140291403914049140591406914079140891409914109141191412914139141491415914169141791418914199142091421914229142391424914259142691427914289142991430914319143291433914349143591436914379143891439914409144191442914439144491445914469144791448914499145091451914529145391454914559145691457914589145991460914619146291463914649146591466914679146891469914709147191472914739147491475914769147791478914799148091481914829148391484914859148691487914889148991490914919149291493914949149591496914979149891499915009150191502915039150491505915069150791508915099151091511915129151391514915159151691517915189151991520915219152291523915249152591526915279152891529915309153191532915339153491535915369153791538915399154091541915429154391544915459154691547915489154991550915519155291553915549155591556915579155891559915609156191562915639156491565915669156791568915699157091571915729157391574915759157691577915789157991580915819158291583915849158591586915879158891589915909159191592915939159491595915969159791598915999160091601916029160391604916059160691607916089160991610916119161291613916149161591616916179161891619916209162191622916239162491625916269162791628916299163091631916329163391634916359163691637916389163991640916419164291643916449164591646916479164891649916509165191652916539165491655916569165791658916599166091661916629166391664916659166691667916689166991670916719167291673916749167591676916779167891679916809168191682916839168491685916869168791688916899169091691916929169391694916959169691697916989169991700917019170291703917049170591706917079170891709917109171191712917139171491715917169171791718917199172091721917229172391724917259172691727917289172991730917319173291733917349173591736917379173891739917409174191742917439174491745917469174791748917499175091751917529175391754917559175691757917589175991760917619176291763917649176591766917679176891769917709177191772917739177491775917769177791778917799178091781917829178391784917859178691787917889178991790917919179291793917949179591796917979179891799918009180191802918039180491805918069180791808918099181091811918129181391814918159181691817918189181991820918219182291823918249182591826918279182891829918309183191832918339183491835918369183791838918399184091841918429184391844918459184691847918489184991850918519185291853918549185591856918579185891859918609186191862918639186491865918669186791868918699187091871918729187391874918759187691877918789187991880918819188291883918849188591886918879188891889918909189191892918939189491895918969189791898918999190091901919029190391904919059190691907919089190991910919119191291913919149191591916919179191891919919209192191922919239192491925919269192791928919299193091931919329193391934919359193691937919389193991940919419194291943919449194591946919479194891949919509195191952919539195491955919569195791958919599196091961919629196391964919659196691967919689196991970919719197291973919749197591976919779197891979919809198191982919839198491985919869198791988919899199091991919929199391994919959199691997919989199992000920019200292003920049200592006920079200892009920109201192012920139201492015920169201792018920199202092021920229202392024920259202692027920289202992030920319203292033920349203592036920379203892039920409204192042920439204492045920469204792048920499205092051920529205392054920559205692057920589205992060920619206292063920649206592066920679206892069920709207192072920739207492075920769207792078920799208092081920829208392084920859208692087920889208992090920919209292093920949209592096920979209892099921009210192102921039210492105921069210792108921099211092111921129211392114921159211692117921189211992120921219212292123921249212592126921279212892129921309213192132921339213492135921369213792138921399214092141921429214392144921459214692147921489214992150921519215292153921549215592156921579215892159921609216192162921639216492165921669216792168921699217092171921729217392174921759217692177921789217992180921819218292183921849218592186921879218892189921909219192192921939219492195921969219792198921999220092201922029220392204922059220692207922089220992210922119221292213922149221592216922179221892219922209222192222922239222492225922269222792228922299223092231922329223392234922359223692237922389223992240922419224292243922449224592246922479224892249922509225192252922539225492255922569225792258922599226092261922629226392264922659226692267922689226992270922719227292273922749227592276922779227892279922809228192282922839228492285922869228792288922899229092291922929229392294922959229692297922989229992300923019230292303923049230592306923079230892309923109231192312923139231492315923169231792318923199232092321923229232392324923259232692327923289232992330923319233292333923349233592336923379233892339923409234192342923439234492345923469234792348923499235092351923529235392354923559235692357923589235992360923619236292363923649236592366923679236892369923709237192372923739237492375923769237792378923799238092381923829238392384923859238692387923889238992390923919239292393923949239592396923979239892399924009240192402924039240492405924069240792408924099241092411924129241392414924159241692417924189241992420924219242292423924249242592426924279242892429924309243192432924339243492435924369243792438924399244092441924429244392444924459244692447924489244992450924519245292453924549245592456924579245892459924609246192462924639246492465924669246792468924699247092471924729247392474924759247692477924789247992480924819248292483924849248592486924879248892489924909249192492924939249492495924969249792498924999250092501925029250392504925059250692507925089250992510925119251292513925149251592516925179251892519925209252192522925239252492525925269252792528925299253092531925329253392534925359253692537925389253992540925419254292543925449254592546925479254892549925509255192552925539255492555925569255792558925599256092561925629256392564925659256692567925689256992570925719257292573925749257592576925779257892579925809258192582925839258492585925869258792588925899259092591925929259392594925959259692597925989259992600926019260292603926049260592606926079260892609926109261192612926139261492615926169261792618926199262092621926229262392624926259262692627926289262992630926319263292633926349263592636926379263892639926409264192642926439264492645926469264792648926499265092651926529265392654926559265692657926589265992660926619266292663926649266592666926679266892669926709267192672926739267492675926769267792678926799268092681926829268392684926859268692687926889268992690926919269292693926949269592696926979269892699927009270192702927039270492705927069270792708927099271092711927129271392714927159271692717927189271992720927219272292723927249272592726927279272892729927309273192732927339273492735927369273792738927399274092741927429274392744927459274692747927489274992750927519275292753927549275592756927579275892759927609276192762927639276492765927669276792768927699277092771927729277392774927759277692777927789277992780927819278292783927849278592786927879278892789927909279192792927939279492795927969279792798927999280092801928029280392804928059280692807928089280992810928119281292813928149281592816928179281892819928209282192822928239282492825928269282792828928299283092831928329283392834928359283692837928389283992840928419284292843928449284592846928479284892849928509285192852928539285492855928569285792858928599286092861928629286392864928659286692867928689286992870928719287292873928749287592876928779287892879928809288192882928839288492885928869288792888928899289092891928929289392894928959289692897928989289992900929019290292903929049290592906929079290892909929109291192912929139291492915929169291792918929199292092921929229292392924929259292692927929289292992930929319293292933929349293592936929379293892939929409294192942929439294492945929469294792948929499295092951929529295392954929559295692957929589295992960929619296292963929649296592966929679296892969929709297192972929739297492975929769297792978929799298092981929829298392984929859298692987929889298992990929919299292993929949299592996929979299892999930009300193002930039300493005930069300793008930099301093011930129301393014930159301693017930189301993020930219302293023930249302593026930279302893029930309303193032930339303493035930369303793038930399304093041930429304393044930459304693047930489304993050930519305293053930549305593056930579305893059930609306193062930639306493065930669306793068930699307093071930729307393074930759307693077930789307993080930819308293083930849308593086930879308893089930909309193092930939309493095930969309793098930999310093101931029310393104931059310693107931089310993110931119311293113931149311593116931179311893119931209312193122931239312493125931269312793128931299313093131931329313393134931359313693137931389313993140931419314293143931449314593146931479314893149931509315193152931539315493155931569315793158931599316093161931629316393164931659316693167931689316993170931719317293173931749317593176931779317893179931809318193182931839318493185931869318793188931899319093191931929319393194931959319693197931989319993200932019320293203932049320593206932079320893209932109321193212932139321493215932169321793218932199322093221932229322393224932259322693227932289322993230932319323293233932349323593236932379323893239932409324193242932439324493245932469324793248932499325093251932529325393254932559325693257932589325993260932619326293263932649326593266932679326893269932709327193272932739327493275932769327793278932799328093281932829328393284932859328693287932889328993290932919329293293932949329593296932979329893299933009330193302933039330493305933069330793308933099331093311933129331393314933159331693317933189331993320933219332293323933249332593326933279332893329933309333193332933339333493335933369333793338933399334093341933429334393344933459334693347933489334993350933519335293353933549335593356933579335893359933609336193362933639336493365933669336793368933699337093371933729337393374933759337693377933789337993380933819338293383933849338593386933879338893389933909339193392933939339493395933969339793398933999340093401934029340393404934059340693407934089340993410934119341293413934149341593416934179341893419934209342193422934239342493425934269342793428934299343093431934329343393434934359343693437934389343993440934419344293443934449344593446934479344893449934509345193452934539345493455934569345793458934599346093461934629346393464934659346693467934689346993470934719347293473934749347593476934779347893479934809348193482934839348493485934869348793488934899349093491934929349393494934959349693497934989349993500935019350293503935049350593506935079350893509935109351193512935139351493515935169351793518935199352093521935229352393524935259352693527935289352993530935319353293533935349353593536935379353893539935409354193542935439354493545935469354793548935499355093551935529355393554935559355693557935589355993560935619356293563935649356593566935679356893569935709357193572935739357493575935769357793578935799358093581935829358393584935859358693587935889358993590935919359293593935949359593596935979359893599936009360193602936039360493605936069360793608936099361093611936129361393614936159361693617936189361993620936219362293623936249362593626936279362893629936309363193632936339363493635936369363793638936399364093641936429364393644936459364693647936489364993650936519365293653936549365593656936579365893659936609366193662936639366493665936669366793668936699367093671936729367393674936759367693677936789367993680936819368293683936849368593686936879368893689936909369193692936939369493695936969369793698936999370093701937029370393704937059370693707937089370993710937119371293713937149371593716937179371893719937209372193722937239372493725937269372793728937299373093731937329373393734937359373693737937389373993740937419374293743937449374593746937479374893749937509375193752937539375493755937569375793758937599376093761937629376393764937659376693767937689376993770937719377293773937749377593776937779377893779937809378193782937839378493785937869378793788937899379093791937929379393794937959379693797937989379993800938019380293803938049380593806938079380893809938109381193812938139381493815938169381793818938199382093821938229382393824938259382693827938289382993830938319383293833938349383593836938379383893839938409384193842938439384493845938469384793848938499385093851938529385393854938559385693857938589385993860938619386293863938649386593866938679386893869938709387193872938739387493875938769387793878938799388093881938829388393884938859388693887938889388993890938919389293893938949389593896938979389893899939009390193902939039390493905939069390793908 |
- // OpenLayers. See https://openlayers.org/
- // License: https://raw.githubusercontent.com/openlayers/openlayers/master/LICENSE.md
- // Version: v4.3.3
- ;(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 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 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 Error('Invalid module identifier');
- }
- if (!goog.isInModuleLoader_()) {
- throw 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 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 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 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 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 part; part = parts.shift();) {
- if (goog.isDefAndNotNull(cur[part])) {
- cur = cur[part];
- } else {
- 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 is being 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 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 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 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 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 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 Error('Invalid module definition');
- }
-
- var moduleName = goog.moduleLoaderState_.moduleName;
- if (!goog.isString(moduleName) || !moduleName) {
- throw 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 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 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 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 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 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;
-
- /**
- * @private
- * @type {ol.proj.Units}
- */
- this.units_ = /** @type {ol.proj.Units} */ (options.units);
-
- /**
- * @private
- * @type {ol.Extent}
- */
- this.extent_ = options.extent !== undefined ? options.extent : null;
-
- /**
- * @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.
- */
- 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.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) {
- return ol.proj.transform(coordinate,
- opt_projection !== undefined ? opt_projection : 'EPSG:3857', 'EPSG:4326');
- };
-
-
- /**
- * 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;
- };
-
-
- /**
- * @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
-
- /**
- * @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 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 tileCoordExtent = this.getTileCoordExtent(tileCoord, opt_extent);
- var z = tileCoord[0] - 1;
- while (z >= this.minZoom) {
- if (callback.call(opt_this, z,
- this.getTileRangeForExtentAndZ(tileCoordExtent, z, opt_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 Z.
- * @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 Z.
- * @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) {
- var tileCoordExtent = this.getTileCoordExtent(tileCoord, opt_extent);
- return this.getTileRangeForExtentAndZ(
- tileCoordExtent, tileCoord[0] + 1, opt_tileRange);
- } else {
- return null;
- }
- };
-
-
- /**
- * @param {number} z Z.
- * @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);
- };
-
-
- /**
- * @param {ol.Extent} extent Extent.
- * @param {number} resolution Resolution.
- * @param {ol.TileRange=} opt_tileRange Temporary tile range object.
- * @return {ol.TileRange} Tile range.
- */
- ol.tilegrid.TileGrid.prototype.getTileRangeForExtentAndResolution = function(extent, resolution, opt_tileRange) {
- var tileCoord = ol.tilegrid.TileGrid.tmpTileCoord_;
- this.getTileCoordForXYAndResolution_(
- extent[0], extent[1], resolution, false, tileCoord);
- var minX = tileCoord[1];
- var minY = tileCoord[2];
- this.getTileCoordForXYAndResolution_(
- extent[2], extent[3], resolution, true, tileCoord);
- return ol.TileRange.createOrUpdate(
- minX, tileCoord[1], minY, tileCoord[2], opt_tileRange);
- };
-
-
- /**
- * @param {ol.Extent} extent Extent.
- * @param {number} z Z.
- * @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 resolution = this.getResolution(z);
- return this.getTileRangeForExtentAndResolution(
- extent, resolution, 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);
- };
-
-
- /**
- * @param {number} x X.
- * @param {number} y Y.
- * @param {number} resolution Resolution.
- * @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);
- };
-
-
- /**
- * 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) {
- var resolution = this.getResolution(z);
- return this.getTileCoordForXYAndResolution_(
- coordinate[0], coordinate[1], resolution, 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
- * @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.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.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',
-
- 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.color');
-
- goog.require('ol.asserts');
- goog.require('ol.math');
-
-
- /**
- * This RegExp matches # followed by 3 or 6 hex digits.
- * @const
- * @type {RegExp}
- * @private
- */
- ol.color.HEX_COLOR_RE_ = /^#(?:[0-9a-f]{3}){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
- ol.asserts.assert(n == 3 || n == 6, 54); // Hex color should have 3 or 6 digits
- var d = n == 3 ? 1 : 2; // number of digits per channel
- 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 (d == 1) {
- r = (r << 4) + r;
- g = (g << 4) + g;
- b = (b << 4) + b;
- }
- a = 1;
- color = [r, g, b, a];
- } 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.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.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.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.Map}
- */
- 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.Map} 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.Map} 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';
-
- // FIXME handle date line wrap
-
- goog.provide('ol.control.Attribution');
-
- goog.require('ol');
- goog.require('ol.dom');
- goog.require('ol.control.Control');
- goog.require('ol.css');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- 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
- });
-
- /**
- * @private
- * @type {boolean}
- */
- this.renderedVisible_ = true;
-
- /**
- * @private
- * @type {Object.<string, Element>}
- */
- this.attributionElements_ = {};
-
- /**
- * @private
- * @type {Object.<string, boolean>}
- */
- this.attributionElementRenderedVisible_ = {};
-
- /**
- * @private
- * @type {Object.<string, Element>}
- */
- this.logoElements_ = {};
-
- };
- ol.inherits(ol.control.Attribution, ol.control.Control);
-
-
- /**
- * @param {?olx.FrameState} frameState Frame state.
- * @return {Array.<Object.<string, ol.Attribution>>} Attributions.
- */
- ol.control.Attribution.prototype.getSourceAttributions = function(frameState) {
- var i, ii, j, jj, tileRanges, source, sourceAttribution,
- sourceAttributionKey, sourceAttributions, sourceKey;
- var intersectsTileRange;
- var layerStatesArray = frameState.layerStatesArray;
- /** @type {Object.<string, ol.Attribution>} */
- var attributions = ol.obj.assign({}, frameState.attributions);
- /** @type {Object.<string, ol.Attribution>} */
- var hiddenAttributions = {};
- var uniqueAttributions = {};
- var projection = /** @type {!ol.proj.Projection} */ (frameState.viewState.projection);
- for (i = 0, ii = layerStatesArray.length; i < ii; i++) {
- source = layerStatesArray[i].layer.getSource();
- if (!source) {
- continue;
- }
- sourceKey = ol.getUid(source).toString();
- sourceAttributions = source.getAttributions();
- if (!sourceAttributions) {
- continue;
- }
- for (j = 0, jj = sourceAttributions.length; j < jj; j++) {
- sourceAttribution = sourceAttributions[j];
- sourceAttributionKey = ol.getUid(sourceAttribution).toString();
- if (sourceAttributionKey in attributions) {
- continue;
- }
- tileRanges = frameState.usedTiles[sourceKey];
- if (tileRanges) {
- var tileGrid = /** @type {ol.source.Tile} */ (source).getTileGridForProjection(projection);
- intersectsTileRange = sourceAttribution.intersectsAnyTileRange(
- tileRanges, tileGrid, projection);
- } else {
- intersectsTileRange = false;
- }
- if (intersectsTileRange) {
- if (sourceAttributionKey in hiddenAttributions) {
- delete hiddenAttributions[sourceAttributionKey];
- }
- var html = sourceAttribution.getHTML();
- if (!(html in uniqueAttributions)) {
- uniqueAttributions[html] = true;
- attributions[sourceAttributionKey] = sourceAttribution;
- }
- } else {
- hiddenAttributions[sourceAttributionKey] = sourceAttribution;
- }
- }
- }
- return [attributions, hiddenAttributions];
- };
-
-
- /**
- * 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);
- /** @type {Object.<string, ol.Attribution>} */
- var visibleAttributions = attributions[0];
- /** @type {Object.<string, ol.Attribution>} */
- var hiddenAttributions = attributions[1];
-
- var attributionElement, attributionKey;
- for (attributionKey in this.attributionElements_) {
- if (attributionKey in visibleAttributions) {
- if (!this.attributionElementRenderedVisible_[attributionKey]) {
- this.attributionElements_[attributionKey].style.display = '';
- this.attributionElementRenderedVisible_[attributionKey] = true;
- }
- delete visibleAttributions[attributionKey];
- } else if (attributionKey in hiddenAttributions) {
- if (this.attributionElementRenderedVisible_[attributionKey]) {
- this.attributionElements_[attributionKey].style.display = 'none';
- delete this.attributionElementRenderedVisible_[attributionKey];
- }
- delete hiddenAttributions[attributionKey];
- } else {
- ol.dom.removeNode(this.attributionElements_[attributionKey]);
- delete this.attributionElements_[attributionKey];
- delete this.attributionElementRenderedVisible_[attributionKey];
- }
- }
- for (attributionKey in visibleAttributions) {
- attributionElement = document.createElement('LI');
- attributionElement.innerHTML =
- visibleAttributions[attributionKey].getHTML();
- this.ulElement_.appendChild(attributionElement);
- this.attributionElements_[attributionKey] = attributionElement;
- this.attributionElementRenderedVisible_[attributionKey] = true;
- }
- for (attributionKey in hiddenAttributions) {
- attributionElement = document.createElement('LI');
- attributionElement.innerHTML =
- hiddenAttributions[attributionKey].getHTML();
- attributionElement.style.display = 'none';
- this.ulElement_.appendChild(attributionElement);
- this.attributionElements_[attributionKey] = attributionElement;
- }
-
- var renderVisible =
- !ol.obj.isEmpty(this.attributionElementRenderedVisible_) ||
- !ol.obj.isEmpty(frameState.logos);
- if (this.renderedVisible_ != renderVisible) {
- this.element.style.display = renderVisible ? '' : 'none';
- this.renderedVisible_ = renderVisible;
- }
- if (renderVisible &&
- ol.obj.isEmpty(this.attributionElementRenderedVisible_)) {
- this.element.classList.add('ol-logo-only');
- } else {
- this.element.classList.remove('ol-logo-only');
- }
-
- 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.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.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.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.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.Map} 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.Map}
- * @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.Map} 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');
-
- goog.require('ol');
-
-
- if (ol.ENABLE_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.Map} 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.Map} 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.Map}
- * @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
- if (!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.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.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.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.Geometry');
-
- goog.require('ol');
- goog.require('ol.Object');
- goog.require('ol.extent');
- goog.require('ol.functions');
- goog.require('ol.proj');
-
-
- /**
- * @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;
-
- };
- 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) {
- this.applyTransform(ol.proj.getTransform(source, destination));
- return this;
- };
-
- 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.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.
- */
- 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
- var end = ends[0];
- 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);
- return opt_dest;
- } else {
- return [pointX, y];
- }
- };
-
-
- /**
- * @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.
- */
- 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.
- * @api
- */
- ol.geom.Polygon.prototype.getInteriorPoint = function() {
- return new ol.geom.Point(this.getFlatInteriorPoint());
- };
-
-
- /**
- * 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_);
- }
- 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 start = Date.now();
- var center = this.getCenter().slice();
- var resolution = this.getResolution();
- var rotation = this.getRotation();
- var animationCount = arguments.length;
- var callback;
- if (animationCount > 1 && typeof arguments[animationCount - 1] === 'function') {
- callback = arguments[animationCount - 1];
- --animationCount;
- }
- 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.getHints()[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.getHints()[ol.ViewHint.INTERACTING] > 0;
- };
-
-
- /**
- * Cancel any ongoing animations.
- * @api
- */
- ol.View.prototype.cancelAnimations = function() {
- this.setHint(ol.ViewHint.ANIMATING, -this.getHints()[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
- });
- };
-
-
- /**
- * Get the current zoom level. Return undefined if the current
- * resolution is undefined or not within the "resolution constraints".
- * @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 zoom;
- if (resolution >= this.minResolution_ && resolution <= this.maxResolution_) {
- var offset = this.minZoom_ || 0;
- var max, zoomFactor;
- if (this.resolutions_) {
- var nearest = ol.array.linearFindNearest(this.resolutions_, resolution, 1);
- offset += nearest;
- if (nearest == this.resolutions_.length - 1) {
- return offset;
- }
- max = this.resolutions_[nearest];
- zoomFactor = max / this.resolutions_[nearest + 1];
- } else {
- max = this.maxResolution_;
- zoomFactor = this.zoomFactor_;
- }
- zoom = offset + Math.log(max / resolution) / Math.log(zoomFactor);
- }
- return zoom;
- };
-
-
- /**
- * 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[0];
- minResolution = 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.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');
-
-
- /**
- * @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.Map}
- */
- 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.Map} 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.Map} 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 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.<number, 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;
-
- if (mapBrowserEvent.type == ol.MapBrowserEventType.POINTERUP) {
- delete this.trackedPointers_[event.pointerId];
- } else if (mapBrowserEvent.type ==
- ol.MapBrowserEventType.POINTERDOWN) {
- this.trackedPointers_[event.pointerId] = event;
- } else if (event.pointerId in this.trackedPointers_) {
- // update only when there was a pointerdown event for this pointer
- this.trackedPointers_[event.pointerId] = 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.getHints()[ol.ViewHint.ANIMATING]) {
- 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.Map}
- */
- 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.Map} 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.Map} 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.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
- });
-
- };
- ol.inherits(ol.layer.Base, ol.Object);
-
-
- /**
- * Create a renderer for this layer.
- * @abstract
- * @param {ol.renderer.Map} mapRenderer The map renderer.
- * @return {ol.renderer.Layer} A layer renderer.
- */
- ol.layer.Base.prototype.createRenderer = function(mapRenderer) {};
-
-
- /**
- * @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);
-
-
- /**
- * @inheritDoc
- */
- ol.layer.Group.prototype.createRenderer = function(mapRenderer) {};
-
-
- /**
- * @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.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.Map} 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);
- };
-
- goog.provide('ol.style.IconImageCache');
-
- goog.require('ol.color');
-
-
- /**
- * @constructor
- */
- ol.style.IconImageCache = function() {
-
- /**
- * @type {Object.<string, ol.style.IconImage>}
- * @private
- */
- this.cache_ = {};
-
- /**
- * @type {number}
- * @private
- */
- this.cacheSize_ = 0;
-
- /**
- * @const
- * @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_;
- };
-
- goog.provide('ol.style');
-
- goog.require('ol.style.IconImageCache');
-
- ol.style.iconImageCache = new ol.style.IconImageCache();
-
- 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.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.style');
- goog.require('ol.transform');
-
-
- /**
- * @constructor
- * @abstract
- * @extends {ol.Disposable}
- * @param {Element} container Container.
- * @param {ol.Map} map Map.
- * @struct
- */
- ol.renderer.Map = function(container, map) {
-
- ol.Disposable.call(this);
-
-
- /**
- * @private
- * @type {ol.Map}
- */
- 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));
- };
-
-
- /**
- * @inheritDoc
- */
- ol.renderer.Map.prototype.disposeInternal = function() {
- for (var id in this.layerRenderers_) {
- this.layerRenderers_[id].dispose();
- }
- };
-
-
- /**
- * @param {ol.Map} 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 layerRenderer = layer.createRenderer(this);
- this.layerRenderers_[layerKey] = layerRenderer;
- this.layerRendererListeners_[layerKey] = ol.events.listen(layerRenderer,
- ol.events.EventType.CHANGE, this.handleLayerRendererChange_, this);
-
- return layerRenderer;
- }
- };
-
-
- /**
- * @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.Map} Map.
- */
- ol.renderer.Map.prototype.getMap = function() {
- return this.map_;
- };
-
-
- /**
- * @abstract
- * @return {string} 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.Map} 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;
- };
-
- goog.provide('ol.renderer.Type');
-
-
- /**
- * Available renderers: `'canvas'` or `'webgl'`.
- * @enum {string}
- */
- ol.renderer.Type = {
- CANVAS: 'canvas',
- WEBGL: 'webgl'
- };
-
- 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.render.canvas');
-
-
- /**
- * @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 {number}
- */
- ol.render.canvas.defaultLineWidth = 1;
-
-
- /**
- * @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);
- }
- };
-
- 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 {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @param {ol.geom.Geometry|ol.render.Feature} geometry Geometry.
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- */
- ol.render.VectorContext.prototype.drawText = function(flatCoordinates, offset, end, stride, 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.
- */
- ol.render.VectorContext.prototype.setImageStyle = function(imageStyle) {};
-
-
- /**
- * @param {ol.style.Text} textStyle Text style.
- */
- ol.render.VectorContext.prototype.setTextStyle = function(textStyle) {};
-
- // 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_;
- if (!contextTextState) {
- context.font = textState.font;
- context.textAlign = textState.textAlign;
- context.textBaseline = textState.textBaseline;
- this.contextTextState_ = {
- font: textState.font,
- textAlign: textState.textAlign,
- textBaseline: textState.textBaseline
- };
- } else {
- if (contextTextState.font != textState.font) {
- contextTextState.font = context.font = textState.font;
- }
- if (contextTextState.textAlign != textState.textAlign) {
- contextTextState.textAlign = context.textAlign = textState.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);
- }
- };
-
- // 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.Map} map Map.
- */
- 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);
-
-
- /**
- * @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.render.ReplayType');
-
-
- /**
- * @enum {string}
- */
- ol.render.ReplayType = {
- CIRCLE: 'Circle',
- DEFAULT: 'Default',
- IMAGE: 'Image',
- LINE_STRING: 'LineString',
- POLYGON: 'Polygon',
- TEXT: 'Text'
- };
-
- 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
- ];
-
- 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.webgl.Shader');
-
- goog.require('ol');
- goog.require('ol.functions');
-
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @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');
-
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @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');
-
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @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
- /* eslint openlayers-internal/no-missing-requires: 0 */
- goog.provide('ol.render.webgl.circlereplay.defaultshader');
-
- goog.require('ol');
- goog.require('ol.webgl.Fragment');
- goog.require('ol.webgl.Vertex');
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @constructor
- * @extends {ol.webgl.Fragment}
- * @struct
- */
- ol.render.webgl.circlereplay.defaultshader.Fragment = function() {
- ol.webgl.Fragment.call(this, ol.render.webgl.circlereplay.defaultshader.Fragment.SOURCE);
- };
- ol.inherits(ol.render.webgl.circlereplay.defaultshader.Fragment, ol.webgl.Fragment);
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.circlereplay.defaultshader.Fragment.DEBUG_SOURCE = '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';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.circlereplay.defaultshader.Fragment.OPTIMIZED_SOURCE = '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;}}';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.circlereplay.defaultshader.Fragment.SOURCE = ol.DEBUG_WEBGL ?
- ol.render.webgl.circlereplay.defaultshader.Fragment.DEBUG_SOURCE :
- ol.render.webgl.circlereplay.defaultshader.Fragment.OPTIMIZED_SOURCE;
-
-
- ol.render.webgl.circlereplay.defaultshader.fragment = new ol.render.webgl.circlereplay.defaultshader.Fragment();
-
-
- /**
- * @constructor
- * @extends {ol.webgl.Vertex}
- * @struct
- */
- ol.render.webgl.circlereplay.defaultshader.Vertex = function() {
- ol.webgl.Vertex.call(this, ol.render.webgl.circlereplay.defaultshader.Vertex.SOURCE);
- };
- ol.inherits(ol.render.webgl.circlereplay.defaultshader.Vertex, ol.webgl.Vertex);
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.circlereplay.defaultshader.Vertex.DEBUG_SOURCE = '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';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.circlereplay.defaultshader.Vertex.OPTIMIZED_SOURCE = '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;if(f==0.0){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);}}';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.circlereplay.defaultshader.Vertex.SOURCE = ol.DEBUG_WEBGL ?
- ol.render.webgl.circlereplay.defaultshader.Vertex.DEBUG_SOURCE :
- ol.render.webgl.circlereplay.defaultshader.Vertex.OPTIMIZED_SOURCE;
-
-
- ol.render.webgl.circlereplay.defaultshader.vertex = new ol.render.webgl.circlereplay.defaultshader.Vertex();
-
-
- /**
- * @constructor
- * @param {WebGLRenderingContext} gl GL.
- * @param {WebGLProgram} program Program.
- * @struct
- */
- ol.render.webgl.circlereplay.defaultshader.Locations = function(gl, program) {
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_fillColor = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_fillColor' : 'n');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_lineWidth = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_lineWidth' : 'k');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_offsetRotateMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_offsetScaleMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_opacity = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_opacity' : 'm');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_pixelRatio = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_pixelRatio' : 'l');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_projectionMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_size = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_size' : 'p');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_strokeColor = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_strokeColor' : 'o');
-
- /**
- * @type {number}
- */
- this.a_instruction = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_instruction' : 'f');
-
- /**
- * @type {number}
- */
- this.a_position = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_position' : 'e');
-
- /**
- * @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');
-
-
- if (ol.ENABLE_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');
-
- goog.require('ol');
-
-
- if (ol.ENABLE_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');
- goog.require('ol.webgl');
-
-
- if (ol.ENABLE_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.Replay');
- goog.require('ol.render.webgl');
- goog.require('ol.webgl');
- goog.require('ol.webgl.Buffer');
-
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @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_) {
- // eslint-disable-next-line openlayers-internal/no-missing-requires
- 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
- /* eslint openlayers-internal/no-missing-requires: 0 */
- goog.provide('ol.render.webgl.texturereplay.defaultshader');
-
- goog.require('ol');
- goog.require('ol.webgl.Fragment');
- goog.require('ol.webgl.Vertex');
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @constructor
- * @extends {ol.webgl.Fragment}
- * @struct
- */
- ol.render.webgl.texturereplay.defaultshader.Fragment = function() {
- ol.webgl.Fragment.call(this, ol.render.webgl.texturereplay.defaultshader.Fragment.SOURCE);
- };
- ol.inherits(ol.render.webgl.texturereplay.defaultshader.Fragment, ol.webgl.Fragment);
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.texturereplay.defaultshader.Fragment.DEBUG_SOURCE = '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';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.texturereplay.defaultshader.Fragment.OPTIMIZED_SOURCE = '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;}';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.texturereplay.defaultshader.Fragment.SOURCE = ol.DEBUG_WEBGL ?
- ol.render.webgl.texturereplay.defaultshader.Fragment.DEBUG_SOURCE :
- ol.render.webgl.texturereplay.defaultshader.Fragment.OPTIMIZED_SOURCE;
-
-
- ol.render.webgl.texturereplay.defaultshader.fragment = new ol.render.webgl.texturereplay.defaultshader.Fragment();
-
-
- /**
- * @constructor
- * @extends {ol.webgl.Vertex}
- * @struct
- */
- ol.render.webgl.texturereplay.defaultshader.Vertex = function() {
- ol.webgl.Vertex.call(this, ol.render.webgl.texturereplay.defaultshader.Vertex.SOURCE);
- };
- ol.inherits(ol.render.webgl.texturereplay.defaultshader.Vertex, ol.webgl.Vertex);
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.texturereplay.defaultshader.Vertex.DEBUG_SOURCE = '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';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.texturereplay.defaultshader.Vertex.OPTIMIZED_SOURCE = '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;}';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.texturereplay.defaultshader.Vertex.SOURCE = ol.DEBUG_WEBGL ?
- ol.render.webgl.texturereplay.defaultshader.Vertex.DEBUG_SOURCE :
- ol.render.webgl.texturereplay.defaultshader.Vertex.OPTIMIZED_SOURCE;
-
-
- ol.render.webgl.texturereplay.defaultshader.vertex = new ol.render.webgl.texturereplay.defaultshader.Vertex();
-
-
- /**
- * @constructor
- * @param {WebGLRenderingContext} gl GL.
- * @param {WebGLProgram} program Program.
- * @struct
- */
- ol.render.webgl.texturereplay.defaultshader.Locations = function(gl, program) {
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_image = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_image' : 'l');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_offsetRotateMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_offsetScaleMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_opacity = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_opacity' : 'k');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_projectionMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
-
- /**
- * @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_position = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_position' : 'c');
-
- /**
- * @type {number}
- */
- this.a_rotateWithView = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_rotateWithView' : 'g');
-
- /**
- * @type {number}
- */
- this.a_texCoord = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_texCoord' : 'd');
- };
-
- }
-
- 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');
-
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @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.Replay');
- goog.require('ol.webgl');
- goog.require('ol.webgl.Context');
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @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) {
- // eslint-disable-next-line openlayers-internal/no-missing-requires
- 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');
-
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @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_;
- };
-
- }
-
- 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;
- };
-
- // This file is automatically generated, do not edit
- /* eslint openlayers-internal/no-missing-requires: 0 */
- goog.provide('ol.render.webgl.linestringreplay.defaultshader');
-
- goog.require('ol');
- goog.require('ol.webgl.Fragment');
- goog.require('ol.webgl.Vertex');
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @constructor
- * @extends {ol.webgl.Fragment}
- * @struct
- */
- ol.render.webgl.linestringreplay.defaultshader.Fragment = function() {
- ol.webgl.Fragment.call(this, ol.render.webgl.linestringreplay.defaultshader.Fragment.SOURCE);
- };
- ol.inherits(ol.render.webgl.linestringreplay.defaultshader.Fragment, ol.webgl.Fragment);
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.linestringreplay.defaultshader.Fragment.DEBUG_SOURCE = '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';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.linestringreplay.defaultshader.Fragment.OPTIMIZED_SOURCE = 'precision mediump float;varying float a;varying vec2 b;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((b.x+1.0)/2.0*o.x*p,(b.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;}';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.linestringreplay.defaultshader.Fragment.SOURCE = ol.DEBUG_WEBGL ?
- ol.render.webgl.linestringreplay.defaultshader.Fragment.DEBUG_SOURCE :
- ol.render.webgl.linestringreplay.defaultshader.Fragment.OPTIMIZED_SOURCE;
-
-
- ol.render.webgl.linestringreplay.defaultshader.fragment = new ol.render.webgl.linestringreplay.defaultshader.Fragment();
-
-
- /**
- * @constructor
- * @extends {ol.webgl.Vertex}
- * @struct
- */
- ol.render.webgl.linestringreplay.defaultshader.Vertex = function() {
- ol.webgl.Vertex.call(this, ol.render.webgl.linestringreplay.defaultshader.Vertex.SOURCE);
- };
- ol.inherits(ol.render.webgl.linestringreplay.defaultshader.Vertex, ol.webgl.Vertex);
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.linestringreplay.defaultshader.Vertex.DEBUG_SOURCE = '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';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.linestringreplay.defaultshader.Vertex.OPTIMIZED_SOURCE = 'varying float a;varying vec2 b;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;b=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);}}';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.linestringreplay.defaultshader.Vertex.SOURCE = ol.DEBUG_WEBGL ?
- ol.render.webgl.linestringreplay.defaultshader.Vertex.DEBUG_SOURCE :
- ol.render.webgl.linestringreplay.defaultshader.Vertex.OPTIMIZED_SOURCE;
-
-
- ol.render.webgl.linestringreplay.defaultshader.vertex = new ol.render.webgl.linestringreplay.defaultshader.Vertex();
-
-
- /**
- * @constructor
- * @param {WebGLRenderingContext} gl GL.
- * @param {WebGLProgram} program Program.
- * @struct
- */
- ol.render.webgl.linestringreplay.defaultshader.Locations = function(gl, program) {
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_color = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_color' : 'n');
-
- /**
- * @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_offsetRotateMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_offsetScaleMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_opacity = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_opacity' : 'm');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_pixelRatio = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_pixelRatio' : 'p');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_projectionMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_size = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_size' : 'o');
-
- /**
- * @type {number}
- */
- this.a_direction = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_direction' : 'g');
-
- /**
- * @type {number}
- */
- this.a_lastPos = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_lastPos' : 'd');
-
- /**
- * @type {number}
- */
- this.a_nextPos = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_nextPos' : 'f');
-
- /**
- * @type {number}
- */
- this.a_position = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_position' : 'e');
- };
-
- }
-
- 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.webgl');
- goog.require('ol.webgl.Buffer');
-
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @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_) {
- // eslint-disable-next-line openlayers-internal/no-missing-requires
- 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
- /* eslint openlayers-internal/no-missing-requires: 0 */
- goog.provide('ol.render.webgl.polygonreplay.defaultshader');
-
- goog.require('ol');
- goog.require('ol.webgl.Fragment');
- goog.require('ol.webgl.Vertex');
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @constructor
- * @extends {ol.webgl.Fragment}
- * @struct
- */
- ol.render.webgl.polygonreplay.defaultshader.Fragment = function() {
- ol.webgl.Fragment.call(this, ol.render.webgl.polygonreplay.defaultshader.Fragment.SOURCE);
- };
- ol.inherits(ol.render.webgl.polygonreplay.defaultshader.Fragment, ol.webgl.Fragment);
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.polygonreplay.defaultshader.Fragment.DEBUG_SOURCE = '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';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.polygonreplay.defaultshader.Fragment.OPTIMIZED_SOURCE = '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;}';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.polygonreplay.defaultshader.Fragment.SOURCE = ol.DEBUG_WEBGL ?
- ol.render.webgl.polygonreplay.defaultshader.Fragment.DEBUG_SOURCE :
- ol.render.webgl.polygonreplay.defaultshader.Fragment.OPTIMIZED_SOURCE;
-
-
- ol.render.webgl.polygonreplay.defaultshader.fragment = new ol.render.webgl.polygonreplay.defaultshader.Fragment();
-
-
- /**
- * @constructor
- * @extends {ol.webgl.Vertex}
- * @struct
- */
- ol.render.webgl.polygonreplay.defaultshader.Vertex = function() {
- ol.webgl.Vertex.call(this, ol.render.webgl.polygonreplay.defaultshader.Vertex.SOURCE);
- };
- ol.inherits(ol.render.webgl.polygonreplay.defaultshader.Vertex, ol.webgl.Vertex);
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.polygonreplay.defaultshader.Vertex.DEBUG_SOURCE = '\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';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.polygonreplay.defaultshader.Vertex.OPTIMIZED_SOURCE = 'attribute vec2 a;uniform mat4 b;uniform mat4 c;uniform mat4 d;void main(void){gl_Position=b*vec4(a,0.0,1.0);}';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.render.webgl.polygonreplay.defaultshader.Vertex.SOURCE = ol.DEBUG_WEBGL ?
- ol.render.webgl.polygonreplay.defaultshader.Vertex.DEBUG_SOURCE :
- ol.render.webgl.polygonreplay.defaultshader.Vertex.OPTIMIZED_SOURCE;
-
-
- ol.render.webgl.polygonreplay.defaultshader.vertex = new ol.render.webgl.polygonreplay.defaultshader.Vertex();
-
-
- /**
- * @constructor
- * @param {WebGLRenderingContext} gl GL.
- * @param {WebGLProgram} program Program.
- * @struct
- */
- ol.render.webgl.polygonreplay.defaultshader.Locations = function(gl, program) {
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_color = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_color' : 'e');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_offsetRotateMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'd');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_offsetScaleMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'c');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_opacity = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_opacity' : 'f');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_projectionMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'b');
-
- /**
- * @type {number}
- */
- this.a_position = gl.getAttribLocation(
- program, ol.DEBUG_WEBGL ? 'a_position' : 'a');
- };
-
- }
-
- 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.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_;
- };
-
-
- /**
- * @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 = partialSort;
- function partialSort(arr, k, left, right, compare) {
- left = left || 0;
- right = right || (arr.length - 1);
- compare = compare || defaultCompare;
- 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));
- partialSort(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;
- }
-
- 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(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.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];
- }
- };
-
- 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.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');
-
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @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_) {
- // eslint-disable-next-line openlayers-internal/no-missing-requires
- 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.has');
- goog.require('ol.render.webgl');
- goog.require('ol.render.webgl.TextureReplay');
- goog.require('ol.style.AtlasManager');
- goog.require('ol.webgl.Buffer');
-
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @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(flatCoordinates, offset,
- end, stride, geometry, feature) {
- if (this.text_) {
- 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.webgl.TextReplay.Align_[textStyle.getTextAlign()];
- var textBaseline = ol.render.webgl.TextReplay.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_;
- };
-
-
- /**
- * @enum {number}
- * @private
- */
- ol.render.webgl.TextReplay.Align_ = {
- left: 0,
- end: 0,
- center: 0.5,
- right: 1,
- start: 1,
- top: 0,
- middle: 0.5,
- hanging: 0.2,
- alphabetic: 0.8,
- ideographic: 0.8,
- bottom: 1
- };
-
- }
-
- 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');
-
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @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.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');
-
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @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 {Array.<number>} flatCoordinates Flat coordinates.
- * @param {number} offset Offset.
- * @param {number} end End.
- * @param {number} stride Stride.
- * @private
- */
- ol.render.webgl.Immediate.prototype.drawText_ = function(replayGroup,
- flatCoordinates, offset, end, stride) {
- var context = this.context_;
- var replay = /** @type {ol.render.webgl.TextReplay} */ (
- replayGroup.getReplay(0, ol.render.ReplayType.TEXT));
- replay.setTextStyle(this.textStyle_);
- replay.drawText(flatCoordinates, offset, end, stride, null, 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_) {
- var flatCoordinates = geometry.getFlatCoordinates();
- var stride = geometry.getStride();
- this.drawText_(replayGroup, flatCoordinates, 0, flatCoordinates.length, stride);
- }
- };
-
-
- /**
- * @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_) {
- var flatCoordinates = geometry.getFlatCoordinates();
- var stride = geometry.getStride();
- this.drawText_(replayGroup, flatCoordinates, 0, flatCoordinates.length, stride);
- }
- };
-
-
- /**
- * @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_) {
- var flatMidpoint = geometry.getFlatMidpoint();
- this.drawText_(replayGroup, flatMidpoint, 0, 2, 2);
- }
- };
-
-
- /**
- * @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_) {
- var flatMidpoints = geometry.getFlatMidpoints();
- this.drawText_(replayGroup, flatMidpoints, 0, flatMidpoints.length, 2);
- }
- };
-
-
- /**
- * @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_) {
- var flatInteriorPoint = geometry.getFlatInteriorPoint();
- this.drawText_(replayGroup, flatInteriorPoint, 0, 2, 2);
- }
- };
-
-
- /**
- * @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_) {
- var flatInteriorPoints = geometry.getFlatInteriorPoints();
- this.drawText_(replayGroup, flatInteriorPoints, 0, flatInteriorPoints.length, 2);
- }
- };
-
-
- /**
- * @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.getCenter(), 0, 2, 2);
- }
- };
-
-
- /**
- * @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;
- };
-
- }
-
- goog.provide('ol.structs.LRUCache');
-
- goog.require('ol.asserts');
-
-
- /**
- * 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
- * @struct
- * @template T
- */
- ol.structs.LRUCache = function() {
-
- /**
- * @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;
-
- };
-
-
- /**
- * FIXME empty description for jsdoc
- */
- ol.structs.LRUCache.prototype.clear = function() {
- this.count_ = 0;
- this.entries_ = {};
- this.oldest_ = null;
- this.newest_ = null;
- };
-
-
- /**
- * @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_;
- };
-
-
- /**
- * @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_;
- };
-
-
- /**
- * @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_;
- };
-
- // 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.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');
-
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @constructor
- * @extends {ol.renderer.Map}
- * @param {Element} container Container.
- * @param {ol.Map} map Map.
- */
- 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.Map} 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);
-
-
- /**
- * @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.Map} 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;
- };
-
- }
-
- // FIXME recheck layer/map projection compatibility when projection changes
- // FIXME layer renderers should skip when they can't reproject
- // FIXME add tilt and height?
-
- goog.provide('ol.Map');
-
- 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.control');
- 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.interaction');
- goog.require('ol.layer.Group');
- goog.require('ol.obj');
- goog.require('ol.renderer.Map');
- goog.require('ol.renderer.Type');
- goog.require('ol.renderer.canvas.Map');
- goog.require('ol.renderer.webgl.Map');
- goog.require('ol.size');
- goog.require('ol.structs.PriorityQueue');
- goog.require('ol.transform');
-
-
- /**
- * @const
- * @type {string}
- */
- ol.OL_URL = 'https://openlayers.org/';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.OL_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';
-
-
- /**
- * @type {Array.<ol.renderer.Type>}
- * @const
- */
- ol.DEFAULT_RENDERER_TYPES = [
- ol.renderer.Type.CANVAS,
- ol.renderer.Type.WEBGL
- ];
-
-
- /**
- * @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.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.Map = function(options) {
-
- ol.Object.call(this);
-
- var optionsInternal = ol.Map.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>}
- * @private
- */
- this.controls_ = optionsInternal.controls;
-
- /**
- * @type {ol.Collection.<ol.interaction.Interaction>}
- * @private
- */
- this.interactions_ = optionsInternal.interactions;
-
- /**
- * @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_ = new /** @type {Function} */ (optionsInternal.rendererConstructor)(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.Map}
- */
- 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.Map}
- */
- 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.Map, ol.Object);
-
-
- /**
- * Add the given control to the map.
- * @param {ol.control.Control} control Control.
- * @api
- */
- ol.Map.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.Map.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.Map.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.Map.prototype.addOverlay = function(overlay) {
- this.getOverlays().push(overlay);
- };
-
-
- /**
- * This deals with map's overlay collection changes.
- * @param {ol.Overlay} overlay Overlay.
- * @private
- */
- ol.Map.prototype.addOverlayInternal_ = function(overlay) {
- var id = overlay.getId();
- if (id !== undefined) {
- this.overlayIdIndex_[id.toString()] = overlay;
- }
- overlay.setMap(this);
- };
-
-
- /**
- *
- * @inheritDoc
- */
- ol.Map.prototype.disposeInternal = function() {
- this.mapBrowserEventHandler_.dispose();
- this.renderer_.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.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.Map.prototype.handleSizeChanged_ = function() {
- this.render();
- };
-
-
- /**
- * @private
- */
- ol.Map.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) {
- 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.Map.prototype.handleTileChange_ = function() {
- this.render();
- };
-
-
- /**
- * @private
- */
- ol.Map.prototype.handleViewPropertyChanged_ = function() {
- this.render();
- };
-
-
- /**
- * @private
- */
- ol.Map.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.Map.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.Map.prototype.isRendered = function() {
- return !!this.frameState_;
- };
-
-
- /**
- * Requests an immediate render in a synchronous manner.
- * @api
- */
- ol.Map.prototype.renderSync = function() {
- if (this.animationDelayKey_) {
- cancelAnimationFrame(this.animationDelayKey_);
- }
- this.animationDelay_();
- };
-
-
- /**
- * Request a map rendering (at the next animation frame).
- * @api
- */
- ol.Map.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.Map.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.Map.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.Map.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.Map.prototype.removeOverlay = function(overlay) {
- return this.getOverlays().remove(overlay);
- };
-
-
- /**
- * @param {number} time Time.
- * @private
- */
- ol.Map.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();
- frameState = /** @type {olx.FrameState} */ ({
- animate: false,
- attributions: {},
- coordinateToPixelTransform: this.coordinateToPixelTransform_,
- extent: extent,
- focus: !this.focus_ ? viewState.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.Map.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.Map.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.Map.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.Map.prototype.setView = function(view) {
- this.set(ol.MapProperty.VIEW, view);
- };
-
-
- /**
- * @param {ol.Feature} feature Feature.
- */
- ol.Map.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.Map.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.Map.prototype.unskipFeature = function(feature) {
- var featureUid = ol.getUid(feature).toString();
- delete this.skippedFeatureUids_[featureUid];
- this.render();
- };
-
-
- /**
- * @param {olx.MapOptions} options Map options.
- * @return {ol.MapOptionsInternal} Internal map options.
- */
- ol.Map.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.OL_LOGO_URL] = ol.OL_URL;
- } 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 {function(new: ol.renderer.Map, Element, ol.Map)}
- */
- var rendererConstructor = ol.renderer.Map;
-
- /**
- * @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.DEFAULT_RENDERER_TYPES);
- }
- } else {
- rendererTypes = ol.DEFAULT_RENDERER_TYPES;
- }
-
- var i, ii;
- for (i = 0, ii = rendererTypes.length; i < ii; ++i) {
- /** @type {ol.renderer.Type} */
- var rendererType = rendererTypes[i];
- if (ol.ENABLE_CANVAS && rendererType == ol.renderer.Type.CANVAS) {
- if (ol.has.CANVAS) {
- rendererConstructor = ol.renderer.canvas.Map;
- break;
- }
- } else if (ol.ENABLE_WEBGL && rendererType == ol.renderer.Type.WEBGL) {
- if (ol.has.WEBGL) {
- rendererConstructor = ol.renderer.webgl.Map;
- break;
- }
- }
- }
-
- 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;
- }
- } else {
- controls = ol.control.defaults();
- }
-
- 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;
- }
- } else {
- interactions = ol.interaction.defaults();
- }
-
- 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,
- rendererConstructor: rendererConstructor,
- values: values
- };
-
- };
-
- 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);
-
- /**
- * @private
- * @type {number|string|undefined}
- */
- this.id_ = options.id;
-
- /**
- * @private
- * @type {boolean}
- */
- this.insertFirst_ = options.insertFirst !== undefined ?
- options.insertFirst : true;
-
- /**
- * @private
- * @type {boolean}
- */
- this.stopEvent_ = options.stopEvent !== undefined ? options.stopEvent : true;
-
- /**
- * @private
- * @type {Element}
- */
- this.element_ = document.createElement('DIV');
- this.element_.className = 'ol-overlay-container ' + ol.css.CLASS_SELECTABLE;
- this.element_.style.position = 'absolute';
-
- /**
- * @protected
- * @type {boolean}
- */
- this.autoPan = options.autoPan !== undefined ? options.autoPan : false;
-
- /**
- * @private
- * @type {olx.OverlayPanOptions}
- */
- this.autoPanAnimation_ = options.autoPanAnimation ||
- /** @type {olx.OverlayPanOptions} */ ({});
-
- /**
- * @private
- * @type {number}
- */
- this.autoPanMargin_ = options.autoPanMargin !== undefined ?
- options.autoPanMargin : 20;
-
- /**
- * @private
- * @type {{bottom_: string,
- * left_: string,
- * right_: string,
- * top_: string,
- * visible: boolean}}
- */
- this.rendered_ = {
- bottom_: '',
- left_: '',
- right_: '',
- top_: '',
- visible: true
- };
-
- /**
- * @private
- * @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.Map|undefined} The map that the overlay is part of.
- * @observable
- * @api
- */
- ol.Overlay.prototype.getMap = function() {
- return /** @type {ol.Map|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.Map|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).
- * @private
- */
- 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.
- * @private
- */
- 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;
- }
- }
- };
-
-
- /**
- * @enum {string}
- * @private
- */
- 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.Map');
- 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.Map}
- * @private
- */
- this.ovmap_ = new ol.Map({
- 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.Map} 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);
-
- 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}
- * @private
- */
- 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_();
- };
-
-
- /**
- * @private
- */
- 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/}
- *
- * @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.ImageState');
-
- /**
- * @enum {number}
- */
- ol.ImageState = {
- IDLE: 0,
- LOADING: 1,
- LOADED: 2,
- ERROR: 3
- };
-
- 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.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.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.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.
- * @api
- */
- ol.geom.MultiPolygon.prototype.getInteriorPoints = function() {
- var interiorPoints = new ol.geom.MultiPoint(null);
- interiorPoints.setFlatCoordinates(ol.geom.GeometryLayout.XY,
- 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.
- *
- * @constructor
- * @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
- * @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.
- *
- * @constructor
- * @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.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.
- *
- * @constructor
- * @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.
- *
- * @constructor
- * @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.Spatial');
-
- goog.require('ol');
- goog.require('ol.format.filter.Filter');
-
-
- /**
- * @classdesc
- * Represents a spatial operator to test whether a geometry-valued property
- * relates to a given geometry.
- *
- * @constructor
- * @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.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.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 `<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;
-
- };
- 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_);
- }
- 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 if (crs.type == 'EPSG') {
- // 'EPSG' is not part of the GeoJSON specification, but is generated by
- // GeoServer.
- // TODO: remove this when http://jira.codehaus.org/browse/GEOS-5996
- // is fixed and widely deployed.
- projection = ol.proj.get('EPSG:' + crs.properties.code);
- } 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');
- /** @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 containerDimension = node.parentNode.getAttribute('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 (containerDimension) {
- dim = ol.format.XSD.readNonNegativeIntegerString(containerDimension);
- }
- 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 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 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.
- * @return {ol.style.Icon} The cloned style.
- * @api
- */
- ol.style.Icon.prototype.clone = function() {
- var oldImage = this.getImage(1);
- var newImage;
- if (this.iconImage_.getImageState() === ol.ImageState.LOADED) {
- if (oldImage.tagName.toUpperCase() === 'IMG') {
- newImage = /** @type {Image} */ (oldImage.cloneNode(true));
- } else {
- newImage = /** @type {HTMLCanvasElement} */ (document.createElement('canvas'));
- var context = newImage.getContext('2d');
- newImage.width = oldImage.width;
- newImage.height = oldImage.height;
- context.drawImage(oldImage, 0, 0);
- }
- }
- 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,
- img: newImage ? newImage : undefined,
- imgSize: newImage ? this.iconImage_.getSize().slice() : undefined,
- src: newImage ? undefined : 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');
-
-
- /**
- * @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 {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;
- };
-
-
- /**
- * 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(),
- 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 font name.
- * @return {string|undefined} Font.
- * @api
- */
- ol.style.Text.prototype.getFont = function() {
- return this.font_;
- };
-
-
- /**
- * 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_;
- };
-
-
- /**
- * Set the font.
- *
- * @param {string|undefined} font Font.
- * @api
- */
- ol.style.Text.prototype.setFont = function(font) {
- this.font_ = font;
- };
-
-
- /**
- * 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 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;
- };
-
- // 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();
- if (node.baseURI && node.baseURI !== 'about:blank') {
- var url = new URL(s, node.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;
- if (node.baseURI && node.baseURI !== 'about:blank') {
- var url = new URL('#' + id, node.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;
- if (node.baseURI && node.baseURI !== 'about:blank') {
- var url = new URL('#' + id, node.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;
-
-
- /**
- * @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.vectortile.VectorTile');
-
- /** @typedef {function(*)} */
- ol.ext.vectortile.VectorTile = function() {};
-
- (function() {(function (exports) {
- 'use strict';
-
- var pointGeometry = Point;
- function Point(x, y) {
- this.x = x;
- this.y = y;
- }
- Point.prototype = {
- clone: function() { return new Point(this.x, this.y); },
- add: function(p) { return this.clone()._add(p); },
- sub: function(p) { return this.clone()._sub(p); },
- multByPoint: function(p) { return this.clone()._multByPoint(p); },
- divByPoint: function(p) { return this.clone()._divByPoint(p); },
- mult: function(k) { return this.clone()._mult(k); },
- div: function(k) { return this.clone()._div(k); },
- rotate: function(a) { return this.clone()._rotate(a); },
- rotateAround: function(a,p) { return this.clone()._rotateAround(a,p); },
- matMult: function(m) { return this.clone()._matMult(m); },
- unit: function() { return this.clone()._unit(); },
- perp: function() { return this.clone()._perp(); },
- round: function() { return this.clone()._round(); },
- mag: function() {
- return Math.sqrt(this.x * this.x + this.y * this.y);
- },
- equals: function(other) {
- return this.x === other.x &&
- this.y === other.y;
- },
- dist: function(p) {
- return Math.sqrt(this.distSqr(p));
- },
- distSqr: function(p) {
- var dx = p.x - this.x,
- dy = p.y - this.y;
- return dx * dx + dy * dy;
- },
- angle: function() {
- return Math.atan2(this.y, this.x);
- },
- angleTo: function(b) {
- return Math.atan2(this.y - b.y, this.x - b.x);
- },
- angleWith: function(b) {
- return this.angleWithSep(b.x, b.y);
- },
- angleWithSep: function(x, y) {
- return Math.atan2(
- this.x * y - this.y * x,
- this.x * x + this.y * y);
- },
- _matMult: function(m) {
- var x = m[0] * this.x + m[1] * this.y,
- y = m[2] * this.x + m[3] * this.y;
- this.x = x;
- this.y = y;
- return this;
- },
- _add: function(p) {
- this.x += p.x;
- this.y += p.y;
- return this;
- },
- _sub: function(p) {
- this.x -= p.x;
- this.y -= p.y;
- return this;
- },
- _mult: function(k) {
- this.x *= k;
- this.y *= k;
- return this;
- },
- _div: function(k) {
- this.x /= k;
- this.y /= k;
- return this;
- },
- _multByPoint: function(p) {
- this.x *= p.x;
- this.y *= p.y;
- return this;
- },
- _divByPoint: function(p) {
- this.x /= p.x;
- this.y /= p.y;
- return this;
- },
- _unit: function() {
- this._div(this.mag());
- return this;
- },
- _perp: function() {
- var y = this.y;
- this.y = this.x;
- this.x = -y;
- return this;
- },
- _rotate: function(angle) {
- var cos = Math.cos(angle),
- sin = Math.sin(angle),
- x = cos * this.x - sin * this.y,
- y = sin * this.x + cos * this.y;
- this.x = x;
- this.y = y;
- return this;
- },
- _rotateAround: function(angle, p) {
- var cos = Math.cos(angle),
- sin = Math.sin(angle),
- x = p.x + cos * (this.x - p.x) - sin * (this.y - p.y),
- y = p.y + sin * (this.x - p.x) + cos * (this.y - p.y);
- this.x = x;
- this.y = y;
- return this;
- },
- _round: function() {
- this.x = Math.round(this.x);
- this.y = Math.round(this.y);
- return this;
- }
- };
- Point.convert = function (a) {
- if (a instanceof Point) {
- return a;
- }
- if (Array.isArray(a)) {
- return new Point(a[0], a[1]);
- }
- return a;
- };
-
- var vectortilefeature = VectorTileFeature$1;
- function VectorTileFeature$1(pbf, end, extent, keys, values) {
- this.properties = {};
- this.extent = extent;
- this.type = 0;
- this._pbf = pbf;
- this._geometry = -1;
- this._keys = keys;
- this._values = values;
- pbf.readFields(readFeature, this, end);
- }
- function readFeature(tag, feature, pbf) {
- if (tag == 1) feature.id = pbf.readVarint();
- else if (tag == 2) readTag(pbf, feature);
- else if (tag == 3) feature.type = pbf.readVarint();
- else if (tag == 4) feature._geometry = pbf.pos;
- }
- function readTag(pbf, feature) {
- var end = pbf.readVarint() + pbf.pos;
- while (pbf.pos < end) {
- var key = feature._keys[pbf.readVarint()],
- value = feature._values[pbf.readVarint()];
- feature.properties[key] = value;
- }
- }
- VectorTileFeature$1.types = ['Unknown', 'Point', 'LineString', 'Polygon'];
- VectorTileFeature$1.prototype.loadGeometry = function() {
- var pbf = this._pbf;
- pbf.pos = this._geometry;
- var end = pbf.readVarint() + pbf.pos,
- cmd = 1,
- length = 0,
- x = 0,
- y = 0,
- lines = [],
- line;
- 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) {
- if (line) lines.push(line);
- line = [];
- }
- line.push(new pointGeometry(x, y));
- } else if (cmd === 7) {
- if (line) {
- line.push(line[0].clone());
- }
- } else {
- throw new Error('unknown command ' + cmd);
- }
- }
- if (line) lines.push(line);
- return lines;
- };
- VectorTileFeature$1.prototype.bbox = function() {
- var pbf = this._pbf;
- pbf.pos = this._geometry;
- var end = pbf.readVarint() + pbf.pos,
- cmd = 1,
- length = 0,
- x = 0,
- y = 0,
- x1 = Infinity,
- x2 = -Infinity,
- y1 = Infinity,
- y2 = -Infinity;
- 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 (x < x1) x1 = x;
- if (x > x2) x2 = x;
- if (y < y1) y1 = y;
- if (y > y2) y2 = y;
- } else if (cmd !== 7) {
- throw new Error('unknown command ' + cmd);
- }
- }
- return [x1, y1, x2, y2];
- };
- VectorTileFeature$1.prototype.toGeoJSON = function(x, y, z) {
- var size = this.extent * Math.pow(2, z),
- x0 = this.extent * x,
- y0 = this.extent * y,
- coords = this.loadGeometry(),
- type = VectorTileFeature$1.types[this.type],
- i, j;
- function project(line) {
- for (var j = 0; j < line.length; j++) {
- var p = line[j], y2 = 180 - (p.y + y0) * 360 / size;
- line[j] = [
- (p.x + x0) * 360 / size - 180,
- 360 / Math.PI * Math.atan(Math.exp(y2 * Math.PI / 180)) - 90
- ];
- }
- }
- switch (this.type) {
- case 1:
- var points = [];
- for (i = 0; i < coords.length; i++) {
- points[i] = coords[i][0];
- }
- coords = points;
- project(coords);
- break;
- case 2:
- for (i = 0; i < coords.length; i++) {
- project(coords[i]);
- }
- break;
- case 3:
- coords = classifyRings(coords);
- for (i = 0; i < coords.length; i++) {
- for (j = 0; j < coords[i].length; j++) {
- project(coords[i][j]);
- }
- }
- break;
- }
- if (coords.length === 1) {
- coords = coords[0];
- } else {
- type = 'Multi' + type;
- }
- var result = {
- type: "Feature",
- geometry: {
- type: type,
- coordinates: coords
- },
- properties: this.properties
- };
- if ('id' in this) {
- result.id = this.id;
- }
- return result;
- };
- function classifyRings(rings) {
- var len = rings.length;
- if (len <= 1) return [rings];
- var polygons = [],
- polygon,
- ccw;
- for (var i = 0; i < len; i++) {
- var area = signedArea(rings[i]);
- if (area === 0) continue;
- if (ccw === undefined) ccw = area < 0;
- if (ccw === area < 0) {
- if (polygon) polygons.push(polygon);
- polygon = [rings[i]];
- } else {
- polygon.push(rings[i]);
- }
- }
- if (polygon) polygons.push(polygon);
- return polygons;
- }
- function signedArea(ring) {
- var sum = 0;
- for (var i = 0, len = ring.length, j = len - 1, p1, p2; i < len; j = i++) {
- p1 = ring[i];
- p2 = ring[j];
- sum += (p2.x - p1.x) * (p1.y + p2.y);
- }
- return sum;
- }
-
- var vectortilelayer = VectorTileLayer$1;
- function VectorTileLayer$1(pbf, end) {
- this.version = 1;
- this.name = null;
- this.extent = 4096;
- this.length = 0;
- this._pbf = pbf;
- this._keys = [];
- this._values = [];
- this._features = [];
- pbf.readFields(readLayer, this, end);
- this.length = this._features.length;
- }
- function readLayer(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) layer._values.push(readValueMessage(pbf));
- }
- function readValueMessage(pbf) {
- var value = null,
- end = pbf.readVarint() + pbf.pos;
- while (pbf.pos < end) {
- var 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;
- }
- return value;
- }
- VectorTileLayer$1.prototype.feature = function(i) {
- if (i < 0 || i >= this._features.length) throw new Error('feature index out of bounds');
- this._pbf.pos = this._features[i];
- var end = this._pbf.readVarint() + this._pbf.pos;
- return new vectortilefeature(this._pbf, end, this.extent, this._keys, this._values);
- };
-
- var vectortile = VectorTile$1;
- function VectorTile$1(pbf, end) {
- this.layers = pbf.readFields(readTile, {}, end);
- }
- function readTile(tag, layers, pbf) {
- if (tag === 3) {
- var layer = new vectortilelayer(pbf, pbf.readVarint() + pbf.pos);
- if (layer.length) layers[layer.name] = layer;
- }
- }
-
- var VectorTile = vectortile;
- var VectorTileFeature = vectortilefeature;
- var VectorTileLayer = vectortilelayer;
- var vectorTile = {
- VectorTile: VectorTile,
- VectorTileFeature: VectorTileFeature,
- VectorTileLayer: VectorTileLayer
- };
-
- exports['default'] = vectorTile;
- exports.VectorTile = VectorTile;
- exports.VectorTileFeature = VectorTileFeature;
- exports.VectorTileLayer = VectorTileLayer;
-
- }((this.vectortile = this.vectortile || {})));}).call(ol.ext);
-
- goog.provide('ol.render.Feature');
-
- goog.require('ol');
- goog.require('ol.extent');
- goog.require('ol.geom.GeometryType');
-
-
- /**
- * Lightweight, read-only, {@link ol.Feature} and {@link ol.geom.Geometry} like
- * structure, optimized for 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>|Array.<Array.<number>>}
- */
- this.ends_ = ends;
-
- /**
- * @private
- * @type {Object.<string, *>}
- */
- this.properties_ = properties;
- };
-
-
- /**
- * 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 = 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_;
- };
-
- /**
- * 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_;
- };
-
- //FIXME Implement projection handling
-
- goog.provide('ol.format.MVT');
-
- goog.require('ol');
- goog.require('ol.ext.PBF');
- goog.require('ol.ext.vectortile.VectorTile');
- 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.Point');
- goog.require('ol.geom.Polygon');
- 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: '',
- 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);
-
-
- /**
- * @inheritDoc
- * @api
- */
- ol.format.MVT.prototype.getLastExtent = function() {
- return this.extent_;
- };
-
-
- /**
- * @inheritDoc
- */
- ol.format.MVT.prototype.getType = function() {
- return ol.format.FormatType.ARRAY_BUFFER;
- };
-
-
- /**
- * @private
- * @param {Object} rawFeature Raw Mapbox feature.
- * @param {string} layer Layer.
- * @param {olx.format.ReadOptions=} opt_options Read options.
- * @return {ol.Feature} Feature.
- */
- ol.format.MVT.prototype.readFeature_ = function(
- rawFeature, layer, opt_options) {
- var feature = new this.featureClass_();
- var id = rawFeature.id;
- var values = rawFeature.properties;
- values[this.layerName_] = layer;
- if (this.geometryName_) {
- feature.setGeometryName(this.geometryName_);
- }
- var geometry = ol.format.Feature.transformWithOptions(
- ol.format.MVT.readGeometry_(rawFeature), false,
- this.adaptOptions(opt_options));
- feature.setGeometry(geometry);
- feature.setId(id);
- feature.setProperties(values);
- return feature;
- };
-
-
- /**
- * @private
- * @param {Object} rawFeature Raw Mapbox feature.
- * @param {string} layer Layer.
- * @return {ol.render.Feature} Feature.
- */
- ol.format.MVT.prototype.readRenderFeature_ = function(rawFeature, layer) {
- var coords = rawFeature.loadGeometry();
- var ends = [];
- var flatCoordinates = [];
- ol.format.MVT.calculateFlatCoordinates_(coords, flatCoordinates, ends);
-
- var type = rawFeature.type;
- /** @type {ol.geom.GeometryType} */
- var geometryType;
- if (type === 1) {
- geometryType = coords.length === 1 ?
- ol.geom.GeometryType.POINT : ol.geom.GeometryType.MULTI_POINT;
- } else if (type === 2) {
- if (coords.length === 1) {
- geometryType = ol.geom.GeometryType.LINE_STRING;
- } else {
- geometryType = ol.geom.GeometryType.MULTI_LINE_STRING;
- }
- } else if (type === 3) {
- geometryType = ol.geom.GeometryType.POLYGON;
- }
-
- var values = rawFeature.properties;
- values[this.layerName_] = layer;
- var id = rawFeature.id;
-
- return new this.featureClass_(geometryType, flatCoordinates, ends, values, id);
- };
-
-
- /**
- * @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 tile = new ol.ext.vectortile.VectorTile(pbf);
- var features = [];
- var featureClass = this.featureClass_;
- var layer, feature;
- for (var name in tile.layers) {
- if (layers && layers.indexOf(name) == -1) {
- continue;
- }
- layer = tile.layers[name];
-
- var rawFeature;
- for (var i = 0, ii = layer.length; i < ii; ++i) {
- rawFeature = layer.feature(i);
- if (featureClass === ol.render.Feature) {
- feature = this.readRenderFeature_(rawFeature, name);
- } else {
- feature = this.readFeature_(rawFeature, name, opt_options);
- }
- features.push(feature);
- }
- this.extent_ = layer ? [0, 0, layer.extent, layer.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;
- };
-
-
- /**
- * @private
- * @param {Object} coords Raw feature coordinates.
- * @param {Array.<number>} flatCoordinates Flat coordinates to be populated by
- * this function.
- * @param {Array.<number>} ends Ends to be populated by this function.
- */
- ol.format.MVT.calculateFlatCoordinates_ = function(
- coords, flatCoordinates, ends) {
- var end = 0;
- for (var i = 0, ii = coords.length; i < ii; ++i) {
- var line = coords[i];
- var j, jj;
- for (j = 0, jj = line.length; j < jj; ++j) {
- var coord = line[j];
- // Non-tilespace coords can be calculated here when a TileGrid and
- // TileCoord are known.
- flatCoordinates.push(coord.x, coord.y);
- }
- end += 2 * j;
- ends.push(end);
- }
- };
-
-
- /**
- * @private
- * @param {Object} rawFeature Raw Mapbox feature.
- * @return {ol.geom.Geometry} Geometry.
- */
- ol.format.MVT.readGeometry_ = function(rawFeature) {
- var type = rawFeature.type;
- if (type === 0) {
- return null;
- }
-
- var coords = rawFeature.loadGeometry();
- var ends = [];
- var flatCoordinates = [];
- ol.format.MVT.calculateFlatCoordinates_(coords, flatCoordinates, ends);
-
- var geom;
- if (type === 1) {
- geom = coords.length === 1 ?
- new ol.geom.Point(null) : new ol.geom.MultiPoint(null);
- } else if (type === 2) {
- if (coords.length === 1) {
- geom = new ol.geom.LineString(null);
- } else {
- geom = new ol.geom.MultiLineString(null);
- }
- } else if (type === 3) {
- geom = new ol.geom.Polygon(null);
- }
-
- geom.setFlatCoordinates(ol.geom.GeometryLayout.XY, flatCoordinates,
- ends);
-
- return geom;
- };
-
-
- /**
- * 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 options = /** @type {olx.format.ReadOptions} */ (objectStack[0]);
- var id = node.getAttribute('id');
- var values = ol.xml.pushParseAndPop({
- ndrefs: [],
- tags: {}
- }, ol.format.OSMXML.WAY_PARSERS_, node, objectStack);
- var state = /** @type {Object} */ (objectStack[objectStack.length - 1]);
- /** @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(id);
- feature.setProperties(values.tags);
- state.features.push(feature);
- };
-
-
- /**
- * @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: {},
- features: []
- }, ol.format.OSMXML.PARSERS_, node, [options]);
- 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_, {
- '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';
-
-
- /**
- * 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);
- 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) {
- values.push({name: keys[i], 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.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_),
- '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.
- * @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';
-
-
- /**
- * @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.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.Map}
- * @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.Map} 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.Map} 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.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.
- * @param {Array.<ol.Attribution>} attributions Attributions.
- */
- ol.ImageBase = function(extent, resolution, pixelRatio, state, attributions) {
-
- ol.events.EventTarget.call(this);
-
- /**
- * @private
- * @type {Array.<ol.Attribution>}
- */
- this.attributions_ = attributions;
-
- /**
- * @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 {Array.<ol.Attribution>} Attributions.
- */
- ol.ImageBase.prototype.getAttributions = function() {
- return this.attributions_;
- };
-
-
- /**
- * @return {ol.Extent} Extent.
- */
- ol.ImageBase.prototype.getExtent = function() {
- return this.extent;
- };
-
-
- /**
- * @abstract
- * @param {Object=} opt_context Object.
- * @return {HTMLCanvasElement|Image|HTMLVideoElement} Image.
- */
- ol.ImageBase.prototype.getImage = function(opt_context) {};
-
-
- /**
- * @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.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.obj');
-
-
- /**
- * @constructor
- * @extends {ol.ImageBase}
- * @param {ol.Extent} extent Extent.
- * @param {number|undefined} resolution Resolution.
- * @param {number} pixelRatio Pixel ratio.
- * @param {Array.<ol.Attribution>} attributions Attributions.
- * @param {string} src Image source URI.
- * @param {?string} crossOrigin Cross origin.
- * @param {ol.ImageLoadFunctionType} imageLoadFunction Image load function.
- */
- ol.Image = function(extent, resolution, pixelRatio, attributions, src,
- crossOrigin, imageLoadFunction) {
-
- ol.ImageBase.call(this, extent, resolution, pixelRatio, ol.ImageState.IDLE,
- attributions);
-
- /**
- * @private
- * @type {string}
- */
- this.src_ = src;
-
- /**
- * @private
- * @type {HTMLCanvasElement|Image|HTMLVideoElement}
- */
- this.image_ = new Image();
- if (crossOrigin !== null) {
- this.image_.crossOrigin = crossOrigin;
- }
-
- /**
- * @private
- * @type {Object.<number, (HTMLCanvasElement|Image|HTMLVideoElement)>}
- */
- this.imageByContext_ = {};
-
- /**
- * @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(opt_context) {
- if (opt_context !== undefined) {
- var image;
- var key = ol.getUid(opt_context);
- if (key in this.imageByContext_) {
- return this.imageByContext_[key];
- } else if (ol.obj.isEmpty(this.imageByContext_)) {
- image = this.image_;
- } else {
- image = /** @type {Image} */ (this.image_.cloneNode(false));
- }
- this.imageByContext_[key] = image;
- return image;
- } else {
- 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.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 {Array.<ol.Attribution>} attributions Attributions.
- * @param {HTMLCanvasElement} canvas Canvas.
- * @param {ol.ImageCanvasLoader=} opt_loader Optional loader function to
- * support asynchronous canvas drawing.
- */
- ol.ImageCanvas = function(extent, resolution, pixelRatio, attributions,
- 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, attributions);
-
- /**
- * @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(opt_context) {
- return this.canvas_;
- };
-
- goog.provide('ol.Tile');
-
- goog.require('ol');
- goog.require('ol.TileState');
- 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.
- */
- ol.Tile = function(tileCoord, state) {
-
- ol.events.EventTarget.call(this);
-
- /**
- * @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 = '';
-
- };
- 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() {};
-
- 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.
- */
- ol.ImageTile = function(tileCoord, state, src, crossOrigin, tileLoadFunction) {
-
- ol.Tile.call(this, tileCoord, state);
-
- /**
- * 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_.src = ol.ImageTile.blankImage.toDataURL('image/png');
- }
- 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.blankImage;
- 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.IDLE || this.state == ol.TileState.ERROR) {
- 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;
- };
-
-
- /**
- * A blank image.
- * @type {HTMLCanvasElement}
- */
- ol.ImageTile.blankImage = (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.render.canvas.Instruction');
-
- /**
- * @enum {number}
- */
- ol.render.canvas.Instruction = {
- BEGIN_GEOMETRY: 0,
- BEGIN_PATH: 1,
- CIRCLE: 2,
- CLOSE_PATH: 3,
- CUSTOM: 4,
- DRAW_IMAGE: 5,
- DRAW_TEXT: 6,
- END_GEOMETRY: 7,
- FILL: 8,
- MOVE_TO_LINE_TO: 9,
- SET_FILL_STYLE: 10,
- SET_STROKE_STYLE: 11,
- SET_TEXT_STYLE: 12,
- STROKE: 13
- };
-
- goog.provide('ol.render.canvas.Replay');
-
- goog.require('ol');
- goog.require('ol.array');
- 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.transform');
- goog.require('ol.has');
- goog.require('ol.obj');
- goog.require('ol.render.VectorContext');
- goog.require('ol.render.canvas.Instruction');
- goog.require('ol.transform');
-
-
- /**
- * @constructor
- * @extends {ol.render.VectorContext}
- * @param {number} tolerance Tolerance.
- * @param {ol.Extent} maxExtent Maximum extent.
- * @param {number} resolution Resolution.
- * @param {boolean} overlaps The replay can have overlapping geometries.
- * @struct
- */
- ol.render.canvas.Replay = function(tolerance, maxExtent, resolution, overlaps) {
- ol.render.VectorContext.call(this);
-
- /**
- * @protected
- * @type {number}
- */
- this.tolerance = tolerance;
-
- /**
- * @protected
- * @const
- * @type {ol.Extent}
- */
- this.maxExtent = maxExtent;
-
- /**
- * @protected
- * @type {boolean}
- */
- this.overlaps = overlaps;
-
- /**
- * @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;
-
- /**
- * @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;
-
- /**
- * @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 {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.
- * @param {number} rotation Rotation.
- */
- ol.render.canvas.Replay.prototype.fill_ = function(context, rotation) {
- if (this.fillOrigin_) {
- var origin = ol.transform.apply(this.renderedTransform_, this.fillOrigin_.slice());
- context.translate(origin[0], origin[1]);
- context.rotate(rotation);
- }
- context.fill();
- if (this.fillOrigin_) {
- context.setTransform.apply(context, this.resetTransform_);
- }
- };
-
-
- /**
- * @private
- * @param {CanvasRenderingContext2D} context Context.
- * @param {number} pixelRatio Pixel ratio.
- * @param {ol.Transform} transform Transform.
- * @param {number} viewRotation View rotation.
- * @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, pixelRatio, transform, viewRotation, 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 localTransform = this.tmpLocalTransform_;
- var resetTransform = this.resetTransform_;
- var prevX, prevY, roundX, roundY;
- var pendingFill = 0;
- var pendingStroke = 0;
- var coordinateCache = this.coordinateCache_;
-
- var state = /** @type {olx.render.State} */ ({
- context: context,
- pixelRatio: 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, fill, stroke, text, 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, viewRotation);
- 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]);
- var image = /** @type {HTMLCanvasElement|HTMLVideoElement|Image} */
- (instruction[3]);
- // Remaining arguments in DRAW_IMAGE are in alphabetical order
- var anchorX = /** @type {number} */ (instruction[4]) * pixelRatio;
- var anchorY = /** @type {number} */ (instruction[5]) * pixelRatio;
- var height = /** @type {number} */ (instruction[6]);
- var opacity = /** @type {number} */ (instruction[7]);
- var originX = /** @type {number} */ (instruction[8]);
- var originY = /** @type {number} */ (instruction[9]);
- var rotateWithView = /** @type {boolean} */ (instruction[10]);
- var rotation = /** @type {number} */ (instruction[11]);
- var scale = /** @type {number} */ (instruction[12]);
- var snapToPixel = /** @type {boolean} */ (instruction[13]);
- var width = /** @type {number} */ (instruction[14]);
- if (rotateWithView) {
- rotation += viewRotation;
- }
- for (; d < dd; d += 2) {
- x = pixelCoordinates[d] - anchorX;
- y = pixelCoordinates[d + 1] - anchorY;
- if (snapToPixel) {
- x = Math.round(x);
- y = Math.round(y);
- }
- if (scale != 1 || rotation !== 0) {
- var centerX = x + anchorX;
- var centerY = y + anchorY;
- ol.transform.compose(localTransform,
- centerX, centerY, scale, scale, rotation, -centerX, -centerY);
- context.setTransform.apply(context, localTransform);
- }
- var alpha = context.globalAlpha;
- if (opacity != 1) {
- context.globalAlpha = alpha * opacity;
- }
-
- var w = (width + originX > image.width) ? image.width - originX : width;
- var h = (height + originY > image.height) ? image.height - originY : height;
-
- context.drawImage(image, originX, originY, w, h,
- x, y, w * pixelRatio, h * pixelRatio);
-
- if (opacity != 1) {
- context.globalAlpha = alpha;
- }
- if (scale != 1 || rotation !== 0) {
- context.setTransform.apply(context, resetTransform);
- }
- }
- ++i;
- break;
- case ol.render.canvas.Instruction.DRAW_TEXT:
- d = /** @type {number} */ (instruction[1]);
- dd = /** @type {number} */ (instruction[2]);
- text = /** @type {string} */ (instruction[3]);
- var offsetX = /** @type {number} */ (instruction[4]) * pixelRatio;
- var offsetY = /** @type {number} */ (instruction[5]) * pixelRatio;
- rotation = /** @type {number} */ (instruction[6]);
- scale = /** @type {number} */ (instruction[7]) * pixelRatio;
- fill = /** @type {boolean} */ (instruction[8]);
- stroke = /** @type {boolean} */ (instruction[9]);
- rotateWithView = /** @type {boolean} */ (instruction[10]);
- if (rotateWithView) {
- rotation += viewRotation;
- }
- for (; d < dd; d += 2) {
- x = pixelCoordinates[d] + offsetX;
- y = pixelCoordinates[d + 1] + offsetY;
- if (scale != 1 || rotation !== 0) {
- ol.transform.compose(localTransform, x, y, scale, scale, rotation, -x, -y);
- context.setTransform.apply(context, localTransform);
- }
-
- // Support multiple lines separated by \n
- var lines = text.split('\n');
- var numLines = lines.length;
- var fontSize, lineY;
- if (numLines > 1) {
- // Estimate line height using width of capital M, and add padding
- fontSize = Math.round(context.measureText('M').width * 1.5);
- lineY = y - (((numLines - 1) / 2) * fontSize);
- } else {
- // No need to calculate line height/offset for a single line
- fontSize = 0;
- lineY = y;
- }
-
- for (var lineIndex = 0; lineIndex < numLines; lineIndex++) {
- var line = lines[lineIndex];
- if (stroke) {
- context.strokeText(line, x, lineY);
- }
- if (fill) {
- context.fillText(line, x, lineY);
- }
-
- // Move next line down by fontSize px
- lineY = lineY + fontSize;
- }
-
- if (scale != 1 || rotation !== 0) {
- context.setTransform.apply(context, resetTransform);
- }
- }
- ++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, viewRotation);
- }
- ++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:
- this.fillOrigin_ = instruction[2];
-
- if (pendingFill) {
- this.fill_(context, viewRotation);
- 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:
- var usePixelRatio = instruction[8] !== undefined ?
- instruction[8] : true;
- var renderedPixelRatio = instruction[9];
-
- var lineWidth = /** @type {number} */ (instruction[2]);
- if (pendingStroke) {
- context.stroke();
- pendingStroke = 0;
- }
- context.strokeStyle = /** @type {ol.ColorLike} */ (instruction[1]);
- context.lineWidth = usePixelRatio ? lineWidth * pixelRatio : lineWidth;
- context.lineCap = /** @type {string} */ (instruction[3]);
- context.lineJoin = /** @type {string} */ (instruction[4]);
- context.miterLimit = /** @type {number} */ (instruction[5]);
- if (ol.has.CANVAS_LINE_DASH) {
- var lineDash = /** @type {Array.<number>} */ (instruction[6]);
- var lineDashOffset = /** @type {number} */ (instruction[7]);
- if (usePixelRatio && pixelRatio !== renderedPixelRatio) {
- lineDash = lineDash.map(function(dash) {
- return dash * pixelRatio / renderedPixelRatio;
- });
- lineDashOffset *= pixelRatio / renderedPixelRatio;
- instruction[6] = lineDash;
- instruction[7] = lineDashOffset;
- instruction[9] = pixelRatio;
- }
- context.lineDashOffset = lineDashOffset;
- context.setLineDash(lineDash);
- }
- ++i;
- break;
- case ol.render.canvas.Instruction.SET_TEXT_STYLE:
- context.font = /** @type {string} */ (instruction[1]);
- context.textAlign = /** @type {string} */ (instruction[2]);
- context.textBaseline = /** @type {string} */ (instruction[3]);
- ++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, viewRotation);
- }
- if (pendingStroke) {
- context.stroke();
- }
- return undefined;
- };
-
-
- /**
- * @param {CanvasRenderingContext2D} context Context.
- * @param {number} pixelRatio Pixel ratio.
- * @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, pixelRatio, transform, viewRotation, skippedFeaturesHash) {
- var instructions = this.instructions;
- this.replay_(context, pixelRatio, transform, viewRotation,
- skippedFeaturesHash, 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) {
- var instructions = this.hitDetectionInstructions;
- return this.replay_(context, 1, transform, viewRotation,
- skippedFeaturesHash, instructions, 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;
- }
- }
- };
-
-
- /**
- * @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() {
- return this.maxExtent;
- };
-
- 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 {boolean} overlaps The replay can have overlapping geometries.
- * @struct
- */
- ol.render.canvas.ImageReplay = function(tolerance, maxExtent, resolution, overlaps) {
- ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, overlaps);
-
- /**
- * @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.height_, this.opacity_,
- this.originX_, this.originY_, this.rotateWithView_, this.rotation_,
- this.scale_, 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.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.height_, this.opacity_,
- this.originX_, this.originY_, this.rotateWithView_, this.rotation_,
- this.scale_, 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.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) {
- 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.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.array');
- goog.require('ol.colorlike');
- goog.require('ol.extent');
- 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 {boolean} overlaps The replay can have overlapping geometries.
- * @struct
- */
- ol.render.canvas.LineStringReplay = function(tolerance, maxExtent, resolution, overlaps) {
-
- ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, overlaps);
-
- /**
- * @private
- * @type {ol.Extent}
- */
- this.bufferedMaxExtent_ = null;
-
- /**
- * @private
- * @type {{currentStrokeStyle: (ol.ColorLike|undefined),
- * currentLineCap: (string|undefined),
- * currentLineDash: Array.<number>,
- * currentLineDashOffset: (number|undefined),
- * currentLineJoin: (string|undefined),
- * currentLineWidth: (number|undefined),
- * currentMiterLimit: (number|undefined),
- * lastStroke: (number|undefined),
- * strokeStyle: (ol.ColorLike|undefined),
- * lineCap: (string|undefined),
- * lineDash: Array.<number>,
- * lineDashOffset: (number|undefined),
- * lineJoin: (string|undefined),
- * lineWidth: (number|undefined),
- * miterLimit: (number|undefined)}|null}
- */
- this.state_ = {
- currentStrokeStyle: undefined,
- currentLineCap: undefined,
- currentLineDash: null,
- currentLineDashOffset: undefined,
- currentLineJoin: undefined,
- currentLineWidth: undefined,
- currentMiterLimit: undefined,
- lastStroke: undefined,
- strokeStyle: undefined,
- lineCap: undefined,
- lineDash: null,
- lineDashOffset: undefined,
- lineJoin: undefined,
- lineWidth: undefined,
- miterLimit: undefined
- };
-
- };
- 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.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_;
- };
-
-
- /**
- * @private
- */
- ol.render.canvas.LineStringReplay.prototype.setStrokeStyle_ = function() {
- var state = this.state_;
- 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 ||
- !ol.array.equals(state.currentLineDash, lineDash) ||
- state.currentLineDashOffset != lineDashOffset ||
- state.currentLineJoin != lineJoin ||
- state.currentLineWidth != lineWidth ||
- state.currentMiterLimit != miterLimit) {
- 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;
- this.instructions.push([
- ol.render.canvas.Instruction.SET_STROKE_STYLE,
- strokeStyle, lineWidth, lineCap, lineJoin, miterLimit, lineDash, lineDashOffset, true, 1
- ], [
- ol.render.canvas.Instruction.BEGIN_PATH
- ]);
- state.currentStrokeStyle = strokeStyle;
- state.currentLineCap = lineCap;
- state.currentLineDash = lineDash;
- state.currentLineDashOffset = lineDashOffset;
- state.currentLineJoin = lineJoin;
- state.currentLineWidth = lineWidth;
- state.currentMiterLimit = miterLimit;
- }
- };
-
-
- /**
- * @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.setStrokeStyle_();
- 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, true, 1
- ], [
- 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.setStrokeStyle_();
- 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, true, 1
- ], [
- 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.setFillStrokeStyle = function(fillStyle, strokeStyle) {
- var strokeStyleColor = strokeStyle.getColor();
- this.state_.strokeStyle = ol.colorlike.asColorLike(strokeStyleColor ?
- strokeStyleColor : ol.render.canvas.defaultStrokeStyle);
- var strokeStyleLineCap = strokeStyle.getLineCap();
- this.state_.lineCap = strokeStyleLineCap !== undefined ?
- strokeStyleLineCap : ol.render.canvas.defaultLineCap;
- var strokeStyleLineDash = strokeStyle.getLineDash();
- this.state_.lineDash = strokeStyleLineDash ?
- strokeStyleLineDash : ol.render.canvas.defaultLineDash;
- var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();
- this.state_.lineDashOffset = strokeStyleLineDashOffset ?
- strokeStyleLineDashOffset : ol.render.canvas.defaultLineDashOffset;
- var strokeStyleLineJoin = strokeStyle.getLineJoin();
- this.state_.lineJoin = strokeStyleLineJoin !== undefined ?
- strokeStyleLineJoin : ol.render.canvas.defaultLineJoin;
- var strokeStyleWidth = strokeStyle.getWidth();
- this.state_.lineWidth = strokeStyleWidth !== undefined ?
- strokeStyleWidth : ol.render.canvas.defaultLineWidth;
- var strokeStyleMiterLimit = strokeStyle.getMiterLimit();
- this.state_.miterLimit = strokeStyleMiterLimit !== undefined ?
- strokeStyleMiterLimit : ol.render.canvas.defaultMiterLimit;
-
- if (this.state_.lineWidth > this.maxLineWidth) {
- this.maxLineWidth = this.state_.lineWidth;
- // invalidate the buffered max extent cache
- this.bufferedMaxExtent_ = null;
- }
- };
-
- goog.provide('ol.render.canvas.PolygonReplay');
-
- goog.require('ol');
- goog.require('ol.array');
- goog.require('ol.color');
- goog.require('ol.colorlike');
- goog.require('ol.extent');
- 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 {boolean} overlaps The replay can have overlapping geometries.
- * @struct
- */
- ol.render.canvas.PolygonReplay = function(tolerance, maxExtent, resolution, overlaps) {
-
- ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, overlaps);
-
- /**
- * @private
- * @type {ol.Extent}
- */
- this.bufferedMaxExtent_ = null;
-
- /**
- * @private
- * @type {{currentFillStyle: (ol.ColorLike|undefined),
- * currentStrokeStyle: (ol.ColorLike|undefined),
- * currentLineCap: (string|undefined),
- * currentLineDash: Array.<number>,
- * currentLineDashOffset: (number|undefined),
- * currentLineJoin: (string|undefined),
- * currentLineWidth: (number|undefined),
- * currentMiterLimit: (number|undefined),
- * fillStyle: (ol.ColorLike|undefined),
- * strokeStyle: (ol.ColorLike|undefined),
- * lineCap: (string|undefined),
- * lineDash: Array.<number>,
- * lineDashOffset: (number|undefined),
- * lineJoin: (string|undefined),
- * lineWidth: (number|undefined),
- * miterLimit: (number|undefined)}|null}
- */
- this.state_ = {
- currentFillStyle: undefined,
- currentStrokeStyle: undefined,
- currentLineCap: undefined,
- currentLineDash: null,
- currentLineDashOffset: undefined,
- currentLineJoin: undefined,
- currentLineWidth: undefined,
- currentMiterLimit: undefined,
- fillStyle: undefined,
- strokeStyle: undefined,
- lineCap: undefined,
- lineDash: null,
- lineDashOffset: undefined,
- lineJoin: undefined,
- lineWidth: undefined,
- miterLimit: undefined
- };
-
- };
- 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, true, 1
- ]);
- }
- 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, true, 1
- ]);
- }
- 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, true, 1
- ]);
- }
- 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);
- }
- }
- };
-
-
- /**
- * @inheritDoc
- */
- ol.render.canvas.PolygonReplay.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_;
- };
-
-
- /**
- * @inheritDoc
- */
- ol.render.canvas.PolygonReplay.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;
- }
- };
-
-
- /**
- * @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;
- 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 (fillStyle !== undefined && (typeof fillStyle !== 'string' || state.currentFillStyle != 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);
- state.currentFillStyle = state.fillStyle;
- }
- if (strokeStyle !== undefined) {
- if (state.currentStrokeStyle != strokeStyle ||
- state.currentLineCap != lineCap ||
- !ol.array.equals(state.currentLineDash, lineDash) ||
- state.currentLineDashOffset != lineDashOffset ||
- state.currentLineJoin != lineJoin ||
- state.currentLineWidth != lineWidth ||
- state.currentMiterLimit != miterLimit) {
- this.instructions.push([
- ol.render.canvas.Instruction.SET_STROKE_STYLE,
- strokeStyle, lineWidth, lineCap, lineJoin, miterLimit, lineDash, lineDashOffset, true, 1
- ]);
- state.currentStrokeStyle = strokeStyle;
- state.currentLineCap = lineCap;
- state.currentLineDash = lineDash;
- state.currentLineDashOffset = lineDashOffset;
- state.currentLineJoin = lineJoin;
- state.currentLineWidth = lineWidth;
- state.currentMiterLimit = miterLimit;
- }
- }
- };
-
- goog.provide('ol.render.canvas.TextReplay');
-
- goog.require('ol');
- goog.require('ol.colorlike');
- 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 {boolean} overlaps The replay can have overlapping geometries.
- * @struct
- */
- ol.render.canvas.TextReplay = function(tolerance, maxExtent, resolution, overlaps) {
-
- ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, overlaps);
-
- /**
- * @private
- * @type {?ol.CanvasFillState}
- */
- this.replayFillState_ = null;
-
- /**
- * @private
- * @type {?ol.CanvasStrokeState}
- */
- this.replayStrokeState_ = null;
-
- /**
- * @private
- * @type {?ol.CanvasTextState}
- */
- this.replayTextState_ = 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 {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;
-
- };
- ol.inherits(ol.render.canvas.TextReplay, ol.render.canvas.Replay);
-
-
- /**
- * @inheritDoc
- */
- ol.render.canvas.TextReplay.prototype.drawText = function(flatCoordinates, offset, end, stride, geometry, feature) {
- if (this.text_ === '' || !this.textState_ ||
- (!this.textFillState_ && !this.textStrokeState_)) {
- return;
- }
- if (this.textFillState_) {
- this.setReplayFillState_(this.textFillState_);
- }
- if (this.textStrokeState_) {
- this.setReplayStrokeState_(this.textStrokeState_);
- }
- this.setReplayTextState_(this.textState_);
- this.beginGeometry(geometry, feature);
- var myBegin = this.coordinates.length;
- var myEnd =
- this.appendFlatCoordinates(flatCoordinates, offset, end, stride, false, false);
- var fill = !!this.textFillState_;
- var stroke = !!this.textStrokeState_;
- var drawTextInstruction = [
- ol.render.canvas.Instruction.DRAW_TEXT, myBegin, myEnd, this.text_,
- this.textOffsetX_, this.textOffsetY_, this.textRotation_, this.textScale_,
- fill, stroke, this.textRotateWithView_];
- this.instructions.push(drawTextInstruction);
- this.hitDetectionInstructions.push(drawTextInstruction);
- this.endGeometry(geometry, feature);
- };
-
-
- /**
- * @param {ol.CanvasFillState} fillState Fill state.
- * @private
- */
- ol.render.canvas.TextReplay.prototype.setReplayFillState_ = function(fillState) {
- var replayFillState = this.replayFillState_;
- if (replayFillState &&
- replayFillState.fillStyle == fillState.fillStyle) {
- return;
- }
- var setFillStyleInstruction =
- [ol.render.canvas.Instruction.SET_FILL_STYLE, fillState.fillStyle];
- this.instructions.push(setFillStyleInstruction);
- this.hitDetectionInstructions.push(setFillStyleInstruction);
- if (!replayFillState) {
- this.replayFillState_ = {
- fillStyle: fillState.fillStyle
- };
- } else {
- replayFillState.fillStyle = fillState.fillStyle;
- }
- };
-
-
- /**
- * @param {ol.CanvasStrokeState} strokeState Stroke state.
- * @private
- */
- ol.render.canvas.TextReplay.prototype.setReplayStrokeState_ = function(strokeState) {
- var replayStrokeState = this.replayStrokeState_;
- if (replayStrokeState &&
- replayStrokeState.lineCap == strokeState.lineCap &&
- replayStrokeState.lineDash == strokeState.lineDash &&
- replayStrokeState.lineDashOffset == strokeState.lineDashOffset &&
- replayStrokeState.lineJoin == strokeState.lineJoin &&
- replayStrokeState.lineWidth == strokeState.lineWidth &&
- replayStrokeState.miterLimit == strokeState.miterLimit &&
- replayStrokeState.strokeStyle == strokeState.strokeStyle) {
- return;
- }
- var setStrokeStyleInstruction = [
- ol.render.canvas.Instruction.SET_STROKE_STYLE, strokeState.strokeStyle,
- strokeState.lineWidth, strokeState.lineCap, strokeState.lineJoin,
- strokeState.miterLimit, strokeState.lineDash, strokeState.lineDashOffset, false, 1
- ];
- this.instructions.push(setStrokeStyleInstruction);
- this.hitDetectionInstructions.push(setStrokeStyleInstruction);
- if (!replayStrokeState) {
- this.replayStrokeState_ = {
- lineCap: strokeState.lineCap,
- lineDash: strokeState.lineDash,
- lineDashOffset: strokeState.lineDashOffset,
- lineJoin: strokeState.lineJoin,
- lineWidth: strokeState.lineWidth,
- miterLimit: strokeState.miterLimit,
- strokeStyle: strokeState.strokeStyle
- };
- } else {
- replayStrokeState.lineCap = strokeState.lineCap;
- replayStrokeState.lineDash = strokeState.lineDash;
- replayStrokeState.lineDashOffset = strokeState.lineDashOffset;
- replayStrokeState.lineJoin = strokeState.lineJoin;
- replayStrokeState.lineWidth = strokeState.lineWidth;
- replayStrokeState.miterLimit = strokeState.miterLimit;
- replayStrokeState.strokeStyle = strokeState.strokeStyle;
- }
- };
-
-
- /**
- * @param {ol.CanvasTextState} textState Text state.
- * @private
- */
- ol.render.canvas.TextReplay.prototype.setReplayTextState_ = function(textState) {
- var replayTextState = this.replayTextState_;
- if (replayTextState &&
- replayTextState.font == textState.font &&
- replayTextState.textAlign == textState.textAlign &&
- replayTextState.textBaseline == textState.textBaseline) {
- return;
- }
- var setTextStyleInstruction = [ol.render.canvas.Instruction.SET_TEXT_STYLE,
- textState.font, textState.textAlign, textState.textBaseline];
- this.instructions.push(setTextStyleInstruction);
- this.hitDetectionInstructions.push(setTextStyleInstruction);
- if (!replayTextState) {
- this.replayTextState_ = {
- font: textState.font,
- textAlign: textState.textAlign,
- textBaseline: textState.textBaseline
- };
- } else {
- replayTextState.font = textState.font;
- replayTextState.textAlign = textState.textAlign;
- replayTextState.textBaseline = textState.textBaseline;
- }
- };
-
-
- /**
- * @inheritDoc
- */
- ol.render.canvas.TextReplay.prototype.setTextStyle = function(textStyle) {
- if (!textStyle) {
- this.text_ = '';
- } else {
- var textFillStyle = textStyle.getFill();
- if (!textFillStyle) {
- this.textFillState_ = null;
- } else {
- var textFillStyleColor = textFillStyle.getColor();
- var fillStyle = ol.colorlike.asColorLike(textFillStyleColor ?
- textFillStyleColor : ol.render.canvas.defaultFillStyle);
- if (!this.textFillState_) {
- this.textFillState_ = {
- fillStyle: fillStyle
- };
- } else {
- var textFillState = this.textFillState_;
- textFillState.fillStyle = fillStyle;
- }
- }
- 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();
- var lineCap = textStrokeStyleLineCap !== undefined ?
- textStrokeStyleLineCap : ol.render.canvas.defaultLineCap;
- var lineDash = textStrokeStyleLineDash ?
- textStrokeStyleLineDash.slice() : ol.render.canvas.defaultLineDash;
- var lineDashOffset = textStrokeStyleLineDashOffset !== undefined ?
- textStrokeStyleLineDashOffset : ol.render.canvas.defaultLineDashOffset;
- var lineJoin = textStrokeStyleLineJoin !== undefined ?
- textStrokeStyleLineJoin : ol.render.canvas.defaultLineJoin;
- var lineWidth = textStrokeStyleWidth !== undefined ?
- textStrokeStyleWidth : ol.render.canvas.defaultLineWidth;
- var miterLimit = textStrokeStyleMiterLimit !== undefined ?
- textStrokeStyleMiterLimit : ol.render.canvas.defaultMiterLimit;
- var strokeStyle = ol.colorlike.asColorLike(textStrokeStyleColor ?
- textStrokeStyleColor : ol.render.canvas.defaultStrokeStyle);
- if (!this.textStrokeState_) {
- this.textStrokeState_ = {
- lineCap: lineCap,
- lineDash: lineDash,
- lineDashOffset: lineDashOffset,
- lineJoin: lineJoin,
- lineWidth: lineWidth,
- miterLimit: miterLimit,
- strokeStyle: strokeStyle
- };
- } else {
- var textStrokeState = this.textStrokeState_;
- textStrokeState.lineCap = lineCap;
- textStrokeState.lineDash = lineDash;
- textStrokeState.lineDashOffset = lineDashOffset;
- textStrokeState.lineJoin = lineJoin;
- textStrokeState.lineWidth = lineWidth;
- textStrokeState.miterLimit = miterLimit;
- textStrokeState.strokeStyle = strokeStyle;
- }
- }
- 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();
- var font = textFont !== undefined ?
- textFont : ol.render.canvas.defaultFont;
- var textAlign = textTextAlign !== undefined ?
- textTextAlign : ol.render.canvas.defaultTextAlign;
- var textBaseline = textTextBaseline !== undefined ?
- textTextBaseline : ol.render.canvas.defaultTextBaseline;
- if (!this.textState_) {
- this.textState_ = {
- font: font,
- textAlign: textAlign,
- textBaseline: textBaseline
- };
- } else {
- var textState = this.textState_;
- textState.font = font;
- textState.textAlign = textAlign;
- textState.textBaseline = textBaseline;
- }
- this.text_ = textText !== undefined ? textText : '';
- this.textOffsetX_ = textOffsetX !== undefined ? textOffsetX : 0;
- this.textOffsetY_ = textOffsetY !== undefined ? textOffsetY : 0;
- this.textRotateWithView_ = textRotateWithView !== undefined ? textRotateWithView : false;
- this.textRotation_ = textRotation !== undefined ? textRotation : 0;
- this.textScale_ = textScale !== undefined ? textScale : 1;
- }
- };
-
- 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.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 {boolean} overlaps The replay group can have overlapping geometries.
- * @param {number=} opt_renderBuffer Optional rendering buffer.
- * @struct
- */
- ol.render.canvas.ReplayGroup = function(
- tolerance, maxExtent, resolution, overlaps, opt_renderBuffer) {
- ol.render.ReplayGroup.call(this);
-
- /**
- * @private
- * @type {number}
- */
- this.tolerance_ = tolerance;
-
- /**
- * @private
- * @type {ol.Extent}
- */
- this.maxExtent_ = maxExtent;
-
- /**
- * @private
- * @type {boolean}
- */
- this.overlaps_ = overlaps;
-
- /**
- * @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 {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.
- * @return {T|undefined} Callback result.
- * @template T
- */
- ol.render.canvas.ReplayGroup.prototype.forEachFeatureAtCoordinate = function(
- coordinate, resolution, rotation, hitTolerance, skippedFeaturesHash, callback) {
-
- 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);
-
- return this.replayHitDetection_(context, transform, rotation,
- skippedFeaturesHash,
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @return {?} Callback result.
- */
- function(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 = callback(feature);
- if (result) {
- return result;
- } else {
- context.clearRect(0, 0, contextSize, contextSize);
- return undefined;
- }
- }
- }
- }
- }
- }, hitExtent);
- };
-
-
- /**
- * @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.overlaps_);
- replays[replayType] = replay;
- }
- return replay;
- };
-
-
- /**
- * @inheritDoc
- */
- ol.render.canvas.ReplayGroup.prototype.isEmpty = function() {
- return ol.obj.isEmpty(this.replaysByZIndex_);
- };
-
-
- /**
- * @param {CanvasRenderingContext2D} context Context.
- * @param {number} pixelRatio Pixel ratio.
- * @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}
- */
- ol.render.canvas.ReplayGroup.prototype.replay = function(context, pixelRatio,
- transform, viewRotation, skippedFeaturesHash, opt_replayTypes) {
-
- /** @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
- var flatClipCoords = this.getClipCoords(transform);
- context.save();
- 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();
-
- 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) {
- replays = this.replaysByZIndex_[zs[i].toString()];
- for (j = 0, jj = replayTypes.length; j < jj; ++j) {
- replay = replays[replayTypes[j]];
- if (replay !== undefined) {
- replay.replay(context, pixelRatio, transform, viewRotation,
- skippedFeaturesHash);
- }
- }
- }
-
- context.restore();
- };
-
-
- /**
- * @private
- * @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} 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.ReplayGroup.prototype.replayHitDetection_ = function(
- context, transform, viewRotation, skippedFeaturesHash,
- featureCallback, 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.replayHitDetection(context, transform, viewRotation,
- skippedFeaturesHash, featureCallback, opt_hitExtent);
- if (result) {
- return result;
- }
- }
- }
- }
- return undefined;
- };
-
-
- /**
- * @const
- * @private
- * @type {Object.<ol.render.ReplayType,
- * function(new: ol.render.canvas.Replay, number, ol.Extent,
- * number, boolean)>}
- */
- 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.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.Map} 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 {Object.<string, ol.Attribution>} attributionsSet Attributions
- * set (target).
- * @param {Array.<ol.Attribution>} attributions Attributions (source).
- * @protected
- */
- ol.renderer.Layer.prototype.updateAttributions = function(attributionsSet, attributions) {
- if (attributions) {
- var attribution, i, ii;
- for (i = 0, ii = attributions.length; i < ii; ++i) {
- attribution = attributions[i];
- attributionsSet[ol.getUid(attribution).toString()] = attribution;
- }
- }
- };
-
-
- /**
- * @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 = currentZ; z >= minZoom; --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.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);
- textReplay.drawText(geometry.getCenter(), 0, 2, 2, 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);
- textReplay.drawText(geometry.getFlatMidpoint(), 0, 2, 2, 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);
- var flatMidpointCoordinates = geometry.getFlatMidpoints();
- textReplay.drawText(flatMidpointCoordinates, 0,
- flatMidpointCoordinates.length, 2, 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);
- var flatInteriorPointCoordinates = geometry.getFlatInteriorPoints();
- textReplay.drawText(flatInteriorPointCoordinates, 0,
- flatInteriorPointCoordinates.length, 2, 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);
- imageReplay.drawPoint(geometry, feature);
- }
- var textStyle = style.getText();
- if (textStyle) {
- var textReplay = replayGroup.getReplay(
- style.getZIndex(), ol.render.ReplayType.TEXT);
- textReplay.setTextStyle(textStyle);
- textReplay.drawText(geometry.getFlatCoordinates(), 0, 2, 2, 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);
- imageReplay.drawMultiPoint(geometry, feature);
- }
- var textStyle = style.getText();
- if (textStyle) {
- var textReplay = replayGroup.getReplay(
- style.getZIndex(), ol.render.ReplayType.TEXT);
- textReplay.setTextStyle(textStyle);
- var flatCoordinates = geometry.getFlatCoordinates();
- textReplay.drawText(flatCoordinates, 0, flatCoordinates.length,
- geometry.getStride(), 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);
- textReplay.drawText(
- geometry.getFlatInteriorPoint(), 0, 2, 2, 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.ViewHint');
- goog.require('ol.dom');
- goog.require('ol.extent');
- goog.require('ol.render.EventType');
- goog.require('ol.render.canvas');
- goog.require('ol.render.canvas.ReplayGroup');
- goog.require('ol.renderer.canvas.Layer');
- goog.require('ol.renderer.vector');
-
-
- /**
- * @constructor
- * @extends {ol.renderer.canvas.Layer}
- * @param {ol.layer.Vector} vectorLayer Vector layer.
- */
- ol.renderer.canvas.VectorLayer = function(vectorLayer) {
-
- ol.renderer.canvas.Layer.call(this, 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.canvas.ReplayGroup}
- */
- this.replayGroup_ = null;
-
- /**
- * @private
- * @type {CanvasRenderingContext2D}
- */
- this.context_ = ol.dom.createCanvasContext2D();
-
- };
- ol.inherits(ol.renderer.canvas.VectorLayer, ol.renderer.canvas.Layer);
-
-
- /**
- * @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()) {
- var layer = 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, pixelRatio, 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, pixelRatio, 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, pixelRatio, 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 = this.getLayer();
- /** @type {Object.<string, boolean>} */
- var features = {};
- return 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);
- }
- });
- }
- };
-
-
- /**
- * 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.updateAttributions(
- frameState.attributions, vectorSource.getAttributions());
- 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)) {
- return true;
- }
-
- this.replayGroup_ = null;
-
- this.dirty_ = false;
-
- var replayGroup = new ol.render.canvas.ReplayGroup(
- ol.renderer.vector.getTolerance(resolution, pixelRatio), extent,
- resolution, vectorSource.getOverlaps(), 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;
-
- 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) || loading;
- }
- return loading;
- };
-
- // This file is automatically generated, do not edit
- /* eslint openlayers-internal/no-missing-requires: 0 */
- goog.provide('ol.renderer.webgl.defaultmapshader');
-
- goog.require('ol');
- goog.require('ol.webgl.Fragment');
- goog.require('ol.webgl.Vertex');
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @constructor
- * @extends {ol.webgl.Fragment}
- * @struct
- */
- ol.renderer.webgl.defaultmapshader.Fragment = function() {
- ol.webgl.Fragment.call(this, ol.renderer.webgl.defaultmapshader.Fragment.SOURCE);
- };
- ol.inherits(ol.renderer.webgl.defaultmapshader.Fragment, ol.webgl.Fragment);
-
-
- /**
- * @const
- * @type {string}
- */
- ol.renderer.webgl.defaultmapshader.Fragment.DEBUG_SOURCE = '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';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.renderer.webgl.defaultmapshader.Fragment.OPTIMIZED_SOURCE = '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;}';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.renderer.webgl.defaultmapshader.Fragment.SOURCE = ol.DEBUG_WEBGL ?
- ol.renderer.webgl.defaultmapshader.Fragment.DEBUG_SOURCE :
- ol.renderer.webgl.defaultmapshader.Fragment.OPTIMIZED_SOURCE;
-
-
- ol.renderer.webgl.defaultmapshader.fragment = new ol.renderer.webgl.defaultmapshader.Fragment();
-
-
- /**
- * @constructor
- * @extends {ol.webgl.Vertex}
- * @struct
- */
- ol.renderer.webgl.defaultmapshader.Vertex = function() {
- ol.webgl.Vertex.call(this, ol.renderer.webgl.defaultmapshader.Vertex.SOURCE);
- };
- ol.inherits(ol.renderer.webgl.defaultmapshader.Vertex, ol.webgl.Vertex);
-
-
- /**
- * @const
- * @type {string}
- */
- ol.renderer.webgl.defaultmapshader.Vertex.DEBUG_SOURCE = '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';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.renderer.webgl.defaultmapshader.Vertex.OPTIMIZED_SOURCE = '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;}';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.renderer.webgl.defaultmapshader.Vertex.SOURCE = ol.DEBUG_WEBGL ?
- ol.renderer.webgl.defaultmapshader.Vertex.DEBUG_SOURCE :
- ol.renderer.webgl.defaultmapshader.Vertex.OPTIMIZED_SOURCE;
-
-
- ol.renderer.webgl.defaultmapshader.vertex = new ol.renderer.webgl.defaultmapshader.Vertex();
-
-
- /**
- * @constructor
- * @param {WebGLRenderingContext} gl GL.
- * @param {WebGLProgram} program Program.
- * @struct
- */
- ol.renderer.webgl.defaultmapshader.Locations = function(gl, program) {
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_opacity = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_opacity' : 'f');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_projectionMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'e');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_texCoordMatrix = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_texCoordMatrix' : 'd');
-
- /**
- * @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.transform');
- goog.require('ol.vec.Mat4');
- goog.require('ol.webgl');
- goog.require('ol.webgl.Buffer');
- goog.require('ol.webgl.Context');
-
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @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_) {
- // eslint-disable-next-line openlayers-internal/no-missing-requires
- 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.VectorLayer');
-
- goog.require('ol');
- goog.require('ol.ViewHint');
- goog.require('ol.extent');
- goog.require('ol.render.webgl.ReplayGroup');
- goog.require('ol.renderer.vector');
- goog.require('ol.renderer.webgl.Layer');
- goog.require('ol.transform');
-
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @constructor
- * @extends {ol.renderer.webgl.Layer}
- * @param {ol.renderer.webgl.Map} mapRenderer Map renderer.
- * @param {ol.layer.Vector} vectorLayer Vector layer.
- */
- 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);
-
-
- /**
- * @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.updateAttributions(
- frameState.attributions, vectorSource.getAttributions());
- 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.layer.Vector');
-
- goog.require('ol');
- goog.require('ol.layer.Layer');
- goog.require('ol.obj');
- goog.require('ol.renderer.Type');
- goog.require('ol.renderer.canvas.VectorLayer');
- goog.require('ol.renderer.webgl.VectorLayer');
- 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));
-
- /**
- * @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;
- };
- ol.inherits(ol.layer.Vector, ol.layer.Layer);
-
-
- /**
- * @inheritDoc
- */
- ol.layer.Vector.prototype.createRenderer = function(mapRenderer) {
- var renderer = null;
- var type = mapRenderer.getType();
- if (ol.ENABLE_CANVAS && type === ol.renderer.Type.CANVAS) {
- renderer = new ol.renderer.canvas.VectorLayer(this);
- } else if (ol.ENABLE_WEBGL && type === ol.renderer.Type.WEBGL) {
- renderer = new ol.renderer.webgl.VectorLayer(/** @type {ol.renderer.webgl.Map} */ (mapRenderer), this);
- }
- return renderer;
- };
-
-
- /**
- * @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();
- };
-
-
- /**
- * @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_ = ol.source.Source.toAttributionsArray_(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 various ways of defining an attribution to an array of `ol.Attributions`.
- *
- * @param {ol.AttributionLike|undefined}
- * attributionLike The attributions as string, array of strings,
- * `ol.Attribution`, array of `ol.Attribution` or undefined.
- * @return {Array.<ol.Attribution>} The array of `ol.Attribution` or null if
- * `undefined` was given.
- */
- ol.source.Source.toAttributionsArray_ = function(attributionLike) {
- if (typeof attributionLike === 'string') {
- return [new ol.Attribution({html: attributionLike})];
- } else if (attributionLike instanceof ol.Attribution) {
- return [attributionLike];
- } else if (Array.isArray(attributionLike)) {
- var len = attributionLike.length;
- var attributions = new Array(len);
- for (var i = 0; i < len; i++) {
- var item = attributionLike[i];
- if (typeof item === 'string') {
- attributions[i] = new ol.Attribution({html: item});
- } else {
- attributions[i] = item;
- }
- }
- return attributions;
- } else {
- return null;
- }
- };
-
-
- /**
- * @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 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.Attribution}`,
- * `Array<{@link ol.Attribution}>` or `undefined`.
- * @api
- */
- ol.source.Source.prototype.setAttributions = function(attributions) {
- this.attributions_ = ol.source.Source.toAttributionsArray_(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'
- };
-
- // 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 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;
- };
-
-
- /**
- * @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_ = options.type;
-
- /**
- * Drawing mode (derived from geometry type.
- * @type {ol.interaction.Draw.Mode_}
- * @private
- */
- this.mode_ = ol.interaction.Draw.getMode_(this.type_);
-
- /**
- * 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) {
- geometry.setCoordinates([coordinates[0].concat([coordinates[0][0]])]);
- } 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 = !this.freehand_;
- if (this.freehand_ &&
- event.type === ol.MapBrowserEventType.POINTERDRAG && this.sketchFeature_ !== null) {
- this.addToDrawing_(event);
- 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_();
- }
- 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) {
-
- /**
- * 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_ = 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.Map} 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.ViewHint');
- 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().getHints()[ol.ViewHint.INTERACTING] &&
- 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.Map} 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.Map} 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.Map} 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.Map} 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.Map} 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.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 ImageVector 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.ViewHint');
- goog.require('ol.extent');
- goog.require('ol.renderer.canvas.IntermediateCanvas');
- goog.require('ol.transform');
-
-
- /**
- * @constructor
- * @extends {ol.renderer.canvas.IntermediateCanvas}
- * @param {ol.layer.Image} imageLayer Single image layer.
- */
- 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();
-
- };
- ol.inherits(ol.renderer.canvas.ImageLayer, ol.renderer.canvas.IntermediateCanvas);
-
-
- /**
- * @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;
- }
- }
- 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.updateAttributions(frameState.attributions, image.getAttributions());
- this.updateLogos(frameState, imageSource);
- this.renderedResolution = viewResolution * pixelRatio / imagePixelRatio;
- }
-
- return !!this.image_;
- };
-
- 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;
- var attributions = [];
-
- if (this.sourceImage_) {
- state = ol.ImageState.IDLE;
- attributions = this.sourceImage_.getAttributions();
- }
-
- ol.ImageBase.call(this, targetExtent, targetResolution, this.sourcePixelRatio_,
- state, attributions);
- };
- 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(opt_context) {
- 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.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.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,
- this.getAttributions(), canvasElement);
- }
- this.canvas_ = canvas;
- this.renderedRevision_ = this.getRevision();
-
- return canvas;
- };
-
- goog.provide('ol.source.ImageVector');
-
- goog.require('ol');
- goog.require('ol.dom');
- goog.require('ol.events');
- goog.require('ol.events.EventType');
- 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');
-
-
- /**
- * @classdesc
- * 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];
-
- /**
- * @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, this.source_.getOverlaps(), 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]);
- }
-
- var transform = this.getTransform_(ol.extent.getCenter(extent),
- resolution, pixelRatio, size);
- replayGroup.replay(this.canvasContext_, pixelRatio, 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 = {};
- return 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);
- }
- });
- }
- };
-
-
- /**
- * 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.renderer.webgl.ImageLayer');
-
- goog.require('ol');
- goog.require('ol.ViewHint');
- goog.require('ol.dom');
- goog.require('ol.extent');
- goog.require('ol.functions');
- goog.require('ol.renderer.webgl.Layer');
- goog.require('ol.source.ImageVector');
- goog.require('ol.transform');
- goog.require('ol.webgl');
- goog.require('ol.webgl.Context');
-
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @constructor
- * @extends {ol.renderer.webgl.Layer}
- * @param {ol.renderer.webgl.Map} mapRenderer Map renderer.
- * @param {ol.layer.Image} imageLayer Tile layer.
- */
- 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);
-
-
- /**
- * @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.updateAttributions(frameState.attributions, image.getAttributions());
- 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() instanceof ol.source.ImageVector) {
- // for ImageVector 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;
- };
-
- }
-
- goog.provide('ol.layer.Image');
-
- goog.require('ol');
- goog.require('ol.layer.Layer');
- goog.require('ol.renderer.Type');
- goog.require('ol.renderer.canvas.ImageLayer');
- goog.require('ol.renderer.webgl.ImageLayer');
-
-
- /**
- * @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));
- };
- ol.inherits(ol.layer.Image, ol.layer.Layer);
-
-
- /**
- * @inheritDoc
- */
- ol.layer.Image.prototype.createRenderer = function(mapRenderer) {
- var renderer = null;
- var type = mapRenderer.getType();
- if (ol.ENABLE_CANVAS && type === ol.renderer.Type.CANVAS) {
- renderer = new ol.renderer.canvas.ImageLayer(this);
- } else if (ol.ENABLE_WEBGL && type === ol.renderer.Type.WEBGL) {
- renderer = new ol.renderer.webgl.ImageLayer(/** @type {ol.renderer.webgl.Map} */ (mapRenderer), this);
- }
- return renderer;
- };
-
-
- /**
- * 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'
- };
-
- // FIXME find correct globalCompositeOperation
-
- goog.provide('ol.renderer.canvas.TileLayer');
-
- goog.require('ol');
- goog.require('ol.TileRange');
- goog.require('ol.TileState');
- goog.require('ol.ViewHint');
- goog.require('ol.array');
- goog.require('ol.dom');
- goog.require('ol.extent');
- 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.
- */
- 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);
-
-
- /**
- * @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.getTileRangeForExtentAndResolution(
- extent, tileResolution);
- 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)) {
- if (tile.getState() == ol.TileState.LOADED) {
- tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;
- if (!newTiles && this.renderedTiles.indexOf(tile) == -1) {
- newTiles = true;
- }
- }
- continue;
- }
-
- var fullyLoaded = tileGrid.forEachTileCoordParentTileRange(
- tile.tileCoord, findLoadedTiles, null, tmpTileRange, tmpExtent);
- if (!fullyLoaded) {
- var childTileRange = tileGrid.getTileCoordChildTileRange(
- tile.tileCoord, tmpTileRange, tmpExtent);
- if (childTileRange) {
- findLoadedTiles(z + 1, childTileRange);
- }
- }
-
- }
- }
-
- 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 {
- 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(ol.array.numberSafeCompareFunction);
- 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);
- 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.
- */
- ol.renderer.canvas.TileLayer.prototype.drawTileImage = function(tile, frameState, layerState, x, y, w, h, gutter) {
- if (!this.getLayer().getSource().getOpaque(frameState.viewState.projection)) {
- this.context.clearRect(x, y, w, h);
- }
- var image = tile.getImage(this.getLayer());
- if (image) {
- this.context.drawImage(image, gutter, gutter,
- image.width - 2 * gutter, image.height - 2 * gutter, x, y, w, h);
- }
- };
-
-
- /**
- * @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_;
- };
-
- // This file is automatically generated, do not edit
- /* eslint openlayers-internal/no-missing-requires: 0 */
- goog.provide('ol.renderer.webgl.tilelayershader');
-
- goog.require('ol');
- goog.require('ol.webgl.Fragment');
- goog.require('ol.webgl.Vertex');
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @constructor
- * @extends {ol.webgl.Fragment}
- * @struct
- */
- ol.renderer.webgl.tilelayershader.Fragment = function() {
- ol.webgl.Fragment.call(this, ol.renderer.webgl.tilelayershader.Fragment.SOURCE);
- };
- ol.inherits(ol.renderer.webgl.tilelayershader.Fragment, ol.webgl.Fragment);
-
-
- /**
- * @const
- * @type {string}
- */
- ol.renderer.webgl.tilelayershader.Fragment.DEBUG_SOURCE = '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';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.renderer.webgl.tilelayershader.Fragment.OPTIMIZED_SOURCE = 'precision mediump float;varying vec2 a;uniform sampler2D e;void main(void){gl_FragColor=texture2D(e,a);}';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.renderer.webgl.tilelayershader.Fragment.SOURCE = ol.DEBUG_WEBGL ?
- ol.renderer.webgl.tilelayershader.Fragment.DEBUG_SOURCE :
- ol.renderer.webgl.tilelayershader.Fragment.OPTIMIZED_SOURCE;
-
-
- ol.renderer.webgl.tilelayershader.fragment = new ol.renderer.webgl.tilelayershader.Fragment();
-
-
- /**
- * @constructor
- * @extends {ol.webgl.Vertex}
- * @struct
- */
- ol.renderer.webgl.tilelayershader.Vertex = function() {
- ol.webgl.Vertex.call(this, ol.renderer.webgl.tilelayershader.Vertex.SOURCE);
- };
- ol.inherits(ol.renderer.webgl.tilelayershader.Vertex, ol.webgl.Vertex);
-
-
- /**
- * @const
- * @type {string}
- */
- ol.renderer.webgl.tilelayershader.Vertex.DEBUG_SOURCE = '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';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.renderer.webgl.tilelayershader.Vertex.OPTIMIZED_SOURCE = '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;}';
-
-
- /**
- * @const
- * @type {string}
- */
- ol.renderer.webgl.tilelayershader.Vertex.SOURCE = ol.DEBUG_WEBGL ?
- ol.renderer.webgl.tilelayershader.Vertex.DEBUG_SOURCE :
- ol.renderer.webgl.tilelayershader.Vertex.OPTIMIZED_SOURCE;
-
-
- ol.renderer.webgl.tilelayershader.vertex = new ol.renderer.webgl.tilelayershader.Vertex();
-
-
- /**
- * @constructor
- * @param {WebGLRenderingContext} gl GL.
- * @param {WebGLProgram} program Program.
- * @struct
- */
- ol.renderer.webgl.tilelayershader.Locations = function(gl, program) {
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_texture = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_texture' : 'e');
-
- /**
- * @type {WebGLUniformLocation}
- */
- this.u_tileOffset = gl.getUniformLocation(
- program, ol.DEBUG_WEBGL ? 'u_tileOffset' : 'd');
-
- /**
- * @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.TileState');
- goog.require('ol.TileRange');
- goog.require('ol.array');
- goog.require('ol.extent');
- goog.require('ol.math');
- goog.require('ol.renderer.webgl.Layer');
- goog.require('ol.renderer.webgl.tilelayershader');
- goog.require('ol.size');
- goog.require('ol.transform');
- goog.require('ol.webgl');
- goog.require('ol.webgl.Buffer');
-
-
- if (ol.ENABLE_WEBGL) {
-
- /**
- * @constructor
- * @extends {ol.renderer.webgl.Layer}
- * @param {ol.renderer.webgl.Map} mapRenderer Map renderer.
- * @param {ol.layer.Tile} tileLayer Tile layer.
- */
- 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);
-
-
- /**
- * @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.getTileRangeForExtentAndResolution(
- extent, tileResolution);
-
- 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_) {
- // eslint-disable-next-line openlayers-internal/no-missing-requires
- 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.layer.Tile');
-
- goog.require('ol');
- goog.require('ol.layer.Layer');
- goog.require('ol.layer.TileProperty');
- goog.require('ol.obj');
- goog.require('ol.renderer.Type');
- goog.require('ol.renderer.canvas.TileLayer');
- goog.require('ol.renderer.webgl.TileLayer');
-
-
- /**
- * @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);
- };
- ol.inherits(ol.layer.Tile, ol.layer.Layer);
-
-
- /**
- * @inheritDoc
- */
- ol.layer.Tile.prototype.createRenderer = function(mapRenderer) {
- var renderer = null;
- var type = mapRenderer.getType();
- if (ol.ENABLE_CANVAS && type === ol.renderer.Type.CANVAS) {
- renderer = new ol.renderer.canvas.TileLayer(this);
- } else if (ol.ENABLE_WEBGL && type === ol.renderer.Type.WEBGL) {
- renderer = new ol.renderer.webgl.TileLayer(/** @type {ol.renderer.webgl.Map} */ (mapRenderer), this);
- }
- return renderer;
- };
-
-
- /**
- * 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.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.TileState');
- goog.require('ol.dom');
- goog.require('ol.extent');
- goog.require('ol.proj');
- goog.require('ol.proj.Units');
- goog.require('ol.layer.VectorTileRenderType');
- 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.canvas.TileLayer');
- goog.require('ol.renderer.vector');
- goog.require('ol.size');
- goog.require('ol.transform');
-
-
- /**
- * @constructor
- * @extends {ol.renderer.canvas.TileLayer}
- * @param {ol.layer.VectorTile} layer VectorTile layer.
- */
- ol.renderer.canvas.VectorTileLayer = function(layer) {
-
- /**
- * @type {CanvasRenderingContext2D}
- */
- this.context = null;
-
- ol.renderer.canvas.TileLayer.call(this, layer);
-
- /**
- * @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.inherits(ol.renderer.canvas.VectorTileLayer, ol.renderer.canvas.TileLayer);
-
-
- /**
- * @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.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);
-
- for (var t = 0, tt = tile.tileKeys.length; t < tt; ++t) {
- var sourceTile = tile.getTile(tile.tileKeys[t]);
- replayState.dirty = false;
-
- var sourceTileCoord = sourceTile.tileCoord;
- var tileProjection = sourceTile.getProjection();
- var sourceTileResolution = sourceTileGrid.getResolution(sourceTile.tileCoord[0]);
- var sourceTileExtent = sourceTileGrid.getTileCoordExtent(sourceTileCoord);
- var sharedExtent = ol.extent.getIntersection(tileExtent, sourceTileExtent);
- var extent, reproject, tileResolution;
- if (tileProjection.getUnits() == ol.proj.Units.TILE_PIXELS) {
- var tilePixelRatio = tileResolution = this.getTilePixelRatio_(source, sourceTile);
- var transform = ol.transform.compose(this.tmpTransform_,
- 0, 0,
- 1 / sourceTileResolution * tilePixelRatio, -1 / sourceTileResolution * tilePixelRatio,
- 0,
- -sourceTileExtent[0], -sourceTileExtent[3]);
- extent = (ol.transform.apply(transform, [sharedExtent[0], sharedExtent[3]])
- .concat(ol.transform.apply(transform, [sharedExtent[2], sharedExtent[1]])));
- } else {
- tileResolution = resolution;
- extent = sharedExtent;
- if (!ol.proj.equivalent(projection, tileProjection)) {
- reproject = true;
- sourceTile.setProjection(projection);
- }
- }
- replayState.dirty = false;
- var replayGroup = new ol.render.canvas.ReplayGroup(0, extent,
- tileResolution, source.getOverlaps(), layer.getRenderBuffer());
- var squaredTolerance = ol.renderer.vector.getSquaredTolerance(
- tileResolution, 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) {
- if (!Array.isArray(styles)) {
- styles = [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) {
- feature.getGeometry().transform(tileProjection, projection);
- }
- renderFeature.call(this, feature);
- }
- replayGroup.finish();
- 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) {
- 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 sourceTileGrid = source.getTileGrid();
- var bufferedExtent, found, tileSpaceCoordinate;
- var i, ii, origin, replayGroup;
- var tile, tileCoord, tileExtent, tilePixelRatio, tileRenderResolution;
- for (i = 0, ii = renderedTiles.length; i < ii; ++i) {
- tile = renderedTiles[i];
- tileCoord = tile.tileCoord;
- 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.getProjection().getUnits() === ol.proj.Units.TILE_PIXELS) {
- var sourceTileCoord = sourceTile.tileCoord;
- var sourceTileExtent = sourceTileGrid.getTileCoordExtent(sourceTileCoord, this.tmpExtent);
- origin = ol.extent.getTopLeft(sourceTileExtent);
- tilePixelRatio = this.getTilePixelRatio_(source, sourceTile);
- var sourceTileResolution = sourceTileGrid.getResolution(sourceTileCoord[0]);
- tileRenderResolution = sourceTileResolution / tilePixelRatio;
- tileSpaceCoordinate = [
- (coordinate[0] - origin[0]) / tileRenderResolution,
- (origin[1] - coordinate[1]) / tileRenderResolution
- ];
- var upscaling = tileGrid.getResolution(tileCoord[0]) / sourceTileResolution;
- resolution = tilePixelRatio * upscaling;
- } else {
- tileSpaceCoordinate = coordinate;
- }
- replayGroup = sourceTile.getReplayGroup(layer, tile.tileCoord.toString());
- found = found || replayGroup.forEachFeatureAtCoordinate(
- tileSpaceCoordinate, 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);
- }
- });
- }
- }
- 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) {
- if (tile.getProjection().getUnits() == ol.proj.Units.TILE_PIXELS) {
- 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]) / this.getTilePixelRatio_(source, tile);
- 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);
- } else {
- return this.getTransform(frameState, 0);
- }
- };
-
-
- /**
- * @private
- * @param {ol.source.VectorTile} source Source.
- * @param {ol.VectorTile} tile Tile.
- * @return {number} The tile's pixel ratio.
- */
- ol.renderer.canvas.VectorTileLayer.prototype.getTilePixelRatio_ = function(source, tile) {
- return ol.extent.getWidth(tile.getExtent()) /
- ol.size.toSize(source.getTileGrid().getTileSize(tile.tileCoord[0]))[0];
- };
-
-
- /**
- * 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 source = /** @type {ol.source.VectorTile} */ (layer.getSource());
- var renderMode = layer.getRenderMode();
- var replays = ol.renderer.canvas.VectorTileLayer.VECTOR_REPLAYS[renderMode];
- var pixelRatio = frameState.pixelRatio;
- var rotation = frameState.viewState.rotation;
- var size = frameState.size;
- var offsetX = Math.round(pixelRatio * size[0] / 2);
- var offsetY = Math.round(pixelRatio * size[1] / 2);
- var tiles = this.renderedTiles;
- var sourceTileGrid = source.getTileGrid();
- 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];
- for (var t = 0, tt = tile.tileKeys.length; t < tt; ++t) {
- var sourceTile = tile.getTile(tile.tileKeys[t]);
- var tilePixelRatio = this.getTilePixelRatio_(source, sourceTile);
- var replayGroup = sourceTile.getReplayGroup(layer, tileCoord.toString());
- if (renderMode != ol.layer.VectorTileRenderType.VECTOR && !replayGroup.hasReplays(replays)) {
- continue;
- }
- var currentZ = sourceTile.tileCoord[0];
- var sourceResolution = sourceTileGrid.getResolution(currentZ);
- var transform = this.getReplayTransform_(sourceTile, frameState);
- ol.transform.translate(transform, worldOffset * tilePixelRatio / sourceResolution, 0);
- var currentClip = replayGroup.getClipCoords(transform);
- context.save();
- context.globalAlpha = layerState.opacity;
- ol.render.canvas.rotateAtOffset(context, -rotation, offsetX, offsetY);
- // 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, pixelRatio, transform, rotation, {}, replays);
- context.restore();
- clips.push(currentClip);
- zs.push(currentZ);
- }
- }
- 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) || loading;
- }
- 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 sourceTileGrid = source.getTileGrid();
- 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]);
- var tilePixelRatio = this.getTilePixelRatio_(source, sourceTile);
- var sourceTileCoord = sourceTile.tileCoord;
- var pixelScale = pixelRatio / resolution;
- var transform = ol.transform.reset(this.tmpTransform_);
- if (sourceTile.getProjection().getUnits() == ol.proj.Units.TILE_PIXELS) {
- var sourceTileExtent = sourceTileGrid.getTileCoordExtent(sourceTileCoord, this.tmpExtent);
- var sourceResolution = sourceTileGrid.getResolution(sourceTileCoord[0]);
- var renderPixelRatio = pixelRatio / tilePixelRatio * sourceResolution / resolution;
- ol.transform.scale(transform, renderPixelRatio, renderPixelRatio);
- var offsetX = (sourceTileExtent[0] - tileExtent[0]) / sourceResolution * tilePixelRatio;
- var offsetY = (tileExtent[3] - sourceTileExtent[3]) / sourceResolution * tilePixelRatio;
- ol.transform.translate(transform, Math.round(offsetX), Math.round(offsetY));
- } else {
- 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, pixelRatio, transform, 0, {}, replays, true);
- }
- }
- };
-
- goog.provide('ol.layer.VectorTile');
-
- goog.require('ol');
- goog.require('ol.asserts');
- goog.require('ol.layer.TileProperty');
- goog.require('ol.layer.Vector');
- goog.require('ol.layer.VectorTileRenderType');
- goog.require('ol.obj');
- goog.require('ol.renderer.Type');
- goog.require('ol.renderer.canvas.VectorTileLayer');
-
-
- /**
- * @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 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);
-
- ol.asserts.assert(options.renderMode == undefined ||
- options.renderMode == ol.layer.VectorTileRenderType.IMAGE ||
- options.renderMode == ol.layer.VectorTileRenderType.HYBRID ||
- options.renderMode == ol.layer.VectorTileRenderType.VECTOR,
- 28); // `renderMode` must be `'image'`, `'hybrid'` or `'vector'`
-
- /**
- * @private
- * @type {ol.layer.VectorTileRenderType|string}
- */
- this.renderMode_ = options.renderMode || ol.layer.VectorTileRenderType.HYBRID;
-
- };
- ol.inherits(ol.layer.VectorTile, ol.layer.Vector);
-
-
- /**
- * @inheritDoc
- */
- ol.layer.VectorTile.prototype.createRenderer = function(mapRenderer) {
- var renderer = null;
- var type = mapRenderer.getType();
- if (ol.ENABLE_CANVAS && type === ol.renderer.Type.CANVAS) {
- renderer = new ol.renderer.canvas.VectorTileLayer(this);
- }
- return renderer;
- };
-
-
- /**
- * 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));
- };
-
-
- /**
- * @return {ol.layer.VectorTileRenderType|string} The render mode.
- */
- ol.layer.VectorTile.prototype.getRenderMode = function() {
- return this.renderMode_;
- };
-
-
- /**
- * 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.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.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');
-
-
- /**
- * @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);
-
- /**
- * @type {number}
- */
- this.highWaterMark = opt_highWaterMark !== undefined ? opt_highWaterMark : 2048;
-
- };
- ol.inherits(ol.TileCache, ol.structs.LRUCache);
-
-
- /**
- * @return {boolean} Can expire cache.
- */
- ol.TileCache.prototype.canExpireCache = function() {
- return this.getCount() > this.highWaterMark;
- };
-
-
- /**
- * @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();
- }
- }
- };
-
- 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_ = '';
-
- };
- 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 = this.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 {number} z Z.
- * @param {number} x X.
- * @param {number} y Y.
- * @return {string} Key.
- * @protected
- */
- ol.source.Tile.prototype.getKeyZXY = ol.tilecoord.getKeyZXY;
-
-
- /**
- * @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.
- * @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');
-
-
- /**
- * @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
- });
-
- /**
- * @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);
- }
-
- };
- 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);
- switch (tile.getState()) {
- case ol.TileState.LOADING:
- this.dispatchEvent(
- new ol.source.Tile.Event(ol.source.TileEventType.TILELOADSTART, tile));
- break;
- case ol.TileState.LOADED:
- this.dispatchEvent(
- new ol.source.Tile.Event(ol.source.TileEventType.TILELOADEND, tile));
- break;
- case ol.TileState.ERROR:
- this.dispatchEvent(
- new ol.source.Tile.Event(ol.source.TileEventType.TILELOADERROR, tile));
- break;
- default:
- // pass
- }
- };
-
-
- /**
- * 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;
- 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 = this.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.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
- });
-
- /**
- * @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)}
- */
- 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);
- 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) {
- if (!ol.ENABLE_RASTER_REPROJECTION ||
- !this.getProjection() ||
- !projection ||
- ol.proj.equivalent(this.getProjection(), projection)) {
- return this.getTileInternal(z, x, y, pixelRatio, /** @type {!ol.proj.Projection} */ (projection));
- } else {
- var cache = this.getTileCacheForProjection(projection);
- var tileCoord = [z, x, y];
- var tile;
- var tileCoordKey = this.getKeyZXY.apply(this, 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 sourceProjection = /** @type {!ol.proj.Projection} */ (this.getProjection());
- 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 = this.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.Attribution');
- 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
- });
-
- /**
- * @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_;
-
- 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 {ol.Attribution}
- * @api
- */
- ol.source.BingMaps.TOS_ATTRIBUTION = new ol.Attribution({
- html: '<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());
-
- var attributions = resource.imageryProviders.map(function(imageryProvider) {
- var html = imageryProvider.attribution;
- /** @type {Object.<string, Array.<ol.TileRange>>} */
- var tileRanges = {};
- imageryProvider.coverageAreas.forEach(function(coverageArea) {
- var minZ = coverageArea.zoomMin;
- var maxZ = Math.min(coverageArea.zoomMax, maxZoom);
- var bbox = coverageArea.bbox;
- var epsg4326Extent = [bbox[1], bbox[0], bbox[3], bbox[2]];
- var extent = ol.extent.applyTransform(epsg4326Extent, transform);
- var tileRange, z, zKey;
- for (z = minZ; z <= maxZ; ++z) {
- zKey = z.toString();
- tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
- if (zKey in tileRanges) {
- tileRanges[zKey].push(tileRange);
- } else {
- tileRanges[zKey] = [tileRange];
- }
- }
- });
- return new ol.Attribution({html: html, tileRanges: tileRanges});
- });
- attributions.push(ol.source.BingMaps.TOS_ATTRIBUTION);
- this.setAttributions(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
- });
-
- };
- 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 tiles.
- *
- * @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_ + '.cartodb.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.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,
- this.getAttributions(), 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.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,
- this.getAttributions(), 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, this.getAttributions(),
- 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.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.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 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, ol.proj.get(projection), 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,
- this.getAttributions(), 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.Attribution');
- 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 {ol.Attribution}
- * @api
- */
- ol.source.OSM.ATTRIBUTION = new ol.Attribution({
- html: '© ' +
- '<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 array
- * of {@link ol.RasterOperation} functions 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,
- attributions: {},
- 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);
-
- 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);
- 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, this.getAttributions(), 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.Attribution');
- 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.<ol.Attribution>}
- */
- ol.source.Stamen.ATTRIBUTIONS = [
- new ol.Attribution({
- html: '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
- });
-
- /**
- * @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');
-
-
- /**
- * @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 = this.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.Attribution');
- 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
- });
-
- 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.getAttributions()) {
- var attributionExtent = extent !== undefined ?
- extent : epsg4326Projection.getExtent();
- /** @type {Object.<string, Array.<ol.TileRange>>} */
- var tileRanges = {};
- var z, zKey;
- for (z = minZoom; z <= maxZoom; ++z) {
- zKey = z.toString();
- tileRanges[zKey] =
- [tileGrid.getTileRangeForExtentAndZ(attributionExtent, z)];
- }
- this.setAttributions([
- new ol.Attribution({
- html: tileJSON.attribution,
- tileRanges: tileRanges
- })
- ]);
- }
- 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.Attribution');
- 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.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();
- /** @type {Object.<string, Array.<ol.TileRange>>} */
- var tileRanges = {};
- var z, zKey;
- for (z = minZoom; z <= maxZoom; ++z) {
- zKey = z.toString();
- tileRanges[zKey] =
- [tileGrid.getTileRangeForExtentAndZ(attributionExtent, z)];
- }
- this.setAttributions([
- new ol.Attribution({
- html: tileJSON.attribution,
- tileRanges: tileRanges
- })
- ]);
- }
-
- this.setState(ol.source.State.READY);
-
- };
-
-
- /**
- * @inheritDoc
- */
- ol.source.TileUTFGrid.prototype.getTile = function(z, x, y, pixelRatio, projection) {
- var tileCoordKey = this.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 = this.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.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
- });
-
- /**
- * @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 {string}
- */
- this.coordKeyPrefix_ = '';
- this.resetCoordKeyPrefix_();
-
- /**
- * @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 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);
- }
-
- 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, projectionObj, baseParams);
- };
-
-
- /**
- * @inheritDoc
- */
- ol.source.TileWMS.prototype.getGutterInternal = function() {
- return this.gutter_;
- };
-
-
- /**
- * @inheritDoc
- */
- ol.source.TileWMS.prototype.getKeyZXY = function(z, x, y) {
- return this.coordKeyPrefix_ + ol.source.TileImage.prototype.getKeyZXY.call(this, z, x, y);
- };
-
-
- /**
- * 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
- */
- ol.source.TileWMS.prototype.resetCoordKeyPrefix_ = function() {
- var i = 0;
- var res = [];
-
- if (this.urls) {
- var j, jj;
- for (j = 0, jj = this.urls.length; j < jj; ++j) {
- res[i++] = this.urls[j];
- }
- }
-
- this.coordKeyPrefix_ = res.join('#');
- };
-
-
- /**
- * @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);
- };
-
- /**
- * @inheritDoc
- */
- ol.source.TileWMS.prototype.setUrls = function(urls) {
- ol.source.TileImage.prototype.setUrls.call(this, urls);
- this.resetCoordKeyPrefix_();
- };
-
-
- /**
- * Update the user-provided params.
- * @param {Object} params Params.
- * @api
- */
- ol.source.TileWMS.prototype.updateParams = function(params) {
- ol.obj.assign(this.params_, params);
- this.resetCoordKeyPrefix_();
- 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.array');
- 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 {string} src Data source url.
- * @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.
- */
- ol.VectorImageTile = function(tileCoord, state, src, format, tileLoadFunction,
- urlTileCoord, tileUrlFunction, sourceTileGrid, tileGrid, sourceTiles,
- pixelRatio, projection, tileClass, handleTileChange) {
-
- ol.Tile.call(this, tileCoord, state);
-
- /**
- * @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 {string}
- */
- this.src_ = src;
-
- /**
- * @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));
- 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;
- if (this.state == ol.TileState.LOADING) {
- 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.src_;
- };
-
-
- /**
- * @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() {
- var leftToLoad = 0;
- 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) {
- --leftToLoad;
- ol.events.unlistenByKey(key);
- ol.array.remove(this.loadListenerKeys_, key);
- if (leftToLoad == 0) {
- this.finishLoading_();
- }
- }
- }.bind(this));
- this.loadListenerKeys_.push(key);
- ++leftToLoad;
- }
- }.bind(this));
- }
- if (leftToLoad == 0) {
- setTimeout(this.finishLoading_.bind(this), 0);
- }
- };
-
-
- /**
- * @private
- */
- ol.VectorImageTile.prototype.finishLoading_ = function() {
- var errors = false;
- var loaded = this.tileKeys.length;
- var state;
- for (var i = loaded - 1; i >= 0; --i) {
- state = this.getTile(this.tileKeys[i]).getState();
- if (state != ol.TileState.LOADED) {
- if (state == ol.TileState.ERROR) {
- errors = true;
- }
- --loaded;
- }
- }
- this.setState(loaded > 0 ?
- ol.TileState.LOADED :
- (errors ? ol.TileState.ERROR : ol.TileState.EMPTY));
- };
-
-
- /**
- * 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.
- */
- ol.VectorTile = function(tileCoord, state, src, format, tileLoadFunction) {
-
- ol.Tile.call(this, tileCoord, state);
-
- /**
- * @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.
- */
- 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.proj');
- goog.require('ol.size');
- goog.require('ol.tilegrid');
- goog.require('ol.source.UrlTile');
-
-
- /**
- * @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
- });
-
- /**
- * @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_ = {};
-
- if (!this.tileGrid) {
- this.tileGrid = this.getTileGridForProjection(ol.proj.get(options.projection || 'EPSG:3857'));
- }
-
- };
- 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_;
- };
-
-
- /**
- * @inheritDoc
- */
- ol.source.VectorTile.prototype.getTile = function(z, x, y, pixelRatio, projection) {
- var tileCoordKey = this.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 = urlTileCoord ?
- this.tileUrlFunction(urlTileCoord, pixelRatio, projection) : undefined;
- var tile = new ol.VectorImageTile(
- tileCoord,
- tileUrl !== undefined ? ol.TileState.IDLE : ol.TileState.EMPTY,
- tileUrl !== undefined ? tileUrl : '',
- this.format_, this.tileLoadFunction, urlTileCoord, this.tileUrlFunction,
- this.tileGrid, this.getTileGridForProjection(projection),
- this.sourceTiles_, pixelRatio, projection, this.tileClass,
- this.handleTileChange.bind(this));
-
- 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 projection;
- projection = ol.proj.get(matrixSet[supportedCRSPropName].replace(
- /urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/, '$1:$3'));
- 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.
- */
- function createFromWMTSTemplate(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(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
- });
-
- this.setKey(this.getKeyForDimensions_());
-
- };
- ol.inherits(ol.source.WMTS, ol.source.TileImage);
-
-
- /**
- * 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'].replace(/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/, '$1:$3');
- var proj1 = 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;
- if ('projection' in config) {
- projection = ol.proj.get(config['projection']);
- } else {
- projection = ol.proj.get(matrixSetObj['SupportedCRS'].replace(
- /urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/, '$1:$3'));
- }
-
- 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) {
- 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;
- }
- }
- }
- 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.source.TileImage');
- goog.require('ol.tilegrid.TileGrid');
-
-
- /**
- * @classdesc
- * Layer source for tile data in Zoomify format.
- *
- * @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 tierSizeInTiles = [];
- var tileSize = ol.DEFAULT_TILE_SIZE;
-
- switch (tierSizeCalculation) {
- case ol.source.Zoomify.TierSizeCalculation_.DEFAULT:
- while (imageWidth > tileSize || imageHeight > tileSize) {
- tierSizeInTiles.push([
- Math.ceil(imageWidth / tileSize),
- Math.ceil(imageHeight / tileSize)
- ]);
- tileSize += tileSize;
- }
- break;
- case ol.source.Zoomify.TierSizeCalculation_.TRUNCATED:
- var width = imageWidth;
- var height = imageHeight;
- while (width > tileSize || height > tileSize) {
- tierSizeInTiles.push([
- Math.ceil(width / tileSize),
- Math.ceil(height / tileSize)
- ]);
- 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 extent = [0, -size[1], size[0], 0];
- var tileGrid = new ol.tilegrid.TileGrid({
- extent: extent,
- origin: ol.extent.getTopLeft(extent),
- resolutions: resolutions
- });
-
- var url = options.url;
- if (url && url.indexOf('{TileGroup}') == -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] +
- tileCountUpToTier[tileCoordZ];
- var tileGroup = (tileIndex / ol.DEFAULT_TILE_SIZE) | 0;
- var localContext = {
- 'z': tileCoordZ,
- 'x': tileCoordX,
- 'y': tileCoordY,
- 'TileGroup': 'TileGroup' + tileGroup
- };
- return template.replace(/\{(\w+?)\}/g, function(m, p) {
- return localContext[p];
- });
- }
- });
- }
-
- var tileUrlFunction = ol.TileUrlFunction.createFromTileUrlFunctions(urls.map(createFromTemplate));
-
- ol.source.TileImage.call(this, {
- attributions: options.attributions,
- cacheSize: options.cacheSize,
- crossOrigin: options.crossOrigin,
- logo: options.logo,
- projection: options.projection,
- reprojectionErrorThreshold: options.reprojectionErrorThreshold,
- tileClass: ol.source.Zoomify.Tile_,
- tileGrid: tileGrid,
- tileUrlFunction: tileUrlFunction
- });
-
- };
- ol.inherits(ol.source.Zoomify, ol.source.TileImage);
-
-
- /**
- * @constructor
- * @extends {ol.ImageTile}
- * @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.
- * @private
- */
- ol.source.Zoomify.Tile_ = function(
- tileCoord, state, src, crossOrigin, tileLoadFunction) {
-
- ol.ImageTile.call(this, tileCoord, state, src, crossOrigin, tileLoadFunction);
-
- /**
- * @private
- * @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement}
- */
- this.zoomifyImage_ = null;
-
- };
- ol.inherits(ol.source.Zoomify.Tile_, ol.ImageTile);
-
-
- /**
- * @inheritDoc
- */
- ol.source.Zoomify.Tile_.prototype.getImage = function() {
- if (this.zoomifyImage_) {
- return this.zoomifyImage_;
- }
- var tileSize = ol.DEFAULT_TILE_SIZE;
- var image = ol.ImageTile.prototype.getImage.call(this);
- if (this.state == ol.TileState.LOADED) {
- if (image.width == tileSize && image.height == tileSize) {
- this.zoomifyImage_ = image;
- return image;
- } else {
- var context = ol.dom.createCanvasContext2D(tileSize, tileSize);
- 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.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.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.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.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.AtlasManager');
- goog.require('ol.style.Circle');
- goog.require('ol.style.Fill');
- goog.require('ol.style.Icon');
- 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.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.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.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.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.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,
- '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.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,
- 'getFont',
- ol.style.Text.prototype.getFont);
-
- 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,
- 'setFont',
- ol.style.Text.prototype.setFont);
-
- 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,
- '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.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,
- 'removeFeature',
- ol.source.Vector.prototype.removeFeature);
-
- goog.exportProperty(
- ol.source.Vector.Event.prototype,
- 'feature',
- ol.source.Vector.Event.prototype.feature);
-
- goog.exportSymbol(
- 'ol.source.VectorTile',
- ol.source.VectorTile,
- OPENLAYERS);
-
- 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.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,
- '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.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.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.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,
- '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,
- 'removeFeature',
- ol.source.Cluster.prototype.removeFeature);
-
- 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.3.3';
- OPENLAYERS.ol = ol;
-
- return OPENLAYERS.ol;
- }));
-
-
|