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: '&copy; <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要在弹出窗口中使用的元素。

希望大家喜欢这个:)