2

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>
        )
    }
}
Heather
  • 141
  • 2
  • 11

2 Answers2

5

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

Vadim Gremyachev
  • 57,952
  • 20
  • 129
  • 193
0

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>
  ) 
}
Alex Parij
  • 1,168
  • 1
  • 14
  • 21
  • I have edited the question to show the code: But this error appears: ```Warning: Failed prop type: The prop `data` is marked as required in `GeoJSON`, but its value is `undefined`. in GeoJSON (created by MapViz) in MapViz (created by App)``` – Heather Feb 10 '17 at 19:32
  • your geoData is undefined, check if you properly loading the test_topo or getting the right properties of it – Alex Parij Feb 10 '17 at 19:50