Также не я, хотя есть проблемы с геоджонами, которые не связаны с его действительностью, всегда полезно выполнить проверку ошибок с помощью d3.json и т. Д.,

даю карту с D3.js. Я начал с загрузки шейп файла страны (Канада) здесь:https://www.arcgis.com/home/item.html?id=dcbcdf86939548af81efbd2d732336db

..и преобразовал его в геойсон здесь (ссылка на файл ниже):http://mapshaper.org/

Пока все, что я вижу, это цветной блок, без каких-либо ошибок на консоли. У меня вопрос, как я могу узнать, если мой файл JSON или мой код неверен? Вот мой код, а внизу - ссылка на файл json.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>D3: Setting path fills</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
        <!-- <script src="https://d3js.org/topojson.v1.min.js"></script> -->
        <style type="text/css">
        /* styles */       
        </style>
    </head>
    <body>
        <script type="text/javascript">
        var canvas = d3.select("body").append("svg")
        .attr("width", 760)
        .attr("height", 700)
        d3.json("canada.geo.json", function(data) {
        var group = canvas.selectAll("g")
        .data(data.features)
        .enter()
        .append("g")

        var projection = d3.geo.mercator();
        var path = d3.geo.path().projection(projection);
        var areas = group.append("path")
        .attr("d",path)
        .attr("class","area")
        })
        </script>
    </body>
</html>

Ссылка на файл json:https://github.com/returnOfTheYeti/CanadaJSON/blob/master/canada.geo.json

Ответы на вопрос(2)

что это действительный JSON - тогда вы можете просто проанализировать его с помощью javascript и проверить на наличие ошибок.

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

// where data is your JSON data
try {
    console.log(JSON.parse(data));
} catch (e) {
    console.error(e);
}

Однако, поскольку вы уже используете D3, вы можете просто использовать метод d3.json для проверки на наличие ошибок. Добавьте дополнительный параметр к вызову d3.

d3.json("canada.geo.json", function(error, canada) {
  if (error) return console.error(error);
  console.log(canada);
});

Видеть:https://github.com/d3/d3-3.x-api-reference/blob/master/Requests.md

 Fraser23 нояб. 2017 г., 06:11
Почему отрицательный голос?
 Rob23 нояб. 2017 г., 06:41
Это хорошо для konw, так как он выдал ошибку: «неожиданный символ в строке 1 столбца 1 данных JSON». Но та же ошибка возникает из-за некоторых других контрольных файлов JSON, которые я также скачал. Это говорит о том, что это больше с моим кодом, возможно? (также я не понизил вас)
 Andrew Reid23 нояб. 2017 г., 07:03
Также не я, хотя есть проблемы с геоджонами, которые не связаны с его действительностью, всегда полезно выполнить проверку ошибок с помощью d3.json и т. Д.,
Решение Вопроса

трехмерном глобусе. GeoProjection берет эти координаты и проецирует их на двухмерную плоскость. Единицами непроецированных координат обычно являются градусы долготы и широты, и геопроекция d3 ожидает этого. Проблема в том, что ваши данные уже спроектированы.

Как я могу узнать, проецируются ли данные?

Существует два быстрых способа определить, проецируются ли ваши данные:

посмотрите на метаданные данных

посмотрите на географические координаты сами

Посмотрите на географические метаданные

Проекция, которую используют ваши данные, определяется в файле .prj, который является частью набора файлов, составляющих шейп-файл:

PROJCS["Canada_Albers_Equal_Area_Conic",
   GEOGCS["GCS_North_American_1983",
      DATUM["D_North_American_1983",
        SPHEROID["GRS_1980",6378137.0,298.257222101]],
      PRIMEM["Greenwich",0.0],
      UNIT["Degree",0.0174532925199433]],
  PROJECTION["Albers"],
  PARAMETER["False_Easting",0.0],
  PARAMETER["False_Northing",0.0],
  PARAMETER["Central_Meridian",-96.0],
  PARAMETER["Standard_Parallel_1",50.0],
  PARAMETER["Standard_Parallel_2",70.0],
  PARAMETER["Latitude_Of_Origin",40.0],
  UNIT["Meter",1.0]]

Ваши данные уже спроецированы с помощью проекции Альберса, а единицей измерения является метр. Проецирование этих данных, как будто они состоят из пар широта / длинна, не будет работать.

Если у вас есть только файл geojson и нет ссылочного шейп-файла, некоторые файлы geojson будут указывать номер EPSG в свойствах проекции, если это число отличается от 4326, вы, вероятно, имели проецируемые данные.

Посмотрите на координаты

Вы можете сказать, что ваши данные не имеют непроецированных данных, потому что значения каждой координаты находятся за пределами долготы и широты (+/- 180 градусов восток / запад, +/- 90 градусов север юг):

"coordinates":[[[[899144.944639163,2633537.

Ваши координаты перемещаются по всему земному шару несколько раз: именно поэтому ваша проекция приводит к тому, что svg полностью заполнен объектами.

Хорошо, что теперь?

Вам доступны два основных решения:

Преобразуйте проекцию так, чтобы геойсон состоял из точек широты и долготы

Используйте d3.geoTransform или d3.geoIdentity для преобразования ваших проецируемых данных.

Преобразовать проекцию

Для этого вы хотите «отменить» ваши данные или, наоборот, спроецировать их так, чтобы они состояли из точек долготы и широты.

Большая часть программного обеспечения ГИС предлагает возможность перепроектировать данные. С шейп-файлом это намного проще, чем с геоджоном, поскольку шейп-файлы гораздо чаще встречаются в программном обеспечении ГИС. GDAL, QGIS, ArcMap предлагают относительно простую конвертацию.

Есть также онлайн-конвертеры, mapshaper.org, вероятно, самый простой для этого, и он имеет дополнительные преимущества при работе с d3 - упрощением (многие шейп-файлы содержат слишком много деталей для целей веб-картографирования). Перетащите все файлы шейп-файла в окно mapshaper, откройте консоль и введите:proj wgs84, Экспортируйте как геойсон (после упрощения), и у вас будет готов геоджон для d3.

После перепроектирования вы можете заметить, что ваши данные выглядят неловко. Не волнуйтесь, он не проецируется (ну, вроде как не проецируется, он отображается как 2d, но с очень простой проекцией, которая предполагает декартовы входные данные).

С вашими непроецированными данными вы теперь готовы проецировать свои данные в d3.

Вотпример с вашими данными (d3-v4. данные упрощены и перепроектированы на mapshaper (не принадлежность ко мне))

Использование d3.geoIdentity или d3.geoTransform

Для этого я бы порекомендовал использовать d3v4 (я вижу, ваш код v3). Хотя geo.transform доступен в v3, он гораздо более громоздок без новых методов, доступных в v4, а именно: d3.geoIdentity и projection.fitSize. Я расскажу о методе v4 использования прогнозируемых данных здесь

С вашими данными вы можете определить другой вид проекции:

var projection = d3.geoIdentity();

Однако этот тип «проекции» доставит вам неприятности, если вы не будете осторожны. Он в основном выплевывает значения x, y, которые ему даны. Однако географически спроецированные координатные пространства обычно имеют [0,0] где-то внизу слева, а svg координатное пространство имеет [0,0] в левом верхнем углу. В координатном пространстве SVG значения y увеличиваются по мере того, как вы спускаетесь по координатной плоскости, в проецируемом координатном пространстве ваших данных значения y увеличиваются по мере того, как вы поднимаетесь. Использование идентификатора, следовательно, будет проецировать ваши данные с ног на голову.

К счастью, мы можем использовать:

var projection = d3.geoIdentity()
   .reflectY(true);

Остается еще одна проблема: координаты в геойсоне не масштабируются и не переводятся так, чтобы объекты были правильно отцентрированы. Для этого есть метод fitSize:

   var projection = d3.geoIdentity()
       .reflectY(true)
       .fitSize([width,height],geojsonObject)

Здесь ширина и высота - это ширина и высота SVG (или родительского контейнера, в котором мы хотим отобразить объект), а объект geojsonObject - это объект геоджона. Обратите внимание, что это не займет массив функций, если у вас есть массив функций, поместите их в коллекцию функций.

Вот ваши данные показаны с использованием этого подхода (я все еще упростил геойсон).

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

Плюсы и минусы каждого варианта:

Отпроектирование данных:

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

Но у вас также есть высокая степень гибкости в том, как вы показываете эти данные, используя любой d3 geoProjection. Использование непроецированных данных также позволяет упростить выравнивание разных слоев: вам не нужно беспокоиться о масштабировании и преобразовании нескольких слоев по отдельности.

Хранение спроецированных данных

Сохраняя проекцию поступающих данных, вы экономите на вычислительном времени, не прибегая к сферической математике. Недостатками являются перечисленные выше недостатки, трудно сопоставить данные, которые не разделяют эту проекцию (что хорошо, если вы экспортируете все, используя эту проекцию), и вы застряли с представлением - d3.geoTransform не предлагает много в способ преобразования вашей проекции, скажем, от Меркатора до Альберса.

Обратите внимание, что метод fit.size (), который я использовал для второго варианта выше, доступен для всех geoProjection (v4).

В двух примерах я использовал ваш код, где это возможно. Несколько предостережений, однако, я изменил на d3v4 (например, d3.geo.path -> d3.geoPath, d3.geo.mercator -> d3.geoMercator). Я также изменил имя вашей переменнойcanvas вsvg, поскольку это выбор SVG, а не холст. Наконец, в первом примере я не изменил вашу проекцию, и центр меркатора по умолчанию имеет значение [0,0] (в длинном / латинском), что объясняет нечетное позиционирование

 Andrew Reid23 нояб. 2017 г., 07:33
Рад быть в состоянии помочь - обратите внимание, что перепроецирование в mapshaper действительно требует, чтобы включить файл .prj в шейпе - без него нет опорной точки.
 Rob23 нояб. 2017 г., 07:29
Фантастически полезный Андрей. добавление 'proj wgs84' к консоли в mapshaper решило мою непосредственную проблему, а остальная часть того, что вы предоставили, вероятно, решит другие будущие проблемы. Приветствия.

Ваш ответ на вопрос