forked from orson/bachemap
Compare commits
3 Commits
main
...
leaderboar
| Author | SHA1 | Date | |
|---|---|---|---|
| 7546b78610 | |||
| de826cd658 | |||
| 1235705cbc |
260
app.py
260
app.py
@ -12,8 +12,6 @@ from wtforms import StringField, FileField, SubmitField, DateTimeField, SelectFi
|
||||
from wtforms.validators import DataRequired, Length
|
||||
import requests
|
||||
from config import Config
|
||||
from geopy.geocoders import Nominatim
|
||||
geolocator = Nominatim(user_agent="Bachemapa @ baches.qro.mx")
|
||||
|
||||
def create_app(config=Config):
|
||||
app = Flask(__name__)
|
||||
@ -21,7 +19,6 @@ def create_app(config=Config):
|
||||
|
||||
mongo = PyMongo(app)
|
||||
login_manager = LoginManager(app)
|
||||
login_manager.login_view = 'thelogin'
|
||||
login_manager.session_protection = "strong"
|
||||
|
||||
class User(UserMixin):
|
||||
@ -45,7 +42,7 @@ def create_app(config=Config):
|
||||
description = StringField('¿Qué estamos viendo?', validators=[DataRequired()])
|
||||
photo = FileField('Evidencia fotogénica', validators=[DataRequired()])
|
||||
timedate = DateTimeField(default=datetime.now())
|
||||
typeofpin = SelectField('Tipo de cosa', choices=['bache', 'coladera', 'obra sin terminar', 'escombro', 'robo-asalto', 'biciestacionamiento', 'mala iluminación', 'bici blanca', 'zapato blanco'])
|
||||
typeofpin = SelectField('Tipo de cosa', choices=['bache', 'coladera', 'obra sin terminar', 'escombro', 'robo-asalto', 'biciestacionamiento', 'mala iluminación'])
|
||||
|
||||
submit = SubmitField('Agregar')
|
||||
|
||||
@ -61,8 +58,8 @@ def create_app(config=Config):
|
||||
return _unique
|
||||
|
||||
class RegistrationForm(FlaskForm):
|
||||
username = StringField('Nombre de usuarix', validators=[DataRequired(), Unique('users', StringField('username', message="Este usuario ya existe"))])
|
||||
pwd = PasswordField('Clave', validators=[DataRequired(), Length(min=10), Unique('users', StringField('pwd', message="Esta clave no es muy buena, escoge otra"))])
|
||||
username = StringField('Nombre de usuarix', validators=[DataRequired(), Unique('users', StringField('username', message="Username already exists"))])
|
||||
pwd = PasswordField('Clave', validators=[DataRequired(), Length(min=10), Unique('users', StringField('pwd', message="Username already exists"))])
|
||||
referral = StringField('ID de quien te invito', [DataRequired()])
|
||||
submit = SubmitField('Registrar')
|
||||
|
||||
@ -74,20 +71,7 @@ def create_app(config=Config):
|
||||
if request.method == 'GET':
|
||||
form = PinForm()
|
||||
pins = mongo.db.pins.find()
|
||||
clean_pins=[]
|
||||
for pin in pins:
|
||||
pin['_id'] = str(pin['_id'])
|
||||
if 'time' in pin and pin['time']:
|
||||
pin['time'] = pin['time'].strftime("%d/%m/%Y %H:%M")
|
||||
if 'last_mod' in pin and pin['last_mod']:
|
||||
pin['last_mod'] = pin['last_mod'].strftime("%d/%m/%Y %H:%M")
|
||||
if 'reviewed' in pin:
|
||||
pin['reviewed'] = str(pin['reviewed'])
|
||||
if 'fixed' in pin:
|
||||
pin['fixed'] = str(pin['fixed'])
|
||||
clean_pins.append(pin)
|
||||
print(type(pins))
|
||||
return render_template('index.html', pins=clean_pins, form=form)
|
||||
return render_template('index.html', pins=pins, form=form)
|
||||
else:
|
||||
form = request.form
|
||||
try:
|
||||
@ -107,15 +91,8 @@ def create_app(config=Config):
|
||||
'lng': request.form['lng'],
|
||||
'typeofpin': request.form['typeofpin'],
|
||||
'added_by': current_user.id,
|
||||
'description': request.form['description'],
|
||||
'address': str(geolocator.reverse(str(request.form['lat'])+ ", "+request.form['lng'])),
|
||||
'reviewed': True,
|
||||
'fixed': False,
|
||||
'last_mod': datetime.now(),
|
||||
'votes': -1,
|
||||
'removal_reason': None,
|
||||
'description': request.form['description']
|
||||
}
|
||||
print(geolocator.reverse(str(request.form['lat'])+ ", "+request.form['lng']))
|
||||
mongo.db.pins.insert_one(pin)
|
||||
flash('¡Gracias por tu aportación!')
|
||||
return redirect(url_for('index'))
|
||||
@ -137,7 +114,7 @@ def create_app(config=Config):
|
||||
def registrame(referral_code):
|
||||
inviter = mongo.db.users.find_one({"referral_code": referral_code})
|
||||
if not inviter:
|
||||
message = "Ooops, parece que nadie te invitó aquí... Puedes saber más sobre esta decisión aquí https://baches.qro.mx/quienes#preguntas"
|
||||
message = "Ooops, parece que nadie te invitó aquí"
|
||||
return render_template('error.html', message = message), 406
|
||||
|
||||
if request.method == 'POST':
|
||||
@ -151,19 +128,13 @@ def create_app(config=Config):
|
||||
"is_admin": False
|
||||
}
|
||||
new_user_id = mongo.db.users.insert_one(new_user_data).inserted_id
|
||||
str_id = str(new_user_id)
|
||||
mongo.db.users.update_one(
|
||||
{'_id': new_user_id},
|
||||
{'$set': {'str_id': str_id}}
|
||||
)
|
||||
invite_link = url_for('registrame', referral_code=new_user_data['referral_code'], _external=True)
|
||||
login_user(load_user(new_user_id), remember=True)
|
||||
flash('Usuario registrado exitosamente')
|
||||
login_user(load_user(new_user_id))
|
||||
return redirect(url_for('index'))
|
||||
#return render_template('dashboard.html', invite_link=invite_link)
|
||||
|
||||
if request.method == 'GET':
|
||||
return render_template('register.html', rform=RegistrationForm())
|
||||
return render_template('register.html', form=RegistrationForm())
|
||||
|
||||
@app.route('/thelogin', methods=['GET', 'POST'])
|
||||
def thelogin():
|
||||
@ -174,11 +145,11 @@ def create_app(config=Config):
|
||||
user_data = mongo.db.users.find_one({"username": username})
|
||||
if user_data and check_password_hash(user_data['pwd'], pwd):
|
||||
user = User(user_data)
|
||||
login_user(user, remember=True)
|
||||
login_user(user)
|
||||
return redirect(url_for('index'))
|
||||
else:
|
||||
return render_template('login.html', messages = 'Ooops, no hay tal usuario', login_form=form2)
|
||||
return render_template('login.html',login_form=form2)
|
||||
return render_template('login.html', messages = 'Ooops, no hay tal usuario', form=form2)
|
||||
return render_template('login.html',form=form2)
|
||||
|
||||
@app.route('/logout')
|
||||
@login_required
|
||||
@ -217,71 +188,30 @@ def create_app(config=Config):
|
||||
print(actual_pin)
|
||||
added_by = actual_pin.get("added_by")
|
||||
print(added_by)
|
||||
print(current_user.id)
|
||||
if current_user.is_admin or current_user.id == added_by:
|
||||
if not current_user.is_admin or current_user.id != added_by:
|
||||
return redirect(url_for('index'))
|
||||
else:
|
||||
mongo.db.pins.delete_one({"_id": ObjectId(pin_id)})
|
||||
return redirect(url_for('dashboard'))
|
||||
else:
|
||||
return redirect(url_for('index'))
|
||||
|
||||
@app.route("/edit_pin/<pin_id>", methods=['POST'])
|
||||
@login_required
|
||||
def edit_pin(pin_id):
|
||||
actual_pin = mongo.db.pins.find_one({"_id": ObjectId(pin_id)})
|
||||
if not actual_pin:
|
||||
flash('Pin no encontrado')
|
||||
return redirect(url_for('dashboard'))
|
||||
|
||||
added_by = actual_pin.get("added_by")
|
||||
|
||||
if current_user.is_admin or current_user.id == added_by:
|
||||
# Get form data
|
||||
typeofpin = request.form.get('typeofpin')
|
||||
description = request.form.get('description')
|
||||
address = request.form.get('address')
|
||||
|
||||
# Update the pin
|
||||
mongo.db.pins.update_one(
|
||||
{"_id": ObjectId(pin_id)},
|
||||
{"$set": {
|
||||
"typeofpin": typeofpin,
|
||||
"description": description,
|
||||
"address": address,
|
||||
"last_mod": datetime.now()
|
||||
}}
|
||||
)
|
||||
flash('Pin actualizado exitosamente')
|
||||
return redirect(url_for('dashboard'))
|
||||
else:
|
||||
flash('No tienes permiso para editar este pin')
|
||||
return render_template('error.html', message='No tienes permiso para editar este pin'), 403
|
||||
|
||||
@app.route('/manifest.json')
|
||||
def manifest():
|
||||
return send_from_directory('static', 'manifest.json')
|
||||
@app.route('/src')
|
||||
def src():
|
||||
return send_from_directory('static', 'src')
|
||||
@app.route('/dashboard')
|
||||
@login_required
|
||||
def dashboard():
|
||||
#if request.method == 'GET':
|
||||
#if current_user.is_authenticated == False:
|
||||
# return redirect(url_for('thelogin'))
|
||||
#else:
|
||||
old_qr = mongo.db.users.find_one({'_id': ObjectId(current_user.id)})
|
||||
print(old_qr.get('referral_code'))
|
||||
invite_code = str(uuid4())
|
||||
qr_update = mongo.db.users.update_one({'_id': ObjectId(current_user.id)}, {'$set': {'referral_code': invite_code}})
|
||||
print(invite_code)
|
||||
if not current_user.is_admin:
|
||||
pins = list(mongo.db.pins.find({"added_by": current_user.id}).sort("time", -1))
|
||||
print(pins)
|
||||
return render_template('dashboard.html', pins=pins, invite_code=invite_code)
|
||||
if current_user.is_admin:
|
||||
users = list(mongo.db.users.find())
|
||||
pins = list(mongo.db.pins.find())
|
||||
return render_template('dashboard.html', users=users, pins=pins, invite_code=invite_code)
|
||||
if request.method == 'GET':
|
||||
if not current_user.is_authenticated:
|
||||
q_filter = "{'_id': ObjectId(current_user.id)}"
|
||||
q_op = "{'$set': {'referral_code':str(uuid4())}}"
|
||||
mongo.db.users.update_one(q_filter, q_op)
|
||||
return redirect(url_for('thelogin'))
|
||||
if not current_user.is_admin:
|
||||
pins = list(mongo.db.pins.find({"added_by": current_user.id}))
|
||||
return render_template('dashboard.html', pins=pins)
|
||||
if current_user.is_admin:
|
||||
users = list(mongo.db.users.find())
|
||||
pins = list(mongo.db.pins.find())
|
||||
return render_template('dashboard.html', users=users, pins=pins)
|
||||
#if request.method == 'POST':
|
||||
# pass
|
||||
|
||||
@app.cli.command('add_user')
|
||||
def add_user():
|
||||
@ -297,97 +227,53 @@ def create_app(config=Config):
|
||||
}
|
||||
mongo.db.users.insert_one(admin_user)
|
||||
print(f"Admin {username} added! Referral code is {admin_user['referral_code']}")
|
||||
|
||||
@app.route("/camera", methods=["GET", "POST"])
|
||||
@login_required
|
||||
def camera():
|
||||
if request.method == "POST":
|
||||
# 1. Grab geolocation data from the form
|
||||
latitude = request.form.get("latitude")
|
||||
longitude = request.form.get("longitude")
|
||||
|
||||
# 2. Grab the photo file
|
||||
photo = request.files.get("photo")
|
||||
|
||||
# 3. Save the file if it exists
|
||||
if photo:
|
||||
# Make sure your 'uploads' folder exists or handle dynamically
|
||||
photo_path = os.path.join(app.config['UPLOAD_FOLDER'], photo.filename)
|
||||
photo.save(photo_path)
|
||||
|
||||
# Create a new pin with the uploaded photo data
|
||||
pin = {
|
||||
'time': datetime.now(),
|
||||
'photo': photo_path,
|
||||
'lat': latitude,
|
||||
'lng': longitude,
|
||||
'typeofpin': request.form.get('typeofpin', 'bache'), # Default to bache if not specified
|
||||
'added_by': current_user.id,
|
||||
'description': request.form.get('description', 'Foto desde cámara'), # Default description
|
||||
'reviewed': False, # Added reviewed field set to False
|
||||
'address': str(geolocator.reverse(f"{latitude}, {longitude}")) if latitude and longitude else "Ubicación desconocida"
|
||||
}
|
||||
|
||||
# Insert the new pin into the database
|
||||
mongo.db.pins.insert_one(pin)
|
||||
flash('¡Gracias por tu aportación!')
|
||||
# For demonstration, just redirect or return a success message
|
||||
return f"Photo uploaded! Lat: {latitude}, Lng: {longitude}"
|
||||
|
||||
# If GET request, just render the camera page
|
||||
return render_template("camera.html")
|
||||
|
||||
@app.route('/leaderboard')
|
||||
def leaderboard():
|
||||
pipeline = [
|
||||
{"$group": {"_id": "$added_by", "count": {"$sum": 1}}},
|
||||
{"$sort": {"count": -1}},
|
||||
{"$limit": 10},
|
||||
]
|
||||
|
||||
# Convert the aggregation result to a list
|
||||
leaders_by_id = list(mongo.db.pins.aggregate(pipeline))
|
||||
|
||||
# Create a list to store the final results
|
||||
cleaned_leaders = []
|
||||
|
||||
# Process each leader
|
||||
for leader in leaders_by_id:
|
||||
user_id = leader["_id"]
|
||||
count = leader["count"]
|
||||
|
||||
# Find the corresponding user
|
||||
try:
|
||||
user = mongo.db.users.find_one({"_id": ObjectId(user_id)})
|
||||
if user and "username" in user:
|
||||
username = user["username"]
|
||||
if len(username) >= 2:
|
||||
cleaned_username = username[0] + "***" + username[-1]
|
||||
else:
|
||||
cleaned_username = username+"***"+random.choice(string.ascii_letters, k=1)
|
||||
cleaned_leaders.append({"username": cleaned_username, "count": count})
|
||||
except Exception as e:
|
||||
print(f"Error processing user_id {user_id}: {e}")
|
||||
continue
|
||||
|
||||
print('THIS IS THE LEADERBOARD', cleaned_leaders)
|
||||
# Get stats using aggregation pipeline
|
||||
# Count total users
|
||||
total_users_result = list(mongo.db.users.aggregate([
|
||||
{"$count": "total"}
|
||||
]))
|
||||
total_users = total_users_result[0]["total"] if total_users_result else 0
|
||||
leaders = mongo.db.pins.aggregate([
|
||||
{
|
||||
"$group": {
|
||||
"_id":"$added_by",
|
||||
"count": {"$sum":1}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$sort": {"count":-1}
|
||||
},
|
||||
{
|
||||
"$limit":10
|
||||
},
|
||||
{
|
||||
"$lookup": {
|
||||
"from": "users",
|
||||
"localField": "added_by",
|
||||
"foreignField": "added_by",
|
||||
"as": "user_info"
|
||||
}
|
||||
},
|
||||
{
|
||||
"$unwind": "$user_info"
|
||||
},
|
||||
{
|
||||
"$project": {
|
||||
"_id":0,
|
||||
"added_by": "$_id",
|
||||
"count":1,
|
||||
"username": "$user_info.username"
|
||||
}
|
||||
}
|
||||
])
|
||||
#print(list(leaders))
|
||||
cleaned_leaders=list()
|
||||
for leader in list(leaders):
|
||||
leader["username"] = leader["username"][0]+"***"+leader["username"][-1]
|
||||
cleaned_leaders.append(leader)
|
||||
if current_user.is_authenticated:
|
||||
username = user.username
|
||||
else:
|
||||
username = None
|
||||
|
||||
# Count unique users who have added pins
|
||||
active_users_result = list(mongo.db.pins.aggregate([
|
||||
{"$group": {"_id": None, "active_users": {"$addToSet": "$added_by"}}},
|
||||
{"$project": {"active_count": {"$size": "$active_users"}}}
|
||||
]))
|
||||
active_users = active_users_result[0]["active_count"] if active_users_result else 0
|
||||
|
||||
# Calculate percentage (handle case where total_users might be 0)
|
||||
active_percentage = round((active_users / total_users) * 100, 1) if total_users > 0 else 0
|
||||
|
||||
return render_template('leaderboard.html', leaders=cleaned_leaders, percentage = active_percentage)
|
||||
return render_template('leaderboard.html', leaders=cleaned_leaders, username=username)
|
||||
|
||||
|
||||
return app
|
||||
|
||||
@ -1,11 +1,5 @@
|
||||
from datetime import timedelta
|
||||
class Config:
|
||||
MONGO_URI = 'mongodb://localhost:27017/mapDB'
|
||||
UPLOAD_FOLDER = 'uploads'
|
||||
SECRET_KEY = 'supersecretkey'
|
||||
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
|
||||
LOGIN_URL = '/thelogin'
|
||||
REMEMBER_COOKIE_DURATION = timedelta(days=7) # Adjust as needed
|
||||
REMEMBER_COOKIE_HTTPONLY = True
|
||||
REMEMBER_COOKIE_SECURE = True # Set to True if using HTTPS
|
||||
SESSION_COOKIE_SAMESITE = 'Lax'
|
||||
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
|
||||
7
static/Leaflet.markercluster-1.4.1/.gitignore
vendored
Normal file
7
static/Leaflet.markercluster-1.4.1/.gitignore
vendored
Normal file
@ -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
|
||||
20
static/Leaflet.markercluster-1.4.1/.travis.yml
Normal file
20
static/Leaflet.markercluster-1.4.1/.travis.yml
Normal file
@ -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"
|
||||
242
static/Leaflet.markercluster-1.4.1/CHANGELOG.md
Normal file
242
static/Leaflet.markercluster-1.4.1/CHANGELOG.md
Normal file
@ -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!
|
||||
70
static/Leaflet.markercluster-1.4.1/CONTRIBUTING.md
Normal file
70
static/Leaflet.markercluster-1.4.1/CONTRIBUTING.md
Normal file
@ -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
|
||||
```
|
||||
23
static/Leaflet.markercluster-1.4.1/ISSUE_TEMPLATE.md
Normal file
23
static/Leaflet.markercluster-1.4.1/ISSUE_TEMPLATE.md
Normal file
@ -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.
|
||||
86
static/Leaflet.markercluster-1.4.1/Jakefile.js
Normal file
86
static/Leaflet.markercluster-1.4.1/Jakefile.js
Normal file
@ -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']);
|
||||
20
static/Leaflet.markercluster-1.4.1/MIT-LICENCE.txt
Normal file
20
static/Leaflet.markercluster-1.4.1/MIT-LICENCE.txt
Normal file
@ -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.
|
||||
292
static/Leaflet.markercluster-1.4.1/README.md
Normal file
292
static/Leaflet.markercluster-1.4.1/README.md
Normal file
@ -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/) |
|
||||
27
static/Leaflet.markercluster-1.4.1/bower.json
Normal file
27
static/Leaflet.markercluster-1.4.1/bower.json
Normal file
@ -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"
|
||||
}
|
||||
}
|
||||
53
static/Leaflet.markercluster-1.4.1/example/geojson-sample.js
Normal file
53
static/Leaflet.markercluster-1.4.1/example/geojson-sample.js
Normal file
@ -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"
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
54
static/Leaflet.markercluster-1.4.1/example/geojson.html
Normal file
54
static/Leaflet.markercluster-1.4.1/example/geojson.html
Normal file
@ -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>
|
||||
BIN
static/Leaflet.markercluster-1.4.1/example/map.png
Normal file
BIN
static/Leaflet.markercluster-1.4.1/example/map.png
Normal file
Binary file not shown.
|
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>
|
||||
6
static/Leaflet.markercluster-1.4.1/example/mobile.css
Normal file
6
static/Leaflet.markercluster-1.4.1/example/mobile.css
Normal file
@ -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>
|
||||
10004
static/Leaflet.markercluster-1.4.1/example/realworld.10000.js
Normal file
10004
static/Leaflet.markercluster-1.4.1/example/realworld.10000.js
Normal file
File diff suppressed because it is too large
Load Diff
393
static/Leaflet.markercluster-1.4.1/example/realworld.388.js
Normal file
393
static/Leaflet.markercluster-1.4.1/example/realworld.388.js
Normal file
@ -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"]
|
||||
];
|
||||
25006
static/Leaflet.markercluster-1.4.1/example/realworld.50000.1.js
Normal file
25006
static/Leaflet.markercluster-1.4.1/example/realworld.50000.1.js
Normal file
File diff suppressed because it is too large
Load Diff
25000
static/Leaflet.markercluster-1.4.1/example/realworld.50000.2.js
Normal file
25000
static/Leaflet.markercluster-1.4.1/example/realworld.50000.2.js
Normal file
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>
|
||||
28
static/Leaflet.markercluster-1.4.1/example/screen.css
Normal file
28
static/Leaflet.markercluster-1.4.1/example/screen.css
Normal file
@ -0,0 +1,28 @@
|
||||
#map {
|
||||
width: 800px;
|
||||
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;
|
||||
}
|
||||
43
static/Leaflet.markercluster-1.4.1/package.json
Normal file
43
static/Leaflet.markercluster-1.4.1/package.json
Normal file
@ -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"
|
||||
}
|
||||
2
static/Leaflet.markercluster-1.4.1/spec/after.js
Normal file
2
static/Leaflet.markercluster-1.4.1/spec/after.js
Normal file
@ -0,0 +1,2 @@
|
||||
// put after Leaflet files as imagePath can't be detected in a PhantomJS env
|
||||
L.Icon.Default.imagePath = "../dist/images";
|
||||
1253
static/Leaflet.markercluster-1.4.1/spec/expect.js
Normal file
1253
static/Leaflet.markercluster-1.4.1/spec/expect.js
Normal file
File diff suppressed because it is too large
Load Diff
76
static/Leaflet.markercluster-1.4.1/spec/index.html
Normal file
76
static/Leaflet.markercluster-1.4.1/spec/index.html
Normal file
@ -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>
|
||||
96
static/Leaflet.markercluster-1.4.1/spec/karma.conf.js
Normal file
96
static/Leaflet.markercluster-1.4.1/spec/karma.conf.js
Normal file
@ -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
|
||||
});
|
||||
};
|
||||
4223
static/Leaflet.markercluster-1.4.1/spec/sinon.js
Normal file
4223
static/Leaflet.markercluster-1.4.1/spec/sinon.js
Normal file
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);
|
||||
});
|
||||
});
|
||||
123
static/Leaflet.markercluster-1.4.1/spec/suites/AddLayersSpec.js
Normal file
123
static/Leaflet.markercluster-1.4.1/spec/suites/AddLayersSpec.js
Normal file
@ -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();
|
||||
});
|
||||
});
|
||||
240
static/Leaflet.markercluster-1.4.1/spec/suites/NonPointSpec.js
Normal file
240
static/Leaflet.markercluster-1.4.1/spec/suites/NonPointSpec.js
Normal file
@ -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);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
63
static/Leaflet.markercluster-1.4.1/spec/suites/PaneSpec.js
Normal file
63
static/Leaflet.markercluster-1.4.1/spec/suites/PaneSpec.js
Normal file
@ -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 }
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
435
static/Leaflet.markercluster-1.4.1/spec/suites/RefreshSpec.js
Normal file
435
static/Leaflet.markercluster-1.4.1/spec/suites/RefreshSpec.js
Normal file
@ -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);
|
||||
});
|
||||
});
|
||||
30
static/Leaflet.markercluster-1.4.1/spec/suites/SpecHelper.js
Normal file
30
static/Leaflet.markercluster-1.4.1/spec/suites/SpecHelper.js
Normal file
@ -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);
|
||||
});
|
||||
});
|
||||
373
static/Leaflet.markercluster-1.4.1/spec/suites/eventsSpec.js
Normal file
373
static/Leaflet.markercluster-1.4.1/spec/suites/eventsSpec.js
Normal file
@ -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);
|
||||
});
|
||||
*/
|
||||
});
|
||||
128
static/Leaflet.markercluster-1.4.1/spec/suites/getBoundsSpec.js
Normal file
128
static/Leaflet.markercluster-1.4.1/spec/suites/getBoundsSpec.js
Normal file
@ -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);
|
||||
});
|
||||
});
|
||||
65
static/Leaflet.markercluster-1.4.1/spec/suites/onAddSpec.js
Normal file
65
static/Leaflet.markercluster-1.4.1/spec/suites/onAddSpec.js
Normal file
@ -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);
|
||||
|
||||
});
|
||||
});
|
||||
344
static/Leaflet.markercluster-1.4.1/spec/suites/spiderfySpec.js
Normal file
344
static/Leaflet.markercluster-1.4.1/spec/suites/spiderfySpec.js
Normal file
@ -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);
|
||||
});
|
||||
});
|
||||
139
static/Leaflet.markercluster-1.4.1/spec/suites/unspiderfySpec.js
Normal file
139
static/Leaflet.markercluster-1.4.1/spec/suites/unspiderfySpec.js
Normal file
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
118
static/Leaflet.markercluster-1.4.1/src/DistanceGrid.js
Normal file
118
static/Leaflet.markercluster-1.4.1/src/DistanceGrid.js
Normal file
@ -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);
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,475 @@
|
||||
//This code is 100% based on https://github.com/jawj/OverlappingMarkerSpiderfier-Leaflet
|
||||
//Huge thanks to jawj for implementing it first to make my job easy :-)
|
||||
|
||||
L.MarkerCluster.include({
|
||||
|
||||
_2PI: Math.PI * 2,
|
||||
_circleFootSeparation: 25, //related to circumference of circle
|
||||
_circleStartAngle: 0,
|
||||
|
||||
_spiralFootSeparation: 28, //related to size of spiral (experiment!)
|
||||
_spiralLengthStart: 11,
|
||||
_spiralLengthFactor: 5,
|
||||
|
||||
_circleSpiralSwitchover: 9, //show spiral instead of circle from this marker count upwards.
|
||||
// 0 -> always spiral; Infinity -> always circle
|
||||
|
||||
spiderfy: function () {
|
||||
if (this._group._spiderfied === this || this._group._inZoomAnimation) {
|
||||
return;
|
||||
}
|
||||
|
||||
var childMarkers = this.getAllChildMarkers(null, true),
|
||||
group = this._group,
|
||||
map = group._map,
|
||||
center = map.latLngToLayerPoint(this._latlng),
|
||||
positions;
|
||||
|
||||
this._group._unspiderfy();
|
||||
this._group._spiderfied = this;
|
||||
|
||||
//TODO Maybe: childMarkers order by distance to center
|
||||
|
||||
if (childMarkers.length >= this._circleSpiralSwitchover) {
|
||||
positions = this._generatePointsSpiral(childMarkers.length, center);
|
||||
} else {
|
||||
center.y += 10; // Otherwise circles look wrong => hack for standard blue icon, renders differently for other icons.
|
||||
positions = this._generatePointsCircle(childMarkers.length, center);
|
||||
}
|
||||
|
||||
this._animationSpiderfy(childMarkers, positions);
|
||||
},
|
||||
|
||||
unspiderfy: function (zoomDetails) {
|
||||
/// <param Name="zoomDetails">Argument from zoomanim if being called in a zoom animation or null otherwise</param>
|
||||
if (this._group._inZoomAnimation) {
|
||||
return;
|
||||
}
|
||||
this._animationUnspiderfy(zoomDetails);
|
||||
|
||||
this._group._spiderfied = null;
|
||||
},
|
||||
|
||||
_generatePointsCircle: function (count, centerPt) {
|
||||
var circumference = this._group.options.spiderfyDistanceMultiplier * this._circleFootSeparation * (2 + count),
|
||||
legLength = circumference / this._2PI, //radius from circumference
|
||||
angleStep = this._2PI / count,
|
||||
res = [],
|
||||
i, angle;
|
||||
|
||||
legLength = Math.max(legLength, 35); // Minimum distance to get outside the cluster icon.
|
||||
|
||||
res.length = count;
|
||||
|
||||
for (i = 0; i < count; i++) { // Clockwise, like spiral.
|
||||
angle = this._circleStartAngle + i * angleStep;
|
||||
res[i] = new L.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle))._round();
|
||||
}
|
||||
|
||||
return res;
|
||||
},
|
||||
|
||||
_generatePointsSpiral: function (count, centerPt) {
|
||||
var spiderfyDistanceMultiplier = this._group.options.spiderfyDistanceMultiplier,
|
||||
legLength = spiderfyDistanceMultiplier * this._spiralLengthStart,
|
||||
separation = spiderfyDistanceMultiplier * this._spiralFootSeparation,
|
||||
lengthFactor = spiderfyDistanceMultiplier * this._spiralLengthFactor * this._2PI,
|
||||
angle = 0,
|
||||
res = [],
|
||||
i;
|
||||
|
||||
res.length = count;
|
||||
|
||||
// Higher index, closer position to cluster center.
|
||||
for (i = count; i >= 0; i--) {
|
||||
// Skip the first position, so that we are already farther from center and we avoid
|
||||
// being under the default cluster icon (especially important for Circle Markers).
|
||||
if (i < count) {
|
||||
res[i] = new L.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle))._round();
|
||||
}
|
||||
angle += separation / legLength + i * 0.0005;
|
||||
legLength += lengthFactor / angle;
|
||||
}
|
||||
return res;
|
||||
},
|
||||
|
||||
_noanimationUnspiderfy: function () {
|
||||
var group = this._group,
|
||||
map = group._map,
|
||||
fg = group._featureGroup,
|
||||
childMarkers = this.getAllChildMarkers(null, true),
|
||||
m, i;
|
||||
|
||||
group._ignoreMove = true;
|
||||
|
||||
this.setOpacity(1);
|
||||
for (i = childMarkers.length - 1; i >= 0; i--) {
|
||||
m = childMarkers[i];
|
||||
|
||||
fg.removeLayer(m);
|
||||
|
||||
if (m._preSpiderfyLatlng) {
|
||||
m.setLatLng(m._preSpiderfyLatlng);
|
||||
delete m._preSpiderfyLatlng;
|
||||
}
|
||||
if (m.setZIndexOffset) {
|
||||
m.setZIndexOffset(0);
|
||||
}
|
||||
|
||||
if (m._spiderLeg) {
|
||||
map.removeLayer(m._spiderLeg);
|
||||
delete m._spiderLeg;
|
||||
}
|
||||
}
|
||||
|
||||
group.fire('unspiderfied', {
|
||||
cluster: this,
|
||||
markers: childMarkers
|
||||
});
|
||||
group._ignoreMove = false;
|
||||
group._spiderfied = null;
|
||||
}
|
||||
});
|
||||
|
||||
//Non Animated versions of everything
|
||||
L.MarkerClusterNonAnimated = L.MarkerCluster.extend({
|
||||
_animationSpiderfy: function (childMarkers, positions) {
|
||||
var group = this._group,
|
||||
map = group._map,
|
||||
fg = group._featureGroup,
|
||||
legOptions = this._group.options.spiderLegPolylineOptions,
|
||||
i, m, leg, newPos;
|
||||
|
||||
group._ignoreMove = true;
|
||||
|
||||
// Traverse in ascending order to make sure that inner circleMarkers are on top of further legs. Normal markers are re-ordered by newPosition.
|
||||
// The reverse order trick no longer improves performance on modern browsers.
|
||||
for (i = 0; i < childMarkers.length; i++) {
|
||||
newPos = map.layerPointToLatLng(positions[i]);
|
||||
m = childMarkers[i];
|
||||
|
||||
// Add the leg before the marker, so that in case the latter is a circleMarker, the leg is behind it.
|
||||
leg = new L.Polyline([this._latlng, newPos], legOptions);
|
||||
map.addLayer(leg);
|
||||
m._spiderLeg = leg;
|
||||
|
||||
// Now add the marker.
|
||||
m._preSpiderfyLatlng = m._latlng;
|
||||
m.setLatLng(newPos);
|
||||
if (m.setZIndexOffset) {
|
||||
m.setZIndexOffset(1000000); //Make these appear on top of EVERYTHING
|
||||
}
|
||||
|
||||
fg.addLayer(m);
|
||||
}
|
||||
this.setOpacity(0.3);
|
||||
|
||||
group._ignoreMove = false;
|
||||
group.fire('spiderfied', {
|
||||
cluster: this,
|
||||
markers: childMarkers
|
||||
});
|
||||
},
|
||||
|
||||
_animationUnspiderfy: function () {
|
||||
this._noanimationUnspiderfy();
|
||||
}
|
||||
});
|
||||
|
||||
//Animated versions here
|
||||
L.MarkerCluster.include({
|
||||
|
||||
_animationSpiderfy: function (childMarkers, positions) {
|
||||
var me = this,
|
||||
group = this._group,
|
||||
map = group._map,
|
||||
fg = group._featureGroup,
|
||||
thisLayerLatLng = this._latlng,
|
||||
thisLayerPos = map.latLngToLayerPoint(thisLayerLatLng),
|
||||
svg = L.Path.SVG,
|
||||
legOptions = L.extend({}, this._group.options.spiderLegPolylineOptions), // Copy the options so that we can modify them for animation.
|
||||
finalLegOpacity = legOptions.opacity,
|
||||
i, m, leg, legPath, legLength, newPos;
|
||||
|
||||
if (finalLegOpacity === undefined) {
|
||||
finalLegOpacity = L.MarkerClusterGroup.prototype.options.spiderLegPolylineOptions.opacity;
|
||||
}
|
||||
|
||||
if (svg) {
|
||||
// If the initial opacity of the spider leg is not 0 then it appears before the animation starts.
|
||||
legOptions.opacity = 0;
|
||||
|
||||
// Add the class for CSS transitions.
|
||||
legOptions.className = (legOptions.className || '') + ' leaflet-cluster-spider-leg';
|
||||
} else {
|
||||
// Make sure we have a defined opacity.
|
||||
legOptions.opacity = finalLegOpacity;
|
||||
}
|
||||
|
||||
group._ignoreMove = true;
|
||||
|
||||
// Add markers and spider legs to map, hidden at our center point.
|
||||
// Traverse in ascending order to make sure that inner circleMarkers are on top of further legs. Normal markers are re-ordered by newPosition.
|
||||
// The reverse order trick no longer improves performance on modern browsers.
|
||||
for (i = 0; i < childMarkers.length; i++) {
|
||||
m = childMarkers[i];
|
||||
|
||||
newPos = map.layerPointToLatLng(positions[i]);
|
||||
|
||||
// Add the leg before the marker, so that in case the latter is a circleMarker, the leg is behind it.
|
||||
leg = new L.Polyline([thisLayerLatLng, newPos], legOptions);
|
||||
map.addLayer(leg);
|
||||
m._spiderLeg = leg;
|
||||
|
||||
// Explanations: https://jakearchibald.com/2013/animated-line-drawing-svg/
|
||||
// In our case the transition property is declared in the CSS file.
|
||||
if (svg) {
|
||||
legPath = leg._path;
|
||||
legLength = legPath.getTotalLength() + 0.1; // Need a small extra length to avoid remaining dot in Firefox.
|
||||
legPath.style.strokeDasharray = legLength; // Just 1 length is enough, it will be duplicated.
|
||||
legPath.style.strokeDashoffset = legLength;
|
||||
}
|
||||
|
||||
// If it is a marker, add it now and we'll animate it out
|
||||
if (m.setZIndexOffset) {
|
||||
m.setZIndexOffset(1000000); // Make normal markers appear on top of EVERYTHING
|
||||
}
|
||||
if (m.clusterHide) {
|
||||
m.clusterHide();
|
||||
}
|
||||
|
||||
// Vectors just get immediately added
|
||||
fg.addLayer(m);
|
||||
|
||||
if (m._setPos) {
|
||||
m._setPos(thisLayerPos);
|
||||
}
|
||||
}
|
||||
|
||||
group._forceLayout();
|
||||
group._animationStart();
|
||||
|
||||
// Reveal markers and spider legs.
|
||||
for (i = childMarkers.length - 1; i >= 0; i--) {
|
||||
newPos = map.layerPointToLatLng(positions[i]);
|
||||
m = childMarkers[i];
|
||||
|
||||
//Move marker to new position
|
||||
m._preSpiderfyLatlng = m._latlng;
|
||||
m.setLatLng(newPos);
|
||||
|
||||
if (m.clusterShow) {
|
||||
m.clusterShow();
|
||||
}
|
||||
|
||||
// Animate leg (animation is actually delegated to CSS transition).
|
||||
if (svg) {
|
||||
leg = m._spiderLeg;
|
||||
legPath = leg._path;
|
||||
legPath.style.strokeDashoffset = 0;
|
||||
//legPath.style.strokeOpacity = finalLegOpacity;
|
||||
leg.setStyle({opacity: finalLegOpacity});
|
||||
}
|
||||
}
|
||||
this.setOpacity(0.3);
|
||||
|
||||
group._ignoreMove = false;
|
||||
|
||||
setTimeout(function () {
|
||||
group._animationEnd();
|
||||
group.fire('spiderfied', {
|
||||
cluster: me,
|
||||
markers: childMarkers
|
||||
});
|
||||
}, 200);
|
||||
},
|
||||
|
||||
_animationUnspiderfy: function (zoomDetails) {
|
||||
var me = this,
|
||||
group = this._group,
|
||||
map = group._map,
|
||||
fg = group._featureGroup,
|
||||
thisLayerPos = zoomDetails ? map._latLngToNewLayerPoint(this._latlng, zoomDetails.zoom, zoomDetails.center) : map.latLngToLayerPoint(this._latlng),
|
||||
childMarkers = this.getAllChildMarkers(null, true),
|
||||
svg = L.Path.SVG,
|
||||
m, i, leg, legPath, legLength, nonAnimatable;
|
||||
|
||||
group._ignoreMove = true;
|
||||
group._animationStart();
|
||||
|
||||
//Make us visible and bring the child markers back in
|
||||
this.setOpacity(1);
|
||||
for (i = childMarkers.length - 1; i >= 0; i--) {
|
||||
m = childMarkers[i];
|
||||
|
||||
//Marker was added to us after we were spiderfied
|
||||
if (!m._preSpiderfyLatlng) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//Close any popup on the marker first, otherwise setting the location of the marker will make the map scroll
|
||||
m.closePopup();
|
||||
|
||||
//Fix up the location to the real one
|
||||
m.setLatLng(m._preSpiderfyLatlng);
|
||||
delete m._preSpiderfyLatlng;
|
||||
|
||||
//Hack override the location to be our center
|
||||
nonAnimatable = true;
|
||||
if (m._setPos) {
|
||||
m._setPos(thisLayerPos);
|
||||
nonAnimatable = false;
|
||||
}
|
||||
if (m.clusterHide) {
|
||||
m.clusterHide();
|
||||
nonAnimatable = false;
|
||||
}
|
||||
if (nonAnimatable) {
|
||||
fg.removeLayer(m);
|
||||
}
|
||||
|
||||
// Animate the spider leg back in (animation is actually delegated to CSS transition).
|
||||
if (svg) {
|
||||
leg = m._spiderLeg;
|
||||
legPath = leg._path;
|
||||
legLength = legPath.getTotalLength() + 0.1;
|
||||
legPath.style.strokeDashoffset = legLength;
|
||||
leg.setStyle({opacity: 0});
|
||||
}
|
||||
}
|
||||
|
||||
group._ignoreMove = false;
|
||||
|
||||
setTimeout(function () {
|
||||
//If we have only <= one child left then that marker will be shown on the map so don't remove it!
|
||||
var stillThereChildCount = 0;
|
||||
for (i = childMarkers.length - 1; i >= 0; i--) {
|
||||
m = childMarkers[i];
|
||||
if (m._spiderLeg) {
|
||||
stillThereChildCount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (i = childMarkers.length - 1; i >= 0; i--) {
|
||||
m = childMarkers[i];
|
||||
|
||||
if (!m._spiderLeg) { //Has already been unspiderfied
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m.clusterShow) {
|
||||
m.clusterShow();
|
||||
}
|
||||
if (m.setZIndexOffset) {
|
||||
m.setZIndexOffset(0);
|
||||
}
|
||||
|
||||
if (stillThereChildCount > 1) {
|
||||
fg.removeLayer(m);
|
||||
}
|
||||
|
||||
map.removeLayer(m._spiderLeg);
|
||||
delete m._spiderLeg;
|
||||
}
|
||||
group._animationEnd();
|
||||
group.fire('unspiderfied', {
|
||||
cluster: me,
|
||||
markers: childMarkers
|
||||
});
|
||||
}, 200);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
L.MarkerClusterGroup.include({
|
||||
//The MarkerCluster currently spiderfied (if any)
|
||||
_spiderfied: null,
|
||||
|
||||
unspiderfy: function () {
|
||||
this._unspiderfy.apply(this, arguments);
|
||||
},
|
||||
|
||||
_spiderfierOnAdd: function () {
|
||||
this._map.on('click', this._unspiderfyWrapper, this);
|
||||
|
||||
if (this._map.options.zoomAnimation) {
|
||||
this._map.on('zoomstart', this._unspiderfyZoomStart, this);
|
||||
}
|
||||
//Browsers without zoomAnimation or a big zoom don't fire zoomstart
|
||||
this._map.on('zoomend', this._noanimationUnspiderfy, this);
|
||||
|
||||
if (!L.Browser.touch) {
|
||||
this._map.getRenderer(this);
|
||||
//Needs to happen in the pageload, not after, or animations don't work in webkit
|
||||
// http://stackoverflow.com/questions/8455200/svg-animate-with-dynamically-added-elements
|
||||
//Disable on touch browsers as the animation messes up on a touch zoom and isn't very noticable
|
||||
}
|
||||
},
|
||||
|
||||
_spiderfierOnRemove: function () {
|
||||
this._map.off('click', this._unspiderfyWrapper, this);
|
||||
this._map.off('zoomstart', this._unspiderfyZoomStart, this);
|
||||
this._map.off('zoomanim', this._unspiderfyZoomAnim, this);
|
||||
this._map.off('zoomend', this._noanimationUnspiderfy, this);
|
||||
|
||||
//Ensure that markers are back where they should be
|
||||
// Use no animation to avoid a sticky leaflet-cluster-anim class on mapPane
|
||||
this._noanimationUnspiderfy();
|
||||
},
|
||||
|
||||
//On zoom start we add a zoomanim handler so that we are guaranteed to be last (after markers are animated)
|
||||
//This means we can define the animation they do rather than Markers doing an animation to their actual location
|
||||
_unspiderfyZoomStart: function () {
|
||||
if (!this._map) { //May have been removed from the map by a zoomEnd handler
|
||||
return;
|
||||
}
|
||||
|
||||
this._map.on('zoomanim', this._unspiderfyZoomAnim, this);
|
||||
},
|
||||
|
||||
_unspiderfyZoomAnim: function (zoomDetails) {
|
||||
//Wait until the first zoomanim after the user has finished touch-zooming before running the animation
|
||||
if (L.DomUtil.hasClass(this._map._mapPane, 'leaflet-touching')) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._map.off('zoomanim', this._unspiderfyZoomAnim, this);
|
||||
this._unspiderfy(zoomDetails);
|
||||
},
|
||||
|
||||
_unspiderfyWrapper: function () {
|
||||
/// <summary>_unspiderfy but passes no arguments</summary>
|
||||
this._unspiderfy();
|
||||
},
|
||||
|
||||
_unspiderfy: function (zoomDetails) {
|
||||
if (this._spiderfied) {
|
||||
this._spiderfied.unspiderfy(zoomDetails);
|
||||
}
|
||||
},
|
||||
|
||||
_noanimationUnspiderfy: function () {
|
||||
if (this._spiderfied) {
|
||||
this._spiderfied._noanimationUnspiderfy();
|
||||
}
|
||||
},
|
||||
|
||||
//If the given layer is currently being spiderfied then we unspiderfy it so it isn't on the map anymore etc
|
||||
_unspiderfyLayer: function (layer) {
|
||||
if (layer._spiderLeg) {
|
||||
this._featureGroup.removeLayer(layer);
|
||||
|
||||
if (layer.clusterShow) {
|
||||
layer.clusterShow();
|
||||
}
|
||||
//Position will be fixed up immediately in _animationUnspiderfy
|
||||
if (layer.setZIndexOffset) {
|
||||
layer.setZIndexOffset(0);
|
||||
}
|
||||
|
||||
this._map.removeLayer(layer._spiderLeg);
|
||||
delete layer._spiderLeg;
|
||||
}
|
||||
}
|
||||
});
|
||||
406
static/Leaflet.markercluster-1.4.1/src/MarkerCluster.js
Normal file
406
static/Leaflet.markercluster-1.4.1/src/MarkerCluster.js
Normal file
@ -0,0 +1,406 @@
|
||||
export var MarkerCluster = L.MarkerCluster = L.Marker.extend({
|
||||
options: L.Icon.prototype.options,
|
||||
|
||||
initialize: function (group, zoom, a, b) {
|
||||
|
||||
L.Marker.prototype.initialize.call(this, a ? (a._cLatLng || a.getLatLng()) : new L.LatLng(0, 0),
|
||||
{ icon: this, pane: group.options.clusterPane });
|
||||
|
||||
this._group = group;
|
||||
this._zoom = zoom;
|
||||
|
||||
this._markers = [];
|
||||
this._childClusters = [];
|
||||
this._childCount = 0;
|
||||
this._iconNeedsUpdate = true;
|
||||
this._boundsNeedUpdate = true;
|
||||
|
||||
this._bounds = new L.LatLngBounds();
|
||||
|
||||
if (a) {
|
||||
this._addChild(a);
|
||||
}
|
||||
if (b) {
|
||||
this._addChild(b);
|
||||
}
|
||||
},
|
||||
|
||||
//Recursively retrieve all child markers of this cluster
|
||||
getAllChildMarkers: function (storageArray, ignoreDraggedMarker) {
|
||||
storageArray = storageArray || [];
|
||||
|
||||
for (var i = this._childClusters.length - 1; i >= 0; i--) {
|
||||
this._childClusters[i].getAllChildMarkers(storageArray);
|
||||
}
|
||||
|
||||
for (var j = this._markers.length - 1; j >= 0; j--) {
|
||||
if (ignoreDraggedMarker && this._markers[j].__dragStart) {
|
||||
continue;
|
||||
}
|
||||
storageArray.push(this._markers[j]);
|
||||
}
|
||||
|
||||
return storageArray;
|
||||
},
|
||||
|
||||
//Returns the count of how many child markers we have
|
||||
getChildCount: function () {
|
||||
return this._childCount;
|
||||
},
|
||||
|
||||
//Zoom to the minimum of showing all of the child markers, or the extents of this cluster
|
||||
zoomToBounds: function (fitBoundsOptions) {
|
||||
var childClusters = this._childClusters.slice(),
|
||||
map = this._group._map,
|
||||
boundsZoom = map.getBoundsZoom(this._bounds),
|
||||
zoom = this._zoom + 1,
|
||||
mapZoom = map.getZoom(),
|
||||
i;
|
||||
|
||||
//calculate how far we need to zoom down to see all of the markers
|
||||
while (childClusters.length > 0 && boundsZoom > zoom) {
|
||||
zoom++;
|
||||
var newClusters = [];
|
||||
for (i = 0; i < childClusters.length; i++) {
|
||||
newClusters = newClusters.concat(childClusters[i]._childClusters);
|
||||
}
|
||||
childClusters = newClusters;
|
||||
}
|
||||
|
||||
if (boundsZoom > zoom) {
|
||||
this._group._map.setView(this._latlng, zoom);
|
||||
} else if (boundsZoom <= mapZoom) { //If fitBounds wouldn't zoom us down, zoom us down instead
|
||||
this._group._map.setView(this._latlng, mapZoom + 1);
|
||||
} else {
|
||||
this._group._map.fitBounds(this._bounds, fitBoundsOptions);
|
||||
}
|
||||
},
|
||||
|
||||
getBounds: function () {
|
||||
var bounds = new L.LatLngBounds();
|
||||
bounds.extend(this._bounds);
|
||||
return bounds;
|
||||
},
|
||||
|
||||
_updateIcon: function () {
|
||||
this._iconNeedsUpdate = true;
|
||||
if (this._icon) {
|
||||
this.setIcon(this);
|
||||
}
|
||||
},
|
||||
|
||||
//Cludge for Icon, we pretend to be an icon for performance
|
||||
createIcon: function () {
|
||||
if (this._iconNeedsUpdate) {
|
||||
this._iconObj = this._group.options.iconCreateFunction(this);
|
||||
this._iconNeedsUpdate = false;
|
||||
}
|
||||
return this._iconObj.createIcon();
|
||||
},
|
||||
createShadow: function () {
|
||||
return this._iconObj.createShadow();
|
||||
},
|
||||
|
||||
|
||||
_addChild: function (new1, isNotificationFromChild) {
|
||||
|
||||
this._iconNeedsUpdate = true;
|
||||
|
||||
this._boundsNeedUpdate = true;
|
||||
this._setClusterCenter(new1);
|
||||
|
||||
if (new1 instanceof L.MarkerCluster) {
|
||||
if (!isNotificationFromChild) {
|
||||
this._childClusters.push(new1);
|
||||
new1.__parent = this;
|
||||
}
|
||||
this._childCount += new1._childCount;
|
||||
} else {
|
||||
if (!isNotificationFromChild) {
|
||||
this._markers.push(new1);
|
||||
}
|
||||
this._childCount++;
|
||||
}
|
||||
|
||||
if (this.__parent) {
|
||||
this.__parent._addChild(new1, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Makes sure the cluster center is set. If not, uses the child center if it is a cluster, or the marker position.
|
||||
* @param child L.MarkerCluster|L.Marker that will be used as cluster center if not defined yet.
|
||||
* @private
|
||||
*/
|
||||
_setClusterCenter: function (child) {
|
||||
if (!this._cLatLng) {
|
||||
// when clustering, take position of the first point as the cluster center
|
||||
this._cLatLng = child._cLatLng || child._latlng;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Assigns impossible bounding values so that the next extend entirely determines the new bounds.
|
||||
* This method avoids having to trash the previous L.LatLngBounds object and to create a new one, which is much slower for this class.
|
||||
* As long as the bounds are not extended, most other methods would probably fail, as they would with bounds initialized but not extended.
|
||||
* @private
|
||||
*/
|
||||
_resetBounds: function () {
|
||||
var bounds = this._bounds;
|
||||
|
||||
if (bounds._southWest) {
|
||||
bounds._southWest.lat = Infinity;
|
||||
bounds._southWest.lng = Infinity;
|
||||
}
|
||||
if (bounds._northEast) {
|
||||
bounds._northEast.lat = -Infinity;
|
||||
bounds._northEast.lng = -Infinity;
|
||||
}
|
||||
},
|
||||
|
||||
_recalculateBounds: function () {
|
||||
var markers = this._markers,
|
||||
childClusters = this._childClusters,
|
||||
latSum = 0,
|
||||
lngSum = 0,
|
||||
totalCount = this._childCount,
|
||||
i, child, childLatLng, childCount;
|
||||
|
||||
// Case where all markers are removed from the map and we are left with just an empty _topClusterLevel.
|
||||
if (totalCount === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset rather than creating a new object, for performance.
|
||||
this._resetBounds();
|
||||
|
||||
// Child markers.
|
||||
for (i = 0; i < markers.length; i++) {
|
||||
childLatLng = markers[i]._latlng;
|
||||
|
||||
this._bounds.extend(childLatLng);
|
||||
|
||||
latSum += childLatLng.lat;
|
||||
lngSum += childLatLng.lng;
|
||||
}
|
||||
|
||||
// Child clusters.
|
||||
for (i = 0; i < childClusters.length; i++) {
|
||||
child = childClusters[i];
|
||||
|
||||
// Re-compute child bounds and weighted position first if necessary.
|
||||
if (child._boundsNeedUpdate) {
|
||||
child._recalculateBounds();
|
||||
}
|
||||
|
||||
this._bounds.extend(child._bounds);
|
||||
|
||||
childLatLng = child._wLatLng;
|
||||
childCount = child._childCount;
|
||||
|
||||
latSum += childLatLng.lat * childCount;
|
||||
lngSum += childLatLng.lng * childCount;
|
||||
}
|
||||
|
||||
this._latlng = this._wLatLng = new L.LatLng(latSum / totalCount, lngSum / totalCount);
|
||||
|
||||
// Reset dirty flag.
|
||||
this._boundsNeedUpdate = false;
|
||||
},
|
||||
|
||||
//Set our markers position as given and add it to the map
|
||||
_addToMap: function (startPos) {
|
||||
if (startPos) {
|
||||
this._backupLatlng = this._latlng;
|
||||
this.setLatLng(startPos);
|
||||
}
|
||||
this._group._featureGroup.addLayer(this);
|
||||
},
|
||||
|
||||
_recursivelyAnimateChildrenIn: function (bounds, center, maxZoom) {
|
||||
this._recursively(bounds, this._group._map.getMinZoom(), maxZoom - 1,
|
||||
function (c) {
|
||||
var markers = c._markers,
|
||||
i, m;
|
||||
for (i = markers.length - 1; i >= 0; i--) {
|
||||
m = markers[i];
|
||||
|
||||
//Only do it if the icon is still on the map
|
||||
if (m._icon) {
|
||||
m._setPos(center);
|
||||
m.clusterHide();
|
||||
}
|
||||
}
|
||||
},
|
||||
function (c) {
|
||||
var childClusters = c._childClusters,
|
||||
j, cm;
|
||||
for (j = childClusters.length - 1; j >= 0; j--) {
|
||||
cm = childClusters[j];
|
||||
if (cm._icon) {
|
||||
cm._setPos(center);
|
||||
cm.clusterHide();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
_recursivelyAnimateChildrenInAndAddSelfToMap: function (bounds, mapMinZoom, previousZoomLevel, newZoomLevel) {
|
||||
this._recursively(bounds, newZoomLevel, mapMinZoom,
|
||||
function (c) {
|
||||
c._recursivelyAnimateChildrenIn(bounds, c._group._map.latLngToLayerPoint(c.getLatLng()).round(), previousZoomLevel);
|
||||
|
||||
//TODO: depthToAnimateIn affects _isSingleParent, if there is a multizoom we may/may not be.
|
||||
//As a hack we only do a animation free zoom on a single level zoom, if someone does multiple levels then we always animate
|
||||
if (c._isSingleParent() && previousZoomLevel - 1 === newZoomLevel) {
|
||||
c.clusterShow();
|
||||
c._recursivelyRemoveChildrenFromMap(bounds, mapMinZoom, previousZoomLevel); //Immediately remove our children as we are replacing them. TODO previousBounds not bounds
|
||||
} else {
|
||||
c.clusterHide();
|
||||
}
|
||||
|
||||
c._addToMap();
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
_recursivelyBecomeVisible: function (bounds, zoomLevel) {
|
||||
this._recursively(bounds, this._group._map.getMinZoom(), zoomLevel, null, function (c) {
|
||||
c.clusterShow();
|
||||
});
|
||||
},
|
||||
|
||||
_recursivelyAddChildrenToMap: function (startPos, zoomLevel, bounds) {
|
||||
this._recursively(bounds, this._group._map.getMinZoom() - 1, zoomLevel,
|
||||
function (c) {
|
||||
if (zoomLevel === c._zoom) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Add our child markers at startPos (so they can be animated out)
|
||||
for (var i = c._markers.length - 1; i >= 0; i--) {
|
||||
var nm = c._markers[i];
|
||||
|
||||
if (!bounds.contains(nm._latlng)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (startPos) {
|
||||
nm._backupLatlng = nm.getLatLng();
|
||||
|
||||
nm.setLatLng(startPos);
|
||||
if (nm.clusterHide) {
|
||||
nm.clusterHide();
|
||||
}
|
||||
}
|
||||
|
||||
c._group._featureGroup.addLayer(nm);
|
||||
}
|
||||
},
|
||||
function (c) {
|
||||
c._addToMap(startPos);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
_recursivelyRestoreChildPositions: function (zoomLevel) {
|
||||
//Fix positions of child markers
|
||||
for (var i = this._markers.length - 1; i >= 0; i--) {
|
||||
var nm = this._markers[i];
|
||||
if (nm._backupLatlng) {
|
||||
nm.setLatLng(nm._backupLatlng);
|
||||
delete nm._backupLatlng;
|
||||
}
|
||||
}
|
||||
|
||||
if (zoomLevel - 1 === this._zoom) {
|
||||
//Reposition child clusters
|
||||
for (var j = this._childClusters.length - 1; j >= 0; j--) {
|
||||
this._childClusters[j]._restorePosition();
|
||||
}
|
||||
} else {
|
||||
for (var k = this._childClusters.length - 1; k >= 0; k--) {
|
||||
this._childClusters[k]._recursivelyRestoreChildPositions(zoomLevel);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_restorePosition: function () {
|
||||
if (this._backupLatlng) {
|
||||
this.setLatLng(this._backupLatlng);
|
||||
delete this._backupLatlng;
|
||||
}
|
||||
},
|
||||
|
||||
//exceptBounds: If set, don't remove any markers/clusters in it
|
||||
_recursivelyRemoveChildrenFromMap: function (previousBounds, mapMinZoom, zoomLevel, exceptBounds) {
|
||||
var m, i;
|
||||
this._recursively(previousBounds, mapMinZoom - 1, zoomLevel - 1,
|
||||
function (c) {
|
||||
//Remove markers at every level
|
||||
for (i = c._markers.length - 1; i >= 0; i--) {
|
||||
m = c._markers[i];
|
||||
if (!exceptBounds || !exceptBounds.contains(m._latlng)) {
|
||||
c._group._featureGroup.removeLayer(m);
|
||||
if (m.clusterShow) {
|
||||
m.clusterShow();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
function (c) {
|
||||
//Remove child clusters at just the bottom level
|
||||
for (i = c._childClusters.length - 1; i >= 0; i--) {
|
||||
m = c._childClusters[i];
|
||||
if (!exceptBounds || !exceptBounds.contains(m._latlng)) {
|
||||
c._group._featureGroup.removeLayer(m);
|
||||
if (m.clusterShow) {
|
||||
m.clusterShow();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
//Run the given functions recursively to this and child clusters
|
||||
// boundsToApplyTo: a L.LatLngBounds representing the bounds of what clusters to recurse in to
|
||||
// zoomLevelToStart: zoom level to start running functions (inclusive)
|
||||
// zoomLevelToStop: zoom level to stop running functions (inclusive)
|
||||
// runAtEveryLevel: function that takes an L.MarkerCluster as an argument that should be applied on every level
|
||||
// runAtBottomLevel: function that takes an L.MarkerCluster as an argument that should be applied at only the bottom level
|
||||
_recursively: function (boundsToApplyTo, zoomLevelToStart, zoomLevelToStop, runAtEveryLevel, runAtBottomLevel) {
|
||||
var childClusters = this._childClusters,
|
||||
zoom = this._zoom,
|
||||
i, c;
|
||||
|
||||
if (zoomLevelToStart <= zoom) {
|
||||
if (runAtEveryLevel) {
|
||||
runAtEveryLevel(this);
|
||||
}
|
||||
if (runAtBottomLevel && zoom === zoomLevelToStop) {
|
||||
runAtBottomLevel(this);
|
||||
}
|
||||
}
|
||||
|
||||
if (zoom < zoomLevelToStart || zoom < zoomLevelToStop) {
|
||||
for (i = childClusters.length - 1; i >= 0; i--) {
|
||||
c = childClusters[i];
|
||||
if (c._boundsNeedUpdate) {
|
||||
c._recalculateBounds();
|
||||
}
|
||||
if (boundsToApplyTo.intersects(c._bounds)) {
|
||||
c._recursively(boundsToApplyTo, zoomLevelToStart, zoomLevelToStop, runAtEveryLevel, runAtBottomLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
//Returns true if we are the parent of only one cluster and that cluster is the same as us
|
||||
_isSingleParent: function () {
|
||||
//Don't need to check this._markers as the rest won't work if there are any
|
||||
return this._childClusters.length > 0 && this._childClusters[0]._childCount === this._childCount;
|
||||
}
|
||||
});
|
||||
|
||||
@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Adds 1 public method to MCG and 1 to L.Marker to facilitate changing
|
||||
* markers' icon options and refreshing their icon and their parent clusters
|
||||
* accordingly (case where their iconCreateFunction uses data of childMarkers
|
||||
* to make up the cluster icon).
|
||||
*/
|
||||
|
||||
|
||||
L.MarkerClusterGroup.include({
|
||||
/**
|
||||
* Updates the icon of all clusters which are parents of the given marker(s).
|
||||
* In singleMarkerMode, also updates the given marker(s) icon.
|
||||
* @param layers L.MarkerClusterGroup|L.LayerGroup|Array(L.Marker)|Map(L.Marker)|
|
||||
* L.MarkerCluster|L.Marker (optional) list of markers (or single marker) whose parent
|
||||
* clusters need to be updated. If not provided, retrieves all child markers of this.
|
||||
* @returns {L.MarkerClusterGroup}
|
||||
*/
|
||||
refreshClusters: function (layers) {
|
||||
if (!layers) {
|
||||
layers = this._topClusterLevel.getAllChildMarkers();
|
||||
} else if (layers instanceof L.MarkerClusterGroup) {
|
||||
layers = layers._topClusterLevel.getAllChildMarkers();
|
||||
} else if (layers instanceof L.LayerGroup) {
|
||||
layers = layers._layers;
|
||||
} else if (layers instanceof L.MarkerCluster) {
|
||||
layers = layers.getAllChildMarkers();
|
||||
} else if (layers instanceof L.Marker) {
|
||||
layers = [layers];
|
||||
} // else: must be an Array(L.Marker)|Map(L.Marker)
|
||||
this._flagParentsIconsNeedUpdate(layers);
|
||||
this._refreshClustersIcons();
|
||||
|
||||
// In case of singleMarkerMode, also re-draw the markers.
|
||||
if (this.options.singleMarkerMode) {
|
||||
this._refreshSingleMarkerModeMarkers(layers);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Simply flags all parent clusters of the given markers as having a "dirty" icon.
|
||||
* @param layers Array(L.Marker)|Map(L.Marker) list of markers.
|
||||
* @private
|
||||
*/
|
||||
_flagParentsIconsNeedUpdate: function (layers) {
|
||||
var id, parent;
|
||||
|
||||
// Assumes layers is an Array or an Object whose prototype is non-enumerable.
|
||||
for (id in layers) {
|
||||
// Flag parent clusters' icon as "dirty", all the way up.
|
||||
// Dumb process that flags multiple times upper parents, but still
|
||||
// much more efficient than trying to be smart and make short lists,
|
||||
// at least in the case of a hierarchy following a power law:
|
||||
// http://jsperf.com/flag-nodes-in-power-hierarchy/2
|
||||
parent = layers[id].__parent;
|
||||
while (parent) {
|
||||
parent._iconNeedsUpdate = true;
|
||||
parent = parent.__parent;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Re-draws the icon of the supplied markers.
|
||||
* To be used in singleMarkerMode only.
|
||||
* @param layers Array(L.Marker)|Map(L.Marker) list of markers.
|
||||
* @private
|
||||
*/
|
||||
_refreshSingleMarkerModeMarkers: function (layers) {
|
||||
var id, layer;
|
||||
|
||||
for (id in layers) {
|
||||
layer = layers[id];
|
||||
|
||||
// Make sure we do not override markers that do not belong to THIS group.
|
||||
if (this.hasLayer(layer)) {
|
||||
// Need to re-create the icon first, then re-draw the marker.
|
||||
layer.setIcon(this._overrideMarkerIcon(layer));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
L.Marker.include({
|
||||
/**
|
||||
* Updates the given options in the marker's icon and refreshes the marker.
|
||||
* @param options map object of icon options.
|
||||
* @param directlyRefreshClusters boolean (optional) true to trigger
|
||||
* MCG.refreshClustersOf() right away with this single marker.
|
||||
* @returns {L.Marker}
|
||||
*/
|
||||
refreshIconOptions: function (options, directlyRefreshClusters) {
|
||||
var icon = this.options.icon;
|
||||
|
||||
L.setOptions(icon, options);
|
||||
|
||||
this.setIcon(icon);
|
||||
|
||||
// Shortcut to refresh the associated MCG clusters right away.
|
||||
// To be used when refreshing a single marker.
|
||||
// Otherwise, better use MCG.refreshClusters() once at the end with
|
||||
// the list of modified markers.
|
||||
if (directlyRefreshClusters && this.__parent) {
|
||||
this.__parent._group.refreshClusters(this);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
});
|
||||
@ -9,7 +9,6 @@ export var MarkerClusterGroup = L.MarkerClusterGroup = L.FeatureGroup.extend({
|
||||
iconCreateFunction: null,
|
||||
clusterPane: L.Marker.prototype.options.pane,
|
||||
|
||||
spiderfyOnEveryZoom: false,
|
||||
spiderfyOnMaxZoom: true,
|
||||
showCoverageOnHover: true,
|
||||
zoomToBoundsOnClick: true,
|
||||
@ -30,9 +29,6 @@ export var MarkerClusterGroup = L.MarkerClusterGroup = L.FeatureGroup.extend({
|
||||
// If you are adding individual markers set to true, if adding bulk markers leave false for massive performance gains.
|
||||
animateAddingMarkers: false,
|
||||
|
||||
// Make it possible to provide custom function to calculate spiderfy shape positions
|
||||
spiderfyShapePositions: null,
|
||||
|
||||
//Increase to increase the distance away that spiderfied markers appear from the center
|
||||
spiderfyDistanceMultiplier: 1,
|
||||
|
||||
@ -210,12 +206,6 @@ export var MarkerClusterGroup = L.MarkerClusterGroup = L.FeatureGroup.extend({
|
||||
var started = (new Date()).getTime();
|
||||
var process = L.bind(function () {
|
||||
var start = (new Date()).getTime();
|
||||
|
||||
// Make sure to unspiderfy before starting to add some layers
|
||||
if (this._map && this._unspiderfy) {
|
||||
this._unspiderfy();
|
||||
}
|
||||
|
||||
for (; offset < l; offset++) {
|
||||
if (chunked && offset % 200 === 0) {
|
||||
// every couple hundred markers, instrument the time elapsed since processing started:
|
||||
@ -548,20 +538,16 @@ export var MarkerClusterGroup = L.MarkerClusterGroup = L.FeatureGroup.extend({
|
||||
//Zoom down to show the given layer (spiderfying if necessary) then calls the callback
|
||||
zoomToShowLayer: function (layer, callback) {
|
||||
|
||||
var map = this._map;
|
||||
|
||||
if (typeof callback !== 'function') {
|
||||
callback = function () {};
|
||||
}
|
||||
|
||||
var showMarker = function () {
|
||||
// Assumes that map.hasLayer checks for direct appearance on map, not recursively calling
|
||||
// hasLayer on Layer Groups that are on map (typically not calling this MarkerClusterGroup.hasLayer, which would always return true)
|
||||
if ((map.hasLayer(layer) || map.hasLayer(layer.__parent)) && !this._inZoomAnimation) {
|
||||
if ((layer._icon || layer.__parent._icon) && !this._inZoomAnimation) {
|
||||
this._map.off('moveend', showMarker, this);
|
||||
this.off('animationend', showMarker, this);
|
||||
|
||||
if (map.hasLayer(layer)) {
|
||||
if (layer._icon) {
|
||||
callback();
|
||||
} else if (layer.__parent._icon) {
|
||||
this.once('spiderfied', callback, this);
|
||||
@ -830,19 +816,18 @@ export var MarkerClusterGroup = L.MarkerClusterGroup = L.FeatureGroup.extend({
|
||||
c += 'large';
|
||||
}
|
||||
|
||||
return new L.DivIcon({ html: '<div><span>' + childCount + ' <span aria-label="markers"></span>' + '</span></div>', className: 'marker-cluster' + c, iconSize: new L.Point(40, 40) });
|
||||
return new L.DivIcon({ html: '<div><span>' + childCount + '</span></div>', className: 'marker-cluster' + c, iconSize: new L.Point(40, 40) });
|
||||
},
|
||||
|
||||
_bindEvents: function () {
|
||||
var map = this._map,
|
||||
spiderfyOnMaxZoom = this.options.spiderfyOnMaxZoom,
|
||||
showCoverageOnHover = this.options.showCoverageOnHover,
|
||||
zoomToBoundsOnClick = this.options.zoomToBoundsOnClick,
|
||||
spiderfyOnEveryZoom = this.options.spiderfyOnEveryZoom;
|
||||
zoomToBoundsOnClick = this.options.zoomToBoundsOnClick;
|
||||
|
||||
//Zoom on cluster click or spiderfy if we are at the lowest level
|
||||
if (spiderfyOnMaxZoom || zoomToBoundsOnClick || spiderfyOnEveryZoom) {
|
||||
this.on('clusterclick clusterkeypress', this._zoomOrSpiderfy, this);
|
||||
if (spiderfyOnMaxZoom || zoomToBoundsOnClick) {
|
||||
this.on('clusterclick', this._zoomOrSpiderfy, this);
|
||||
}
|
||||
|
||||
//Show convex hull (boundary) polygon on mouse over
|
||||
@ -857,10 +842,6 @@ export var MarkerClusterGroup = L.MarkerClusterGroup = L.FeatureGroup.extend({
|
||||
var cluster = e.layer,
|
||||
bottomCluster = cluster;
|
||||
|
||||
if (e.type === 'clusterkeypress' && e.originalEvent && e.originalEvent.keyCode !== 13 || e.originalEvent.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (bottomCluster._childClusters.length === 1) {
|
||||
bottomCluster = bottomCluster._childClusters[0];
|
||||
}
|
||||
@ -875,10 +856,6 @@ export var MarkerClusterGroup = L.MarkerClusterGroup = L.FeatureGroup.extend({
|
||||
cluster.zoomToBounds();
|
||||
}
|
||||
|
||||
if (this.options.spiderfyOnEveryZoom) {
|
||||
cluster.spiderfy();
|
||||
}
|
||||
|
||||
// Focus the map again for keyboard users.
|
||||
if (e.originalEvent && e.originalEvent.keyCode === 13) {
|
||||
this._map._container.focus();
|
||||
@ -910,11 +887,10 @@ export var MarkerClusterGroup = L.MarkerClusterGroup = L.FeatureGroup.extend({
|
||||
var spiderfyOnMaxZoom = this.options.spiderfyOnMaxZoom,
|
||||
showCoverageOnHover = this.options.showCoverageOnHover,
|
||||
zoomToBoundsOnClick = this.options.zoomToBoundsOnClick,
|
||||
spiderfyOnEveryZoom = this.options.spiderfyOnEveryZoom,
|
||||
map = this._map;
|
||||
|
||||
if (spiderfyOnMaxZoom || zoomToBoundsOnClick || spiderfyOnEveryZoom) {
|
||||
this.off('clusterclick clusterkeypress', this._zoomOrSpiderfy, this);
|
||||
if (spiderfyOnMaxZoom || zoomToBoundsOnClick) {
|
||||
this.off('clusterclick', this._zoomOrSpiderfy, this);
|
||||
}
|
||||
if (showCoverageOnHover) {
|
||||
this.off('clustermouseover', this._showCoverage, this);
|
||||
@ -968,13 +944,6 @@ export var MarkerClusterGroup = L.MarkerClusterGroup = L.FeatureGroup.extend({
|
||||
this._gridUnclustered = {};
|
||||
|
||||
//Set up DistanceGrids for each zoom
|
||||
|
||||
if (!isFinite(maxZoom) ) {
|
||||
throw "Map has no maxZoom specified";
|
||||
}
|
||||
if (!isFinite(minZoom)) {
|
||||
throw "Map has no minZoom specified";
|
||||
}
|
||||
for (var zoom = maxZoom; zoom >= minZoom; zoom--) {
|
||||
this._gridClusters[zoom] = new L.DistanceGrid(radiusFn(zoom));
|
||||
this._gridUnclustered[zoom] = new L.DistanceGrid(radiusFn(zoom));
|
||||
22
static/Leaflet.markercluster-1.4.1/src/MarkerOpacity.js
Normal file
22
static/Leaflet.markercluster-1.4.1/src/MarkerOpacity.js
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Extends L.Marker to include two extra methods: clusterHide and clusterShow.
|
||||
*
|
||||
* They work as setOpacity(0) and setOpacity(1) respectively, but
|
||||
* don't overwrite the options.opacity
|
||||
*
|
||||
*/
|
||||
|
||||
L.Marker.include({
|
||||
clusterHide: function () {
|
||||
var backup = this.options.opacity;
|
||||
this.setOpacity(0);
|
||||
this.options.opacity = backup;
|
||||
return this;
|
||||
},
|
||||
|
||||
clusterShow: function () {
|
||||
return this.setOpacity(this.options.opacity);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
8
static/Leaflet.markercluster-1.4.1/src/index.js
Normal file
8
static/Leaflet.markercluster-1.4.1/src/index.js
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
export { MarkerClusterGroup } from './MarkerClusterGroup.js';
|
||||
export { MarkerCluster } from './MarkerCluster.js';
|
||||
import {} from './MarkerOpacity.js';
|
||||
import {} from './DistanceGrid.js';
|
||||
import {} from './MarkerCluster.QuickHull.js';
|
||||
import {} from './MarkerCluster.Spiderfier.js';
|
||||
import {} from './MarkerClusterGroup.Refresh.js';
|
||||
@ -1,60 +0,0 @@
|
||||
.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;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user