如何将SVG / d3映射添加到React Native?

用例

我想创建一个React Native应用,该应用在具有特殊地图投影的世界地图上显示存储在PostGIS数据库中的坐标。

到目前为止我做了什么

我已成功将地图加载到应用程序的Web版本的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 / d3映射添加到React Native?

我还研究了如何实现SVG形状,甚至映射到React Native,并发现了几种实现方法:

问题

但是,我无法使用这些解决方案来实现任何地图。上面列表中的前两个没有提及任何地图实现,而后一个似乎是非常早期的beta版本。所以我想知道在React Native中目前是否还可以做到这一点。有人知道在React native中插入SVG地图的方法吗?

songqian729 回答:如何将SVG / d3映射添加到React Native?

可以在react native中创建d3映射。问题是您不能使用d3.select()之类的Dom选择器。 您需要使用react-native-svg。 阅读文档here,了解如何安装和使用它。它的实现确实接近浏览器SVG API。

您导入Svg,G和Path组件

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的帮助,请在此答案的注释中询问。

本文链接:https://www.f2er.com/2741643.html

大家都在问