12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769 |
- /*
- Leaflet.draw 0.4.14, a plugin that adds drawing and editing tools to Leaflet powered maps.
- (c) 2012-2017, Jacob Toye, Jon West, Smartrak, Leaflet
- https://github.com/Leaflet/Leaflet.draw
- http://leafletjs.com
- */
- (function (window, document, undefined) {
- /**
- * Leaflet.draw assumes that you have already included the Leaflet library.
- */
- L.drawVersion = "0.4.14";
- /**
- * @class L.Draw
- * @aka Draw
- *
- *
- * To add the draw toolbar set the option drawControl: true in the map options.
- *
- * @example
- * ```js
- * var map = L.map('map', {drawControl: true}).setView([51.505, -0.09], 13);
- *
- * L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
- * attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
- * }).addTo(map);
- * ```
- *
- * ### Adding the edit toolbar
- * To use the edit toolbar you must initialise the Leaflet.draw control and manually add it to the map.
- *
- * ```js
- * var map = L.map('map').setView([51.505, -0.09], 13);
- *
- * L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
- * attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
- * }).addTo(map);
- *
- * // FeatureGroup is to store editable layers
- * var drawnItems = new L.FeatureGroup();
- * map.addLayer(drawnItems);
- *
- * var drawControl = new L.Control.Draw({
- * edit: {
- * featureGroup: drawnItems
- * }
- * });
- * map.addControl(drawControl);
- * ```
- *
- * The key here is the featureGroup option. This tells the plugin which FeatureGroup contains the layers that
- * should be editable. The featureGroup can contain 0 or more features with geometry types Point, LineString, and Polygon.
- * Leaflet.draw does not work with multigeometry features such as MultiPoint, MultiLineString, MultiPolygon,
- * or GeometryCollection. If you need to add multigeometry features to the draw plugin, convert them to a
- * FeatureCollection of non-multigeometries (Points, LineStrings, or Polygons).
- */
- L.Draw = {};
- /**
- * @class L.drawLocal
- * @aka L.drawLocal
- *
- * The core toolbar class of the API — it is used to create the toolbar ui
- *
- * @example
- * ```js
- * var modifiedDraw = L.drawLocal.extend({
- * draw: {
- * toolbar: {
- * buttons: {
- * polygon: 'Draw an awesome polygon'
- * }
- * }
- * }
- * });
- * ```
- *
- * The default state for the control is the draw toolbar just below the zoom control.
- * This will allow map users to draw vectors and markers.
- * **Please note the edit toolbar is not enabled by default.**
- */
- L.drawLocal = {
- // format: {
- // numeric: {
- // delimiters: {
- // thousands: ',',
- // decimal: '.'
- // }
- // }
- // },
- draw: {
- toolbar: {
- // #TODO: this should be reorganized where actions are nested in actions
- // ex: actions.undo or actions.cancel
- actions: {
- title: 'Cancel drawing',
- text: 'Cancel'
- },
- finish: {
- title: 'Finish drawing',
- text: 'Finish'
- },
- undo: {
- title: 'Delete last point drawn',
- text: 'Delete last point'
- },
- buttons: {
- polyline: 'Draw a polyline',
- polygon: 'Draw a polygon',
- rectangle: 'Draw a rectangle',
- circle: 'Draw a circle',
- marker: 'Draw a marker',
- circlemarker: 'Draw a circlemarker'
- }
- },
- handlers: {
- circle: {
- tooltip: {
- start: 'Click and drag to draw circle.'
- },
- radius: 'Radius'
- },
- circlemarker: {
- tooltip: {
- start: 'Click map to place circle marker.'
- }
- },
- marker: {
- tooltip: {
- start: 'Click map to place marker.'
- }
- },
- polygon: {
- tooltip: {
- start: 'Click to start drawing shape.',
- cont: 'Click to continue drawing shape.',
- end: 'Click first point to close this shape.'
- }
- },
- polyline: {
- error: '<strong>Error:</strong> shape edges cannot cross!',
- tooltip: {
- start: 'Click to start drawing line.',
- cont: 'Click to continue drawing line.',
- end: 'Click last point to finish line.'
- }
- },
- rectangle: {
- tooltip: {
- start: 'Click and drag to draw rectangle.'
- }
- },
- simpleshape: {
- tooltip: {
- end: 'Release mouse to finish drawing.'
- }
- }
- }
- },
- edit: {
- toolbar: {
- actions: {
- save: {
- title: 'Save changes',
- text: 'Save'
- },
- cancel: {
- title: 'Cancel editing, discards all changes',
- text: 'Cancel'
- },
- clearAll: {
- title: 'Clear all layers',
- text: 'Clear All'
- }
- },
- buttons: {
- edit: 'Edit layers',
- editDisabled: 'No layers to edit',
- remove: 'Delete layers',
- removeDisabled: 'No layers to delete'
- }
- },
- handlers: {
- edit: {
- tooltip: {
- text: 'Drag handles or markers to edit features.',
- subtext: 'Click cancel to undo changes.'
- }
- },
- remove: {
- tooltip: {
- text: 'Click on a feature to remove.'
- }
- }
- }
- }
- };
- /**
- * ### Events
- * Once you have successfully added the Leaflet.draw plugin to your map you will want to respond to the different
- * actions users can initiate. The following events will be triggered on the map:
- *
- * @class L.Draw.Event
- * @aka Draw.Event
- *
- * Use `L.Draw.Event.EVENTNAME` constants to ensure events are correct.
- *
- * @example
- * ```js
- * map.on(L.Draw.Event.CREATED; function (e) {
- * var type = e.layerType,
- * layer = e.layer;
- *
- * if (type === 'marker') {
- * // Do marker specific actions
- * }
- *
- * // Do whatever else you need to. (save to db; add to map etc)
- * map.addLayer(layer);
- *});
- * ```
- */
- L.Draw.Event = {};
- /**
- * @event draw:created: PolyLine; Polygon; Rectangle; Circle; Marker | String
- *
- * Layer that was just created.
- * The type of layer this is. One of: `polyline`; `polygon`; `rectangle`; `circle`; `marker`
- * Triggered when a new vector or marker has been created.
- *
- */
- L.Draw.Event.CREATED = 'draw:created';
- /**
- * @event draw:edited: LayerGroup
- *
- * List of all layers just edited on the map.
- *
- *
- * Triggered when layers in the FeatureGroup; initialised with the plugin; have been edited and saved.
- *
- * @example
- * ```js
- * map.on('draw:edited', function (e) {
- * var layers = e.layers;
- * layers.eachLayer(function (layer) {
- * //do whatever you want; most likely save back to db
- * });
- * });
- * ```
- */
- L.Draw.Event.EDITED = 'draw:edited';
- /**
- * @event draw:deleted: LayerGroup
- *
- * List of all layers just removed from the map.
- *
- * Triggered when layers have been removed (and saved) from the FeatureGroup.
- */
- L.Draw.Event.DELETED = 'draw:deleted';
- /**
- * @event draw:drawstart: String
- *
- * The type of layer this is. One of:`polyline`; `polygon`; `rectangle`; `circle`; `marker`
- *
- * Triggered when the user has chosen to draw a particular vector or marker.
- */
- L.Draw.Event.DRAWSTART = 'draw:drawstart';
- /**
- * @event draw:drawstop: String
- *
- * The type of layer this is. One of: `polyline`; `polygon`; `rectangle`; `circle`; `marker`
- *
- * Triggered when the user has finished a particular vector or marker.
- */
- L.Draw.Event.DRAWSTOP = 'draw:drawstop';
- /**
- * @event draw:drawvertex: LayerGroup
- *
- * List of all layers just being added from the map.
- *
- * Triggered when a vertex is created on a polyline or polygon.
- */
- L.Draw.Event.DRAWVERTEX = 'draw:drawvertex';
- /**
- * @event draw:editstart: String
- *
- * The type of edit this is. One of: `edit`
- *
- * Triggered when the user starts edit mode by clicking the edit tool button.
- */
- L.Draw.Event.EDITSTART = 'draw:editstart';
- /**
- * @event draw:editmove: ILayer
- *
- * Layer that was just moved.
- *
- * Triggered as the user moves a rectangle; circle or marker.
- */
- L.Draw.Event.EDITMOVE = 'draw:editmove';
- /**
- * @event draw:editresize: ILayer
- *
- * Layer that was just moved.
- *
- * Triggered as the user resizes a rectangle or circle.
- */
- L.Draw.Event.EDITRESIZE = 'draw:editresize';
- /**
- * @event draw:editvertex: LayerGroup
- *
- * List of all layers just being edited from the map.
- *
- * Triggered when a vertex is edited on a polyline or polygon.
- */
- L.Draw.Event.EDITVERTEX = 'draw:editvertex';
- /**
- * @event draw:editstop: String
- *
- * The type of edit this is. One of: `edit`
- *
- * Triggered when the user has finshed editing (edit mode) and saves edits.
- */
- L.Draw.Event.EDITSTOP = 'draw:editstop';
- /**
- * @event draw:deletestart: String
- *
- * The type of edit this is. One of: `remove`
- *
- * Triggered when the user starts remove mode by clicking the remove tool button.
- */
- L.Draw.Event.DELETESTART = 'draw:deletestart';
- /**
- * @event draw:deletestop: String
- *
- * The type of edit this is. One of: `remove`
- *
- * Triggered when the user has finished removing shapes (remove mode) and saves.
- */
- L.Draw.Event.DELETESTOP = 'draw:deletestop';
- /**
- * @event draw:toolbaropened: String
- *
- * Triggered when a toolbar is opened.
- */
- L.Draw.Event.TOOLBAROPENED = 'draw:toolbaropened';
- /**
- * @event draw:toolbarclosed: String
- *
- * Triggered when a toolbar is closed.
- */
- L.Draw.Event.TOOLBARCLOSED = 'draw:toolbarclosed';
- /**
- * @event draw:markercontext: String
- *
- * Triggered when a marker is right clicked.
- */
- L.Draw.Event.MARKERCONTEXT = 'draw:markercontext';
- L.Draw = L.Draw || {};
- /**
- * @class L.Draw.Feature
- * @aka Draw.Feature
- */
- L.Draw.Feature = L.Handler.extend({
- // @method initialize(): void
- initialize: function (map, options) {
- this._map = map;
- this._container = map._container;
- this._overlayPane = map._panes.overlayPane;
- this._popupPane = map._panes.popupPane;
- // Merge default shapeOptions options with custom shapeOptions
- if (options && options.shapeOptions) {
- options.shapeOptions = L.Util.extend({}, this.options.shapeOptions, options.shapeOptions);
- }
- L.setOptions(this, options);
- var version = L.version.split('.');
- //If Version is >= 1.2.0
- if (parseInt(version[0], 10) === 1 && parseInt(version[1], 10) >= 2) {
- L.Draw.Feature.include(L.Evented.prototype);
- } else {
- L.Draw.Feature.include(L.Mixin.Events);
- }
- },
- // @method enable(): void
- // Enables this handler
- enable: function () {
- if (this._enabled) {
- return;
- }
- L.Handler.prototype.enable.call(this);
- this.fire('enabled', {handler: this.type});
- this._map.fire(L.Draw.Event.DRAWSTART, {layerType: this.type});
- },
- // @method disable(): void
- disable: function () {
- if (!this._enabled) {
- return;
- }
- L.Handler.prototype.disable.call(this);
- this._map.fire(L.Draw.Event.DRAWSTOP, {layerType: this.type});
- this.fire('disabled', {handler: this.type});
- },
- // @method addHooks(): void
- // Add's event listeners to this handler
- addHooks: function () {
- var map = this._map;
- if (map) {
- L.DomUtil.disableTextSelection();
- map.getContainer().focus();
- this._tooltip = new L.Draw.Tooltip(this._map);
- L.DomEvent.on(this._container, 'keyup', this._cancelDrawing, this);
- }
- },
- // @method removeHooks(): void
- // Removes event listeners from this handler
- removeHooks: function () {
- if (this._map) {
- L.DomUtil.enableTextSelection();
- this._tooltip.dispose();
- this._tooltip = null;
- L.DomEvent.off(this._container, 'keyup', this._cancelDrawing, this);
- }
- },
- // @method setOptions(object): void
- // Sets new options to this handler
- setOptions: function (options) {
- L.setOptions(this, options);
- },
- _fireCreatedEvent: function (layer) {
- this._map.fire(L.Draw.Event.CREATED, {layer: layer, layerType: this.type});
- },
- // Cancel drawing when the escape key is pressed
- _cancelDrawing: function (e) {
- if (e.keyCode === 27) {
- this._map.fire('draw:canceled', {layerType: this.type});
- this.disable();
- }
- }
- });
- /**
- * @class L.Draw.Polyline
- * @aka Draw.Polyline
- * @inherits L.Draw.Feature
- */
- L.Draw.Polyline = L.Draw.Feature.extend({
- statics: {
- TYPE: 'polyline'
- },
- Poly: L.Polyline,
- options: {
- allowIntersection: true,
- repeatMode: false,
- drawError: {
- color: '#b00b00',
- timeout: 2500
- },
- icon: new L.DivIcon({
- iconSize: new L.Point(8, 8),
- className: 'leaflet-div-icon leaflet-editing-icon'
- }),
- touchIcon: new L.DivIcon({
- iconSize: new L.Point(20, 20),
- className: 'leaflet-div-icon leaflet-editing-icon leaflet-touch-icon'
- }),
- guidelineDistance: 20,
- maxGuideLineLength: 4000,
- shapeOptions: {
- stroke: true,
- color: '#3388ff',
- weight: 4,
- opacity: 0.5,
- fill: false,
- clickable: true
- },
- metric: true, // Whether to use the metric measurement system or imperial
- feet: true, // When not metric, to use feet instead of yards for display.
- nautic: false, // When not metric, not feet use nautic mile for display
- showLength: true, // Whether to display distance in the tooltip
- zIndexOffset: 2000, // This should be > than the highest z-index any map layers
- factor: 1, // To change distance calculation
- maxPoints: 0 // Once this number of points are placed, finish shape
- },
- // @method initialize(): void
- initialize: function (map, options) {
- // if touch, switch to touch icon
- if (L.Browser.touch) {
- this.options.icon = this.options.touchIcon;
- }
- // Need to set this here to ensure the correct message is used.
- this.options.drawError.message = L.drawLocal.draw.handlers.polyline.error;
- // Merge default drawError options with custom options
- if (options && options.drawError) {
- options.drawError = L.Util.extend({}, this.options.drawError, options.drawError);
- }
- // Save the type so super can fire, need to do this as cannot do this.TYPE :(
- this.type = L.Draw.Polyline.TYPE;
- L.Draw.Feature.prototype.initialize.call(this, map, options);
- },
- // @method addHooks(): void
- // Add listener hooks to this handler
- addHooks: function () {
- L.Draw.Feature.prototype.addHooks.call(this);
- if (this._map) {
- this._markers = [];
- this._markerGroup = new L.LayerGroup();
- this._map.addLayer(this._markerGroup);
- this._poly = new L.Polyline([], this.options.shapeOptions);
- this._tooltip.updateContent(this._getTooltipText());
- // Make a transparent marker that will used to catch click events. These click
- // events will create the vertices. We need to do this so we can ensure that
- // we can create vertices over other map layers (markers, vector layers). We
- // also do not want to trigger any click handlers of objects we are clicking on
- // while drawing.
- if (!this._mouseMarker) {
- this._mouseMarker = L.marker(this._map.getCenter(), {
- icon: L.divIcon({
- className: 'leaflet-mouse-marker',
- iconAnchor: [20, 20],
- iconSize: [40, 40]
- }),
- opacity: 0,
- zIndexOffset: this.options.zIndexOffset
- });
- }
- this._mouseMarker
- .on('mouseout', this._onMouseOut, this)
- .on('mousemove', this._onMouseMove, this) // Necessary to prevent 0.8 stutter
- .on('mousedown', this._onMouseDown, this)
- .on('mouseup', this._onMouseUp, this) // Necessary for 0.8 compatibility
- .addTo(this._map);
- this._map
- .on('mouseup', this._onMouseUp, this) // Necessary for 0.7 compatibility
- .on('mousemove', this._onMouseMove, this)
- .on('zoomlevelschange', this._onZoomEnd, this)
- .on('touchstart', this._onTouch, this)
- .on('zoomend', this._onZoomEnd, this);
- }
- },
- // @method removeHooks(): void
- // Remove listener hooks from this handler.
- removeHooks: function () {
- L.Draw.Feature.prototype.removeHooks.call(this);
- this._clearHideErrorTimeout();
- this._cleanUpShape();
- // remove markers from map
- this._map.removeLayer(this._markerGroup);
- delete this._markerGroup;
- delete this._markers;
- this._map.removeLayer(this._poly);
- delete this._poly;
- this._mouseMarker
- .off('mousedown', this._onMouseDown, this)
- .off('mouseout', this._onMouseOut, this)
- .off('mouseup', this._onMouseUp, this)
- .off('mousemove', this._onMouseMove, this);
- this._map.removeLayer(this._mouseMarker);
- delete this._mouseMarker;
- // clean up DOM
- this._clearGuides();
- this._map
- .off('mouseup', this._onMouseUp, this)
- .off('mousemove', this._onMouseMove, this)
- .off('zoomlevelschange', this._onZoomEnd, this)
- .off('zoomend', this._onZoomEnd, this)
- .off('touchstart', this._onTouch, this)
- .off('click', this._onTouch, this);
- },
- // @method deleteLastVertex(): void
- // Remove the last vertex from the polyline, removes polyline from map if only one point exists.
- deleteLastVertex: function () {
- if (this._markers.length <= 1) {
- return;
- }
- var lastMarker = this._markers.pop(),
- poly = this._poly,
- // Replaces .spliceLatLngs()
- latlngs = poly.getLatLngs(),
- latlng = latlngs.splice(-1, 1)[0];
- this._poly.setLatLngs(latlngs);
- this._markerGroup.removeLayer(lastMarker);
- if (poly.getLatLngs().length < 2) {
- this._map.removeLayer(poly);
- }
- this._vertexChanged(latlng, false);
- },
- // @method addVertex(): void
- // Add a vertex to the end of the polyline
- addVertex: function (latlng) {
- var markersLength = this._markers.length;
- // markersLength must be greater than or equal to 2 before intersections can occur
- if (markersLength >= 2 && !this.options.allowIntersection && this._poly.newLatLngIntersects(latlng)) {
- this._showErrorTooltip();
- return;
- } else if (this._errorShown) {
- this._hideErrorTooltip();
- }
- this._markers.push(this._createMarker(latlng));
- this._poly.addLatLng(latlng);
- if (this._poly.getLatLngs().length === 2) {
- this._map.addLayer(this._poly);
- }
- this._vertexChanged(latlng, true);
- },
- // @method completeShape(): void
- // Closes the polyline between the first and last points
- completeShape: function () {
- if (this._markers.length <= 1) {
- return;
- }
- this._fireCreatedEvent();
- this.disable();
- if (this.options.repeatMode) {
- this.enable();
- }
- },
- _finishShape: function () {
- var latlngs = this._poly._defaultShape ? this._poly._defaultShape() : this._poly.getLatLngs();
- var intersects = this._poly.newLatLngIntersects(latlngs[latlngs.length - 1]);
- if ((!this.options.allowIntersection && intersects) || !this._shapeIsValid()) {
- this._showErrorTooltip();
- return;
- }
- this._fireCreatedEvent();
- this.disable();
- if (this.options.repeatMode) {
- this.enable();
- }
- },
- // Called to verify the shape is valid when the user tries to finish it
- // Return false if the shape is not valid
- _shapeIsValid: function () {
- return true;
- },
- _onZoomEnd: function () {
- if (this._markers !== null) {
- this._updateGuide();
- }
- },
- _onMouseMove: function (e) {
- var newPos = this._map.mouseEventToLayerPoint(e.originalEvent);
- var latlng = this._map.layerPointToLatLng(newPos);
- // Save latlng
- // should this be moved to _updateGuide() ?
- this._currentLatLng = latlng;
- this._updateTooltip(latlng);
- // Update the guide line
- this._updateGuide(newPos);
- // Update the mouse marker position
- this._mouseMarker.setLatLng(latlng);
- L.DomEvent.preventDefault(e.originalEvent);
- },
- _vertexChanged: function (latlng, added) {
- this._map.fire(L.Draw.Event.DRAWVERTEX, {layers: this._markerGroup});
- this._updateFinishHandler();
- this._updateRunningMeasure(latlng, added);
- this._clearGuides();
- this._updateTooltip();
- },
- _onMouseDown: function (e) {
- if (!this._clickHandled && !this._touchHandled && !this._disableMarkers) {
- this._onMouseMove(e);
- this._clickHandled = true;
- this._disableNewMarkers();
- var originalEvent = e.originalEvent;
- var clientX = originalEvent.clientX;
- var clientY = originalEvent.clientY;
- this._startPoint.call(this, clientX, clientY);
- }
- },
- _startPoint: function (clientX, clientY) {
- this._mouseDownOrigin = L.point(clientX, clientY);
- },
- _onMouseUp: function (e) {
- var originalEvent = e.originalEvent;
- var clientX = originalEvent.clientX;
- var clientY = originalEvent.clientY;
- this._endPoint.call(this, clientX, clientY, e);
- this._clickHandled = null;
- },
- _endPoint: function (clientX, clientY, e) {
- if (this._mouseDownOrigin) {
- var dragCheckDistance = L.point(clientX, clientY)
- .distanceTo(this._mouseDownOrigin);
- var lastPtDistance = this._calculateFinishDistance(e.latlng);
- if (this.options.maxPoints > 1 && this.options.maxPoints == this._markers.length + 1) {
- this.addVertex(e.latlng);
- this._finishShape();
- } else if (lastPtDistance < 10 && L.Browser.touch) {
- this._finishShape();
- } else if (Math.abs(dragCheckDistance) < 9 * (window.devicePixelRatio || 1)) {
- this.addVertex(e.latlng);
- }
- this._enableNewMarkers(); // after a short pause, enable new markers
- }
- this._mouseDownOrigin = null;
- },
- // ontouch prevented by clickHandled flag because some browsers fire both click/touch events,
- // causing unwanted behavior
- _onTouch: function (e) {
- var originalEvent = e.originalEvent;
- var clientX;
- var clientY;
- if (originalEvent.touches && originalEvent.touches[0] && !this._clickHandled && !this._touchHandled && !this._disableMarkers) {
- clientX = originalEvent.touches[0].clientX;
- clientY = originalEvent.touches[0].clientY;
- this._disableNewMarkers();
- this._touchHandled = true;
- this._startPoint.call(this, clientX, clientY);
- this._endPoint.call(this, clientX, clientY, e);
- this._touchHandled = null;
- }
- this._clickHandled = null;
- },
- _onMouseOut: function () {
- if (this._tooltip) {
- this._tooltip._onMouseOut.call(this._tooltip);
- }
- },
- // calculate if we are currently within close enough distance
- // of the closing point (first point for shapes, last point for lines)
- // this is semi-ugly code but the only reliable way i found to get the job done
- // note: calculating point.distanceTo between mouseDownOrigin and last marker did NOT work
- _calculateFinishDistance: function (potentialLatLng) {
- var lastPtDistance;
- if (this._markers.length > 0) {
- var finishMarker;
- if (this.type === L.Draw.Polyline.TYPE) {
- finishMarker = this._markers[this._markers.length - 1];
- } else if (this.type === L.Draw.Polygon.TYPE) {
- finishMarker = this._markers[0];
- } else {
- return Infinity;
- }
- var lastMarkerPoint = this._map.latLngToContainerPoint(finishMarker.getLatLng()),
- potentialMarker = new L.Marker(potentialLatLng, {
- icon: this.options.icon,
- zIndexOffset: this.options.zIndexOffset * 2
- });
- var potentialMarkerPint = this._map.latLngToContainerPoint(potentialMarker.getLatLng());
- lastPtDistance = lastMarkerPoint.distanceTo(potentialMarkerPint);
- } else {
- lastPtDistance = Infinity;
- }
- return lastPtDistance;
- },
- _updateFinishHandler: function () {
- var markerCount = this._markers.length;
- // The last marker should have a click handler to close the polyline
- if (markerCount > 1) {
- this._markers[markerCount - 1].on('click', this._finishShape, this);
- }
- // Remove the old marker click handler (as only the last point should close the polyline)
- if (markerCount > 2) {
- this._markers[markerCount - 2].off('click', this._finishShape, this);
- }
- },
- _createMarker: function (latlng) {
- var marker = new L.Marker(latlng, {
- icon: this.options.icon,
- zIndexOffset: this.options.zIndexOffset * 2
- });
- this._markerGroup.addLayer(marker);
- return marker;
- },
- _updateGuide: function (newPos) {
- var markerCount = this._markers ? this._markers.length : 0;
- if (markerCount > 0) {
- newPos = newPos || this._map.latLngToLayerPoint(this._currentLatLng);
- // draw the guide line
- this._clearGuides();
- this._drawGuide(
- this._map.latLngToLayerPoint(this._markers[markerCount - 1].getLatLng()),
- newPos
- );
- }
- },
- _updateTooltip: function (latLng) {
- var text = this._getTooltipText();
- if (latLng) {
- this._tooltip.updatePosition(latLng);
- }
- if (!this._errorShown) {
- this._tooltip.updateContent(text);
- }
- },
- _drawGuide: function (pointA, pointB) {
- var length = Math.floor(Math.sqrt(Math.pow((pointB.x - pointA.x), 2) + Math.pow((pointB.y - pointA.y), 2))),
- guidelineDistance = this.options.guidelineDistance,
- maxGuideLineLength = this.options.maxGuideLineLength,
- // Only draw a guideline with a max length
- i = length > maxGuideLineLength ? length - maxGuideLineLength : guidelineDistance,
- fraction,
- dashPoint,
- dash;
- //create the guides container if we haven't yet
- if (!this._guidesContainer) {
- this._guidesContainer = L.DomUtil.create('div', 'leaflet-draw-guides', this._overlayPane);
- }
- //draw a dash every GuildeLineDistance
- for (; i < length; i += this.options.guidelineDistance) {
- //work out fraction along line we are
- fraction = i / length;
- //calculate new x,y point
- dashPoint = {
- x: Math.floor((pointA.x * (1 - fraction)) + (fraction * pointB.x)),
- y: Math.floor((pointA.y * (1 - fraction)) + (fraction * pointB.y))
- };
- //add guide dash to guide container
- dash = L.DomUtil.create('div', 'leaflet-draw-guide-dash', this._guidesContainer);
- dash.style.backgroundColor =
- !this._errorShown ? this.options.shapeOptions.color : this.options.drawError.color;
- L.DomUtil.setPosition(dash, dashPoint);
- }
- },
- _updateGuideColor: function (color) {
- if (this._guidesContainer) {
- for (var i = 0, l = this._guidesContainer.childNodes.length; i < l; i++) {
- this._guidesContainer.childNodes[i].style.backgroundColor = color;
- }
- }
- },
- // removes all child elements (guide dashes) from the guides container
- _clearGuides: function () {
- if (this._guidesContainer) {
- while (this._guidesContainer.firstChild) {
- this._guidesContainer.removeChild(this._guidesContainer.firstChild);
- }
- }
- },
- _getTooltipText: function () {
- var showLength = this.options.showLength,
- labelText, distanceStr;
- if (this._markers.length === 0) {
- labelText = {
- text: L.drawLocal.draw.handlers.polyline.tooltip.start
- };
- } else {
- distanceStr = showLength ? this._getMeasurementString() : '';
- if (this._markers.length === 1) {
- labelText = {
- text: L.drawLocal.draw.handlers.polyline.tooltip.cont,
- subtext: distanceStr
- };
- } else {
- labelText = {
- text: L.drawLocal.draw.handlers.polyline.tooltip.end,
- subtext: distanceStr
- };
- }
- }
- return labelText;
- },
- _updateRunningMeasure: function (latlng, added) {
- var markersLength = this._markers.length,
- previousMarkerIndex, distance;
- if (this._markers.length === 1) {
- this._measurementRunningTotal = 0;
- } else {
- previousMarkerIndex = markersLength - (added ? 2 : 1);
- // Calculate the distance based on the version
- if (L.GeometryUtil.isVersion07x()) {
- // distance = latlng.distanceTo(this._markers[previousMarkerIndex].getLatLng()) * (this.options.factor || 1);
- distance = 1;
- } else {
- // distance = this._map.distance(latlng, this._markers[previousMarkerIndex].getLatLng()) * (this.options.factor || 1);
- distance = 1;
- }
- this._measurementRunningTotal += distance * (added ? 1 : -1);
- }
- },
- _getMeasurementString: function () {
- var currentLatLng = this._currentLatLng,
- previousLatLng = this._markers[this._markers.length - 1].getLatLng(),
- distance;
- // Calculate the distance from the last fixed point to the mouse position based on the version
- if (L.GeometryUtil.isVersion07x()) {
- // distance = previousLatLng && currentLatLng && currentLatLng.distanceTo ? this._measurementRunningTotal + currentLatLng.distanceTo(previousLatLng) * (this.options.factor || 1) : this._measurementRunningTotal || 0;
- distance = 0;
- } else {
- // distance = previousLatLng && currentLatLng ? this._measurementRunningTotal + this._map.distance(currentLatLng, previousLatLng) * (this.options.factor || 1) : this._measurementRunningTotal || 0;
- distance = 0;
- }
- return L.GeometryUtil.readableDistance(distance, this.options.metric, this.options.feet, this.options.nautic, this.options.precision);
- },
- _showErrorTooltip: function () {
- this._errorShown = true;
- // Update tooltip
- this._tooltip
- .showAsError()
- .updateContent({text: this.options.drawError.message});
- // Update shape
- this._updateGuideColor(this.options.drawError.color);
- this._poly.setStyle({color: this.options.drawError.color});
- // Hide the error after 2 seconds
- this._clearHideErrorTimeout();
- this._hideErrorTimeout = setTimeout(L.Util.bind(this._hideErrorTooltip, this), this.options.drawError.timeout);
- },
- _hideErrorTooltip: function () {
- this._errorShown = false;
- this._clearHideErrorTimeout();
- // Revert tooltip
- this._tooltip
- .removeError()
- .updateContent(this._getTooltipText());
- // Revert shape
- this._updateGuideColor(this.options.shapeOptions.color);
- this._poly.setStyle({color: this.options.shapeOptions.color});
- },
- _clearHideErrorTimeout: function () {
- if (this._hideErrorTimeout) {
- clearTimeout(this._hideErrorTimeout);
- this._hideErrorTimeout = null;
- }
- },
- // disable new markers temporarily;
- // this is to prevent duplicated touch/click events in some browsers
- _disableNewMarkers: function () {
- this._disableMarkers = true;
- },
- // see _disableNewMarkers
- _enableNewMarkers: function () {
- setTimeout(function () {
- this._disableMarkers = false;
- }.bind(this), 50);
- },
- _cleanUpShape: function () {
- if (this._markers.length > 1) {
- this._markers[this._markers.length - 1].off('click', this._finishShape, this);
- }
- },
- _fireCreatedEvent: function () {
- var poly = new this.Poly(this._poly.getLatLngs(), this.options.shapeOptions);
- L.Draw.Feature.prototype._fireCreatedEvent.call(this, poly);
- }
- });
- /**
- * @class L.Draw.Polygon
- * @aka Draw.Polygon
- * @inherits L.Draw.Polyline
- */
- L.Draw.Polygon = L.Draw.Polyline.extend({
- statics: {
- TYPE: 'polygon'
- },
- Poly: L.Polygon,
- options: {
- showArea: false,
- showLength: false,
- shapeOptions: {
- stroke: true,
- color: '#3388ff',
- weight: 4,
- opacity: 0.5,
- fill: true,
- fillColor: null, //same as color by default
- fillOpacity: 0.2,
- clickable: true
- },
- // Whether to use the metric measurement system (truthy) or not (falsy).
- // Also defines the units to use for the metric system as an array of
- // strings (e.g. `['ha', 'm']`).
- metric: true,
- feet: true, // When not metric, to use feet instead of yards for display.
- nautic: false, // When not metric, not feet use nautic mile for display
- // Defines the precision for each type of unit (e.g. {km: 2, ft: 0}
- precision: {}
- },
- // @method initialize(): void
- initialize: function (map, options) {
- L.Draw.Polyline.prototype.initialize.call(this, map, options);
- // Save the type so super can fire, need to do this as cannot do this.TYPE :(
- this.type = L.Draw.Polygon.TYPE;
- },
- _updateFinishHandler: function () {
- var markerCount = this._markers.length;
- // The first marker should have a click handler to close the polygon
- if (markerCount === 1) {
- this._markers[0].on('click', this._finishShape, this);
- }
- // Add and update the double click handler
- if (markerCount > 2) {
- this._markers[markerCount - 1].on('dblclick', this._finishShape, this);
- // Only need to remove handler if has been added before
- if (markerCount > 3) {
- this._markers[markerCount - 2].off('dblclick', this._finishShape, this);
- }
- }
- },
- _getTooltipText: function () {
- var text, subtext;
- if (this._markers.length === 0) {
- text = L.drawLocal.draw.handlers.polygon.tooltip.start;
- } else if (this._markers.length < 3) {
- text = L.drawLocal.draw.handlers.polygon.tooltip.cont;
- subtext = this._getMeasurementString();
- } else {
- text = L.drawLocal.draw.handlers.polygon.tooltip.end;
- subtext = this._getMeasurementString();
- }
- return {
- text: text,
- subtext: subtext
- };
- },
- _getMeasurementString: function () {
- var area = this._area,
- measurementString = '';
- if (!area && !this.options.showLength) {
- return null;
- }
- if (this.options.showLength) {
- measurementString = L.Draw.Polyline.prototype._getMeasurementString.call(this);
- }
- if (area) {
- measurementString += '<br>' + L.GeometryUtil.readableArea(area, this.options.metric, this.options.precision);
- }
- return measurementString;
- },
- _shapeIsValid: function () {
- return this._markers.length >= 3;
- },
- _vertexChanged: function (latlng, added) {
- var latLngs;
- // Check to see if we should show the area
- if (!this.options.allowIntersection && this.options.showArea) {
- latLngs = this._poly.getLatLngs();
- this._area = L.GeometryUtil.geodesicArea(latLngs);
- }
- L.Draw.Polyline.prototype._vertexChanged.call(this, latlng, added);
- },
- _cleanUpShape: function () {
- var markerCount = this._markers.length;
- if (markerCount > 0) {
- this._markers[0].off('click', this._finishShape, this);
- if (markerCount > 2) {
- this._markers[markerCount - 1].off('dblclick', this._finishShape, this);
- }
- }
- }
- });
- L.SimpleShape = {};
- /**
- * @class L.Draw.SimpleShape
- * @aka Draw.SimpleShape
- * @inherits L.Draw.Feature
- */
- L.Draw.SimpleShape = L.Draw.Feature.extend({
- options: {
- repeatMode: false
- },
- // @method initialize(): void
- initialize: function (map, options) {
- this._endLabelText = L.drawLocal.draw.handlers.simpleshape.tooltip.end;
- L.Draw.Feature.prototype.initialize.call(this, map, options);
- },
- // @method addHooks(): void
- // Add listener hooks to this handler.
- addHooks: function () {
- L.Draw.Feature.prototype.addHooks.call(this);
- if (this._map) {
- this._mapDraggable = this._map.dragging.enabled();
- if (this._mapDraggable) {
- this._map.dragging.disable();
- }
- //TODO refactor: move cursor to styles
- this._container.style.cursor = 'crosshair';
- this._tooltip.updateContent({text: this._initialLabelText});
- this._map
- .on('mousedown', this._onMouseDown, this)
- .on('mousemove', this._onMouseMove, this)
- .on('touchstart', this._onMouseDown, this)
- .on('touchmove', this._onMouseMove, this);
- // we should prevent default, otherwise default behavior (scrolling) will fire,
- // and that will cause document.touchend to fire and will stop the drawing
- // (circle, rectangle) in touch mode.
- // (update): we have to send passive now to prevent scroll, because by default it is {passive: true} now, which means,
- // handler can't event.preventDefault
- // check the news https://developers.google.com/web/updates/2016/06/passive-event-listeners
- document.addEventListener('touchstart', L.DomEvent.preventDefault, {passive: false});
- }
- },
- // @method removeHooks(): void
- // Remove listener hooks from this handler.
- removeHooks: function () {
- L.Draw.Feature.prototype.removeHooks.call(this);
- if (this._map) {
- if (this._mapDraggable) {
- this._map.dragging.enable();
- }
- //TODO refactor: move cursor to styles
- this._container.style.cursor = '';
- this._map
- .off('mousedown', this._onMouseDown, this)
- .off('mousemove', this._onMouseMove, this)
- .off('touchstart', this._onMouseDown, this)
- .off('touchmove', this._onMouseMove, this);
- L.DomEvent.off(document, 'mouseup', this._onMouseUp, this);
- L.DomEvent.off(document, 'touchend', this._onMouseUp, this);
- document.removeEventListener('touchstart', L.DomEvent.preventDefault);
- // If the box element doesn't exist they must not have moved the mouse, so don't need to destroy/return
- if (this._shape) {
- this._map.removeLayer(this._shape);
- delete this._shape;
- }
- }
- this._isDrawing = false;
- },
- _getTooltipText: function () {
- return {
- text: this._endLabelText
- };
- },
- _onMouseDown: function (e) {
- this._isDrawing = true;
- this._startLatLng = e.latlng;
- L.DomEvent
- .on(document, 'mouseup', this._onMouseUp, this)
- .on(document, 'touchend', this._onMouseUp, this)
- .preventDefault(e.originalEvent);
- },
- _onMouseMove: function (e) {
- var latlng = e.latlng;
- this._tooltip.updatePosition(latlng);
- if (this._isDrawing) {
- this._tooltip.updateContent(this._getTooltipText());
- this._drawShape(latlng);
- }
- },
- _onMouseUp: function () {
- if (this._shape) {
- this._fireCreatedEvent();
- }
- this.disable();
- if (this.options.repeatMode) {
- this.enable();
- }
- }
- });
- /**
- * @class L.Draw.Rectangle
- * @aka Draw.Rectangle
- * @inherits L.Draw.SimpleShape
- */
- L.Draw.Rectangle = L.Draw.SimpleShape.extend({
- statics: {
- TYPE: 'rectangle'
- },
- options: {
- shapeOptions: {
- stroke: true,
- color: '#3388ff',
- weight: 4,
- opacity: 0.5,
- fill: true,
- fillColor: null, //same as color by default
- fillOpacity: 0.2,
- showArea: true,
- clickable: true
- },
- metric: true // Whether to use the metric measurement system or imperial
- },
- // @method initialize(): void
- initialize: function (map, options) {
- // Save the type so super can fire, need to do this as cannot do this.TYPE :(
- this.type = L.Draw.Rectangle.TYPE;
- this._initialLabelText = L.drawLocal.draw.handlers.rectangle.tooltip.start;
- L.Draw.SimpleShape.prototype.initialize.call(this, map, options);
- },
- // @method disable(): void
- disable: function () {
- if (!this._enabled) {
- return;
- }
- this._isCurrentlyTwoClickDrawing = false;
- L.Draw.SimpleShape.prototype.disable.call(this);
- },
- _onMouseUp: function (e) {
- if (!this._shape && !this._isCurrentlyTwoClickDrawing) {
- this._isCurrentlyTwoClickDrawing = true;
- return;
- }
- // Make sure closing click is on map
- if (this._isCurrentlyTwoClickDrawing && !_hasAncestor(e.target, 'leaflet-pane')) {
- return;
- }
- L.Draw.SimpleShape.prototype._onMouseUp.call(this);
- },
- _drawShape: function (latlng) {
- if (!this._shape) {
- this._shape = new L.Rectangle(new L.LatLngBounds(this._startLatLng, latlng), this.options.shapeOptions);
- this._map.addLayer(this._shape);
- } else {
- this._shape.setBounds(new L.LatLngBounds(this._startLatLng, latlng));
- }
- },
- _fireCreatedEvent: function () {
- var rectangle = new L.Rectangle(this._shape.getBounds(), this.options.shapeOptions);
- L.Draw.SimpleShape.prototype._fireCreatedEvent.call(this, rectangle);
- },
- _getTooltipText: function () {
- var tooltipText = L.Draw.SimpleShape.prototype._getTooltipText.call(this),
- shape = this._shape,
- showArea = this.options.showArea,
- latLngs, area, subtext;
- if (shape) {
- latLngs = this._shape._defaultShape ? this._shape._defaultShape() : this._shape.getLatLngs();
- area = L.GeometryUtil.geodesicArea(latLngs);
- subtext = showArea ? L.GeometryUtil.readableArea(area, this.options.metric) : '';
- }
- return {
- text: tooltipText.text,
- subtext: subtext
- };
- }
- });
- function _hasAncestor(el, cls) {
- while ((el = el.parentElement) && !el.classList.contains(cls)) {
- ;
- }
- return el;
- }
- /**
- * @class L.Draw.Marker
- * @aka Draw.Marker
- * @inherits L.Draw.Feature
- */
- L.Draw.Marker = L.Draw.Feature.extend({
- statics: {
- TYPE: 'marker'
- },
- options: {
- icon: new L.Icon.Default(),
- repeatMode: false,
- zIndexOffset: 2000 // This should be > than the highest z-index any markers
- },
- // @method initialize(): void
- initialize: function (map, options) {
- // Save the type so super can fire, need to do this as cannot do this.TYPE :(
- this.type = L.Draw.Marker.TYPE;
- this._initialLabelText = L.drawLocal.draw.handlers.marker.tooltip.start;
- L.Draw.Feature.prototype.initialize.call(this, map, options);
- },
- // @method addHooks(): void
- // Add listener hooks to this handler.
- addHooks: function () {
- L.Draw.Feature.prototype.addHooks.call(this);
- if (this._map) {
- this._tooltip.updateContent({text: this._initialLabelText});
- // Same mouseMarker as in Draw.Polyline
- if (!this._mouseMarker) {
- this._mouseMarker = L.marker(this._map.getCenter(), {
- icon: L.divIcon({
- className: 'leaflet-mouse-marker',
- iconAnchor: [20, 20],
- iconSize: [40, 40]
- }),
- opacity: 0,
- zIndexOffset: this.options.zIndexOffset
- });
- }
- this._mouseMarker
- .on('click', this._onClick, this)
- .addTo(this._map);
- this._map.on('mousemove', this._onMouseMove, this);
- this._map.on('click', this._onTouch, this);
- }
- },
- // @method removeHooks(): void
- // Remove listener hooks from this handler.
- removeHooks: function () {
- L.Draw.Feature.prototype.removeHooks.call(this);
- if (this._map) {
- this._map
- .off('click', this._onClick, this)
- .off('click', this._onTouch, this);
- if (this._marker) {
- this._marker.off('click', this._onClick, this);
- this._map
- .removeLayer(this._marker);
- delete this._marker;
- }
- this._mouseMarker.off('click', this._onClick, this);
- this._map.removeLayer(this._mouseMarker);
- delete this._mouseMarker;
- this._map.off('mousemove', this._onMouseMove, this);
- }
- },
- _onMouseMove: function (e) {
- var latlng = e.latlng;
- this._tooltip.updatePosition(latlng);
- this._mouseMarker.setLatLng(latlng);
- if (!this._marker) {
- this._marker = this._createMarker(latlng);
- // Bind to both marker and map to make sure we get the click event.
- this._marker.on('click', this._onClick, this);
- this._map
- .on('click', this._onClick, this)
- .addLayer(this._marker);
- } else {
- latlng = this._mouseMarker.getLatLng();
- this._marker.setLatLng(latlng);
- }
- },
- _createMarker: function (latlng) {
- return new L.Marker(latlng, {
- icon: this.options.icon,
- zIndexOffset: this.options.zIndexOffset
- });
- },
- _onClick: function () {
- this._fireCreatedEvent();
- this.disable();
- if (this.options.repeatMode) {
- this.enable();
- }
- },
- _onTouch: function (e) {
- // called on click & tap, only really does any thing on tap
- this._onMouseMove(e); // creates & places marker
- this._onClick(); // permanently places marker & ends interaction
- },
- _fireCreatedEvent: function () {
- var marker = new L.Marker.Touch(this._marker.getLatLng(), {icon: this.options.icon});
- L.Draw.Feature.prototype._fireCreatedEvent.call(this, marker);
- }
- });
- /**
- * @class L.Draw.CircleMarker
- * @aka Draw.CircleMarker
- * @inherits L.Draw.Marker
- */
- L.Draw.CircleMarker = L.Draw.Marker.extend({
- statics: {
- TYPE: 'circlemarker'
- },
- options: {
- stroke: true,
- color: '#3388ff',
- weight: 4,
- opacity: 0.5,
- fill: true,
- fillColor: null, //same as color by default
- fillOpacity: 0.2,
- clickable: true,
- zIndexOffset: 2000 // This should be > than the highest z-index any markers
- },
- // @method initialize(): void
- initialize: function (map, options) {
- // Save the type so super can fire, need to do this as cannot do this.TYPE :(
- this.type = L.Draw.CircleMarker.TYPE;
- this._initialLabelText = L.drawLocal.draw.handlers.circlemarker.tooltip.start;
- L.Draw.Feature.prototype.initialize.call(this, map, options);
- },
- _fireCreatedEvent: function () {
- var circleMarker = new L.CircleMarker(this._marker.getLatLng(), this.options);
- L.Draw.Feature.prototype._fireCreatedEvent.call(this, circleMarker);
- },
- _createMarker: function (latlng) {
- return new L.CircleMarker(latlng, this.options);
- }
- });
- /**
- * @class L.Draw.Circle
- * @aka Draw.Circle
- * @inherits L.Draw.SimpleShape
- */
- L.Draw.Circle = L.Draw.SimpleShape.extend({
- statics: {
- TYPE: 'circle'
- },
- options: {
- shapeOptions: {
- stroke: true,
- color: '#3388ff',
- weight: 4,
- opacity: 0.5,
- fill: true,
- fillColor: null, //same as color by default
- fillOpacity: 0.2,
- clickable: true
- },
- showRadius: true,
- metric: true, // Whether to use the metric measurement system or imperial
- feet: true, // When not metric, use feet instead of yards for display
- nautic: false // When not metric, not feet use nautic mile for display
- },
- // @method initialize(): void
- initialize: function (map, options) {
- // Save the type so super can fire, need to do this as cannot do this.TYPE :(
- this.type = L.Draw.Circle.TYPE;
- this._initialLabelText = L.drawLocal.draw.handlers.circle.tooltip.start;
- L.Draw.SimpleShape.prototype.initialize.call(this, map, options);
- },
- _drawShape: function (latlng) {
- // Calculate the distance based on the version
- if (L.GeometryUtil.isVersion07x()) {
- var distance = this._startLatLng.distanceTo(latlng);
- } else {
- var distance = this._map.distance(this._startLatLng, latlng);
- }
- if (!this._shape) {
- this._shape = new L.Circle(this._startLatLng, distance, this.options.shapeOptions);
- this._map.addLayer(this._shape);
- } else {
- this._shape.setRadius(distance);
- }
- },
- _fireCreatedEvent: function () {
- var circle = new L.Circle(this._startLatLng, this._shape.getRadius(), this.options.shapeOptions);
- L.Draw.SimpleShape.prototype._fireCreatedEvent.call(this, circle);
- },
- _onMouseMove: function (e) {
- var latlng = e.latlng,
- showRadius = this.options.showRadius,
- useMetric = this.options.metric,
- radius;
- this._tooltip.updatePosition(latlng);
- if (this._isDrawing) {
- this._drawShape(latlng);
- // Get the new radius (rounded to 1 dp)
- radius = this._shape.getRadius().toFixed(1);
- var subtext = '';
- if (showRadius) {
- subtext = L.drawLocal.draw.handlers.circle.radius + ': ' +
- L.GeometryUtil.readableDistance(radius, useMetric, this.options.feet, this.options.nautic);
- }
- this._tooltip.updateContent({
- text: this._endLabelText,
- subtext: subtext
- });
- }
- }
- });
- L.Edit = L.Edit || {};
- /**
- * @class L.Edit.Marker
- * @aka Edit.Marker
- */
- L.Edit.Marker = L.Handler.extend({
- // @method initialize(): void
- initialize: function (marker, options) {
- this._marker = marker;
- L.setOptions(this, options);
- },
- // @method addHooks(): void
- // Add listener hooks to this handler
- addHooks: function () {
- var marker = this._marker;
- marker.dragging.enable();
- marker.on('dragend', this._onDragEnd, marker);
- this._toggleMarkerHighlight();
- },
- // @method removeHooks(): void
- // Remove listener hooks from this handler
- removeHooks: function () {
- var marker = this._marker;
- marker.dragging.disable();
- marker.off('dragend', this._onDragEnd, marker);
- this._toggleMarkerHighlight();
- },
- _onDragEnd: function (e) {
- var layer = e.target;
- layer.edited = true;
- this._map.fire(L.Draw.Event.EDITMOVE, {layer: layer});
- },
- _toggleMarkerHighlight: function () {
- var icon = this._marker._icon;
- // Don't do anything if this layer is a marker but doesn't have an icon. Markers
- // should usually have icons. If using Leaflet.draw with Leaflet.markercluster there
- // is a chance that a marker doesn't.
- if (!icon) {
- return;
- }
- // This is quite naughty, but I don't see another way of doing it. (short of setting a new icon)
- icon.style.display = 'none';
- if (L.DomUtil.hasClass(icon, 'leaflet-edit-marker-selected')) {
- L.DomUtil.removeClass(icon, 'leaflet-edit-marker-selected');
- // Offset as the border will make the icon move.
- this._offsetMarker(icon, -4);
- } else {
- L.DomUtil.addClass(icon, 'leaflet-edit-marker-selected');
- // Offset as the border will make the icon move.
- this._offsetMarker(icon, 4);
- }
- icon.style.display = '';
- },
- _offsetMarker: function (icon, offset) {
- var iconMarginTop = parseInt(icon.style.marginTop, 10) - offset,
- iconMarginLeft = parseInt(icon.style.marginLeft, 10) - offset;
- icon.style.marginTop = iconMarginTop + 'px';
- icon.style.marginLeft = iconMarginLeft + 'px';
- }
- });
- L.Marker.addInitHook(function () {
- if (L.Edit.Marker) {
- this.editing = new L.Edit.Marker(this);
- if (this.options.editable) {
- this.editing.enable();
- }
- }
- });
- L.Edit = L.Edit || {};
- /**
- * @class L.Edit.Polyline
- * @aka L.Edit.Poly
- * @aka Edit.Poly
- */
- L.Edit.Poly = L.Handler.extend({
- // @method initialize(): void
- initialize: function (poly) {
- this.latlngs = [poly._latlngs];
- if (poly._holes) {
- this.latlngs = this.latlngs.concat(poly._holes);
- }
- this._poly = poly;
- this._poly.on('revert-edited', this._updateLatLngs, this);
- },
- // Compatibility method to normalize Poly* objects
- // between 0.7.x and 1.0+
- _defaultShape: function () {
- if (!L.Polyline._flat) {
- return this._poly._latlngs;
- }
- return L.Polyline._flat(this._poly._latlngs) ? this._poly._latlngs : this._poly._latlngs[0];
- },
- _eachVertexHandler: function (callback) {
- for (var i = 0; i < this._verticesHandlers.length; i++) {
- callback(this._verticesHandlers[i]);
- }
- },
- // @method addHooks(): void
- // Add listener hooks to this handler
- addHooks: function () {
- this._initHandlers();
- this._eachVertexHandler(function (handler) {
- handler.addHooks();
- });
- },
- // @method removeHooks(): void
- // Remove listener hooks from this handler
- removeHooks: function () {
- this._eachVertexHandler(function (handler) {
- handler.removeHooks();
- });
- },
- // @method updateMarkers(): void
- // Fire an update for each vertex handler
- updateMarkers: function () {
- this._eachVertexHandler(function (handler) {
- handler.updateMarkers();
- });
- },
- _initHandlers: function () {
- this._verticesHandlers = [];
- for (var i = 0; i < this.latlngs.length; i++) {
- this._verticesHandlers.push(new L.Edit.PolyVerticesEdit(this._poly, this.latlngs[i], this._poly.options.poly));
- }
- },
- _updateLatLngs: function (e) {
- this.latlngs = [e.layer._latlngs];
- if (e.layer._holes) {
- this.latlngs = this.latlngs.concat(e.layer._holes);
- }
- }
- });
- /**
- * @class L.Edit.PolyVerticesEdit
- * @aka Edit.PolyVerticesEdit
- */
- L.Edit.PolyVerticesEdit = L.Handler.extend({
- options: {
- icon: new L.DivIcon({
- iconSize: new L.Point(8, 8),
- className: 'leaflet-div-icon leaflet-editing-icon'
- }),
- touchIcon: new L.DivIcon({
- iconSize: new L.Point(20, 20),
- className: 'leaflet-div-icon leaflet-editing-icon leaflet-touch-icon'
- }),
- drawError: {
- color: '#b00b00',
- timeout: 1000
- }
- },
- // @method intialize(): void
- initialize: function (poly, latlngs, options) {
- // if touch, switch to touch icon
- if (L.Browser.touch) {
- this.options.icon = this.options.touchIcon;
- }
- this._poly = poly;
- if (options && options.drawError) {
- options.drawError = L.Util.extend({}, this.options.drawError, options.drawError);
- }
- this._latlngs = latlngs;
- L.setOptions(this, options);
- },
- // Compatibility method to normalize Poly* objects
- // between 0.7.x and 1.0+
- _defaultShape: function () {
- if (!L.Polyline._flat) {
- return this._latlngs;
- }
- return L.Polyline._flat(this._latlngs) ? this._latlngs : this._latlngs[0];
- },
- // @method addHooks(): void
- // Add listener hooks to this handler.
- addHooks: function () {
- var poly = this._poly;
- var path = poly._path;
- if (!(poly instanceof L.Polygon)) {
- poly.options.fill = false;
- if (poly.options.editing) {
- poly.options.editing.fill = false;
- }
- }
- if (path) {
- if (poly.options.editing.className) {
- if (poly.options.original.className) {
- poly.options.original.className.split(' ').forEach(function (className) {
- L.DomUtil.removeClass(path, className);
- });
- }
- poly.options.editing.className.split(' ').forEach(function (className) {
- L.DomUtil.addClass(path, className);
- });
- }
- }
- poly.setStyle(poly.options.editing);
- if (this._poly._map) {
- this._map = this._poly._map; // Set map
- if (!this._markerGroup) {
- this._initMarkers();
- }
- this._poly._map.addLayer(this._markerGroup);
- }
- },
- // @method removeHooks(): void
- // Remove listener hooks from this handler.
- removeHooks: function () {
- var poly = this._poly;
- var path = poly._path;
- if (path) {
- if (poly.options.editing.className) {
- poly.options.editing.className.split(' ').forEach(function (className) {
- L.DomUtil.removeClass(path, className);
- });
- if (poly.options.original.className) {
- poly.options.original.className.split(' ').forEach(function (className) {
- L.DomUtil.addClass(path, className);
- });
- }
- }
- }
- poly.setStyle(poly.options.original);
- if (poly._map) {
- poly._map.removeLayer(this._markerGroup);
- delete this._markerGroup;
- delete this._markers;
- }
- },
- // @method updateMarkers(): void
- // Clear markers and update their location
- updateMarkers: function () {
- this._markerGroup.clearLayers();
- this._initMarkers();
- },
- _initMarkers: function () {
- if (!this._markerGroup) {
- this._markerGroup = new L.LayerGroup();
- }
- this._markers = [];
- var latlngs = this._defaultShape(),
- i, j, len, marker;
- for (i = 0, len = latlngs.length; i < len; i++) {
- marker = this._createMarker(latlngs[i], i);
- marker.on('click', this._onMarkerClick, this);
- marker.on('contextmenu', this._onContextMenu, this);
- this._markers.push(marker);
- }
- var markerLeft, markerRight;
- for (i = 0, j = len - 1; i < len; j = i++) {
- if (i === 0 && !(L.Polygon && (this._poly instanceof L.Polygon))) {
- continue;
- }
- markerLeft = this._markers[j];
- markerRight = this._markers[i];
- this._createMiddleMarker(markerLeft, markerRight);
- this._updatePrevNext(markerLeft, markerRight);
- }
- },
- _createMarker: function (latlng, index) {
- // Extending L.Marker in TouchEvents.js to include touch.
- var marker = new L.Marker.Touch(latlng, {
- draggable: true,
- icon: this.options.icon,
- });
- marker._origLatLng = latlng;
- marker._index = index;
- marker
- .on('dragstart', this._onMarkerDragStart, this)
- .on('drag', this._onMarkerDrag, this)
- .on('dragend', this._fireEdit, this)
- .on('touchmove', this._onTouchMove, this)
- .on('touchend', this._fireEdit, this)
- .on('MSPointerMove', this._onTouchMove, this)
- .on('MSPointerUp', this._fireEdit, this);
- this._markerGroup.addLayer(marker);
- return marker;
- },
- _onMarkerDragStart: function () {
- this._poly.fire('editstart');
- },
- _spliceLatLngs: function () {
- var latlngs = this._defaultShape();
- var removed = [].splice.apply(latlngs, arguments);
- this._poly._convertLatLngs(latlngs, true);
- this._poly.redraw();
- return removed;
- },
- _removeMarker: function (marker) {
- var i = marker._index;
- this._markerGroup.removeLayer(marker);
- this._markers.splice(i, 1);
- this._spliceLatLngs(i, 1);
- this._updateIndexes(i, -1);
- marker
- .off('dragstart', this._onMarkerDragStart, this)
- .off('drag', this._onMarkerDrag, this)
- .off('dragend', this._fireEdit, this)
- .off('touchmove', this._onMarkerDrag, this)
- .off('touchend', this._fireEdit, this)
- .off('click', this._onMarkerClick, this)
- .off('MSPointerMove', this._onTouchMove, this)
- .off('MSPointerUp', this._fireEdit, this);
- },
- _fireEdit: function () {
- this._poly.edited = true;
- this._poly.fire('edit');
- this._poly._map.fire(L.Draw.Event.EDITVERTEX, {layers: this._markerGroup, poly: this._poly});
- },
- _onMarkerDrag: function (e) {
- var marker = e.target;
- var poly = this._poly;
- L.extend(marker._origLatLng, marker._latlng);
- if (marker._middleLeft) {
- marker._middleLeft.setLatLng(this._getMiddleLatLng(marker._prev, marker));
- }
- if (marker._middleRight) {
- marker._middleRight.setLatLng(this._getMiddleLatLng(marker, marker._next));
- }
- if (poly.options.poly) {
- var tooltip = poly._map._editTooltip; // Access the tooltip
- // If we don't allow intersections and the polygon intersects
- if (!poly.options.poly.allowIntersection && poly.intersects()) {
- var originalColor = poly.options.color;
- poly.setStyle({color: this.options.drawError.color});
- // Manually trigger 'dragend' behavior on marker we are about to remove
- // WORKAROUND: introduced in 1.0.0-rc2, may be related to #4484
- if (L.version.indexOf('0.7') !== 0) {
- marker.dragging._draggable._onUp(e);
- }
- this._onMarkerClick(e); // Remove violating marker
- // FIXME: Reset the marker to it's original position (instead of remove)
- if (tooltip) {
- tooltip.updateContent({
- text: L.drawLocal.draw.handlers.polyline.error
- });
- }
- // Reset everything back to normal after a second
- setTimeout(function () {
- poly.setStyle({color: originalColor});
- if (tooltip) {
- tooltip.updateContent({
- text: L.drawLocal.edit.handlers.edit.tooltip.text,
- subtext: L.drawLocal.edit.handlers.edit.tooltip.subtext
- });
- }
- }, 1000);
- }
- }
- //refresh the bounds when draging
- this._poly._bounds._southWest = L.latLng(Infinity, Infinity);
- this._poly._bounds._northEast = L.latLng(-Infinity, -Infinity);
- var latlngs = this._poly.getLatLngs();
- this._poly._convertLatLngs(latlngs, true);
- this._poly.redraw();
- this._poly.fire('editdrag');
- },
- _onMarkerClick: function (e) {
- var minPoints = L.Polygon && (this._poly instanceof L.Polygon) ? 4 : 3,
- marker = e.target;
- // If removing this point would create an invalid polyline/polygon don't remove
- if (this._defaultShape().length < minPoints) {
- return;
- }
- // remove the marker
- this._removeMarker(marker);
- // update prev/next links of adjacent markers
- this._updatePrevNext(marker._prev, marker._next);
- // remove ghost markers near the removed marker
- if (marker._middleLeft) {
- this._markerGroup.removeLayer(marker._middleLeft);
- }
- if (marker._middleRight) {
- this._markerGroup.removeLayer(marker._middleRight);
- }
- // create a ghost marker in place of the removed one
- if (marker._prev && marker._next) {
- this._createMiddleMarker(marker._prev, marker._next);
- } else if (!marker._prev) {
- marker._next._middleLeft = null;
- } else if (!marker._next) {
- marker._prev._middleRight = null;
- }
- this._fireEdit();
- },
- _onContextMenu: function (e) {
- var marker = e.target;
- var poly = this._poly;
- this._poly._map.fire(L.Draw.Event.MARKERCONTEXT, {
- marker: marker,
- layers: this._markerGroup,
- poly: this._poly
- });
- L.DomEvent.stopPropagation;
- },
- _onTouchMove: function (e) {
- var layerPoint = this._map.mouseEventToLayerPoint(e.originalEvent.touches[0]),
- latlng = this._map.layerPointToLatLng(layerPoint),
- marker = e.target;
- L.extend(marker._origLatLng, latlng);
- if (marker._middleLeft) {
- marker._middleLeft.setLatLng(this._getMiddleLatLng(marker._prev, marker));
- }
- if (marker._middleRight) {
- marker._middleRight.setLatLng(this._getMiddleLatLng(marker, marker._next));
- }
- this._poly.redraw();
- this.updateMarkers();
- },
- _updateIndexes: function (index, delta) {
- this._markerGroup.eachLayer(function (marker) {
- if (marker._index > index) {
- marker._index += delta;
- }
- });
- },
- _createMiddleMarker: function (marker1, marker2) {
- var latlng = this._getMiddleLatLng(marker1, marker2),
- marker = this._createMarker(latlng),
- onClick,
- onDragStart,
- onDragEnd;
- marker.setOpacity(0.6);
- marker1._middleRight = marker2._middleLeft = marker;
- onDragStart = function () {
- marker.off('touchmove', onDragStart, this);
- var i = marker2._index;
- marker._index = i;
- marker
- .off('click', onClick, this)
- .on('click', this._onMarkerClick, this);
- latlng.lat = marker.getLatLng().lat;
- latlng.lng = marker.getLatLng().lng;
- this._spliceLatLngs(i, 0, latlng);
- this._markers.splice(i, 0, marker);
- marker.setOpacity(1);
- this._updateIndexes(i, 1);
- marker2._index++;
- this._updatePrevNext(marker1, marker);
- this._updatePrevNext(marker, marker2);
- this._poly.fire('editstart');
- };
- onDragEnd = function () {
- marker.off('dragstart', onDragStart, this);
- marker.off('dragend', onDragEnd, this);
- marker.off('touchmove', onDragStart, this);
- this._createMiddleMarker(marker1, marker);
- this._createMiddleMarker(marker, marker2);
- };
- onClick = function () {
- onDragStart.call(this);
- onDragEnd.call(this);
- this._fireEdit();
- };
- marker
- .on('click', onClick, this)
- .on('dragstart', onDragStart, this)
- .on('dragend', onDragEnd, this)
- .on('touchmove', onDragStart, this);
- this._markerGroup.addLayer(marker);
- },
- _updatePrevNext: function (marker1, marker2) {
- if (marker1) {
- marker1._next = marker2;
- }
- if (marker2) {
- marker2._prev = marker1;
- }
- },
- _getMiddleLatLng: function (marker1, marker2) {
- var map = this._poly._map,
- p1 = map.project(marker1.getLatLng()),
- p2 = map.project(marker2.getLatLng());
- return map.unproject(p1._add(p2)._divideBy(2));
- }
- });
- L.Polyline.addInitHook(function () {
- // Check to see if handler has already been initialized. This is to support versions of Leaflet that still have L.Handler.PolyEdit
- if (this.editing) {
- return;
- }
- if (L.Edit.Poly) {
- this.editing = new L.Edit.Poly(this);
- if (this.options.editable) {
- this.editing.enable();
- }
- }
- this.on('add', function () {
- if (this.editing && this.editing.enabled()) {
- this.editing.addHooks();
- }
- });
- this.on('remove', function () {
- if (this.editing && this.editing.enabled()) {
- this.editing.removeHooks();
- }
- });
- });
- L.Edit = L.Edit || {};
- /**
- * @class L.Edit.SimpleShape
- * @aka Edit.SimpleShape
- */
- L.Edit.SimpleShape = L.Handler.extend({
- options: {
- moveIcon: new L.DivIcon({
- iconSize: new L.Point(8, 8),
- className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-move'
- }),
- resizeIcon: new L.DivIcon({
- iconSize: new L.Point(8, 8),
- className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-resize'
- }),
- touchMoveIcon: new L.DivIcon({
- iconSize: new L.Point(20, 20),
- className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-move leaflet-touch-icon'
- }),
- touchResizeIcon: new L.DivIcon({
- iconSize: new L.Point(20, 20),
- className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-resize leaflet-touch-icon'
- }),
- },
- // @method intialize(): void
- initialize: function (shape, options) {
- // if touch, switch to touch icon
- if (L.Browser.touch) {
- this.options.moveIcon = this.options.touchMoveIcon;
- this.options.resizeIcon = this.options.touchResizeIcon;
- }
- this._shape = shape;
- L.Util.setOptions(this, options);
- },
- // @method addHooks(): void
- // Add listener hooks to this handler
- addHooks: function () {
- var shape = this._shape;
- if (this._shape._map) {
- this._map = this._shape._map;
- shape.setStyle(shape.options.editing);
- if (shape._map) {
- this._map = shape._map;
- if (!this._markerGroup) {
- this._initMarkers();
- }
- this._map.addLayer(this._markerGroup);
- }
- }
- },
- // @method removeHooks(): void
- // Remove listener hooks from this handler
- removeHooks: function () {
- var shape = this._shape;
- shape.setStyle(shape.options.original);
- if (shape._map) {
- this._unbindMarker(this._moveMarker);
- for (var i = 0, l = this._resizeMarkers.length; i < l; i++) {
- this._unbindMarker(this._resizeMarkers[i]);
- }
- this._resizeMarkers = null;
- this._map.removeLayer(this._markerGroup);
- delete this._markerGroup;
- }
- this._map = null;
- },
- // @method updateMarkers(): void
- // Remove the edit markers from this layer
- updateMarkers: function () {
- this._markerGroup.clearLayers();
- this._initMarkers();
- },
- _initMarkers: function () {
- if (!this._markerGroup) {
- this._markerGroup = new L.LayerGroup();
- }
- // Create center marker
- this._createMoveMarker();
- // Create edge marker
- this._createResizeMarker();
- },
- _createMoveMarker: function () {
- // Children override
- },
- _createResizeMarker: function () {
- // Children override
- },
- _createMarker: function (latlng, icon) {
- // Extending L.Marker in TouchEvents.js to include touch.
- var marker = new L.Marker.Touch(latlng, {
- draggable: true,
- icon: icon,
- zIndexOffset: 10
- });
- this._bindMarker(marker);
- this._markerGroup.addLayer(marker);
- return marker;
- },
- _bindMarker: function (marker) {
- marker
- .on('dragstart', this._onMarkerDragStart, this)
- .on('drag', this._onMarkerDrag, this)
- .on('dragend', this._onMarkerDragEnd, this)
- .on('touchstart', this._onTouchStart, this)
- .on('touchmove', this._onTouchMove, this)
- .on('MSPointerMove', this._onTouchMove, this)
- .on('touchend', this._onTouchEnd, this)
- .on('MSPointerUp', this._onTouchEnd, this);
- },
- _unbindMarker: function (marker) {
- marker
- .off('dragstart', this._onMarkerDragStart, this)
- .off('drag', this._onMarkerDrag, this)
- .off('dragend', this._onMarkerDragEnd, this)
- .off('touchstart', this._onTouchStart, this)
- .off('touchmove', this._onTouchMove, this)
- .off('MSPointerMove', this._onTouchMove, this)
- .off('touchend', this._onTouchEnd, this)
- .off('MSPointerUp', this._onTouchEnd, this);
- },
- _onMarkerDragStart: function (e) {
- var marker = e.target;
- marker.setOpacity(0);
- this._shape.fire('editstart');
- },
- _fireEdit: function () {
- this._shape.edited = true;
- this._shape.fire('edit');
- },
- _onMarkerDrag: function (e) {
- var marker = e.target,
- latlng = marker.getLatLng();
- if (marker === this._moveMarker) {
- this._move(latlng);
- } else {
- this._resize(latlng);
- }
- this._shape.redraw();
- this._shape.fire('editdrag');
- },
- _onMarkerDragEnd: function (e) {
- var marker = e.target;
- marker.setOpacity(1);
- this._fireEdit();
- },
- _onTouchStart: function (e) {
- L.Edit.SimpleShape.prototype._onMarkerDragStart.call(this, e);
- if (typeof (this._getCorners) === 'function') {
- // Save a reference to the opposite point
- var corners = this._getCorners(),
- marker = e.target,
- currentCornerIndex = marker._cornerIndex;
- marker.setOpacity(0);
- // Copyed from Edit.Rectangle.js line 23 _onMarkerDragStart()
- // Latlng is null otherwise.
- this._oppositeCorner = corners[(currentCornerIndex + 2) % 4];
- this._toggleCornerMarkers(0, currentCornerIndex);
- }
- this._shape.fire('editstart');
- },
- _onTouchMove: function (e) {
- var layerPoint = this._map.mouseEventToLayerPoint(e.originalEvent.touches[0]),
- latlng = this._map.layerPointToLatLng(layerPoint),
- marker = e.target;
- if (marker === this._moveMarker) {
- this._move(latlng);
- } else {
- this._resize(latlng);
- }
- this._shape.redraw();
- // prevent touchcancel in IOS
- // e.preventDefault();
- return false;
- },
- _onTouchEnd: function (e) {
- var marker = e.target;
- marker.setOpacity(1);
- this.updateMarkers();
- this._fireEdit();
- },
- _move: function () {
- // Children override
- },
- _resize: function () {
- // Children override
- }
- });
- L.Edit = L.Edit || {};
- /**
- * @class L.Edit.Rectangle
- * @aka Edit.Rectangle
- * @inherits L.Edit.SimpleShape
- */
- L.Edit.Rectangle = L.Edit.SimpleShape.extend({
- _createMoveMarker: function () {
- var bounds = this._shape.getBounds(),
- center = bounds.getCenter();
- this._moveMarker = this._createMarker(center, this.options.moveIcon);
- },
- _createResizeMarker: function () {
- var corners = this._getCorners();
- this._resizeMarkers = [];
- for (var i = 0, l = corners.length; i < l; i++) {
- this._resizeMarkers.push(this._createMarker(corners[i], this.options.resizeIcon));
- // Monkey in the corner index as we will need to know this for dragging
- this._resizeMarkers[i]._cornerIndex = i;
- }
- },
- _onMarkerDragStart: function (e) {
- L.Edit.SimpleShape.prototype._onMarkerDragStart.call(this, e);
- // Save a reference to the opposite point
- var corners = this._getCorners(),
- marker = e.target,
- currentCornerIndex = marker._cornerIndex;
- this._oppositeCorner = corners[(currentCornerIndex + 2) % 4];
- this._toggleCornerMarkers(0, currentCornerIndex);
- },
- _onMarkerDragEnd: function (e) {
- var marker = e.target,
- bounds, center;
- // Reset move marker position to the center
- if (marker === this._moveMarker) {
- bounds = this._shape.getBounds();
- center = bounds.getCenter();
- marker.setLatLng(center);
- }
- this._toggleCornerMarkers(1);
- this._repositionCornerMarkers();
- L.Edit.SimpleShape.prototype._onMarkerDragEnd.call(this, e);
- },
- _move: function (newCenter) {
- var latlngs = this._shape._defaultShape ? this._shape._defaultShape() : this._shape.getLatLngs(),
- bounds = this._shape.getBounds(),
- center = bounds.getCenter(),
- offset, newLatLngs = [];
- // Offset the latlngs to the new center
- for (var i = 0, l = latlngs.length; i < l; i++) {
- offset = [latlngs[i].lat - center.lat, latlngs[i].lng - center.lng];
- newLatLngs.push([newCenter.lat + offset[0], newCenter.lng + offset[1]]);
- }
- this._shape.setLatLngs(newLatLngs);
- // Reposition the resize markers
- this._repositionCornerMarkers();
- this._map.fire(L.Draw.Event.EDITMOVE, {layer: this._shape});
- },
- _resize: function (latlng) {
- var bounds;
- // Update the shape based on the current position of this corner and the opposite point
- this._shape.setBounds(L.latLngBounds(latlng, this._oppositeCorner));
- // Reposition the move marker
- bounds = this._shape.getBounds();
- this._moveMarker.setLatLng(bounds.getCenter());
- this._map.fire(L.Draw.Event.EDITRESIZE, {layer: this._shape});
- },
- _getCorners: function () {
- var bounds = this._shape.getBounds(),
- nw = bounds.getNorthWest(),
- ne = bounds.getNorthEast(),
- se = bounds.getSouthEast(),
- sw = bounds.getSouthWest();
- return [nw, ne, se, sw];
- },
- _toggleCornerMarkers: function (opacity) {
- for (var i = 0, l = this._resizeMarkers.length; i < l; i++) {
- this._resizeMarkers[i].setOpacity(opacity);
- }
- },
- _repositionCornerMarkers: function () {
- var corners = this._getCorners();
- for (var i = 0, l = this._resizeMarkers.length; i < l; i++) {
- this._resizeMarkers[i].setLatLng(corners[i]);
- }
- }
- });
- L.Rectangle.addInitHook(function () {
- if (L.Edit.Rectangle) {
- this.editing = new L.Edit.Rectangle(this);
- if (this.options.editable) {
- this.editing.enable();
- }
- }
- });
- L.Edit = L.Edit || {};
- /**
- * @class L.Edit.CircleMarker
- * @aka Edit.Circle
- * @inherits L.Edit.SimpleShape
- */
- L.Edit.CircleMarker = L.Edit.SimpleShape.extend({
- _createMoveMarker: function () {
- var center = this._shape.getLatLng();
- this._moveMarker = this._createMarker(center, this.options.moveIcon);
- },
- _createResizeMarker: function () {
- // To avoid an undefined check in L.Edit.SimpleShape.removeHooks
- this._resizeMarkers = [];
- },
- _move: function (latlng) {
- if (this._resizeMarkers.length) {
- var resizemarkerPoint = this._getResizeMarkerPoint(latlng);
- // Move the resize marker
- this._resizeMarkers[0].setLatLng(resizemarkerPoint);
- }
- // Move the circle
- this._shape.setLatLng(latlng);
- this._map.fire(L.Draw.Event.EDITMOVE, {layer: this._shape});
- },
- });
- L.CircleMarker.addInitHook(function () {
- if (L.Edit.CircleMarker) {
- this.editing = new L.Edit.CircleMarker(this);
- if (this.options.editable) {
- this.editing.enable();
- }
- }
- this.on('add', function () {
- if (this.editing && this.editing.enabled()) {
- this.editing.addHooks();
- }
- });
- this.on('remove', function () {
- if (this.editing && this.editing.enabled()) {
- this.editing.removeHooks();
- }
- });
- });
- L.Edit = L.Edit || {};
- /**
- * @class L.Edit.Circle
- * @aka Edit.Circle
- * @inherits L.Edit.CircleMarker
- */
- L.Edit.Circle = L.Edit.CircleMarker.extend({
- _createResizeMarker: function () {
- var center = this._shape.getLatLng(),
- resizemarkerPoint = this._getResizeMarkerPoint(center);
- this._resizeMarkers = [];
- this._resizeMarkers.push(this._createMarker(resizemarkerPoint, this.options.resizeIcon));
- },
- _getResizeMarkerPoint: function (latlng) {
- // From L.shape.getBounds()
- var delta = this._shape._radius * Math.cos(Math.PI / 4),
- point = this._map.project(latlng);
- return this._map.unproject([point.x + delta, point.y - delta]);
- },
- _resize: function (latlng) {
- var moveLatLng = this._moveMarker.getLatLng();
- // Calculate the radius based on the version
- if (L.GeometryUtil.isVersion07x()) {
- radius = moveLatLng.distanceTo(latlng);
- } else {
- radius = this._map.distance(moveLatLng, latlng);
- }
- this._shape.setRadius(radius);
- this._map._editTooltip.updateContent({
- text: L.drawLocal.edit.handlers.edit.tooltip.subtext + '<br />' + L.drawLocal.edit.handlers.edit.tooltip.text,
- subtext: L.drawLocal.draw.handlers.circle.radius + ': ' +
- L.GeometryUtil.readableDistance(radius, true, this.options.feet, this.options.nautic)
- });
- this._shape.setRadius(radius);
- this._map.fire(L.Draw.Event.EDITRESIZE, {layer: this._shape});
- }
- });
- L.Circle.addInitHook(function () {
- if (L.Edit.Circle) {
- this.editing = new L.Edit.Circle(this);
- if (this.options.editable) {
- this.editing.enable();
- }
- }
- this.on('add', function () {
- if (this.editing && this.editing.enabled()) {
- this.editing.addHooks();
- }
- });
- this.on('remove', function () {
- if (this.editing && this.editing.enabled()) {
- this.editing.removeHooks();
- }
- });
- });
- L.Map.mergeOptions({
- touchExtend: true
- });
- /**
- * @class L.Map.TouchExtend
- * @aka TouchExtend
- */
- L.Map.TouchExtend = L.Handler.extend({
- // @method initialize(): void
- // Sets TouchExtend private accessor variables
- initialize: function (map) {
- this._map = map;
- this._container = map._container;
- this._pane = map._panes.overlayPane;
- },
- // @method addHooks(): void
- // Adds dom listener events to the map container
- addHooks: function () {
- L.DomEvent.on(this._container, 'touchstart', this._onTouchStart, this);
- L.DomEvent.on(this._container, 'touchend', this._onTouchEnd, this);
- L.DomEvent.on(this._container, 'touchmove', this._onTouchMove, this);
- if (this._detectIE()) {
- L.DomEvent.on(this._container, 'MSPointerDown', this._onTouchStart, this);
- L.DomEvent.on(this._container, 'MSPointerUp', this._onTouchEnd, this);
- L.DomEvent.on(this._container, 'MSPointerMove', this._onTouchMove, this);
- L.DomEvent.on(this._container, 'MSPointerCancel', this._onTouchCancel, this);
- } else {
- L.DomEvent.on(this._container, 'touchcancel', this._onTouchCancel, this);
- L.DomEvent.on(this._container, 'touchleave', this._onTouchLeave, this);
- }
- },
- // @method removeHooks(): void
- // Removes dom listener events from the map container
- removeHooks: function () {
- L.DomEvent.off(this._container, 'touchstart', this._onTouchStart);
- L.DomEvent.off(this._container, 'touchend', this._onTouchEnd);
- L.DomEvent.off(this._container, 'touchmove', this._onTouchMove);
- if (this._detectIE()) {
- L.DomEvent.off(this._container, 'MSPointerDowm', this._onTouchStart);
- L.DomEvent.off(this._container, 'MSPointerUp', this._onTouchEnd);
- L.DomEvent.off(this._container, 'MSPointerMove', this._onTouchMove);
- L.DomEvent.off(this._container, 'MSPointerCancel', this._onTouchCancel);
- } else {
- L.DomEvent.off(this._container, 'touchcancel', this._onTouchCancel);
- L.DomEvent.off(this._container, 'touchleave', this._onTouchLeave);
- }
- },
- _touchEvent: function (e, type) {
- // #TODO: fix the pageX error that is do a bug in Android where a single touch triggers two click events
- // _filterClick is what leaflet uses as a workaround.
- // This is a problem with more things than just android. Another problem is touchEnd has no touches in
- // its touch list.
- var touchEvent = {};
- if (typeof e.touches !== 'undefined') {
- if (!e.touches.length) {
- return;
- }
- touchEvent = e.touches[0];
- } else if (e.pointerType === 'touch') {
- touchEvent = e;
- if (!this._filterClick(e)) {
- return;
- }
- } else {
- return;
- }
- var containerPoint = this._map.mouseEventToContainerPoint(touchEvent),
- layerPoint = this._map.mouseEventToLayerPoint(touchEvent),
- latlng = this._map.layerPointToLatLng(layerPoint);
- this._map.fire(type, {
- latlng: latlng,
- layerPoint: layerPoint,
- containerPoint: containerPoint,
- pageX: touchEvent.pageX,
- pageY: touchEvent.pageY,
- originalEvent: e
- });
- },
- /** Borrowed from Leaflet and modified for bool ops **/
- _filterClick: function (e) {
- var timeStamp = (e.timeStamp || e.originalEvent.timeStamp),
- elapsed = L.DomEvent._lastClick && (timeStamp - L.DomEvent._lastClick);
- // are they closer together than 500ms yet more than 100ms?
- // Android typically triggers them ~300ms apart while multiple listeners
- // on the same event should be triggered far faster;
- // or check if click is simulated on the element, and if it is, reject any non-simulated events
- if ((elapsed && elapsed > 100 && elapsed < 500) || (e.target._simulatedClick && !e._simulated)) {
- L.DomEvent.stop(e);
- return false;
- }
- L.DomEvent._lastClick = timeStamp;
- return true;
- },
- _onTouchStart: function (e) {
- if (!this._map._loaded) {
- return;
- }
- var type = 'touchstart';
- this._touchEvent(e, type);
- },
- _onTouchEnd: function (e) {
- if (!this._map._loaded) {
- return;
- }
- var type = 'touchend';
- this._touchEvent(e, type);
- },
- _onTouchCancel: function (e) {
- if (!this._map._loaded) {
- return;
- }
- var type = 'touchcancel';
- if (this._detectIE()) {
- type = 'pointercancel';
- }
- this._touchEvent(e, type);
- },
- _onTouchLeave: function (e) {
- if (!this._map._loaded) {
- return;
- }
- var type = 'touchleave';
- this._touchEvent(e, type);
- },
- _onTouchMove: function (e) {
- if (!this._map._loaded) {
- return;
- }
- var type = 'touchmove';
- this._touchEvent(e, type);
- },
- _detectIE: function () {
- var ua = window.navigator.userAgent;
- var msie = ua.indexOf('MSIE ');
- if (msie > 0) {
- // IE 10 or older => return version number
- return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
- }
- var trident = ua.indexOf('Trident/');
- if (trident > 0) {
- // IE 11 => return version number
- var rv = ua.indexOf('rv:');
- return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
- }
- var edge = ua.indexOf('Edge/');
- if (edge > 0) {
- // IE 12 => return version number
- return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
- }
- // other browser
- return false;
- }
- });
- L.Map.addInitHook('addHandler', 'touchExtend', L.Map.TouchExtend);
- /**
- * @class L.Marker.Touch
- * @aka Marker.Touch
- *
- * This isn't full Touch support. This is just to get markers to also support dom touch events after creation
- * #TODO: find a better way of getting markers to support touch.
- */
- L.Marker.Touch = L.Marker.extend({
- _initInteraction: function () {
- if (!this.addInteractiveTarget) {
- // 0.7.x support
- return this._initInteractionLegacy();
- }
- // TODO this may need be updated to re-add touch events for 1.0+
- return L.Marker.prototype._initInteraction.apply(this);
- },
- // This is an exact copy of https://github.com/Leaflet/Leaflet/blob/v0.7/src/layer/marker/Marker.js
- // with the addition of the touch events
- _initInteractionLegacy: function () {
- if (!this.options.clickable) {
- return;
- }
- // TODO refactor into something shared with Map/Path/etc. to DRY it up
- var icon = this._icon,
- events = ['dblclick',
- 'mousedown',
- 'mouseover',
- 'mouseout',
- 'contextmenu',
- 'touchstart',
- 'touchend',
- 'touchmove'];
- if (this._detectIE) {
- events.concat(['MSPointerDown',
- 'MSPointerUp',
- 'MSPointerMove',
- 'MSPointerCancel']);
- } else {
- events.concat(['touchcancel']);
- }
- L.DomUtil.addClass(icon, 'leaflet-clickable');
- L.DomEvent.on(icon, 'click', this._onMouseClick, this);
- L.DomEvent.on(icon, 'keypress', this._onKeyPress, this);
- for (var i = 0; i < events.length; i++) {
- L.DomEvent.on(icon, events[i], this._fireMouseEvent, this);
- }
- if (L.Handler.MarkerDrag) {
- this.dragging = new L.Handler.MarkerDrag(this);
- if (this.options.draggable) {
- this.dragging.enable();
- }
- }
- },
- _detectIE: function () {
- var ua = window.navigator.userAgent;
- var msie = ua.indexOf('MSIE ');
- if (msie > 0) {
- // IE 10 or older => return version number
- return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
- }
- var trident = ua.indexOf('Trident/');
- if (trident > 0) {
- // IE 11 => return version number
- var rv = ua.indexOf('rv:');
- return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
- }
- var edge = ua.indexOf('Edge/');
- if (edge > 0) {
- // IE 12 => return version number
- return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
- }
- // other browser
- return false;
- }
- });
- /**
- * @class L.LatLngUtil
- * @aka LatLngUtil
- */
- L.LatLngUtil = {
- // Clones a LatLngs[], returns [][]
- // @method cloneLatLngs(LatLngs[]): L.LatLngs[]
- // Clone the latLng point or points or nested points and return an array with those points
- cloneLatLngs: function (latlngs) {
- var clone = [];
- for (var i = 0, l = latlngs.length; i < l; i++) {
- // Check for nested array (Polyline/Polygon)
- if (Array.isArray(latlngs[i])) {
- clone.push(L.LatLngUtil.cloneLatLngs(latlngs[i]));
- } else {
- clone.push(this.cloneLatLng(latlngs[i]));
- }
- }
- return clone;
- },
- // @method cloneLatLng(LatLng): L.LatLng
- // Clone the latLng and return a new LatLng object.
- cloneLatLng: function (latlng) {
- return L.latLng(latlng.lat, latlng.lng);
- }
- };
- (function () {
- var defaultPrecision = {
- km: 2,
- ha: 2,
- m: 0,
- mi: 2,
- ac: 2,
- yd: 0,
- ft: 0,
- nm: 2
- };
- /**
- * @class L.GeometryUtil
- * @aka GeometryUtil
- */
- L.GeometryUtil = L.extend(L.GeometryUtil || {}, {
- // Ported from the OpenLayers implementation. See https://github.com/openlayers/openlayers/blob/master/lib/OpenLayers/Geometry/LinearRing.js#L270
- // @method geodesicArea(): number
- geodesicArea: function (latLngs) {
- var pointsCount = latLngs.length,
- area = 0.0,
- d2r = Math.PI / 180,
- p1, p2;
- if (pointsCount > 2) {
- for (var i = 0; i < pointsCount; i++) {
- p1 = latLngs[i];
- p2 = latLngs[(i + 1) % pointsCount];
- area += ((p2.lng - p1.lng) * d2r) *
- (2 + Math.sin(p1.lat * d2r) + Math.sin(p2.lat * d2r));
- }
- area = area * 6378137.0 * 6378137.0 / 2.0;
- }
- return Math.abs(area);
- },
- // @method formattedNumber(n, precision): string
- // Returns n in specified number format (if defined) and precision
- formattedNumber: function (n, precision) {
- var formatted = parseFloat(n).toFixed(precision),
- format = L.drawLocal.format && L.drawLocal.format.numeric,
- delimiters = format && format.delimiters,
- thousands = delimiters && delimiters.thousands,
- decimal = delimiters && delimiters.decimal;
- if (thousands || decimal) {
- var splitValue = formatted.split('.');
- formatted = thousands ? splitValue[0].replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1' + thousands) : splitValue[0];
- decimal = decimal || '.';
- if (splitValue.length > 1) {
- formatted = formatted + decimal + splitValue[1];
- }
- }
- return formatted;
- },
- // @method readableArea(area, isMetric, precision): string
- // Returns a readable area string in yards or metric.
- // The value will be rounded as defined by the precision option object.
- readableArea: function (area, isMetric, precision) {
- var areaStr,
- units,
- precision = L.Util.extend({}, defaultPrecision, precision);
- if (isMetric) {
- units = ['ha', 'm'];
- type = typeof isMetric;
- if (type === 'string') {
- units = [isMetric];
- } else if (type !== 'boolean') {
- units = isMetric;
- }
- if (area >= 1000000 && units.indexOf('km') !== -1) {
- areaStr = L.GeometryUtil.formattedNumber(area * 0.000001, precision['km']) + ' km²';
- } else if (area >= 10000 && units.indexOf('ha') !== -1) {
- areaStr = L.GeometryUtil.formattedNumber(area * 0.0001, precision['ha']) + ' ha';
- } else {
- areaStr = L.GeometryUtil.formattedNumber(area, precision['m']) + ' m²';
- }
- } else {
- area /= 0.836127; // Square yards in 1 meter
- if (area >= 3097600) { //3097600 square yards in 1 square mile
- areaStr = L.GeometryUtil.formattedNumber(area / 3097600, precision['mi']) + ' mi²';
- } else if (area >= 4840) { //4840 square yards in 1 acre
- areaStr = L.GeometryUtil.formattedNumber(area / 4840, precision['ac']) + ' acres';
- } else {
- areaStr = L.GeometryUtil.formattedNumber(area, precision['yd']) + ' yd²';
- }
- }
- return areaStr;
- },
- // @method readableDistance(distance, units): string
- // Converts a metric distance to one of [ feet, nauticalMile, metric or yards ] string
- //
- // @alternative
- // @method readableDistance(distance, isMetric, useFeet, isNauticalMile, precision): string
- // Converts metric distance to distance string.
- // The value will be rounded as defined by the precision option object.
- readableDistance: function (distance, isMetric, isFeet, isNauticalMile, precision) {
- var distanceStr,
- units,
- precision = L.Util.extend({}, defaultPrecision, precision);
- if (isMetric) {
- units = typeof isMetric == 'string' ? isMetric : 'metric';
- } else if (isFeet) {
- units = 'feet';
- } else if (isNauticalMile) {
- units = 'nauticalMile';
- } else {
- units = 'yards';
- }
- switch (units) {
- case 'metric':
- // show metres when distance is < 1km, then show km
- if (distance > 1000) {
- distanceStr = L.GeometryUtil.formattedNumber(distance / 1000, precision['km']) + ' km';
- } else {
- distanceStr = L.GeometryUtil.formattedNumber(distance, precision['m']) + ' m';
- }
- break;
- case 'feet':
- distance *= 1.09361 * 3;
- distanceStr = L.GeometryUtil.formattedNumber(distance, precision['ft']) + ' ft';
- break;
- case 'nauticalMile':
- distance *= 0.53996;
- distanceStr = L.GeometryUtil.formattedNumber(distance / 1000, precision['nm']) + ' nm';
- break;
- case 'yards':
- default:
- distance *= 1.09361;
- if (distance > 1760) {
- distanceStr = L.GeometryUtil.formattedNumber(distance / 1760, precision['mi']) + ' miles';
- } else {
- distanceStr = L.GeometryUtil.formattedNumber(distance, precision['yd']) + ' yd';
- }
- break;
- }
- return distanceStr;
- },
- // @method isVersion07x(): boolean
- // Returns true if the Leaflet version is 0.7.x, false otherwise.
- isVersion07x: function () {
- var version = L.version.split('.');
- //If Version is == 0.7.*
- return parseInt(version[0], 10) === 0 && parseInt(version[1], 10) === 7;
- },
- });
- })();
- /**
- * @class L.LineUtil
- * @aka Util
- * @aka L.Utils
- */
- L.Util.extend(L.LineUtil, {
- // @method segmentsIntersect(): boolean
- // Checks to see if two line segments intersect. Does not handle degenerate cases.
- // http://compgeom.cs.uiuc.edu/~jeffe/teaching/373/notes/x06-sweepline.pdf
- segmentsIntersect: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2, /*Point*/ p3) {
- return this._checkCounterclockwise(p, p2, p3) !==
- this._checkCounterclockwise(p1, p2, p3) &&
- this._checkCounterclockwise(p, p1, p2) !==
- this._checkCounterclockwise(p, p1, p3);
- },
- // check to see if points are in counterclockwise order
- _checkCounterclockwise: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2) {
- return (p2.y - p.y) * (p1.x - p.x) > (p1.y - p.y) * (p2.x - p.x);
- }
- });
- /**
- * @class L.Polyline
- * @aka Polyline
- */
- L.Polyline.include({
- // @method intersects(): boolean
- // Check to see if this polyline has any linesegments that intersect.
- // NOTE: does not support detecting intersection for degenerate cases.
- intersects: function () {
- var points = this._getProjectedPoints(),
- len = points ? points.length : 0,
- i, p, p1;
- if (this._tooFewPointsForIntersection()) {
- return false;
- }
- for (i = len - 1; i >= 3; i--) {
- p = points[i - 1];
- p1 = points[i];
- if (this._lineSegmentsIntersectsRange(p, p1, i - 2)) {
- return true;
- }
- }
- return false;
- },
- // @method newLatLngIntersects(): boolean
- // Check for intersection if new latlng was added to this polyline.
- // NOTE: does not support detecting intersection for degenerate cases.
- newLatLngIntersects: function (latlng, skipFirst) {
- // Cannot check a polyline for intersecting lats/lngs when not added to the map
- if (!this._map) {
- return false;
- }
- return this.newPointIntersects(this._map.latLngToLayerPoint(latlng), skipFirst);
- },
- // @method newPointIntersects(): boolean
- // Check for intersection if new point was added to this polyline.
- // newPoint must be a layer point.
- // NOTE: does not support detecting intersection for degenerate cases.
- newPointIntersects: function (newPoint, skipFirst) {
- var points = this._getProjectedPoints(),
- len = points ? points.length : 0,
- lastPoint = points ? points[len - 1] : null,
- // The previous previous line segment. Previous line segment doesn't need testing.
- maxIndex = len - 2;
- if (this._tooFewPointsForIntersection(1)) {
- return false;
- }
- return this._lineSegmentsIntersectsRange(lastPoint, newPoint, maxIndex, skipFirst ? 1 : 0);
- },
- // Polylines with 2 sides can only intersect in cases where points are collinear (we don't support detecting these).
- // Cannot have intersection when < 3 line segments (< 4 points)
- _tooFewPointsForIntersection: function (extraPoints) {
- var points = this._getProjectedPoints(),
- len = points ? points.length : 0;
- // Increment length by extraPoints if present
- len += extraPoints || 0;
- return !points || len <= 3;
- },
- // Checks a line segment intersections with any line segments before its predecessor.
- // Don't need to check the predecessor as will never intersect.
- _lineSegmentsIntersectsRange: function (p, p1, maxIndex, minIndex) {
- var points = this._getProjectedPoints(),
- p2, p3;
- minIndex = minIndex || 0;
- // Check all previous line segments (beside the immediately previous) for intersections
- for (var j = maxIndex; j > minIndex; j--) {
- p2 = points[j - 1];
- p3 = points[j];
- if (L.LineUtil.segmentsIntersect(p, p1, p2, p3)) {
- return true;
- }
- }
- return false;
- },
- _getProjectedPoints: function () {
- if (!this._defaultShape) {
- return this._originalPoints;
- }
- var points = [],
- _shape = this._defaultShape();
- for (var i = 0; i < _shape.length; i++) {
- points.push(this._map.latLngToLayerPoint(_shape[i]));
- }
- return points;
- }
- });
- /**
- * @class L.Polygon
- * @aka Polygon
- */
- L.Polygon.include({
- // @method intersects(): boolean
- // Checks a polygon for any intersecting line segments. Ignores holes.
- intersects: function () {
- var polylineIntersects,
- points = this._getProjectedPoints(),
- len, firstPoint, lastPoint, maxIndex;
- if (this._tooFewPointsForIntersection()) {
- return false;
- }
- polylineIntersects = L.Polyline.prototype.intersects.call(this);
- // If already found an intersection don't need to check for any more.
- if (polylineIntersects) {
- return true;
- }
- len = points.length;
- firstPoint = points[0];
- lastPoint = points[len - 1];
- maxIndex = len - 2;
- // Check the line segment between last and first point. Don't need to check the first line segment (minIndex = 1)
- return this._lineSegmentsIntersectsRange(lastPoint, firstPoint, maxIndex, 1);
- }
- });
- /**
- * @class L.Control.Draw
- * @aka L.Draw
- */
- L.Control.Draw = L.Control.extend({
- // Options
- options: {
- position: 'topleft',
- draw: {},
- edit: false
- },
- // @method initialize(): void
- // Initializes draw control, toolbars from the options
- initialize: function (options) {
- if (L.version < '0.7') {
- throw new Error('Leaflet.draw 0.2.3+ requires Leaflet 0.7.0+. Download latest from https://github.com/Leaflet/Leaflet/');
- }
- L.Control.prototype.initialize.call(this, options);
- var toolbar;
- this._toolbars = {};
- // Initialize toolbars
- if (L.DrawToolbar && this.options.draw) {
- toolbar = new L.DrawToolbar(this.options.draw);
- this._toolbars[L.DrawToolbar.TYPE] = toolbar;
- // Listen for when toolbar is enabled
- this._toolbars[L.DrawToolbar.TYPE].on('enable', this._toolbarEnabled, this);
- }
- if (L.EditToolbar && this.options.edit) {
- toolbar = new L.EditToolbar(this.options.edit);
- this._toolbars[L.EditToolbar.TYPE] = toolbar;
- // Listen for when toolbar is enabled
- this._toolbars[L.EditToolbar.TYPE].on('enable', this._toolbarEnabled, this);
- }
- L.toolbar = this; //set global var for editing the toolbar
- },
- // @method onAdd(): container
- // Adds the toolbar container to the map
- onAdd: function (map) {
- var container = L.DomUtil.create('div', 'leaflet-draw'),
- addedTopClass = false,
- topClassName = 'leaflet-draw-toolbar-top',
- toolbarContainer;
- for (var toolbarId in this._toolbars) {
- if (this._toolbars.hasOwnProperty(toolbarId)) {
- toolbarContainer = this._toolbars[toolbarId].addToolbar(map);
- if (toolbarContainer) {
- // Add class to the first toolbar to remove the margin
- if (!addedTopClass) {
- if (!L.DomUtil.hasClass(toolbarContainer, topClassName)) {
- L.DomUtil.addClass(toolbarContainer.childNodes[0], topClassName);
- }
- addedTopClass = true;
- }
- container.appendChild(toolbarContainer);
- }
- }
- }
- return container;
- },
- // @method onRemove(): void
- // Removes the toolbars from the map toolbar container
- onRemove: function () {
- for (var toolbarId in this._toolbars) {
- if (this._toolbars.hasOwnProperty(toolbarId)) {
- this._toolbars[toolbarId].removeToolbar();
- }
- }
- },
- // @method setDrawingOptions(options): void
- // Sets options to all toolbar instances
- setDrawingOptions: function (options) {
- for (var toolbarId in this._toolbars) {
- if (this._toolbars[toolbarId] instanceof L.DrawToolbar) {
- this._toolbars[toolbarId].setOptions(options);
- }
- }
- },
- _toolbarEnabled: function (e) {
- var enabledToolbar = e.target;
- for (var toolbarId in this._toolbars) {
- if (this._toolbars[toolbarId] !== enabledToolbar) {
- this._toolbars[toolbarId].disable();
- }
- }
- }
- });
- L.Map.mergeOptions({
- drawControlTooltips: true,
- drawControl: false
- });
- L.Map.addInitHook(function () {
- if (this.options.drawControl) {
- this.drawControl = new L.Control.Draw();
- this.addControl(this.drawControl);
- }
- });
- /**
- * @class L.Draw.Toolbar
- * @aka Toolbar
- *
- * The toolbar class of the API — it is used to create the ui
- * This will be depreciated
- *
- * @example
- *
- * ```js
- * var toolbar = L.Toolbar();
- * toolbar.addToolbar(map);
- * ```
- *
- * ### Disabling a toolbar
- *
- * If you do not want a particular toolbar in your app you can turn it off by setting the toolbar to false.
- *
- * ```js
- * var drawControl = new L.Control.Draw({
- * draw: false,
- * edit: {
- * featureGroup: editableLayers
- * }
- * });
- * ```
- *
- * ### Disabling a toolbar item
- *
- * If you want to turn off a particular toolbar item, set it to false. The following disables drawing polygons and
- * markers. It also turns off the ability to edit layers.
- *
- * ```js
- * var drawControl = new L.Control.Draw({
- * draw: {
- * polygon: false,
- * marker: false
- * },
- * edit: {
- * featureGroup: editableLayers,
- * edit: false
- * }
- * });
- * ```
- */
- L.Toolbar = L.Class.extend({
- // @section Methods for modifying the toolbar
- // @method initialize(options): void
- // Toolbar constructor
- initialize: function (options) {
- L.setOptions(this, options);
- this._modes = {};
- this._actionButtons = [];
- this._activeMode = null;
- var version = L.version.split('.');
- //If Version is >= 1.2.0
- if (parseInt(version[0], 10) === 1 && parseInt(version[1], 10) >= 2) {
- L.Toolbar.include(L.Evented.prototype);
- } else {
- L.Toolbar.include(L.Mixin.Events);
- }
- },
- // @method enabled(): boolean
- // Gets a true/false of whether the toolbar is enabled
- enabled: function () {
- return this._activeMode !== null;
- },
- // @method disable(): void
- // Disables the toolbar
- disable: function () {
- if (!this.enabled()) {
- return;
- }
- this._activeMode.handler.disable();
- },
- // @method addToolbar(map): L.DomUtil
- // Adds the toolbar to the map and returns the toolbar dom element
- addToolbar: function (map) {
- var container = L.DomUtil.create('div', 'leaflet-draw-section'),
- buttonIndex = 0,
- buttonClassPrefix = this._toolbarClass || '',
- modeHandlers = this.getModeHandlers(map),
- i;
- this._toolbarContainer = L.DomUtil.create('div', 'leaflet-draw-toolbar leaflet-bar');
- this._map = map;
- for (i = 0; i < modeHandlers.length; i++) {
- if (modeHandlers[i].enabled) {
- this._initModeHandler(
- modeHandlers[i].handler,
- this._toolbarContainer,
- buttonIndex++,
- buttonClassPrefix,
- modeHandlers[i].title
- );
- }
- }
- // if no buttons were added, do not add the toolbar
- if (!buttonIndex) {
- return;
- }
- // Save button index of the last button, -1 as we would have ++ after the last button
- this._lastButtonIndex = --buttonIndex;
- // Create empty actions part of the toolbar
- this._actionsContainer = L.DomUtil.create('ul', 'leaflet-draw-actions');
- // Add draw and cancel containers to the control container
- container.appendChild(this._toolbarContainer);
- container.appendChild(this._actionsContainer);
- return container;
- },
- // @method removeToolbar(): void
- // Removes the toolbar and drops the handler event listeners
- removeToolbar: function () {
- // Dispose each handler
- for (var handlerId in this._modes) {
- if (this._modes.hasOwnProperty(handlerId)) {
- // Unbind handler button
- this._disposeButton(
- this._modes[handlerId].button,
- this._modes[handlerId].handler.enable,
- this._modes[handlerId].handler
- );
- // Make sure is disabled
- this._modes[handlerId].handler.disable();
- // Unbind handler
- this._modes[handlerId].handler
- .off('enabled', this._handlerActivated, this)
- .off('disabled', this._handlerDeactivated, this);
- }
- }
- this._modes = {};
- // Dispose the actions toolbar
- for (var i = 0, l = this._actionButtons.length; i < l; i++) {
- this._disposeButton(
- this._actionButtons[i].button,
- this._actionButtons[i].callback,
- this
- );
- }
- this._actionButtons = [];
- this._actionsContainer = null;
- },
- _initModeHandler: function (handler, container, buttonIndex, classNamePredix, buttonTitle) {
- var type = handler.type;
- this._modes[type] = {};
- this._modes[type].handler = handler;
- this._modes[type].button = this._createButton({
- type: type,
- title: buttonTitle,
- className: classNamePredix + '-' + type,
- container: container,
- callback: this._modes[type].handler.enable,
- context: this._modes[type].handler
- });
- this._modes[type].buttonIndex = buttonIndex;
- this._modes[type].handler
- .on('enabled', this._handlerActivated, this)
- .on('disabled', this._handlerDeactivated, this);
- },
- /* Detect iOS based on browser User Agent, based on:
- * http://stackoverflow.com/a/9039885 */
- _detectIOS: function () {
- var iOS = (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream);
- return iOS;
- },
- _createButton: function (options) {
- var link = L.DomUtil.create('a', options.className || '', options.container);
- // Screen reader tag
- var sr = L.DomUtil.create('span', 'sr-only', options.container);
- link.href = '#';
- link.appendChild(sr);
- if (options.title) {
- link.title = options.title;
- sr.innerHTML = options.title;
- }
- if (options.text) {
- link.innerHTML = options.text;
- sr.innerHTML = options.text;
- }
- /* iOS does not use click events */
- var buttonEvent = this._detectIOS() ? 'touchstart' : 'click';
- L.DomEvent
- .on(link, 'click', L.DomEvent.stopPropagation)
- .on(link, 'mousedown', L.DomEvent.stopPropagation)
- .on(link, 'dblclick', L.DomEvent.stopPropagation)
- .on(link, 'touchstart', L.DomEvent.stopPropagation)
- .on(link, 'click', L.DomEvent.preventDefault)
- .on(link, buttonEvent, options.callback, options.context);
- return link;
- },
- _disposeButton: function (button, callback) {
- /* iOS does not use click events */
- var buttonEvent = this._detectIOS() ? 'touchstart' : 'click';
- L.DomEvent
- .off(button, 'click', L.DomEvent.stopPropagation)
- .off(button, 'mousedown', L.DomEvent.stopPropagation)
- .off(button, 'dblclick', L.DomEvent.stopPropagation)
- .off(button, 'touchstart', L.DomEvent.stopPropagation)
- .off(button, 'click', L.DomEvent.preventDefault)
- .off(button, buttonEvent, callback);
- },
- _handlerActivated: function (e) {
- // Disable active mode (if present)
- this.disable();
- // Cache new active feature
- this._activeMode = this._modes[e.handler];
- L.DomUtil.addClass(this._activeMode.button, 'leaflet-draw-toolbar-button-enabled');
- this._showActionsToolbar();
- this.fire('enable');
- },
- _handlerDeactivated: function () {
- this._hideActionsToolbar();
- L.DomUtil.removeClass(this._activeMode.button, 'leaflet-draw-toolbar-button-enabled');
- this._activeMode = null;
- this.fire('disable');
- },
- _createActions: function (handler) {
- var container = this._actionsContainer,
- buttons = this.getActions(handler),
- l = buttons.length,
- li, di, dl, button;
- // Dispose the actions toolbar (todo: dispose only not used buttons)
- for (di = 0, dl = this._actionButtons.length; di < dl; di++) {
- this._disposeButton(this._actionButtons[di].button, this._actionButtons[di].callback);
- }
- this._actionButtons = [];
- // Remove all old buttons
- while (container.firstChild) {
- container.removeChild(container.firstChild);
- }
- for (var i = 0; i < l; i++) {
- if ('enabled' in buttons[i] && !buttons[i].enabled) {
- continue;
- }
- li = L.DomUtil.create('li', '', container);
- button = this._createButton({
- title: buttons[i].title,
- text: buttons[i].text,
- container: li,
- callback: buttons[i].callback,
- context: buttons[i].context
- });
- this._actionButtons.push({
- button: button,
- callback: buttons[i].callback
- });
- }
- },
- _showActionsToolbar: function () {
- var buttonIndex = this._activeMode.buttonIndex,
- lastButtonIndex = this._lastButtonIndex,
- toolbarPosition = this._activeMode.button.offsetTop - 1;
- // Recreate action buttons on every click
- this._createActions(this._activeMode.handler);
- // Correctly position the cancel button
- this._actionsContainer.style.top = toolbarPosition + 'px';
- if (buttonIndex === 0) {
- L.DomUtil.addClass(this._toolbarContainer, 'leaflet-draw-toolbar-notop');
- L.DomUtil.addClass(this._actionsContainer, 'leaflet-draw-actions-top');
- }
- if (buttonIndex === lastButtonIndex) {
- L.DomUtil.addClass(this._toolbarContainer, 'leaflet-draw-toolbar-nobottom');
- L.DomUtil.addClass(this._actionsContainer, 'leaflet-draw-actions-bottom');
- }
- this._actionsContainer.style.display = 'block';
- this._map.fire(L.Draw.Event.TOOLBAROPENED);
- },
- _hideActionsToolbar: function () {
- this._actionsContainer.style.display = 'none';
- L.DomUtil.removeClass(this._toolbarContainer, 'leaflet-draw-toolbar-notop');
- L.DomUtil.removeClass(this._toolbarContainer, 'leaflet-draw-toolbar-nobottom');
- L.DomUtil.removeClass(this._actionsContainer, 'leaflet-draw-actions-top');
- L.DomUtil.removeClass(this._actionsContainer, 'leaflet-draw-actions-bottom');
- this._map.fire(L.Draw.Event.TOOLBARCLOSED);
- }
- });
- L.Draw = L.Draw || {};
- /**
- * @class L.Draw.Tooltip
- * @aka Tooltip
- *
- * The tooltip class — it is used to display the tooltip while drawing
- * This will be depreciated
- *
- * @example
- *
- * ```js
- * var tooltip = L.Draw.Tooltip();
- * ```
- *
- */
- L.Draw.Tooltip = L.Class.extend({
- // @section Methods for modifying draw state
- // @method initialize(map): void
- // Tooltip constructor
- initialize: function (map) {
- this._map = map;
- this._popupPane = map._panes.popupPane;
- this._visible = false;
- this._container = map.options.drawControlTooltips ?
- L.DomUtil.create('div', 'leaflet-draw-tooltip', this._popupPane) : null;
- this._singleLineLabel = false;
- this._map.on('mouseout', this._onMouseOut, this);
- },
- // @method dispose(): void
- // Remove Tooltip DOM and unbind events
- dispose: function () {
- this._map.off('mouseout', this._onMouseOut, this);
- if (this._container) {
- this._popupPane.removeChild(this._container);
- this._container = null;
- }
- },
- // @method updateContent(labelText): this
- // Changes the tooltip text to string in function call
- updateContent: function (labelText) {
- if (!this._container) {
- return this;
- }
- labelText.subtext = labelText.subtext || '';
- // update the vertical position (only if changed)
- if (labelText.subtext.length === 0 && !this._singleLineLabel) {
- L.DomUtil.addClass(this._container, 'leaflet-draw-tooltip-single');
- this._singleLineLabel = true;
- } else if (labelText.subtext.length > 0 && this._singleLineLabel) {
- L.DomUtil.removeClass(this._container, 'leaflet-draw-tooltip-single');
- this._singleLineLabel = false;
- }
- this._container.innerHTML =
- (labelText.subtext.length > 0 ?
- '<span class="leaflet-draw-tooltip-subtext">' + labelText.subtext + '</span>' + '<br />' : '') +
- '<span>' + labelText.text + '</span>';
- if (!labelText.text && !labelText.subtext) {
- this._visible = false;
- this._container.style.visibility = 'hidden';
- } else {
- this._visible = true;
- this._container.style.visibility = 'inherit';
- }
- return this;
- },
- // @method updatePosition(latlng): this
- // Changes the location of the tooltip
- updatePosition: function (latlng) {
- var pos = this._map.latLngToLayerPoint(latlng),
- tooltipContainer = this._container;
- if (this._container) {
- if (this._visible) {
- tooltipContainer.style.visibility = 'inherit';
- }
- L.DomUtil.setPosition(tooltipContainer, pos);
- }
- return this;
- },
- // @method showAsError(): this
- // Applies error class to tooltip
- showAsError: function () {
- if (this._container) {
- L.DomUtil.addClass(this._container, 'leaflet-error-draw-tooltip');
- }
- return this;
- },
- // @method removeError(): this
- // Removes the error class from the tooltip
- removeError: function () {
- if (this._container) {
- L.DomUtil.removeClass(this._container, 'leaflet-error-draw-tooltip');
- }
- return this;
- },
- _onMouseOut: function () {
- if (this._container) {
- this._container.style.visibility = 'hidden';
- }
- }
- });
- /**
- * @class L.DrawToolbar
- * @aka Toolbar
- */
- L.DrawToolbar = L.Toolbar.extend({
- statics: {
- TYPE: 'draw'
- },
- options: {
- polyline: {},
- polygon: {},
- rectangle: {},
- circle: {},
- marker: {},
- circlemarker: {}
- },
- // @method initialize(): void
- initialize: function (options) {
- // Ensure that the options are merged correctly since L.extend is only shallow
- for (var type in this.options) {
- if (this.options.hasOwnProperty(type)) {
- if (options[type]) {
- options[type] = L.extend({}, this.options[type], options[type]);
- }
- }
- }
- this._toolbarClass = 'leaflet-draw-draw';
- L.Toolbar.prototype.initialize.call(this, options);
- },
- // @method getModeHandlers(): object
- // Get mode handlers information
- getModeHandlers: function (map) {
- return [
- {
- enabled: this.options.polyline,
- handler: new L.Draw.Polyline(map, this.options.polyline),
- title: L.drawLocal.draw.toolbar.buttons.polyline
- },
- {
- enabled: this.options.polygon,
- handler: new L.Draw.Polygon(map, this.options.polygon),
- title: L.drawLocal.draw.toolbar.buttons.polygon
- },
- {
- enabled: this.options.rectangle,
- handler: new L.Draw.Rectangle(map, this.options.rectangle),
- title: L.drawLocal.draw.toolbar.buttons.rectangle
- },
- {
- enabled: this.options.circle,
- handler: new L.Draw.Circle(map, this.options.circle),
- title: L.drawLocal.draw.toolbar.buttons.circle
- },
- {
- enabled: this.options.marker,
- handler: new L.Draw.Marker(map, this.options.marker),
- title: L.drawLocal.draw.toolbar.buttons.marker
- },
- {
- enabled: this.options.circlemarker,
- handler: new L.Draw.CircleMarker(map, this.options.circlemarker),
- title: L.drawLocal.draw.toolbar.buttons.circlemarker
- }
- ];
- },
- // @method getActions(): object
- // Get action information
- getActions: function (handler) {
- return [
- {
- enabled: handler.completeShape,
- title: L.drawLocal.draw.toolbar.finish.title,
- text: L.drawLocal.draw.toolbar.finish.text,
- callback: handler.completeShape,
- context: handler
- },
- {
- enabled: handler.deleteLastVertex,
- title: L.drawLocal.draw.toolbar.undo.title,
- text: L.drawLocal.draw.toolbar.undo.text,
- callback: handler.deleteLastVertex,
- context: handler
- },
- {
- title: L.drawLocal.draw.toolbar.actions.title,
- text: L.drawLocal.draw.toolbar.actions.text,
- callback: this.disable,
- context: this
- }
- ];
- },
- // @method setOptions(): void
- // Sets the options to the toolbar
- setOptions: function (options) {
- L.setOptions(this, options);
- for (var type in this._modes) {
- if (this._modes.hasOwnProperty(type) && options.hasOwnProperty(type)) {
- this._modes[type].handler.setOptions(options[type]);
- }
- }
- }
- });
- /*L.Map.mergeOptions({
- editControl: true
- });*/
- /**
- * @class L.EditToolbar
- * @aka EditToolbar
- */
- L.EditToolbar = L.Toolbar.extend({
- statics: {
- TYPE: 'edit'
- },
- options: {
- edit: {
- selectedPathOptions: {
- dashArray: '10, 10',
- fill: true,
- fillColor: '#fe57a1',
- fillOpacity: 0.1,
- // Whether to user the existing layers color
- maintainColor: false
- }
- },
- remove: {},
- poly: null,
- featureGroup: null /* REQUIRED! TODO: perhaps if not set then all layers on the map are selectable? */
- },
- // @method intialize(): void
- initialize: function (options) {
- // Need to set this manually since null is an acceptable value here
- if (options.edit) {
- if (typeof options.edit.selectedPathOptions === 'undefined') {
- options.edit.selectedPathOptions = this.options.edit.selectedPathOptions;
- }
- options.edit.selectedPathOptions = L.extend({}, this.options.edit.selectedPathOptions, options.edit.selectedPathOptions);
- }
- if (options.remove) {
- options.remove = L.extend({}, this.options.remove, options.remove);
- }
- if (options.poly) {
- options.poly = L.extend({}, this.options.poly, options.poly);
- }
- this._toolbarClass = 'leaflet-draw-edit';
- L.Toolbar.prototype.initialize.call(this, options);
- this._selectedFeatureCount = 0;
- },
- // @method getModeHandlers(): object
- // Get mode handlers information
- getModeHandlers: function (map) {
- var featureGroup = this.options.featureGroup;
- return [
- {
- enabled: this.options.edit,
- handler: new L.EditToolbar.Edit(map, {
- featureGroup: featureGroup,
- selectedPathOptions: this.options.edit.selectedPathOptions,
- poly: this.options.poly
- }),
- title: L.drawLocal.edit.toolbar.buttons.edit
- },
- {
- enabled: this.options.remove,
- handler: new L.EditToolbar.Delete(map, {
- featureGroup: featureGroup
- }),
- title: L.drawLocal.edit.toolbar.buttons.remove
- }
- ];
- },
- // @method getActions(): object
- // Get actions information
- getActions: function (handler) {
- var actions = [
- {
- title: L.drawLocal.edit.toolbar.actions.save.title,
- text: L.drawLocal.edit.toolbar.actions.save.text,
- callback: this._save,
- context: this
- },
- {
- title: L.drawLocal.edit.toolbar.actions.cancel.title,
- text: L.drawLocal.edit.toolbar.actions.cancel.text,
- callback: this.disable,
- context: this
- }
- ];
- if (handler.removeAllLayers) {
- actions.push({
- title: L.drawLocal.edit.toolbar.actions.clearAll.title,
- text: L.drawLocal.edit.toolbar.actions.clearAll.text,
- callback: this._clearAllLayers,
- context: this
- });
- }
- return actions;
- },
- // @method addToolbar(map): L.DomUtil
- // Adds the toolbar to the map
- addToolbar: function (map) {
- var container = L.Toolbar.prototype.addToolbar.call(this, map);
- this._checkDisabled();
- this.options.featureGroup.on('layeradd layerremove', this._checkDisabled, this);
- return container;
- },
- // @method removeToolbar(): void
- // Removes the toolbar from the map
- removeToolbar: function () {
- this.options.featureGroup.off('layeradd layerremove', this._checkDisabled, this);
- L.Toolbar.prototype.removeToolbar.call(this);
- },
- // @method disable(): void
- // Disables the toolbar
- disable: function () {
- if (!this.enabled()) {
- return;
- }
- this._activeMode.handler.revertLayers();
- L.Toolbar.prototype.disable.call(this);
- },
- _save: function () {
- this._activeMode.handler.save();
- if (this._activeMode) {
- this._activeMode.handler.disable();
- }
- },
- _clearAllLayers: function () {
- this._activeMode.handler.removeAllLayers();
- if (this._activeMode) {
- this._activeMode.handler.disable();
- }
- },
- _checkDisabled: function () {
- var featureGroup = this.options.featureGroup,
- hasLayers = featureGroup.getLayers().length !== 0,
- button;
- if (this.options.edit) {
- button = this._modes[L.EditToolbar.Edit.TYPE].button;
- if (hasLayers) {
- L.DomUtil.removeClass(button, 'leaflet-disabled');
- } else {
- L.DomUtil.addClass(button, 'leaflet-disabled');
- }
- button.setAttribute(
- 'title',
- hasLayers ?
- L.drawLocal.edit.toolbar.buttons.edit
- : L.drawLocal.edit.toolbar.buttons.editDisabled
- );
- }
- if (this.options.remove) {
- button = this._modes[L.EditToolbar.Delete.TYPE].button;
- if (hasLayers) {
- L.DomUtil.removeClass(button, 'leaflet-disabled');
- } else {
- L.DomUtil.addClass(button, 'leaflet-disabled');
- }
- button.setAttribute(
- 'title',
- hasLayers ?
- L.drawLocal.edit.toolbar.buttons.remove
- : L.drawLocal.edit.toolbar.buttons.removeDisabled
- );
- }
- }
- });
- /**
- * @class L.EditToolbar.Edit
- * @aka EditToolbar.Edit
- */
- L.EditToolbar.Edit = L.Handler.extend({
- statics: {
- TYPE: 'edit'
- },
- // @method intialize(): void
- initialize: function (map, options) {
- L.Handler.prototype.initialize.call(this, map);
- L.setOptions(this, options);
- // Store the selectable layer group for ease of access
- this._featureGroup = options.featureGroup;
- if (!(this._featureGroup instanceof L.FeatureGroup)) {
- throw new Error('options.featureGroup must be a L.FeatureGroup');
- }
- this._uneditedLayerProps = {};
- // Save the type so super can fire, need to do this as cannot do this.TYPE :(
- this.type = L.EditToolbar.Edit.TYPE;
- var version = L.version.split('.');
- //If Version is >= 1.2.0
- if (parseInt(version[0], 10) === 1 && parseInt(version[1], 10) >= 2) {
- L.EditToolbar.Edit.include(L.Evented.prototype);
- } else {
- L.EditToolbar.Edit.include(L.Mixin.Events);
- }
- },
- // @method enable(): void
- // Enable the edit toolbar
- enable: function () {
- if (this._enabled || !this._hasAvailableLayers()) {
- return;
- }
- this.fire('enabled', {handler: this.type});
- //this disable other handlers
- this._map.fire(L.Draw.Event.EDITSTART, {handler: this.type});
- //allow drawLayer to be updated before beginning edition.
- L.Handler.prototype.enable.call(this);
- this._featureGroup
- .on('layeradd', this._enableLayerEdit, this)
- .on('layerremove', this._disableLayerEdit, this);
- },
- // @method disable(): void
- // Disable the edit toolbar
- disable: function () {
- if (!this._enabled) {
- return;
- }
- this._featureGroup
- .off('layeradd', this._enableLayerEdit, this)
- .off('layerremove', this._disableLayerEdit, this);
- L.Handler.prototype.disable.call(this);
- this._map.fire(L.Draw.Event.EDITSTOP, {handler: this.type});
- this.fire('disabled', {handler: this.type});
- },
- // @method addHooks(): void
- // Add listener hooks for this handler
- addHooks: function () {
- var map = this._map;
- if (map) {
- map.getContainer().focus();
- this._featureGroup.eachLayer(this._enableLayerEdit, this);
- this._tooltip = new L.Draw.Tooltip(this._map);
- this._tooltip.updateContent({
- text: L.drawLocal.edit.handlers.edit.tooltip.text,
- subtext: L.drawLocal.edit.handlers.edit.tooltip.subtext
- });
- // Quickly access the tooltip to update for intersection checking
- map._editTooltip = this._tooltip;
- this._updateTooltip();
- this._map
- .on('mousemove', this._onMouseMove, this)
- .on('touchmove', this._onMouseMove, this)
- .on('MSPointerMove', this._onMouseMove, this)
- .on(L.Draw.Event.EDITVERTEX, this._updateTooltip, this);
- }
- },
- // @method removeHooks(): void
- // Remove listener hooks for this handler
- removeHooks: function () {
- if (this._map) {
- // Clean up selected layers.
- this._featureGroup.eachLayer(this._disableLayerEdit, this);
- // Clear the backups of the original layers
- this._uneditedLayerProps = {};
- this._tooltip.dispose();
- this._tooltip = null;
- this._map
- .off('mousemove', this._onMouseMove, this)
- .off('touchmove', this._onMouseMove, this)
- .off('MSPointerMove', this._onMouseMove, this)
- .off(L.Draw.Event.EDITVERTEX, this._updateTooltip, this);
- }
- },
- // @method revertLayers(): void
- // Revert each layer's geometry changes
- revertLayers: function () {
- this._featureGroup.eachLayer(function (layer) {
- this._revertLayer(layer);
- }, this);
- },
- // @method save(): void
- // Save the layer geometries
- save: function () {
- var editedLayers = new L.LayerGroup();
- this._featureGroup.eachLayer(function (layer) {
- if (layer.edited) {
- editedLayers.addLayer(layer);
- layer.edited = false;
- }
- });
- this._map.fire(L.Draw.Event.EDITED, {layers: editedLayers});
- },
- _backupLayer: function (layer) {
- var id = L.Util.stamp(layer);
- if (!this._uneditedLayerProps[id]) {
- // Polyline, Polygon or Rectangle
- if (layer instanceof L.Polyline || layer instanceof L.Polygon || layer instanceof L.Rectangle) {
- this._uneditedLayerProps[id] = {
- latlngs: L.LatLngUtil.cloneLatLngs(layer.getLatLngs())
- };
- } else if (layer instanceof L.Circle) {
- this._uneditedLayerProps[id] = {
- latlng: L.LatLngUtil.cloneLatLng(layer.getLatLng()),
- radius: layer.getRadius()
- };
- } else if (layer instanceof L.Marker || layer instanceof L.CircleMarker) { // Marker
- this._uneditedLayerProps[id] = {
- latlng: L.LatLngUtil.cloneLatLng(layer.getLatLng())
- };
- }
- }
- },
- _getTooltipText: function () {
- return ({
- text: L.drawLocal.edit.handlers.edit.tooltip.text,
- subtext: L.drawLocal.edit.handlers.edit.tooltip.subtext
- });
- },
- _updateTooltip: function () {
- this._tooltip.updateContent(this._getTooltipText());
- },
- _revertLayer: function (layer) {
- var id = L.Util.stamp(layer);
- layer.edited = false;
- if (this._uneditedLayerProps.hasOwnProperty(id)) {
- // Polyline, Polygon or Rectangle
- if (layer instanceof L.Polyline || layer instanceof L.Polygon || layer instanceof L.Rectangle) {
- layer.setLatLngs(this._uneditedLayerProps[id].latlngs);
- } else if (layer instanceof L.Circle) {
- layer.setLatLng(this._uneditedLayerProps[id].latlng);
- layer.setRadius(this._uneditedLayerProps[id].radius);
- } else if (layer instanceof L.Marker || layer instanceof L.CircleMarker) { // Marker or CircleMarker
- layer.setLatLng(this._uneditedLayerProps[id].latlng);
- }
- layer.fire('revert-edited', {layer: layer});
- }
- },
- _enableLayerEdit: function (e) {
- var layer = e.layer || e.target || e,
- pathOptions, poly;
- // Back up this layer (if haven't before)
- this._backupLayer(layer);
- if (this.options.poly) {
- poly = L.Util.extend({}, this.options.poly);
- layer.options.poly = poly;
- }
- // Set different style for editing mode
- if (this.options.selectedPathOptions) {
- pathOptions = L.Util.extend({}, this.options.selectedPathOptions);
- // Use the existing color of the layer
- if (pathOptions.maintainColor) {
- pathOptions.color = layer.options.color;
- pathOptions.fillColor = layer.options.fillColor;
- }
- layer.options.original = L.extend({}, layer.options);
- layer.options.editing = pathOptions;
- }
- if (layer instanceof L.Marker) {
- if (layer.editing) {
- layer.editing.enable();
- }
- layer.dragging.enable();
- layer
- .on('dragend', this._onMarkerDragEnd)
- // #TODO: remove when leaflet finally fixes their draggable so it's touch friendly again.
- .on('touchmove', this._onTouchMove, this)
- .on('MSPointerMove', this._onTouchMove, this)
- .on('touchend', this._onMarkerDragEnd, this)
- .on('MSPointerUp', this._onMarkerDragEnd, this);
- } else {
- layer.editing.enable();
- }
- },
- _disableLayerEdit: function (e) {
- var layer = e.layer || e.target || e;
- layer.edited = false;
- if (layer.editing) {
- layer.editing.disable();
- }
- delete layer.options.editing;
- delete layer.options.original;
- // Reset layer styles to that of before select
- if (this._selectedPathOptions) {
- if (layer instanceof L.Marker) {
- this._toggleMarkerHighlight(layer);
- } else {
- // reset the layer style to what is was before being selected
- layer.setStyle(layer.options.previousOptions);
- // remove the cached options for the layer object
- delete layer.options.previousOptions;
- }
- }
- if (layer instanceof L.Marker) {
- layer.dragging.disable();
- layer
- .off('dragend', this._onMarkerDragEnd, this)
- .off('touchmove', this._onTouchMove, this)
- .off('MSPointerMove', this._onTouchMove, this)
- .off('touchend', this._onMarkerDragEnd, this)
- .off('MSPointerUp', this._onMarkerDragEnd, this);
- } else {
- layer.editing.disable();
- }
- },
- _onMouseMove: function (e) {
- this._tooltip.updatePosition(e.latlng);
- },
- _onMarkerDragEnd: function (e) {
- var layer = e.target;
- layer.edited = true;
- this._map.fire(L.Draw.Event.EDITMOVE, {layer: layer});
- },
- _onTouchMove: function (e) {
- var touchEvent = e.originalEvent.changedTouches[0],
- layerPoint = this._map.mouseEventToLayerPoint(touchEvent),
- latlng = this._map.layerPointToLatLng(layerPoint);
- e.target.setLatLng(latlng);
- },
- _hasAvailableLayers: function () {
- return this._featureGroup.getLayers().length !== 0;
- }
- });
- /**
- * @class L.EditToolbar.Delete
- * @aka EditToolbar.Delete
- */
- L.EditToolbar.Delete = L.Handler.extend({
- statics: {
- TYPE: 'remove' // not delete as delete is reserved in js
- },
- // @method intialize(): void
- initialize: function (map, options) {
- L.Handler.prototype.initialize.call(this, map);
- L.Util.setOptions(this, options);
- // Store the selectable layer group for ease of access
- this._deletableLayers = this.options.featureGroup;
- if (!(this._deletableLayers instanceof L.FeatureGroup)) {
- throw new Error('options.featureGroup must be a L.FeatureGroup');
- }
- // Save the type so super can fire, need to do this as cannot do this.TYPE :(
- this.type = L.EditToolbar.Delete.TYPE;
- var version = L.version.split('.');
- //If Version is >= 1.2.0
- if (parseInt(version[0], 10) === 1 && parseInt(version[1], 10) >= 2) {
- L.EditToolbar.Delete.include(L.Evented.prototype);
- } else {
- L.EditToolbar.Delete.include(L.Mixin.Events);
- }
- },
- // @method enable(): void
- // Enable the delete toolbar
- enable: function () {
- if (this._enabled || !this._hasAvailableLayers()) {
- return;
- }
- this.fire('enabled', {handler: this.type});
- this._map.fire(L.Draw.Event.DELETESTART, {handler: this.type});
- L.Handler.prototype.enable.call(this);
- this._deletableLayers
- .on('layeradd', this._enableLayerDelete, this)
- .on('layerremove', this._disableLayerDelete, this);
- },
- // @method disable(): void
- // Disable the delete toolbar
- disable: function () {
- if (!this._enabled) {
- return;
- }
- this._deletableLayers
- .off('layeradd', this._enableLayerDelete, this)
- .off('layerremove', this._disableLayerDelete, this);
- L.Handler.prototype.disable.call(this);
- this._map.fire(L.Draw.Event.DELETESTOP, {handler: this.type});
- this.fire('disabled', {handler: this.type});
- },
- // @method addHooks(): void
- // Add listener hooks to this handler
- addHooks: function () {
- var map = this._map;
- if (map) {
- map.getContainer().focus();
- this._deletableLayers.eachLayer(this._enableLayerDelete, this);
- this._deletedLayers = new L.LayerGroup();
- this._tooltip = new L.Draw.Tooltip(this._map);
- this._tooltip.updateContent({text: L.drawLocal.edit.handlers.remove.tooltip.text});
- this._map.on('mousemove', this._onMouseMove, this);
- }
- },
- // @method removeHooks(): void
- // Remove listener hooks from this handler
- removeHooks: function () {
- if (this._map) {
- this._deletableLayers.eachLayer(this._disableLayerDelete, this);
- this._deletedLayers = null;
- this._tooltip.dispose();
- this._tooltip = null;
- this._map.off('mousemove', this._onMouseMove, this);
- }
- },
- // @method revertLayers(): void
- // Revert the deleted layers back to their prior state.
- revertLayers: function () {
- // Iterate of the deleted layers and add them back into the featureGroup
- this._deletedLayers.eachLayer(function (layer) {
- this._deletableLayers.addLayer(layer);
- layer.fire('revert-deleted', {layer: layer});
- }, this);
- },
- // @method save(): void
- // Save deleted layers
- save: function () {
- this._map.fire(L.Draw.Event.DELETED, {layers: this._deletedLayers});
- },
- // @method removeAllLayers(): void
- // Remove all delateable layers
- removeAllLayers: function () {
- // Iterate of the delateable layers and add remove them
- this._deletableLayers.eachLayer(function (layer) {
- this._removeLayer({layer: layer});
- }, this);
- this.save();
- },
- _enableLayerDelete: function (e) {
- var layer = e.layer || e.target || e;
- layer.on('click', this._removeLayer, this);
- },
- _disableLayerDelete: function (e) {
- var layer = e.layer || e.target || e;
- layer.off('click', this._removeLayer, this);
- // Remove from the deleted layers so we can't accidentally revert if the user presses cancel
- this._deletedLayers.removeLayer(layer);
- },
- _removeLayer: function (e) {
- var layer = e.layer || e.target || e;
- this._deletableLayers.removeLayer(layer);
- this._deletedLayers.addLayer(layer);
- layer.fire('deleted');
- },
- _onMouseMove: function (e) {
- this._tooltip.updatePosition(e.latlng);
- },
- _hasAvailableLayers: function () {
- return this._deletableLayers.getLayers().length !== 0;
- }
- });
- }(window, document));
- //# sourceMappingURL=leaflet.draw-src.map
|