- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有 2 个插件想协同工作:Leaflet Tag Filter Button由 maydemirx 和 MarkerCluster.LayerSupport 制作由 ghybs 制作(顺便说一句,很棒的人和插件)。我想要发生的是,当我单击标签过滤器按钮上的过滤器时,我希望标记簇根据新过滤器 ( like this ) 进行更新。因此,5 个点的簇变为 2 个,或者 10 个点的簇变为 1 个标记。我成功地将 layerSupported 集群添加到我的 map 中,所以那里没有问题。不过,我不确定如何将受支持的集群与标签过滤器按钮集成,因为它们是两个独立的实体。
传单标签过滤器按钮支持 update() method and an enablePruneCluster method ,这两者听起来都可以用来实现我正在寻找的东西。然而,当我将它们单独应用于过滤器按钮时,它们不起作用。我错误地应用了过滤器按钮方法,错误地创建了 layerSupported 集群,和/或插件没有相互兼容。
这是我生成图层支持的标记集群组的代码:
var clusters = L.markerClusterGroup.layerSupport({maxClusterRadius:75}),
group1 = L.layerGroup();
var getjson = $.getJSON("map-v2.geojson",function(data){
var bev = L.geoJson(data,{
pointToLayer: function(feature,latlng){
var marker = L.marker(latlng, { tags: feature.properties.Genres.concat(feature.properties.Creator)});
marker.bindPopup('<p align=center>' + '<strong>Title: </strong>' + feature.properties.Title + '<br/><a href="' + feature.properties.Image_Bank_URL + '" target="_blank"><img src="' + feature.properties.Thumbnail_URL + '"/></a><br/>' + '<strong>Date: </strong>' + feature.properties.Date + '<br/>' + '<strong>Creator: </strong>' + feature.properties.Creator, {minWidth : 250});
return marker;
}
});
bev.addTo(group1);
clusters.addLayer(group1);
map.addLayer(clusters);
});
// Here is where I add the layer supported clusters to the map.
clusters.checkIn(group1);
clusters.addTo(map);
这是我生成标签过滤器按钮的部分:
// Here is the code block for the Tag Filter Button. I start by accessing a tags file that has the data that I use for filter options. I should note that the genres.addToRelated is not working (it is supposed to link the 2 buttons together to work in conjunction with each other).
$.getJSON('tags.json', function(data) {
var genres = L.control.tagFilterButton({
data: data.genres,
filterOnEveryClick: true,
icon: '<i class="fas fa-tags"></i>',
}).addTo(map);
var creators = L.control.tagFilterButton({
data: data.creators,
filterOnEveryClick: true,
icon: '<i class="fas fa-user-edit"></i>',
}).addTo(map);
jQuery('.easy-button-button').click(function() {
target = jQuery('.easy-button-button').not(this);
target.parent().find('.tag-filter-tags-container').css({
'display' : 'none',
});
});
genres.addToRelated(creators);
genres.update(clusters);
genres.enablePruneCluster(clusters);
});
如果你想看到这一切,这里是一个 plunker of the code .
最佳答案
奇怪的是,Leaflet 标签过滤器按钮插件和/或最新的 Leaflet 版本看起来有一些错误/监听器可能会在 Web 控制台打开时暂停脚本(因此浏览器)。
修复这些错误后,“addToReleated
”方法仍然存在错误。由于我不知道它应该做什么,所以我暂时忽略它,让你可能与插件作者一起修复它。
至于与 Leaflet.markercluster 的整合插件,它看起来真的不像第一个插件应该支持它。 PruneCluster插件(标签过滤器按钮的 enablePruneCluster
方法适用)与 Leaflet.markercluster 的工作方式非常不同。
通过查看 Tag Filter Button 的源代码,您似乎可以通过改编 enablePruneCluster
来实现它。默认_prepareLayerSources
中调用registerCustomSource
的代码和隐藏
函数.这个想法是避免直接使用 _map
,而是使用 MCG。
由于您可以直接在 hide
函数中处理对 MCG addLayers
和 removeLayers
的调用,因此实际上不需要 Leaflet.MarkerCluster .LayerSupport 插件。
这里是一个快速但肮脏的实现,称为“enableMCG
”:
////////////////////////////////////////////////
// Quick and dirty implementation of enableMCG
////////////////////////////////////////////////
L.Control.TagFilterButton.include({
// Goal: read from MCG instead of from _map
enableMCG: function(mcgInstance) {
this.registerCustomSource({
name: 'mcg',
source: {
mcg: mcgInstance,
hide: function(layerSource) {
var releatedLayers = [];
for (
var r = 0; r < this._releatedFilterButtons.length; r++
) {
releatedLayers = releatedLayers.concat(
this._releatedFilterButtons[r].getInvisibles()
);
}
var toBeRemovedFromInvisibles = [],
i,
toAdd = [];
for (var i = 0; i < this._invisibles.length; i++) {
if (releatedLayers.indexOf(this._invisibles[i]) == -1) {
for (
var j = 0; j < this._invisibles[i].options.tags.length; j++
) {
if (
this._selectedTags.length == 0 ||
this._selectedTags.indexOf(
this._invisibles[i].options.tags[j]
) !== -1
) {
//this._map.addLayer(this._invisibles[i]);
toAdd.push(this._invisibles[i]);
toBeRemovedFromInvisibles.push(i);
break;
}
}
}
}
// Batch add into MCG
layerSource.mcg.addLayers(toAdd);
while (toBeRemovedFromInvisibles.length > 0) {
this._invisibles.splice(
toBeRemovedFromInvisibles.pop(),
1
);
}
var removedMarkers = [];
var totalCount = 0;
if (this._selectedTags.length > 0) {
//this._map.eachLayer(
layerSource.mcg.eachLayer(
function(layer) {
if (
layer &&
layer.options &&
layer.options.tags
) {
totalCount++;
if (releatedLayers.indexOf(layer) == -1) {
var found = false;
for (
var i = 0; i < layer.options.tags.length; i++
) {
found =
this._selectedTags.indexOf(
layer.options.tags[i]
) !== -1;
if (found) {
break;
}
}
if (!found) {
removedMarkers.push(layer);
}
}
}
}.bind(this)
);
for (i = 0; i < removedMarkers.length; i++) {
//this._map.removeLayer(removedMarkers[i]);
this._invisibles.push(removedMarkers[i]);
}
// Batch remove from MCG
layerSource.mcg.removeLayers(removedMarkers);
}
return totalCount - removedMarkers.length;
},
},
});
this.layerSources.currentSource = this.layerSources.sources[
'mcg'
];
},
});
////////////////////////////////////////////////
// Fix for TagFilterButton
////////////////////////////////////////////////
L.Control.TagFilterButton.include({
_prepareLayerSources: function() {
this.layerSources = new Object();
this.layerSources['sources'] = new Object();
this.registerCustomSource({
name: 'default',
source: {
hide: function() {
var releatedLayers = [];
for (var r = 0; r < this._releatedFilterButtons.length; r++) {
releatedLayers = releatedLayers.concat(
this._releatedFilterButtons[r].getInvisibles()
);
}
var toBeRemovedFromInvisibles = [],
i;
// "Fix": add var
for (var i = 0; i < this._invisibles.length; i++) {
if (releatedLayers.indexOf(this._invisibles[i]) == -1) {
// "Fix": add var
for (var j = 0; j < this._invisibles[i].options.tags.length; j++) {
if (
this._selectedTags.length == 0 ||
this._selectedTags.indexOf(
this._invisibles[i].options.tags[j]
) !== -1
) {
this._map.addLayer(this._invisibles[i]);
toBeRemovedFromInvisibles.push(i);
break;
}
}
}
}
while (toBeRemovedFromInvisibles.length > 0) {
this._invisibles.splice(toBeRemovedFromInvisibles.pop(), 1);
}
var removedMarkers = [];
var totalCount = 0;
if (this._selectedTags.length > 0) {
this._map.eachLayer(
function(layer) {
if (layer && layer.options && layer.options.tags) {
totalCount++;
if (releatedLayers.indexOf(layer) == -1) {
var found = false;
for (var i = 0; i < layer.options.tags.length; i++) {
found =
this._selectedTags.indexOf(layer.options.tags[i]) !==
-1;
if (found) {
break;
}
}
if (!found) {
removedMarkers.push(layer);
}
}
}
}.bind(this)
);
for (i = 0; i < removedMarkers.length; i++) {
this._map.removeLayer(removedMarkers[i]);
this._invisibles.push(removedMarkers[i]);
}
}
return totalCount - removedMarkers.length;
},
},
});
this.layerSources.currentSource = this.layerSources.sources['default'];
},
});
////////////////////////////////////////////////
// Adapted from TagFilterButton demo
// https://github.com/maydemirx/leaflet-tag-filter-button/blob/0.0.4/docs/assets/js/main.js
////////////////////////////////////////////////
var osmUrl = 'http://{s}.tile.osm.org/{z}/{x}/{y}.png',
osmAttrib =
'© <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors',
osm = L.tileLayer(osmUrl, {
maxZoom: 18,
attribution: osmAttrib,
});
// initialize the map on the "map" div with a given center and zoom
var releatedUsageMap = L.map('releated-usage-map')
.setView([50.5, 30.5], 12)
.addLayer(osm);
var mcg = L.markerClusterGroup().addTo(releatedUsageMap);
L.marker([50.521, 30.52], {
tags: ['tomato', 'active']
})
.bindPopup('tomato, active')
.addTo(mcg);
L.marker([50.487, 30.54], {
tags: ['tomato', 'ended']
})
.bindPopup('tomato, ended')
.addTo(mcg);
L.marker([50.533, 30.5], {
tags: ['tomato', 'ended']
})
.bindPopup('tomato, ended')
.addTo(mcg);
L.marker([50.54, 30.48], {
tags: ['strawberry', 'active']
})
.bindPopup('strawberry, active')
.addTo(mcg);
L.marker([50.505, 30.46], {
tags: ['strawberry', 'ended']
})
.bindPopup('strawberry, ended')
.addTo(mcg);
L.marker([50.5, 30.43], {
tags: ['cherry', 'active']
})
.bindPopup('cherry, active')
.addTo(mcg);
L.marker([50.48, 30.5], {
tags: ['cherry', 'ended']
})
.bindPopup('cherry, ended')
.addTo(mcg);
var statusFilterButton = L.control
.tagFilterButton({
data: ['active', 'ended'],
filterOnEveryClick: true,
icon: '<span>suitcase</span>',
})
.addTo(releatedUsageMap);
// Enable MCG integration
statusFilterButton.enableMCG(mcg);
/*var foodFilterButton = L.control
.tagFilterButton({
data: ['tomato', 'cherry', 'strawberry'],
filterOnEveryClick: true,
icon: '<i class="fa fa-pagelines"></i>',
})
.addTo(releatedUsageMap);
foodFilterButton.addToReleated(statusFilterButton);*/
html,
body,
#releated-usage-map {
height: 100%;
margin: 0;
}
<!-- Leaflet -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.3/leaflet.css" media="screen, print" rel="stylesheet" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="">
<script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.3/leaflet.js' integrity="sha512-tAGcCfR4Sc5ZP5ZoVz0quoZDYX5aCtEm/eu1KhSLj2c9eFrylXZknQYmxUssFaVJKvvc0dJQixhGjG2yXWiV9Q==" crossorigin=""></script>
<!-- MarkerCluster Plugin -->
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.3.0/MarkerCluster.css" />
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.3.0/MarkerCluster.Default.css" />
<script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.3.0/leaflet.markercluster.js'></script>
<!-- EasyButton Plugin (compatibility for tagFilterButton) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet-easybutton@2/src/easy-button.css">
<script src="https://cdn.jsdelivr.net/npm/leaflet-easybutton@2/src/easy-button.js"></script>
<!-- tagFilterButton Plugin -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet-tag-filter-button@0.0.4/src/leaflet-tag-filter-button.css">
<script src="https://cdn.jsdelivr.net/npm/leaflet-tag-filter-button@0.0.4/src/leaflet-tag-filter-button.js"></script>
<div id="releated-usage-map"></div>
关于javascript - Leaflet Tag Filter Button and MarkerCluster.LayerSupport Plugins - 集成以在单击时更新集群,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51770138/
SQLite、Content provider 和 Shared Preference 之间的所有已知区别。 但我想知道什么时候需要根据情况使用 SQLite 或 Content Provider 或
警告:我正在使用一个我无法完全控制的后端,所以我正在努力解决 Backbone 中的一些注意事项,这些注意事项可能在其他地方更好地解决......不幸的是,我别无选择,只能在这里处理它们! 所以,我的
我一整天都在挣扎。我的预输入搜索表达式与远程 json 数据完美配合。但是当我尝试使用相同的 json 数据作为预取数据时,建议为空。点击第一个标志后,我收到预定义消息“无法找到任何内容...”,结果
我正在制作一个模拟 NHL 选秀彩票的程序,其中屏幕右侧应该有一个 JTextField,并且在左侧绘制弹跳的选秀球。我创建了一个名为 Ball 的类,它实现了 Runnable,并在我的主 Draf
这个问题已经有答案了: How can I calculate a time span in Java and format the output? (18 个回答) 已关闭 9 年前。 这是我的代码
我有一个 ASP.NET Web API 应用程序在我的本地 IIS 实例上运行。 Web 应用程序配置有 CORS。我调用的 Web API 方法类似于: [POST("/API/{foo}/{ba
我将用户输入的时间和日期作为: DatePicker dp = (DatePicker) findViewById(R.id.datePicker); TimePicker tp = (TimePic
放宽“邻居”的标准是否足够,或者是否有其他标准行动可以采取? 最佳答案 如果所有相邻解决方案都是 Tabu,则听起来您的 Tabu 列表的大小太长或您的释放策略太严格。一个好的 Tabu 列表长度是
我正在阅读来自 cppreference 的代码示例: #include #include #include #include template void print_queue(T& q)
我快疯了,我试图理解工具提示的行为,但没有成功。 1. 第一个问题是当我尝试通过插件(按钮 1)在点击事件中使用它时 -> 如果您转到 Fiddle,您会在“内容”内看到该函数' 每次点击都会调用该属
我在功能组件中有以下代码: const [ folder, setFolder ] = useState([]); const folderData = useContext(FolderContex
我在使用预签名网址和 AFNetworking 3.0 从 S3 获取图像时遇到问题。我可以使用 NSMutableURLRequest 和 NSURLSession 获取图像,但是当我使用 AFHT
我正在使用 Oracle ojdbc 12 和 Java 8 处理 Oracle UCP 管理器的问题。当 UCP 池启动失败时,我希望关闭它创建的连接。 当池初始化期间遇到 ORA-02391:超过
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve
引用这个plunker: https://plnkr.co/edit/GWsbdDWVvBYNMqyxzlLY?p=preview 我在 styles.css 文件和 src/app.ts 文件中指定
为什么我的条形这么细?我尝试将宽度设置为 1,它们变得非常厚。我不知道还能尝试什么。默认厚度为 0.8,这是应该的样子吗? import matplotlib.pyplot as plt import
当我编写时,查询按预期执行: SELECT id, day2.count - day1.count AS diff FROM day1 NATURAL JOIN day2; 但我真正想要的是右连接。当
我有以下时间数据: 0 08/01/16 13:07:46,335437 1 18/02/16 08:40:40,565575 2 14/01/16 22:2
一些背景知识 -我的 NodeJS 服务器在端口 3001 上运行,我的 React 应用程序在端口 3000 上运行。我在 React 应用程序 package.json 中设置了一个代理来代理对端
我面临着一个愚蠢的问题。我试图在我的 Angular 应用程序中延迟加载我的图像,我已经尝试过这个2: 但是他们都设置了 src attr 而不是 data-src,我在这里遗漏了什么吗?保留 d
我是一名优秀的程序员,十分优秀!