如何将 SVG/d3 映射添加到 React Native?
How to add an SVG/d3 map to React Native?
用例
我想创建一个 React Native 应用程序,它在具有特殊地图投影的世界地图上显示存储在 PostGIS 数据库中的坐标。
到目前为止我做了什么
我已成功将地图加载到我的网络版应用程序的 React 环境中。这是我实现的代码(只包括持有地图的组件):
import React, { useEffect, useRef } from 'react';
import Aux from '../../../../hoc/Auxiliary';
import styles from './Backmap.module.css';
import * as d3 from "d3";
import { feature } from "topojson-client";
import landmass from "./../../../../land-50m";
const Backmap = (props) => {
const mapContainer = useRef(null);
let width = props.windowSize.windowWidth;
let height = props.windowSize.windowHeight;
useEffect(() => {
const svg = d3.select(mapContainer.current)
.attr("width", width)
.attr("height", height)
const g = svg.append("g")
let features = feature(landmass, landmass.objects.land).features
let projection = d3.geoAzimuthalEqualArea()
.center([180, -180])
.rotate([0, -90])
.fitSize([width, height], { type: "FeatureCollection", features: features })
.clipAngle(150)
let path = d3.geoPath().projection(projection)
g.selectAll("#landmass")
.data(features)
.enter().append("path")
.attr("id", "landmass")
.attr("d", path);
}, [])
return (
<Aux>
<svg
className={styles.Backmap}
width={props.windowSize.windowWidth}
height={props.windowSize.windowHeight}
ref={mapContainer}
>
</svg>
</Aux>
)
}
export default Backmap;
这是上面代码生成的地图:
我还研究了如何实现 SVG 形状甚至映射到 React Native,并遇到了几种实现方式:
- react-native-svg(SVG)
- React Native ART(SVG)
- react-native-simple-maps(地图)
问题
但是,我无法使用这些解决方案实现任何地图。上面列表中的前两个没有提到任何地图实现,而后一个似乎是一个非常早期的测试版。所以我想知道这在 React Native 中目前是否可行。有人知道在 React native 中插入 SVG 地图的方法吗?
可以在 React Native 中创建 d3 地图。问题是你不能使用像 d3.select() 这样的 Dom 选择器。
你需要使用 react-native-svg。
阅读文档 here 了解如何安装和使用它。它的实现非常接近浏览器 SVG API。
您导入 Svg、G 和路径组件
import Svg, { G, Path } from "react-native-svg";
您以通常的 d3 方式创建投影和路径。
let projection = d3.geoAzimuthalEqualArea()
.center([180, -180]).rotate([0, -90])
.fitSize([width, height], { type: "FeatureCollection", features: features })
.clipAngle(150)
let path = d3.geoPath().projection(projection)
同样提取特征
let features = feature(landmass, landmass.objects.land).features
但我们不使用 d3 附加组件。我们直接附加 Svg 和 G 组件。
return (
<Svg width='100%' height='100%'>
<G>
</G>
</Svg> )
宽度和高度可以根据需要设置样式。
接下来附加路径,但映射特征数组以创建路径组件。
return (
<Svg width='100%' height='100%'>
<G>
{features.map((feature, index) => {
return (<Path d={path(feature)} key={index} stroke="black" fill="grey"></Path>)
})}
</G>
</Svg> )
如果您在旋转 svg 方面需要帮助,请在对此答案的评论中提问。
用例
我想创建一个 React Native 应用程序,它在具有特殊地图投影的世界地图上显示存储在 PostGIS 数据库中的坐标。
到目前为止我做了什么
我已成功将地图加载到我的网络版应用程序的 React 环境中。这是我实现的代码(只包括持有地图的组件):
import React, { useEffect, useRef } from 'react';
import Aux from '../../../../hoc/Auxiliary';
import styles from './Backmap.module.css';
import * as d3 from "d3";
import { feature } from "topojson-client";
import landmass from "./../../../../land-50m";
const Backmap = (props) => {
const mapContainer = useRef(null);
let width = props.windowSize.windowWidth;
let height = props.windowSize.windowHeight;
useEffect(() => {
const svg = d3.select(mapContainer.current)
.attr("width", width)
.attr("height", height)
const g = svg.append("g")
let features = feature(landmass, landmass.objects.land).features
let projection = d3.geoAzimuthalEqualArea()
.center([180, -180])
.rotate([0, -90])
.fitSize([width, height], { type: "FeatureCollection", features: features })
.clipAngle(150)
let path = d3.geoPath().projection(projection)
g.selectAll("#landmass")
.data(features)
.enter().append("path")
.attr("id", "landmass")
.attr("d", path);
}, [])
return (
<Aux>
<svg
className={styles.Backmap}
width={props.windowSize.windowWidth}
height={props.windowSize.windowHeight}
ref={mapContainer}
>
</svg>
</Aux>
)
}
export default Backmap;
这是上面代码生成的地图:
我还研究了如何实现 SVG 形状甚至映射到 React Native,并遇到了几种实现方式:
- react-native-svg(SVG)
- React Native ART(SVG)
- react-native-simple-maps(地图)
问题
但是,我无法使用这些解决方案实现任何地图。上面列表中的前两个没有提到任何地图实现,而后一个似乎是一个非常早期的测试版。所以我想知道这在 React Native 中目前是否可行。有人知道在 React native 中插入 SVG 地图的方法吗?
可以在 React Native 中创建 d3 地图。问题是你不能使用像 d3.select() 这样的 Dom 选择器。 你需要使用 react-native-svg。 阅读文档 here 了解如何安装和使用它。它的实现非常接近浏览器 SVG API。
您导入 Svg、G 和路径组件
import Svg, { G, Path } from "react-native-svg";
您以通常的 d3 方式创建投影和路径。
let projection = d3.geoAzimuthalEqualArea()
.center([180, -180]).rotate([0, -90])
.fitSize([width, height], { type: "FeatureCollection", features: features })
.clipAngle(150)
let path = d3.geoPath().projection(projection)
同样提取特征
let features = feature(landmass, landmass.objects.land).features
但我们不使用 d3 附加组件。我们直接附加 Svg 和 G 组件。
return (
<Svg width='100%' height='100%'>
<G>
</G>
</Svg> )
宽度和高度可以根据需要设置样式。
接下来附加路径,但映射特征数组以创建路径组件。
return (
<Svg width='100%' height='100%'>
<G>
{features.map((feature, index) => {
return (<Path d={path(feature)} key={index} stroke="black" fill="grey"></Path>)
})}
</G>
</Svg> )
如果您在旋转 svg 方面需要帮助,请在对此答案的评论中提问。