four-eyes
four-eyes

Reputation: 12394

Unexpected lines/polygons when converting JSON to topoJSON

I want to display the topoJSON on a leaflet map with d3. Doing that, I follow this example hosted on GitHub. That is the code I derived from the gitHub example:

<!DOCTYPE html>

<html lang="en">

<head>
    <meta charset="utf-8">
    <title>D3 Test</title>
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css">
    <script type="text/javascript" src="https://d3js.org/d3.v3.min.js"></script>
    <script type="text/javascript" src="http://d3js.org/topojson.v1.min.js"></script>
    <script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
</head>

<body>
    <div id="map" style="width:600px; height:600px;"></div>
    <script>
            var map = new L.Map("map", {
                            center: [37.8, -96.9],
                            zoom: 4
                    })
                    .addLayer(new L.TileLayer("http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"));

            var svg = d3.select(map.getPanes().overlayPane).append('svg');
            var g = svg.append('g').attr('class', 'leaflet-zoom-hide');

            d3.json("pathToTopotJson", function(error, collection) {
                    if (error) throw error;
                    console.log(collection)

                    var bounds = d3.geo.bounds(topojson.feature(collection, collection.objects.collection));
                    var path = d3.geo.path().projection(projectPoint);

                    var feature = g.selectAll('path')
                            .data(topojson.feature(collection, collection.objects.collection).features)
                            .enter()
                            .append('path');


                    map.on('viewreset', reset);
                    reset();

                    // Reposition the SVG to cover the features.
                    function reset() {
                            var bottomLeft = projectPoint(bounds[0]),
                                    topRight = projectPoint(bounds[1]);

                            svg.attr('width', topRight[0] - bottomLeft[0])
                                    .attr('height', bottomLeft[1] - topRight[1])
                                    .style('margin-left', bottomLeft[0] + 'px')
                                    .style('margin-top', topRight[1] + 'px');

                            var translation = -bottomLeft[0] + ',' + -topRight[1];
                            g.attr('transform', 'translate(' + -bottomLeft[0] + ',' + -topRight[1] + ')');

                            feature.attr('d', path);
                    }
                    // Use Leaflet to implement a D3 geographic projection.
                    function projectPoint(x) {
                            var point = map.latLngToLayerPoint(new L.LatLng(x[1], x[0]));
                            return [point.x, point.y];
                    }

            })
    </script>

The topoJSON gets displayed. But, with unexpected Polygons/Lines: unexpected polygons

When I display the JSON the polygons/lines are not there: josn display

Whats going wrong with topoJSON? Is it something in my code or did the converting go wrong?

Upvotes: 1

Views: 223

Answers (1)

IvanSanchez
IvanSanchez

Reputation: 19069

Whats going wrong with topoJSON? Is it something in my code or did the converting go wrong?

There's nothing wrong, that is a common artifact when a polygon crosses the antimeridian.

Reproject your data to a different map projection to avoid the antimeridian altogether, or use the --spherical and --cartesian topojson command-line options to work around the problem.

You should do a bit of research into antimeridian crossings. Also, try isolating the problematic geometries (i.e. russia), and seeing if that geometry alone gets transformed to TopoJSON and displayed in a proper manner. Isolating problematic geometries will make your life easier, and will make bugs more apparent.

Upvotes: 4

Related Questions