我有一个带有多个多边形的传单地图,用于显示状态下的停电情况。每个镇都可以悬停或单击,从而触发信息在角落的窗格中更新或显示在弹出窗口中。
当用户单击城镇或将鼠标悬停在城镇上时,显示的数据应符合以下条件: 城镇,受影响的城镇百分比和受影响的会员人数
问题 是,我没有任何数据值显示在我的popUpClick函数中(其中包括镇名,该镇名是弹出窗口的,因为它是数组的属性) 。如您从此screenshot所看到的,数据正在为我的表和info.update函数(infobox)工作,但弹出窗口中没有值。
该多边形还可以用作choropleth(完全起作用,不是问题)。
PHP将动态数据重新分配给以以下形式开始的json文件:
var serviceTowns = {features:[{type:"Feature",properties:
{percentOut:0, timeOut:"", estRestTime:"", cause:"", metersOut:0, backon:"",
ShapeSTLength:47738.66356312807, ShapeSTArea:103650697.18991089, CNTY:5,
FIPS6:5085, townMC:"Wheelock", OBJECTID:52, town:"WHEELOCK"}, geometry:
{coordinates:[[[-72.066382,44.623496],[-72.073445,44.614341],
[-72.090108,44.592577],[-72.095247,44.585794],[-72.107467,44.589859],
[-72.116114,44.592813],[-72.124595,44.595557],[-72.1943,44.62068],
[-72.202489,44.624105],[-72.207124,44.616742],[-72.228896,44.587984],
[-72.237341,44.576588],[-72.223447,44.568422],[-72.203096,44.556556],
[-72.177752,44.541709],[-72.166183,44.535004],[-72.153987,44.527993],
[-72.137759,44.518585],[-72.131456,44.517563],[-72.124548,44.516587],
[-72.112684,44.514713],[-72.102359,44.513155],[-72.093739,44.511928],
[-72.083545,44.51038],[-72.078082,44.529532],[-72.072177,44.549492],
[-72.066275,44.569281],[-72.060237,44.589858],[-72.057689,44.598425],
[-72.064812,44.618792],[-72.066382,44.623496]]],type:"Polygon"}},
我包括了整个构建的笔(省略了数据库凭据),但这仅允许进行调查,因为实时数据来自安全数据库。
就来转一圈。我没有在onclick弹出窗口中显示任何数据值(其中包括镇名,因为它是数组的属性,所以将是弹出窗口的名称)。
不言而喻,非常感谢您的帮助。 谢谢, 杰克
// set initial map view point
const map = L.map('mapid').setView([44.5, -72.6034], 8);
// add map tile layer and set max zoom
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© <a href=”http://osm.org/copyright”>OpenStreetMap</a> contributors',
maxZoom: 11,
}).addTo(map);
// Global Variables ////////
// let metersOut = '0';
// let percentOut = '';
// let town = '';
// add town polygon
L.geoJson(serviceTowns, {
color: '#000',
fillColor: 'grey',
weight: '0.7',
zindex: '2',
}).addTo(map)
// set choropleth params from metersOut in outageValues
function getColor(percentOut) {
return percentOut > 80 ? '#FF0000' :
percentOut > 60 ? '#FFA500' :
percentOut > 40 ? '#FFFF00' :
percentOut > 20 ? '#7CFC00' :
percentOut > 0 ? '#0000FF' :
'grey';
}
// call outage data from php generated object "outageValues" and apply to polygon
function style(feature) {
let percentOut = percentValues[feature.properties.town];
return {
fillColor: getColor(percentOut),
weight: 1,
opacity: 1,
color: 'black',
fillOpacity: 0.3
};
}
L.geoJson(serviceTowns, { style: style }).addTo(map);
// create hover hightlight and townname feature ////////
function highlightFeature(e) {
let layer = e.target;
info.update(layer.feature.properties);
layer.setStyle({
weight: 4,
color: '#666',
fillOpacity: 0.7,
});
if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
layer.bringToFront();
}
}
function resetHighlight(e) {
geojson.resetStyle(e.target);
info.update();
}
// End highlight //////
// Onclick gets townname with # of members affected and % of town affected ////////
function popUpClick(layer, props) {
if (props) {
metersOut = (outageValues[props.town] ? outageValues[props.town] : 0);
percentOut = (percentValues[props.town] ? percentValues[props.town] : 0);
town = props.townMC;
}
if (props) {
(layer.bindPopup(('<h3>' + town + '</h3><p># of members affected: ' + metersOut + '<br/>' + percentOut + '% of ' + town + ' affected')))
}
}
// Define hover and click events
function onEachFeature(feature, layer) {
let popup = popUpClick(layer, feature);
// Set click params and generate popup for click ///////////
layer.on({
click: popup,
mouseover: highlightFeature,
mouseout: resetHighlight
});
}
//End Mouse functions ///
// Keep json layer fresh ////
geojson = L.geoJson(serviceTowns, {
style: style,
onEachFeature: onEachFeature,
}).addTo(map);
// ////
// Add Info pane to map div ////////
// ///////
var info = L.control();
info.onAdd = function (map) {
this._div = L.DomUtil.create('div', 'info'); // create a div with a class "info"
this.update();
return this._div;
};
// call town data from outageValues and display in infopane
info.update = function (props) {
// parse data from php db
if (props) {
metersOut = (outageValues[props.town] ? outageValues[props.town] : 0);
percentOut = (percentValues[props.town] ? percentValues[props.town] : 0);
town = props.townMC;
}
let message = 'Hover over a town';
if (props) {
message = (metersOut + ' Members affected in ' + town + '<br/>' + percentOut + '% of ' + town + ' affected' + '<br/>'
);
}
this._div.innerHTML = '<h4>VEC Service Territory</h4>' + message;
};
info.addTo(map);
// ////////////
// create legend in bottom and call colors from choropleth params set in getColor function
const legend = L.control({ position: 'bottomleft' });
legend.onAdd = function (map) {
let div = L.DomUtil.create('div', 'info legend'),
grades = [1, 20, 40, 60, 80],
labels = [],
from, to;
labels.push('<p>% of Town<br/>Affected</p><br/><i style="background: grey"></i> ' + '0'); // title and trick legend into showing null value for grey
for (let i = 0; i < grades.length; i++) {
from = grades[i];
to = grades[i + 1];
div.innerHTML =
labels.push(
'<i style="background:' + getColor(from + 1) + '"></i> ' + from + (to ? '–' + to : '+'));
}
div.innerHTML = labels.join('<br>');
return div;
};
legend.addTo(map);
////// features diabled
// map.dragging.disable();
// map.touchZoom.disable();
map.doubleClickZoom.disable();
map.scrollWheelZoom.disable();
<!-- this is the map build with a current outage table to be placed in a frame module -->
<!-- Connect to a local database to access updated data -->
<?php
$host = "localhost";
$user = "xxxx";
$pass = "xxx";
$database = "xxx";
$conn = mysqli_connect($host, $user, $pass, $database);
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
$sortBy = array('town');
$order = 'off';
if (isset($_GET['sortBy']) && in_array($_GET['sortBy'], $sortBy)) {
$order = $_GET['sortBy'];
}
//Select # of live outages
$outageDataSql = "SELECT * FROM oms_by_town_live_percent ORDER BY " . $order;
$outageDataResult = mysqli_query($conn, $outageDataSql);
$numOutageData = mysqli_num_rows($outageDataResult);
$outageData = [];
while ($row = mysqli_fetch_assoc($outageDataResult)) {
$outageData[$row['town']] = $row;
}
$outageValues = [];
foreach ($outageData as $outage) {
$outageValues[$outage['town']] = $outage['out'];
}
$percentValues = [];
foreach ($outageData as $percent) {
$percentValues[$percent['town']] = round($percent['percent'], 2);
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>VEC Outage Center</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="leaflet.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
<script src="serviceTowns.js"></script>
<link rel="stylesheet" href="leaflet.css" />
<link rel="stylesheet" href="map.css" />
</head>
<body>
<!----------------- Map area ---------------------->
<div id="mapid"></div>
<script type="text/javascript">
var outageValues = JSON.parse(<?php echo "'" . json_encode($outageValues) . "'"; ?>);
var percentValues = JSON.parse(<?php echo "'" . json_encode($percentValues) . "'"; ?>);
</script>
<!----------------- Current Outages Table ------------------------>
<div id="outTable">
<?php
$resultID = mysqli_query($conn, $outageDataSql);
for ($x = 0; $x < mysqli_num_rows($resultID); $x++) {
$ascdesc = ($_GET['ad']) ? 'asc' : 'desc';
$row = mysqli_fetch_assoc($resultID);
$out = $row['out'];
$percent = round($row['percent'], 2);
$town = $row['town'];
$off = $row['off'];
$off = date("m/d h:ia", strtotime($off));
$etr = $row['etr'];
if ($etr != null) {
$etr = date("m/d h:ia", strtotime($etr));
} else {
$etr = "TBD";
}
$current = $current . "<tr>
<td>$town</td>
<td bgcolor='#f5f5f5'>$out</td>
<td>$off</td>
<td bgcolor='#f5f5f5'>$etr</td>
<td>$percent</td>
</tr>";
}
echo "<table align=center width=90% cellpadding=3>\n";
echo "<tr class='cTable'>
<th bgcolor='#1682c8'><a href='?sortBy=town&ad='" . $ascdesc . "'><font color='white'>Town</font></a></th>
<th bgcolor='#1682c8'><font color='white'># of Member<br>Outages</font></th>
<th bgcolor='#1682c8'><font color='white'>Time Off</font></th>
<th bgcolor='#1682c8'><font color='white'>Estimated<br>Restoration Time</font></th>
<th bgcolor='#1682c8'><font color='white'>Percent Out</font></th>
</tr>\n";
echo $current;
"\n";
echo "</table>";
?>
</div>
<script src="mapScripts.js"?=v18></script>
</body>
</html>
答案 0 :(得分:0)
您可能只是没有正确地钻入feature
对象。输入一些console.log({feature})
语句,您将看到数据是否确实存在,但处于不同的对象级别。
在https://leafletjs.com/examples/geojson/的传单文档中,feature
有一个名为properties
的属性(是的,这是Leaflet / GeoJSON的令人困惑的命名决定),但是在您的popupClick
中您已将feature
重命名为{em> 的函数,而不是深入研究props
。这就是我的猜测。
feature.properties
这意味着您希望onEachFeature(feature, layer) ->
popUpClick(layer, feature) ->
popUpClick(layer, props) ->
props.townMC
具有feature
属性,但实际上它有一个townMC
对象,其中包含properties
—将townMC
参数重命名为{ {1}},然后使用props
3. feature
方法似乎是从事件到侦听器函数的映射,但是您已经将let town = feature.properties.townMC
映射到调用结果 on
。这对我来说很奇怪,我不确定为什么它可以工作。它可以解释为什么要素属性为空/未定义的原因,因为它被调用太早了。否则可能是红色鲱鱼。
其他建议:
click
的参数)popupClick
内使用popupClick
来存储所有变量;它们现在已经全球化了,可能会有不良的副作用let
中的两个popupClick
语句