【问题标题】:Leaflet: Map container not found传单:找不到地图容器
【发布时间】:2017-07-27 15:04:16
【问题描述】:

我有下面的反应类,它通过浏览器获取地理位置。

我正在绘制一张传单地图。我想将地理位置作为 setView 的输入,以便地图“缩放”到客户端浏览器位置的区域。

这是反应类:

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

    var Worldmap = React.createClass({

        render: function() {

            let geolocation = [];

            navigator.geolocation.getCurrentPosition(function(position) {
                let lat = position.coords.latitude;
                let lon = position.coords.longitude;
                geolocation.push(lat, lon);
                locationCode()
            });

            function locationCode() {
                if(geolocation.length <= 0)
                    geolocation.push(0, 0);
            }


            let map = L.map('leafletmap').setView(geolocation, 3);

            L.geoJSON(countries, {
                style: function(feature) {
                    return {
                        fillColor: "#FFBB78",
                        fillOpacity: 0.6,
                        stroke: true,
                        color: "black",
                        weight: 2
                    };
                }
            }).bindPopup(function(layer) {
                return layer.feature.properties.name;
            }).addTo(map);

            return (
                <div id="leafletmap" style={{width: "100%", height: "800px" }}/>
            )
        }
    });

    export default Worldmap

它在一个主文件中调用,其中 HTML 呈现为 &lt;WorldMap /&gt;

我在加载页面时收到错误 Uncaught Error: Map container not found.。环顾四周,通常是因为地图在提供值之前试图在 div 中显示(在这种情况下为 (gelocation, 3))。但是,它不应该在从下面的渲染函数返回之前显示它。

可能是什么问题?

在控制台中打印出geolocation 可以正确获取坐标,所以这似乎不是问题。

【问题讨论】:

    标签: javascript reactjs leaflet react-leaflet


    【解决方案1】:

    &lt;div id="leafletmap"&gt; 必须添加到 dom 调用 L.map('leafletmap')

    【讨论】:

    • 我应该如何处理它。在 React 类之外添加传单功能?如果我将那些包含在渲染 DOM 的 main.js 中,我将无法访问 geolocation 变量。
    • 参见github.com/PaulLeCam/react-leaflet/blob/master/src/Map.js - 对L.map() 的调用在组件安装时完成,而不是在组件渲染时完成。跨度>
    • 由于 React 类的结构方式(语法比我的新),与我的示例相比,我无法真正理解该示例
    • 对于那些正在寻找工作源代码的人,请在@hoogw 下方向下滚动。我有一个答案告诉你如何实现它。
    【解决方案2】:

    除了@IvanSanchez 的回复,您还可以将地理位置和 L.map(...) 代码添加到 componentDidMount() React 生命周期方法(取决于您希望实现的其他目标)。您还可以为找到的位置创建和绑定事件处理程序。

    这种方式肯定是加了dom和leaflet才能找到的。

    如果还不清楚,很乐意提供帮助。

    【讨论】:

      【解决方案3】:

      如果您使用 Angular,我希望这会有所帮助:

      const container = document.getElementById('map')
      if(container) {
          // code to render map here...
      }
      

      【讨论】:

        【解决方案4】:

        我在反应时遇到了同样的问题,我通过在 useEeffect 的顶部初始化解决了它 这是我的反应代码。

          const  mapContainerRef = useRef(null), 
          useEffect( async () => {
          const res =await Axios.get(BASE_PATH + 'fetchProperty')
        
          const container = L.DomUtil.get(mapContainerRef.current); if(container != null){ container._leaflet_id = null; }
        
          if(container) {
        
        
          const mapView = L.map( mapContainerRef.current, {
            zoom: 13,
            center: [19.059984, 72.889999]
            //  maxZoom: 13
            // minZoom: 15
          });
          // const canvas = mapView.getCanvasContainer();
          mapView.zoomControl.setPosition("bottomright");
          mapView.attributionControl.addAttribution(
            "<a href='https://mascots.pro'>Mascots. pro</a>"
          );
          L.tileLayer(
            // "https://api.mapbox.com/styles/v1/mapbox/dark-v9/tiles/{z}/{x}/{y}?access_token=" + https://api.mapbox.com/styles/v1/anonymousmw/cko1eb1r20mdu18qqtps8i03p/tiles/{z}/{x}/{y}?access_token=
            "https://api.mapbox.com/styles/v1/mapbox/dark-v9/tiles/{z}/{x}/{y}?access_token=" +
              access_token,
            {
              attribution: '<a href="http://mascots.work">Mascots</a>'
            }
          ).addTo(mapView);
        
          const mask = L.tileLayer.mask(
            "https://api.mapbox.com/styles/v1/anonymousmw/cko1eb1r20mdu18qqtps8i03p/tiles/{z}/{x}/{y}?access_token=" +
              access_token,
            {
              attribution: '<a href="https://mascots.pro">Mascots pro</a>',
              maskSize: 300
              // maxZoom: 18,
              // maxNativeZoom: 16
              // tms: true
            }
          )
          .addTo(mapView);
        
          mapView.on("mousemove", function (e) {
            mask.setCenter(e.containerPoint);
          });
          res.data.map((marker) => {
          
            const innerHtmlContent = `<div id='popup-container' class='popup-container'> <h3> Property Details</h3>
            <div class='popup-label'>Building Name :<p>${marker.Building}</p></div>
            <div class='popup-address-label'> Address : <p>${marker.Landmark}, ${marker.Location}</p></div>
            <div class='popup-rent-label'>Monthly Rent : <p> ₹ ${marker.Price}</p></div>
            </div>`;
            const divElement = document.createElement("div");
            const assignBtn = document.createElement("div");
            assignBtn.className = "map-link";
            assignBtn.innerHTML = `<button class="view-btn">View Property</button>`;
            divElement.innerHTML = innerHtmlContent;
            divElement.appendChild(assignBtn);
            assignBtn.addEventListener("click", (e) => {
              console.log("dsvsdvb");
            });
            var iconOptions = {
              iconUrl: "/images/location_pin2.svg",
              iconSize: [25, 25]
            };
            var customIcon = L.icon(iconOptions);
        
            // create popup contents
            var customPopup = divElement;
        
            // specify popup options
            var customOptions = {
              maxWidth: "500",
              className: "custom"
            };
        
            const markerOptions = {
              // title: "MyLocation",
              //    draggable: true
              clickable: true,
              icon: customIcon
            };
            const mark = L.marker([marker.Latitude,marker.Longitude], markerOptions);
            mark.bindPopup(customPopup, customOptions);
            mark.addTo(mapView);
            // return mapView.off();
           
          });
          return () => mapView.remove();
        }
        }, [])
        
        return (
          <div className="map-box">
                <div className="map-container" ref={mapContainerRef}></div>
            </div>
        );
        

        }

        【讨论】:

          【解决方案5】:

          引起的错误

          div id="map" 必须在调用 L.map('map') 之前添加到 dom 中。

          解决方法是:

                   useEffect(() => {
          

          这是我的工作 app.js:

                     import React, { useState, useEffect } from 'react';
          
          
          
                     import './App.css';
          
                     import L from 'leaflet';
                     import 'leaflet/dist/leaflet.css';
          
          
                     function App() {
          
          
          
          
          
          
                    // Similar to componentDidMount and componentDidUpdate:
                    useEffect(() => {
          
          
          
                                        let current_lat = 28.625789;
                                        let current_long = 77.0547899;
                                        let current_zoom = 16;
                                        let center_lat = current_lat;
                                        let center_long = current_long;
                                        let center_zoom = current_zoom;
          
          
          
          
                                        // The <div id="map"> must be added to the dom before calling L.map('map')
                                          let map = L.map('map', {
                                            center: [center_lat, center_long],
                                            zoom: center_zoom
                                          });
          
                                          L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
                                            attribution: '&copy; <a href="https://openstreetmap.org/copyright">OpenStreetMap</a> contributors'
                                          }).addTo(map);
          
          
          
                    });
          
          
          
          
          
                            return (
          
          
                        
          
                                          <div class="right-sidebar-container">
                                                  
                                            <div id="map">
          
                                            </div>
                                          
                                        </div>
          
                            );
          
          
          
          
          
                   } // app
          
          
          
          
          
          
          
               export default App;
          

          【讨论】:

            【解决方案6】:

            在 Angular 中,我必须将它放在 ngAfterViewInit 中,如下所示:

            ngAfterViewInit() {
                this.mymap = L.map('mapid').setView([51.505, -0.09], 13);
            }
            

            在我的“view.component.ts”导出类中

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2022-07-09
              • 2021-04-12
              • 1970-01-01
              • 1970-01-01
              • 2021-04-12
              • 2018-06-28
              • 2015-12-10
              相关资源
              最近更新 更多