492 changed files with 193538 additions and 2810 deletions
@ -0,0 +1,7 @@
|
||||
# Build Folders (you can keep bin if you'd like, to store dlls and pdbs) |
||||
bin |
||||
obj |
||||
|
||||
# mstest test results |
||||
TestResults |
||||
node_modules |
@ -0,0 +1,20 @@
|
||||
sudo: false |
||||
language: node_js |
||||
node_js: |
||||
- 6 |
||||
cache: |
||||
directories: |
||||
- "travis_phantomjs" |
||||
before_install: |
||||
- "export PHANTOMJS_VERSION=2.1.1" |
||||
- "hash -r" |
||||
- "phantomjs --version" |
||||
- "export PATH=$PWD/travis_phantomjs/phantomjs-$PHANTOMJS_VERSION-linux-x86_64/bin:$PATH" |
||||
- "hash -r" |
||||
- "phantomjs --version" |
||||
- "if [ $(phantomjs --version) != \"$PHANTOMJS_VERSION\" ]; then rm -rf $PWD/travis_phantomjs; mkdir -p $PWD/travis_phantomjs; fi" |
||||
- "hash -r" |
||||
- "if [ $(phantomjs --version) != \"$PHANTOMJS_VERSION\" ]; then wget https://github.com/Medium/phantomjs/releases/download/v$PHANTOMJS_VERSION/phantomjs-$PHANTOMJS_VERSION-linux-x86_64.tar.bz2 -O $PWD/travis_phantomjs/phantomjs-$PHANTOMJS_VERSION-linux-x86_64.tar.bz2; fi" |
||||
- "if [ $(phantomjs --version) != \"$PHANTOMJS_VERSION\" ]; then tar -xvf $PWD/travis_phantomjs/phantomjs-$PHANTOMJS_VERSION-linux-x86_64.tar.bz2 -C $PWD/travis_phantomjs; fi" |
||||
- "hash -r" |
||||
- "phantomjs --version" |
@ -0,0 +1,242 @@
|
||||
Leaflet.markercluster |
||||
===================== |
||||
|
||||
(all changes without author notice are by [@danzel](https://github.com/danzel)) |
||||
|
||||
## 1.4.1 (2018-09-14) |
||||
|
||||
### Bugfixes |
||||
|
||||
* Better support stopping dragged markers from being clustered (by [@DerGuteWolf](https://github.com/DerGuteWolf)) [#909](https://github.com/Leaflet/Leaflet.markercluster/pull/909) |
||||
|
||||
## 1.4.0 (2018-08-22) |
||||
|
||||
Required leaflet version bumped to 1.3.1 |
||||
|
||||
### Improvements |
||||
|
||||
* Tests run against leaflet 1.1.0+ [#863](https://github.com/Leaflet/Leaflet.markercluster/issues/863) |
||||
|
||||
### Bugfixes |
||||
|
||||
* Fix clearLayers not removing removed markers [#860](https://github.com/Leaflet/Leaflet.markercluster/issues/860) |
||||
* Remember opacity 0 correctly (by [@r-yanyo](https://github.com/r-yanyo)) [#890](https://github.com/Leaflet/Leaflet.markercluster/pull/890) |
||||
* Fix chunkedLoading LatLngBounds.intersects() (by [@boldtrn](https://github.com/boldtrn)) [#743](https://github.com/Leaflet/Leaflet.markercluster/issues/743) [#891](https://github.com/Leaflet/Leaflet.markercluster/pull/891) |
||||
|
||||
## 1.3.0 (2018-01-19) |
||||
|
||||
### Improvements |
||||
|
||||
* Use Rollup for builds (by [@IvanSanchez](https://github.com/IvanSanchez)) [#769](https://github.com/Leaflet/Leaflet.markercluster/pull/769) |
||||
|
||||
### Bugfixes |
||||
|
||||
* Fix Spiderfier positioning for small markers (by [@ghybs](https://github.com/ghybs)) [#846](https://github.com/Leaflet/Leaflet.markercluster/pull/846) |
||||
* Fix anchor usage with latest leaflet version [#861](https://github.com/Leaflet/Leaflet.markercluster/issues/861) |
||||
|
||||
## 1.2.0 (2017-11-06) |
||||
|
||||
### Improvements |
||||
|
||||
* Move `clusterPane` option in to `options` field (by [@ghybs](https://github.com/ghybs)) [#832](https://github.com/Leaflet/Leaflet.markercluster/pull/832) |
||||
|
||||
### Bugfixes |
||||
|
||||
* Fix very small `maxClusterRadius` hanging the browser (by [@lucaswerkmeister](https://github.com/lucaswerkmeister)) [#838](https://github.com/Leaflet/Leaflet.markercluster/pull/838) |
||||
|
||||
## 1.1.0 (2017-08-27) |
||||
|
||||
### Improvements |
||||
|
||||
* Add `clusterPane` option to allow putting clusters in a different pane (by [@ckrahe](https://github.com/ckrahe)) [#819](https://github.com/Leaflet/Leaflet.markercluster/issues/819) |
||||
|
||||
## 1.0.6 (2017-06-19) |
||||
|
||||
### Bugfixes |
||||
|
||||
* Fix some issues when used with non-integer zoom [#789](https://github.com/Leaflet/Leaflet.markercluster/issues/789) |
||||
* Change examples to use https (by [@ghybs](https://github.com/ghybs)) [#794](https://github.com/Leaflet/Leaflet.markercluster/pull/794) |
||||
|
||||
## 1.0.5 (2017-04-26) |
||||
|
||||
### Improvements |
||||
|
||||
* Allow passing fitBounds options to zoomToBounds (by [@timkelty](https://github.com/timkelty)) [#779](https://github.com/Leaflet/Leaflet.markercluster/pull/779) |
||||
|
||||
### Bugfixes |
||||
|
||||
* Fixed bug where disableClusteringAtZoom being 0 is treated the same as null (by [@MrCheeze](https://github.com/MrCheeze)) [#773](https://github.com/Leaflet/Leaflet.markercluster/pull/773) |
||||
|
||||
## 1.0.4 (2017-03-14) |
||||
|
||||
### Bugfixes |
||||
|
||||
* Fix errors removing a MarkerClusterGroup from the map during an animation [#758](https://github.com/Leaflet/Leaflet.markercluster/issues/758) |
||||
|
||||
## 1.0.3 (2017-02-02) |
||||
|
||||
### Bugfixes |
||||
|
||||
* Fix moving markers while the MarkerClusterGroup is not on the map [#753](https://github.com/Leaflet/Leaflet.markercluster/issues/753) |
||||
|
||||
## 1.0.2 (2017-01-27) |
||||
|
||||
### Improvements |
||||
|
||||
* Support `layeradd` and `layerremove` events [#647](https://github.com/Leaflet/Leaflet.markercluster/issues/647) |
||||
|
||||
### Bugfixes |
||||
|
||||
* Add support for maps with negative minZoom [#704](https://github.com/Leaflet/Leaflet.markercluster/issues/704) |
||||
* Fixed zoomToShowLayer() markers disappearing bug (by [@z3ut](https://github.com/z3ut)) [#739](https://github.com/Leaflet/Leaflet.markercluster/issues/739) |
||||
* Fix an issue when opening a popup inside of zoomToShowLayer |
||||
* If a marker is moved with an open popup on it, re-open the popup after moving it. [#651](https://github.com/Leaflet/Leaflet.markercluster/issues/651) |
||||
|
||||
|
||||
## 1.0.1 (2017-01-25) |
||||
|
||||
### Improvements |
||||
|
||||
* Add install and build steps with jake (by [@kazes](https://github.com/kazes)) [#733](https://github.com/Leaflet/Leaflet.markercluster/pull/733) |
||||
* Readme improvements (by [@ghybs](https://github.com/ghybs), [@bertyhell](https://github.com/bertyhell)) [#734](https://github.com/Leaflet/Leaflet.markercluster/pull/738), [#734](https://github.com/Leaflet/Leaflet.markercluster/pull/738 |
||||
* Bump all examples to leaflet 1.0.3 |
||||
|
||||
### Bugfixes |
||||
|
||||
* Fixed leaflet 1.0.2 bug where clearLayers would throw an exception (by [@marcianoviereck92](https://github.com/marcianoviereck92)) [#746](https://github.com/Leaflet/Leaflet.markercluster/pull/746) |
||||
|
||||
|
||||
## 1.0.0 (2016-10-03) |
||||
|
||||
### Improvements |
||||
|
||||
* Compatibility with Leaflet 1.0.0 (by [@danzel](https://githum.com/danzel), [@Eschon](https://github.com/Eschon), [@ghybs](https://github.com/ghybs), [@IvanSanchez](https://github.com/IvanSanchez)) |
||||
* Support moving markers [#57](https://github.com/Leaflet/Leaflet.markercluster/issues/57) |
||||
* chunkedLoading option to keep browser more responsive during larging a load data set [#292](https://github.com/Leaflet/Leaflet.markercluster/issues/292) |
||||
* maxClusterRadius can be a function (by [@Schwanksta](https://github.com/Schwanksta)) [#298](https://github.com/Leaflet/Leaflet.markercluster/issues/298) |
||||
* Spiderfy without zooming when all markers at same location (by [@rdenniston](https://github.com/rdenniston), [@ghybs](https://github.com/ghybs)) [#415](https://github.com/Leaflet/Leaflet.markercluster/issues/415), [#606](https://github.com/Leaflet/Leaflet.markercluster/issues/606) |
||||
* On becoming visible, markers retain their original opacity. (by [@IvanSanchez](https://github.com/IvanSanchez)) [#444](https://github.com/Leaflet/Leaflet.markercluster/issues/444) |
||||
* Spiderleg Polyline options (by [@mikeatlas](https://github.com/mikeatlas)) [#466](https://github.com/Leaflet/Leaflet.markercluster/issues/466) |
||||
* Extra methods to allow refreshing cluster icons (by [@ghybs](https://github.com/ghybs)) [#564](https://github.com/Leaflet/Leaflet.markercluster/issues/564) |
||||
* Ability to disable animations (by [@ghybs](https://github.com/ghybs)) [#578](https://github.com/Leaflet/Leaflet.markercluster/issues/578) |
||||
* Optimized performance of bulk addLayers and removeLayers (by [@ghybs](https://github.com/ghybs)) [#584](https://github.com/Leaflet/Leaflet.markercluster/issues/584) |
||||
* Replaced spiderfy legs animation from SMIL to CSS transition (by [@ghybs](https://github.com/ghybs)) [#585](https://github.com/Leaflet/Leaflet.markercluster/issues/585) |
||||
* Provide more detailed context information on the spiderfied event (by [@evanvosberg](https://github.com/evanvosberg)) [#421](https://github.com/Leaflet/Leaflet.markercluster/issues/421) |
||||
* Add unspiderfied event |
||||
* Readme updates (by [@ghybs](https://github.com/ghybs), [@tomchadwin](https://github.com/tomchadwin) [@Cyrille37](https://github.com/Cyrille37) [@franckl](https://github.com/franckl) [@mikeatlas](https://github.com/mikeatlas) |
||||
[@rdenniston](https://github.com/rdenniston) [@maackle](https://github.com/maackle) [@fureigh](https://github.com/fureigh) [@Wildhoney](https://github.com/Wildhoney) [@Schwanksta](https://github.com/Schwanksta) [@frankrowe](https://github.com/frankrowe)) |
||||
* Improve adding and removing nested LayerGroups (by [@ghybs](https://github.com/ghybs)) [#624](https://github.com/Leaflet/Leaflet.markercluster/pull/624) |
||||
* Add public unspiderfy method (by [@zverev](https://github.com/zverev)) [#617](https://github.com/Leaflet/Leaflet.markercluster/pull/617) |
||||
* Optimized performance of bulk add with complex icon create function (by [@mlazowik](https://github.com/mlazowik)) [#697](https://github.com/Leaflet/Leaflet.markercluster/pull/697) |
||||
* Remove leaflet from peerDependencies (by [@tyleralves](https://github.com/tyleralves)) [#703](https://github.com/Leaflet/Leaflet.markercluster/pull/703) |
||||
* Simplified _recursively (by [@ghybs](https://github.com/ghybs)) [#656](https://github.com/Leaflet/Leaflet.markercluster/pull/656) |
||||
|
||||
### Bugfixes |
||||
|
||||
* Fix getBounds when removeOutsideVisibleBounds: false is set. [#321](https://github.com/Leaflet/Leaflet.markercluster/issues/321) |
||||
* Fix zoomToShowLayer fails after initial spiderfy [#286](https://github.com/Leaflet/Leaflet.markercluster/issues/286) |
||||
* Fix cluster not disappearing on Android [#344](https://github.com/Leaflet/Leaflet.markercluster/issues/344) |
||||
* Fix RemoveLayers() when spiderified (by [@Grsmto](https://github.com/Grsmto)) [#358](https://github.com/Leaflet/Leaflet.markercluster/issues/358) |
||||
* Remove lines from map when removing cluster (by [@olive380](https://github.com/olive380)) [#532](https://github.com/Leaflet/Leaflet.markercluster/issues/532) |
||||
* Fix getConvexHull when all markers are located at same latitude (by [@olive380](https://github.com/olive380)) [#533](https://github.com/Leaflet/Leaflet.markercluster/issues/533) |
||||
* Fix removeLayers when cluster is not on the map (by [@eschon](https://github.com/eschon)) [#556](https://github.com/Leaflet/Leaflet.markercluster/issues/556) |
||||
* Improved zoomToShowLayer with callback check (by [@ghybs](https://github.com/ghybs)) [#572](https://github.com/Leaflet/Leaflet.markercluster/issues/572) |
||||
* Improved reliability of RefreshSpec test suite for PhantomJS (by [@ghybs](https://github.com/ghybs)) [#577](https://github.com/Leaflet/Leaflet.markercluster/issues/577) |
||||
* Corrected effect of removeOutsideVisibleBounds option (by [@ghybs](https://github.com/ghybs)) [#575](https://github.com/Leaflet/Leaflet.markercluster/issues/575) |
||||
* Fix getLayer when provided a string [#531](https://github.com/Leaflet/Leaflet.markercluster/issues/531) |
||||
* Documentation improvements (by [@ghybs](https://github.com/ghybs)) [#579](https://github.com/Leaflet/Leaflet.markercluster/issues/579) |
||||
* Correct _getExpandedVisibleBounds for Max Latitude (by [@ghybs](https://github.com/ghybs)) [#587](https://github.com/Leaflet/Leaflet.markercluster/issues/587) |
||||
* Correct unspiderfy vector (by [@ghybs](https://github.com/ghybs)) [#604](https://github.com/Leaflet/Leaflet.markercluster/issues/604) |
||||
* Remove "leaflet-cluster-anim" class on map remove while spiderfied (by [@ghybs](https://github.com/ghybs)) [#607](https://github.com/Leaflet/Leaflet.markercluster/issues/607) |
||||
* Fix disableClusteringAtZoom maxZoom troubles (by [@OriginalSin](https://github.com/OriginalSin)) [#609](https://github.com/Leaflet/Leaflet.markercluster/issues/609) |
||||
* Fix clusters not disappearing when they were near the edge on mobile (by [@ghybs](https://github.com/ghybs)) [#529](https://github.com/Leaflet/Leaflet.markercluster/issues/529) |
||||
* Remove leaflet from dependencies (by [@ghybs](https://github.com/ghybs)) [#639](https://github.com/Leaflet/Leaflet.markercluster/issues/639) |
||||
* Fix interaction between zoomOrSpiderfy and disableClusteringAtZoom (by [@ghybs](https://github.com/ghybs)) [#633](https://github.com/Leaflet/Leaflet.markercluster/issues/633) [#648](https://github.com/Leaflet/Leaflet.markercluster/issues/648) |
||||
|
||||
|
||||
## 0.4 (2013-12-19) |
||||
|
||||
### Improvements |
||||
|
||||
* Fix Quick Zoom in/out causing everything to disappear in Firefox (Reported by [@paulovieira](https://github.com/paulovieira)) [#140](https://github.com/Leaflet/Leaflet.markercluster/issues/140) |
||||
* Slow the expand/contract animation down from 200ms to 300ms |
||||
|
||||
### Bugfixes |
||||
|
||||
* Fix some cases zoomToShowLayer wouldn't work (Reported by [@absemetov](https://github.com/absemetov)) [#203](https://github.com/Leaflet/Leaflet.markercluster/issues/203) [#228](https://github.com/Leaflet/Leaflet.markercluster/issues/228) [#286](https://github.com/Leaflet/Leaflet.markercluster/issues/286) |
||||
|
||||
|
||||
## 0.3 (2013-12-18) |
||||
|
||||
### Improvements |
||||
|
||||
* Work better with custom projections (by [@andersarstrand](https://github.com/andersarstrand)) [#74](https://github.com/Leaflet/Leaflet.markercluster/issues/74) |
||||
* Add custom getBounds that works (Reported by [@2803media](https://github.com/2803media)) |
||||
* Allow spacing spiderfied icons further apart (Reported by [@stevevance](https://github.com/stevevance)) [#100](https://github.com/Leaflet/Leaflet.markercluster/issues/100) |
||||
* Add custom eachLayer that works (Reported by [@cilogi](https://github.com/cilogi)) [#102](https://github.com/Leaflet/Leaflet.markercluster/issues/102) |
||||
* Add an option (removeOutsideVisibleBounds) to prevent removing clusters that are outside of the visible bounds (by [@wildhoney](https://github.com/wildhoney)) [#103](https://github.com/Leaflet/Leaflet.markercluster/issues/103) |
||||
* Add getBounds method to cluster (Reported by [@nderambure](https://github.com/nderambure)) [#88](https://github.com/Leaflet/Leaflet.markercluster/issues/88) |
||||
* Lots of unit tests |
||||
* Support having Circle / CircleMarker as child markers |
||||
* Add factory methods (Reported by [@mourner](https://github.com/mourner)) [#21](https://github.com/Leaflet/Leaflet.markercluster/issues/21) |
||||
* Add getVisibleParent method to allow getting the visible parent cluster or the marker if it is visible. (By [@littleiffel](https://github.com/littleiffel)) [#102](https://github.com/Leaflet/Leaflet.markercluster/issues/102) |
||||
* Allow adding non-clusterable things to a MarkerClusterGroup, we don't cluster them. (Reported by [@benbalter](https://github.com/benbalter)) [#195](https://github.com/Leaflet/Leaflet.markercluster/issues/195) |
||||
* removeLayer supports taking a FeatureGroup (Reported by [@pabloalcaraz](https://github.com/pabloalcaraz)) [#236](https://github.com/Leaflet/Leaflet.markercluster/issues/236) |
||||
* DistanceGrid tests, QuickHull tests and improvements (By [@tmcw](https://github.com/tmcw)) [#247](https://github.com/Leaflet/Leaflet.markercluster/issues/247) [#248](https://github.com/Leaflet/Leaflet.markercluster/issues/248) [#249](https://github.com/Leaflet/Leaflet.markercluster/issues/249) |
||||
* Implemented getLayers (Reported by [@metajungle](https://github.com/metajungle)) [#222](https://github.com/Leaflet/Leaflet.markercluster/issues/222) |
||||
* zoomToBounds now only zooms in as far as it needs to to get all of the markers on screen if this is less zoom than zooming to the actual bounds would be (Reported by [@adamyonk](https://github.com/adamyonk)) [#185](https://github.com/Leaflet/Leaflet.markercluster/issues/185) |
||||
* Keyboard accessibility improvements (By [@Zombienaute](https://github.com/Zombienaute)) [#273](https://github.com/Leaflet/Leaflet.markercluster/issues/273) |
||||
* IE Specific css in the default styles is no longer a separate file (By [@frankrowe](https://github.com/frankrowe)) [#280](https://github.com/Leaflet/Leaflet.markercluster/issues/280) |
||||
* Improve usability with small maps (Reported by [@JSCSJSCS](https://github.com/JSCSJSCS)) [#144](https://github.com/Leaflet/Leaflet.markercluster/issues/144) |
||||
* Implement FeatureGroup.getLayer (Reported by [@newmanw](https://github.com/newmanw)) [#244](https://github.com/Leaflet/Leaflet.markercluster/issues/244) |
||||
|
||||
### Bugfixes |
||||
|
||||
* Fix singleMarkerMode when you aren't on the map (by [@duncanparkes](https://github.com/duncanparkes)) [#77](https://github.com/Leaflet/Leaflet.markercluster/issues/77) |
||||
* Fix clearLayers when you aren't on the map (by [@duncanparkes](https://github.com/duncanparkes)) [#79](https://github.com/Leaflet/Leaflet.markercluster/issues/79) |
||||
* IE10 Bug fix (Reported by [@theLundquist](https://github.com/theLundquist)) [#86](https://github.com/Leaflet/Leaflet.markercluster/issues/86) |
||||
* Fixes for hasLayer after removing a layer (Reported by [@cvisto](https://github.com/cvisto)) [#44](https://github.com/Leaflet/Leaflet.markercluster/issues/44) |
||||
* Fix clearLayers not unsetting __parent of the markers, preventing them from being re-added. (Reported by [@apuntovanini](https://github.com/apuntovanini)) [#99](https://github.com/Leaflet/Leaflet.markercluster/issues/99) |
||||
* Fix map.removeLayer(markerClusterGroup) not working (Reported by [@Driklyn](https://github.com/Driklyn)) [#108](https://github.com/Leaflet/Leaflet.markercluster/issues/108) |
||||
* Fix map.addLayers not updating cluster icons (Reported by [@Driklyn](https://github.com/Driklyn)) [#114](https://github.com/Leaflet/Leaflet.markercluster/issues/114) |
||||
* Fix spiderfied clusters breaking if a marker is added to them (Reported by [@Driklyn](https://github.com/Driklyn)) [#114](https://github.com/Leaflet/Leaflet.markercluster/issues/114) |
||||
* Don't show coverage for spiderfied clusters as it will be wrong. (Reported by [@ajbeaven](https://github.com/ajbeaven)) [#95](https://github.com/Leaflet/Leaflet.markercluster/issues/95) |
||||
* Improve zoom in/out immediately making all everything disappear, still issues in Firefox [#140](https://github.com/Leaflet/Leaflet.markercluster/issues/140) |
||||
* Fix animation not stopping with only one marker. (Reported by [@Driklyn](https://github.com/Driklyn)) [#146](https://github.com/Leaflet/Leaflet.markercluster/issues/146) |
||||
* Various fixes for new leaflet (Reported by [@PeterAronZentai](https://github.com/PeterAronZentai)) [#159](https://github.com/Leaflet/Leaflet.markercluster/issues/159) |
||||
* Fix clearLayers when we are spiderfying (Reported by [@skullbooks](https://github.com/skullbooks)) [#162](https://github.com/Leaflet/Leaflet.markercluster/issues/162) |
||||
* Fix removing layers in certain situations (Reported by [@bpavot](https://github.com/bpavot)) [#160](https://github.com/Leaflet/Leaflet.markercluster/issues/160) |
||||
* Support calling hasLayer with null (by [@l0c0luke](https://github.com/l0c0luke)) [#170](https://github.com/Leaflet/Leaflet.markercluster/issues/170) |
||||
* Lots of fixes for removing a MarkerClusterGroup from the map (Reported by [@annetdeboer](https://github.com/annetdeboer)) [#200](https://github.com/Leaflet/Leaflet.markercluster/issues/200) |
||||
* Throw error when being added to a map with no maxZoom. |
||||
* Fixes for markers not appearing after a big zoom (Reported by [@arnoldbird](https://github.com/annetdeboer)) [#216](https://github.com/Leaflet/Leaflet.markercluster/issues/216) (Reported by [@mathilde-pellerin](https://github.com/mathilde-pellerin)) [#260](https://github.com/Leaflet/Leaflet.markercluster/issues/260) |
||||
* Fix coverage polygon not being removed when a MarkerClusterGroup is removed (Reported by [@ZeusTheTrueGod](https://github.com/ZeusTheTrueGod)) [#245](https://github.com/Leaflet/Leaflet.markercluster/issues/245) |
||||
* Fix getVisibleParent when no parent is visible (Reported by [@ajbeaven](https://github.com/ajbeaven)) [#265](https://github.com/Leaflet/Leaflet.markercluster/issues/265) |
||||
* Fix spiderfied markers not hiding on a big zoom (Reported by [@Vaesive](https://github.com/Vaesive)) [#268](https://github.com/Leaflet/Leaflet.markercluster/issues/268) |
||||
* Fix clusters not hiding on a big zoom (Reported by [@versusvoid](https://github.com/versusvoid)) [#281](https://github.com/Leaflet/Leaflet.markercluster/issues/281) |
||||
* Don't fire multiple clustermouseover/off events due to child divs in the cluster marker (Reported by [@heidemn](https://github.com/heidemn)) [#252](https://github.com/Leaflet/Leaflet.markercluster/issues/252) |
||||
|
||||
## 0.2 (2012-10-11) |
||||
|
||||
### Improvements |
||||
|
||||
* Add addLayers/removeLayers bulk add and remove functions that perform better than the individual methods |
||||
* Allow customising the polygon generated for showing the area a cluster covers (by [@yohanboniface](https://github.com/yohanboniface)) [#68](https://github.com/Leaflet/Leaflet.markercluster/issues/68) |
||||
* Add zoomToShowLayer method to zoom down to a marker then call a callback once it is visible |
||||
* Add animateAddingMarkers to allow disabling animations caused when adding/removing markers |
||||
* Add hasLayer |
||||
* Pass the L.MarkerCluster to iconCreateFunction to give more flexibility deciding the icon |
||||
* Make addLayers support geojson layers |
||||
* Allow disabling clustering at a given zoom level |
||||
* Allow styling markers that are added like they were clusters of size 1 |
||||
|
||||
|
||||
### Bugfixes |
||||
|
||||
* Support when leaflet is configured to use canvas rather than SVG |
||||
* Fix some potential crashes in zoom handlers |
||||
* Tidy up when we are removed from the map |
||||
|
||||
## 0.1 (2012-08-16) |
||||
|
||||
Initial Release! |
@ -0,0 +1,70 @@
|
||||
Contributing to Leaflet.MarkerCluster |
||||
===================================== |
||||
|
||||
1. [Reporting Bugs](#reporting-bugs) |
||||
2. [Contributing Code](#contributing-code) |
||||
3. [Building](#building) |
||||
4. [Testing](#testing) |
||||
|
||||
## Reporting Bugs |
||||
|
||||
Before reporting a bug on the project's [issues page](https://github.com/Leaflet/Leaflet.markercluster/issues), |
||||
first make sure that your issue is caused by Leaflet.MarkerCluster, not your application code |
||||
(e.g. passing incorrect arguments to methods, etc.). |
||||
Second, search the already reported issues for similar cases, |
||||
and if it's already reported, just add any additional details in the comments. |
||||
|
||||
After you've made sure that you've found a new Leaflet.markercluster bug, |
||||
here are some tips for creating a helpful report that will make fixing it much easier and quicker: |
||||
|
||||
* Write a **descriptive, specific title**. Bad: *Problem with polylines*. Good: *Doing X in IE9 causes Z*. |
||||
* Include **browser, OS and Leaflet version** info in the description. |
||||
* Create a **simple test case** that demonstrates the bug (e.g. using [JSFiddle](http://jsfiddle.net/) or [JS Bin](http://jsbin.com/)). |
||||
* Check whether the bug can be reproduced in **other browsers**. |
||||
* Check if the bug occurs in the stable version, master, or both. |
||||
* *Bonus tip:* if the bug only appears in the master version but the stable version is fine, |
||||
use `git bisect` to find the exact commit that introduced the bug. |
||||
|
||||
If you just want some help with your project, |
||||
try asking [on the Leaflet forum](https://groups.google.com/forum/#!forum/leaflet-js) instead. |
||||
|
||||
## Contributing Code |
||||
|
||||
### Considerations for Accepting Patches |
||||
|
||||
While we happily accept patches, we're also committed to keeping Leaflet simple, lightweight and blazingly fast. |
||||
So bugfixes, performance optimizations and small improvements that don't add a lot of code |
||||
are much more likely to get accepted quickly. |
||||
|
||||
Before sending a pull request with a new feature, check if it's been discussed before already |
||||
(either on [GitHub issues](https://github.com/Leaflet/Leaflet/issues) |
||||
or [Leaflet UserVoice](http://leaflet.uservoice.com/)), |
||||
and ask yourself two questions: |
||||
|
||||
1. Are you sure that this new feature is important enough to justify its presence in the Leaflet core? |
||||
Or will it look better as a plugin in a separate repository? |
||||
2. Is it written in a simple, concise way that doesn't add bulk to the codebase? |
||||
|
||||
If your feature or API improvement did get merged into master, |
||||
please consider submitting another pull request with the corresponding [documentation update](#improving-documentation). |
||||
|
||||
## Building |
||||
|
||||
Install the dependencies: |
||||
``` |
||||
npm install -g jake |
||||
npm install |
||||
``` |
||||
|
||||
Then to build: |
||||
``` |
||||
jake |
||||
``` |
||||
Output will be in the ```dist/``` directory |
||||
|
||||
## Testing |
||||
|
||||
To run unit tests: |
||||
``` |
||||
jake test |
||||
``` |
@ -0,0 +1,23 @@
|
||||
- [ ] I'm reporting a bug, not asking for help |
||||
- [ ] I'm sure this is a Leaflet.MarkerCluster code issue, not an issue with my own code nor with the framework I'm using (Cordova, Ionic, Angular, React…) |
||||
- [ ] I've searched through the issues to make sure it's not yet reported |
||||
|
||||
---- |
||||
|
||||
## How to reproduce |
||||
|
||||
- Leaflet version I'm using: |
||||
- Leaflet.MarkerCluster version I'm using: |
||||
- Browser (with version) I'm using: |
||||
- OS/Platform (with version) I'm using: |
||||
- step 1 |
||||
- step 2 |
||||
|
||||
## What behaviour I'm expecting and which behaviour I'm seeing |
||||
|
||||
## Minimal example reproducing the issue |
||||
|
||||
- [ ] this example is as simple as possible |
||||
- [ ] this example does not rely on any third party code |
||||
|
||||
Using http://leafletjs.com/edit.html or any other jsfiddle-like site. |
@ -0,0 +1,86 @@
|
||||
/* |
||||
Leaflet.markercluster building, testing and linting scripts. |
||||
|
||||
To use, install Node, then run the following commands in the project root: |
||||
|
||||
npm install -g jake |
||||
npm install |
||||
|
||||
To check the code for errors and build Leaflet from source, run "jake". |
||||
To run the tests, run "jake test". |
||||
|
||||
For a custom build, open build/build.html in the browser and follow the instructions. |
||||
*/ |
||||
|
||||
var path = require('path'); |
||||
|
||||
desc('Check Leaflet.markercluster source for errors with JSHint'); |
||||
task('lint', function(){ |
||||
jake.exec('jshint', { |
||||
printStdout: true |
||||
}, function () { |
||||
console.log('\tCheck passed.\n'); |
||||
complete(); |
||||
}); |
||||
}); |
||||
|
||||
desc('Combine Leaflet.markercluster source files'); |
||||
task('build', ['lint'], function(){ |
||||
jake.exec('npm run-script rollup', function() { console.log('Rolled up.'); }); |
||||
}); |
||||
|
||||
desc('Compress bundled files'); |
||||
task('uglify', ['build'], function(){ |
||||
jake.exec('npm run-script uglify', function() { console.log('Uglyfied.'); }); |
||||
}); |
||||
|
||||
desc('Run PhantomJS tests'); |
||||
task('test', ['lint'], function() { |
||||
|
||||
var karma = require('karma'), |
||||
testConfig = {configFile : path.join(__dirname, './spec/karma.conf.js')}; |
||||
|
||||
testConfig.browsers = ['PhantomJS']; |
||||
|
||||
function isArgv(optName) { |
||||
return process.argv.indexOf(optName) !== -1; |
||||
} |
||||
|
||||
if (isArgv('--chrome')) { |
||||
testConfig.browsers.push('Chrome'); |
||||
} |
||||
if (isArgv('--safari')) { |
||||
testConfig.browsers.push('Safari'); |
||||
} |
||||
if (isArgv('--ff')) { |
||||
testConfig.browsers.push('Firefox'); |
||||
} |
||||
if (isArgv('--ie')) { |
||||
testConfig.browsers.push('IE'); |
||||
} |
||||
|
||||
if (isArgv('--cov')) { |
||||
testConfig.preprocessors = { |
||||
'src/**/*.js': 'coverage' |
||||
}; |
||||
testConfig.coverageReporter = { |
||||
type : 'html', |
||||
dir : 'coverage/' |
||||
}; |
||||
testConfig.reporters = ['coverage']; |
||||
} |
||||
|
||||
console.log('Running tests...'); |
||||
|
||||
var server = new karma.Server(testConfig, function(exitCode) { |
||||
if (!exitCode) { |
||||
console.log('\tTests ran successfully.\n'); |
||||
complete(); |
||||
} else { |
||||
process.exit(exitCode); |
||||
} |
||||
}); |
||||
server.start(); |
||||
}); |
||||
|
||||
task('default', ['build', 'uglify']); |
@ -0,0 +1,20 @@
|
||||
Copyright 2012 David Leaver |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining |
||||
a copy of this software and associated documentation files (the |
||||
"Software"), to deal in the Software without restriction, including |
||||
without limitation the rights to use, copy, modify, merge, publish, |
||||
distribute, sublicense, and/or sell copies of the Software, and to |
||||
permit persons to whom the Software is furnished to do so, subject to |
||||
the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be |
||||
included in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
@ -0,0 +1,292 @@
|
||||
Leaflet.markercluster |
||||
===================== |
||||
|
||||
Provides Beautiful Animated Marker Clustering functionality for [Leaflet](http://leafletjs.com), a JS library for interactive maps. |
||||
|
||||
*Requires Leaflet 1.0.0* |
||||
|
||||
 |
||||
|
||||
For a Leaflet 0.7 compatible version, [use the leaflet-0.7 branch](https://github.com/Leaflet/Leaflet.markercluster/tree/leaflet-0.7)<br> |
||||
For a Leaflet 0.5 compatible version, [Download b128e950](https://github.com/Leaflet/Leaflet.markercluster/archive/b128e950d8f5d7da5b60bd0aa9a88f6d3dd17c98.zip)<br> |
||||
For a Leaflet 0.4 compatible version, [Download the 0.2 release](https://github.com/Leaflet/Leaflet.markercluster/archive/0.2.zip) |
||||
|
||||
<!--- |
||||
TOC created with gh-md-toc |
||||
https://github.com/ekalinin/github-markdown-toc |
||||
removed link to h1 and indented back 2 spaces all links. |
||||
--> |
||||
## Table of Contents |
||||
* [Using the plugin](#using-the-plugin) |
||||
* [Building, testing and linting scripts](#building-testing-and-linting-scripts) |
||||
* [Examples](#examples) |
||||
* [Usage](#usage) |
||||
* [Options](#options) |
||||
* [Defaults](#defaults) |
||||
* [Customising the Clustered Markers](#customising-the-clustered-markers) |
||||
* [All Options](#all-options) |
||||
* [Enabled by default (boolean options)](#enabled-by-default-boolean-options) |
||||
* [Other options](#other-options) |
||||
* [Chunked addLayers options](#chunked-addlayers-options) |
||||
* [Events](#events) |
||||
* [Additional MarkerClusterGroup Events](#additional-markerclustergroup-events) |
||||
* [Methods](#methods) |
||||
* [Group methods](#group-methods) |
||||
* [Adding and removing Markers](#adding-and-removing-markers) |
||||
* [Bulk adding and removing Markers](#bulk-adding-and-removing-markers) |
||||
* [Getting the visible parent of a marker](#getting-the-visible-parent-of-a-marker) |
||||
* [Refreshing the clusters icon](#refreshing-the-clusters-icon) |
||||
* [Other Group Methods](#other-group-methods) |
||||
* [Clusters methods](#clusters-methods) |
||||
* [Getting the bounds of a cluster](#getting-the-bounds-of-a-cluster) |
||||
* [Zooming to the bounds of a cluster](#zooming-to-the-bounds-of-a-cluster) |
||||
* [Other clusters methods](#other-clusters-methods) |
||||
* [Handling LOTS of markers](#handling-lots-of-markers) |
||||
* [License](#license) |
||||
* [Sub-plugins](#sub-plugins) |
||||
|
||||
|
||||
## Using the plugin |
||||
Include the plugin CSS and JS files on your page after Leaflet files, using your method of choice: |
||||
* [Download the `v1.4.1` release](https://github.com/Leaflet/Leaflet.markercluster/archive/v1.4.1.zip) |
||||
* Use unpkg CDN: `https://unpkg.com/leaflet.markercluster@1.4.1/dist/` |
||||
* Install with npm: `npm install leaflet.markercluster` |
||||
|
||||
In each case, use files in the `dist` folder: |
||||
* `MarkerCluster.css` |
||||
* `MarkerCluster.Default.css` (not needed if you use your own `iconCreateFunction` instead of the default one) |
||||
* `leaflet.markercluster.js` (or `leaflet.markercluster-src.js` for the non-minified version) |
||||
|
||||
### Building, testing and linting scripts |
||||
Install jake `npm install -g jake` then run `npm install` |
||||
* To check the code for errors and build Leaflet from source, run `jake`. |
||||
* To run the tests, run `jake test`. |
||||
|
||||
### Examples |
||||
See the included examples for usage. |
||||
|
||||
The [realworld example](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-realworld.388.html) is a good place to start, it uses all of the defaults of the clusterer. |
||||
Or check out the [custom example](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-custom.html) for how to customise the behaviour and appearance of the clusterer |
||||
|
||||
### Usage |
||||
Create a new MarkerClusterGroup, add your markers to it, then add it to the map |
||||
|
||||
```javascript |
||||
var markers = L.markerClusterGroup(); |
||||
markers.addLayer(L.marker(getRandomLatLng(map))); |
||||
... Add more layers ... |
||||
map.addLayer(markers); |
||||
``` |
||||
|
||||
## Options |
||||
### Defaults |
||||
By default the Clusterer enables some nice defaults for you: |
||||
* **showCoverageOnHover**: When you mouse over a cluster it shows the bounds of its markers. |
||||
* **zoomToBoundsOnClick**: When you click a cluster we zoom to its bounds. |
||||
* **spiderfyOnMaxZoom**: When you click a cluster at the bottom zoom level we spiderfy it so you can see all of its markers. (*Note: the spiderfy occurs at the current zoom level if all items within the cluster are still clustered at the maximum zoom level or at zoom specified by `disableClusteringAtZoom` option*) |
||||
* **removeOutsideVisibleBounds**: Clusters and markers too far from the viewport are removed from the map for performance. |
||||
* **spiderLegPolylineOptions**: Allows you to specify [PolylineOptions](http://leafletjs.com/reference.html#polyline-options) to style spider legs. By default, they are `{ weight: 1.5, color: '#222', opacity: 0.5 }`. |
||||
|
||||
You can disable any of these as you want in the options when you create the MarkerClusterGroup: |
||||
```javascript |
||||
var markers = L.markerClusterGroup({ |
||||
spiderfyOnMaxZoom: false, |
||||
showCoverageOnHover: false, |
||||
zoomToBoundsOnClick: false |
||||
}); |
||||
``` |
||||
|
||||
### Customising the Clustered Markers |
||||
As an option to MarkerClusterGroup you can provide your own function for creating the Icon for the clustered markers. |
||||
The default implementation changes color at bounds of 10 and 100, but more advanced uses may require customising this. |
||||
You do not need to include the .Default css if you go this way. |
||||
You are passed a MarkerCluster object, you'll probably want to use `getChildCount()` or `getAllChildMarkers()` to work out the icon to show. |
||||
|
||||
```javascript |
||||
var markers = L.markerClusterGroup({ |
||||
iconCreateFunction: function(cluster) { |
||||
return L.divIcon({ html: '<b>' + cluster.getChildCount() + '</b>' }); |
||||
} |
||||
}); |
||||
``` |
||||
Check out the [custom example](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-custom.html) for an example of this. |
||||
|
||||
If you need to update the clusters icon (e.g. they are based on markers real-time data), use the method [refreshClusters()](#refreshing-the-clusters-icon). |
||||
|
||||
### All Options |
||||
#### Enabled by default (boolean options) |
||||
* **showCoverageOnHover**: When you mouse over a cluster it shows the bounds of its markers. |
||||
* **zoomToBoundsOnClick**: When you click a cluster we zoom to its bounds. |
||||
* **spiderfyOnMaxZoom**: When you click a cluster at the bottom zoom level we spiderfy it so you can see all of its markers. (*Note: the spiderfy occurs at the current zoom level if all items within the cluster are still clustered at the maximum zoom level or at zoom specified by `disableClusteringAtZoom` option*). |
||||
* **removeOutsideVisibleBounds**: Clusters and markers too far from the viewport are removed from the map for performance. |
||||
* **animate**: Smoothly split / merge cluster children when zooming and spiderfying. If `L.DomUtil.TRANSITION` is false, this option has no effect (no animation is possible). |
||||
|
||||
#### Other options |
||||
* **animateAddingMarkers**: If set to true (and `animate` option is also true) then adding individual markers to the MarkerClusterGroup after it has been added to the map will add the marker and animate it into the cluster. Defaults to false as this gives better performance when bulk adding markers. addLayers does not support this, only addLayer with individual Markers. |
||||
* **disableClusteringAtZoom**: If set, at this zoom level and below, markers will not be clustered. This defaults to disabled. [See Example](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-realworld-maxzoom.388.html). Note: you may be interested in disabling `spiderfyOnMaxZoom` option when using `disableClusteringAtZoom`. |
||||
* **maxClusterRadius**: The maximum radius that a cluster will cover from the central marker (in pixels). Default 80. Decreasing will make more, smaller clusters. You can also use a function that accepts the current map zoom and returns the maximum cluster radius in pixels. |
||||
* **polygonOptions**: Options to pass when creating the L.Polygon(points, options) to show the bounds of a cluster. Defaults to empty, which lets Leaflet use the [default Path options](http://leafletjs.com/reference.html#path-options). |
||||
* **singleMarkerMode**: If set to true, overrides the icon for all added markers to make them appear as a 1 size cluster. Note: the markers are not replaced by cluster objects, only their icon is replaced. Hence they still react to normal events, and option `disableClusteringAtZoom` does not restore their previous icon (see [#391](https://github.com/Leaflet/Leaflet.markercluster/issues/391)). |
||||
* **spiderLegPolylineOptions**: Allows you to specify [PolylineOptions](http://leafletjs.com/reference.html#polyline-options) to style spider legs. By default, they are `{ weight: 1.5, color: '#222', opacity: 0.5 }`. |
||||
* **spiderfyDistanceMultiplier**: Increase from 1 to increase the distance away from the center that spiderfied markers are placed. Use if you are using big marker icons (Default: 1). |
||||
* **iconCreateFunction**: Function used to create the cluster icon. See [the default implementation](https://github.com/Leaflet/Leaflet.markercluster/blob/15ed12654acdc54a4521789c498e4603fe4bf781/src/MarkerClusterGroup.js#L542) or the [custom example](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-custom.html). |
||||
* **clusterPane**: Map pane where the cluster icons will be added. Defaults to L.Marker's default (currently 'markerPane'). [See the pane example](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-pane.html). |
||||
|
||||
#### Chunked addLayers options |
||||
Options for the [addLayers](#bulk-adding-and-removing-markers) method. See [#357](https://github.com/Leaflet/Leaflet.markercluster/issues/357) for explanation on how the chunking works. |
||||
* **chunkedLoading**: Boolean to split the addLayer**s** processing in to small intervals so that the page does not freeze. |
||||
* **chunkInterval**: Time interval (in ms) during which addLayers works before pausing to let the rest of the page process. In particular, this prevents the page from freezing while adding a lot of markers. Defaults to 200ms. |
||||
* **chunkDelay**: Time delay (in ms) between consecutive periods of processing for addLayers. Default to 50ms. |
||||
* **chunkProgress**: Callback function that is called at the end of each chunkInterval. Typically used to implement a progress indicator, e.g. [code in RealWorld 50k](https://github.com/Leaflet/Leaflet.markercluster/blob/master/example/marker-clustering-realworld.50000.html#L33-L49). Defaults to null. Arguments: |
||||
1. Number of processed markers |
||||
2. Total number of markers being added |
||||
3. Elapsed time (in ms) |
||||
|
||||
## Events |
||||
Leaflet events like `click`, `mouseover`, etc. are just related to _Markers_ in the cluster. |
||||
To receive events for clusters, listen to `'cluster' + '<eventName>'`, ex: `clusterclick`, `clustermouseover`, `clustermouseout`. |
||||
|
||||
Set your callback up as follows to handle both cases: |
||||
|
||||
```javascript |
||||
markers.on('click', function (a) { |
||||
console.log('marker ' + a.layer); |
||||
}); |
||||
|
||||
markers.on('clusterclick', function (a) { |
||||
// a.layer is actually a cluster |
||||
console.log('cluster ' + a.layer.getAllChildMarkers().length); |
||||
}); |
||||
``` |
||||
|
||||
### Additional MarkerClusterGroup Events |
||||
|
||||
- **animationend**: Fires when marker clustering/unclustering animation has completed |
||||
- **spiderfied**: Fires when overlapping markers get spiderified (Contains ```cluster``` and ```markers``` attributes) |
||||
- **unspiderfied**: Fires when overlapping markers get unspiderified (Contains ```cluster``` and ```markers``` attributes) |
||||
|
||||
## Methods |
||||
|
||||
### Group methods |
||||
|
||||
#### Adding and removing Markers |
||||
`addLayer`, `removeLayer` and `clearLayers` are supported and they should work for most uses. |
||||
|
||||
#### Bulk adding and removing Markers |
||||
`addLayers` and `removeLayers` are bulk methods for adding and removing markers and should be favoured over the single versions when doing bulk addition/removal of markers. Each takes an array of markers. You can use [dedicated options](#chunked-addlayers-options) to fine-tune the behaviour of `addLayers`. |
||||
|
||||
These methods extract non-group layer children from Layer Group types, even deeply nested. _However_, be noted that: |
||||
- `chunkProgress` jumps backward when `addLayers` finds a group (since appending its children to the input array makes the total increase). |
||||
- Groups are not actually added into the MarkerClusterGroup, only their non-group child layers. Therfore, `hasLayer` method will return `true` for non-group child layers, but `false` on any (possibly parent) Layer Group types. |
||||
|
||||
If you are removing a lot of markers it will almost definitely be better to call `clearLayers` then call `addLayers` to add the markers you don't want to remove back in. See [#59](https://github.com/Leaflet/Leaflet.markercluster/issues/59#issuecomment-9320628) for details. |
||||
|
||||
#### Getting the visible parent of a marker |
||||
If you have a marker in your MarkerClusterGroup and you want to get the visible parent of it (Either itself or a cluster it is contained in that is currently visible on the map). |
||||
This will return null if the marker and its parent clusters are not visible currently (they are not near the visible viewpoint) |
||||
```javascript |
||||
var visibleOne = markerClusterGroup.getVisibleParent(myMarker); |
||||
console.log(visibleOne.getLatLng()); |
||||
``` |
||||
|
||||
#### Refreshing the clusters icon |
||||
If you have [customized](#customising-the-clustered-markers) the clusters icon to use some data from the contained markers, and later that data changes, use this method to force a refresh of the cluster icons. |
||||
You can use the method: |
||||
- without arguments to force all cluster icons in the Marker Cluster Group to be re-drawn. |
||||
- with an array or a mapping of markers to force only their parent clusters to be re-drawn. |
||||
- with an L.LayerGroup. The method will look for all markers in it. Make sure it contains only markers which are also within this Marker Cluster Group. |
||||
- with a single marker. |
||||
```javascript |
||||
markers.refreshClusters(); |
||||
markers.refreshClusters([myMarker0, myMarker33]); |
||||
markers.refreshClusters({id_0: myMarker0, id_any: myMarker33}); |
||||
markers.refreshClusters(myLayerGroup); |
||||
markers.refreshClusters(myMarker); |
||||
``` |
||||
|
||||
The plugin also adds a method on L.Marker to easily update the underlying icon options and refresh the icon. |
||||
If passing a second argument that evaluates to `true`, the method will also trigger a `refreshCluster` on the parent MarkerClusterGroup for that single marker. |
||||
```javascript |
||||
// Use as many times as required to update markers, |
||||
// then call refreshClusters once finished. |
||||
for (i in markersSubArray) { |
||||
markersSubArray[i].refreshIconOptions(newOptionsMappingArray[i]); |
||||
} |
||||
markers.refreshClusters(markersSubArray); |
||||
|
||||
// If updating only one marker, pass true to |
||||
// refresh this marker's parent clusters right away. |
||||
myMarker.refreshIconOptions(optionsMap, true); |
||||
``` |
||||
|
||||
#### Other Group Methods |
||||
* **hasLayer**(layer): Returns true if the given layer (marker) is in the MarkerClusterGroup. |
||||
* **zoomToShowLayer**(layer, callback): Zooms to show the given marker (spiderfying if required), calls the callback when the marker is visible on the map. |
||||
|
||||
### Clusters methods |
||||
The following methods can be used with clusters (not the group). They are typically used for event handling. |
||||
|
||||
#### Getting the bounds of a cluster |
||||
When you receive an event from a cluster you can query it for the bounds. |
||||
```javascript |
||||
markers.on('clusterclick', function (a) { |
||||
var latLngBounds = a.layer.getBounds(); |
||||
}); |
||||
``` |
||||
|
||||
You can also query for the bounding convex polygon. |
||||
See [example/marker-clustering-convexhull.html](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-convexhull.html) for a working example. |
||||
```javascript |
||||
markers.on('clusterclick', function (a) { |
||||
map.addLayer(L.polygon(a.layer.getConvexHull())); |
||||
}); |
||||
``` |
||||
|
||||
#### Zooming to the bounds of a cluster |
||||
When you receive an event from a cluster you can zoom to its bounds in one easy step. |
||||
If all of the markers will appear at a higher zoom level, that zoom level is zoomed to instead. |
||||
`zoomToBounds` takes an optional argument to pass [options to the resulting `fitBounds` call](http://leafletjs.com/reference.html#map-fitboundsoptions). |
||||
|
||||
See [marker-clustering-zoomtobounds.html](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-zoomtobounds.html) for a working example. |
||||
```javascript |
||||
markers.on('clusterclick', function (a) { |
||||
a.layer.zoomToBounds({padding: [20, 20]}); |
||||
}); |
||||
``` |
||||
|
||||
#### Other clusters methods |
||||
* **getChildCount**: Returns the total number of markers contained within that cluster. |
||||
* **getAllChildMarkers(storage: array | undefined, ignoreDraggedMarker: boolean | undefined)**: Returns an array of all markers contained within this cluster (storage will be used if provided). If ignoreDraggedMarker is true and there is currently a marker dragged, the dragged marker will not be included in the array. |
||||
* **spiderfy**: Spiderfies the child markers of this cluster |
||||
* **unspiderfy**: Unspiderfies a cluster (opposite of spiderfy) |
||||
|
||||
## Handling LOTS of markers |
||||
The Clusterer can handle 10,000 or even 50,000 markers (in chrome). IE9 has some issues with 50,000. |
||||
- [realworld 10,000 example](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-realworld.10000.html) |
||||
- [realworld 50,000 example](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-realworld.50000.html) |
||||
|
||||
Note: these two examples use the `chunkedLoading` option set to true in order to avoid locking the browser for a long time. |
||||
|
||||
## License |
||||
|
||||
Leaflet.markercluster is free software, and may be redistributed under the MIT-LICENSE. |
||||
|
||||
[](https://travis-ci.org/Leaflet/Leaflet.markercluster) |
||||
|
||||
## Sub-plugins |
||||
Leaflet.markercluster plugin is very popular and as such it generates high and |
||||
diverse expectations for increased functionalities. |
||||
|
||||
If you are in that case, be sure to have a look first at the repository |
||||
[issues](https://github.com/Leaflet/Leaflet.markercluster/issues) in case what |
||||
you are looking for would already be discussed, and some workarounds would be proposed. |
||||
|
||||
Check also the below sub-plugins: |
||||
|
||||
| Plugin | Description | Maintainer | |
||||
| :----- | :---------- | :--------- | |
||||
| [Leaflet.FeatureGroup.SubGroup](https://github.com/ghybs/Leaflet.FeatureGroup.SubGroup) | Creates a Feature Group that adds its child layers into a parent group when added to a map (e.g. through L.Control.Layers). Typical usage is to dynamically add/remove groups of markers from Marker Cluster. | [ghybs](https://github.com/ghybs) | |
||||
| [Leaflet.MarkerCluster.LayerSupport](https://github.com/ghybs/Leaflet.MarkerCluster.LayerSupport) | Brings compatibility with L.Control.Layers and other Leaflet plugins. I.e. everything that uses direct calls to map.addLayer and map.removeLayer. | [ghybs](https://github.com/ghybs) | |
||||
| [Leaflet.MarkerCluster.Freezable](https://github.com/ghybs/Leaflet.MarkerCluster.Freezable) | Adds the ability to freeze clusters at a specified zoom. E.g. freezing at maxZoom + 1 makes as if clustering was programmatically disabled. | [ghybs](https://github.com/ghybs) | |
||||
| [Leaflet.MarkerCluster.PlacementStrategies](https://github.com/adammertel/Leaflet.MarkerCluster.PlacementStrategies) | Implements new strategies to position clustered markers (eg: clock, concentric circles, ...). Recommended to use with circleMarkers. [Demo](https://adammertel.github.io/Leaflet.MarkerCluster.PlacementStrategies/demo/demo1.html) | [adammertel](https://github.com/adammertel) / [UNIVIE](http://carto.univie.ac.at/) | |
||||
| [Leaflet.MarkerCluster.List](https://github.com/adammertel/Leaflet.MarkerCluster.List) | Displays child elements in a list. Suitable for mobile devices. [Demo](https://adammertel.github.io/Leaflet.MarkerCluster.List/demo/demo1.html) | [adammertel](https://github.com/adammertel) / [UNIVIE](http://carto.univie.ac.at/) | |
@ -0,0 +1,27 @@
|
||||
{ |
||||
"name": "leaflet.markercluster", |
||||
"version": "1.4.1", |
||||
"homepage": "https://github.com/Leaflet/Leaflet.markercluster", |
||||
"authors": [ |
||||
"Dave Leaver <danzel@localhost.geek.nz>" |
||||
], |
||||
"description": "Marker Clustering plugin for Leaflet.", |
||||
"main": [ |
||||
"dist/leaflet.markercluster-src.js", |
||||
"dist/MarkerCluster.css", |
||||
"dist/MarkerCluster.Default.css" |
||||
], |
||||
"license": "MIT", |
||||
"ignore": [ |
||||
"**/.*", |
||||
"node_modules", |
||||
"bower_components", |
||||
"example", |
||||
"spec", |
||||
"test", |
||||
"tests" |
||||
], |
||||
"dependencies": { |
||||
"leaflet": ">= 1.3.1" |
||||
} |
||||
} |
@ -0,0 +1,37 @@
|
||||
exports.config = { |
||||
|
||||
// environment
|
||||
"browser": true, |
||||
"node": true, |
||||
"predef": ['L', 'define'], |
||||
"strict": false, |
||||
|
||||
// code style
|
||||
"bitwise": true, |
||||
"camelcase": true, |
||||
"curly": true, |
||||
"eqeqeq": true, |
||||
"forin": false, |
||||
"immed": true, |
||||
"latedef": true, |
||||
"newcap": true, |
||||
"noarg": true, |
||||
"noempty": true, |
||||
"nonew": true, |
||||
"undef": true, |
||||
"unused": true, |
||||
//"quotmark": "single",
|
||||
|
||||
// whitespace
|
||||
"indent": 4, |
||||
"trailing": true, |
||||
"white": true, |
||||
"smarttabs": true, |
||||
//"maxlen": 120
|
||||
|
||||
// code simplicity - not enforced but nice to check from time to time
|
||||
// "maxstatements": 20,
|
||||
// "maxcomplexity": 5
|
||||
// "maxparams": 4,
|
||||
// "maxdepth": 4
|
||||
}; |
@ -0,0 +1,41 @@
|
||||
|
||||
// Config file for running Rollup in "normal" mode (non-watch)
|
||||
|
||||
import rollupGitVersion from 'rollup-plugin-git-version' |
||||
import json from 'rollup-plugin-json' |
||||
|
||||
import gitRev from 'git-rev-sync' |
||||
|
||||
|
||||
let version = require('../package.json').version; |
||||
let release; |
||||
|
||||
// Skip the git branch+rev in the banner when doing a release build
|
||||
if (process.env.NODE_ENV === 'release') { |
||||
release = true; |
||||
} else { |
||||
release = false; |
||||
const branch = gitRev.branch(); |
||||
const rev = gitRev.short(); |
||||
version += '+' + branch + '.' + rev; |
||||
} |
||||
|
||||
const banner = `/*
|
||||
* Leaflet.markercluster ` + version + `, |
||||
* Provides Beautiful Animated Marker Clustering functionality for Leaflet, a JS library for interactive maps. |
||||
* https://github.com/Leaflet/Leaflet.markercluster
|
||||
* (c) 2012-2017, Dave Leaver, smartrak |
||||
*/`; |
||||
|
||||
export default { |
||||
format: 'umd', |
||||
moduleName: 'Leaflet.markercluster', |
||||
banner: banner, |
||||
entry: 'src/index.js', |
||||
dest: 'dist/leaflet.markercluster-src.js', |
||||
plugins: [ |
||||
release ? json() : rollupGitVersion(), |
||||
], |
||||
sourceMap: true, |
||||
legacy: true // Needed to create files loadable by IE8
|
||||
}; |
@ -0,0 +1,60 @@
|
||||
.marker-cluster-small { |
||||
background-color: rgba(181, 226, 140, 0.6); |
||||
} |
||||
.marker-cluster-small div { |
||||
background-color: rgba(110, 204, 57, 0.6); |
||||
} |
||||
|
||||
.marker-cluster-medium { |
||||
background-color: rgba(241, 211, 87, 0.6); |
||||
} |
||||
.marker-cluster-medium div { |
||||
background-color: rgba(240, 194, 12, 0.6); |
||||
} |
||||
|
||||
.marker-cluster-large { |
||||
background-color: rgba(253, 156, 115, 0.6); |
||||
} |
||||
.marker-cluster-large div { |
||||
background-color: rgba(241, 128, 23, 0.6); |
||||
} |
||||
|
||||
/* IE 6-8 fallback colors */ |
||||
.leaflet-oldie .marker-cluster-small { |
||||
background-color: rgb(181, 226, 140); |
||||
} |
||||
.leaflet-oldie .marker-cluster-small div { |
||||
background-color: rgb(110, 204, 57); |
||||
} |
||||
|
||||
.leaflet-oldie .marker-cluster-medium { |
||||
background-color: rgb(241, 211, 87); |
||||
} |
||||
.leaflet-oldie .marker-cluster-medium div { |
||||
background-color: rgb(240, 194, 12); |
||||
} |
||||
|
||||
.leaflet-oldie .marker-cluster-large { |
||||
background-color: rgb(253, 156, 115); |
||||
} |
||||
.leaflet-oldie .marker-cluster-large div { |
||||
background-color: rgb(241, 128, 23); |
||||
} |
||||
|
||||
.marker-cluster { |
||||
background-clip: padding-box; |
||||
border-radius: 20px; |
||||
} |
||||
.marker-cluster div { |
||||
width: 30px; |
||||
height: 30px; |
||||
margin-left: 5px; |
||||
margin-top: 5px; |
||||
|
||||
text-align: center; |
||||
border-radius: 15px; |
||||
font: 12px "Helvetica Neue", Arial, Helvetica, sans-serif; |
||||
} |
||||
.marker-cluster span { |
||||
line-height: 30px; |
||||
} |
@ -0,0 +1,14 @@
|
||||
.leaflet-cluster-anim .leaflet-marker-icon, .leaflet-cluster-anim .leaflet-marker-shadow { |
||||
-webkit-transition: -webkit-transform 0.3s ease-out, opacity 0.3s ease-in; |
||||
-moz-transition: -moz-transform 0.3s ease-out, opacity 0.3s ease-in; |
||||
-o-transition: -o-transform 0.3s ease-out, opacity 0.3s ease-in; |
||||
transition: transform 0.3s ease-out, opacity 0.3s ease-in; |
||||
} |
||||
|
||||
.leaflet-cluster-spider-leg { |
||||
/* stroke-dashoffset (duration and function) should match with leaflet-marker-icon transform in order to track it exactly */ |
||||
-webkit-transition: -webkit-stroke-dashoffset 0.3s ease-out, -webkit-stroke-opacity 0.3s ease-in; |
||||
-moz-transition: -moz-stroke-dashoffset 0.3s ease-out, -moz-stroke-opacity 0.3s ease-in; |
||||
-o-transition: -o-stroke-dashoffset 0.3s ease-out, -o-stroke-opacity 0.3s ease-in; |
||||
transition: stroke-dashoffset 0.3s ease-out, stroke-opacity 0.3s ease-in; |
||||
} |
@ -0,0 +1,5 @@
|
||||
We don't ship the .js files in the git master branch. |
||||
They are only present in version tags and in npm. |
||||
|
||||
See how to get the JS files here: https://github.com/Leaflet/Leaflet.markercluster#using-the-plugin |
||||
Or how to build them: https://github.com/Leaflet/Leaflet.markercluster#building-testing-and-linting-scripts |
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,53 @@
|
||||
var geojsonSample = { |
||||
"type": "FeatureCollection", |
||||
"features": [ |
||||
{ |
||||
"type": "Feature", |
||||
"geometry": { |
||||
"type": "Point", |
||||
"coordinates": [102.0, 0.5] |
||||
}, |
||||
"properties": { |
||||
"prop0": "value0", |
||||
"color": "blue" |
||||
} |
||||
}, |
||||
|
||||
{ |
||||
"type": "Feature", |
||||
"geometry": { |
||||
"type": "LineString", |
||||
"coordinates": [[102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]] |
||||
}, |
||||
"properties": { |
||||
"color": "red", |
||||
"prop1": 0.0 |
||||
} |
||||
}, |
||||
|
||||
{ |
||||
"type": "Feature", |
||||
"geometry": { |
||||
"type": "Polygon", |
||||
"coordinates": [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]] |
||||
}, |
||||
"properties": { |
||||
"color": "green", |
||||
"prop1": { |
||||
"this": "that" |
||||
} |
||||
} |
||||
}, |
||||
|
||||
{ |
||||
"type": "Feature", |
||||
"geometry": { |
||||
"type": "MultiPolygon", |
||||
"coordinates": [[[[100.0, 1.5], [100.5, 1.5], [100.5, 2.0], [100.0, 2.0], [100.0, 1.5]]], [[[100.5, 2.0], [100.5, 2.5], [101.0, 2.5], [101.0, 2.0], [100.5, 2.0]]]] |
||||
}, |
||||
"properties": { |
||||
"color": "purple" |
||||
} |
||||
} |
||||
] |
||||
}; |
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../dist/MarkerCluster.Default.css" /> |
||||
<script src="../dist/leaflet.markercluster-src.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
|
||||
<script type="text/javascript"> |
||||
|
||||
var geoJsonData = { |
||||
"type": "FeatureCollection", |
||||
"features": [ |
||||
{ "type": "Feature", "id":"1", "properties": { "address": "2" }, "geometry": { "type": "Point", "coordinates": [175.2209316333,-37.8210922667 ] } }, |
||||
{ "type": "Feature", "id":"2", "properties": { "address": "151" }, "geometry": { "type": "Point", "coordinates": [175.2238417833,-37.80975435 ] } }, |
||||
{ "type": "Feature", "id":"3", "properties": { "address": "21" }, "geometry": { "type": "Point", "coordinates": [175.2169955667,-37.818193 ] } }, |
||||
{ "type": "Feature", "id":"4", "properties": { "address": "14" }, "geometry": { "type": "Point", "coordinates": [175.2240856667,-37.8216963 ] } }, |
||||
{ "type": "Feature", "id":"5", "properties": { "address": "38B" }, "geometry": { "type": "Point", "coordinates": [175.2196982333,-37.8188702167 ] } }, |
||||
{ "type": "Feature", "id":"6", "properties": { "address": "38" }, "geometry": { "type": "Point", "coordinates": [175.2209942 ,-37.8192782833 ] } } |
||||
] |
||||
}; |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}); |
||||
|
||||
var map = L.map('map') |
||||
.addLayer(tiles); |
||||
|
||||
var markers = L.markerClusterGroup(); |
||||
|
||||
var geoJsonLayer = L.geoJson(geoJsonData, { |
||||
onEachFeature: function (feature, layer) { |
||||
layer.bindPopup(feature.properties.address); |
||||
} |
||||
}); |
||||
markers.addLayer(geoJsonLayer); |
||||
|
||||
map.addLayer(markers); |
||||
map.fitBounds(markers.getBounds()); |
||||
</script> |
||||
</body> |
||||
</html> |
After Width: | Height: | Size: 381 KiB |
@ -0,0 +1,81 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../dist/MarkerCluster.Default.css" /> |
||||
<script src="../dist/leaflet.markercluster-src.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<button id="populate">Populate 1 marker</button> |
||||
<button id="remove">Remove 1 marker</button> |
||||
|
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = L.latLng(50.5, 30.51); |
||||
|
||||
var map = L.map('map', {center: latlng, zoom: 15, layers: [tiles]}); |
||||
|
||||
var markers = L.markerClusterGroup({ spiderfyOnMaxZoom: false, showCoverageOnHover: false, zoomToBoundsOnClick: false }); |
||||
|
||||
function populate() { |
||||
for (var i = 0; i < 100; i++) { |
||||
var m = L.marker(getRandomLatLng(map)); |
||||
markers.addLayer(m); |
||||
} |
||||
return false; |
||||
} |
||||
function getRandomLatLng(map) { |
||||
var bounds = map.getBounds(), |
||||
southWest = bounds.getSouthWest(), |
||||
northEast = bounds.getNorthEast(), |
||||
lngSpan = northEast.lng - southWest.lng, |
||||
latSpan = northEast.lat - southWest.lat; |
||||
|
||||
return L.latLng( |
||||
southWest.lat + latSpan * Math.random(), |
||||
southWest.lng + lngSpan * Math.random()); |
||||
} |
||||
|
||||
|
||||
var polygon; |
||||
markers.on('clustermouseover', function (a) { |
||||
if (polygon) { |
||||
map.removeLayer(polygon); |
||||
} |
||||
polygon = L.polygon(a.layer.getConvexHull()); |
||||
map.addLayer(polygon); |
||||
}); |
||||
|
||||
markers.on('clustermouseout', function (a) { |
||||
if (polygon) { |
||||
map.removeLayer(polygon); |
||||
polygon = null; |
||||
} |
||||
}); |
||||
|
||||
map.on('zoomend', function () { |
||||
if (polygon) { |
||||
map.removeLayer(polygon); |
||||
polygon = null; |
||||
} |
||||
}); |
||||
|
||||
|
||||
populate(); |
||||
map.addLayer(markers); |
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,114 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../dist/MarkerCluster.css" /> |
||||
<script src="../dist/leaflet.markercluster-src.js"></script> |
||||
|
||||
<style> |
||||
.mycluster { |
||||
width: 40px; |
||||
height: 40px; |
||||
background-color: greenyellow; |
||||
text-align: center; |
||||
font-size: 24px; |
||||
} |
||||
|
||||
</style> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
|
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = L.latLng(50.5, 30.51); |
||||
|
||||
var map = L.map('map', {center: latlng, zoom: 15, layers: [tiles]}); |
||||
|
||||
|
||||
//Custom radius and icon create function |
||||
var markers = L.markerClusterGroup({ |
||||
maxClusterRadius: 120, |
||||
iconCreateFunction: function (cluster) { |
||||
var markers = cluster.getAllChildMarkers(); |
||||
var n = 0; |
||||
for (var i = 0; i < markers.length; i++) { |
||||
n += markers[i].number; |
||||
} |
||||
return L.divIcon({ html: n, className: 'mycluster', iconSize: L.point(40, 40) }); |
||||
}, |
||||
//Disable all of the defaults: |
||||
spiderfyOnMaxZoom: false, showCoverageOnHover: false, zoomToBoundsOnClick: false |
||||
}); |
||||
|
||||
|
||||
function populate() { |
||||
for (var i = 0; i < 100; i++) { |
||||
var m = L.marker(getRandomLatLng(map), { title: i }); |
||||
m.number = i; |
||||
markers.addLayer(m); |
||||
} |
||||
return false; |
||||
} |
||||
function populateRandomVector() { |
||||
for (var i = 0, latlngs = [], len = 20; i < len; i++) { |
||||
latlngs.push(getRandomLatLng(map)); |
||||
} |
||||
var path = L.polyline(latlngs); |
||||
map.addLayer(path); |
||||
} |
||||
function getRandomLatLng(map) { |
||||
var bounds = map.getBounds(), |
||||
southWest = bounds.getSouthWest(), |
||||
northEast = bounds.getNorthEast(), |
||||
lngSpan = northEast.lng - southWest.lng, |
||||
latSpan = northEast.lat - southWest.lat; |
||||
|
||||
return L.latLng( |
||||
southWest.lat + latSpan * Math.random(), |
||||
southWest.lng + lngSpan * Math.random()); |
||||
} |
||||
|
||||
populate(); |
||||
map.addLayer(markers); |
||||
|
||||
|
||||
|
||||
var shownLayer, polygon; |
||||
|
||||
function removePolygon() { |
||||
if (shownLayer) { |
||||
shownLayer.setOpacity(1); |
||||
shownLayer = null; |
||||
} |
||||
if (polygon) { |
||||
map.removeLayer(polygon); |
||||
polygon = null; |
||||
} |
||||
}; |
||||
|
||||
markers.on('clustermouseover', function (a) { |
||||
removePolygon(); |
||||
|
||||
a.layer.setOpacity(0.2); |
||||
shownLayer = a.layer; |
||||
polygon = L.polygon(a.layer.getConvexHull()); |
||||
map.addLayer(polygon); |
||||
}); |
||||
markers.on('clustermouseout', removePolygon); |
||||
map.on('zoomend', removePolygon); |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../dist/MarkerCluster.Default.css" /> |
||||
<script src="../dist/leaflet.markercluster-src.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<button id="moveone">Move a random marker</button> |
||||
|
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = new L.LatLng(50.5, 30.51); |
||||
|
||||
var map = new L.Map('map', {center: latlng, zoom: 15, layers: [tiles]}); |
||||
|
||||
var markers = new L.MarkerClusterGroup(); |
||||
var markersList = []; |
||||
|
||||
function populate() { |
||||
for (var i = 0; i < 100; i++) { |
||||
var m = new L.Marker(getRandomLatLng(map), { draggable: true }); |
||||
markersList.push(m); |
||||
markers.addLayer(m); |
||||
} |
||||
return false; |
||||
} |
||||
function populateRandomVector() { |
||||
for (var i = 0, latlngs = [], len = 20; i < len; i++) { |
||||
latlngs.push(getRandomLatLng(map)); |
||||
} |
||||
var path = new L.Polyline(latlngs); |
||||
map.addLayer(path); |
||||
} |
||||
function getRandomLatLng(map) { |
||||
var bounds = map.getBounds(), |
||||
southWest = bounds.getSouthWest(), |
||||
northEast = bounds.getNorthEast(), |
||||
lngSpan = northEast.lng - southWest.lng, |
||||
latSpan = northEast.lat - southWest.lat; |
||||
|
||||
return new L.LatLng( |
||||
southWest.lat + latSpan * Math.random(), |
||||
southWest.lng + lngSpan * Math.random()); |
||||
} |
||||
|
||||
markers.on('clusterclick', function (a) { |
||||
alert('cluster ' + a.layer.getAllChildMarkers().length); |
||||
}); |
||||
markers.on('click', function (a) { |
||||
alert('marker ' + a.layer); |
||||
}); |
||||
|
||||
populate(); |
||||
map.addLayer(markers); |
||||
|
||||
L.DomUtil.get('moveone').onclick = function () { |
||||
var m = markersList[Math.floor(Math.random() * markersList.length)]; |
||||
var bounds = map.getBounds(), |
||||
southWest = bounds.getSouthWest(), |
||||
northEast = bounds.getNorthEast(), |
||||
lngSpan = northEast.lng - southWest.lng, |
||||
latSpan = northEast.lat - southWest.lat; |
||||
m.setLatLng(new L.LatLng( |
||||
southWest.lat + latSpan * 0.5, |
||||
southWest.lng + lngSpan * 0.5)); |
||||
}; |
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,80 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../dist/MarkerCluster.Default.css" /> |
||||
<script src="../dist/leaflet.markercluster-src.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<button id="populate">Populate 1 marker</button> |
||||
<button id="remove">Remove 1 marker</button> |
||||
<span>Mouse over a cluster to see the bounds of its children and click a cluster to zoom to those bounds</span> |
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = L.latLng(50.5, 30.51); |
||||
|
||||
var map = L.map('map', {center: latlng, zoom: 15, layers: [tiles]}); |
||||
|
||||
var markers = L.markerClusterGroup({ animateAddingMarkers : true }); |
||||
var markersList = []; |
||||
|
||||
function populate() { |
||||
for (var i = 0; i < 100; i++) { |
||||
var m = L.marker(getRandomLatLng(map)); |
||||
markersList.push(m); |
||||
markers.addLayer(m); |
||||
} |
||||
return false; |
||||
} |
||||
function getRandomLatLng(map) { |
||||
var bounds = map.getBounds(), |
||||
southWest = bounds.getSouthWest(), |
||||
northEast = bounds.getNorthEast(), |
||||
lngSpan = northEast.lng - southWest.lng, |
||||
latSpan = northEast.lat - southWest.lat; |
||||
|
||||
return L.latLng( |
||||
southWest.lat + latSpan * Math.random(), |
||||
southWest.lng + lngSpan * Math.random()); |
||||
} |
||||
|
||||
populate(); |
||||
map.addLayer(markers); |
||||
|
||||
for (var i = 0; i < 100; i++) { |
||||
markers.addLayer(markersList[i]); |
||||
} |
||||
|
||||
//Ugly add/remove code |
||||
L.DomUtil.get('populate').onclick = function () { |
||||
var bounds = map.getBounds(), |
||||
southWest = bounds.getSouthWest(), |
||||
northEast = bounds.getNorthEast(), |
||||
lngSpan = northEast.lng - southWest.lng, |
||||
latSpan = northEast.lat - southWest.lat; |
||||
var m = L.marker([ |
||||
southWest.lat + latSpan * 0.5, |
||||
southWest.lng + lngSpan * 0.5]); |
||||
markersList.push(m); |
||||
markers.addLayer(m); |
||||
}; |
||||
L.DomUtil.get('remove').onclick = function () { |
||||
markers.removeLayer(markersList.pop()); |
||||
}; |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,70 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../dist/MarkerCluster.Default.css" /> |
||||
<script src="../dist/leaflet.markercluster-src.js"></script> |
||||
<script type="text/javascript" src="geojson-sample.js"></script> |
||||
|
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<span>Mouse over a cluster to see the bounds of its children and click a cluster to zoom to those bounds</span> |
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = L.latLng(0.78, 102.37); |
||||
|
||||
var map = L.map('map', {center: latlng, zoom: 7, layers: [tiles]}); |
||||
|
||||
|
||||
var geojson = L.geoJson(geojsonSample, { |
||||
|
||||
style: function (feature) { |
||||
return {color: feature.properties.color}; |
||||
}, |
||||
|
||||
onEachFeature: function (feature, layer) { |
||||
var popupText = 'geometry type: ' + feature.geometry.type; |
||||
|
||||
if (feature.properties.color) { |
||||
popupText += '<br/>color: ' + feature.properties.color; |
||||
} |
||||
|
||||
layer.bindPopup(popupText); |
||||
} |
||||
}); |
||||
|
||||
geojson.addLayer(new L.Marker(new L.LatLng(2.745530718801952, 105.194091796875))); |
||||
|
||||
var eye1 = new L.Marker(new L.LatLng(-0.7250783020332547, 101.8212890625)); |
||||
var eye2 = new L.Marker(new L.LatLng(-0.7360637370492077, 103.2275390625)); |
||||
var nose = new L.Marker(new L.LatLng(-1.3292264529974207, 102.5463867187)); |
||||
var mouth = new L.Polyline([ |
||||
new L.LatLng(-1.3841426927920029, 101.7333984375), |
||||
new L.LatLng(-1.6037944300589726, 101.964111328125), |
||||
new L.LatLng(-1.6806671337507222, 102.249755859375), |
||||
new L.LatLng(-1.7355743631421197, 102.67822265625), |
||||
new L.LatLng(-1.5928123762763, 103.0078125), |
||||
new L.LatLng(-1.3292264529974207, 103.3154296875) |
||||
]); |
||||
|
||||
var markers = L.markerClusterGroup(); |
||||
markers.addLayer(geojson).addLayers([eye1,eye2,nose,mouth]); |
||||
|
||||
map.addLayer(markers); |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,104 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../dist/MarkerCluster.css" /> |
||||
<script src="../dist/leaflet.markercluster-src.js"></script> |
||||
|
||||
<style> |
||||
.myclusterA { |
||||
width: 40px; |
||||
height: 40px; |
||||
background-color: greenyellow; |
||||
text-align: center; |
||||
font-size: 24px; |
||||
} |
||||
.myclusterB { |
||||
width: 40px; |
||||
height: 40px; |
||||
background-color: red; |
||||
text-align: center; |
||||
font-size: 24px; |
||||
} |
||||
|
||||
</style> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
|
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = L.latLng(50.5, 30.51); |
||||
|
||||
var map = L.map('map', {center: latlng, zoom: 15, layers: [tiles]}); |
||||
|
||||
//Define a pane above the default markerPane |
||||
map.createPane('paneB').style.zIndex = 610; |
||||
|
||||
//Create two markerClusterGroups, one in the default markerPane, one in our custom pane |
||||
var markersA = createMarkerClusterGroup('myclusterA'); |
||||
var markersB = createMarkerClusterGroup('myclusterB', 'paneB'); |
||||
|
||||
function createMarkerClusterGroup(className, pane) { |
||||
var options = { |
||||
maxClusterRadius: 120, |
||||
iconCreateFunction: function (cluster) { |
||||
var markers = cluster.getAllChildMarkers(); |
||||
var n = 0; |
||||
for (var i = 0; i < markers.length; i++) { |
||||
n += markers[i].number; |
||||
} |
||||
return L.divIcon({ html: n, className: className, iconSize: L.point(40, 40) }); |
||||
}, |
||||
//Disable all of the defaults & specify the pane: |
||||
spiderfyOnMaxZoom: false, |
||||
showCoverageOnHover: false, |
||||
zoomToBoundsOnClick: false |
||||
}; |
||||
if (pane) { |
||||
options.clusterPane = pane; |
||||
} |
||||
var mcg = L.markerClusterGroup(options); |
||||
return(mcg); |
||||
} |
||||
|
||||
function populate(markers) { |
||||
for (var i = 0; i < 100; i++) { |
||||
var m = L.marker(getRandomLatLng(map), { title: i }); |
||||
m.number = i; |
||||
markers.addLayer(m); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
function getRandomLatLng(map) { |
||||
var bounds = map.getBounds(), |
||||
southWest = bounds.getSouthWest(), |
||||
northEast = bounds.getNorthEast(), |
||||
lngSpan = northEast.lng - southWest.lng, |
||||
latSpan = northEast.lat - southWest.lat; |
||||
|
||||
return L.latLng( |
||||
southWest.lat + latSpan * Math.random(), |
||||
southWest.lng + lngSpan * Math.random()); |
||||
} |
||||
|
||||
populate(markersA); |
||||
populate(markersB); |
||||
map.addLayer(markersA); |
||||
map.addLayer(markersB); |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../dist/MarkerCluster.Default.css" /> |
||||
<script src="../dist/leaflet.markercluster-src.js"></script> |
||||
<script src="realworld.388.js"></script> |
||||
|
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<span>Markers will show on the bottom 2 zoom levels even though the markers would normally cluster.</span> |
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Points © 2012 LINZ' |
||||
}), |
||||
latlng = L.latLng(-37.82, 175.24); |
||||
|
||||
var map = L.map('map', {center: latlng, zoom: 13, layers: [tiles]}); |
||||
|
||||
var markers = L.markerClusterGroup({ disableClusteringAtZoom: 17 }); |
||||
|
||||
for (var i = 0; i < addressPoints.length; i++) { |
||||
var a = addressPoints[i]; |
||||
var title = a[2]; |
||||
var marker = L.marker(L.latLng(a[0], a[1]), { title: title }); |
||||
marker.bindPopup(title); |
||||
markers.addLayer(marker); |
||||
} |
||||
|
||||
map.addLayer(markers); |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> |
||||
<link rel="stylesheet" href="mobile.css" /> |
||||
|
||||
<link rel="stylesheet" href="../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../dist/MarkerCluster.Default.css" /> |
||||
<script src="../dist/leaflet.markercluster-src.js"></script> |
||||
<script src="realworld.388.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
|
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Points © 2012 LINZ' |
||||
}), |
||||
latlng = L.latLng(-37.821, 175.22); |
||||
|
||||
var map = L.map('map', {center: latlng, zoom: 15, layers: [tiles]}); |
||||
|
||||
var markers = L.markerClusterGroup(); |
||||
|
||||
for (var i = 0; i < addressPoints.length; i++) { |
||||
var a = addressPoints[i]; |
||||
var title = a[2]; |
||||
var marker = L.marker(L.latLng(a[0], a[1]), { title: title }); |
||||
marker.bindPopup(title); |
||||
markers.addLayer(marker); |
||||
} |
||||
|
||||
map.addLayer(markers); |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../dist/MarkerCluster.Default.css" /> |
||||
<script src="../dist/leaflet.markercluster-src.js"></script> |
||||
|
||||
<script src="realworld.10000.js"></script> |
||||
|
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<span>Mouse over a cluster to see the bounds of its children and click a cluster to zoom to those bounds</span> |
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Points © 2012 LINZ' |
||||
}), |
||||
latlng = L.latLng(-37.89, 175.46); |
||||
|
||||
var map = L.map('map', {center: latlng, zoom: 13, layers: [tiles]}); |
||||
|
||||
var markers = L.markerClusterGroup({ chunkedLoading: true }); |
||||
|
||||
for (var i = 0; i < addressPoints.length; i++) { |
||||
var a = addressPoints[i]; |
||||
var title = a[2]; |
||||
var marker = L.marker(L.latLng(a[0], a[1]), { title: title }); |
||||
marker.bindPopup(title); |
||||
markers.addLayer(marker); |
||||
} |
||||
|
||||
map.addLayer(markers); |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../dist/MarkerCluster.Default.css" /> |
||||
<script src="../dist/leaflet.markercluster-src.js"></script> |
||||
<script src="realworld.388.js"></script> |
||||
|
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<span>Mouse over a cluster to see the bounds of its children and click a cluster to zoom to those bounds</span> |
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Points © 2012 LINZ' |
||||
}), |
||||
latlng = L.latLng(-37.82, 175.24); |
||||
|
||||
var map = L.map('map', {center: latlng, zoom: 13, layers: [tiles]}); |
||||
|
||||
var markers = L.markerClusterGroup(); |
||||
|
||||
for (var i = 0; i < addressPoints.length; i++) { |
||||
var a = addressPoints[i]; |
||||
var title = a[2]; |
||||
var marker = L.marker(new L.LatLng(a[0], a[1]), { title: title }); |
||||
marker.bindPopup(title); |
||||
markers.addLayer(marker); |
||||
} |
||||
|
||||
map.addLayer(markers); |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,78 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../dist/MarkerCluster.Default.css" /> |
||||
<script src="../dist/leaflet.markercluster-src.js"></script> |
||||
|
||||
<script src="realworld.50000.1.js"></script> |
||||
<script src="realworld.50000.2.js"></script> |
||||
|
||||
</head> |
||||
<body> |
||||
|
||||
<div id="progress"><div id="progress-bar"></div></div> |
||||
<div id="map"></div> |
||||
<span>Mouse over a cluster to see the bounds of its children and click a cluster to zoom to those bounds</span> |
||||
<script type="text/javascript"> |
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Points © 2012 LINZ' |
||||
}), |
||||
latlng = L.latLng(-37.79, 175.27); |
||||
|
||||
var map = L.map('map', { center: latlng, zoom: 13, layers: [tiles] }); |
||||
|
||||
var progress = document.getElementById('progress'); |
||||
var progressBar = document.getElementById('progress-bar'); |
||||
|
||||
function updateProgressBar(processed, total, elapsed, layersArray) { |
||||
if (elapsed > 1000) { |
||||
// if it takes more than a second to load, display the progress bar: |
||||
progress.style.display = 'block'; |
||||
progressBar.style.width = Math.round(processed/total*100) + '%'; |
||||
} |
||||
|
||||
if (processed === total) { |
||||
// all markers processed - hide the progress bar: |
||||
progress.style.display = 'none'; |
||||
} |
||||
} |
||||
|
||||
var markers = L.markerClusterGroup({ chunkedLoading: true, chunkProgress: updateProgressBar }); |
||||
|
||||
var markerList = []; |
||||
|
||||
//console.log('start creating markers: ' + window.performance.now()); |
||||
|
||||
for (var i = 0; i < addressPoints.length; i++) { |
||||
var a = addressPoints[i]; |
||||
var title = a[2]; |
||||
var marker = L.marker(L.latLng(a[0], a[1]), { title: title }); |
||||
marker.bindPopup(title); |
||||
markerList.push(marker); |
||||
} |
||||
for (var i = 0; i < addressPoints2.length; i++) { |
||||
var a = addressPoints2[i]; |
||||
var title = a[2]; |
||||
var marker = L.marker(L.latLng(a[0], a[1]), { title: title }); |
||||
marker.bindPopup(title); |
||||
markerList.push(marker); |
||||
} |
||||
|
||||
//console.log('start clustering: ' + window.performance.now()); |
||||
|
||||
markers.addLayers(markerList); |
||||
map.addLayer(markers); |
||||
|
||||
//console.log('end clustering: ' + window.performance.now()); |
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,60 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../dist/MarkerCluster.Default.css" /> |
||||
<script src="../dist/leaflet.markercluster-src.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<span>Click a cluster to zoom to its bounds</span> |
||||
|
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = L.latLng(50.5, 30.51); |
||||
|
||||
var map = L.map('map', {center: latlng, zoom: 15, layers: [tiles]}); |
||||
|
||||
var markers = L.markerClusterGroup({ singleMarkerMode: true}); |
||||
|
||||
function populate() { |
||||
for (var i = 0; i < 100; i++) { |
||||
var m = L.marker(getRandomLatLng(map)); |
||||
markers.addLayer(m); |
||||
} |
||||
return false; |
||||
} |
||||
function getRandomLatLng(map) { |
||||
var bounds = map.getBounds(), |
||||
southWest = bounds.getSouthWest(), |
||||
northEast = bounds.getNorthEast(), |
||||
lngSpan = northEast.lng - southWest.lng, |
||||
latSpan = northEast.lat - southWest.lat; |
||||
|
||||
return L.latLng( |
||||
southWest.lat + latSpan * Math.random(), |
||||
southWest.lng + lngSpan * Math.random()); |
||||
} |
||||
|
||||
markers.on('clusterclick', function (a) { |
||||
a.layer.zoomToBounds(); |
||||
}); |
||||
|
||||
populate(); |
||||
map.addLayer(markers); |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,60 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../dist/MarkerCluster.Default.css" /> |
||||
<script src="../dist/leaflet.markercluster-src.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<button id="populate">Populate 1 marker</button> |
||||
<button id="remove">Remove 1 marker</button> |
||||
|
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = L.latLng(50.5, 30.51); |
||||
|
||||
var map = L.map('map', {center: latlng, zoom: 15, layers: [tiles]}); |
||||
|
||||
var markers = L.markerClusterGroup({ spiderfyOnMaxZoom: false, showCoverageOnHover: false, zoomToBoundsOnClick: false }); |
||||
|
||||
function populate() { |
||||
for (var i = 0; i < 100; i++) { |
||||
var m = L.marker(getRandomLatLng(map)); |
||||
markers.addLayer(m); |
||||
} |
||||
return false; |
||||
} |
||||
function getRandomLatLng(map) { |
||||
var bounds = map.getBounds(), |
||||
southWest = bounds.getSouthWest(), |
||||
northEast = bounds.getNorthEast(), |
||||
lngSpan = northEast.lng - southWest.lng, |
||||
latSpan = northEast.lat - southWest.lat; |
||||
|
||||
return L.latLng( |
||||
southWest.lat + latSpan * Math.random(), |
||||
southWest.lng + lngSpan * Math.random()); |
||||
} |
||||
|
||||
markers.on('clusterclick', function (a) { |
||||
a.layer.spiderfy(); |
||||
}); |
||||
|
||||
populate(); |
||||
map.addLayer(markers); |
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,60 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../dist/MarkerCluster.Default.css" /> |
||||
<script src="../dist/leaflet.markercluster-src.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<span>Click a cluster to zoom to its bounds</span> |
||||
|
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = L.latLng(50.5, 30.51); |
||||
|
||||
var map = L.map('map', {center: latlng, zoom: 15, layers: [tiles]}); |
||||
|
||||
var markers = L.markerClusterGroup({spiderfyOnMaxZoom: false, showCoverageOnHover: false, zoomToBoundsOnClick: false}); |
||||
|
||||
function populate() { |
||||
for (var i = 0; i < 100; i++) { |
||||
var m = L.marker(getRandomLatLng(map)); |
||||
markers.addLayer(m); |
||||
} |
||||
return false; |
||||
} |
||||
function getRandomLatLng(map) { |
||||
var bounds = map.getBounds(), |
||||
southWest = bounds.getSouthWest(), |
||||
northEast = bounds.getNorthEast(), |
||||
lngSpan = northEast.lng - southWest.lng, |
||||
latSpan = northEast.lat - southWest.lat; |
||||
|
||||
return L.latLng( |
||||
southWest.lat + latSpan * Math.random(), |
||||
southWest.lng + lngSpan * Math.random()); |
||||
} |
||||
|
||||
markers.on('clusterclick', function (a) { |
||||
a.layer.zoomToBounds(); |
||||
}); |
||||
|
||||
populate(); |
||||
map.addLayer(markers); |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,59 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../dist/MarkerCluster.Default.css" /> |
||||
<script src="../dist/leaflet.markercluster-src.js"></script> |
||||
<script src="realworld.388.js"></script> |
||||
|
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<button id="doit">Zoom to marker</button> |
||||
<span>When clicked we will zoom down to a marker, spiderfying if required to show it and then open its popup</span> |
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = L.latLng(-37.82, 175.24); |
||||
|
||||
var map = L.map('map', {center: latlng, zoom: 13, layers: [tiles]}); |
||||
|
||||
var markers = L.markerClusterGroup(); |
||||
var markerList = []; |
||||
|
||||
function populate() { |
||||
for (var i = 0; i < addressPoints.length; i++) { |
||||
var a = addressPoints[i]; |
||||
var title = a[2]; |
||||
var marker = L.marker(L.latLng(a[0], a[1]), { title: title }); |
||||
marker.bindPopup(title); |
||||
markers.addLayer(marker); |
||||
markerList.push(marker); |
||||
} |
||||
} |
||||
|
||||
populate(); |
||||
|
||||
map.addLayer(markers); |
||||
|
||||
document.getElementById('doit').onclick = function () { |
||||
var m = markerList[Math.floor(Math.random() * markerList.length)]; |
||||
markers.zoomToShowLayer(m, function () { |
||||
m.openPopup(); |
||||
}); |
||||
}; |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,88 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../dist/MarkerCluster.Default.css" /> |
||||
<script src="../dist/leaflet.markercluster-src.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<button id="populate">Populate 1 marker</button> |
||||
<button id="remove">Remove 1 marker</button> |
||||
|
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = new L.LatLng(50.5, 30.51); |
||||
|
||||
var map = new L.Map('map', {center: latlng, zoom: 15, layers: [tiles]}); |
||||
|
||||
var markers = new L.MarkerClusterGroup(); |
||||
var markersList = []; |
||||
|
||||
function populate() { |
||||
for (var i = 0; i < 100; i++) { |
||||
var m = new L.Marker(getRandomLatLng(map)); |
||||
markersList.push(m); |
||||
markers.addLayer(m); |
||||
} |
||||
return false; |
||||
} |
||||
function populateRandomVector() { |
||||
for (var i = 0, latlngs = [], len = 20; i < len; i++) { |
||||
latlngs.push(getRandomLatLng(map)); |
||||
} |
||||
var path = new L.Polyline(latlngs); |
||||
map.addLayer(path); |
||||
} |
||||
function getRandomLatLng(map) { |
||||
var bounds = map.getBounds(), |
||||
southWest = bounds.getSouthWest(), |
||||
northEast = bounds.getNorthEast(), |
||||
lngSpan = northEast.lng - southWest.lng, |
||||
latSpan = northEast.lat - southWest.lat; |
||||
|
||||
return new L.LatLng( |
||||
southWest.lat + latSpan * Math.random(), |
||||
southWest.lng + lngSpan * Math.random()); |
||||
} |
||||
|
||||
markers.on('clusterclick', function (a) { |
||||
alert('cluster ' + a.layer.getAllChildMarkers().length); |
||||
}); |
||||
markers.on('click', function (a) { |
||||
alert('marker ' + a.layer); |
||||
}); |
||||
|
||||
populate(); |
||||
map.addLayer(markers); |
||||
|
||||
L.DomUtil.get('populate').onclick = function () { |
||||
var bounds = map.getBounds(), |
||||
southWest = bounds.getSouthWest(), |
||||
northEast = bounds.getNorthEast(), |
||||
lngSpan = northEast.lng - southWest.lng, |
||||
latSpan = northEast.lat - southWest.lat; |
||||
var m = new L.Marker(new L.LatLng( |
||||
southWest.lat + latSpan * 0.5, |
||||
southWest.lng + lngSpan * 0.5)); |
||||
markersList.push(m); |
||||
markers.addLayer(m); |
||||
}; |
||||
L.DomUtil.get('remove').onclick = function () { |
||||
markers.removeLayer(markersList.pop()); |
||||
}; |
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,6 @@
|
||||
html, body, #map { |
||||
margin: 0; |
||||
padding: 0; |
||||
width: 100%; |
||||
height: 100%; |
||||
} |
@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="../screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.Default.css" /> |
||||
<script src="../../src/DistanceGrid.js"></script> |
||||
<script src="../../src/MarkerCluster.js"></script> |
||||
<script src="../../src/MarkerClusterGroup.js"></script> |
||||
<script src="../../src/MarkerCluster.QuickHull.js"></script> |
||||
<script src="../../src/MarkerCluster.Spiderfier.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<button id="doit">Add 1000 Markers</button><br/> |
||||
<span>Bug <a href="https://github.com/danzel/Leaflet.markercluster/issues/51">#51</a>. Click the button. It will add 1000 markers to the map. this should be fast, but previously in (non-IE browsers) it was very slow.</span><br/> |
||||
<span>Bug <a href="https://github.com/danzel/Leaflet.markercluster/issues/43">#43</a>. Improving performance more.</span><br/> |
||||
<span id="time"></span> |
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = new L.LatLng(50.5, 30.51); |
||||
|
||||
var map = new L.Map('map', {center: latlng, zoom: 15, layers: [tiles]}); |
||||
|
||||
var markers = new L.MarkerClusterGroup(); |
||||
var markersList = []; |
||||
|
||||
function getRandomLatLng(map) { |
||||
var bounds = map.getBounds(), |
||||
southWest = bounds.getSouthWest(), |
||||
northEast = bounds.getNorthEast(), |
||||
lngSpan = northEast.lng - southWest.lng, |
||||
latSpan = northEast.lat - southWest.lat; |
||||
|
||||
return new L.LatLng( |
||||
southWest.lat + latSpan * Math.random(), |
||||
southWest.lng + lngSpan * Math.random()); |
||||
} |
||||
|
||||
function populate(length) { |
||||
var prestart = +new Date(); |
||||
var list = [], i; |
||||
for (i = 0; i < length; i++) { |
||||
var m = new L.Marker(getRandomLatLng(map)); |
||||
list.push(m); |
||||
} |
||||
|
||||
var start = +new Date(); |
||||
|
||||
markers.addLayers(list); |
||||
|
||||
var end = +new Date(); |
||||
|
||||
document.getElementById('time').innerHTML = 'Creating 1000 markers took: ' + (start - prestart) + 'ms . Appending 1000 markers took: ' + (end - start) + 'ms'; |
||||
|
||||
return false; |
||||
} |
||||
|
||||
populate(1000); |
||||
var start = +new Date(); |
||||
map.addLayer(markers); |
||||
var end = +new Date(); |
||||
document.getElementById('time').innerHTML += ' . Adding to map took: ' + (end - start) + 'ms'; |
||||
|
||||
//Ugly add/remove code |
||||
L.DomUtil.get('doit').onclick = function () { |
||||
populate(1000); |
||||
}; |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,52 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="../screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.Default.css" /> |
||||
<script src="../../src/DistanceGrid.js"></script> |
||||
<script src="../../src/MarkerCluster.js"></script> |
||||
<script src="../../src/MarkerClusterGroup.js"></script> |
||||
<script src="../../src/MarkerCluster.QuickHull.js"></script> |
||||
<script src="../../src/MarkerCluster.Spiderfier.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<button id="populate">Populate 1 marker</button> |
||||
<span>Bug <a href="https://github.com/danzel/Leaflet.markercluster/issues/69">#69</a>. Click the button 2+ times. Zoom out. Should just be a single cluster but instead one of the child markers is still visible.</span><br/> |
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = new L.LatLng(50.5, 30.51); |
||||
|
||||
var map = new L.Map('map', {center: new L.LatLng(50.41, 30.51), zoom: 17, layers: [tiles]}); |
||||
|
||||
var markers = new L.MarkerClusterGroup({ animateAddingMarkers : true }); |
||||
var markersList = []; |
||||
|
||||
function populate() { |
||||
var m = new L.Marker(latlng); |
||||
markersList.push(m); |
||||
markers.addLayer(m); |
||||
return false; |
||||
} |
||||
|
||||
map.addLayer(markers); |
||||
|
||||
//Ugly add/remove code |
||||
L.DomUtil.get('populate').onclick = function () { |
||||
populate(); |
||||
}; |
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,62 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="../screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.Default.css" /> |
||||
<script src="../../src/DistanceGrid.js"></script> |
||||
<script src="../../src/MarkerCluster.js"></script> |
||||
<script src="../../src/MarkerClusterGroup.js"></script> |
||||
<script src="../../src/MarkerCluster.QuickHull.js"></script> |
||||
<script src="../../src/MarkerCluster.Spiderfier.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<span>Bug <a href="https://github.com/danzel/Leaflet.markercluster/issues/64">#64</a>. Nothing should appear on the map.</span><br/> |
||||
<span id="time"></span> |
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = new L.LatLng(50.5, 30.51); |
||||
|
||||
var map = new L.Map('map', {center: latlng, zoom: 15, layers: [tiles]}); |
||||
|
||||
var markers = new L.MarkerClusterGroup(); |
||||
|
||||
function getRandomLatLng(map) { |
||||
var bounds = map.getBounds(), |
||||
southWest = bounds.getSouthWest(), |
||||
northEast = bounds.getNorthEast(), |
||||
lngSpan = northEast.lng - southWest.lng, |
||||
latSpan = northEast.lat - southWest.lat; |
||||
|
||||
return new L.LatLng( |
||||
southWest.lat + latSpan * Math.random(), |
||||
southWest.lng + lngSpan * Math.random()); |
||||
} |
||||
|
||||
function populate(length) { |
||||
var list = [], i; |
||||
for (i = 0; i < length; i++) { |
||||
var m = new L.Marker(getRandomLatLng(map)); |
||||
markers.addLayer(m); |
||||
markers.removeLayer(m); |
||||
} |
||||
} |
||||
|
||||
populate(1000); |
||||
map.addLayer(markers); |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,47 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="../screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.Default.css" /> |
||||
<script src="../../src/DistanceGrid.js"></script> |
||||
<script src="../../src/MarkerCluster.js"></script> |
||||
<script src="../../src/MarkerClusterGroup.js"></script> |
||||
<script src="../../src/MarkerCluster.QuickHull.js"></script> |
||||
<script src="../../src/MarkerCluster.Spiderfier.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<button id="doit">Zoom in</button><br/> |
||||
<span>Bug <a href="https://github.com/leaflet/Leaflet.markercluster/issues/216">#216</a>. Click the button. It will zoom in, leaflet will not do an animation for the zoom. A marker should be visible.</span><br/> |
||||
<span id="time"></span> |
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = new L.LatLng(-37.36142550190516, 174.254150390625); |
||||
|
||||
var map = new L.Map('map', {center: latlng, zoom: 7, layers: [tiles]}); |
||||
|
||||
var markers = new L.MarkerClusterGroup(); |
||||
markers.addLayer(new L.Marker([-37.77852090603777, 175.3103667497635])); //The one we zoom in on |
||||
markers.addLayer(new L.Marker([-37.711800591811055, 174.50034790039062])); //Marker that we cluster with at the top zoom level, but not 1 level down |
||||
map.addLayer(markers); |
||||
|
||||
//Ugly add/remove code |
||||
L.DomUtil.get('doit').onclick = function () { |
||||
map.setView([-37.77852090603777, 175.3103667497635], 15); |
||||
}; |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,59 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="../screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.Default.css" /> |
||||
<script src="../../src/DistanceGrid.js"></script> |
||||
<script src="../../src/MarkerCluster.js"></script> |
||||
<script src="../../src/MarkerClusterGroup.js"></script> |
||||
<script src="../../src/MarkerCluster.QuickHull.js"></script> |
||||
<script src="../../src/MarkerCluster.Spiderfier.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<span>Bug <a href="https://github.com/leaflet/Leaflet.markercluster/issues/344">#344</a>. Click the cluster at the screen edge. Map will zoom to it and its markers will appear, but it will not disappear.</span><br/> |
||||
<span id="time"></span> |
||||
<script type="text/javascript"> |
||||
|
||||
var iconCreateFunction = function (cluster) { |
||||
var childCount = cluster.getChildCount(); |
||||
|
||||
var c = ' marker-cluster-'; |
||||
if (childCount < 10) { |
||||
c += 'small'; |
||||
} else if (childCount < 100) { |
||||
c += 'medium'; |
||||
} else { |
||||
c += 'large'; |
||||
} |
||||
|
||||
return new L.DivIcon({ html: '<div><span>' + childCount + '</span></div>', className: 'marker-cluster' + c, iconSize: new L.Point(270, 270) }); |
||||
}; |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = new L.LatLng(54.18815548107151, 6.1083984375); |
||||
|
||||
var map = new L.Map('map', {center: latlng, zoom: 5, layers: [tiles]}); |
||||
|
||||
var markers = new L.MarkerClusterGroup({ iconCreateFunction: iconCreateFunction }); |
||||
var markersList = []; |
||||
|
||||
markers.addLayer(new L.Marker([41.969073, 5])); |
||||
markers.addLayer(new L.Marker([41.969073, 7])); |
||||
|
||||
map.addLayer(markers); |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,106 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="../screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.Default.css" /> |
||||
<script src="../../dist/leaflet.markercluster-src.js"></script> |
||||
</head> |
||||
<body style="font-family: verdana; font-size: 80%;"> |
||||
|
||||
<div id="map"></div> |
||||
Click on the cluster to <strong>spiderfy</strong> and then <button id="moveTrain">move train</button><br/> |
||||
<br/> |
||||
<div style="color: #888;"><strong>Note:</strong> The marker on the old cluster position comes back on next move or on map scrolling.</div> |
||||
|
||||
<script type="text/javascript"> |
||||
|
||||
var stationJson = { |
||||
"type":"FeatureCollection", |
||||
"features":[ |
||||
{"type":"Feature","id":1,"properties":{"type":"station","name":"Appenzell"},"geometry":{"type":"Point","coordinates":[9.40991,47.32849]}}, |
||||
{"type":"Feature","id":2,"properties":{"type":"station","name":"Gais"},"geometry":{"type":"Point","coordinates":[9.45107,47.36073]}}, |
||||
{"type":"Feature","id":3,"properties":{"type":"station","name":"St. Gallen"},"geometry":{"type":"Point","coordinates":[9.36901,47.42208]}}, |
||||
{"type":"Feature","id":4,"properties":{"type":"station","name":"Teufen"},"geometry":{"type":"Point","coordinates":[9.390178,47.390157]}} |
||||
]}; |
||||
|
||||
var trainJson = [{ |
||||
"type":"FeatureCollection", |
||||
"features":[ |
||||
{"type":"Feature","id":10,"properties":{"type":"train","name":"Testtrain"},"geometry":{"type":"Point","coordinates":[9.36901,47.42208]}} |
||||
]},{ |
||||
"type":"FeatureCollection", |
||||
"features":[ |
||||
{"type":"Feature","id":10,"properties":{"type":"train","name":"Testtrain"},"geometry":{"type":"Point","coordinates":[9.390178,47.390157]}} |
||||
]},{ |
||||
"type":"FeatureCollection", |
||||
"features":[ |
||||
{"type":"Feature","id":10,"properties":{"type":"train","name":"Testtrain"},"geometry":{"type":"Point","coordinates":[9.45107,47.36073]}} |
||||
]},{ |
||||
"type":"FeatureCollection", |
||||
"features":[ |
||||
{"type":"Feature","id":10,"properties":{"type":"train","name":"Testtrain"},"geometry":{"type":"Point","coordinates":[9.40991,47.32849]}} |
||||
]}]; |
||||
|
||||
var trainPosition = 0, |
||||
trainDirection = 'up'; |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
map = new L.Map('map', {zoom: 15, layers: [tiles]}), |
||||
markers = new L.MarkerClusterGroup({ spiderfyOnMaxZoom: false, showCoverageOnHover: false, zoomToBoundsOnClick: false }); |
||||
|
||||
var stationGeoJsonLayer = L.geoJson(stationJson, { |
||||
onEachFeature: function (feature, layer) { |
||||
layer.bindPopup(feature.properties.name); |
||||
} |
||||
}), |
||||
trainGeoJsonLayer = L.geoJson(trainJson[trainPosition], { |
||||
onEachFeature: function (feature, layer) { |
||||
layer.bindPopup(feature.properties.name); |
||||
} |
||||
}); |
||||
|
||||
// initial load |
||||
markers.addLayer(stationGeoJsonLayer); |
||||
markers.addLayer(trainGeoJsonLayer); |
||||
map.fitBounds(markers.getBounds()); |
||||
|
||||
markers.on('clusterclick', function (a) { |
||||
a.layer.spiderfy(); |
||||
}); |
||||
|
||||
map.addLayer(markers); |
||||
|
||||
/** |
||||
* Demonstration method that simulates that we got a new geoJson object with updated train positions. |
||||
*/ |
||||
function moveTrain() { |
||||
if (trainDirection == 'up') trainPosition++; |
||||
else if (trainDirection == 'down') trainPosition--; |
||||
if (trainPosition == trainJson.length-1) trainDirection = 'down'; |
||||
else if (trainPosition == 0) trainDirection = 'up'; |
||||
|
||||
// build a new geoJson layer with the new train information |
||||
trainGeoJsonLayer = L.geoJson(trainJson[trainPosition], {}); |
||||
|
||||
// update the cluster markers with both layers (stations first so that the station marker is always the first on spider. |
||||
markers.clearLayers(); |
||||
markers.addLayer(stationGeoJsonLayer); |
||||
markers.addLayer(trainGeoJsonLayer); |
||||
} |
||||
|
||||
L.DomUtil.get('moveTrain').onclick = function () { |
||||
moveTrain(); |
||||
}; |
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="../screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.Default.css" /> |
||||
<script src="../../src/DistanceGrid.js"></script> |
||||
<script src="../../src/MarkerCluster.js"></script> |
||||
<script src="../../src/MarkerClusterGroup.js"></script> |
||||
<script src="../../src/MarkerCluster.QuickHull.js"></script> |
||||
<script src="../../src/MarkerCluster.Spiderfier.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<button id="doit">AddMarker</button><button id="doit2">Add by Timer</button><br/> |
||||
<span>Bug <a href="https://github.com/danzel/Leaflet.markercluster/issues/114">#114</a>. Markers are added to the map periodically using addLayers. Bug was that after becoming a cluster (size 2 or 3 usually) they would never change again even if more markers were added to them.</span><br/> |
||||
|
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = new L.LatLng(40.782982, -73.969452); |
||||
|
||||
var map = new L.Map('map', { |
||||
center: latlng, |
||||
zoom: 12, |
||||
maxZoom: 12, |
||||
layers: [tiles] |
||||
}); |
||||
|
||||
var markerCluster = new L.MarkerClusterGroup(); |
||||
map.addLayer(markerCluster); |
||||
|
||||
function getRandomLatLng() { |
||||
return [ |
||||
40.782982 + (Math.random() > 0.5 ? 0.5 : -0.5) * Math.random(), |
||||
-73.969452 + (Math.random() > 0.5 ? 0.5 : -0.5) * Math.random() |
||||
]; |
||||
} |
||||
|
||||
document.getElementById('doit').onclick = function () { |
||||
markerCluster.addLayers([new L.Marker(map.getCenter())]); |
||||
}; |
||||
document.getElementById('doit2').onclick = function () { |
||||
setInterval(function () { |
||||
var n = 100; |
||||
var markers = new Array(); |
||||
|
||||
for (var i = 0; i < n; i++) { |
||||
markers.push(L.marker(getRandomLatLng())); |
||||
} |
||||
|
||||
markerCluster.addLayers(markers); |
||||
|
||||
}, 1000); |
||||
}; |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,75 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.4/dist/leaflet.css" integrity="sha384-BF7C732iE6WuqJMhUnTNJJLVvW1TIP87P2nMDY7aN2j2EJFWIaqK89j3WlirhFZU" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.3.4/dist/leaflet-src.js" integrity="sha384-oMM5jge511WERo7suehl8Npas4BrPvBEOY54KSP3MygO5gqNxTMKKIcMkS/E9JEX" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="../screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.Default.css" /> |
||||
<script src="../../dist/leaflet.markercluster.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<span>Bug <a href="https://github.com/Leaflet/Leaflet.markercluster/issues/907">#907</a>. Drag a marker from a spiderfied cluster over other clusters.</span><br/> |
||||
<span>Bug <a href="https://github.com/Leaflet/Leaflet.markercluster/issues/808">#808</a>. Drag a marker and while dragging zoom out with scroll-wheel.</span><br/> |
||||
|
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 12, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = new L.LatLng(48.85, 2.35); |
||||
|
||||
var map = new L.Map('map', {center: latlng, zoom: 12, layers: [tiles]}); |
||||
|
||||
var mcg = new L.MarkerClusterGroup(); |
||||
map.addLayer(mcg); |
||||
|
||||
var dragMarker; |
||||
var lastCluster; |
||||
var oldZIndex; |
||||
for (var i = 0; i < 25; i += 1) { |
||||
L.marker(getRandomLatLng(), { |
||||
draggable: true |
||||
}).addTo(mcg).on("dragstart", function(event) { |
||||
oldZIndex = event.target._zIndex; |
||||
event.target.setZIndexOffset(-1000); |
||||
dragMarker = this; |
||||
}).on("dragend", function(event) { |
||||
event.target.setZIndexOffset(oldZIndex); |
||||
dragMarker = null; |
||||
if (lastCluster) { |
||||
lastCluster.unspiderfy(); |
||||
} |
||||
lastCluster = null |
||||
}); |
||||
} |
||||
mcg.on('clustermouseover', function (event) { |
||||
if (dragMarker && lastCluster !== event.layer) { |
||||
if (lastCluster) { |
||||
mcg.once("unspiderfied", function() { // wait for animation end |
||||
event.layer.spiderfy(); |
||||
}); |
||||
lastCluster.unspiderfy(); |
||||
} else { |
||||
event.layer.spiderfy(); |
||||
} |
||||
lastCluster = event.layer; |
||||
} |
||||
}); |
||||
|
||||
function getRandomLatLng() { |
||||
return [ |
||||
48.8 + 0.1 * Math.random(), |
||||
2.25 + 0.2 * Math.random() |
||||
]; |
||||
} |
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,74 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="../screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.Default.css" /> |
||||
<script src="../../src/DistanceGrid.js"></script> |
||||
<script src="../../src/MarkerCluster.js"></script> |
||||
<script src="../../src/MarkerClusterGroup.js"></script> |
||||
<script src="../../src/MarkerCluster.QuickHull.js"></script> |
||||
<script src="../../src/MarkerCluster.Spiderfier.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<p>Whenever a marker is clicked it is removed from the clusterer and added directly to the map instead.</p> |
||||
<p>Click Marker on Left, zoom out 1 layer, click marker on right.</p> |
||||
<p>Expected behaviour: Both markers are shown. Bugged behaviour: Both markers are on map with opacity 0.</p> |
||||
<pre id="log"></pre> |
||||
|
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = new L.LatLng(50.5, 30.51); |
||||
|
||||
var map = new L.Map('map', {center: latlng, zoom: 15, layers: [tiles]}); |
||||
|
||||
var markers = new L.MarkerClusterGroup({ animateAddingMarkers: true }); |
||||
var markersList = []; |
||||
var m; |
||||
|
||||
m = new L.Marker([50.5, 30.51]); |
||||
markersList.push(m); |
||||
markers.addLayer(m); |
||||
m = new L.Marker([50.5, 30.515]); |
||||
markersList.push(m); |
||||
markers.addLayer(m); |
||||
|
||||
map.addLayer(markers); |
||||
|
||||
var lastClicked = null; |
||||
markers.on('click', function (m) { |
||||
console.log('clicked ' + m); |
||||
if (lastClicked) { |
||||
map.removeLayer(lastClicked); |
||||
markers.addLayer(lastClicked); |
||||
} |
||||
|
||||
lastClicked = m.layer; |
||||
|
||||
markers.removeLayer(lastClicked); |
||||
map.addLayer(lastClicked); |
||||
}); |
||||
|
||||
map.on('click', function () { |
||||
console.log('map clicked'); |
||||
if (lastClicked) { |
||||
map.removeLayer(lastClicked); |
||||
markers.addLayer(lastClicked); |
||||
} |
||||
lastClicked = null; |
||||
}); |
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,65 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="../screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.Default.css" /> |
||||
<script src="../../src/DistanceGrid.js"></script> |
||||
<script src="../../src/MarkerCluster.js"></script> |
||||
<script src="../../src/MarkerClusterGroup.js"></script> |
||||
<script src="../../src/MarkerCluster.QuickHull.js"></script> |
||||
<script src="../../src/MarkerCluster.Spiderfier.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<button id="doit">Remove and add direct to map</button><button id="doit2">clearLayers</button><button id="doit3">removeLayers</button><br/> |
||||
<span>Bug <a href="https://github.com/danzel/Leaflet.markercluster/issues/54">#54</a>. Spiderfy the cluster then click the button. Should result in 2 markers right beside each other on the map.</span><br/> |
||||
<span>Bug <a href="https://github.com/danzel/Leaflet.markercluster/issues/53">#53</a>. Spiderfy the cluster then click the button. Spider lines remain on the map.</span><br/> |
||||
<span>Bug <a href="https://github.com/danzel/Leaflet.markercluster/issues/49">#49</a>. Spiderfy the cluster then click the second button. Spider lines remain on the map. Click the map to get an error.</span> |
||||
|
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = new L.LatLng(50.5, 30.51); |
||||
|
||||
var map = new L.Map('map', {center: latlng, zoom: 15, layers: [tiles]}); |
||||
|
||||
var markers = new L.MarkerClusterGroup(); |
||||
var markersList = []; |
||||
var m; |
||||
|
||||
m = new L.Marker([50.5, 30.51]); |
||||
markersList.push(m); |
||||
markers.addLayer(m); |
||||
m = new L.Marker([50.5, 30.5101]); |
||||
markersList.push(m); |
||||
markers.addLayer(m); |
||||
|
||||
map.addLayer(markers); |
||||
|
||||
//Ugly add/remove code |
||||
L.DomUtil.get('doit').onclick = function () { |
||||
map.removeLayer(markers); |
||||
map.addLayer(markersList[0]); |
||||
map.addLayer(markersList[1]); |
||||
}; |
||||
L.DomUtil.get('doit2').onclick = function () { |
||||
markers.clearLayers(); |
||||
}; |
||||
L.DomUtil.get('doit3').onclick = function () { |
||||
markers.removeLayers(markersList); |
||||
}; |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="../screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.Default.css" /> |
||||
<script src="../../src/DistanceGrid.js"></script> |
||||
<script src="../../src/MarkerCluster.js"></script> |
||||
<script src="../../src/MarkerClusterGroup.js"></script> |
||||
<script src="../../src/MarkerCluster.QuickHull.js"></script> |
||||
<script src="../../src/MarkerCluster.Spiderfier.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<a href="#" onclick="swapLayers()">1 - Swap layers</a><br> |
||||
<a href="#" onclick="removeMarker()">2 - Remove all markers</a><br> |
||||
<a href="#" onclick="swapLayers()">3 - Swap layers again => Marker is still there<a/></br> |
||||
|
||||
<span>Bug <a href="https://github.com/danzel/Leaflet.markercluster/issues/160">#160</a>. Click 1,2,3. There should be nothing on the map.</span><br/> |
||||
<script type="text/javascript"> |
||||
|
||||
var map = new L.Map('map'); |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}); |
||||
map.addLayer(tiles); |
||||
|
||||
var objectBounds = [[44.98131207805678, 6.0726203025917], [44.981459751363204, 6.073026722623153]]; |
||||
map.fitBounds(new L.LatLngBounds(objectBounds)); |
||||
|
||||
var markers1 = new L.MarkerClusterGroup(); |
||||
var markers2 = new L.MarkerClusterGroup(); |
||||
|
||||
map.addLayer(markers1); |
||||
|
||||
var aMarker = new L.Marker(new L.LatLng(44.9813, 6.072620)); |
||||
var anotherMarker = new L.Marker(new L.LatLng(44.9814, 6.072621)); |
||||
|
||||
markers1.addLayer(aMarker); |
||||
markers2.addLayer(anotherMarker); |
||||
|
||||
swapLayers = function(){ |
||||
if (map.hasLayer(markers1)){ |
||||
map.removeLayer(markers1); |
||||
map.addLayer(markers2); |
||||
}else{ |
||||
map.removeLayer(markers2); |
||||
map.addLayer(markers1); |
||||
} |
||||
}; |
||||
|
||||
removeMarker = function(){ |
||||
markers1.removeLayer(aMarker); |
||||
markers2.removeLayer(anotherMarker); |
||||
}; |
||||
|
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="../screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.Default.css" /> |
||||
<script src="../../src/DistanceGrid.js"></script> |
||||
<script src="../../src/MarkerCluster.js"></script> |
||||
<script src="../../src/MarkerClusterGroup.js"></script> |
||||
<script src="../../src/MarkerCluster.QuickHull.js"></script> |
||||
<script src="../../src/MarkerCluster.Spiderfier.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<button id="doit">setView</button><br/> |
||||
<span>Bug <a href="https://github.com/danzel/Leaflet.markercluster/issues/63">#63</a>. Zoom down on the very left side untill markers are visible. Click the button. Scroll to the left in one go, those markers should be in clusters but the actual markers will still be visible.</span><br/> |
||||
<span id="time"></span> |
||||
<script type="text/javascript"> |
||||
|
||||
//Mobile does different bounds to desktop, makes the bug easier to reproduce |
||||
L.Browser.mobile = true; |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = new L.LatLng(50.5, 30.51); |
||||
|
||||
var map = new L.Map('map', {center: latlng, zoom: 15, layers: [tiles]}); |
||||
|
||||
var markers = new L.MarkerClusterGroup(); |
||||
var markersList = []; |
||||
|
||||
function getRandomLatLng(map) { |
||||
var bounds = map.getBounds(), |
||||
southWest = bounds.getSouthWest(), |
||||
northEast = bounds.getNorthEast(), |
||||
lngSpan = northEast.lng - southWest.lng, |
||||
latSpan = northEast.lat - southWest.lat; |
||||
|
||||
return new L.LatLng( |
||||
southWest.lat + latSpan * Math.random(), |
||||
southWest.lng + lngSpan * Math.random()); |
||||
} |
||||
|
||||
function populate(length) { |
||||
for (var i = 0; i < length; i++) { |
||||
var m = new L.Marker(getRandomLatLng(map)); |
||||
markers.addLayer(m); |
||||
} |
||||
} |
||||
|
||||
populate(1000); |
||||
map.addLayer(markers); |
||||
|
||||
L.DomUtil.get('doit').onclick = function () { |
||||
map.setView(new L.LatLng(50.5, 30.525), 15); |
||||
}; |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,63 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="../screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.Default.css" /> |
||||
<script src="../../src/DistanceGrid.js"></script> |
||||
<script src="../../src/MarkerCluster.js"></script> |
||||
<script src="../../src/MarkerClusterGroup.js"></script> |
||||
<script src="../../src/MarkerCluster.QuickHull.js"></script> |
||||
<script src="../../src/MarkerCluster.Spiderfier.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<button id="doit">open popup</button><br/> |
||||
<span>Bug <a href="https://github.com/danzel/Leaflet.markercluster/issues/65">#65</a>. Click 2 then click the button. You should be scrolled to the marker, old behaviour would zoom you out.</span><br/> |
||||
<span id="time"></span> |
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = new L.LatLng(50.5, 30.51); |
||||
|
||||
var map = new L.Map('map', {center: latlng, zoom: 15, layers: [tiles]}); |
||||
|
||||
var markers = new L.MarkerClusterGroup(); |
||||
var markersList = []; |
||||
|
||||
var m = new L.Marker(new L.LatLng(50.507, 30.502)); |
||||
m.bindPopup('asdasd'); |
||||
markersList.push(m); |
||||
markers.addLayer(m); |
||||
|
||||
|
||||
m = new L.Marker(new L.LatLng(50.493, 30.518)); |
||||
markersList.push(m); |
||||
markers.addLayer(m); |
||||
|
||||
m = new L.Marker(new L.LatLng(50.493, 30.518)); |
||||
markersList.push(m); |
||||
markers.addLayer(m); |
||||
|
||||
|
||||
map.addLayer(markers); |
||||
|
||||
L.DomUtil.get('doit').onclick = function () { |
||||
markers.zoomToShowLayer(markersList[0], function () { |
||||
markersList[0].openPopup(); |
||||
}); |
||||
}; |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,56 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="../screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../../dist/MarkerCluster.Default.css" /> |
||||
<script src="../../src/DistanceGrid.js"></script> |
||||
<script src="../../src/MarkerCluster.js"></script> |
||||
<script src="../../src/MarkerClusterGroup.js"></script> |
||||
<script src="../../src/MarkerCluster.QuickHull.js"></script> |
||||
<script src="../../src/MarkerCluster.Spiderfier.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<button id="doit">open popup</button><br/> |
||||
<span>Bug <a href="https://github.com/danzel/Leaflet.markercluster/issues/286">#286 (from @Grsmto)</a>. Click the button. The cluster should spiderfy and show the popup, old behaviour did nothing.</span><br/> |
||||
<span id="time"></span> |
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = new L.LatLng(50.5, 30.51); |
||||
|
||||
var map = new L.Map('map', {center: latlng, zoom: 18, layers: [tiles]}); |
||||
|
||||
var markers = new L.MarkerClusterGroup(); |
||||
var markersList = []; |
||||
|
||||
for (var i = 0; i < 3; i++) { |
||||
var m = new L.Marker(latlng); |
||||
m.bindPopup('asdasd' + i); |
||||
markersList.push(m); |
||||
markers.addLayer(m); |
||||
} |
||||
|
||||
map.addLayer(markers); |
||||
|
||||
L.DomUtil.get('doit').onclick = function () { |
||||
//debugger; |
||||
markers.zoomToShowLayer(markersList[0], function () { |
||||
markersList[0].openPopup(); |
||||
}); |
||||
}; |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,393 @@
|
||||
|
||||
//An extract of address points from the LINZ bulk extract: http://www.linz.govt.nz/survey-titles/landonline-data/landonline-bde
|
||||
//Should be this data set: http://data.linz.govt.nz/#/layer/779-nz-street-address-electoral/
|
||||
var addressPoints = [ |
||||
[-37.8210922667, 175.2209316333, "2"], |
||||
[-37.8210819833, 175.2213903167, "3"], |
||||
[-37.8210881833, 175.2215004833, "3A"], |
||||
[-37.8211946833, 175.2213655333, "1"], |
||||
[-37.8209458667, 175.2214051333, "5"], |
||||
[-37.8208292333, 175.2214374833, "7"], |
||||
[-37.8325816, 175.2238798667, "537"], |
||||
[-37.8315855167, 175.2279767, "454"], |
||||
[-37.8096336833, 175.2223743833, "176"], |
||||
[-37.80970685, 175.2221815833, "178"], |
||||
[-37.8102146667, 175.2211562833, "190"], |
||||
[-37.8088037167, 175.2242227, "156"], |
||||
[-37.8112330167, 175.2193425667, "210"], |
||||
[-37.8116368667, 175.2193005167, "212"], |
||||
[-37.80812645, 175.2255449333, "146"], |
||||
[-37.8080231333, 175.2286383167, "125"], |
||||
[-37.8089538667, 175.2222222333, "174"], |
||||
[-37.8080905833, 175.2275400667, "129"], |
||||
[-37.808811, 175.2227592833, "172"], |
||||
[-37.80832975, 175.2276898167, "131"], |
||||
[-37.8089395333, 175.2281710333, "133"], |
||||
[-37.8093421, 175.2274883167, "135"], |
||||
[-37.8084820833, 175.22601925, "137"], |
||||
[-37.80881015, 175.22622865, "139"], |
||||
[-37.8090947667, 175.2263585667, "141"], |
||||
[-37.8092962333, 175.2244872333, "147"], |
||||
[-37.8091016667, 175.2249140167, "145"], |
||||
[-37.8088785167, 175.2253611667, "143"], |
||||
[-37.80825965, 175.22530115, "148"], |
||||
[-37.80995685, 175.2238554333, "153"], |
||||
[-37.80975435, 175.2238417833, "151"], |
||||
[-37.80950755, 175.2237912, "149"], |
||||
[-37.8092772667, 175.2231980833, "170"], |
||||
[-37.8082753833, 175.20672975, "4"], |
||||
[-37.8078434833, 175.211822, "56"], |
||||
[-37.8083775667, 175.2090812333, "30B"], |
||||
[-37.8084588, 175.2058838167, "174"], |
||||
[-37.8088788333, 175.2062702833, "175"], |
||||
[-37.8091632833, 175.20514875, "182A"], |
||||
[-37.8094891167, 175.20384695, "202"], |
||||
[-37.8156715667, 175.2034881667, "277"], |
||||
[-37.8109189333, 175.2024631, "220"], |
||||
[-37.8108164333, 175.2039622, "219"], |
||||
[-37.8125773667, 175.2026079667, "238"], |
||||
[-37.8125799333, 175.2032824, "241A"], |
||||
[-37.8125869, 175.2037423833, "241C"], |
||||
[-37.8140266833, 175.2025706, "256"], |
||||
[-37.80932, 175.2051094333, "182B"], |
||||
[-37.8098799667, 175.2040444167, "197"], |
||||
[-37.8094298833, 175.20561245, "189"], |
||||
[-37.8172409333, 175.2035291167, "287"], |
||||
[-37.8232166667, 175.22452865, "2028"], |
||||
[-37.8225024333, 175.2249944667, "2022"], |
||||
[-37.82334135, 175.2244748667, "2030"], |
||||
[-37.8229725333, 175.2246809333, "2026"], |
||||
[-37.8224034667, 175.22507345, "2020"], |
||||
[-37.8227806, 175.2248285833, "2024"], |
||||
[-37.8178801, 175.2181871667, "6"], |
||||
[-37.81811315, 175.2180543667, "4"], |
||||
[-37.8181739833, 175.21851995, "1"], |
||||
[-37.81797515, 175.2186312, "3"], |
||||
[-37.8181787, 175.2176995, "2A"], |
||||
[-37.8183385333, 175.21812895, "2"], |
||||
[-37.8293053167, 175.2105357833, "31"], |
||||
[-37.8309444333, 175.21208735, "16"], |
||||
[-37.8306726667, 175.2115020833, "19"], |
||||
[-37.8300903, 175.2120791, "26"], |
||||
[-37.8289416167, 175.2113778333, "33"], |
||||
[-37.8274969167, 175.2113355167, "53"], |
||||
[-37.8199192667, 175.2173622833, "5A"], |
||||
[-37.8200392833, 175.2174100167, "3"], |
||||
[-37.8196328, 175.2167642, "18"], |
||||
[-37.81752585, 175.2155467667, "22C"], |
||||
[-37.81766615, 175.2153714167, "22B"], |
||||
[-37.8179022667, 175.2151616833, "22A"], |
||||
[-37.8191980333, 175.21664245, "20A"], |
||||
[-37.81799325, 175.21565925, "20C"], |
||||
[-37.8187486333, 175.2165228667, "20B"], |
||||
[-37.81964875, 175.2172874167, "7"], |
||||
[-37.81925545, 175.2171617, "11"], |
||||
[-37.8190491667, 175.2170928333, "13"], |
||||
[-37.8194515667, 175.2172147167, "9"], |
||||
[-37.81981045, 175.21733245, "5B"], |
||||
[-37.81876595, 175.2172445167, "15B"], |
||||
[-37.8185999167, 175.2172441, "17A"], |
||||
[-37.81816745, 175.21725905, "21B"], |
||||
[-37.8182157167, 175.2164626333, "24"], |
||||
[-37.8180109667, 175.2173984167, "23A"], |
||||
[-37.8179918, 175.217159, "23B"], |
||||
[-37.8188473167, 175.2170330333, "15"], |
||||
[-37.8186481333, 175.2169800667, "17"], |
||||
[-37.8184132, 175.2169327333, "19"], |
||||
[-37.8202288333, 175.2174746333, "1"], |
||||
[-37.818193, 175.2169955667, "21"], |
||||
[-37.8178000833, 175.21733275, "25"], |
||||
[-37.8176839, 175.2168488333, "26"], |
||||
[-37.8198172, 175.2204960667, "5"], |
||||
[-37.819986, 175.22049635, "3"], |
||||
[-37.8197666, 175.2200825, "4"], |
||||
[-37.8193835833, 175.2191669667, "10"], |
||||
[-37.8193426333, 175.2198626667, "11"], |
||||
[-37.8192171667, 175.2191711, "12"], |
||||
[-37.8192621333, 175.2196364167, "13"], |
||||
[-37.8195289667, 175.2193943167, "8"], |
||||
[-37.81946, 175.2201499167, "9"], |
||||
[-37.8196037833, 175.219674, "6"], |
||||
[-37.8194712, 175.2204032, "7A"], |
||||
[-37.8196381, 175.2203709333, "7"], |
||||
[-37.8200137667, 175.2201364333, "2"], |
||||
[-37.8191725167, 175.2193772833, "14"], |
||||
[-37.8214417333, 175.2256822167, "4"], |
||||
[-37.8210291, 175.2259429667, "8"], |
||||
[-37.8212328333, 175.2258132, "6"], |
||||
[-37.8216819833, 175.2253209, "3"], |
||||
[-37.8334697167, 175.2038651667, "326"], |
||||
[-37.8322603667, 175.2028621167, "317"], |
||||
[-37.8322013667, 175.2046802667, "1/341"], |
||||
[-37.8320576167, 175.2165535833, "435"], |
||||
[-37.8319540333, 175.20506915, "2/341"], |
||||
[-37.8316975667, 175.2053442333, "3/341"], |
||||
[-37.8328229833, 175.2062598, "346"], |
||||
[-37.83161565, 175.2074915, "355"], |
||||
[-37.83219305, 175.20629425, "347"], |
||||
[-37.8328549, 175.2080619667, "362"], |
||||
[-37.8321289667, 175.2084019333, "367"], |
||||
[-37.8322225167, 175.2120427667, "397"], |
||||
[-37.8321649, 175.21119325, "393"], |
||||
[-37.8321458833, 175.2131246333, "407"], |
||||
[-37.8327043833, 175.21377405, "416"], |
||||
[-37.8321267167, 175.2144058167, "417"], |
||||
[-37.83212555, 175.2096521333, "373"], |
||||
[-37.8331028667, 175.20928495, "366"], |
||||
[-37.82866875, 175.22177625, "563"], |
||||
[-37.8295602, 175.21924335, "582"], |
||||
[-37.8304707833, 175.2182986167, "590"], |
||||
[-37.83086, 175.2180687667, "592"], |
||||
[-37.8328604833, 175.2172892167, "618"], |
||||
[-37.8342575667, 175.2168357833, "638"], |
||||
[-37.8239713, 175.2245693667, "504"], |
||||
[-37.8365260167, 175.2170911, "673"], |
||||
[-37.8233928833, 175.2249669167, "492"], |
||||
[-37.8248650167, 175.2246300833, "509"], |
||||
[-37.8191798333, 175.2265331667, "435"], |
||||
[-37.8143243333, 175.2310940167, "368"], |
||||
[-37.81459255, 175.2320046, "363"], |
||||
[-37.81127515, 175.2356499167, "311"], |
||||
[-37.8126359667, 175.2340855167, "333"], |
||||
[-37.8096158333, 175.2375218167, "293"], |
||||
[-37.8315868667, 175.2177722833, "604"], |
||||
[-37.8160177667, 175.2299268333, "391"], |
||||
[-37.8204715667, 175.2265481833, "456"], |
||||
[-37.8206352, 175.2265670333, "458"], |
||||
[-37.8208412667, 175.2265323333, "460"], |
||||
[-37.8210184333, 175.22648325, "462"], |
||||
[-37.8212643833, 175.2270422167, "465"], |
||||
[-37.82119945, 175.2264274333, "464"], |
||||
[-37.82136485, 175.2263145667, "466"], |
||||
[-37.8215261, 175.22684075, "467"], |
||||
[-37.8215301833, 175.2262078, "468"], |
||||
[-37.8217701667, 175.2266360167, "1/471"], |
||||
[-37.8218376833, 175.22686725, "2/471"], |
||||
[-37.8217084667, 175.2260839667, "472"], |
||||
[-37.8219782333, 175.2265028333, "475"], |
||||
[-37.8218988833, 175.2259723, "476"], |
||||
[-37.8223939333, 175.2262447, "479"], |
||||
[-37.8223048667, 175.2256582833, "480"], |
||||
[-37.8226657, 175.2261230833, "481"], |
||||
[-37.8224199, 175.2255487833, "482"], |
||||
[-37.8229134167, 175.2259527833, "485"], |
||||
[-37.8226937833, 175.2253693167, "486"], |
||||
[-37.8231509667, 175.2258170333, "487"], |
||||
[-37.82295265, 175.2252571167, "488"], |
||||
[-37.8233779, 175.2256743833, "489"], |
||||
[-37.8232052667, 175.2251109333, "490"], |
||||
[-37.8236200333, 175.22553395, "493"], |
||||
[-37.82385775, 175.2253390833, "495"], |
||||
[-37.8203220167, 175.22650925, "454"], |
||||
[-37.8179795333, 175.2262826, "428"], |
||||
[-37.81038215, 175.2365298167, "303"], |
||||
[-37.8161746667, 175.2297239833, "393"], |
||||
[-37.8083635333, 175.233955, "294"], |
||||
[-37.82029495, 175.2214968167, "39"], |
||||
[-37.8204754333, 175.2247793333, "12B"], |
||||
[-37.8205440833, 175.22344905, "23"], |
||||
[-37.8195974333, 175.2254019333, "2"], |
||||
[-37.8210801, 175.2237748667, "20A"], |
||||
[-37.8209057333, 175.22389775, "18"], |
||||
[-37.8208016833, 175.2221582833, "32"], |
||||
[-37.8209372667, 175.2236919, "20"], |
||||
[-37.8210586833, 175.22351925, "22B"], |
||||
[-37.82092905, 175.2234855333, "22"], |
||||
[-37.8208587333, 175.2231887667, "24"], |
||||
[-37.8210241167, 175.2230882, "24B"], |
||||
[-37.8208547833, 175.2229410667, "26"], |
||||
[-37.8209917, 175.2228447667, "26B"], |
||||
[-37.82097645, 175.2227176167, "28B"], |
||||
[-37.8208099167, 175.2226765167, "28"], |
||||
[-37.8207666833, 175.2224338833, "30"], |
||||
[-37.8209508833, 175.2222094167, "32B"], |
||||
[-37.82076515, 175.2219195167, "34A"], |
||||
[-37.8207399667, 175.2218131667, "34B"], |
||||
[-37.8203075833, 175.2240482833, "19"], |
||||
[-37.8205368167, 175.2237746667, "21"], |
||||
[-37.8205025833, 175.2231658, "25A"], |
||||
[-37.820465, 175.2229733667, "27"], |
||||
[-37.82043535, 175.2227387, "29"], |
||||
[-37.8204582, 175.2225319667, "31"], |
||||
[-37.82024115, 175.2224347833, "31B"], |
||||
[-37.8203792333, 175.2222631667, "33"], |
||||
[-37.82034095, 175.2219843, "35"], |
||||
[-37.8201566167, 175.2219446, "35B"], |
||||
[-37.82030575, 175.2217594333, "37"], |
||||
[-37.8202966833, 175.2233158167, "25"], |
||||
[-37.8192714167, 175.2253842667, "1"], |
||||
[-37.81969695, 175.22516645, "4"], |
||||
[-37.8194904667, 175.22468815, "5"], |
||||
[-37.8198524333, 175.2249096667, "6"], |
||||
[-37.8200581833, 175.2247122, "8"], |
||||
[-37.8193447, 175.2244639667, "5C"], |
||||
[-37.8208238, 175.2241340167, "16"], |
||||
[-37.8193183667, 175.22515695, "1A"], |
||||
[-37.81940575, 175.2249383333, "3"], |
||||
[-37.8211855167, 175.2242545333, "18A"], |
||||
[-37.8207094833, 175.22430275, "14"], |
||||
[-37.82027725, 175.22488135, "10A"], |
||||
[-37.8202305833, 175.2245652667, "10"], |
||||
[-37.8205049667, 175.2244201333, "12"], |
||||
[-37.8196320333, 175.2255586, "22"], |
||||
[-37.8209711, 175.2250444667, "8"], |
||||
[-37.82120665, 175.2252942833, "5"], |
||||
[-37.8210184, 175.2254290333, "7"], |
||||
[-37.8213430333, 175.2252086167, "3"], |
||||
[-37.8207887833, 175.2251555667, "10"], |
||||
[-37.82060805, 175.2257042333, "13"], |
||||
[-37.8208330333, 175.22553905, "9"], |
||||
[-37.8216988833, 175.2249665667, "1"], |
||||
[-37.8215665833, 175.2246573333, "2"], |
||||
[-37.8213729, 175.2247789333, "4"], |
||||
[-37.8211700667, 175.2249324333, "6"], |
||||
[-37.8205967667, 175.2252867, "12"], |
||||
[-37.8204008833, 175.2254234667, "14"], |
||||
[-37.82043265, 175.22582195, "15"], |
||||
[-37.8202037333, 175.2255415833, "16"], |
||||
[-37.8200154333, 175.2256547667, "18"], |
||||
[-37.8197443167, 175.2256164833, "20"], |
||||
[-37.8202814333, 175.22590955, "17"], |
||||
[-37.8202967667, 175.21462555, "98"], |
||||
[-37.82204485, 175.21819735, "61B"], |
||||
[-37.8224241, 175.2179326667, "61C"], |
||||
[-37.8215043167, 175.2227943833, "24"], |
||||
[-37.8219082, 175.2255408167, "8"], |
||||
[-37.8216963, 175.2240856667, "14"], |
||||
[-37.8213418333, 175.2188135667, "55"], |
||||
[-37.8204966333, 175.2183406333, "54A"], |
||||
[-37.8221799833, 175.21122085, "139"], |
||||
[-37.8217387, 175.22431625, "12"], |
||||
[-37.8218650167, 175.2149734167, "107"], |
||||
[-37.8214083333, 175.2220152667, "30"], |
||||
[-37.8213738333, 175.2217301, "32"], |
||||
[-37.8221598167, 175.2247839333, "9"], |
||||
[-37.8216356, 175.2235610667, "18"], |
||||
[-37.8212188167, 175.2221387333, "30B"], |
||||
[-37.8200466667, 175.2166111, "84A"], |
||||
[-37.8216679333, 175.2238393333, "16"], |
||||
[-37.8211582833, 175.22031685, "34"], |
||||
[-37.8221918667, 175.2250378333, "7"], |
||||
[-37.8187410167, 175.2067290167, "170C"], |
||||
[-37.8206532, 175.2170745667, "81"], |
||||
[-37.8212348667, 175.2181024167, "67"], |
||||
[-37.8213057667, 175.2185351167, "57"], |
||||
[-37.8214571, 175.2145877333, "110"], |
||||
[-37.82207085, 175.2136727167, "121"], |
||||
[-37.82190125, 175.2123493, "130"], |
||||
[-37.8207519667, 175.2102467333, "150"], |
||||
[-37.8212159, 175.2096407, "159"], |
||||
[-37.8208313833, 175.2067756, "172"], |
||||
[-37.8214413333, 175.2222779833, "28"], |
||||
[-37.8206921333, 175.2182549, "54"], |
||||
[-37.82043975, 175.2181215, "56"], |
||||
[-37.8218791, 175.2252452167, "10"], |
||||
[-37.82029435, 175.2169818, "84"], |
||||
[-37.8215885167, 175.22308725, "22"], |
||||
[-37.8215897333, 175.2233113167, "20"], |
||||
[-37.82167455, 175.2183345, "61A"], |
||||
[-37.8217164667, 175.2179857333, "63"], |
||||
[-37.82147385, 175.22253565, "26"], |
||||
[-37.8206765333, 175.2160304333, "86"], |
||||
[-37.8188941, 175.2069437, "170A"], |
||||
[-37.8188068333, 175.2068104833, "170B"], |
||||
[-37.8193742667, 175.2085580333, "170"], |
||||
[-37.8214388167, 175.2200072, "45"], |
||||
[-37.8209547167, 175.2157149167, "92"], |
||||
[-37.82088565, 175.2164849333, "85"], |
||||
[-37.82136235, 175.2159546667, "97"], |
||||
[-37.8219607333, 175.2232987, "19"], |
||||
[-37.8210501, 175.2179753833, "69"], |
||||
[-37.8212466667, 175.2222175833, "28A"], |
||||
[-37.8213836167, 175.22300555, "22A"], |
||||
[-37.821339, 175.2227439167, "24A"], |
||||
[-37.8208144333, 175.2173117167, "77"], |
||||
[-37.8189363667, 175.2211582333, "25"], |
||||
[-37.8196676167, 175.2209947333, "26B"], |
||||
[-37.8194113, 175.2211991, "26"], |
||||
[-37.81883205, 175.2209747, "27"], |
||||
[-37.8186925833, 175.2207728833, "29"], |
||||
[-37.8199931833, 175.2240802167, "2"], |
||||
[-37.8191759333, 175.2208279333, "30"], |
||||
[-37.81835395, 175.2196571667, "39"], |
||||
[-37.8198807333, 175.2235938167, "6"], |
||||
[-37.8194567833, 175.22349015, "7"], |
||||
[-37.8200507833, 175.21933875, "58"], |
||||
[-37.8197902167, 175.2182408, "59A"], |
||||
[-37.81991635, 175.21797195, "59B"], |
||||
[-37.8198223833, 175.2179361833, "59C"], |
||||
[-37.8201049333, 175.2197347167, "60"], |
||||
[-37.8199380333, 175.21836645, "61A"], |
||||
[-37.82003775, 175.2182443833, "61B"], |
||||
[-37.8200944167, 175.21803015, "61C"], |
||||
[-37.8201259667, 175.2185610667, "63"], |
||||
[-37.82026275, 175.2188001167, "65"], |
||||
[-37.8188917833, 175.2203729333, "34"], |
||||
[-37.8184921333, 175.2203832, "33"], |
||||
[-37.8190387167, 175.2206181333, "32"], |
||||
[-37.81968705, 175.2224253667, "16"], |
||||
[-37.81981205, 175.223119, "10"], |
||||
[-37.8193882833, 175.2229798333, "11"], |
||||
[-37.8190901167, 175.2227829833, "13B"], |
||||
[-37.8193593, 175.2227247833, "13"], |
||||
[-37.81993935, 175.2226893333, "14B"], |
||||
[-37.81842725, 175.2201474167, "35"], |
||||
[-37.8187965833, 175.2200475333, "36"], |
||||
[-37.8183878167, 175.2198735667, "37"], |
||||
[-37.8188702167, 175.2196982333, "38B"], |
||||
[-37.82027885, 175.2209890667, "82"], |
||||
[-37.8199839667, 175.2190668, "56"], |
||||
[-37.8187008333, 175.21973745, "38A"], |
||||
[-37.8196820167, 175.22262455, "14"], |
||||
[-37.8186528333, 175.2191018, "42"], |
||||
[-37.8182912167, 175.21915535, "43"], |
||||
[-37.81870525, 175.21945675, "40"], |
||||
[-37.8195044333, 175.2214081833, "24"], |
||||
[-37.81857075, 175.2205925167, "31"], |
||||
[-37.8195656167, 175.2181396, "57"], |
||||
[-37.8198411667, 175.2213911167, "24A"], |
||||
[-37.8195851667, 175.2240869667, "3"], |
||||
[-37.8192829167, 175.2239720167, "3A"], |
||||
[-37.8193257, 175.2224725667, "15"], |
||||
[-37.8197290167, 175.2224129833, "16A"], |
||||
[-37.8196499333, 175.2221262667, "18"], |
||||
[-37.8196755333, 175.2243193333, "1"], |
||||
[-37.8192091667, 175.22166805, "21"], |
||||
[-37.81957585, 175.22166585, "22"], |
||||
[-37.8199106833, 175.2238436, "4"], |
||||
[-37.81953715, 175.22372785, "5A"], |
||||
[-37.8193377833, 175.22378105, "5"], |
||||
[-37.8189702833, 175.2184597333, "46"], |
||||
[-37.8185876167, 175.21821495, "47A"], |
||||
[-37.8185706333, 175.2178869167, "47B"], |
||||
[-37.8191945667, 175.21845965, "48"], |
||||
[-37.8188482167, 175.2176680833, "49"], |
||||
[-37.8194043667, 175.21852395, "50"], |
||||
[-37.8196233333, 175.2186248333, "52"], |
||||
[-37.81920055, 175.2179787167, "53"], |
||||
[-37.8198255, 175.2188011167, "54"], |
||||
[-37.8205994333, 175.2207248667, "81"], |
||||
[-37.8193045333, 175.2222075667, "17"], |
||||
[-37.8205621167, 175.2204520167, "79"], |
||||
[-37.8180799333, 175.2194407, "41A"], |
||||
[-37.8208301833, 175.2206735833, "81A"], |
||||
[-37.8202558, 175.2206809333, "80"], |
||||
[-37.81941275, 175.21804965, "55"], |
||||
[-37.8190239, 175.2179808833, "51"], |
||||
[-37.8187854, 175.2180712167, "47"], |
||||
[-37.8187476667, 175.2186516333, "44"], |
||||
[-37.8182977, 175.21889655, "45"], |
||||
[-37.81831675, 175.2194069833, "41"], |
||||
[-37.8192735167, 175.2219502167, "19"], |
||||
[-37.8196219167, 175.22189825, "20"], |
||||
[-37.81962665, 175.2216432667, "22A"], |
||||
[-37.8192782833, 175.2209942, "28"], |
||||
[-37.8208129833, 175.2209176833, "83A"], |
||||
[-37.8206351167, 175.2209705667, "83"], |
||||
[-37.8203109333, 175.2212402667, "84"], |
||||
[-37.81909575, 175.22139795, "23"], |
||||
[-37.8197787167, 175.2228814, "12"], |
||||
[-37.8195628333, 175.21791605, "57A"], |
||||
[-37.8198373833, 175.2233606833, "8"], |
||||
[-37.8194342167, 175.22322975, "9"] |
||||
]; |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Leaflet debug page</title> |
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" /> |
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="stylesheet" href="screen.css" /> |
||||
|
||||
<link rel="stylesheet" href="../dist/MarkerCluster.css" /> |
||||
<link rel="stylesheet" href="../dist/MarkerCluster.Default.css" /> |
||||
<script src="../dist/leaflet.markercluster-src.js"></script> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="map"></div> |
||||
<button id="doit">Remove marker #1</button><button id="doit2">Remove marker #2</button><br/> |
||||
<span>New Bug. Spiderfy the cluster then click the button #1. All markers disapear, but it should remain marker #2.</span><br/> |
||||
<span>New Bug. Spiderfy the cluster then click the button #2. All markers disapear, but it should remain marker #1.</span><br/> |
||||
|
||||
<script type="text/javascript"> |
||||
|
||||
var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
||||
maxZoom: 18, |
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
||||
}), |
||||
latlng = new L.LatLng(50.5, 30.51); |
||||
|
||||
var map = new L.Map('map', {center: latlng, zoom: 15, layers: [tiles]}); |
||||
|
||||
var markers = new L.MarkerClusterGroup({ disableClusteringAtZoom: 19}); |
||||
var markersList = []; |
||||
var m; |
||||
|
||||
geoJsonFeature = { "type": "FeatureCollection", |
||||
"features": [ { "type": "Feature", |
||||
"geometry": { |
||||
"type": "Point", |
||||
"coordinates": [30.51, 50.5] |
||||
} |
||||
} |
||||
] |
||||
}; |
||||
m = L.geoJson(geoJsonFeature, { |
||||
pointToLayer: function (feature, latlng) { |
||||
return L.marker(latlng); |
||||
} |
||||
}); |
||||
markersList.push(m); |
||||
markers.addLayer(m); |
||||
|
||||
|
||||
geoJsonFeature = { "type": "FeatureCollection", |
||||
"features": [ { "type": "Feature", |
||||
"geometry": { |
||||
"type": "Point", |
||||
"coordinates": [30.5101, 50.5] |
||||
} |
||||
} |
||||
] |
||||
}; |
||||
m = L.geoJson(geoJsonFeature, { |
||||
pointToLayer: function (feature, latlng) { |
||||
return L.marker(latlng); |
||||
} |
||||
}); |
||||
markersList.push(m); |
||||
markers.addLayer(m); |
||||
|
||||
map.addLayer(markers); |
||||
|
||||
L.DomUtil.get('doit').onclick = function () { |
||||
markers.removeLayer(markersList[0]); |
||||
}; |
||||
|
||||
L.DomUtil.get('doit2').onclick = function () { |
||||
markers.removeLayer(markersList[1]); |
||||
}; |
||||
|
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,28 @@
|
||||
#map { |
||||
width: 100%; |
||||
height: 600px; |
||||
border: 1px solid #ccc; |
||||
} |
||||
|
||||
#progress { |
||||
display: none; |
||||
position: absolute; |
||||
z-index: 1000; |
||||
left: 400px; |
||||
top: 300px; |
||||
width: 200px; |
||||
height: 20px; |
||||
margin-top: -20px; |
||||
margin-left: -100px; |
||||
background-color: #fff; |
||||
background-color: rgba(255, 255, 255, 0.7); |
||||
border-radius: 4px; |
||||
padding: 2px; |
||||
} |
||||
|
||||
#progress-bar { |
||||
width: 0; |
||||
height: 100%; |
||||
background-color: #76A6FC; |
||||
border-radius: 4px; |
||||
} |
@ -0,0 +1,43 @@
|
||||
{ |
||||
"name": "leaflet.markercluster", |
||||
"repository": "https://github.com/Leaflet/Leaflet.markercluster", |
||||
"version": "1.4.1", |
||||
"description": "Provides Beautiful Animated Marker Clustering functionality for Leaflet", |
||||
"devDependencies": { |
||||
"git-rev-sync": "^1.8.0", |
||||
"happen": "^0.3.1", |
||||
"jake": "~0.5.16", |
||||
"jshint": "^2.9.4", |
||||
"karma": "^1.5.0", |
||||
"karma-chrome-launcher": "^2.0.0", |
||||
"karma-coverage": "^1.1.1", |
||||
"karma-firefox-launcher": "^1.0.1", |
||||
"karma-mocha": "^1.3.0", |
||||
"karma-phantomjs-launcher": "^1.0.4", |
||||
"karma-rollup-plugin": "^0.2.4", |
||||
"karma-safari-launcher": "^1.0.0", |
||||
"leaflet": "^1.3.1", |
||||
"mocha": "~1.10.0", |
||||
"phantomjs-prebuilt": "^2.1.14", |
||||
"rollup": "^0.41.4", |
||||
"rollup-plugin-git-version": "0.2.1", |
||||
"rollup-plugin-json": "^2.1.0", |
||||
"uglify-js": "~2.3.6" |
||||
}, |
||||
"peerDependencies": { |
||||
"leaflet": "~1.3.1" |
||||
}, |
||||
"main": "dist/leaflet.markercluster-src.js", |
||||
"scripts": { |
||||
"test": "karma start ./spec/karma.conf.js", |
||||
"prepublish": "jake", |
||||
"rollup": "rollup -c build/rollup-config.js", |
||||
"uglify": "uglifyjs dist/leaflet.markercluster-src.js -c -m -o dist/leaflet.markercluster.js --source-map dist/leaflet.markercluster.js.map --in-source-map dist/leaflet.markercluster-src.js.map --source-map-url leaflet.markercluster.js.map" |
||||
}, |
||||
"keywords": [ |
||||
"gis", |
||||
"map", |
||||
"cluster" |
||||
], |
||||
"license": "MIT" |
||||
} |
@ -0,0 +1,2 @@
|
||||
// put after Leaflet files as imagePath can't be detected in a PhantomJS env
|
||||
L.Icon.Default.imagePath = "../dist/images"; |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,76 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<meta charset="utf-8"> |
||||
<title>Spec Runner</title> |
||||
<link rel="stylesheet" type="text/css" href="../node_modules/mocha/mocha.css"> |
||||
<link rel="stylesheet" type="text/css" href="../node_modules/leaflet/dist/leaflet.css"> |
||||
<link rel="stylesheet" type="text/css" href="../dist/MarkerCluster.css"> |
||||
<link rel="stylesheet" type="text/css" href="../dist/MarkerCluster.Default.css"> |
||||
</head> |
||||
<body> |
||||
<div id="mocha"></div> |
||||
<script src="expect.js"></script> |
||||
<script type="text/javascript" src="../node_modules/mocha/mocha.js"></script> |
||||
<script type="text/javascript" src="../node_modules/happen/happen.js"></script> |
||||
<script type="text/javascript" src="sinon.js"></script> |
||||
<script type="text/javascript" src="../node_modules/leaflet/dist/leaflet-src.js"></script> |
||||
|
||||
<!-- source files --> |
||||
<script type="text/javascript" src="../dist/leaflet.markercluster-src.js"></script> |
||||
|
||||
<script> |
||||
mocha.setup('bdd'); |
||||
mocha.ignoreLeaks(); |
||||
</script> |
||||
|
||||
<!-- spec files --> |
||||
|
||||
<script type="text/javascript" src="suites/SpecHelper.js"></script> |
||||
|
||||
<script type="text/javascript" src="suites/LeafletSpec.js"></script> |
||||
|
||||
<script type="text/javascript" src="suites/DistanceGridSpec.js"></script> |
||||
<script type="text/javascript" src="suites/QuickHullSpec.js"></script> |
||||
|
||||
<script type="text/javascript" src="suites/AddLayer.MultipleSpec.js"></script> |
||||
<script type="text/javascript" src="suites/AddLayer.SingleSpec.js"></script> |
||||
<script type="text/javascript" src="suites/AddLayersSpec.js"></script> |
||||
<script type="text/javascript" src="suites/animateOptionSpec.js"></script> |
||||
<script type="text/javascript" src="suites/singleMarkerModeSpec.js"></script> |
||||
|
||||
<script type="text/javascript" src="suites/ChildChangingIconSupportSpec.js"></script> |
||||
<script type="text/javascript" src="suites/markerMoveSupportSpec.js"></script> |
||||
|
||||
<script type="text/javascript" src="suites/CircleMarkerSupportSpec.js"></script> |
||||
<script type="text/javascript" src="suites/CircleSupportSpec.js"></script> |
||||
|
||||
<script type="text/javascript" src="suites/onAddSpec.js"></script> |
||||
<script type="text/javascript" src="suites/onRemoveSpec.js"></script> |
||||
<script type="text/javascript" src="suites/clearLayersSpec.js"></script> |
||||
<script type="text/javascript" src="suites/eachLayerSpec.js"></script> |
||||
<script type="text/javascript" src="suites/eventsSpec.js"></script> |
||||
<script type="text/javascript" src="suites/getBoundsSpec.js"></script> |
||||
<script type="text/javascript" src="suites/getLayersSpec.js"></script> |
||||
<script type="text/javascript" src="suites/getVisibleParentSpec.js"></script> |
||||
|
||||
<script type="text/javascript" src="suites/NonPointSpec.js"></script> |
||||
|
||||
<script type="text/javascript" src="suites/RemoveLayerSpec.js"></script> |
||||
<script type="text/javascript" src="suites/removeLayersSpec.js"></script> |
||||
<script type="text/javascript" src="suites/spiderfySpec.js"></script> |
||||
<script type="text/javascript" src="suites/unspiderfySpec.js"></script> |
||||
<script type="text/javascript" src="suites/zoomAnimationSpec.js"></script> |
||||
|
||||
<script type="text/javascript" src="suites/RememberOpacity.js"></script> |
||||
<script type="text/javascript" src="suites/supportNegativeZoomSpec.js"></script> |
||||
|
||||
<script type="text/javascript" src="suites/RefreshSpec.js"></script> |
||||
<script type="text/javascript" src="suites/removeOutsideVisibleBoundsSpec.js"></script> |
||||
<script type="text/javascript" src="suites/nonIntegerZoomSpec.js"></script> |
||||
|
||||
<script> |
||||
(window.mochaPhantomJS || window.mocha).run(); |
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,96 @@
|
||||
var json = require('rollup-plugin-json'); |
||||
|
||||
// Karma configuration
|
||||
module.exports = function (config) { |
||||
|
||||
// var libSources = require(__dirname + '/../build/build.js').getFiles();
|
||||
|
||||
var files = [ |
||||
"spec/sinon.js", |
||||
"spec/expect.js", |
||||
|
||||
"node_modules/leaflet/dist/leaflet-src.js", |
||||
"src/index.js", |
||||
|
||||
"spec/after.js", |
||||
"node_modules/happen/happen.js", |
||||
"spec/suites/SpecHelper.js", |
||||
"spec/suites/**/*.js", |
||||
"dist/*.css" |
||||
]; |
||||
|
||||
config.set({ |
||||
// base path, that will be used to resolve files and exclude
|
||||
basePath: '../', |
||||
|
||||
plugins: [ |
||||
'karma-rollup-plugin', |
||||
'karma-mocha', |
||||
'karma-coverage', |
||||
'karma-phantomjs-launcher', |
||||
'karma-chrome-launcher', |
||||
'karma-safari-launcher', |
||||
'karma-firefox-launcher' |
||||
], |
||||
|
||||
// frameworks to use
|
||||
frameworks: ['mocha'], |
||||
|
||||
// list of files / patterns to load in the browser
|
||||
files: files, |
||||
// proxies: {
|
||||
// '/base/dist/images/': 'dist/images/'
|
||||
// },
|
||||
exclude: [], |
||||
|
||||
// Rollup the ES6 Leaflet.markercluster sources into just one file, before tests
|
||||
preprocessors: { |
||||
'src/index.js': ['rollup'] |
||||
}, |
||||
rollupPreprocessor: { |
||||
plugins: [ |
||||
json() |
||||
], |
||||
format: 'umd', |
||||
moduleName: 'Leaflet.markercluster' |
||||
}, |
||||
|
||||
// test results reporter to use
|
||||
// possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
|
||||
reporters: ['dots'], |
||||
|
||||
// web server port
|
||||
port: 9876, |
||||
|
||||
// level of logging
|
||||
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
|
||||
logLevel: config.LOG_WARN, |
||||
|
||||
// enable / disable colors in the output (reporters and logs)
|
||||
colors: true, |
||||
|
||||
// enable / disable watching file and executing tests whenever any file changes
|
||||
autoWatch: false, |
||||
|
||||
// Start these browsers, currently available:
|
||||
// - Chrome
|
||||
// - ChromeCanary
|
||||
// - Firefox
|
||||
// - Opera
|
||||
// - Safari (only Mac)
|
||||
// - PhantomJS
|
||||
// - IE (only Windows)
|
||||
browsers: ['PhantomJS'], |
||||
|
||||
// If browser does not capture in given timeout [ms], kill it
|
||||
captureTimeout: 5000, |
||||
|
||||
// Workaround for PhantomJS random DISCONNECTED error
|
||||
browserDisconnectTimeout: 10000, // default 2000
|
||||
browserDisconnectTolerance: 1, // default 0
|
||||
|
||||
// Continuous Integration mode
|
||||
// if true, it capture browsers, run tests and exit
|
||||
singleRun: true |
||||
}); |
||||
}; |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,125 @@
|
||||
describe('addLayer adding multiple markers', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var map, div, clock; |
||||
|
||||
beforeEach(function () { |
||||
clock = sinon.useFakeTimers(); |
||||
|
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
map.remove(); |
||||
document.body.removeChild(div); |
||||
clock.restore(); |
||||
|
||||
map = div = clock = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('creates a cluster when 2 overlapping markers are added before the group is added to the map', function () { |
||||
|
||||
var group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
map.addLayer(group); |
||||
|
||||
expect(marker._icon).to.be(undefined); |
||||
expect(marker2._icon).to.be(undefined); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1); |
||||
}); |
||||
it('creates a cluster when 2 overlapping markers are added after the group is added to the map', function () { |
||||
|
||||
var group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
|
||||
expect(marker._icon).to.be(null); //Null as was added and then removed
|
||||
expect(marker2._icon).to.be(undefined); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1); |
||||
}); |
||||
it('creates a cluster with an animation when 2 overlapping markers are added after the group is added to the map', function () { |
||||
|
||||
var group = new L.MarkerClusterGroup({ animateAddingMarkers: true }); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane); |
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(3); |
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000); |
||||
|
||||
//Then markers should be removed from map
|
||||
expect(marker._icon).to.be(null); |
||||
expect(marker2._icon).to.be(null); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1); |
||||
}); |
||||
|
||||
it('creates a cluster and marker when 2 overlapping markers and one non-overlapping are added before the group is added to the map', function () { |
||||
|
||||
var group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
var marker3 = new L.Marker([3.0, 1.5]); |
||||
|
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
group.addLayer(marker3); |
||||
map.addLayer(group); |
||||
|
||||
expect(marker._icon).to.be(undefined); |
||||
expect(marker2._icon).to.be(undefined); |
||||
expect(marker3._icon.parentNode).to.be(map._panes.markerPane); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(2); |
||||
}); |
||||
it('creates a cluster and marker when 2 overlapping markers and one non-overlapping are added after the group is added to the map', function () { |
||||
|
||||
var group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
var marker3 = new L.Marker([3.0, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
group.addLayer(marker3); |
||||
|
||||
expect(marker._icon).to.be(null); //Null as was added and then removed
|
||||
expect(marker2._icon).to.be(undefined); |
||||
expect(marker3._icon.parentNode).to.be(map._panes.markerPane); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(2); |
||||
}); |
||||
}); |
@ -0,0 +1,118 @@
|
||||
describe('addLayer adding a single marker', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var div, map, group; |
||||
|
||||
beforeEach(function () { |
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
if (group instanceof L.MarkerClusterGroup) { |
||||
group.clearLayers(); |
||||
map.removeLayer(group); |
||||
} |
||||
|
||||
map.remove(); |
||||
div.remove() |
||||
|
||||
div = map = group = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('appears when added to the group before the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayer(marker); |
||||
map.addLayer(group); |
||||
|
||||
expect(marker._icon).to.not.be(undefined); |
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane); |
||||
}); |
||||
|
||||
it('appears when added to the group after the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(marker); |
||||
|
||||
expect(marker._icon).to.not.be(undefined); |
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane); |
||||
}); |
||||
|
||||
it('appears (using animations) when added after the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup({ animateAddingMarkers: true }); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(marker); |
||||
|
||||
expect(marker._icon).to.not.be(undefined); |
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane); |
||||
}); |
||||
|
||||
it('does not appear when too far away when added before the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([3.5, 1.5]); |
||||
|
||||
group.addLayer(marker); |
||||
map.addLayer(group); |
||||
|
||||
expect(marker._icon).to.be(undefined); |
||||
}); |
||||
|
||||
it('does not appear when too far away when added after the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([3.5, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(marker); |
||||
|
||||
expect(marker._icon).to.be(undefined); |
||||
}); |
||||
|
||||
it('passes control to addLayers when marker is a Layer Group', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker1 = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
var layerGroup = new L.LayerGroup([marker1, marker2]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(layerGroup); |
||||
|
||||
expect(group._topClusterLevel.getChildCount()).to.equal(2); |
||||
|
||||
expect(marker1._icon).to.be(undefined); |
||||
expect(marker2._icon).to.be(undefined); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1); |
||||
}); |
||||
}); |
@ -0,0 +1,123 @@
|
||||
describe('addLayers adding multiple markers', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var div, map, group; |
||||
|
||||
beforeEach(function () { |
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
if (group instanceof L.MarkerClusterGroup) { |
||||
group.clearLayers(); |
||||
map.removeLayer(group); |
||||
} |
||||
|
||||
map.remove(); |
||||
div.remove() |
||||
|
||||
div = map = group = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('creates a cluster when 2 overlapping markers are added before the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
expect(marker._icon).to.be(undefined); |
||||
expect(marker2._icon).to.be(undefined); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1); |
||||
}); |
||||
|
||||
it('creates a cluster when 2 overlapping markers are added after the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayers([marker, marker2]); |
||||
|
||||
expect(marker._icon).to.be(undefined); |
||||
expect(marker2._icon).to.be(undefined); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1); |
||||
}); |
||||
|
||||
it('creates a cluster and marker when 2 overlapping markers and one non-overlapping are added before the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
var marker3 = new L.Marker([3.0, 1.5]); |
||||
|
||||
group.addLayers([marker, marker2, marker3]); |
||||
map.addLayer(group); |
||||
|
||||
expect(marker._icon).to.be(undefined); |
||||
expect(marker2._icon).to.be(undefined); |
||||
expect(marker3._icon.parentNode).to.be(map._panes.markerPane); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(2); |
||||
}); |
||||
|
||||
it('creates a cluster and marker when 2 overlapping markers and one non-overlapping are added after the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
var marker3 = new L.Marker([3.0, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayers([marker, marker2, marker3]); |
||||
|
||||
expect(marker._icon).to.be(undefined); |
||||
expect(marker2._icon).to.be(undefined); |
||||
expect(marker3._icon.parentNode).to.be(map._panes.markerPane); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(2); |
||||
}); |
||||
|
||||
it('handles nested Layer Groups', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker1 = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
var marker3 = new L.Marker([3.0, 1.5]); |
||||
var layerGroup = new L.LayerGroup([marker1, new L.LayerGroup([marker2])]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayers([layerGroup, marker3]); |
||||
|
||||
expect(marker1._icon).to.be(undefined); |
||||
expect(marker2._icon).to.be(undefined); |
||||
expect(marker3._icon.parentNode).to.be(map._panes.markerPane); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(2); |
||||
}); |
||||
}); |
@ -0,0 +1,56 @@
|
||||
describe('support child markers changing icon', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var map, div, clock; |
||||
|
||||
beforeEach(function () { |
||||
clock = sinon.useFakeTimers(); |
||||
|
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
map.remove(); |
||||
document.body.removeChild(div); |
||||
clock.restore(); |
||||
|
||||
map = div = clock = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('child markers end up with the right icon after becoming unclustered', function () { |
||||
|
||||
var group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([1.5, 1.5], { icon: new L.DivIcon({html: 'Inner1Text' }) }); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(marker); |
||||
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane); |
||||
expect(marker._icon.innerHTML).to.contain('Inner1Text'); |
||||
|
||||
group.addLayer(marker2); |
||||
|
||||
expect(marker._icon).to.be(null); //Have been removed from the map
|
||||
|
||||
marker.setIcon(new L.DivIcon({ html: 'Inner2Text' })); //Change the icon
|
||||
|
||||
group.removeLayer(marker2); //Remove the other marker, so we'll become unclustered
|
||||
|
||||
expect(marker._icon.innerHTML).to.contain('Inner2Text'); |
||||
}); |
||||
}); |
@ -0,0 +1,147 @@
|
||||
describe('support for CircleMarker elements', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var clock, div, map, group; |
||||
|
||||
beforeEach(function () { |
||||
clock = sinon.useFakeTimers(); |
||||
|
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
if (group instanceof L.MarkerClusterGroup) { |
||||
group.clearLayers(); |
||||
map.removeLayer(group); |
||||
} |
||||
|
||||
map.remove(); |
||||
div.remove() |
||||
clock.restore(); |
||||
|
||||
clock = div = map = group = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('appears when added to the group before the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.CircleMarker([1.5, 1.5]); |
||||
|
||||
group.addLayer(marker); |
||||
map.addLayer(group); |
||||
|
||||
// Leaflet 1.0.0 now uses an intermediate L.Renderer.
|
||||
// marker > _path > _rootGroup (g) > _container (svg) > pane (div)
|
||||
expect(marker._path.parentNode.parentNode).to.not.be(undefined); |
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane')); |
||||
|
||||
clock.tick(1000); |
||||
}); |
||||
|
||||
it('appears when added to the group after the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.CircleMarker([1.5, 1.5]); |
||||
|
||||
group.addLayer(marker); |
||||
map.addLayer(group); |
||||
|
||||
expect(marker._path.parentNode.parentNode).to.not.be(undefined); |
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane')); |
||||
|
||||
clock.tick(1000); |
||||
}); |
||||
|
||||
it('appears animated when added to the group after the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup({ animateAddingMarkers: true }); |
||||
|
||||
var marker = new L.CircleMarker([1.5, 1.5]); |
||||
var marker2 = new L.CircleMarker([1.5, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
|
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane')); |
||||
expect(marker2._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane')); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
expect(marker._path.parentNode).to.be(null); |
||||
expect(marker2._path.parentNode).to.be(null); |
||||
}); |
||||
|
||||
it('creates a cluster when 2 overlapping markers are added before the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.CircleMarker([1.5, 1.5]); |
||||
var marker2 = new L.CircleMarker([1.5, 1.5]); |
||||
|
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
expect(marker._path).to.be(undefined); |
||||
expect(marker2._path).to.be(undefined); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1); |
||||
|
||||
clock.tick(1000); |
||||
}); |
||||
|
||||
it('creates a cluster when 2 overlapping markers are added after the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.CircleMarker([1.5, 1.5]); |
||||
var marker2 = new L.CircleMarker([1.5, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
|
||||
expect(marker._path.parentNode).to.be(null); //Removed then re-added, so null
|
||||
expect(marker2._path).to.be(undefined); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1); |
||||
|
||||
clock.tick(1000); |
||||
}); |
||||
|
||||
it('disappears when removed from the group', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.CircleMarker([1.5, 1.5]); |
||||
|
||||
group.addLayer(marker); |
||||
map.addLayer(group); |
||||
|
||||
expect(marker._path.parentNode).to.not.be(undefined); |
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane')); |
||||
|
||||
group.removeLayer(marker); |
||||
|
||||
expect(marker._path.parentNode).to.be(null); |
||||
|
||||
clock.tick(1000); |
||||
}); |
||||
}); |
@ -0,0 +1,144 @@
|
||||
describe('support for Circle elements', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var clock, div, map, group; |
||||
|
||||
beforeEach(function () { |
||||
clock = sinon.useFakeTimers(); |
||||
|
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
if (group instanceof L.MarkerClusterGroup) { |
||||
group.clearLayers(); |
||||
map.removeLayer(group); |
||||
} |
||||
|
||||
map.remove(); |
||||
div.remove() |
||||
clock.restore(); |
||||
|
||||
clock = div = map = group = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('appears when added to the group before the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Circle([1.5, 1.5], 200); |
||||
|
||||
group.addLayer(marker); |
||||
map.addLayer(group); |
||||
|
||||
// Leaflet 1.0.0 now uses an intermediate L.Renderer.
|
||||
// marker > _path > _rootGroup (g) > _container (svg) > pane (div)
|
||||
expect(marker._path.parentNode).to.not.be(undefined); |
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane')); |
||||
|
||||
clock.tick(1000); |
||||
}); |
||||
|
||||
it('appears when added to the group after the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Circle([1.5, 1.5], 200); |
||||
|
||||
group.addLayer(marker); |
||||
map.addLayer(group); |
||||
|
||||
expect(marker._path.parentNode).to.not.be(undefined); |
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane')); |
||||
|
||||
clock.tick(1000); |
||||
}); |
||||
|
||||
it('appears animated when added to the group after the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup({ animateAddingMarkers: true }); |
||||
|
||||
var marker = new L.Circle([1.5, 1.5], 200); |
||||
var marker2 = new L.Circle([1.5, 1.5], 200); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
|
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane')); |
||||
expect(marker2._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane')); |
||||
|
||||
clock.tick(1000); |
||||
}); |
||||
|
||||
it('creates a cluster when 2 overlapping markers are added before the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Circle([1.5, 1.5], 200); |
||||
var marker2 = new L.Circle([1.5, 1.5], 200); |
||||
|
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
expect(marker._path).to.be(undefined); |
||||
expect(marker2._path).to.be(undefined); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1); |
||||
|
||||
clock.tick(1000); |
||||
}); |
||||
|
||||
it('creates a cluster when 2 overlapping markers are added after the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Circle([1.5, 1.5], 200); |
||||
var marker2 = new L.Circle([1.5, 1.5], 200); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
|
||||
expect(marker._path.parentNode).to.be(null); //Removed then re-added, so null
|
||||
expect(marker2._path).to.be(undefined); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1); |
||||
|
||||
clock.tick(1000); |
||||
}); |
||||
|
||||
it('disappears when removed from the group', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Circle([1.5, 1.5], 200); |
||||
|
||||
group.addLayer(marker); |
||||
map.addLayer(group); |
||||
|
||||
expect(marker._path.parentNode).to.not.be(undefined); |
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane')); |
||||
|
||||
group.removeLayer(marker); |
||||
|
||||
expect(marker._path.parentNode).to.be(null); |
||||
|
||||
clock.tick(1000); |
||||
}); |
||||
}); |
@ -0,0 +1,41 @@
|
||||
describe('distance grid', function () { |
||||
it('addObject', function () { |
||||
var grid = new L.DistanceGrid(100), |
||||
obj = {}; |
||||
|
||||
expect(grid.addObject(obj, { x: 0, y: 0 })).to.eql(undefined); |
||||
expect(grid.removeObject(obj, { x: 0, y: 0 })).to.eql(true); |
||||
}); |
||||
|
||||
it('eachObject', function (done) { |
||||
var grid = new L.DistanceGrid(100), |
||||
obj = {}; |
||||
|
||||
expect(grid.addObject(obj, { x: 0, y: 0 })).to.eql(undefined); |
||||
|
||||
grid.eachObject(function(o) { |
||||
expect(o).to.eql(obj); |
||||
done(); |
||||
}); |
||||
}); |
||||
|
||||
it('getNearObject', function () { |
||||
var grid = new L.DistanceGrid(100), |
||||
obj = {}; |
||||
|
||||
grid.addObject(obj, { x: 0, y: 0 }); |
||||
|
||||
expect(grid.getNearObject({ x: 50, y: 50 })).to.equal(obj); |
||||
expect(grid.getNearObject({ x: 100, y: 0 })).to.equal(obj); |
||||
}); |
||||
|
||||
it('getNearObject with cellSize 0', function () { |
||||
var grid = new L.DistanceGrid(0), |
||||
obj = {}; |
||||
|
||||
grid.addObject(obj, { x: 0, y: 0 }); |
||||
|
||||
expect(grid.getNearObject({ x: 50, y: 50 })).to.equal(null); |
||||
expect(grid.getNearObject({ x: 0, y: 0 })).to.equal(obj); |
||||
}); |
||||
}); |
@ -0,0 +1,6 @@
|
||||
describe('L#noConflict', function() { |
||||
it('restores the previous L value and returns Leaflet namespace', function(){ |
||||
|
||||
expect(L.version).to.be.ok(); |
||||
}); |
||||
}); |
@ -0,0 +1,240 @@
|
||||
describe('adding non point data works', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var div, map, group; |
||||
|
||||
beforeEach(function () { |
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
if (group instanceof L.MarkerClusterGroup) { |
||||
group.clearLayers(); |
||||
map.removeLayer(group); |
||||
} |
||||
|
||||
map.remove(); |
||||
div.remove() |
||||
|
||||
div = map = group = null; |
||||
}); |
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('Allows adding a polygon before via addLayer', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0,2.0], [1.5, 2.0]]); |
||||
|
||||
group.addLayer(polygon); |
||||
map.addLayer(group); |
||||
|
||||
// Leaflet 1.0.0 now uses an intermediate L.Renderer.
|
||||
// polygon > _path > _rootGroup (g) > _container (svg) > pane (div)
|
||||
expect(polygon._path).to.not.be(undefined); |
||||
expect(polygon._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane')); |
||||
|
||||
expect(group.hasLayer(polygon)); |
||||
}); |
||||
|
||||
it('Allows adding a polygon before via addLayers([])', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
group.addLayers([polygon]); |
||||
map.addLayer(group); |
||||
|
||||
expect(polygon._path).to.not.be(undefined); |
||||
expect(polygon._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane')); |
||||
}); |
||||
|
||||
it('Removes polygons from map when removed', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
group.addLayer(polygon); |
||||
map.addLayer(group); |
||||
map.removeLayer(group); |
||||
|
||||
expect(polygon._path.parentNode).to.be(null); |
||||
}); |
||||
|
||||
describe('hasLayer', function () { |
||||
|
||||
it('returns false when not added', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
expect(group.hasLayer(polygon)).to.be(false); |
||||
|
||||
map.addLayer(group); |
||||
|
||||
expect(group.hasLayer(polygon)).to.be(false); |
||||
|
||||
map.addLayer(polygon); |
||||
|
||||
expect(group.hasLayer(polygon)).to.be(false); |
||||
}); |
||||
|
||||
it('returns true before adding to map', function() { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
group.addLayers([polygon]); |
||||
|
||||
expect(group.hasLayer(polygon)).to.be(true); |
||||
}); |
||||
|
||||
it('returns true after adding to map after adding polygon', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
group.addLayer(polygon); |
||||
map.addLayer(group); |
||||
|
||||
expect(group.hasLayer(polygon)).to.be(true); |
||||
}); |
||||
|
||||
it('returns true after adding to map before adding polygon', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(polygon); |
||||
|
||||
expect(group.hasLayer(polygon)).to.be(true); |
||||
}); |
||||
|
||||
}); |
||||
|
||||
describe('removeLayer', function() { |
||||
|
||||
it('removes before adding to map', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
group.addLayer(polygon); |
||||
expect(group.hasLayer(polygon)).to.be(true); |
||||
|
||||
group.removeLayer(polygon); |
||||
expect(group.hasLayer(polygon)).to.be(false); |
||||
}); |
||||
|
||||
it('removes before adding to map', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
group.addLayers([polygon]); |
||||
expect(group.hasLayer(polygon)).to.be(true); |
||||
|
||||
group.removeLayer(polygon); |
||||
expect(group.hasLayer(polygon)).to.be(false); |
||||
}); |
||||
|
||||
it('removes after adding to map after adding polygon', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
group.addLayer(polygon); |
||||
map.addLayer(group); |
||||
expect(group.hasLayer(polygon)).to.be(true); |
||||
|
||||
group.removeLayer(polygon); |
||||
expect(group.hasLayer(polygon)).to.be(false); |
||||
}); |
||||
|
||||
it('removes after adding to map before adding polygon', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(polygon); |
||||
expect(group.hasLayer(polygon)).to.be(true); |
||||
|
||||
group.removeLayer(polygon); |
||||
expect(group.hasLayer(polygon)).to.be(false); |
||||
}); |
||||
|
||||
}); |
||||
|
||||
describe('removeLayers', function () { |
||||
|
||||
it('removes before adding to map', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
group.addLayer(polygon); |
||||
expect(group.hasLayer(polygon)).to.be(true); |
||||
|
||||
group.removeLayers([polygon]); |
||||
expect(group.hasLayer(polygon)).to.be(false); |
||||
}); |
||||
|
||||
it('removes before adding to map', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
group.addLayers([polygon]); |
||||
expect(group.hasLayer(polygon)).to.be(true); |
||||
|
||||
group.removeLayers([polygon]); |
||||
expect(group.hasLayer(polygon)).to.be(false); |
||||
}); |
||||
|
||||
it('removes after adding to map after adding polygon', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
group.addLayer(polygon); |
||||
map.addLayer(group); |
||||
expect(group.hasLayer(polygon)).to.be(true); |
||||
|
||||
group.removeLayers([polygon]); |
||||
expect(group.hasLayer(polygon)).to.be(false); |
||||
}); |
||||
|
||||
it('removes after adding to map before adding polygon', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(polygon); |
||||
expect(group.hasLayer(polygon)).to.be(true); |
||||
|
||||
group.removeLayers([polygon]); |
||||
expect(group.hasLayer(polygon)).to.be(false); |
||||
}); |
||||
|
||||
}); |
||||
}); |
@ -0,0 +1,63 @@
|
||||
describe('Map pane selection', function() { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var div, map, group; |
||||
|
||||
beforeEach(function () { |
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
// Create map pane
|
||||
map.createPane('testPane'); |
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
if (group instanceof L.MarkerClusterGroup) { |
||||
group.clearLayers(); |
||||
map.removeLayer(group); |
||||
} |
||||
|
||||
map.remove(); |
||||
div.remove() |
||||
|
||||
div = map = group = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('recognizes and applies option', function() { |
||||
group = new L.MarkerClusterGroup({clusterPane: 'testPane'}); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
expect(map._panes.testPane.childNodes.length).to.be(1); |
||||
}); |
||||
|
||||
it('defaults to default marker pane', function() { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
expect(map._panes[L.Marker.prototype.options.pane].childNodes.length).to.be(1); |
||||
}); |
||||
}); |
@ -0,0 +1,52 @@
|
||||
describe('quickhull', function () { |
||||
describe('getDistant', function () { |
||||
it('zero distance', function () { |
||||
var bl = [ |
||||
{ lat: 0, lng: 0 }, |
||||
{ lat: 0, lng: 10 } |
||||
]; |
||||
expect(L.QuickHull.getDistant({ lat: 0, lng: 0 }, bl)).to.eql(0); |
||||
}); |
||||
it('non-zero distance', function () { |
||||
var bl = [ |
||||
{ lat: 0, lng: 0 }, |
||||
{ lat: 0, lng: 10 } |
||||
]; |
||||
expect(L.QuickHull.getDistant({ lat: 5, lng: 5 }, bl)).to.eql(-50); |
||||
}); |
||||
}); |
||||
|
||||
describe('getConvexHull', function () { |
||||
it('creates a hull', function () { |
||||
expect(L.QuickHull.getConvexHull([ { lat: 0, lng: 0 }, |
||||
{ lat: 10, lng: 0 }, |
||||
{ lat: 10, lng: 10 }, |
||||
{ lat: 0, lng: 10 }, |
||||
{ lat: 5, lng: 5 } |
||||
])).to.eql([ |
||||
{ lat: 0, lng: 10 }, |
||||
{ lat: 10, lng: 10 }, |
||||
{ lat: 10, lng: 0 }, |
||||
{ lat: 0, lng: 0 } |
||||
]); |
||||
}); |
||||
it('creates a hull for vertically-aligned objects', function () { |
||||
expect(L.QuickHull.getConvexHull([ { lat: 0, lng: 0 }, |
||||
{ lat: 5, lng: 0 }, |
||||
{ lat: 10, lng: 0 } |
||||
])).to.eql([ |
||||
{ lat: 0, lng: 0 }, |
||||
{ lat: 10, lng: 0 } |
||||
]); |
||||
}); |
||||
it('creates a hull for horizontally-aligned objects', function () { |
||||
expect(L.QuickHull.getConvexHull([ { lat: 0, lng: 0 }, |
||||
{ lat: 0, lng: 5 }, |
||||
{ lat: 0, lng: 10 } |
||||
])).to.eql([ |
||||
{ lat: 0, lng: 0 }, |
||||
{ lat: 0, lng: 10 } |
||||
]); |
||||
}); |
||||
}); |
||||
}); |
@ -0,0 +1,435 @@
|
||||
describe('refreshClusters', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var clock, div, map, group; |
||||
|
||||
beforeEach(function () { |
||||
clock = sinon.useFakeTimers(); |
||||
|
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
if (group instanceof L.MarkerClusterGroup) { |
||||
group.clearLayers(); |
||||
map.removeLayer(group); |
||||
} |
||||
|
||||
map.remove(); |
||||
div.remove() |
||||
clock.restore(); |
||||
|
||||
clock = div = map = group = null; |
||||
}); |
||||
|
||||
function getClusterAtZoom(marker, zoom) { |
||||
var parent = marker.__parent; |
||||
|
||||
while (parent && parent._zoom !== zoom) { |
||||
parent = parent.__parent; |
||||
} |
||||
|
||||
return parent; |
||||
} |
||||
|
||||
function setMapView() { |
||||
// Now look at the markers to force cluster icons drawing.
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
} |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('flags all non-visible parent clusters of a given marker', function () { |
||||
|
||||
group = L.markerClusterGroup().addTo(map); |
||||
|
||||
var marker1 = L.marker([1.5, 1.5]).addTo(group), |
||||
marker2 = L.marker([1.5, 1.5]).addTo(group); // Needed to force a cluster.
|
||||
|
||||
setMapView(); |
||||
|
||||
var marker1cluster10 = getClusterAtZoom(marker1, 10), |
||||
marker1cluster2 = getClusterAtZoom(marker1, 2), |
||||
marker1cluster5 = getClusterAtZoom(marker1, 5); |
||||
|
||||
// First go to some zoom levels so that Leaflet initializes clusters icons.
|
||||
expect(marker1cluster10._iconNeedsUpdate).to.be.ok(); |
||||
map.setZoom(10, {animate: false}); |
||||
expect(marker1cluster10._iconNeedsUpdate).to.not.be.ok(); |
||||
|
||||
expect(marker1cluster2._iconNeedsUpdate).to.be.ok(); |
||||
map.setZoom(2, {animate: false}); |
||||
expect(marker1cluster2._iconNeedsUpdate).to.not.be.ok(); |
||||
|
||||
// Finish on an intermediate zoom level.
|
||||
expect(marker1cluster5._iconNeedsUpdate).to.be.ok(); |
||||
map.setZoom(5, {animate: false}); |
||||
expect(marker1cluster5._iconNeedsUpdate).to.not.be.ok(); |
||||
|
||||
// Run any animation.
|
||||
clock.tick(1000); |
||||
|
||||
// Then request clusters refresh.
|
||||
// No need to actually modify the marker.
|
||||
group.refreshClusters(marker1); |
||||
|
||||
// Now check that non-visible clusters are flagged as "dirty".
|
||||
expect(marker1cluster10._iconNeedsUpdate).to.be.ok(); |
||||
expect(marker1cluster2._iconNeedsUpdate).to.be.ok(); |
||||
|
||||
// Also check that visible clusters are "un-flagged" since they should be re-drawn.
|
||||
expect(marker1cluster5._iconNeedsUpdate).to.not.be.ok(); |
||||
|
||||
}); |
||||
|
||||
it('re-draws visible clusters', function () { |
||||
|
||||
group = L.markerClusterGroup({ |
||||
iconCreateFunction: function (cluster) { |
||||
var markers = cluster.getAllChildMarkers(); |
||||
|
||||
for(var i in markers) { |
||||
if (markers[i].changed) { |
||||
return new L.DivIcon({ |
||||
className: "changed" |
||||
}); |
||||
} |
||||
} |
||||
return new L.DivIcon({ |
||||
className: "original" |
||||
}); |
||||
} |
||||
}).addTo(map); |
||||
|
||||
var marker1 = L.marker([1.5, 1.5]).addTo(group), |
||||
marker2 = L.marker([1.5, 1.5]).addTo(group); // Needed to force a cluster.
|
||||
|
||||
setMapView(); |
||||
|
||||
var marker1cluster9 = getClusterAtZoom(marker1, 9); |
||||
|
||||
// First go to some zoom levels so that Leaflet initializes clusters icons.
|
||||
expect(marker1cluster9._iconNeedsUpdate).to.be.ok(); |
||||
map.setZoom(9, {animate: false}); |
||||
expect(marker1cluster9._iconNeedsUpdate).to.not.be.ok(); |
||||
|
||||
expect(marker1cluster9._icon.className).to.contain("original"); |
||||
expect(marker1cluster9._icon.className).to.not.contain("changed"); |
||||
|
||||
// Run any animation.
|
||||
clock.tick(1000); |
||||
|
||||
// Alter the marker.
|
||||
marker1.changed = true; |
||||
|
||||
// Then request clusters refresh.
|
||||
group.refreshClusters(marker1); |
||||
|
||||
// Now check that visible clusters icon is re-drawn.
|
||||
expect(marker1cluster9._icon.className).to.contain("changed"); |
||||
expect(marker1cluster9._icon.className).to.not.contain("original"); |
||||
|
||||
}); |
||||
|
||||
// Shared code for the 2 below tests
|
||||
function iconCreateFunction(cluster) { |
||||
var markers = cluster.getAllChildMarkers(); |
||||
|
||||
for(var i in markers) { |
||||
if (markers[i].changed) { |
||||
return new L.DivIcon({ |
||||
className: "changed" |
||||
}); |
||||
} |
||||
} |
||||
return new L.DivIcon({ |
||||
className: "original" |
||||
}); |
||||
} |
||||
|
||||
it('re-draws markers in singleMarkerMode', function () { |
||||
|
||||
group = L.markerClusterGroup({ |
||||
singleMarkerMode: true, |
||||
iconCreateFunction: iconCreateFunction |
||||
}).addTo(map); |
||||
|
||||
var marker1 = L.marker([1.5, 1.5]).addTo(group); |
||||
|
||||
setMapView(); |
||||
|
||||
expect(marker1._icon.className).to.contain("original"); |
||||
|
||||
// Alter the marker.
|
||||
marker1.changed = true; |
||||
|
||||
// Then request clusters refresh.
|
||||
group.refreshClusters(marker1); |
||||
|
||||
expect(marker1._icon.className).to.contain("changed"); |
||||
expect(marker1._icon.className).to.not.contain("original"); |
||||
|
||||
}); |
||||
|
||||
it('does not modify markers that do not belong to the current group (in singleMarkerMode)', function () { |
||||
|
||||
group = L.markerClusterGroup({ |
||||
singleMarkerMode: true, |
||||
iconCreateFunction: iconCreateFunction |
||||
}).addTo(map); |
||||
|
||||
var marker1 = L.marker([1.5, 1.5]).addTo(group), |
||||
marker2 = L.marker([1.5, 1.5], { |
||||
icon: iconCreateFunction({ |
||||
getAllChildMarkers: function () { |
||||
return marker2; |
||||
} |
||||
}) |
||||
}).addTo(map); |
||||
|
||||
setMapView(); |
||||
|
||||
expect(marker1._icon.className).to.contain("original"); |
||||
expect(marker2._icon.className).to.contain("original"); |
||||
|
||||
// Alter the markers.
|
||||
marker1.changed = true; |
||||
marker2.changed = true; |
||||
|
||||
// Then request clusters refresh.
|
||||
group.refreshClusters([marker1, marker2]); |
||||
|
||||
expect(marker1._icon.className).to.contain("changed"); |
||||
expect(marker1._icon.className).to.not.contain("original"); |
||||
|
||||
expect(marker2._icon.className).to.contain("original"); |
||||
expect(marker2._icon.className).to.not.contain("changed"); |
||||
|
||||
}); |
||||
|
||||
|
||||
// Shared code for below tests.
|
||||
var marker1 = L.marker([1.5, 1.5]), |
||||
marker2 = L.marker([1.5, 1.5]), // Needed to force a cluster.
|
||||
marker3 = L.marker([1.1, 1.1]), |
||||
marker4 = L.marker([1.1, 1.1]), // Needed to force a cluster.
|
||||
marker5 = L.marker([1.9, 1.9]), |
||||
marker6 = L.marker([1.9, 1.9]), // Needed to force a cluster.
|
||||
marker1cluster8, |
||||
marker1cluster3, |
||||
marker1cluster5, |
||||
marker3cluster8, |
||||
marker3cluster3, |
||||
marker3cluster5, |
||||
marker5cluster8, |
||||
marker5cluster3, |
||||
marker5cluster5; |
||||
|
||||
function init3clusterBranches() { |
||||
|
||||
group = L.markerClusterGroup({ |
||||
maxClusterRadius: 2 // Make sure we keep distinct clusters.
|
||||
}).addTo(map); |
||||
|
||||
// Populate Marker Cluster Group.
|
||||
marker1.addTo(group); |
||||
marker2.addTo(group); |
||||
marker3.addTo(group); |
||||
marker4.addTo(group); |
||||
marker5.addTo(group); |
||||
marker6.addTo(group); |
||||
|
||||
setMapView(); |
||||
|
||||
marker1cluster8 = getClusterAtZoom(marker1, 8); |
||||
marker1cluster3 = getClusterAtZoom(marker1, 3); |
||||
marker1cluster5 = getClusterAtZoom(marker1, 5); |
||||
marker3cluster8 = getClusterAtZoom(marker3, 8); |
||||
marker3cluster3 = getClusterAtZoom(marker3, 3); |
||||
marker3cluster5 = getClusterAtZoom(marker3, 5); |
||||
marker5cluster8 = getClusterAtZoom(marker5, 8); |
||||
marker5cluster3 = getClusterAtZoom(marker5, 3); |
||||
marker5cluster5 = getClusterAtZoom(marker5, 5); |
||||
|
||||
// Make sure we have 3 distinct clusters up to zoom level Z (let's choose Z = 3)
|
||||
expect(marker1cluster3._childCount).to.equal(2); |
||||
expect(marker3cluster3._childCount).to.equal(2); |
||||
expect(marker5cluster3._childCount).to.equal(2); |
||||
|
||||
// First go to some zoom levels so that Leaflet initializes clusters icons.
|
||||
expect(marker1cluster8._iconNeedsUpdate).to.not.be.ok(); |
||||
expect(marker3cluster8._iconNeedsUpdate).to.not.be.ok(); |
||||
expect(marker5cluster8._iconNeedsUpdate).to.not.be.ok(); |
||||
|
||||
expect(marker1cluster3._iconNeedsUpdate).to.be.ok(); |
||||
expect(marker3cluster3._iconNeedsUpdate).to.be.ok(); |
||||
expect(marker5cluster3._iconNeedsUpdate).to.be.ok(); |
||||
map.setZoom(3, {animate: false}); |
||||
expect(marker1cluster3._iconNeedsUpdate).to.not.be.ok(); |
||||
expect(marker3cluster3._iconNeedsUpdate).to.not.be.ok(); |
||||
expect(marker5cluster3._iconNeedsUpdate).to.not.be.ok(); |
||||
|
||||
// Finish on an intermediate zoom level.
|
||||
expect(marker1cluster5._iconNeedsUpdate).to.be.ok(); |
||||
expect(marker3cluster5._iconNeedsUpdate).to.be.ok(); |
||||
expect(marker5cluster5._iconNeedsUpdate).to.be.ok(); |
||||
map.setZoom(5, {animate: false}); |
||||
expect(marker1cluster5._iconNeedsUpdate).to.not.be.ok(); |
||||
expect(marker3cluster5._iconNeedsUpdate).to.not.be.ok(); |
||||
expect(marker5cluster5._iconNeedsUpdate).to.not.be.ok(); |
||||
|
||||
// Run any animation.
|
||||
clock.tick(1000); |
||||
|
||||
// Ready to refresh clusters with method of choice and assess result.
|
||||
} |
||||
|
||||
it('does not flag clusters of other markers', function () { |
||||
|
||||
init3clusterBranches(); |
||||
|
||||
// Then request clusters refresh.
|
||||
// No need to actually modify the marker.
|
||||
group.refreshClusters(marker1); |
||||
|
||||
// Now check that non-visible clusters are flagged as "dirty".
|
||||
expect(marker1cluster8._iconNeedsUpdate).to.be.ok(); |
||||
expect(marker1cluster3._iconNeedsUpdate).to.be.ok(); |
||||
|
||||
// Finally check that non-involved clusters are not "dirty".
|
||||
expect(marker3cluster8._iconNeedsUpdate).to.not.be.ok(); |
||||
expect(marker3cluster3._iconNeedsUpdate).to.not.be.ok(); |
||||
|
||||
expect(marker5cluster8._iconNeedsUpdate).to.not.be.ok(); |
||||
expect(marker5cluster3._iconNeedsUpdate).to.not.be.ok(); |
||||
|
||||
}); |
||||
|
||||
it('processes itself when no argument is passed', function () { |
||||
|
||||
init3clusterBranches(); |
||||
|
||||
// Then request clusters refresh.
|
||||
// No need to actually modify the marker.
|
||||
group.refreshClusters(); |
||||
|
||||
// Now check that non-visible clusters are flagged as "dirty".
|
||||
expect(marker1cluster8._iconNeedsUpdate).to.be.ok(); |
||||
expect(marker1cluster3._iconNeedsUpdate).to.be.ok(); |
||||
|
||||
expect(marker3cluster8._iconNeedsUpdate).to.be.ok(); |
||||
expect(marker3cluster3._iconNeedsUpdate).to.be.ok(); |
||||
|
||||
expect(marker5cluster8._iconNeedsUpdate).to.be.ok(); |
||||
expect(marker5cluster3._iconNeedsUpdate).to.be.ok(); |
||||
|
||||
}); |
||||
|
||||
it('accepts an array of markers', function () { |
||||
|
||||
init3clusterBranches(); |
||||
|
||||
// Then request clusters refresh.
|
||||
// No need to actually modify the markers.
|
||||
group.refreshClusters([marker1, marker5]); |
||||
// Clusters of marker3 and 4 shall not be flagged.
|
||||
|
||||
// Now check that non-visible clusters are flagged as "dirty".
|
||||
expect(marker1cluster8._iconNeedsUpdate).to.be.ok(); |
||||
expect(marker1cluster3._iconNeedsUpdate).to.be.ok(); |
||||
|
||||
expect(marker5cluster8._iconNeedsUpdate).to.be.ok(); |
||||
expect(marker5cluster3._iconNeedsUpdate).to.be.ok(); |
||||
|
||||
// Clusters of marker3 and 4 shall not be flagged.
|
||||
expect(marker3cluster8._iconNeedsUpdate).to.not.be.ok(); |
||||
expect(marker3cluster3._iconNeedsUpdate).to.not.be.ok(); |
||||
|
||||
}); |
||||
|
||||
it('accepts a mapping of markers', function () { |
||||
|
||||
init3clusterBranches(); |
||||
|
||||
// Then request clusters refresh.
|
||||
// No need to actually modify the markers.
|
||||
group.refreshClusters({ |
||||
id1: marker1, |
||||
id2: marker5 |
||||
}); // Clusters of marker3 and 4 shall not be flagged.
|
||||
|
||||
// Now check that non-visible clusters are flagged as "dirty".
|
||||
expect(marker1cluster8._iconNeedsUpdate).to.be.ok(); |
||||
expect(marker1cluster3._iconNeedsUpdate).to.be.ok(); |
||||
|
||||
expect(marker5cluster8._iconNeedsUpdate).to.be.ok(); |
||||
expect(marker5cluster3._iconNeedsUpdate).to.be.ok(); |
||||
|
||||
// Clusters of marker3 and 4 shall not be flagged.
|
||||
expect(marker3cluster8._iconNeedsUpdate).to.not.be.ok(); |
||||
expect(marker3cluster3._iconNeedsUpdate).to.not.be.ok(); |
||||
|
||||
}); |
||||
|
||||
it('accepts an L.LayerGroup', function () { |
||||
|
||||
init3clusterBranches(); |
||||
|
||||
// Then request clusters refresh.
|
||||
// No need to actually modify the markers.
|
||||
var layerGroup = new L.LayerGroup([marker1, marker5]); |
||||
group.refreshClusters(layerGroup); |
||||
// Clusters of marker3 and 4 shall not be flagged.
|
||||
|
||||
// Now check that non-visible clusters are flagged as "dirty".
|
||||
expect(marker1cluster8._iconNeedsUpdate).to.be.ok(); |
||||
expect(marker1cluster3._iconNeedsUpdate).to.be.ok(); |
||||
|
||||
expect(marker5cluster8._iconNeedsUpdate).to.be.ok(); |
||||
expect(marker5cluster3._iconNeedsUpdate).to.be.ok(); |
||||
|
||||
// Clusters of marker3 and 4 shall not be flagged.
|
||||
expect(marker3cluster8._iconNeedsUpdate).to.not.be.ok(); |
||||
expect(marker3cluster3._iconNeedsUpdate).to.not.be.ok(); |
||||
|
||||
}); |
||||
|
||||
it('accepts an L.MarkerCluster', function () { |
||||
|
||||
init3clusterBranches(); |
||||
|
||||
// Then request clusters refresh.
|
||||
// No need to actually modify the markers.
|
||||
group.refreshClusters(marker1cluster8); |
||||
// Clusters of marker3, 4, 5 and 6 shall not be flagged.
|
||||
|
||||
// Now check that non-visible clusters are flagged as "dirty".
|
||||
expect(marker1cluster8._iconNeedsUpdate).to.be.ok(); |
||||
expect(marker1cluster3._iconNeedsUpdate).to.be.ok(); |
||||
|
||||
// Clusters of marker3 and 4 shall not be flagged.
|
||||
expect(marker3cluster8._iconNeedsUpdate).to.not.be.ok(); |
||||
expect(marker3cluster3._iconNeedsUpdate).to.not.be.ok(); |
||||
|
||||
expect(marker5cluster8._iconNeedsUpdate).to.not.be.ok(); |
||||
expect(marker5cluster3._iconNeedsUpdate).to.not.be.ok(); |
||||
|
||||
}); |
||||
}); |
@ -0,0 +1,162 @@
|
||||
describe('Remember opacity', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var map, div, clock, markers, group; |
||||
|
||||
var markerDefs = [ |
||||
{latLng: [ 0, 0], opts: {opacity: 0.9}}, |
||||
{latLng: [ 0, 1], opts: {opacity: 0.5}}, |
||||
{latLng: [ 0,-1], opts: {opacity: 0.5}}, |
||||
{latLng: [ 1, 0], opts: {opacity: 0.5}}, |
||||
{latLng: [-1, 0], opts: {opacity: 0.5}}, |
||||
{latLng: [ 1, 1], opts: {opacity: 0.2}}, |
||||
{latLng: [ 1,-1], opts: {opacity: 0.2}}, |
||||
{latLng: [-1, 1], opts: {opacity: 0.2}}, |
||||
{latLng: [-1,-1], opts: {opacity: 0.2}} |
||||
]; |
||||
|
||||
var bounds = L.latLngBounds( L.latLng( -1.1, -1.1), |
||||
L.latLng( 1.1, 1.1) ); |
||||
|
||||
beforeEach(function () { |
||||
clock = sinon.useFakeTimers(); |
||||
|
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
markers = []; |
||||
for (var i = 0; i < markerDefs.length; i++) { |
||||
markers.push( L.marker(markerDefs[i].latLng, markerDefs[i].opts ) ); |
||||
} |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
group.clearLayers(); |
||||
map.removeLayer(group); |
||||
map.remove(); |
||||
document.body.removeChild(div); |
||||
clock.restore(); |
||||
|
||||
clock = div = map = markers = group = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('clusters semitransparent markers into an opaque one', function () { |
||||
map.setView(new L.LatLng(0,0), 1); |
||||
|
||||
group = new L.MarkerClusterGroup({ |
||||
maxClusterRadius: 20 |
||||
}); |
||||
group.addLayers(markers); |
||||
map.addLayer(group); |
||||
|
||||
var visibleClusters = group._featureGroup.getLayers(); |
||||
expect(visibleClusters.length).to.be(1); |
||||
expect(visibleClusters[0].options.opacity).to.be(1); |
||||
}); |
||||
|
||||
|
||||
it('unclusters an opaque marker into semitransparent ones', function () { |
||||
map.setView(new L.LatLng(0,0), 1); |
||||
var visibleClusters; |
||||
|
||||
group = new L.MarkerClusterGroup({ |
||||
maxClusterRadius: 20 |
||||
}); |
||||
group.addLayers(markers); |
||||
map.addLayer(group); |
||||
|
||||
map.fitBounds(bounds); |
||||
clock.tick(1000); |
||||
|
||||
visibleClusters = group._featureGroup.getLayers(); |
||||
expect(visibleClusters.length).to.be(9); |
||||
for (var i=0; i<9; i++) { |
||||
expect(visibleClusters[i].options.opacity).to.be.within(0.2,0.9); |
||||
} |
||||
|
||||
// It shall also work after zooming in/out a second time.
|
||||
map.setView(new L.LatLng(0,0), 1); |
||||
clock.tick(1000); |
||||
|
||||
map.fitBounds(bounds); |
||||
clock.tick(1000); |
||||
|
||||
visibleClusters = group._featureGroup.getLayers(); |
||||
expect(visibleClusters.length).to.be(9); |
||||
for (var i=0; i<9; i++) { |
||||
expect(visibleClusters[i].options.opacity).to.be.within(0.2,0.9); |
||||
} |
||||
}); |
||||
|
||||
|
||||
it('has no problems zooming in and out several times', function () { |
||||
var visibleClusters; |
||||
|
||||
group = new L.MarkerClusterGroup({ |
||||
maxClusterRadius: 20 |
||||
}); |
||||
group.addLayers(markers); |
||||
map.addLayer(group); |
||||
|
||||
// Zoom in and out a couple times
|
||||
for (var i=0; i<10; i++) { |
||||
map.fitBounds(bounds); |
||||
clock.tick(1000); |
||||
|
||||
visibleClusters = group._featureGroup.getLayers(); |
||||
expect(visibleClusters.length).to.be(9); |
||||
for (var i=0; i<9; i++) { |
||||
expect(visibleClusters[i].options.opacity).to.be.within(0.2,0.9); |
||||
} |
||||
|
||||
map.setView(new L.LatLng(0,0), 1); |
||||
clock.tick(1000); |
||||
|
||||
visibleClusters = group._featureGroup.getLayers(); |
||||
expect(visibleClusters.length).to.be(1); |
||||
expect(visibleClusters[0].options.opacity).to.be(1); |
||||
} |
||||
|
||||
}); |
||||
|
||||
it('retains the opacity of each individual marker', function () { |
||||
map.setView(new L.LatLng(0,0), 1); |
||||
|
||||
var visibleClusters; |
||||
group = new L.MarkerClusterGroup({ |
||||
maxClusterRadius: 20 |
||||
}); |
||||
group.addLayers(markers); |
||||
map.addLayer(group); |
||||
|
||||
|
||||
// Zoom in and out a couple times
|
||||
for (var i=0; i<5; i++) { |
||||
map.fitBounds(bounds); |
||||
clock.tick(1000); |
||||
|
||||
map.setView(new L.LatLng(0,0), 1); |
||||
clock.tick(1000); |
||||
} |
||||
|
||||
for (var i=0; i<markerDefs.length; i++) { |
||||
|
||||
// console.log(markerDefs[i].latLng, markerDefs[i].opts.opacity);
|
||||
|
||||
map.setView(L.latLng(markerDefs[i].latLng), 18); |
||||
clock.tick(1000); |
||||
visibleClusters = group._featureGroup.getLayers(); |
||||
expect(visibleClusters.length).to.be(1); |
||||
expect(visibleClusters[0].options.opacity).to.be(markerDefs[i].opts.opacity); |
||||
} |
||||
}); |
||||
|
||||
}); |
@ -0,0 +1,204 @@
|
||||
describe('removeLayer', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var clock, div, map, group; |
||||
|
||||
beforeEach(function () { |
||||
clock = sinon.useFakeTimers(); |
||||
|
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
if (group instanceof L.MarkerClusterGroup) { |
||||
group.clearLayers(); |
||||
map.removeLayer(group); |
||||
} |
||||
|
||||
map.remove(); |
||||
div.remove() |
||||
clock.restore(); |
||||
|
||||
clock = div = map = group = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('removes a layer that was added to it', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
|
||||
group.addLayer(marker); |
||||
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane); |
||||
|
||||
group.removeLayer(marker); |
||||
|
||||
expect(marker._icon).to.be(null); |
||||
}); |
||||
|
||||
it('doesnt remove a layer not added to it', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
|
||||
map.addLayer(marker); |
||||
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane); |
||||
|
||||
group.removeLayer(marker); |
||||
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane); |
||||
}); |
||||
|
||||
it('removes a layer that was added to it (before being on the map) that is shown in a cluster', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
group.removeLayer(marker); |
||||
|
||||
expect(marker._icon).to.be(undefined); |
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane); |
||||
}); |
||||
|
||||
it('removes a layer that was added to it (after being on the map) that is shown in a cluster', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
|
||||
group.removeLayer(marker); |
||||
|
||||
expect(marker._icon).to.be(null); |
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane); |
||||
}); |
||||
|
||||
it('removes a layer that was added to it (before being on the map) that is individually', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1, 1.5]); |
||||
var marker2 = new L.Marker([3, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane); |
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane); |
||||
|
||||
group.removeLayer(marker); |
||||
|
||||
expect(marker._icon).to.be(null); |
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane); |
||||
}); |
||||
|
||||
it('removes a layer (with animation) that was added to it (after being on the map) that is shown in a cluster', function () { |
||||
|
||||
group = new L.MarkerClusterGroup({ animateAddingMarkers: true }); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000); |
||||
|
||||
expect(marker._icon).to.be(null); |
||||
expect(marker2._icon).to.be(null); |
||||
|
||||
group.removeLayer(marker); |
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000); |
||||
|
||||
expect(marker._icon).to.be(null); |
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane); |
||||
}); |
||||
|
||||
it('removes the layers that are in the given LayerGroup', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayers([marker, marker2]); |
||||
|
||||
var layer = L.layerGroup(); |
||||
layer.addLayer(marker2); |
||||
group.removeLayer(layer); |
||||
|
||||
expect(marker._icon).to.not.be(undefined); |
||||
expect(marker2._icon).to.be(undefined); |
||||
}); |
||||
|
||||
it('removes the layers that are in the given LayerGroup when not on the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([marker, marker2]); |
||||
|
||||
var layer = L.layerGroup(); |
||||
layer.addLayer(marker2); |
||||
group.removeLayer(layer); |
||||
|
||||
expect(group.hasLayer(marker)).to.be(true); |
||||
expect(group.hasLayer(marker2)).to.be(false); |
||||
}); |
||||
|
||||
it('passes control to removeLayers when marker is a Layer Group', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker1 = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([marker1, marker2]); |
||||
|
||||
var layer = L.layerGroup(); |
||||
layer.addLayer(marker2); |
||||
group.removeLayer(new L.LayerGroup([layer])); |
||||
|
||||
expect(group.hasLayer(marker1)).to.be(true); |
||||
expect(group.hasLayer(marker2)).to.be(false); |
||||
}); |
||||
}); |
@ -0,0 +1,30 @@
|
||||
function noSpecs() { |
||||
xit('has no specs'); |
||||
} |
||||
|
||||
if (!Array.prototype.map) { |
||||
Array.prototype.map = function(fun /*, thisp */) { |
||||
"use strict"; |
||||
|
||||
if (this === void 0 || this === null) |
||||
throw new TypeError(); |
||||
|
||||
var t = Object(this); |
||||
var len = t.length >>> 0; |
||||
if (typeof fun !== "function") |
||||
throw new TypeError(); |
||||
|
||||
var res = new Array(len); |
||||
var thisp = arguments[1]; |
||||
for (var i = 0; i < len; i++) { |
||||
if (i in t) |
||||
res[i] = fun.call(thisp, t[i], i, t); |
||||
} |
||||
|
||||
return res; |
||||
}; |
||||
} |
||||
|
||||
Number.isFinite = Number.isFinite || function(value) { |
||||
return typeof value === 'number' && isFinite(value); |
||||
} |
@ -0,0 +1,117 @@
|
||||
describe('animate option', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var div, map, group; |
||||
|
||||
beforeEach(function () { |
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
if (group instanceof L.MarkerClusterGroup) { |
||||
group.removeLayers(group.getLayers()); |
||||
map.removeLayer(group); |
||||
} |
||||
|
||||
map.remove(); |
||||
div.remove(); |
||||
|
||||
div = map = group = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('hooks animated methods version by default', function () { |
||||
|
||||
// Need to add to map so that we have the top cluster level created.
|
||||
group = L.markerClusterGroup().addTo(map); |
||||
|
||||
var withAnimation = L.MarkerClusterGroup.prototype._withAnimation; |
||||
|
||||
// MCG animated methods.
|
||||
expect(group._animationStart).to.be(withAnimation._animationStart); |
||||
expect(group._animationZoomIn).to.be(withAnimation._animationZoomIn); |
||||
expect(group._animationZoomOut).to.be(withAnimation._animationZoomOut); |
||||
expect(group._animationAddLayer).to.be(withAnimation._animationAddLayer); |
||||
|
||||
// MarkerCluster spiderfy animated methods
|
||||
var cluster = group._topClusterLevel; |
||||
|
||||
withAnimation = L.MarkerCluster.prototype; |
||||
|
||||
expect(cluster._animationSpiderfy).to.be(withAnimation._animationSpiderfy); |
||||
expect(cluster._animationUnspiderfy).to.be(withAnimation._animationUnspiderfy); |
||||
|
||||
}); |
||||
|
||||
it('hooks non-animated methods version when set to false', function () { |
||||
|
||||
// Need to add to map so that we have the top cluster level created.
|
||||
group = L.markerClusterGroup({animate: false}).addTo(map); |
||||
|
||||
var noAnimation = L.MarkerClusterGroup.prototype._noAnimation; |
||||
|
||||
// MCG non-animated methods.
|
||||
expect(group._animationStart).to.be(noAnimation._animationStart); |
||||
expect(group._animationZoomIn).to.be(noAnimation._animationZoomIn); |
||||
expect(group._animationZoomOut).to.be(noAnimation._animationZoomOut); |
||||
expect(group._animationAddLayer).to.be(noAnimation._animationAddLayer); |
||||
|
||||
// MarkerCluster spiderfy non-animated methods
|
||||
var cluster = group._topClusterLevel; |
||||
|
||||
noAnimation = L.MarkerClusterNonAnimated.prototype; |
||||
|
||||
expect(cluster._animationSpiderfy).to.be(noAnimation._animationSpiderfy); |
||||
expect(cluster._animationUnspiderfy).to.be(noAnimation._animationUnspiderfy); |
||||
|
||||
}); |
||||
|
||||
it('always hooks non-animated methods version when L.DomUtil.TRANSITION is false', function () { |
||||
// Fool Leaflet, make it think the browser does not support transitions.
|
||||
var realDomUtil = L.DomUtil; |
||||
var fakeDomUtil = {}; |
||||
for (k in realDomUtil) { |
||||
fakeDomUtil[k] = realDomUtil[k]; |
||||
} |
||||
fakeDomUtil.TRANSITION = false; |
||||
L.DomUtil = fakeDomUtil; |
||||
|
||||
try { |
||||
// Need to add to map so that we have the top cluster level created.
|
||||
group = L.markerClusterGroup({animate: true}).addTo(map); |
||||
|
||||
var noAnimation = L.MarkerClusterGroup.prototype._noAnimation; |
||||
|
||||
// MCG non-animated methods.
|
||||
expect(group._animationStart).to.be(noAnimation._animationStart); |
||||
expect(group._animationZoomIn).to.be(noAnimation._animationZoomIn); |
||||
expect(group._animationZoomOut).to.be(noAnimation._animationZoomOut); |
||||
expect(group._animationAddLayer).to.be(noAnimation._animationAddLayer); |
||||
|
||||
// MarkerCluster spiderfy non-animated methods
|
||||
var cluster = group._topClusterLevel; |
||||
|
||||
noAnimation = L.MarkerClusterNonAnimated.prototype; |
||||
|
||||
expect(cluster._animationSpiderfy).to.be(noAnimation._animationSpiderfy); |
||||
expect(cluster._animationUnspiderfy).to.be(noAnimation._animationUnspiderfy); |
||||
} finally { |
||||
//Undo the DomUtil replacement hack
|
||||
L.DomUtil = realDomUtil; |
||||
} |
||||
}); |
||||
}); |
@ -0,0 +1,54 @@
|
||||
describe('clearLayer', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var map, div; |
||||
|
||||
beforeEach(function () { |
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
afterEach(function () { |
||||
map.remove(); |
||||
document.body.removeChild(div); |
||||
|
||||
map = div = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('clears everything before adding to map', function () { |
||||
var group = new L.MarkerClusterGroup(); |
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([polygon, marker]); |
||||
group.clearLayers(); |
||||
|
||||
expect(group.hasLayer(polygon)).to.be(false); |
||||
expect(group.hasLayer(marker)).to.be(false); |
||||
}); |
||||
|
||||
it('hits polygons and markers after adding to map', function () { |
||||
var group = new L.MarkerClusterGroup(); |
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([polygon, marker]); |
||||
map.addLayer(group); |
||||
group.clearLayers(); |
||||
|
||||
expect(group.hasLayer(polygon)).to.be(false); |
||||
expect(group.hasLayer(marker)).to.be(false); |
||||
}); |
||||
}); |
@ -0,0 +1,63 @@
|
||||
describe('disableClusteringAtZoom option', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var div, map, group, clock; |
||||
|
||||
beforeEach(function () { |
||||
clock = sinon.useFakeTimers(); |
||||
|
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
group.clearLayers(); |
||||
map.removeLayer(group); |
||||
map.remove(); |
||||
div.remove(); |
||||
clock.restore(); |
||||
|
||||
div, map, group, clock = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('unclusters at zoom level equal or higher', function () { |
||||
|
||||
var maxZoom = 15; |
||||
|
||||
group = new L.MarkerClusterGroup({ |
||||
disableClusteringAtZoom: maxZoom |
||||
}); |
||||
|
||||
group.addLayers([ |
||||
new L.Marker([1.5, 1.5]), |
||||
new L.Marker([1.5, 1.5]) |
||||
]); |
||||
map.addLayer(group); |
||||
|
||||
expect(group._maxZoom).to.equal(maxZoom - 1); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.equal(1); // 1 cluster.
|
||||
|
||||
map.setZoom(14); |
||||
clock.tick(1000); |
||||
expect(map._panes.markerPane.childNodes.length).to.equal(1); // 1 cluster.
|
||||
|
||||
map.setZoom(15); |
||||
clock.tick(1000); |
||||
expect(map._panes.markerPane.childNodes.length).to.equal(2); // 2 markers.
|
||||
}); |
||||
}); |
@ -0,0 +1,65 @@
|
||||
describe('eachLayer', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var map, div; |
||||
|
||||
beforeEach(function () { |
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
map.remove(); |
||||
document.body.removeChild(div); |
||||
|
||||
map = div = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('hits polygons and markers before adding to map', function () { |
||||
var group = new L.MarkerClusterGroup(); |
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([polygon, marker]); |
||||
|
||||
var layers = []; |
||||
group.eachLayer(function (l) { |
||||
layers.push(l); |
||||
}); |
||||
|
||||
expect(layers.length).to.be(2); |
||||
expect(layers).to.contain(marker); |
||||
expect(layers).to.contain(polygon); |
||||
}); |
||||
|
||||
it('hits polygons and markers after adding to map', function () { |
||||
var group = new L.MarkerClusterGroup(); |
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([polygon, marker]); |
||||
map.addLayer(group); |
||||
|
||||
var layers = []; |
||||
group.eachLayer(function (l) { |
||||
layers.push(l); |
||||
}); |
||||
|
||||
expect(layers.length).to.be(2); |
||||
expect(layers).to.contain(marker); |
||||
expect(layers).to.contain(polygon); |
||||
}); |
||||
}); |
@ -0,0 +1,373 @@
|
||||
describe('events', function() { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var div, map, group; |
||||
|
||||
beforeEach(function () { |
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
if (group instanceof L.MarkerClusterGroup) { |
||||
group.removeLayers(group.getLayers()); |
||||
map.removeLayer(group); |
||||
} |
||||
|
||||
map.remove(); |
||||
div.remove(); |
||||
|
||||
div = map = group = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('is fired for a single child marker', function () { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.on('click', callback); |
||||
group.addLayer(marker); |
||||
map.addLayer(group); |
||||
|
||||
// In Leaflet 1.0.0, event propagation must be explicitly set by 3rd argument.
|
||||
marker.fire('click', null, true); |
||||
|
||||
expect(callback.called).to.be(true); |
||||
}); |
||||
|
||||
it('is fired for a child polygon', function () { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
group.on('click', callback); |
||||
group.addLayer(polygon); |
||||
map.addLayer(group); |
||||
|
||||
polygon.fire('click', null, true); |
||||
|
||||
expect(callback.called).to.be(true); |
||||
}); |
||||
|
||||
it('is fired for a cluster click', function () { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.on('clusterclick', callback); |
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
var cluster = group.getVisibleParent(marker); |
||||
expect(cluster instanceof L.MarkerCluster).to.be(true); |
||||
|
||||
cluster.fire('click', null, true); |
||||
|
||||
expect(callback.called).to.be(true); |
||||
}); |
||||
|
||||
describe('after being added, removed, re-added from the map', function() { |
||||
|
||||
it('still fires events for nonpoint data', function() { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
group.on('click', callback); |
||||
group.addLayer(polygon); |
||||
map.addLayer(group); |
||||
map.removeLayer(group); |
||||
map.addLayer(group); |
||||
|
||||
polygon.fire('click', null, true); |
||||
|
||||
expect(callback.called).to.be(true); |
||||
}); |
||||
|
||||
it('still fires events for point data', function() { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.on('click', callback); |
||||
group.addLayer(marker); |
||||
map.addLayer(group); |
||||
map.removeLayer(group); |
||||
map.addLayer(group); |
||||
|
||||
marker.fire('click', null, true); |
||||
|
||||
expect(callback.called).to.be(true); |
||||
}); |
||||
|
||||
it('still fires cluster events', function() { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.on('clusterclick', callback); |
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
map.removeLayer(group); |
||||
map.addLayer(group); |
||||
|
||||
var cluster = group.getVisibleParent(marker); |
||||
expect(cluster instanceof L.MarkerCluster).to.be(true); |
||||
|
||||
cluster.fire('click', null, true); |
||||
|
||||
expect(callback.called).to.be(true); |
||||
}); |
||||
|
||||
it('does not break map events', function () { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
map.on('zoomend', callback); |
||||
map.addLayer(group); |
||||
|
||||
map.removeLayer(group); |
||||
map.addLayer(group); |
||||
|
||||
map.fire('zoomend'); |
||||
|
||||
expect(callback.called).to.be(true); |
||||
}); |
||||
|
||||
//layeradd
|
||||
it('fires layeradd when markers are added while not on the map', function() { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
group.on('layeradd', callback); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
group.addLayer(marker); |
||||
|
||||
expect(callback.callCount).to.be(1); |
||||
}); |
||||
|
||||
it('fires layeradd when vectors are added while not on the map', function() { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
group.on('layeradd', callback); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
group.addLayer(polygon); |
||||
|
||||
expect(callback.callCount).to.be(1); |
||||
}); |
||||
|
||||
it('fires layeradd when markers are added while on the map', function() { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
group.on('layeradd', callback); |
||||
map.addLayer(group); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
group.addLayer(marker); |
||||
|
||||
expect(callback.callCount).to.be(1); |
||||
}); |
||||
|
||||
it('fires layeradd when vectors are added while on the map', function() { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
group.on('layeradd', callback); |
||||
map.addLayer(group); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
group.addLayer(polygon); |
||||
|
||||
expect(callback.callCount).to.be(1); |
||||
}); |
||||
|
||||
it('fires layeradd when markers are added using addLayers while on the map with chunked loading', function() { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup({ chunkedLoading: true }); |
||||
group.on('layeradd', callback); |
||||
map.addLayer(group); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
group.addLayers([marker]); |
||||
|
||||
expect(callback.callCount).to.be(1); |
||||
}); |
||||
|
||||
it('fires layeradd when vectors are added using addLayers while on the map with chunked loading', function() { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup({ chunkedLoading: true }); |
||||
group.on('layeradd', callback); |
||||
map.addLayer(group); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
group.addLayers([polygon]); |
||||
|
||||
expect(callback.callCount).to.be(1); |
||||
}); |
||||
|
||||
//layerremove
|
||||
it('fires layerremove when a marker is removed while not on the map', function() { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
group.on('layerremove', callback); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
group.addLayer(marker); |
||||
group.removeLayer(marker); |
||||
|
||||
expect(callback.callCount).to.be(1); |
||||
}); |
||||
|
||||
it('fires layerremove when a vector is removed while not on the map', function() { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
group.on('layerremove', callback); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
group.addLayer(polygon); |
||||
group.removeLayer(polygon); |
||||
|
||||
expect(callback.callCount).to.be(1); |
||||
}); |
||||
|
||||
it('fires layerremove when a marker is removed while on the map', function() { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
group.on('layerremove', callback); |
||||
map.addLayer(group); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
group.addLayer(marker); |
||||
group.removeLayer(marker); |
||||
|
||||
expect(callback.callCount).to.be(1); |
||||
}); |
||||
|
||||
it('fires layerremove when a vector is removed while on the map', function() { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
group.on('layerremove', callback); |
||||
map.addLayer(group); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
group.addLayer(polygon); |
||||
group.removeLayer(polygon); |
||||
|
||||
expect(callback.callCount).to.be(1); |
||||
}); |
||||
|
||||
it('fires layerremove when a marker is removed using removeLayers while on the map with chunked loading', function() { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup({ chunkedLoading: true }); |
||||
group.on('layerremove', callback); |
||||
map.addLayer(group); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
group.addLayers([marker]); |
||||
group.removeLayers([marker]); |
||||
|
||||
expect(callback.callCount).to.be(1); |
||||
}); |
||||
|
||||
it('fires layerremove when a vector is removed using removeLayers while on the map with chunked loading', function() { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup({ chunkedLoading: true }); |
||||
group.on('layerremove', callback); |
||||
map.addLayer(group); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
group.addLayers([polygon]); |
||||
group.removeLayers([polygon]); |
||||
|
||||
expect(callback.callCount).to.be(1); |
||||
}); |
||||
|
||||
it('fires layerremove when a marker is removed using removeLayers while not on the map with chunked loading', function() { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup({ chunkedLoading: true }); |
||||
group.on('layerremove', callback); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
group.addLayers([marker]); |
||||
group.removeLayers([marker]); |
||||
|
||||
expect(callback.callCount).to.be(1); |
||||
}); |
||||
|
||||
it('fires layerremove when a vector is removed using removeLayers while not on the map with chunked loading', function() { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup({ chunkedLoading: true }); |
||||
group.on('layerremove', callback); |
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
group.addLayers([polygon]); |
||||
group.removeLayers([polygon]); |
||||
|
||||
expect(callback.callCount).to.be(1); |
||||
}); |
||||
}); |
||||
|
||||
/* |
||||
//No normal events can be fired by a clustered marker, so probably don't need this.
|
||||
it('is fired for a clustered child marker', function() { |
||||
var callback = sinon.spy(); |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.on('click', callback); |
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
marker.fire('click'); |
||||
|
||||
expect(callback.called).to.be(true); |
||||
}); |
||||
*/ |
||||
}); |
@ -0,0 +1,128 @@
|
||||
describe('getBounds', function() { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var map, div; |
||||
|
||||
beforeEach(function() { |
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
afterEach(function() { |
||||
map.remove(); |
||||
document.body.removeChild(div); |
||||
|
||||
map = div = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
describe('polygon layer', function() { |
||||
it('returns the correct bounds before adding to the map', function() { |
||||
var group = new L.MarkerClusterGroup(); |
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
group.addLayer(polygon); |
||||
|
||||
expect(group.getBounds().equals(polygon.getBounds())).to.be(true); |
||||
}); |
||||
|
||||
it('returns the correct bounds after adding to the map after adding polygon', function() { |
||||
var group = new L.MarkerClusterGroup(); |
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
group.addLayer(polygon); |
||||
map.addLayer(group); |
||||
|
||||
expect(group.getBounds().equals(polygon.getBounds())).to.be(true); |
||||
}); |
||||
|
||||
it('returns the correct bounds after adding to the map before adding polygon', function() { |
||||
var group = new L.MarkerClusterGroup(); |
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(polygon); |
||||
|
||||
expect(group.getBounds().equals(polygon.getBounds())).to.be(true); |
||||
}); |
||||
}); |
||||
|
||||
describe('marker layers', function () { |
||||
it('returns the correct bounds before adding to the map', function () { |
||||
var group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.0, 5.0]); |
||||
var marker3 = new L.Marker([6.0, 2.0]); |
||||
|
||||
group.addLayers([marker, marker2, marker3]); |
||||
|
||||
expect(group.getBounds().equals(L.latLngBounds([1.0, 5.0], [6.0, 1.5]))).to.be(true); |
||||
}); |
||||
|
||||
it('returns the correct bounds after adding to the map after adding markers', function () { |
||||
var group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.0, 5.0]); |
||||
var marker3 = new L.Marker([6.0, 2.0]); |
||||
|
||||
group.addLayers([marker, marker2, marker3]); |
||||
map.addLayer(group); |
||||
|
||||
expect(group.getBounds().equals(L.latLngBounds([1.0, 5.0], [6.0, 1.5]))).to.be(true); |
||||
}); |
||||
|
||||
it('returns the correct bounds after adding to the map before adding markers', function () { |
||||
var group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.0, 5.0]); |
||||
var marker3 = new L.Marker([6.0, 2.0]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayers([marker, marker2, marker3]); |
||||
|
||||
expect(group.getBounds().equals(L.latLngBounds([1.0, 5.0], [6.0, 1.5]))).to.be(true); |
||||
}); |
||||
}); |
||||
|
||||
describe('marker and polygon layers', function() { |
||||
it('returns the correct bounds before adding to the map', function() { |
||||
var group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([6.0, 3.0]); |
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
group.addLayers([marker, polygon]); |
||||
|
||||
expect(group.getBounds().equals(L.latLngBounds([1.5, 1.5], [6.0, 3.0]))).to.be(true); |
||||
}); |
||||
|
||||
it('returns the correct bounds after adding to the map', function () { |
||||
var group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([6.0, 3.0]); |
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayers([marker, polygon]); |
||||
|
||||
expect(group.getBounds().equals(L.latLngBounds([1.5, 1.5], [6.0, 3.0]))).to.be(true); |
||||
}); |
||||
}); |
||||
|
||||
describe('blank layer', function () { |
||||
it('returns a blank bounds', function () { |
||||
var group = new L.MarkerClusterGroup(); |
||||
|
||||
expect(group.getBounds().isValid()).to.be(false); |
||||
}); |
||||
}); |
||||
}); |
@ -0,0 +1,75 @@
|
||||
describe('getLayers', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var map, div; |
||||
|
||||
beforeEach(function () { |
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
afterEach(function () { |
||||
map.remove(); |
||||
document.body.removeChild(div); |
||||
|
||||
map = div = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('hits polygons and markers before adding to map', function () { |
||||
var group = new L.MarkerClusterGroup(); |
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([polygon, marker]); |
||||
|
||||
var layers = group.getLayers(); |
||||
|
||||
expect(layers.length).to.be(2); |
||||
expect(layers).to.contain(marker); |
||||
expect(layers).to.contain(polygon); |
||||
}); |
||||
|
||||
it('hits polygons and markers after adding to map', function () { |
||||
var group = new L.MarkerClusterGroup(); |
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([polygon, marker]); |
||||
map.addLayer(group); |
||||
|
||||
var layers = group.getLayers(); |
||||
|
||||
expect(layers.length).to.be(2); |
||||
expect(layers).to.contain(marker); |
||||
expect(layers).to.contain(polygon); |
||||
}); |
||||
|
||||
it('skips markers and polygons removed while not on the map', function () { |
||||
var group = new L.MarkerClusterGroup(); |
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([polygon, marker]); |
||||
|
||||
map.addLayer(group); |
||||
map.removeLayer(group); |
||||
|
||||
group.removeLayers([polygon, marker]); |
||||
|
||||
var layers = group.getLayers(); |
||||
|
||||
expect(layers.length).to.be(0); |
||||
}); |
||||
}); |
@ -0,0 +1,72 @@
|
||||
describe('getVisibleParent', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var group, map, div; |
||||
|
||||
beforeEach(function () { |
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
group.clearLayers(); |
||||
map.removeLayer(group); |
||||
map.remove(); |
||||
document.body.removeChild(div); |
||||
|
||||
group = map = div = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('gets the marker if the marker is visible', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayer(marker); |
||||
map.addLayer(group); |
||||
|
||||
var vp = group.getVisibleParent(marker); |
||||
|
||||
expect(vp).to.be(marker); |
||||
}); |
||||
|
||||
it('gets the visible cluster if it is clustered', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
var vp = group.getVisibleParent(marker); |
||||
|
||||
expect(vp).to.be.a(L.MarkerCluster); |
||||
expect(vp._icon).to.not.be(null); |
||||
expect(vp._icon).to.not.be(undefined); |
||||
}); |
||||
|
||||
it('returns null if the marker and parents are all not visible', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([5.5, 1.5]); |
||||
var marker2 = new L.Marker([5.5, 1.5]); |
||||
|
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
var vp = group.getVisibleParent(marker); |
||||
|
||||
expect(vp).to.be(null); |
||||
}); |
||||
}); |
@ -0,0 +1,77 @@
|
||||
describe('moving markers', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var div, map, group, clock; |
||||
|
||||
beforeEach(function () { |
||||
clock = sinon.useFakeTimers(); |
||||
|
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
if (group instanceof L.MarkerClusterGroup) { |
||||
group.clearLayers(); |
||||
map.removeLayer(group); |
||||
} |
||||
|
||||
map.remove(); |
||||
div.remove(); |
||||
clock.restore(); |
||||
|
||||
div = map = group = clock; |
||||
}); |
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('moves a marker that was moved while off the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([10, 10]); |
||||
map.addLayer(group); |
||||
group.addLayer(marker); |
||||
|
||||
map.removeLayer(group); |
||||
marker.setLatLng([1.5, 1.5]); |
||||
map.addLayer(group); |
||||
|
||||
expect(group.getLayers().length).to.be(1); |
||||
}); |
||||
|
||||
it('moves multiple markers that were moved while off the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
map.addLayer(group); |
||||
|
||||
var markers = []; |
||||
for (var i = 0; i < 10; i++) { |
||||
var marker = new L.Marker([10, 10]); |
||||
group.addLayer(marker); |
||||
markers.push(marker); |
||||
} |
||||
|
||||
map.removeLayer(group); |
||||
for (var i = 0; i < 10; i++) { |
||||
var marker = markers[i]; |
||||
marker.setLatLng([1.5, 1.5]); |
||||
} |
||||
map.addLayer(group); |
||||
|
||||
expect(group.getLayers().length).to.be(10); |
||||
}); |
||||
}); |
@ -0,0 +1,52 @@
|
||||
describe('non-integer min/max zoom', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var map, div, clock; |
||||
|
||||
beforeEach(function () { |
||||
clock = sinon.useFakeTimers(); |
||||
|
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { minZoom: 0.5, maxZoom: 18.5, trackResize: false }); |
||||
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
map.remove(); |
||||
document.body.removeChild(div); |
||||
clock.restore(); |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('dont break adding and removing markers', function () { |
||||
var group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
var marker3 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
map.addLayer(group); |
||||
|
||||
group.addLayer(marker3); |
||||
|
||||
expect(marker._icon).to.be(undefined); |
||||
expect(marker2._icon).to.be(undefined); |
||||
expect(marker3._icon).to.be(undefined); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1); |
||||
|
||||
group.removeLayer(marker2); |
||||
}); |
||||
}); |
@ -0,0 +1,65 @@
|
||||
describe('onAdd', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var map, div; |
||||
|
||||
beforeEach(function () { |
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { trackResize: false }); |
||||
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
map.remove(); |
||||
document.body.removeChild(div); |
||||
|
||||
map = div = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('throws an error if maxZoom is not specified', function () { |
||||
|
||||
var group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayer(marker); |
||||
|
||||
var ex = null; |
||||
try { |
||||
map.addLayer(group); |
||||
} catch (e) { |
||||
ex = e; |
||||
} |
||||
|
||||
expect(ex).to.not.be(null); |
||||
}); |
||||
|
||||
it('successfully handles removing and re-adding a layer while not on the map', function () { |
||||
map.options.maxZoom = 18; |
||||
var group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(marker); |
||||
|
||||
map.removeLayer(group); |
||||
group.removeLayer(marker); |
||||
group.addLayer(marker); |
||||
|
||||
map.addLayer(group); |
||||
|
||||
expect(map.hasLayer(group)).to.be(true); |
||||
expect(group.hasLayer(marker)).to.be(true); |
||||
}); |
||||
}); |
@ -0,0 +1,52 @@
|
||||
describe('onRemove', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var map, div; |
||||
|
||||
beforeEach(function () { |
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
map.remove(); |
||||
document.body.removeChild(div); |
||||
|
||||
map = div = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('removes the shown coverage polygon', function () { |
||||
|
||||
var group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
var marker3 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
group.addLayer(marker3); |
||||
|
||||
map.addLayer(group); |
||||
|
||||
group._showCoverage({ layer: group._topClusterLevel }); |
||||
|
||||
expect(group._shownPolygon).to.not.be(null); |
||||
|
||||
map.removeLayer(group); |
||||
|
||||
expect(group._shownPolygon).to.be(null); |
||||
}); |
||||
}); |
@ -0,0 +1,195 @@
|
||||
describe('removeLayers', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var div, map, group, clock; |
||||
|
||||
beforeEach(function () { |
||||
clock = sinon.useFakeTimers(); |
||||
|
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
if (group instanceof L.MarkerClusterGroup) { |
||||
group.clearLayers(); |
||||
map.removeLayer(group); |
||||
} |
||||
|
||||
map.remove(); |
||||
div.remove(); |
||||
clock.restore(); |
||||
|
||||
div = map = group = clock = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('removes all the layer given to it', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var markers = [ |
||||
new L.Marker([1.5, 1.5]), |
||||
new L.Marker([1.5, 1.5]), |
||||
new L.Marker([1.5, 1.5]) |
||||
]; |
||||
|
||||
map.addLayer(group); |
||||
|
||||
group.addLayers(markers); |
||||
|
||||
group.removeLayers(markers); |
||||
|
||||
expect(group.hasLayer(markers[0])).to.be(false); |
||||
expect(group.hasLayer(markers[1])).to.be(false); |
||||
expect(group.hasLayer(markers[2])).to.be(false); |
||||
|
||||
expect(group.getLayers().length).to.be(0); |
||||
}); |
||||
|
||||
it('removes all the layer given to it even though they move', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var markers = [ |
||||
new L.Marker([10, 10]), |
||||
new L.Marker([20, 20]), |
||||
new L.Marker([30, 30]) |
||||
]; |
||||
var len = markers.length; |
||||
map.addLayer(group); |
||||
|
||||
group.addLayers(markers); |
||||
|
||||
markers.forEach(function (marker) { |
||||
marker.setLatLng([1.5, 1.5]); |
||||
group.removeLayer(marker); |
||||
expect(group.getLayers().length).to.be(len - 1); |
||||
group.addLayer(marker); |
||||
expect(group.getLayers().length).to.be(len); |
||||
}); |
||||
|
||||
expect(group.getLayers().length).to.be(len); |
||||
}); |
||||
|
||||
it('removes all the layer given to it even if the group is not on the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var markers = [ |
||||
new L.Marker([1.5, 1.5]), |
||||
new L.Marker([1.5, 1.5]), |
||||
new L.Marker([1.5, 1.5]) |
||||
]; |
||||
|
||||
map.addLayer(group); |
||||
group.addLayers(markers); |
||||
map.removeLayer(group); |
||||
group.removeLayers(markers); |
||||
map.addLayer(group); |
||||
|
||||
expect(group.hasLayer(markers[0])).to.be(false); |
||||
expect(group.hasLayer(markers[1])).to.be(false); |
||||
expect(group.hasLayer(markers[2])).to.be(false); |
||||
|
||||
expect(group.getLayers().length).to.be(0); |
||||
}); |
||||
|
||||
it('doesnt break if we are spiderfied', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var markers = [ |
||||
new L.Marker([1.5, 1.5]), |
||||
new L.Marker([1.5, 1.5]), |
||||
new L.Marker([1.5, 1.5]) |
||||
]; |
||||
|
||||
map.addLayer(group); |
||||
|
||||
group.addLayers(markers); |
||||
|
||||
markers[0].__parent.spiderfy(); |
||||
|
||||
// We must wait for the spiderfy animation to timeout
|
||||
clock.tick(200); |
||||
|
||||
group.removeLayers(markers); |
||||
|
||||
expect(group.hasLayer(markers[0])).to.be(false); |
||||
expect(group.hasLayer(markers[1])).to.be(false); |
||||
expect(group.hasLayer(markers[2])).to.be(false); |
||||
|
||||
expect(group.getLayers().length).to.be(0); |
||||
|
||||
group.on('spiderfied', function() { |
||||
expect(group._spiderfied).to.be(null); |
||||
}); |
||||
}); |
||||
|
||||
it('handles nested Layer Groups', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker1 = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
var marker3 = new L.Marker([1.5, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
|
||||
group.addLayers([marker1, marker2, marker3]); |
||||
|
||||
expect(group.hasLayer(marker1)).to.be(true); |
||||
expect(group.hasLayer(marker2)).to.be(true); |
||||
expect(group.hasLayer(marker3)).to.be(true); |
||||
|
||||
group.removeLayers([ |
||||
marker1, |
||||
new L.LayerGroup([ |
||||
marker2, new L.LayerGroup([ |
||||
marker3 |
||||
]) |
||||
]) |
||||
]); |
||||
|
||||
expect(group.hasLayer(marker1)).to.be(false); |
||||
expect(group.hasLayer(marker2)).to.be(false); |
||||
expect(group.hasLayer(marker3)).to.be(false); |
||||
|
||||
expect(group.getLayers().length).to.be(0); |
||||
}); |
||||
|
||||
it('chunked loading zoom out', function () { |
||||
//See #743 for more details
|
||||
var markers = []; |
||||
|
||||
group = new L.MarkerClusterGroup({ |
||||
chunkedLoading: true, chunkProgress: function () { |
||||
//Before this provoked an "undefined" exception
|
||||
map.zoomOut(); |
||||
group.removeLayers(markers); |
||||
} |
||||
}); |
||||
|
||||
for (var i = 1; i < 1000; i++) { |
||||
markers.push(new L.Marker([1.0 + (.0001 * i), 1.0 + (.0001 * i)])); |
||||
} |
||||
|
||||
map.addLayer(group); |
||||
|
||||
group.addLayers(markers); |
||||
}); |
||||
}); |
@ -0,0 +1,248 @@
|
||||
describe('Option removeOutsideVisibleBounds', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var marker1, marker2, marker3, marker4, marker5, markers, div, map, group, clock, realBrowser; |
||||
|
||||
beforeEach(function () { |
||||
realBrowser = L.Browser; |
||||
clock = sinon.useFakeTimers(); |
||||
|
||||
marker1 = L.marker([1.5, -0.4]); // 2 screens width away.
|
||||
marker2 = L.marker([1.5, 0.6]); // 1 screen width away.
|
||||
marker3 = L.marker([1.5, 1.5]); // In view port.
|
||||
marker4 = L.marker([1.5, 2.4]); // 1 screen width away.
|
||||
marker5 = L.marker([1.5, 3.4]); // 2 screens width away.
|
||||
markers = [marker1, marker2, marker3, marker4, marker5]; |
||||
|
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
|
||||
// Add all markers once to map then remove them immediately so that their icon is null (instead of undefined).
|
||||
for (i = 0; i < markers.length; i++) { |
||||
map.removeLayer(markers[i].addTo(map)); |
||||
} |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
if (group instanceof L.MarkerClusterGroup) { |
||||
//group.removeLayers(group.getLayers());
|
||||
group.clearLayers(); |
||||
map.removeLayer(group); |
||||
} |
||||
|
||||
map.remove(); |
||||
div.remove(); |
||||
clock.restore(); |
||||
|
||||
marker1 = marker2 = marker3 = marker4 = marker5 = markers = div = map = group = clock = null; |
||||
}); |
||||
|
||||
function prepareGroup() { |
||||
// "group" should be assigned with a Marker Cluster Group before calling this function.
|
||||
group.addTo(map); |
||||
|
||||
group.addLayers(markers); |
||||
} |
||||
|
||||
function setBrowserToMobile() { |
||||
var fakeBrowser = {}; |
||||
for (k in realBrowser) { |
||||
fakeBrowser[k] = realBrowser[k]; |
||||
} |
||||
fakeBrowser.mobile = true; |
||||
L.Browser = fakeBrowser; |
||||
} |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('removes objects more than 1 screen away from view port by default', function () { |
||||
|
||||
group = L.markerClusterGroup(); |
||||
|
||||
prepareGroup(); |
||||
|
||||
expect(marker1._icon).to.be(null); |
||||
expect(map._panes.markerPane.childNodes.length).to.be(3); // markers 2, 3 and 4.
|
||||
expect(marker5._icon).to.be(null); |
||||
|
||||
}); |
||||
|
||||
it('removes objects out of view port by default for mobile device', function () { |
||||
setBrowserToMobile(); |
||||
try { |
||||
group = L.markerClusterGroup(); |
||||
|
||||
prepareGroup(); |
||||
|
||||
expect(marker1._icon).to.be(null); |
||||
expect(marker2._icon).to.be(null); |
||||
expect(map._panes.markerPane.childNodes.length).to.be(1); // marker 3 only.
|
||||
expect(marker4._icon).to.be(null); |
||||
expect(marker5._icon).to.be(null); |
||||
} |
||||
finally { |
||||
L.Browser = realBrowser; |
||||
} |
||||
}); |
||||
|
||||
it('leaves all objects on map when set to false', function () { |
||||
|
||||
group = L.markerClusterGroup({ |
||||
removeOutsideVisibleBounds: false |
||||
}); |
||||
|
||||
prepareGroup(); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(5); // All 5 markers.
|
||||
|
||||
}); |
||||
|
||||
|
||||
// Following tests need markers at very high latitude.
|
||||
// They test the _checkBoundsMaxLat method against the default Web/Spherical Mercator projection maximum latitude (85.0511287798).
|
||||
// The actual map view should be '-1.0986328125,84.92929204957956,1.0986328125,85.11983467698401'
|
||||
// The expanded bounds without correction should be '-3.2958984375,84.7387494221751,3.2958984375,85.31037730438847'
|
||||
var latLngsMaxLatDefault = [ |
||||
[100, 3], // Impossible in real world, but nothing prevents the user from entering such latitude, and Web/Spherical Mercator projection will still display it at 85.0511287798
|
||||
[85.2, 1.5], // 1 "screen" heights away.
|
||||
[85, 0], // In center of view.
|
||||
[84.8, -1.5], // 1 "screen" height away.
|
||||
[84.6, -3] // 2 "screens" height away.
|
||||
]; |
||||
|
||||
function moveMarkersAndMapToMaxLat(latLngs, isSouth) { |
||||
for (i = 0; i < markers.length; i++) { |
||||
if (isSouth) { |
||||
markers[i].setLatLng([-latLngs[i][0], latLngs[i][1]]); |
||||
} else { |
||||
markers[i].setLatLng(latLngs[i]); |
||||
} |
||||
} |
||||
|
||||
map.fitBounds([ |
||||
[isSouth ? -86 : 85, -1], |
||||
[isSouth ? -85 : 86, 1] // The actual map view longitude span will be wider. '-1.0986328125,84.92929204957956,1.0986328125,85.11983467698401'
|
||||
]); |
||||
} |
||||
|
||||
function checkProjection(latLngs) { |
||||
expect(map.options.crs).to.equal(L.CRS.EPSG3857); |
||||
expect(L.CRS.EPSG3857.projection).to.equal(L.Projection.SphericalMercator); |
||||
expect(L.Projection.SphericalMercator.MAX_LATITUDE).to.be.a('number'); |
||||
|
||||
var mapZoom = map.getZoom(); |
||||
|
||||
for (i = 0; i < markers.length; i++) { |
||||
try { |
||||
expect(markers[i].__parent._zoom).to.be.below(mapZoom); |
||||
} catch (e) { |
||||
console.log("Failed marker: " + (i + 1)); |
||||
throw e; |
||||
} |
||||
} |
||||
} |
||||
|
||||
it('includes objects above the Web Mercator projection maximum limit by default', function () { |
||||
|
||||
moveMarkersAndMapToMaxLat(latLngsMaxLatDefault); |
||||
|
||||
group = L.markerClusterGroup(); |
||||
|
||||
prepareGroup(); |
||||
|
||||
checkProjection(latLngsMaxLatDefault); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(4); // Markers 1, 2, 3 and 4.
|
||||
expect(marker5._icon).to.be(null); |
||||
|
||||
}); |
||||
|
||||
it('includes objects below the Web Mercator projection minimum limit by default', function () { |
||||
|
||||
moveMarkersAndMapToMaxLat(latLngsMaxLatDefault, true); |
||||
|
||||
// Make sure we are really in Southern hemisphere.
|
||||
expect(map.getBounds().getNorth()).to.be.below(-80); |
||||
|
||||
group = L.markerClusterGroup(); |
||||
|
||||
prepareGroup(); |
||||
|
||||
checkProjection(latLngsMaxLatDefault); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(4); // Markers 1, 2, 3 and 4.
|
||||
expect(marker5._icon).to.be(null); |
||||
|
||||
}); |
||||
|
||||
|
||||
// The actual map view should be '-1.0986328125,84.92929204957956,1.0986328125,85.11983467698401'
|
||||
var latLngsMaxLatMobile = [ |
||||
[100, 1], // Impossible in real world, but nothing prevents the user from entering such latitude, and Web/Spherical Mercator projection will still display it at 85.0511287798
|
||||
[85.2, 0.5], // 1 "screen" heights away, but should be included by the correction.
|
||||
[85, 0], // In center of view.
|
||||
[84.9, -1], // 1 "screen" height away.
|
||||
[84.8, -1.5] // 2 "screens" height away.
|
||||
]; |
||||
|
||||
it('includes objects above the Web Mercator projection maximum limit for mobile device', function () { |
||||
setBrowserToMobile(); |
||||
try { |
||||
moveMarkersAndMapToMaxLat(latLngsMaxLatMobile); |
||||
|
||||
group = L.markerClusterGroup({ |
||||
maxClusterRadius: 10 |
||||
}); |
||||
|
||||
prepareGroup(); |
||||
|
||||
checkProjection(latLngsMaxLatMobile); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(3); // Markers 1, 2 and 3.
|
||||
expect(marker4._icon).to.be(null); |
||||
expect(marker5._icon).to.be(null); |
||||
} |
||||
finally { |
||||
L.Browser = realBrowser; |
||||
} |
||||
}); |
||||
|
||||
it('includes objects below the Web Mercator projection minimum limit for mobile device', function () { |
||||
setBrowserToMobile(); |
||||
try { |
||||
moveMarkersAndMapToMaxLat(latLngsMaxLatMobile, true); |
||||
|
||||
// Make sure we are really in Southern hemisphere.
|
||||
expect(map.getBounds().getNorth()).to.be.below(-80); |
||||
|
||||
group = L.markerClusterGroup({ |
||||
maxClusterRadius: 10 |
||||
}); |
||||
|
||||
prepareGroup(); |
||||
|
||||
checkProjection(latLngsMaxLatMobile); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(3); // Markers 1, 2 and 3.
|
||||
expect(marker4._icon).to.be(null); |
||||
expect(marker5._icon).to.be(null); |
||||
} |
||||
finally { |
||||
L.Browser = realBrowser; |
||||
} |
||||
}); |
||||
}); |
@ -0,0 +1,74 @@
|
||||
describe('singleMarkerMode option', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var div, map, group, defaultIcon, clusterIcon, marker; |
||||
|
||||
beforeEach(function () { |
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
|
||||
defaultIcon = new L.Icon.Default(); |
||||
clusterIcon = new L.Icon.Default(); |
||||
marker = L.marker([1.5, 1.5]); |
||||
marker.setIcon(defaultIcon); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
if (group instanceof L.MarkerClusterGroup) { |
||||
group.removeLayers(group.getLayers()); |
||||
map.removeLayer(group); |
||||
} |
||||
|
||||
map.remove(); |
||||
div.remove(); |
||||
|
||||
div = map = group = defaultIcon = clusterIcon = marker = null
|
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('overrides marker icons when set to true', function () { |
||||
|
||||
group = L.markerClusterGroup({ |
||||
singleMarkerMode: true, |
||||
iconCreateFunction: function (layer) { |
||||
return clusterIcon; |
||||
} |
||||
}).addTo(map); |
||||
|
||||
expect(marker.options.icon).to.equal(defaultIcon); |
||||
|
||||
marker.addTo(group); |
||||
|
||||
expect(marker.options.icon).to.equal(clusterIcon); |
||||
|
||||
}); |
||||
|
||||
it('does not modify marker icons by default (or set to false)', function () { |
||||
|
||||
group = L.markerClusterGroup({ |
||||
iconCreateFunction: function (layer) { |
||||
return clusterIcon; |
||||
} |
||||
}).addTo(map); |
||||
|
||||
expect(marker.options.icon).to.equal(defaultIcon); |
||||
|
||||
marker.addTo(group); |
||||
|
||||
expect(marker.options.icon).to.equal(defaultIcon); |
||||
|
||||
}); |
||||
}); |
@ -0,0 +1,344 @@
|
||||
describe('spiderfy', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var div, map, group, clock; |
||||
|
||||
beforeEach(function () { |
||||
clock = sinon.useFakeTimers(); |
||||
|
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
if (group instanceof L.MarkerClusterGroup) { |
||||
group.removeLayers(group.getLayers()); |
||||
map.removeLayer(group); |
||||
} |
||||
|
||||
map.remove(); |
||||
div.remove(); |
||||
clock.restore(); |
||||
|
||||
div = map = group = clock = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('Spiderfies 2 Markers', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
map.addLayer(group); |
||||
|
||||
marker.__parent.spiderfy(); |
||||
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane); |
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane); |
||||
}); |
||||
|
||||
it('Spiderfies 2 CircleMarkers', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.CircleMarker([1.5, 1.5]); |
||||
var marker2 = new L.CircleMarker([1.5, 1.5]); |
||||
|
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
map.addLayer(group); |
||||
|
||||
marker.__parent.spiderfy(); |
||||
|
||||
// Leaflet 1.0.0 now uses an intermediate L.Renderer.
|
||||
// marker > _path > _rootGroup (g) > _container (svg) > pane (div)
|
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane')); |
||||
expect(marker2._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane')); |
||||
}); |
||||
|
||||
it('Spiderfies 2 Circles', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Circle([1.5, 1.5], 10); |
||||
var marker2 = new L.Circle([1.5, 1.5], 10); |
||||
|
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
map.addLayer(group); |
||||
|
||||
marker.__parent.spiderfy(); |
||||
|
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane')); |
||||
expect(marker2._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane')); |
||||
}); |
||||
|
||||
it('Spiderfies at current zoom if all child markers are at the exact same position', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
// Get the appropriate cluster.
|
||||
var cluster = marker.__parent, |
||||
zoom = map.getZoom(); |
||||
|
||||
while (cluster._zoom !== zoom) { |
||||
cluster = cluster.__parent; |
||||
} |
||||
|
||||
expect(zoom).to.be.lessThan(10); |
||||
|
||||
cluster.fireEvent('click', null, true); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
expect(map.getZoom()).to.equal(zoom); |
||||
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane); |
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane); |
||||
|
||||
}); |
||||
|
||||
it('Spiderfies at current zoom if all child markers are still within a single cluster at map maxZoom', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.50001]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
expect(marker.__parent._zoom).to.equal(18); |
||||
|
||||
// Get the appropriate cluster.
|
||||
var cluster = marker.__parent, |
||||
zoom = map.getZoom(); |
||||
|
||||
while (cluster._zoom !== zoom) { |
||||
cluster = cluster.__parent; |
||||
} |
||||
|
||||
expect(zoom).to.be.lessThan(10); |
||||
|
||||
cluster.fireEvent('click', null, true); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
expect(map.getZoom()).to.equal(zoom); |
||||
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane); |
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane); |
||||
|
||||
}); |
||||
|
||||
it('removes all markers and spider legs when group is removed from map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
marker.__parent.spiderfy(); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(3); // The 2 markers + semi-transparent cluster.
|
||||
expect(map.getPane('overlayPane').firstChild.firstChild.childNodes.length).to.be(2); // The 2 spider legs.
|
||||
|
||||
}); |
||||
|
||||
it('adds then removes class "leaflet-cluster-anim" from mapPane on spiderfy', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
marker.__parent.spiderfy(); |
||||
|
||||
expect(map._panes.mapPane.className).to.contain('leaflet-cluster-anim'); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
expect(map._panes.mapPane.className).to.not.contain('leaflet-cluster-anim'); |
||||
|
||||
}); |
||||
|
||||
it('adds then removes class "leaflet-cluster-anim" from mapPane on unspiderfy', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
marker.__parent.spiderfy(); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
marker.__parent.unspiderfy(); |
||||
|
||||
expect(map._panes.mapPane.className).to.contain('leaflet-cluster-anim'); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
expect(map._panes.mapPane.className).to.not.contain('leaflet-cluster-anim'); |
||||
|
||||
}); |
||||
|
||||
it('fires unspiderfied event on unspiderfy', function (done) { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
marker.__parent.spiderfy(); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
// Add event listener
|
||||
group.on('unspiderfied', function (event) { |
||||
expect(event.target).to.be(group); |
||||
expect(event.cluster).to.be.a(L.Marker); |
||||
expect(event.markers[1]).to.be(marker); |
||||
expect(event.markers[0]).to.be(marker2); |
||||
|
||||
done(); |
||||
}); |
||||
|
||||
marker.__parent.unspiderfy(); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
}); |
||||
|
||||
it('does not leave class "leaflet-cluster-anim" on mapPane when group is removed while spiderfied', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
marker.__parent.spiderfy(); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
map.removeLayer(group); |
||||
|
||||
expect(map._panes.mapPane.className).to.not.contain('leaflet-cluster-anim'); |
||||
|
||||
}); |
||||
|
||||
describe('zoomend event listener', function () { |
||||
|
||||
it('unspiderfies correctly', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Circle([1.5, 1.5], 10); |
||||
var marker2 = new L.Circle([1.5, 1.5], 10); |
||||
|
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
map.addLayer(group); |
||||
|
||||
marker.__parent.spiderfy(); |
||||
|
||||
expect(group._spiderfied).to.not.be(null); |
||||
|
||||
map.fire('zoomend'); |
||||
|
||||
//We should unspiderfy with no animation, so this should be null
|
||||
expect(group._spiderfied).to.be(null); |
||||
}); |
||||
|
||||
}); |
||||
|
||||
describe('spiderfied event listener', function () { |
||||
it('Spiderfies 2 Markers', function (done) { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
map.addLayer(group); |
||||
|
||||
// Add event listener
|
||||
group.on('spiderfied', function (event) { |
||||
expect(event.target).to.be(group); |
||||
expect(event.cluster).to.be.a(L.Marker); |
||||
expect(event.markers[1]).to.be(marker); |
||||
expect(event.markers[0]).to.be(marker2); |
||||
|
||||
done(); |
||||
}); |
||||
|
||||
marker.__parent.spiderfy(); |
||||
|
||||
clock.tick(200); |
||||
}); |
||||
|
||||
it('Spiderfies 2 Circles', function (done) { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Circle([1.5, 1.5], 10); |
||||
var marker2 = new L.Circle([1.5, 1.5], 10); |
||||
|
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
map.addLayer(group); |
||||
|
||||
// Add event listener
|
||||
group.on('spiderfied', function (event) { |
||||
expect(event.target).to.be(group); |
||||
expect(event.cluster).to.be.a(L.Marker); |
||||
expect(event.markers[1]).to.be(marker); |
||||
expect(event.markers[0]).to.be(marker2); |
||||
|
||||
done(); |
||||
}); |
||||
|
||||
marker.__parent.spiderfy(); |
||||
|
||||
clock.tick(200); |
||||
}); |
||||
}); |
||||
}); |
@ -0,0 +1,89 @@
|
||||
describe('things behave correctly with negative minZoom', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var div, map, group; |
||||
|
||||
beforeEach(function () { |
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { minZoom: -3, maxZoom: 18, trackResize: false }); |
||||
|
||||
map.setView(L.latLng(0, 0), -3); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
if (group instanceof L.MarkerClusterGroup) { |
||||
group.clearLayers(); |
||||
map.removeLayer(group); |
||||
} |
||||
|
||||
map.remove(); |
||||
div.remove(); |
||||
|
||||
div = map = group = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('shows a single marker added to the group before the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayer(marker); |
||||
map.addLayer(group); |
||||
|
||||
expect(marker._icon).to.not.be(undefined); |
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane); |
||||
}); |
||||
|
||||
it('shows a single marker added to the group after the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(marker); |
||||
|
||||
expect(marker._icon).to.not.be(undefined); |
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane); |
||||
}); |
||||
|
||||
it('creates a cluster when 2 overlapping markers are added before the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
map.addLayer(group); |
||||
|
||||
expect(marker._icon).to.be(undefined); |
||||
expect(marker2._icon).to.be(undefined); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1); |
||||
}); |
||||
it('creates a cluster when 2 overlapping markers are added after the group is added to the map', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
map.addLayer(group); |
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
|
||||
expect(marker._icon).to.be(null); //Null as was added and then removed
|
||||
expect(marker2._icon).to.be(undefined); |
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1); |
||||
}); |
||||
}); |
@ -0,0 +1,139 @@
|
||||
describe('unspiderfy', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var div, map, group, clock; |
||||
|
||||
beforeEach(function () { |
||||
clock = sinon.useFakeTimers(); |
||||
|
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
if (group instanceof L.MarkerClusterGroup) { |
||||
group.removeLayers(group.getLayers()); |
||||
map.removeLayer(group); |
||||
} |
||||
map.remove(); |
||||
div.remove(); |
||||
|
||||
clock.restore(); |
||||
|
||||
div = map = group = clock = null; |
||||
}); |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('Unspiderfies 2 Markers', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
map.addLayer(group); |
||||
|
||||
marker.__parent.spiderfy(); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
group.unspiderfy(); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
expect(map.hasLayer(marker)).to.be(false); |
||||
expect(map.hasLayer(marker2)).to.be(false); |
||||
}); |
||||
|
||||
it('Unspiderfies 2 CircleMarkers', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.CircleMarker([1.5, 1.5]); |
||||
var marker2 = new L.CircleMarker([1.5, 1.5]); |
||||
|
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
map.addLayer(group); |
||||
|
||||
marker.__parent.spiderfy(); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
group.unspiderfy(); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
expect(map.hasLayer(marker)).to.be(false); |
||||
expect(map.hasLayer(marker2)).to.be(false); |
||||
}); |
||||
|
||||
it('Unspiderfies 2 Circles', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Circle([1.5, 1.5], 10); |
||||
var marker2 = new L.Circle([1.5, 1.5], 10); |
||||
|
||||
group.addLayer(marker); |
||||
group.addLayer(marker2); |
||||
map.addLayer(group); |
||||
|
||||
marker.__parent.spiderfy(); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
group.unspiderfy(); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
expect(map.hasLayer(marker)).to.be(false); |
||||
expect(map.hasLayer(marker2)).to.be(false); |
||||
}); |
||||
|
||||
it('fires unspiderfied event on unspiderfy', function (done) { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([1.5, 1.5]); |
||||
var marker2 = new L.Marker([1.5, 1.5]); |
||||
|
||||
group.addLayers([marker, marker2]); |
||||
map.addLayer(group); |
||||
|
||||
marker.__parent.spiderfy(); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
// Add event listener
|
||||
group.on('unspiderfied', function (event) { |
||||
expect(event.target).to.be(group); |
||||
expect(event.cluster).to.be.a(L.Marker); |
||||
expect(event.markers[1]).to.be(marker); |
||||
expect(event.markers[0]).to.be(marker2); |
||||
|
||||
done(); |
||||
}); |
||||
|
||||
group.unspiderfy(); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
}); |
||||
|
||||
}); |
@ -0,0 +1,382 @@
|
||||
describe('zoomAnimation', function () { |
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
var div, map, group, clock, realBrowser; |
||||
|
||||
beforeEach(function () { |
||||
realBrowser = L.Browser; |
||||
clock = sinon.useFakeTimers(); |
||||
|
||||
div = document.createElement('div'); |
||||
div.style.width = '200px'; |
||||
div.style.height = '200px'; |
||||
document.body.appendChild(div); |
||||
|
||||
map = L.map(div, { maxZoom: 18, trackResize: false }); |
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
if (group instanceof L.MarkerClusterGroup) { |
||||
group.clearLayers(); |
||||
map.removeLayer(group); |
||||
} |
||||
|
||||
map.remove(); |
||||
document.body.removeChild(div); |
||||
clock.restore(); |
||||
|
||||
div = map = group = clock = null; |
||||
}); |
||||
|
||||
function setBrowserToMobile() { |
||||
var fakeBrowser = {}; |
||||
for (k in realBrowser) { |
||||
fakeBrowser[k] = realBrowser[k]; |
||||
} |
||||
fakeBrowser.mobile = true; |
||||
L.Browser = fakeBrowser; |
||||
} |
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
it('adds the visible marker to the map when zooming in', function () { |
||||
map.setView(new L.LatLng(-37.36142550190516, 174.254150390625), 7); |
||||
|
||||
group = new L.MarkerClusterGroup({ |
||||
showCoverageOnHover: true, |
||||
maxClusterRadius: 20, |
||||
disableClusteringAtZoom: 15 |
||||
}); |
||||
var marker = new L.Marker([-37.77852090603777, 175.3103667497635]); |
||||
group.addLayer(marker); //The one we zoom in on
|
||||
group.addLayer(new L.Marker([-37.711800591811055, 174.50034790039062])); //Marker that we cluster with at the top zoom level, but not 1 level down
|
||||
map.addLayer(group); |
||||
|
||||
clock.tick(1000); |
||||
map.setView([-37.77852090603777, 175.3103667497635], 15); |
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000); |
||||
|
||||
expect(marker._icon).to.not.be(undefined); |
||||
expect(marker._icon).to.not.be(null); |
||||
}); |
||||
|
||||
it('adds the visible marker to the map when jumping around', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
var marker1 = new L.Marker([48.858280181884766, 2.2945759296417236]); |
||||
var marker2 = new L.Marker([16.02359962463379, -61.70280075073242]); |
||||
group.addLayer(marker1); //The one we zoom in on first
|
||||
group.addLayer(marker2); //Marker that we cluster with at the top zoom level, but not 1 level down
|
||||
map.addLayer(group); |
||||
|
||||
//show the first
|
||||
map.fitBounds(new L.LatLngBounds(new L.LatLng(41.371582, -5.142222), new L.LatLng(51.092804, 9.561556))); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
map.fitBounds(new L.LatLngBounds(new L.LatLng(15.830972671508789, -61.807167053222656), new L.LatLng(16.516849517822266, -61.0))); |
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000); |
||||
|
||||
//Now the second one should be visible on the map
|
||||
expect(marker2._icon).to.not.be(undefined); |
||||
expect(marker2._icon).to.not.be(null); |
||||
}); |
||||
|
||||
it('adds the visible markers to the map, but not parent clusters when jumping around', function () { |
||||
|
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker1 = new L.Marker([59.9520, 30.3307]), |
||||
marker2 = new L.Marker([59.9516, 30.3308]), |
||||
marker3 = new L.Marker([59.9513, 30.3312]); |
||||
|
||||
group.addLayer(marker1); |
||||
group.addLayer(marker2); |
||||
group.addLayer(marker3); |
||||
map.addLayer(group); |
||||
|
||||
//Show none of them
|
||||
map.setView([53.0676, 170.6835], 16); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
//Zoom so that all the markers will be visible (Same as zoomToShowLayer)
|
||||
map.setView(marker1.getLatLng(), 18); |
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000); |
||||
|
||||
//Now the markers should all be visible, and there should be no visible clusters
|
||||
expect(marker1._icon.parentNode).to.be(map._panes.markerPane); |
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane); |
||||
expect(marker3._icon.parentNode).to.be(map._panes.markerPane); |
||||
expect(map._panes.markerPane.childNodes.length).to.be(3); |
||||
}); |
||||
|
||||
it('removes clicked clusters on the edge of a mobile screen', function () { |
||||
setBrowserToMobile(); |
||||
|
||||
try { |
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([ |
||||
[1, 1], |
||||
[2, 2] |
||||
])); |
||||
|
||||
group = new L.MarkerClusterGroup({ |
||||
maxClusterRadius: 80 |
||||
}).addTo(map); |
||||
|
||||
// Add a marker 1 pixel below the initial screen bottom edge.
|
||||
var bottomPoint = map.getPixelBounds().max.add([0, 1]), |
||||
bottomLatLng = map.unproject(bottomPoint), |
||||
centerLng = map.getCenter().lng, |
||||
bottomPosition = new L.LatLng( |
||||
bottomLatLng.lat, |
||||
centerLng |
||||
), |
||||
bottomMarker = new L.Marker(bottomPosition).addTo(group), |
||||
initialZoom = map.getZoom(); |
||||
|
||||
expect(bottomMarker._icon).to.be(undefined); |
||||
|
||||
// Add many markers 79 pixels above the first one, so they cluster with it.
|
||||
var newPoint = bottomPoint.add([0, -79]), |
||||
newLatLng = L.latLng( |
||||
map.unproject(newPoint).lat, |
||||
centerLng |
||||
); |
||||
|
||||
for (var i = 0; i < 10; i += 1) { |
||||
group.addLayer(new L.Marker(newLatLng)); |
||||
} |
||||
|
||||
var parentCluster = bottomMarker.__parent; |
||||
|
||||
expect(parentCluster._icon.parentNode).to.be(map._panes.markerPane); |
||||
|
||||
parentCluster.fireEvent('click', null, true); |
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000); |
||||
|
||||
expect(map.getZoom()).to.equal(initialZoom + 1); // The fitBounds with 200px height should result in zooming 1 level in.
|
||||
|
||||
// Finally make sure that the cluster has been removed from map.
|
||||
expect(parentCluster._icon).to.be(null); |
||||
expect(map._panes.markerPane.childNodes.length).to.be(2); // The bottomMarker + cluster for the 10 above markers.
|
||||
} |
||||
finally { |
||||
L.Browser = realBrowser; |
||||
} |
||||
}); |
||||
|
||||
describe('zoomToShowLayer', function () { |
||||
|
||||
it('zoom to single marker inside map view', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([59.9520, 30.3307]); |
||||
|
||||
group.addLayer(marker); |
||||
map.addLayer(group); |
||||
|
||||
var zoomCallbackSpy = sinon.spy(); |
||||
|
||||
map.setView(marker.getLatLng(), 10); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
var initialCenter = map.getCenter(); |
||||
var initialZoom = map.getZoom(); |
||||
|
||||
group.zoomToShowLayer(marker, zoomCallbackSpy); |
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000); |
||||
|
||||
//Marker should be visible, map center and zoom level should stay the same, callback called once
|
||||
expect(marker._icon).to.not.be(undefined); |
||||
expect(marker._icon).to.not.be(null); |
||||
expect(map.getBounds().contains(marker.getLatLng())).to.be.true; |
||||
expect(map.getCenter()).to.eql(initialCenter); |
||||
expect(map.getZoom()).to.equal(initialZoom); |
||||
sinon.assert.calledOnce(zoomCallbackSpy); |
||||
}); |
||||
|
||||
it('pan map to single marker outside map view', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker = new L.Marker([59.9520, 30.3307]); |
||||
|
||||
group.addLayer(marker); |
||||
map.addLayer(group); |
||||
|
||||
var zoomCallbackSpy = sinon.spy(); |
||||
|
||||
//Show none of them
|
||||
map.setView([53.0676, 170.6835], 16); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
var initialZoom = map.getZoom(); |
||||
|
||||
group.zoomToShowLayer(marker, zoomCallbackSpy); |
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000); |
||||
|
||||
//Marker should be visible, map center should be equal to marker center,
|
||||
//zoom level should stay the same, callback called once
|
||||
expect(marker._icon).to.not.be(undefined); |
||||
expect(marker._icon).to.not.be(null); |
||||
expect(map.getBounds().contains(marker.getLatLng())).to.be.true; |
||||
expect(map.getCenter()).to.eql(marker.getLatLng()); |
||||
expect(map.getZoom()).to.equal(initialZoom); |
||||
sinon.assert.calledOnce(zoomCallbackSpy); |
||||
}); |
||||
|
||||
it('change view and zoom to marker in cluster inside map view', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker1 = new L.Marker([59.9520, 30.3307]); |
||||
var marker2 = new L.Marker([59.9516, 30.3308]); |
||||
var marker3 = new L.Marker([59.9513, 30.3312]); |
||||
|
||||
group.addLayer(marker1); |
||||
group.addLayer(marker2); |
||||
group.addLayer(marker3); |
||||
map.addLayer(group); |
||||
|
||||
var zoomCallbackSpy = sinon.spy(); |
||||
|
||||
map.setView(marker1.getLatLng(), 16); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
group.zoomToShowLayer(marker1, zoomCallbackSpy); |
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000); |
||||
|
||||
//Now the markers should all be visible, there should be no visible clusters, and callback called once
|
||||
expect(marker1._icon.parentNode).to.be(map._panes.markerPane); |
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane); |
||||
expect(marker3._icon.parentNode).to.be(map._panes.markerPane); |
||||
expect(map._panes.markerPane.childNodes.length).to.be(3); |
||||
expect(map.getBounds().contains(marker1.getLatLng())).to.be.true; |
||||
sinon.assert.calledOnce(zoomCallbackSpy); |
||||
}); |
||||
|
||||
it('change view and zoom to marker in cluster outside map view', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker1 = new L.Marker([59.9520, 30.3307]); |
||||
var marker2 = new L.Marker([59.9516, 30.3308]); |
||||
var marker3 = new L.Marker([59.9513, 30.3312]); |
||||
|
||||
group.addLayer(marker1); |
||||
group.addLayer(marker2); |
||||
group.addLayer(marker3); |
||||
map.addLayer(group); |
||||
|
||||
var zoomCallbackSpy = sinon.spy(); |
||||
|
||||
//Show none of them
|
||||
map.setView([53.0676, 170.6835], 16); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
group.zoomToShowLayer(marker1, zoomCallbackSpy); |
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000); |
||||
|
||||
//Now the markers should all be visible, there should be no visible clusters, and callback called once
|
||||
expect(marker1._icon.parentNode).to.be(map._panes.markerPane); |
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane); |
||||
expect(marker3._icon.parentNode).to.be(map._panes.markerPane); |
||||
expect(map._panes.markerPane.childNodes.length).to.be(3); |
||||
expect(map.getBounds().contains(marker1.getLatLng())).to.be.true; |
||||
sinon.assert.calledOnce(zoomCallbackSpy); |
||||
}); |
||||
|
||||
it('spiderfy overlapping markers', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker1 = new L.Marker([59.9520, 30.3307]); |
||||
var marker2 = new L.Marker([59.9520, 30.3307]); |
||||
var marker3 = new L.Marker([59.9520, 30.3307]); |
||||
|
||||
group.addLayer(marker1); |
||||
group.addLayer(marker2); |
||||
group.addLayer(marker3); |
||||
map.addLayer(group); |
||||
|
||||
var zoomCallbackSpy = sinon.spy(); |
||||
|
||||
//Show none of them
|
||||
map.setView([53.0676, 170.6835], 16); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
group.zoomToShowLayer(marker1, zoomCallbackSpy); |
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000); |
||||
|
||||
//Now the markers should all be visible, parent cluster should be spiderfied, and callback called once
|
||||
expect(marker1._icon.parentNode).to.be(map._panes.markerPane); |
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane); |
||||
expect(marker3._icon.parentNode).to.be(map._panes.markerPane); |
||||
expect(map._panes.markerPane.childNodes.length).to.be(4);//3 markers + spiderfied parent cluster
|
||||
sinon.assert.calledOnce(zoomCallbackSpy); |
||||
}); |
||||
|
||||
it('zoom or spiderfy markers if they visible on next level of zoom', function () { |
||||
group = new L.MarkerClusterGroup(); |
||||
|
||||
var marker1 = new L.Marker([59.9520, 30.3307]); |
||||
var marker2 = new L.Marker([59.9516, 30.3308]); |
||||
var marker3 = new L.Marker([59.9513, 30.3312]); |
||||
|
||||
group.addLayer(marker1); |
||||
group.addLayer(marker2); |
||||
group.addLayer(marker3); |
||||
map.addLayer(group); |
||||
|
||||
var zoomCallbackSpy = sinon.spy(); |
||||
|
||||
//Markers will be visible on zoom 18
|
||||
map.setView([59.9520, 30.3307], 17); |
||||
|
||||
clock.tick(1000); |
||||
|
||||
group.zoomToShowLayer(marker1, zoomCallbackSpy); |
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000); |
||||
|
||||
//Now the markers should all be visible (zoomed or spiderfied), and callback called once
|
||||
expect(marker1._icon).to.not.be(undefined); |
||||
expect(marker1._icon).to.not.be(null); |
||||
expect(marker2._icon).to.not.be(undefined); |
||||
expect(marker2._icon).to.not.be(null); |
||||
expect(marker3._icon).to.not.be(undefined); |
||||
expect(marker3._icon).to.not.be(null); |
||||
sinon.assert.calledOnce(zoomCallbackSpy); |
||||
}); |
||||
}); |
||||
}); |
@ -0,0 +1,118 @@
|
||||
|
||||
L.DistanceGrid = function (cellSize) { |
||||
this._cellSize = cellSize; |
||||
this._sqCellSize = cellSize * cellSize; |
||||
this._grid = {}; |
||||
this._objectPoint = { }; |
||||
}; |
||||
|
||||
L.DistanceGrid.prototype = { |
||||
|
||||
addObject: function (obj, point) { |
||||
var x = this._getCoord(point.x), |
||||
y = this._getCoord(point.y), |
||||
grid = this._grid, |
||||
row = grid[y] = grid[y] || {}, |
||||
cell = row[x] = row[x] || [], |
||||
stamp = L.Util.stamp(obj); |
||||
|
||||
this._objectPoint[stamp] = point; |
||||
|
||||
cell.push(obj); |
||||
}, |
||||
|
||||
updateObject: function (obj, point) { |
||||
this.removeObject(obj); |
||||
this.addObject(obj, point); |
||||
}, |
||||
|
||||
//Returns true if the object was found
|
||||
removeObject: function (obj, point) { |
||||
var x = this._getCoord(point.x), |
||||
y = this._getCoord(point.y), |
||||
grid = this._grid, |
||||
row = grid[y] = grid[y] || {}, |
||||
cell = row[x] = row[x] || [], |
||||
i, len; |
||||
|
||||
delete this._objectPoint[L.Util.stamp(obj)]; |
||||
|
||||
for (i = 0, len = cell.length; i < len; i++) { |
||||
if (cell[i] === obj) { |
||||
|
||||
cell.splice(i, 1); |
||||
|
||||
if (len === 1) { |
||||
delete row[x]; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
} |
||||
|
||||
}, |
||||
|
||||
eachObject: function (fn, context) { |
||||
var i, j, k, len, row, cell, removed, |
||||
grid = this._grid; |
||||
|
||||
for (i in grid) { |
||||
row = grid[i]; |
||||
|
||||
for (j in row) { |
||||
cell = row[j]; |
||||
|
||||
for (k = 0, len = cell.length; k < len; k++) { |
||||
removed = fn.call(context, cell[k]); |
||||
if (removed) { |
||||
k--; |
||||
len--; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
|
||||
getNearObject: function (point) { |
||||
var x = this._getCoord(point.x), |
||||
y = this._getCoord(point.y), |
||||
i, j, k, row, cell, len, obj, dist, |
||||
objectPoint = this._objectPoint, |
||||
closestDistSq = this._sqCellSize, |
||||
closest = null; |
||||
|
||||
for (i = y - 1; i <= y + 1; i++) { |
||||
row = this._grid[i]; |
||||
if (row) { |
||||
|
||||
for (j = x - 1; j <= x + 1; j++) { |
||||
cell = row[j]; |
||||
if (cell) { |
||||
|
||||
for (k = 0, len = cell.length; k < len; k++) { |
||||
obj = cell[k]; |
||||
dist = this._sqDist(objectPoint[L.Util.stamp(obj)], point); |
||||
if (dist < closestDistSq || |
||||
dist <= closestDistSq && closest === null) { |
||||
closestDistSq = dist; |
||||
closest = obj; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return closest; |
||||
}, |
||||
|
||||
_getCoord: function (x) { |
||||
var coord = Math.floor(x / this._cellSize); |
||||
return isFinite(coord) ? coord : x; |
||||
}, |
||||
|
||||
_sqDist: function (p, p2) { |
||||
var dx = p2.x - p.x, |
||||
dy = p2.y - p.y; |
||||
return dx * dx + dy * dy; |
||||
} |
||||
}; |
@ -0,0 +1,165 @@
|
||||
/* Copyright (c) 2012 the authors listed at the following URL, and/or |
||||
the authors of referenced articles or incorporated external code: |
||||
http://en.literateprograms.org/Quickhull_(Javascript)?action=history&offset=20120410175256
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining |
||||
a copy of this software and associated documentation files (the |
||||
"Software"), to deal in the Software without restriction, including |
||||
without limitation the rights to use, copy, modify, merge, publish, |
||||
distribute, sublicense, and/or sell copies of the Software, and to |
||||
permit persons to whom the Software is furnished to do so, subject to |
||||
the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be |
||||
included in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
|
||||
Retrieved from: http://en.literateprograms.org/Quickhull_(Javascript)?oldid=18434
|
||||
*/ |
||||
|
||||
(function () { |
||||
L.QuickHull = { |
||||
|
||||
/* |
||||
* @param {Object} cpt a point to be measured from the baseline |
||||
* @param {Array} bl the baseline, as represented by a two-element |
||||
* array of latlng objects. |
||||
* @returns {Number} an approximate distance measure |
||||
*/ |
||||
getDistant: function (cpt, bl) { |
||||
var vY = bl[1].lat - bl[0].lat, |
||||
vX = bl[0].lng - bl[1].lng; |
||||
return (vX * (cpt.lat - bl[0].lat) + vY * (cpt.lng - bl[0].lng)); |
||||
}, |
||||
|
||||
/* |
||||
* @param {Array} baseLine a two-element array of latlng objects |
||||
* representing the baseline to project from |
||||
* @param {Array} latLngs an array of latlng objects |
||||
* @returns {Object} the maximum point and all new points to stay |
||||
* in consideration for the hull. |
||||
*/ |
||||
findMostDistantPointFromBaseLine: function (baseLine, latLngs) { |
||||
var maxD = 0, |
||||
maxPt = null, |
||||
newPoints = [], |
||||
i, pt, d; |
||||
|
||||
for (i = latLngs.length - 1; i >= 0; i--) { |
||||
pt = latLngs[i]; |
||||
d = this.getDistant(pt, baseLine); |
||||
|
||||
if (d > 0) { |
||||
newPoints.push(pt); |
||||
} else { |
||||
continue; |
||||
} |
||||
|
||||
if (d > maxD) { |
||||
maxD = d; |
||||
maxPt = pt; |
||||
} |
||||
} |
||||
|
||||
return { maxPoint: maxPt, newPoints: newPoints }; |
||||
}, |
||||
|
||||
|
||||
/* |
||||
* Given a baseline, compute the convex hull of latLngs as an array |
||||
* of latLngs. |
||||
* |
||||
* @param {Array} latLngs |
||||
* @returns {Array} |
||||
*/ |
||||
buildConvexHull: function (baseLine, latLngs) { |
||||
var convexHullBaseLines = [], |
||||
t = this.findMostDistantPointFromBaseLine(baseLine, latLngs); |
||||
|
||||
if (t.maxPoint) { // if there is still a point "outside" the base line
|
||||
convexHullBaseLines = |
||||
convexHullBaseLines.concat( |
||||
this.buildConvexHull([baseLine[0], t.maxPoint], t.newPoints) |
||||
); |
||||
convexHullBaseLines = |
||||
convexHullBaseLines.concat( |
||||
this.buildConvexHull([t.maxPoint, baseLine[1]], t.newPoints) |
||||
); |
||||
return convexHullBaseLines; |
||||
} else { // if there is no more point "outside" the base line, the current base line is part of the convex hull
|
||||
return [baseLine[0]]; |
||||
} |
||||
}, |
||||
|
||||
/* |
||||
* Given an array of latlngs, compute a convex hull as an array |
||||
* of latlngs |
||||
* |
||||
* @param {Array} latLngs |
||||
* @returns {Array} |
||||
*/ |
||||
getConvexHull: function (latLngs) { |
||||
// find first baseline
|
||||
var maxLat = false, minLat = false, |
||||
maxLng = false, minLng = false, |
||||
maxLatPt = null, minLatPt = null, |
||||
maxLngPt = null, minLngPt = null, |
||||
maxPt = null, minPt = null, |
||||
i; |
||||
|
||||
for (i = latLngs.length - 1; i >= 0; i--) { |
||||
var pt = latLngs[i]; |
||||
if (maxLat === false || pt.lat > maxLat) { |
||||
maxLatPt = pt; |
||||
maxLat = pt.lat; |
||||
} |
||||
if (minLat === false || pt.lat < minLat) { |
||||
minLatPt = pt; |
||||
minLat = pt.lat; |
||||
} |
||||
if (maxLng === false || pt.lng > maxLng) { |
||||
maxLngPt = pt; |
||||
maxLng = pt.lng; |
||||
} |
||||
if (minLng === false || pt.lng < minLng) { |
||||
minLngPt = pt; |
||||
minLng = pt.lng; |
||||
} |
||||
} |
||||
|
||||
if (minLat !== maxLat) { |
||||
minPt = minLatPt; |
||||
maxPt = maxLatPt; |
||||
} else { |
||||
minPt = minLngPt; |
||||
maxPt = maxLngPt; |
||||
} |
||||
|
||||
var ch = [].concat(this.buildConvexHull([minPt, maxPt], latLngs), |
||||
this.buildConvexHull([maxPt, minPt], latLngs)); |
||||
return ch; |
||||
} |
||||
}; |
||||
}()); |
||||
|
||||
L.MarkerCluster.include({ |
||||
getConvexHull: function () { |
||||
var childMarkers = this.getAllChildMarkers(), |
||||
points = [], |
||||
p, i; |
||||
|
||||
for (i = childMarkers.length - 1; i >= 0; i--) { |
||||
p = childMarkers[i].getLatLng(); |
||||
points.push(p); |
||||
} |
||||
|
||||
return L.QuickHull.getConvexHull(points); |
||||
} |
||||
}); |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue