Проблема с D3.JS и Flask - попытка получить карту США

1

Я работаю над проектом с использованием D3.JS и Flask, пытающихся отобразить карту США. Проблема в том, что карта не отображается. Я знаю, что элемент SVG привязан, что данные json проходят, но сама карта не подходит. Затем я попытался создать простой документ index.html и поместил json файл в этот проект, и с помощью простого Python-сервера можно было увидеть карту. Итак, теперь для кода.

Для начала здесь JS-код:

   <script type="text/javascript">

    //Define default path generator
    let path = d3.geo.path();

    //Creating the SVG element and attaching it to the page.
    let svg = d3.select("#us-map")
       .append("svg")
       .attr("width", 900)
       .attr("height", 700);

     //This function will get the data for the map of the U.S
     d3.json("/json", function(json){
         console.log(json.features) //This shows an array of 52 objects
         //Bind data and create one path per GeoJSON feature
         svg.selectAll("path")
            .data(json.features)
            .enter()
            .append("path")
            .attr("d", path);
         });

     </script>

Код Python:

@app.route("/json")
def json():
    data = Data()
    data_file = data.convert_json_for_d3()
    #return data_file
    return data_file.to_json()

Метод в классе, который я вызываю из приведенного выше кода:

  def convert_json_for_d3(self):
    self.__data = pd.read_json('us-states.json')
    df = self.__data
    return df

HTML:

<section id="us-map">
    <h1>UFO Sitings in the U.S.</h1>
</section>

Я работаю над этим уже целый день. Сначала получение данных json, работающих с D3, было сложной задачей. Я подумал, что у меня это было в тот момент. Однако, как я уже сказал, карта не появляется. Он работает, если я помещаю его в простой файл index.html вместе с json. Так что мне интересно, стоит ли проблема с Flask? Один последний момент, я следую по коду из книги "Интерактивная визуализация данных для Интернета". Репозиторий github, который я вытаскивал, приведен здесь: https://github.com/alignedleft/d3-book/blob/master/chapter_12/01_paths.html

Работая с простым файлом HTML, данные отображаются следующим образом:

        object {type: "FeatureCollection", features: Array(52)}
           features:Array(52)
             0:Object
               geometry: Object
                 coordinates: Array(1)
                  0: Array (33)
                   0
                   1
                   :
            1:Object
            :

Data in my Flask Project looks like this:
Object {features: Object, type: Object}
   features: Object
       0: Object 
         geometry: Object
          coordinates: Array(1)
             0: Array (33)

            0:Array(2)
   1: Object
   :

Таким образом, и массив объектов почти идентичен, за исключением самой первой строки.

Спасибо за любую помощь.

Теги:
d3.js
flask

1 ответ

1
Лучший ответ

Два вопроса (на основе комментариев ниже и обновленного вопроса)

Один из них - проект geojson в вашем проекте Flask. Например, функции должны быть массивом, а не объектом, тип все равно должен быть featureCollection (это обсуждается в комментариях ниже). Где-то вдоль линии ваша структура geojson изменяется на то, что не принято d3.geo.path() как действительный geojson.

Во-вторых, вы не используете проекцию для преобразования ваших пар широты и долготы (в геометрии каждой функции) в координатное пространство svg.

По второму вопросу:

При использовании d3.geo.path(); вам нужно указать проекцию (например: d3.geo.path().projection(d3.geo.mercator());). Если вы не обеспечиваете проекцию, используется нулевая проекция. Это интерпретирует предоставленный geojson без применения каких-либо преобразований - по существу ваши значения переводятся в значения пикселей на svg.

Соединенные Штаты находятся в западном полушарии, поэтому все долготы являются отрицательными (и по мере того как северный юг географические значения возрастают, так как один идет на север, а значения svg y возрастают по мере того, как один движется вниз, изображение будет перевернуто). Нулевая проекция (без другого преобразования на svg) будет рисовать путь, который находится слева от ваших границ svg. Вот почему эти три вещи могут случиться:

  • "элемент SVG прикрепляется"
  • "что данные json проходят", но
  • "сама карта не [визуально] подходит"

Геоисон, упомянутый в главе, на которой вы ссылаетесь, представляет собой непроектированные данные - он содержит пару широт и долготу для каждой вершины: [-133.05341,56.125739]. Это идеально, так как d3.geo.projection берет этот тип координат, точки на трехмерном эллипсоиде и проектирует их на двумерную декартову плоскость. Если у вас уже есть плоские данные, вам нужно будет использовать геоинформацию.

Таким образом, чтобы визуализировать ваши данные, вам нужно будет выбрать проекцию для преобразования пар широты и долготы в соответствующие значения. Американские альберсы могут быть самыми легкими, поскольку это сложная проекция, которая уменьшает Аляску и перемещает как Аляску, так и Гавайи ближе к континентальным США. Albers USA также устанавливает все параметры проецирования, чтобы показать США без изменения параметров проецирования (центр, поворот, параллели, масштаб и т.д.), В то время как для других прогнозов потребуется установка правильных параметров.

Я получил ваши данные для отображения с проекцией albersUsa, используя следующий код:

var projection = d3.geo.albersUsa().translate([width/2,height/2]);

var path = d3.geo.path().projection(projection);

d3.json("us.json",function(data) {

    svg.append("path")
      .datum(data)
      .attr('d',path)
      .attr('fill','steelblue')
      .attr('stroke','black');

});

Вот рабочая демонстрация и скриншот:

Изображение 174551

Если ваша карта слишком велика для вашего svg (или наоборот), вы можете установить масштаб с помощью projection.scale(n), при меньшем увеличении числа, увеличьте масштаб.

  • 0
    Андрей спасибо за информацию! Я могу заставить его отображаться и вне моего проекта Flask. Проблема в том, что он не отображается в моем проекте Flask. Я попытался вставить ваш код и получил ту же проблему - SVG есть, данные есть, но нет карты :(. Как я могу взять свой код, как будто, вставить его в файл HTML, запустить простой сервер Python и он работает нормально. Это похоже на проблему с Flask, которая вообще не имеет смысла для меня. Когда я console.log мои данные, я вижу массив с 52 объектами. Но я думаю, что вы правы, что карта там, но не появляется!
  • 0
    Просто чтобы прояснить, я использовал ваш код в своем проекте и та же проблема! :(
Показать ещё 10 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню