I want to create a React Native app that displays coordinates stored in a PostGIS database on a world map with a special map projection.
I successfully loaded the map to a React environment for my web version of the app. This is the code I implemented (only including the component that holds the map):
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;
This is the resulting map from above code:
I also researched how to implement SVG shapes and even maps to React Native and came across several ways of doing so:
However, I could not implement any map using these solutions. The former two in the above list don't mention any map implementation and the latter one seems to be a very early beta version. So I am wondering if this is even currently possible in React Native. Does anybody know an approach to inserting an SVG map in React native?
It is possible to create d3 maps in react native. The thing is you cant use Dom selectors like d3.select(). You need to use react-native-svg. Read the documentation here learn how to install and use it. Its implementaion is really close to the browser SVG API.
You import the Svg, G, and Path components
import Svg, { G, Path } from "react-native-svg";
You create a projection and path in the usual d3 manner.
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)
The features are also extracted the same way.
let features = feature(landmass, landmass.objects.land).features
But we dont append components using d3. We append the Svg and G components directly.
return (
<Svg width='100%' height='100%'>
<G>
</G>
</Svg> )
The width and height can be styled as required.
Next the paths are appended but mapping the featurers Array to create path components.
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> )
If you need help in rotating the svg ask in the comments to this answer.