传单:找不到地图容器
Posted
技术标签:
【中文标题】传单:找不到地图容器【英文标题】: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 呈现为 <WorldMap />
。
我在加载页面时收到错误 Uncaught Error: Map container not found.
。环顾四周,通常是因为地图在提供值之前试图在 div 中显示(在这种情况下为 (gelocation, 3))。但是,它不应该在从下面的渲染函数返回之前显示它。
可能是什么问题?
在控制台中打印出geolocation
可以正确获取坐标,所以这似乎不是问题。
【问题讨论】:
【参考方案1】:<div id="leafletmap">
必须添加到 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: '© <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”导出类中
【讨论】:
以上是关于传单:找不到地图容器的主要内容,如果未能解决你的问题,请参考以下文章