Брошюра: Контейнер карты не найден

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

Я составляю карту листовки. Я хочу, чтобы геолокация использовалась в качестве входных данных для 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-код отображается как <WorldMap />.

Я получаю ошибку Uncaught Error: Map container not found. при загрузке страницы. Если оглянуться вокруг, обычно это происходит из-за того, что карта пытается отобразить в div до того, как ей будут предоставлены значения (в данном случае (gelocation, 3)). Однако он не должен отображать его до возврата из функции рендеринга ниже.

В чем может быть проблема?

Распечатка geolocation в консоли правильно определяет координаты, так что, похоже, это не проблема.


person cbll    schedule 07.03.2017    source источник


Ответы (6)


<div id="leafletmap"> необходимо добавить в дом перед вызовом L.map('leafletmap').

person IvanSanchez    schedule 07.03.2017
comment
Как мне к этому подойти. Добавить функции листовки вне класса React? Если я включу их в main.js, где отображается DOM, я не смогу получить доступ к переменной геолокации. - person cbll; 07.03.2017
comment
См. github.com/PaulLeCam/react-leaflet/blob/master /src/Map.js - вызов L.map() выполняется, когда компонент смонтирован, а не когда компонент отображается. - person IvanSanchez; 07.03.2017
comment
Я не могу понять этот пример по сравнению с моим из-за того, как структурирован класс React (более новый синтаксис, чем у меня) - person cbll; 07.03.2017
comment
Для тех, кто ищет рабочий исходный код, прокрутите вниз под @hoogw. У меня был ответ, показывающий, как это реализовать. - person hoogw; 22.05.2021

В дополнение к ответу @ IvanSanchez вы можете добавить код геолокации и L.map (...) в метод жизненного цикла componentDidMount () React (в зависимости от того, какие другие цели вы надеетесь достичь). Вы также можете создавать и связывать обработчики событий для найденного местоположения.

Таким образом, должно быть, был добавлен дом и буклет, который можно найти.

С радостью помогу с этим, если все еще непонятно.

person Samuel_NET    schedule 17.07.2017

Надеюсь, это поможет, если вы используете Angular:

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

У меня была такая же проблема с реакцией, которую я решил, инициализировав вверху в 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>
);

}

person Jerry    schedule 11.05.2021

Ошибка, вызванная

Div id = map должен быть добавлен в dom перед вызовом L.map ('map').

Решение - использовать:

         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;
person hoogw    schedule 21.05.2021

В Angular мне пришлось поместить его в ngAfterViewInit, например:

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

будучи этим в моем экспортированном классе view.component.ts

person Raineru San    schedule 09.03.2021