D3js — геоджсон полигонов не рисуется

Я пытаюсь нарисовать карту (полигоны районов города) с помощью d3js. И все, что я получаю, это бежевый прямоугольник.

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>Lpgz crime rates</title>
    <script src = "https://d3js.org/d3.v6.min.js"></script>
    <style>
        #map {
            width: 800px;
            height: 600px;
            border: 1px solid black;
        }
        .map path {
            stroke: #999;
            stroke-width: 0.5;
        }
    </style>
</head>
<body>
    <svg id = "map" viewBox = "0 0 800 600"></svg>
    <script>
        const width = 800;
        const height = 600;
        const margin = 20;

        const svg = d3.select('#map')
            .attr('width', width)
            .attr('height', height);

        Promise.all([
            d3.json('data/Leipzig_ortsteile.geojson'),
            d3.json('data/crime_rates.json')
        ]).then(([ortsteile, crimeRates]) => {
            console.info("GeoJSON data:", ortsteile.features);
            console.info("Crime rates data:", crimeRates);

            const projection = d3.geoMercator()
                .fitSize([width, height], ortsteile);

            const pathGenerator = d3.geoPath().projection(projection);

            const colorScale = d3.scaleSequential(d3.interpolateReds)
                .domain([0, d3.max(Object.values(crimeRates))]);

            const paths = svg.selectAll('path')
                .data(ortsteile.features)
                .enter()
                .append('path')
                .attr('d', d => {
                    const pathData = pathGenerator(d);
                    console.info(`Path data for ${d.properties.Name}:`, pathData);
                    return pathData;
                })
                .attr('fill', d => {
                    const rate = crimeRates[d.properties.Name];
                    console.info(`Area: ${d.properties.Name}, Crime rate: ${rate}`);
                    return rate ? colorScale(rate) : '#ccc';
                })
                .attr('stroke', '#999')
                .attr('stroke-width', '0.5');

            console.info("SVG Paths:", paths);

        }).catch(err => console.error("Error loading data:", err));
    </script>
</body>
</html>

Вот как геоджсон выглядит внутри:

{
"type": "FeatureCollection",
"name": "log_lat",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "FID": 0, "OT": "00", "Name": "Zentrum" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 12.37927526130802, 51.344360566287889 ], [ 12.379117566590359, 51.344399728002436 ], [ 12.378953533569369, 51. ....

Я попробовал несколько вариантов, включая центрирование по координатам центра города, изменение размеров... Я не получаю никаких ошибок, и выходные данные на консоли выглядят нормально (для меня).

@AndrewReid спасибо за ваш комментарий! Пробовал перематывать с помощью Mapshaper.org, но ничего не изменилось...

Anastasiia Iurshina 23.05.2024 19:55

Возможно, я ошибся, включив в качестве опции Mapshaper - D3 использует порядок намотки, противоположный спецификации geojson (хотя, по иронии судьбы, спецификация geojson также указывает 2D-координаты и, следовательно, подразумевается внутри снаружи, и поэтому порядок намотки не имеет значения. D3 - один из них). из немногих инструментов для обработки координат как трехмерных точек на глобусе, где порядок намотки имеет значение, но противоречит спецификации geojson в отношении направления намотки - но я отвлекся), поэтому Mapshaper может на самом деле наматывать их неправильно. Однако, возможно, я что-то еще упустил, можете ли вы вообще поделиться геоджоном?

Andrew Reid 24.05.2024 05:20

@AndrewReid Я добавил файл сюда: github.com/iurshina/lpz_crime/blob/master/data/… Должно быть что-то с D3, потому что везде он выглядит нормально... (но я бэкенд-специалист и у меня очень мало опыта работы с js и геоданными, это может быть что-то очень глупое...)

Anastasiia Iurshina 24.05.2024 09:22
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, что с вашим кодом все в порядке.

Прошу прощения, что в моем комментарии была ссылка на мапшейпер - этот сервис исправляет намотку, тогда как D3 требует, чтобы она была некорректной. Я включил его, поскольку этот сервис удобен для пользователя и не требует какого-либо кода (а также, как правило, совместим с D3), в отличие от двух других проверенных вариантов. Но я никогда не использовал его раньше.

Ваш файл будет работать практически в любой другой среде карт/графиков, поскольку они рассматривают широту и долготу как плоские. Следствием этого является то, что порядок намотки не имеет значения для этих каркасов: для многоугольника внешняя часть всегда является неограниченной, а внутренняя часть ограничена.

Для D3 широта и долгота указаны на глобусе, поэтому неограниченной части нет. Весь экран имеет тот же цвет, что и последний нарисованный объект, и охватывает весь земной шар, за исключением нужной области. Таким образом, FitSize подходит для всего земного шара.

Один из способов убедиться, что ваш geojson настроен неправильно, — это вручную настроить проекцию на увеличение интересующей вас области и удалить любую заливку. Обычно вы должны увидеть контур всех ваших объектов (если все ваши объекты представляют собой тарабарщину, то у вас есть еще одна проблема: вы проецируете уже спроецированные данные).

Ниже у меня есть полный пример использования Turf для перемотки назад, хотя я понимаю, что мой связанный пример не совсем полный.

<html>
<head>
    <script src = " https://cdn.jsdelivr.net/npm/@turf/[email protected]/turf.min.js "></script>
    <script src = "https://d3js.org/d3.v6.min.js"></script>
</head>
<body>

<script>

d3.json("target.json").then(function(data) {
    
    var fixed = data.features.map(function(feature) {
        return turf.rewind(feature,{reverse:true});
    })
        

    data.features = fixed;
    
    d3.select("body").append("p")
      .text(JSON.stringify(data));
    
})
</script>

Другие вопросы по теме