结合 react-leaflet 和 leaflet-pixi-overlay
Combining react-leaflet and leaflet-pixi-overlay
我正在尝试显示具有许多移动标记、不同图标等的复杂地图...我有一个纯粹的反应/反应传单解决方案,但它开始与每秒移动约 1k 标记作斗争。
看起来 leaflet-pixi-overlay 可能是一种真正加快速度的方法。但我只是从整个链开始 (react/javascript/maps/leaflet/etc..) 并且在连接所有这些时遇到问题。
现在我只是想在叠加层中显示一个多边形,但没有渲染任何内容。事实证明,对于该多边形的点,lat/long 到 x/y 的转换失败了。 Pixi 的 latLngToLayerPoint 函数 returns 'infinity' for x 和 y.
这似乎是因为未为相关层定义缩放(也是 'infinity')。
即使我使用地图的缩放设置调用 latLngToLayerPoint,事情也会失败(x/y 值不再是无限的,但它们已经超出了范围)。
这是我的代码:
import React, { useEffect, useRef } from 'react';
import { Map, TileLayer } from 'react-leaflet'
import "leaflet/dist/leaflet.css"
import * as PIXI from 'pixi.js'
import 'leaflet-pixi-overlay' // Must be called before the 'leaflet' import
import L from 'leaflet';
let polyLatLngs = [[50.630, 13.047], [50.645, 13.070], [50.625, 13.090], [50.608, 13.070], [50.630, 13.047]]
let pixiContainer = new PIXI.Container()
let prevZoom
let firstDraw = true;
let projectedPolygon;
var shape = new PIXI.Graphics();
pixiContainer.addChild(shape);
let myOverlay = L.pixiOverlay(function (utils) {
let map = utils.getMap()
let zoom = map.getZoom()
console.log('map zoom=' + zoom + ', center=' + map.getCenter())
console.log(' bounds=' + JSON.stringify(map.getBounds()))
console.log(' size=' + map.getSize() + ', panes=' + JSON.stringify(map.getPanes()))
if (map) {
var container = utils.getContainer();
var renderer = utils.getRenderer();
var project = utils.latLngToLayerPoint;
var scale = utils.getScale();
if (firstDraw) {
projectedPolygon = polyLatLngs.map((coords, index) => {
console.log('i=' + index + ', coords=' + coords + ', proj=' + project(coords))
return project(coords)
// return project(coords, zoom) // : this fails too
})
}
if (firstDraw || prevZoom !== zoom) {
shape.clear();
shape.lineStyle(3 / scale, 0x3388ff, 1);
shape.beginFill(0x3388ff, 0.2);
projectedPolygon.forEach(function (coords, index) {
if (index === 0) shape.moveTo(coords.x, coords.y);
else shape.lineTo(coords.x, coords.y);
});
shape.endFill();
}
firstDraw = false;
prevZoom = zoom;
renderer.render(container);
}
}, pixiContainer)
function PxMap(props) {
const mapRef = useRef(null);
useEffect(() => {
if (mapRef.current !== null) {
let map = mapRef.current.leafletElement;
console.log('useEffect: add overlay ')
console.log(JSON.stringify(map.getPane('overlayPane').childElementCount))
myOverlay.addTo(map);
console.log(JSON.stringify(map.getPane('overlayPane').childElementCount))
}
}, [mapRef]);
return (
<div style={{ flexgrow: 1, height: '100%' }}>
<Map
preferCanvas={true}
ref={mapRef}
style={{ height: '100%' }}
center={[50.63, 13.047]}
zoom={12}
>
<TileLayer
attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?"
/>
</Map>
</div>
)
}
export default PxMap
我认为 React 和 leaflet 之间的连接正确,地图显示正常,我可以看到叠加层正在添加等...
但是某处缺少连接,以便为 PIXI 提供更多上下文/信息。
有什么想法吗?谢谢!
终于找到问题所在,深入leaflet-pixi-overlay lib
解决方法是在Map元素中定义minZoom和maxZoom:
<Map
preferCanvas={true}
ref={mapRef}
style={{ height: '100%' }}
center={[50.63, 13.047]}
zoom={12}
minZoom={ 9} // Add these options...
maxZoom={ 16} //
在内部,L.PixiOverlay.js 依靠这两个值来定义:
// return the layer projection zoom level
projectionZoom: function (map) {return (map.getMaxZoom() + map.getMinZoom()) / 2;},
哪个又用于定义默认缩放设置?
this._initialZoom = this.options.projectionZoom(map);
....
zoom = (zoom === undefined) ? _layer._initialZoom : zoom;
var projectedPoint = map.project(L.latLng(latLng), zoom);
不确定为什么这样做,但设置这些选项可以解决问题。
我正在尝试显示具有许多移动标记、不同图标等的复杂地图...我有一个纯粹的反应/反应传单解决方案,但它开始与每秒移动约 1k 标记作斗争。
看起来 leaflet-pixi-overlay 可能是一种真正加快速度的方法。但我只是从整个链开始 (react/javascript/maps/leaflet/etc..) 并且在连接所有这些时遇到问题。
现在我只是想在叠加层中显示一个多边形,但没有渲染任何内容。事实证明,对于该多边形的点,lat/long 到 x/y 的转换失败了。 Pixi 的 latLngToLayerPoint 函数 returns 'infinity' for x 和 y.
这似乎是因为未为相关层定义缩放(也是 'infinity')。
即使我使用地图的缩放设置调用 latLngToLayerPoint,事情也会失败(x/y 值不再是无限的,但它们已经超出了范围)。
这是我的代码:
import React, { useEffect, useRef } from 'react';
import { Map, TileLayer } from 'react-leaflet'
import "leaflet/dist/leaflet.css"
import * as PIXI from 'pixi.js'
import 'leaflet-pixi-overlay' // Must be called before the 'leaflet' import
import L from 'leaflet';
let polyLatLngs = [[50.630, 13.047], [50.645, 13.070], [50.625, 13.090], [50.608, 13.070], [50.630, 13.047]]
let pixiContainer = new PIXI.Container()
let prevZoom
let firstDraw = true;
let projectedPolygon;
var shape = new PIXI.Graphics();
pixiContainer.addChild(shape);
let myOverlay = L.pixiOverlay(function (utils) {
let map = utils.getMap()
let zoom = map.getZoom()
console.log('map zoom=' + zoom + ', center=' + map.getCenter())
console.log(' bounds=' + JSON.stringify(map.getBounds()))
console.log(' size=' + map.getSize() + ', panes=' + JSON.stringify(map.getPanes()))
if (map) {
var container = utils.getContainer();
var renderer = utils.getRenderer();
var project = utils.latLngToLayerPoint;
var scale = utils.getScale();
if (firstDraw) {
projectedPolygon = polyLatLngs.map((coords, index) => {
console.log('i=' + index + ', coords=' + coords + ', proj=' + project(coords))
return project(coords)
// return project(coords, zoom) // : this fails too
})
}
if (firstDraw || prevZoom !== zoom) {
shape.clear();
shape.lineStyle(3 / scale, 0x3388ff, 1);
shape.beginFill(0x3388ff, 0.2);
projectedPolygon.forEach(function (coords, index) {
if (index === 0) shape.moveTo(coords.x, coords.y);
else shape.lineTo(coords.x, coords.y);
});
shape.endFill();
}
firstDraw = false;
prevZoom = zoom;
renderer.render(container);
}
}, pixiContainer)
function PxMap(props) {
const mapRef = useRef(null);
useEffect(() => {
if (mapRef.current !== null) {
let map = mapRef.current.leafletElement;
console.log('useEffect: add overlay ')
console.log(JSON.stringify(map.getPane('overlayPane').childElementCount))
myOverlay.addTo(map);
console.log(JSON.stringify(map.getPane('overlayPane').childElementCount))
}
}, [mapRef]);
return (
<div style={{ flexgrow: 1, height: '100%' }}>
<Map
preferCanvas={true}
ref={mapRef}
style={{ height: '100%' }}
center={[50.63, 13.047]}
zoom={12}
>
<TileLayer
attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?"
/>
</Map>
</div>
)
}
export default PxMap
我认为 React 和 leaflet 之间的连接正确,地图显示正常,我可以看到叠加层正在添加等...
但是某处缺少连接,以便为 PIXI 提供更多上下文/信息。
有什么想法吗?谢谢!
终于找到问题所在,深入leaflet-pixi-overlay lib
解决方法是在Map元素中定义minZoom和maxZoom:
<Map
preferCanvas={true}
ref={mapRef}
style={{ height: '100%' }}
center={[50.63, 13.047]}
zoom={12}
minZoom={ 9} // Add these options...
maxZoom={ 16} //
在内部,L.PixiOverlay.js 依靠这两个值来定义:
// return the layer projection zoom level
projectionZoom: function (map) {return (map.getMaxZoom() + map.getMinZoom()) / 2;},
哪个又用于定义默认缩放设置?
this._initialZoom = this.options.projectionZoom(map);
....
zoom = (zoom === undefined) ? _layer._initialZoom : zoom;
var projectedPoint = map.project(L.latLng(latLng), zoom);
不确定为什么这样做,但设置这些选项可以解决问题。