Значения обновления карты листовки отображаются при наведении, но не всплывающем окне - данные из sqlDB через PHP - PullRequest
0 голосов
/ 01 марта 2019

У меня есть листовка с несколькими полигонами для отображения отключений питания в состоянии.Каждый город можно навести на него или щелкнуть, что приведет к обновлению информации внутри панели в углу или отображению во всплывающем окне.

Когда пользователь нажимает или наводит указатель мыши на город, отображаемые данные должны выглядеть следующим образом: Город,% затронутого города и количество затронутых членов

Проблема заключается в том, что я не получаю никаких значений данных для отображения в моей функции popUpClick (которая включает название города, которое будет отображаться во всплывающем окне, поскольку оно является свойством массива).Как видно из этого снимка экрана , данные работают для моей таблицы и функции info.update (инфобокс), но во всплывающем окне нет значений.

Многоугольник также функционирует как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 (которое включает название города, которое будет отображаться во всплывающем окне, поскольку это свойство массива).

ItСамо собой разумеется, что любая помощь очень ценится.Спасибо, Джейк

// 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: '&copy; <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 ? '&ndash;' + 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>

1 Ответ

0 голосов
/ 02 марта 2019

Возможно, вы не правильно сверлили объект feature.Вставьте несколько операторов console.log({feature}), и вы увидите, действительно ли существуют данные, но на другом уровне объекта.

В листовке с документами по адресу https://leafletjs.com/examples/geojson/ a feature есть свойство с именемproperties (да, Leaflet / GeoJSON - это вводящее в заблуждение решение по присвоению имен), но в вашей функции popupClick у вас есть переименовано с feature в props, не углубляясь в feature.properties.Так что это мое предположение.

onEachFeature(feature, layer) -> 
popUpClick(layer, feature) -> 
popUpClick(layer, props) -> 
props.townMC

, что означает, что вы ожидаете, что feature будет иметь свойство townMC, но на самом деле у него есть properties объект, содержащий townMC - переименуйте параметр props вfeature и затем используйте let town = feature.properties.townMC 3. Кажется, что метод on принимает преобразование из события в функцию слушателя, но вы отобразили click в результат вызова popupClick.Это странно для меня, и я не уверен, почему это работает вообще.Это может объяснить, почему свойства объекта пусты / не определены, так как он вызывается слишком рано.Или это может быть красная сельдь.

Другие советы:

  • не изменяйте порядок и названия параметров (т. Е. Переставляйте / переименовывайте параметры popupClick)
  • используйте let внутри popupClick для всех ваших переменных;теперь они глобальны и могут иметь плохие побочные эффекты
  • объединить два if оператора внутри popupClick
  • написать несколько модульных тестов и / или утверждений для отдельныхфункции, чтобы сузить, где ошибка может быть
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...