Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

D3-geo is giving incorrect result on small areas in my case #227

Closed
listenzcc opened this issue Feb 9, 2021 · 2 comments
Closed

D3-geo is giving incorrect result on small areas in my case #227

listenzcc opened this issue Feb 9, 2021 · 2 comments

Comments

@listenzcc
Copy link

listenzcc commented Feb 9, 2021

The issue is, d3-geo package is filling the whole earth instead the area, when one of my geo Polygon is small.

Following is the picture of testing case.

debug

The case can be repeated by the html code.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title D3-Geo Debug></title>
    <script src="https://d3js.org/d3.v6.min.js"></script>
</head>

<body>
    <div>
        <h1>D3-Geo Debug</h1>
        <p>It shows a strange behavior of D3-Geo</p>
        <p>If the features of geoJson is of too small and other unknown characters,</p>
        <p>D3 will parse it to filling the whole earth.</p>
    </div>

    <div style="display:flex;">
        <div id="Div-1">
            <h2>Incorrect Plot of Both Area</h2>
            <p>It supposes to be TWO SMALL Areas</p>
            <p>However, one area is shown as the whole earth,</p>
            <p>and, the black point is the other area</p>
            <p>
                coordinates: [
                [
                [
                [112.902145, 29.79149],
                [112.929246, 29.77383],
                [112.923703, 29.766557],
                [112.894138, 29.783699],
                [112.902145, 29.79149],
                ],
                ],
                [
                [
                [112.716747, 32.357612],
                [112.735841, 32.356095],
                [112.733993, 32.356601],
                [112.724138, 32.358623],
                [112.716747, 32.357612],
                ],
                ],
                ],
            </p>
        </div>

        <div id="Div-2" style="padding-left:20px;">
            <h2>Correct Plot of One Area</h2>
            <p>The zoom-in view of the black point</p>
            <p>
                coordinates: [
                [
                [
                [112.902145, 29.79149],
                [112.929246, 29.77383],
                [112.923703, 29.766557],
                [112.894138, 29.783699],
                [112.902145, 29.79149],
                ],
                ],
                ],
            </p>
        </div>
    </div>

    <script type="text/javascript">
        let geoJson1 = {
            type: "FeatureCollection",
            name: "100000_full",
            features: [
                {
                    type: "Feature",
                    properties: {
                        adcode: "xx",
                        name: "xx",
                        center: [114.298572, 30.584355],
                        centroid: [112.271286, 30.987521],
                        childrenNum: 0,
                        level: "xx",
                        parent: { adcode: 0 },
                        subFeatureIndex: 0,
                        acroutes: [0],
                    },
                    geometry: {
                        type: "MultiPolygon",
                        coordinates: [
                            [
                                [
                                    [112.902145, 29.79149],
                                    [112.929246, 29.77383],
                                    [112.923703, 29.766557],
                                    [112.894138, 29.783699],
                                    [112.902145, 29.79149],
                                ],
                            ],
                            [
                                [
                                    [112.716747, 32.357612],
                                    [112.735841, 32.356095],
                                    [112.733993, 32.356601],
                                    [112.724138, 32.358623],
                                    [112.716747, 32.357612],
                                ],
                            ],
                        ],
                    },
                },
            ]
        }

        let geoJson2 = {
            type: "FeatureCollection",
            name: "100000_full",
            features: [
                {
                    type: "Feature",
                    properties: {
                        adcode: "xx",
                        name: "xx",
                        center: [114.298572, 30.584355],
                        centroid: [112.271286, 30.987521],
                        childrenNum: 0,
                        level: "xx",
                        parent: { adcode: 0 },
                        subFeatureIndex: 0,
                        acroutes: [0],
                    },
                    geometry: {
                        type: "MultiPolygon",
                        coordinates: [
                            [
                                [
                                    [112.902145, 29.79149],
                                    [112.929246, 29.77383],
                                    [112.923703, 29.766557],
                                    [112.894138, 29.783699],
                                    [112.902145, 29.79149],
                                ],
                            ],
                        ],
                    },
                },
            ]
        }
    </script>

    <script type="text/javascript">
        console.log('You are using D3.js version of', d3.version)

        let width = 500;
        let height = 500;

        let svg1 = d3
            .select("#Div-1")
            .append("svg")
            .attr("width", width)
            .attr("height", height);

        let svg2 = d3
            .select("#Div-2")
            .append("svg")
            .attr("width", width)
            .attr("height", height);

        function draw(svg, json) {
            let features = json.features

            let projection = d3
                .geoNaturalEarth1()
                .fitSize([width, height], json)
                .rotate([0, 0, 0])
                .precision(20);

            let path = d3.geoPath(projection);

            svg
                .selectAll("path")
                .data(features)
                .enter()
                .append("path")
                .attr("d", path)
                .style("fill", function (d) {
                    console.log(d);
                    let h = parseInt(Math.random() * 360),
                        s = 0.5,
                        l = 0.5;
                    return d3.hsl(h, s, l).toString();
                })
                .style("stroke-width", 3)
                .style("stroke", "#000000")
        }

        draw(svg1, geoJson1)
        draw(svg2, geoJson2)


    </script>
</body>

</html>

@Fil
Copy link
Member

Fil commented Feb 9, 2021

The second ring in the geometry is anticlockwise, as demonstrated in this notebook

So when we paint it, we actually paint the whole globe with a tiny hole.
See #138 (comment)

@Fil Fil closed this as completed Feb 9, 2021
@listenzcc
Copy link
Author

The second ring in the geometry is anticlockwise, as demonstrated in this notebook

So when we paint it, we actually paint the whole globe with a tiny hole.
See #138 (comment)

Thanks a lot. It solves my issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants