QGIS- Leaflet(自定义 OnClick 事件)
QGIS- Leaflet (Customizing OnClick event)
使用 Leaflet 网络地图单击多边形时,我很难添加代码来自定义操作/事件。
最终目标不仅是显示那个小弹出窗口,还有一个信息滑块 HTML 代码,由我自己添加。
目前我怀疑这可能是添加或更改某些内容但不确定的地方:
function pop_LotDrawing_2(feature, layer) {
layer.on({
mouseout: function(e) {
for (i in e.target._eventParents) {
e.target._eventParents[i].resetStyle(e.target);
}
},
mouseover: highlightFeature,
});
var popupContent = '<table>\
<tr>\
<td colspan="2"><strong>Lot</strong><br />' + (feature.properties['Lot'] !== null ? Autolinker.link(String(feature.properties['Lot'])) : '') + '</td>\
</tr>\
<tr>\
<th scope="row">Design</th>\
<td>' + (feature.properties['Design'] !== null ? Autolinker.link(String(feature.properties['Design'])) : '') + '</td>\
</tr>\
<tr>\
<th scope="row">Area (sqm)</th>\
<td>' + (feature.properties['Area (sqm)'] !== null ? Autolinker.link(String(feature.properties['Area (sqm)'])) : '') + '</td>\
</tr>\
</table>';
layer.bindPopup(popupContent, {maxHeight: 400});
最终,我想实现类似这个网站的东西:http://novieveshki.ru/map/
enter image description here
执行此操作的一种方法可能是创建一个包含所有多边形要素的数组。您可以将所有多边形添加到此数组,然后遍历数组中的元素以附加事件处理程序并将其添加到地图。您可以使用 polygon.on()
.
附加事件处理程序
这是我在地图上添加圆形和三角形的示例。我给这两个形状一个描述。然后我将它们添加到 polygons
数组,一旦它们被初始化,我循环遍历数组以附加事件处理程序并将它们添加到地图。点击 "Run Snippet" 试一试(在全屏视图下可能更容易看到)。
您可以根据需要设置侧边栏的样式,并根据需要修改事件处理程序 and/or CSS 以创建动画效果。
希望这能让你走上正轨。
let map = new L.Map('map');
// polygons array to hold all polygons
let polygons = [];
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://openstreetmap.org">OpenStreetMap</a> contributors',
maxZoom: 18
}).addTo(map);
// Location to center the map
let london = new L.LatLng(51.505, -0.09);
map.setView(london, 13);
// Create a circle around a point
let circleLocation = new L.LatLng(51.508, -0.11),
circleOptions = {
color: 'red',
fillColor: '#f03',
fillOpacity: 0.5
};
let circle = new L.Circle(circleLocation, 500, circleOptions);
// This is what will be displayed in the sidebar on click
circle.desc = "You clicked a circle!";
// Add the circle to the polygons array
polygons.push(circle);
// Create a triangle with vertices below
let p1 = new L.LatLng(51.509, -0.08),
p2 = new L.LatLng(51.503, -0.06),
p3 = new L.LatLng(51.51, -0.047),
polygonPoints = [p1, p2, p3];
let polygon = new L.Polygon(polygonPoints);
// This is what will be displayed in the sidebar on click
polygon.desc = "You clicked a triangle!";
// Add the triangle to the polygons array
polygons.push(polygon);
// Loop over all elements in the polygons array and attach the event handler and add the element to the map
polygons.forEach(function (i) {
i.on("click", changeSidebar);
map.addLayer(i);
});
// Basic event handler that just changes the sidebar innerHTML to the element's `desc` property defined above.
function changeSidebar (event) {
sidebar.innerHTML = event.target.desc;
}
#sidebar {
width: 30%;
height: 500px;
position: absolute;
right: 0;
background-color: #c3c3c3;
}
#map {
width: 70%;
height: 500px;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/leaflet.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/leaflet.js"></script>
<div id="sidebar"></div>
<div id="map"></div>
其实后来我也发现我们可以插入并传递一个函数而不是传递一个popupContent(html)。
在哪里更改它:
layer.bindPopup(popupContent, {maxHeight: 400});
代替原始变量作为html插入:
var popupContent = '<table>\
<tr>\
<td colspan="2"><strong>Lot</strong><br />' + (feature.properties['Lot'] !== null ? Autolinker.link(String(feature.properties['Lot'])) : '') + '</td>\
</tr>\
<tr>\
<th scope="row">Design</th>\
<td>' + (feature.properties['Design'] !== null ? Autolinker.link(String(feature.properties['Design'])) : '') + '</td>\
</tr>\
<tr>\
<th scope="row">Area (sqm)</th>\
<td>' + (feature.properties['Area (sqm)'] !== null ? Autolinker.link(String(feature.properties['Area (sqm)'])) : '') + '</td>\
</tr>\
</table>';
我们可以换成一个改变前端效果的函数:
例如
function popup(){
//do whatever here
}
layer.bindPopup(popup, {maxHeight: 400});
想法也受到答案及其文档的启发:https://leafletjs.com/reference-1.5.0.html#popup
设置内容
(html内容)
设置弹出窗口的 HTML 内容。如果一个函数被传递,源层将被传递给该函数。该函数应该return一个字符串或HTML要在弹出窗口中使用的元素。
希望大家喜欢这个:)
使用 Leaflet 网络地图单击多边形时,我很难添加代码来自定义操作/事件。
最终目标不仅是显示那个小弹出窗口,还有一个信息滑块 HTML 代码,由我自己添加。 目前我怀疑这可能是添加或更改某些内容但不确定的地方:
function pop_LotDrawing_2(feature, layer) {
layer.on({
mouseout: function(e) {
for (i in e.target._eventParents) {
e.target._eventParents[i].resetStyle(e.target);
}
},
mouseover: highlightFeature,
});
var popupContent = '<table>\
<tr>\
<td colspan="2"><strong>Lot</strong><br />' + (feature.properties['Lot'] !== null ? Autolinker.link(String(feature.properties['Lot'])) : '') + '</td>\
</tr>\
<tr>\
<th scope="row">Design</th>\
<td>' + (feature.properties['Design'] !== null ? Autolinker.link(String(feature.properties['Design'])) : '') + '</td>\
</tr>\
<tr>\
<th scope="row">Area (sqm)</th>\
<td>' + (feature.properties['Area (sqm)'] !== null ? Autolinker.link(String(feature.properties['Area (sqm)'])) : '') + '</td>\
</tr>\
</table>';
layer.bindPopup(popupContent, {maxHeight: 400});
最终,我想实现类似这个网站的东西:http://novieveshki.ru/map/
enter image description here
执行此操作的一种方法可能是创建一个包含所有多边形要素的数组。您可以将所有多边形添加到此数组,然后遍历数组中的元素以附加事件处理程序并将其添加到地图。您可以使用 polygon.on()
.
这是我在地图上添加圆形和三角形的示例。我给这两个形状一个描述。然后我将它们添加到 polygons
数组,一旦它们被初始化,我循环遍历数组以附加事件处理程序并将它们添加到地图。点击 "Run Snippet" 试一试(在全屏视图下可能更容易看到)。
您可以根据需要设置侧边栏的样式,并根据需要修改事件处理程序 and/or CSS 以创建动画效果。
希望这能让你走上正轨。
let map = new L.Map('map');
// polygons array to hold all polygons
let polygons = [];
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://openstreetmap.org">OpenStreetMap</a> contributors',
maxZoom: 18
}).addTo(map);
// Location to center the map
let london = new L.LatLng(51.505, -0.09);
map.setView(london, 13);
// Create a circle around a point
let circleLocation = new L.LatLng(51.508, -0.11),
circleOptions = {
color: 'red',
fillColor: '#f03',
fillOpacity: 0.5
};
let circle = new L.Circle(circleLocation, 500, circleOptions);
// This is what will be displayed in the sidebar on click
circle.desc = "You clicked a circle!";
// Add the circle to the polygons array
polygons.push(circle);
// Create a triangle with vertices below
let p1 = new L.LatLng(51.509, -0.08),
p2 = new L.LatLng(51.503, -0.06),
p3 = new L.LatLng(51.51, -0.047),
polygonPoints = [p1, p2, p3];
let polygon = new L.Polygon(polygonPoints);
// This is what will be displayed in the sidebar on click
polygon.desc = "You clicked a triangle!";
// Add the triangle to the polygons array
polygons.push(polygon);
// Loop over all elements in the polygons array and attach the event handler and add the element to the map
polygons.forEach(function (i) {
i.on("click", changeSidebar);
map.addLayer(i);
});
// Basic event handler that just changes the sidebar innerHTML to the element's `desc` property defined above.
function changeSidebar (event) {
sidebar.innerHTML = event.target.desc;
}
#sidebar {
width: 30%;
height: 500px;
position: absolute;
right: 0;
background-color: #c3c3c3;
}
#map {
width: 70%;
height: 500px;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/leaflet.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/leaflet.js"></script>
<div id="sidebar"></div>
<div id="map"></div>
其实后来我也发现我们可以插入并传递一个函数而不是传递一个popupContent(html)。
在哪里更改它:
layer.bindPopup(popupContent, {maxHeight: 400});
代替原始变量作为html插入:
var popupContent = '<table>\
<tr>\
<td colspan="2"><strong>Lot</strong><br />' + (feature.properties['Lot'] !== null ? Autolinker.link(String(feature.properties['Lot'])) : '') + '</td>\
</tr>\
<tr>\
<th scope="row">Design</th>\
<td>' + (feature.properties['Design'] !== null ? Autolinker.link(String(feature.properties['Design'])) : '') + '</td>\
</tr>\
<tr>\
<th scope="row">Area (sqm)</th>\
<td>' + (feature.properties['Area (sqm)'] !== null ? Autolinker.link(String(feature.properties['Area (sqm)'])) : '') + '</td>\
</tr>\
</table>';
我们可以换成一个改变前端效果的函数: 例如
function popup(){
//do whatever here
}
layer.bindPopup(popup, {maxHeight: 400});
想法也受到答案及其文档的启发:https://leafletjs.com/reference-1.5.0.html#popup
设置内容
(html内容) 设置弹出窗口的 HTML 内容。如果一个函数被传递,源层将被传递给该函数。该函数应该return一个字符串或HTML要在弹出窗口中使用的元素。
希望大家喜欢这个:)