2017-02-15 6 views
4

Учитывая EPSG проекция (скажем, это Alabama один: [http://spatialreference.org/ref/epsg/26729/][1])Преобразование EPSG проекции границы на D3.js

Как вы можете взять данные WGS84 проекции границы таким образом, что вы можете использовать их в Проекция D3.js.

Например, как вы узнаете, какую проекцию, степень поворота или ограничительную рамку использовать для отображения карты?

ответ

9

Это довольно сложный вопрос. Ответ будет отличаться в зависимости от системы пространственной привязки (SRS или системы справочной системы координат (CRS)), на которую вы смотрите, и какова ваша конечная цель.

Я использую d3.js v4 в этом ответе

Короткий ответ:

Например, как бы вы знаете, что проекция, степень вращения или ограничительной рамки, чтобы использовать, чтобы показать карта?

Не существует жестких и быстрых правил, которые охватывают все проекции. Глядя на параметры проекции, вы обычно можете получить достаточную информацию для быстрого создания проекции - при условии, что проекция выходит из окна в d3.

Наилучший совет, который я могу дать при настройке параметров, например, при повороте или в центре, какие параллели использовать и т. Д., Заключается в том, чтобы увеличить масштаб при уточнении проекции, чтобы вы могли видеть, что делает каждый параметр, и где ты смотришь. Затем сделайте свое масштабирование или степень подгонки. Это и использовать валидатор geojson для вашей ограничивающей рамки, например this one.

Наконец, вы всегда можете использовать прогнозируемые данные и падение d3.geoProjection в целом (this question), если все ваши данные уже проецируется в той же проекции, пытаясь определить проекция является спорным вопросом.


Геодезические

Я быстро отметить, что этот вопрос может быть осложнено еще больше, если вы смотрите на различия между датумами. Например, ссылка SRS, на которую вы ссылались, использовала NAD27 datum. Датой является математическое представление земной формы, NAD27 будет отличаться от NAD83 или WGS84, хотя все они измеряются в градусах, так как базовая единица представляет трехмерную поверхность земли. Если вы смешиваете данные, в которых используются конфликтующие данные, вы можете столкнуться с некоторыми проблемами точности, например, смещение нулевой точки между NAD27 и NAD83 не является незначительным в зависимости от ваших потребностей (скриншот wikipedia, не может ссылаться на изображение):

enter image description here

Если смена мест в местах из-за использования нескольких баз данных является проблемой, вам потребуется больше, чем d3, чтобы преобразовать их в одну стандартную датум. D3 предполагает, что вы будете использовать WGS84, базовую станцию, используемую системой GPS. Если эти сдвиги не являются проблемой, тогда игнорируйте эту часть ответа.


В Примере Проекция

Итак, давайте посмотрим на ваши проекциях EPSG:26729:

PROJCS["NAD27/Alabama East", 
    GEOGCS["NAD27", 
     DATUM["North_American_Datum_1927", 
      SPHEROID["Clarke 1866",6378206.4,294.9786982138982, 
       AUTHORITY["EPSG","7008"]], 
      AUTHORITY["EPSG","6267"]], 
     PRIMEM["Greenwich",0, 
      AUTHORITY["EPSG","8901"]], 
     UNIT["degree",0.01745329251994328, 
      AUTHORITY["EPSG","9122"]], 
     AUTHORITY["EPSG","4267"]], 
    UNIT["US survey foot",0.3048006096012192, 
     AUTHORITY["EPSG","9003"]], 
    PROJECTION["Transverse_Mercator"], 
    PARAMETER["latitude_of_origin",30.5], 
    PARAMETER["central_meridian",-85.83333333333333], 
    PARAMETER["scale_factor",0.99996], 
    PARAMETER["false_easting",500000], 
    PARAMETER["false_northing",0], 
    AUTHORITY["EPSG","26729"], 
    AXIS["X",EAST], 
    AXIS["Y",NORTH]] 

Это довольно стандартное описание проекции. Каждый тип проекции будет иметь параметры, характерные для него, поэтому они не всегда будут одинаковыми.

Наиболее важные части этого описания являются:

NAD27/Alabama East имя проекции, не требуется, но хорошая ссылка, как это немного легче запомнить, чем числа EPSG, а также ссылки/инструменты могут использовать только общее название вместо номера EPSG.

PROJECTION["Transverse_Mercator"] Тип проекции, с которым мы имеем дело. Это определяет, как 3d-координаты, представляющие точки на поверхности земли, переводятся в 2d-координаты на декартовой плоскости. Если вы видите проекцию здесь, которая не указана в списке поддерживаемых прогнозов d3 (v3 - v4), то вам придется немного поработать над определением пользовательской проекции. Но, как правило, вы найдете проекцию, которая соответствует этому. Тип проекции изменяет, поворачивается ли карта или центрируется на каждой оси.

PARAMETER["latitude_of_origin",30.5], 
PARAMETER["central_meridian",-85.83333333333333], 

Эти два параметра устанавливают центр проекции. Для поперечного Меркатора важно только центральный меридиан. See this demo of the effect of choosing a central meridian on a transverse Mercator.

Широта происхождения, главным образом, используется для установки опорной точки для northnigs. Центральный меридиан делает это также для восточных, но, как отмечено выше, устанавливает центральный меридиан, в котором искажение сводится к минимуму от полюса к полюсу (оно эквивалентно экватору на обычном Меркаторе). Если вам действительно нужны правильные северные и восточные районы, так что вы можете сравнить местоположения x, y с бумажной картой и веб-карту, разделяющую одну и ту же проекцию, d3, вероятно, не лучший автомобиль для этого. Если вы не заботитесь о измерении координат в декартовом пространстве координат, эти параметры не имеют значения: D3 не реплицирует систему координат проекции (измеряется в футах как ложные восточные/северные), но воспроизводит ту же форму в координате SVG пространство.


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

d3.geoTransverseMercator() 
    .rotate([85.8333,0]) 
    .center([0,30.5]) 

Почему я повернуть примерно на 86 градусов? Так создается поперечный Меркатор. В demo поперечного Меркатора карта поворачивается вдоль оси х. Центрирование по оси x будет просто панорамировать карту влево и вправо и не изменять характер проекции. В demo ясно, что проекция претерпевает изменения, принципиально отличающиеся от панорамирования, это применяемое вращение. Используемое вращение отрицательно, так как я поворачиваю землю под проекцию. Таким образом, эта проекция сосредоточена на -85,833 градуса или 85,8333 градуса на запад.

Поскольку на поперечном Меркаторе искажение согласовано вдоль меридиана, мы можем панорамировать вниз и не поворачиваться.Вот почему я использую центр по оси y (в этом случае, а в других случаях вы также можете вращать на оси y с отрицательным y, так как это будет вращать цилиндрическую проекцию под картой, давая тот же результат, что и панорамирование).

Если мы масштаб изображения справедливого бита, это то, что проекция выглядит следующим образом:

enter image description here

Это может выглядеть довольно искаженном, но оно предназначено только для отображения области в и вблизи Алабаме. Увеличение в нем начинает выглядеть намного более нормальным:

enter image description here

Следующий вопрос, естественно: Что о масштабах? Это будет отличаться в зависимости от размера вашего окна просмотра и области, которую вы хотите показать. И ваша проекция не указывает никаких границ. Я коснусь ограничений в конце ответа, если вы хотите показать степень проекции карты. Даже если проекция имеет границы, они могут очень не совпадать с областью, которую вы хотите показать (которая обычно является подмножеством общих границ проекции).

Как насчет центровки в другом месте? Скажите, вы хотите показать только город, который не попадает в центр проекции? Ну, мы можем использовать центр. Поскольку мы повернули землю по оси x, любое центрирование относительно центрального меридиана. Центрирование до [1,30.5] будет центрировать карту на 1 градус к востоку от центрального меридиана (85,8333 градуса запад). Таким образом, х-компонента будет относиться к вращению, у-компонент будет относиться к экватору - его широте).

Если придерживаться проекции важно, это странное поведение центрирования необходимо, если нет, то может быть проще просто изменить вращение х, так что у вас есть выступ, который выглядит следующим образом:

d3.geoTransverseMercator() 
    .center([0,y]) 
    .rotate([-x,0]) 
    ... 

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


различных проекциях Типы

Различные проекции могут иметь различные параметры. Например, конические проекции могут иметь одну (касательную) или две (секущие) линии, они представляют точки, где проекция пересекает землю (и, следовательно, где минимизация искажений). Эти выступы (такие как Альберс или Ламберт) используют подобный метод для центрирования (повернуть -x, центр у), но имеют дополнительный параметр, чтобы указать параллели, которые представляют собой тангенс или секущие линии:

d3.geoAlbers() 
    .rotate([-x,0]) 
    .center([0,y]) 
    .parallels([a,b]) 

See this answer on how to rotate/center an Albers (что по существу одинаково для всех конических проекций, которые приходят на ум в данный момент).

Плоский/азимутальный projeciton (который я еще не проверял), скорее всего, будет только по центру. Но каждая проекция карты может иметь несколько иной метод в «центрировании» (обычно комбинация .rotate и .center).

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


обрамлению Коробка

Однако, вы можете иметь проекцию, которая определяет границу. Или, скорее, image with a bounds and a projection. В этом случае вам нужно будет указать эти границы. Это легко делается с помощью функции GeoJSON с использованием .fitExtent методом d3.geoProjection():

projection.fitExtent (степень, объект):

Устанавливает масштаб проекции и перевести под заданный объект GeoJSON в центре данной степени. Степень указана как массив [[x₀, y₀], [x₁, y₁]], где x₀ - левая сторона ограничивающего блока, y₀ - верхняя, x₁ - правая, а y₁ - нижняя. Возвращает проекцию.

(смотри также this question/answer)

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

enter image description here

Прежде чем перейти к координатам ограничительной рамки, давайте посмотрим на проекцию. В этом случае это что-то like:

PROJCS["ETRS89/Austria Lambert", 
    GEOGCS["ETRS89", 
     DATUM["European_Terrestrial_Reference_System_1989", 
      SPHEROID["GRS 1980",6378137,298.257222101, 
       AUTHORITY["EPSG","7019"]], 
      AUTHORITY["EPSG","6258"]], 
     PRIMEM["Greenwich",0, 
      AUTHORITY["EPSG","8901"]], 
     UNIT["degree",0.01745329251994328, 
      AUTHORITY["EPSG","9122"]], 
     AUTHORITY["EPSG","4258"]], 
    UNIT["metre",1, 
     AUTHORITY["EPSG","9001"]], 
    PROJECTION["Lambert_Conformal_Conic_2SP"], 
    PARAMETER["standard_parallel_1",49], 
    PARAMETER["standard_parallel_2",46], 
    PARAMETER["latitude_of_origin",47.5], 
    PARAMETER["central_meridian",13.33333333333333], 
    PARAMETER["false_easting",400000], 
    PARAMETER["false_northing",400000], 
    AUTHORITY["EPSG","3416"], 
    AXIS["Y",EAST], 
    AXIS["X",NORTH]] 

Как мы будем позволить d3 выбрать масштаб и центральную точку на основе прямоугольника, мы заботимся только о нескольких параметрах:

PARAMETER["standard_parallel_1",49], 
PARAMETER["standard_parallel_2",46], 

Это две секущие линии, где проекция карты перехватывает поверхность земли.

PARAMETER["central_meridian",13.33333333333333], 

Это центральный меридиан, число мы будем использовать для вращения проекции вдоль оси х (как один будет делать для всех конических выступов, которые приходят на ум).

И самое главное:

PROJECTION["Lambert_Conformal_Conic_2SP"], 

Эта линия дает нам проекция семьи/тип.

В целом это дает нам что-то вроде:

d3.geoConicConformal() 
    .rotate([-13.33333,0] 
    .parallels([46,49]) 

Теперь, ограничивающий прямоугольник, который определяется этими пределами:

  • Восток: 17.2 градусов
  • West: 9,3 градуса
  • Север: 49,2 градуса
  • Юг: 46.0 градусов

The .fitExtent.fitSize) методами взять объект GeoJSON и переводить и масштабировать проекцию соответствующим образом. Здесь я буду использовать .fitSize, так как он пропускает поля по границам (fitExtent позволяет создавать поля, это единственная разница). Поэтому нам нужно создать объект GeoJSON с этими границами:

var bbox = {   
      "type": "Polygon", 
      "coordinates": [ 
      [ 
       [9.3, 49.2], [17.2, 49.2], [17.2, 46], [9.3, 46], [9.3,49.2] 
      ] 
      ] 
     } 

Не забывайте использовать right hand rule, и иметь свой конечный пункт такой же в качестве точки старта (бесконечная печаль в противном случае).

Теперь все, что нам нужно сделать, это назвать этот метод, и у нас будет наша проекция. Поскольку я использую изображение для проверки параметров проекции, я знаю соотношение сторон, которое я хочу. Если вы не знаете соотношение сторон, у вас может быть некоторая избыточная ширина или высота. Это дает мне что-то вроде:

var projection = d3.geoConicConformal() 
.parallels([46,49]) 
.rotate([-13.333,0]) 
.fitSize([width,height],bbox) 

И счастливый глядя конечный продукт, как (имея в виду сильно понижающей дискретизации мира topojson):

enter image description here


+2

Просто совет: поставить короткий ответ * перед тем * полный ответ. –

+1

Дарн, я знал, что должен был назвать эту часть заключением или резюме и более конкретно предоставил короткий ответ вверх: «Это зависит». –

+1

Я знаю, что это против политики StackOverflow, но @AndrewReid, это один из лучших ответов, которые я видел на этом сайте. Невероятно полезно и полезно. Благодарим вас за внимание! – aboutaaron

Смежные вопросы