在 React 传单中使用 Geojson 和大量数据
Using Geojson with tons of data in react leaflet
我正在使用 react-leaflet 的 GeoJson 来显示一个区域的所有多边形。但是,当数据量增加到 10000 时,性能变差,我的应用程序出现性能问题,导致它变慢和滞后。如何提高 GeoJSON 在大数据上的性能?
我的代码:
<Header />
<MapContainer center={[10.7743, 106.6669]} zoom={5}>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<GeoJSON
style={LayerStyle}
data={polygonData.features}
onEachFeature={onEachContry}
/>
</MapContainer>
polygonData.features的数据很大,有10万条记录
您可以尝试将您的大 geojson
转换为 topojson
。因为
topojson eliminates redundancy, allowing related geometries to be stored
efficiently in the same file
如前所述 here,当您在传单地图上渲染它时,您可以获得更小的文件大小并因此获得更好的性能。
您可以使用此 site 将巨大的 geojson(17.1mb) 转换为 topojson(2.7mb)。
您可以看到转换后的大小差异。请注意,它没有无限的免费转换能力。
之后,您可以创建自己的 React 包装器来渲染 topojson
。为此,您可以使用 Vadim 的回答 。它需要一些调整才能与 react-leaflet v.3.x
兼容,并且能够在每个县添加弹出窗口,但在进行一些小的更改后,您可以在 topojson
中可视化您的巨大 geojson
因为它是正常的 geojson
.
function TopoJSON(props) {
const layerRef = useRef(null);
const { data, ...otherProps } = props;
function addData(layer, jsonData) {
if (jsonData.type === "Topology") {
for (let key in jsonData.objects) {
let geojson = topojson.feature(jsonData, jsonData.objects[key]);
layer.addData(geojson);
}
} else {
layer.addData(jsonData);
}
}
function onEachFeature(feature, layer) {
if (feature.properties) {
const { VARNAME_3, NAME_0 } = feature.properties;
layer.bindPopup(`${VARNAME_3}, ${NAME_0}`);
}
}
useEffect(() => {
const layer = layerRef.current;
addData(layer, props.data);
}, [props.data]);
return (
<GeoJSON ref={layerRef} {...otherProps} onEachFeature={onEachFeature} />
);
}
并像这样使用它:
import topojson from "./phuong.json";
<MapContainer ..>
...
<TopoJSON data={topojson} />
</MapContainer>
一种方法是减少 GeoJSON 中的功能。 GeoJSON 很大(55MB),因为它有很多地理点,可以使用工具 Mapshaper (mapshaper.org).
进行简化
之前
之后
我正在使用 react-leaflet 的 GeoJson 来显示一个区域的所有多边形。但是,当数据量增加到 10000 时,性能变差,我的应用程序出现性能问题,导致它变慢和滞后。如何提高 GeoJSON 在大数据上的性能? 我的代码:
<Header />
<MapContainer center={[10.7743, 106.6669]} zoom={5}>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<GeoJSON
style={LayerStyle}
data={polygonData.features}
onEachFeature={onEachContry}
/>
</MapContainer>
polygonData.features的数据很大,有10万条记录
您可以尝试将您的大 geojson
转换为 topojson
。因为
topojson eliminates redundancy, allowing related geometries to be stored efficiently in the same file
如前所述 here,当您在传单地图上渲染它时,您可以获得更小的文件大小并因此获得更好的性能。
您可以使用此 site 将巨大的 geojson(17.1mb) 转换为 topojson(2.7mb)。 您可以看到转换后的大小差异。请注意,它没有无限的免费转换能力。
之后,您可以创建自己的 React 包装器来渲染 topojson
。为此,您可以使用 Vadim 的回答 react-leaflet v.3.x
兼容,并且能够在每个县添加弹出窗口,但在进行一些小的更改后,您可以在 topojson
中可视化您的巨大 geojson
因为它是正常的 geojson
.
function TopoJSON(props) {
const layerRef = useRef(null);
const { data, ...otherProps } = props;
function addData(layer, jsonData) {
if (jsonData.type === "Topology") {
for (let key in jsonData.objects) {
let geojson = topojson.feature(jsonData, jsonData.objects[key]);
layer.addData(geojson);
}
} else {
layer.addData(jsonData);
}
}
function onEachFeature(feature, layer) {
if (feature.properties) {
const { VARNAME_3, NAME_0 } = feature.properties;
layer.bindPopup(`${VARNAME_3}, ${NAME_0}`);
}
}
useEffect(() => {
const layer = layerRef.current;
addData(layer, props.data);
}, [props.data]);
return (
<GeoJSON ref={layerRef} {...otherProps} onEachFeature={onEachFeature} />
);
}
并像这样使用它:
import topojson from "./phuong.json";
<MapContainer ..>
...
<TopoJSON data={topojson} />
</MapContainer>
一种方法是减少 GeoJSON 中的功能。 GeoJSON 很大(55MB),因为它有很多地理点,可以使用工具 Mapshaper (mapshaper.org).
进行简化