如何强制传单更新地图? [英] How do I force leaflet to update the map?

查看:83
本文介绍了如何强制传单更新地图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在遇到问题,因为我正在使用Leaflet和React,问题是Leaflet也希望控制DOM呈现,就我研究而言。

I'm running into issues as I am using Leaflet together with React, the issue being that Leaflet wants to control the DOM rendering as well, as far as I've researched.

现在,各国将使用与后端信息对应的特定颜色代码正确着色(范围为1 - > 100)。但是,它每分钟更新一次。更新后,国家/地区颜色不会更改。但是如果你将鼠标悬停在给定的国家/地区上,这有点奇怪。

Right now, the countries will correctly be colored with the specific color code corresponding with the backend information(range of 1-->100). However, it is updated every minute. Upon update, the country color will not change. It will however if you hover the mouse over a given country, which is a bit weird.

这是我的源代码:

import React from 'react';
import L from 'leaflet';
import countries from './countries.js';


var Worldmap = React.createClass({

    render: function() {

        if(!this.props.data)
            return <div> loading world map ..  </div>;

        let dataratio = this.props.data; // Props from main component
        let size = Object.keys(dataratio).length; // Do we have data?

        if(size > 1) { // If we do have data, ..

            let dataratioToArr = Object.keys(dataratio).map(data => [ data, dataratio[data]]); // Conv. map to multidimensional array

            let featuresArr = countries.features; // array of all countries in array features from countries.js

            for(let i = 0; i < featuresArr.length; i++) // i = 178(no. of countries)
                for(let j = 0; j < dataratioToArr.length; j++) // j = no. of countries we have with dataratio > 1 from backend
                    if(dataratioToArr[j][0] == featuresArr[i].id) // If ISO-3 compliant ID of country(f.e. "USA") matches, push a "data" property to countries.js
                        featuresArr[i].properties.data = dataratioToArr[j][1];
        }

        return(
            <div id="leafletmap" style={{width: "100%", height: "80%", border: "2px solid black" }} />
        )
    },

    componentDidMount : function() {
        let geolocation =  [];
        // Retrieve geoloc coordinates
        navigator.geolocation.getCurrentPosition(function(position) {
            let lat = position.coords.latitude;
            let lon = position.coords.longitude;

            if(lat != null && lon != null) // If we can get latitude and longitude, reset geolocation and push values.
                geolocation.length = 0;
            geolocation.push(lat, lon);
            if(!lat || !lon) // If we can't get latitude or longitude, set a default value.
                geolocation = [0,0];

            let map = L.map('leafletmap').setView(geolocation, 3); // ([coordinates], zoomlevel)

            let info = L.control();

            info.onAdd = function (map) {
                this._div = L.DomUtil.create('div', 'info');
                this.update();
                return this._div;
            };

            info.update = function (props) {
                this._div.innerHTML = '<h4>Data ratio</h4>' +  (props ?
                    '<b>' + props.name + '</b><br />' + props.data + ' ratio'
                        : 'Hover over a country');
            };

            info.addTo(map);


            function getColor(d) {
                return d > 90 ? '#4a1486' :
                    d > 75  ? '#6a51a3' :
                        d > 50  ? '#807dba' :
                            d > 25  ? '#9e9ac8' :
                                d > 15   ? '#bcbddc' :
                                    d > 5   ? '#dadaeb' :
                                        d > 1   ? '#f2f0f7' :
                                            '#D3D3D3'; // Default color of data doesn't exist or is 0.
            }


            function style(feature) {
                return {
                    weight: 2,
                    opacity: 1,
                    color: 'white',
                    fillOpacity: 1,
                    fillColor: getColor(feature.properties.data)
                };
            }

            function highlightFeature(e) {
                let layer = e.target;

                layer.setStyle({
                    weight: 5,
                    color: '#666',
                    fillOpacity: 0.7
                });

                if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
                    layer.bringToFront();
                }

                info.update(layer.feature.properties);
            }

            let geojson;

            function resetHighlight(e) {
                geojson.resetStyle(e.target);
                info.update();
            }

            function zoomToFeature(e) {
                map.fitBounds(e.target.getBounds());
            }

            function onEachFeature(feature, layer) {
                layer.on({
                    mouseover: highlightFeature,
                    mouseout: resetHighlight,
                    click: zoomToFeature
                });
            }


            geojson = L.geoJson(countries, { // from import
                style: style,
                onEachFeature: onEachFeature
            }).addTo(map);

            let legend = L.control({position: 'bottomright'});

            legend.onAdd = function (map) {

                let div = L.DomUtil.create('div', 'info legend'),
                    grades = [1, 5, 15, 25, 50, 75, 90],
                    labels = [],
                    from, to;

                for (let i = 0; i < grades.length; i++) {
                    from = grades[i];
                    to = grades[i + 1];

                    labels.push(
                        '<i style="background:' + getColor(from + 1) + '"></i> ' +
                        from + (to ? '&ndash;' + to : '+'));
                }

                div.innerHTML = labels.join('<br>');
                return div;
            };

            legend.addTo(map);
        });

    }
});

export default Worldmap

如何强制传单重绘或刷新映射到新的 this.props.data 正在收到?

How do I force leaflet to redraw or refresh the map upon a new this.props.data being received?

我尝试使用 componentDidUpdate 我基本上会做 map.remove(),但后来我遇到了不同组件之间的范围问题..它全部加载在 componentDidMount 如果你再次调用传单地图,它会说它已经初始化了。

I tried using componentDidUpdate where I basically would do map.remove(), but then I run into scoping issues between the different components.. It's all loaded in componentDidMount and if you call the leaflet map again it will say it's already initialized.

推荐答案

扩展我的评论。
您需要清除图层并重新向地图添加数据。在您的情况下,您可能需要更改访问地图和geojson处理的方式,但我在这里给出了一般解决方案。

To extend my comment. You need to clear the layer and and re-add data to your map. It's possible that in your case you will need to change how you access the map and geojson processing but I'm giving you the general solution here.

   componentDidMount(){
      var map = this.map = L.map('leafletmap');
   } 


   componentWillReceiveProps(nextProps) {
      if (nextProps.data !== this.props.data) {
       this.map.clearLayers();
      }
   } 


  componentDidUpdate(prevProps,prevState) {
      if (prevProps.data !== this.props.data) {
          this.map.addData(geojsonData);
       }
   }

这篇关于如何强制传单更新地图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆