Hack Your Maps – как создать свою карту

Измененный стиль карты
Измененный стиль карты
Несмот­ря на то, что кар­ты явля­ют­ся важ­ной частью мно­гих сай­тов и при­ло­же­ний, рабо­тать с веб-кар­та­ми мно­гие начи­на­ют толь­ко сей­час. В ста­тье «Hack Your Maps» разо­бран один из при­ме­ров созда­ния соб­ствен­ной кар­ты – как кар­ту мож­но инте­гри­ро­вать с исто­ри­ей, напри­мер, о Шер­ло­ке Холм­се.

Про­шло пять лет с момен­та напи­са­ния ста­тьи «Take Control of Your Maps», но исполь­зо­ва­ние карт все еще оста­ет­ся белым пят­ном для мно­гих дизай­не­ров. Ста­тья «Hack Your Maps» вновь обра­ща­ет­ся к вопро­су созда­ния и исполь­зо­ва­ния карт в дизайн-про­цес­се.

На самом деле, в веб-кар­тах нет ниче­го зага­доч­но­го: возь­ми­те любую про­стран­ствен­ную плос­кость, раз­де­ли­те ее на отдель­ные тай­лы (фраг­мен­ты, плит­ки), поме­сти­те их в DOM и добавь­те обра­бот­чи­ки собы­тий для пано­ра­ми­ро­ва­ния и мас­шта­би­ро­ва­ния. Эта базо­вая фор­му­ла может быть при­ме­не­на как к Порт­лан­ду, так и к Мар­су или игре Супер Марио.

Откры­тые инстру­мен­ты дают нам воз­мож­ность экс­пе­ри­мен­ти­ро­вать с раз­лич­ны­ми аспек­та­ми карт – от пози­ци­о­ни­ро­ва­ния тай­лов до фор­ма­та век­тор­ных эле­мен­тов.

В ста­тье, напи­сан­ной дизай­не­ром и раз­ра­бот­чи­ком Йон­гом Ханом (Young Hahn), рас­смат­ри­ва­ет­ся рабо­та с откры­тым кар­то­гра­фи­че­ским инстру­мен­том MapBox, где несколь­ко откры­тых биб­лио­тек были собра­ны в один API, опуб­ли­ко­ван­ный на mapbox.js (дру­гие откры­тые биб­лио­те­ки, на кото­рые вы може­те обра­тить вни­ма­ние, – Leaflet и D3.js).

Начало

Автор ста­тьи – боль­шой поклон­ник Шер­ло­ка Холм­са. Для тех, кто нико­гда не был в Лон­доне (как и он сам), мог­ла бы быть очень полез­на кар­та зна­чи­мых в кни­ге мест. Но, вме­сто того, что­бы про­сто сде­лать кар­ту таких мест рядом с тек­стом, Хан решил рас­ши­рить роль кар­ты и пол­но­стью объ­еди­нить ее с исто­ри­ей.

Варианты объединения карты с текстом
Вари­ан­ты объ­еди­не­ния кар­ты с тек­стом

Места

Для того, что­бы обес­пе­чить осно­ву исто­рии Хан рекон­стру­и­ро­вал рас­сказ «Чер­те­жи Брю­са-Пар­тинг­то­на» – выбрал 8 клю­че­вых лока­ций и важ­ные части тек­ста и офор­мил их с помо­щью HTML, CSS, и JavaScript (Demo 1).

История в текстовом виде
Исто­рия в тек­сто­вом виде
  • Исто­рия раз­би­та на эле­мен­ты section для каж­дой клю­че­вой лока­ции. С помо­щью JavaScript реа­ли­зо­ван пере­ход от одно­го эле­мен­та к дру­го­му.

Теперь мы начи­на­ем делать саму кар­ту – пока отдель­но от исто­рии.

Картографирование данных

Для кар­то­гра­фи­ро­ва­ния сокра­щен­ной исто­рии нуж­на база дан­ных из 8 гео­гра­фи­че­ских точек. GeoJSON, фор­мат для опи­са­ния гео­гра­фи­че­ских дан­ных в JSON, явля­ет­ся иде­аль­ной отправ­ной точ­кой для это­го:

{
    "geometry": { "type": "Point", "coordinates": [-0.15591514, 51.51830379] },
    "properties": { "title": "Baker St." }
}, {
    "geometry": { "type": "Point", "coordinates": [-0.07571203, 51.51424049] },
    "properties": { "title": "Aldgate Station" }
}, {
    "geometry": { "type": "Point", "coordinates": [-0.08533793, 51.50438536] },
    "properties": { "title": "London Bridge Station" }
}, {
    "geometry": { "type": "Point", "coordinates": [0.05991101, 51.48752939] },
    "properties": { "title": "Woolwich Arsenal" }
}, {
    "geometry": { "type": "Point", "coordinates": [-0.18335806, 51.49439521] },
    "properties": { "title": "Gloucester Station" }
}, {
    "geometry": { "type": "Point", "coordinates": [-0.19684993, 51.5033856] },
    "properties": { "title": "Caulfield Gardens" }
}, {
    "geometry": { "type": "Point", "coordinates": [-0.10669358, 51.51433123] },
    "properties": { "title": "The Daily Telegraph" }
}, {
    "geometry": { "type": "Point", "coordinates": [-0.12416858, 51.50779757] },
    "properties": { "title": "Charing Cross Station" }
}

Каж­дый объ­ект в мас­си­ве JSON име­ет geometry – дан­ные, кото­рые опи­сы­ва­ют рас­по­ло­же­ние это­го объ­ек­та в про­стран­стве, properties – дан­ные, кото­рые мы выби­ра­ем, что­бы опи­сать объ­ект. Имея такие дан­ные, мож­но создать базо­вую кар­ту (Demo 2):

Базовая карта
Базо­вая кар­та

Обра­ти­те вни­ма­ние на то, что коор­ди­на­ты – это широ­та и дол­го­та. Все еще нет опре­де­лен­но­го поряд­ка, поэто­му неко­то­рые исполь­зу­юn lat, lon, а неко­то­рые – lon, lat.

Хан исполь­зу­ет mapbox.js как основ­ную биб­лио­те­ку. Каж­дая кар­та – это набор клю­че­вых пара­мет­ров, пере­да­ва­е­мых в mapbox.map():

  1. DOM element container.
  2. Один или боль­ше сло­ев Photoshop, пози­ци­о­ни­ру­ю­щих тай­лы и мар­ке­ры.
  3. Обра­ботч­ки собы­тий, кото­рые свя­зы­ва­ют поль­зо­ва­тель­ский ввод с дей­стви­ем, напри­мер, пере­тас­ки­ва­ни­ем.

За локациями

Пер­во­на­чаль­ная кар­та – это несколь­ко точек, не содер­жа­щих в себе ника­кой тай­ны и интри­ги. Что­бы это изме­нить, мы можем исполь­зо­вать для каж­дой лока­ции иллю­стра­ции – клю­че­вые собы­тия рас­ска­за. Теперь вид­но, что это не толь­ко точ­ки в про­стран­стве (Demo 3 и diff).

Измененный стиль карты
Изме­нен­ный стиль кар­ты
  • Основ­ное изме­не­ние здесь в том, что мы опре­де­ли­ли factory function для слоя с мар­ке­ра­ми. Factory function берет каж­дый объ­ект GeoJSON и кон­вер­ти­ру­ет его в эле­мент DOM – a, div, img или какой-либо дру­гой.
  • Здесь мы гене­ри­ру­ем div и начи­на­ем испль­зо­вать вме­сто title в GeoJSON аттри­бут id. Это дает нам воз­мож­ность исполь­зо­вать CSS для отоб­ра­же­ния иллю­стра­ций на мар­ке­рах.

Соединение всего вместе

Теперь вре­мя соеди­нить исто­рию с кар­той. С помо­щью скрол­ла – пере­хо­да, кото­рый мы созда­ли в самом нача­ле, – мы можем коор­ди­ни­ро­вать сек­ции исто­рии с места­ми на кар­те, созда­вая еди­ный опыт пере­жи­ва­ния рас­ска­за – в то вре­мя, как поль­зо­ва­тель чита­ет каж­ду сек­цию, на кар­те высве­чи­ва­ет­ся новая лока­ция (смот­реть Demo 4, зачем читать diff).

Объединенная карта
Объ­еди­нен­ная кар­та
  • Связь меж­ду исто­ри­ей и кар­той – это setActive() функ­ция (ранее она отве­ча­ла толь­ко за скролл, теперь она так­же нахо­дит актив­ный мар­кер и класс).
  • Кар­ты исполь­зу­ет биб­лио­те­ку в mapbox.js API для ани­ма­ции и пере­ме­ще­ния меж­ду гео­гра­фи­че­ски­ми лока­ци­я­ми.
  • Мы отклю­чи­ли все обра­бот­чи­ки собы­тий на кар­те, пере­дав пустой мас­сив в mapbox.map(). Теперь кар­та изме­ня­ет­ся толь­ко за счет скрол­ла сек­ций исто­рии. Если мы ходим дать поль­зо­ва­те­лю воз­мож­ность откло­нить­ся от сюжет­ной линии или иссле­до­вать Лон­дон, то мы можем вновь вклю­чить обра­бот­чик собы­тий.

На этой ста­дии исто­рия и кар­та хоро­шо допол­ня­ют друг дру­га. Кар­та добав­ля­ет про­стран­ствен­ный кон­текст, визу­аль­ную интри­гу и вре­мен­ной эле­мент в рас­сказ.

Ваша собственная карта

Если вы вни­ма­тель­но сле­ди­ли за кодом, то, веро­ят­но, заме­ти­ли, что неко­то­рые вещи, напри­мер ease.optimal() или как исполь­зо­вать аттри­бут title дан­ных в GeoJSON. Весь код и дизайн вы може­те най­ти здесь – GitHub repository.

Дан­ный при­мер – это один из спо­со­бов инте­гра­ции кар­ты в ваш дизайн. Не оста­нав­ли­вай­тесь на этом – сде­лай­те что-то свое и про­буй­те новое.