2
votes

I just started using the react-leaflet library and got a map to load with a geoJSON layer, however I would like to use a TopoJSON layer instead.

I know that it is possible with pure Leaflet like this: https://gist.github.com/rclark/5779673/.

But how would I go about doing this with React-Leaflet?

Edit

class MapViz extends React.Component {

    getStyle() {...};

    render() {
        const position = [x,y];
        var geoData = topojson.feature(test_topo,test_topo.objects).geometries;
        return (
            <Map id="my-map" center={position} zoom={10.2}>
                <TileLayer ... />
                <GeoJSON data={geoData} style={this.getStyle} />
            </Map>
        )
    }
}
2

2 Answers

4
votes

Based on the provided TopoJSON layer the following component for rendering TopoJSON could be introduced for react-leaflet library

import React, { useRef, useEffect } from "react";
import { GeoJSON, withLeaflet } from "react-leaflet";
import * as topojson from "topojson-client";

function TopoJSON(props) {
  const layerRef = useRef(null);
  const { data, ...defProps } = 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);
    }
  }

  useEffect(() => {
    const layer = layerRef.current.leafletElement;
    addData(layer, props.data);
  }, []);

  return <GeoJSON ref={layerRef} {...defProps} />;
}

export default withLeaflet(TopoJSON);

Notes:

Usage

<Map center={[37.2756537,-104.6561154]} zoom={5}>
    <TileLayer
      attribution='&amp;copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
      url="https://{s}.tile.osm.org/{z}/{x}/{y}.png"
    />
     <TopoJSON
      data={data}
      />
</Map>

Result

enter image description here

Here is a live demo

0
votes

It is very similar to the gist you linked. You need to convert from TopoJSON to GeoJSON and set the data as usually you do with GeoJSON. It can be in your render method

 import topojson from 'topojson';
 ....
 ....


render() {
  geoData = topojson.feature(topoData,topoData.objects).features;

  return (
    <LeafletMap>
      <GeoJson
        data={geoData}
      />
     </LeafletMap>
  ) 
}