#leaflet
Вопрос:
У меня есть приведенный ниже класс react, который извлекает геолокацию через браузер.
Я составляю карту листовки. Я хочу, чтобы геолокация была входом в setView, чтобы карта «масштабировалась» в область расположения браузера клиента.
Вот класс react:
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
в консоли правильно извлекает координаты, так что, похоже, проблема не в этом.
Ответ №1:
Его <div id="leafletmap">
необходимо добавить в dom перед вызовом L.map('leafletmap')
.
Комментарии:
1. Как мне к этому подойти? Добавить функции листовки за пределами класса React? Если я включу их в main.js там, где отображается DOM, я не могу получить доступ к переменной геолокации.
2. Видишь github.com/PaulLeCam/react-leaflet/blob/master/src/Map.js — вызов
L.map()
выполняется при монтировании компонента, а не при его визуализации .3. Я действительно не могу понять смысл этого примера по сравнению с моим, из-за того, как структурирован класс React(более новый синтаксис, чем у меня).
4. Для тех, кто ищет рабочий исходный код, прокрутите вниз ниже @hoogw. У меня был ответ, который показал вам, как его реализовать.
Ответ №2:
В дополнение к ответу @IvanSanchez вы можете добавить код геолокации и карты(…) в componentDidMount() Метод жизненного цикла реакции (в зависимости от того, каких других целей вы надеетесь достичь). Вы также можете создавать и связывать обработчики событий для найденного местоположения.
Таким образом, должно быть, был добавлен dom, и листовка может его найти.
Рад помочь с этим, если это все еще неясно.
Ответ №3:
Я надеюсь, что это поможет, если вы используете Angular:
const container = document.getElementById('map')
if(container) {
// code to render map here...
}
Ответ №4:
У меня была та же проблема с react, я решил ее, инициализировав вверху в 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=»карта» должен быть добавлен в dom перед вызовом L. 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: 'amp;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»