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

По этой теме уже есть одно обучающее руководство  —  “Планы на отпуск с Python и HERE Maps”. Представленный же здесь материал абсолютно самодостаточен, так что можно начать с него, а потом ради интереса ознакомиться с предыдущей статьей. Какими-то технологиями мы воспользуемся повторно, но кое-что обязательно усовершенствуем. В конце вы узнаете, как развернуть приложение на Heroku, чтобы друзья тоже смогли увидеть ваше творение. 

Поехали! 

Создание проекта 

Требования 

  • Лучшие фотографии с отпуска; 
  • Координаты посещенных мест. Для выполнения задачи воспользуемся библиотекой Python geopy:
pip install geopy
  • Легковесный фреймворк для веб-приложений Flask:  
pip install Flask
  • Аккаунт HERE developer. Здесь предоставлены инструкции по созданию API-ключа, который нужен для выполнения вызова к HERE maps из приложения. 
  • Аккаунт Heroku. Данный инструмент служит для создания и запуска приложений в облаке. В настоящее время можно бесплатно разместить на платформе одно приложение при отсутствии необходимости в платном аккаунте.

Написание кода 

  1. Создаем новый файл Python, например app_runner.py, и вставляем следующий код: 
from flask import Flask,render_template
app = Flask(__name__)

@app.route('/')
def render_map():
return render_template('map.html')

if __name__ == '__main__':
app.run(debug = True)

2. Создаем новую директорию в каталоге проекта под названием templates и там же файл map.html

3. Вставляем следующие содержимое: 

<html>  
<head>
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<script src="https://js.api.here.com/v3/3.1/mapsjs-core.js"type="text/javascript" charset="utf-8"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-service.js"type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-mapevents.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-ui.js"></script>
<link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.1/mapsjs-ui.css" />
</head>
<body style='margin: 0'>
<div style="width: 100%; height: 100%" id="map"></div>

<script>
function addMarkerToGroup(group, coordinate, html) {
var marker = new H.map.Marker(coordinate);
marker.setData(html);
group.addObject(marker);
}

function addInfoBubble(map) {
var group = new H.map.Group();

map.addObject(group);

group.addEventListener('tap', function (evt) {
var bubble = new H.ui.InfoBubble(evt.target.getGeometry(), {
content: evt.target.getData()
});
ui.addBubble(bubble);
}, false);

addMarkerToGroup(group, {lat:41.3806533, lng:2.1899274},
'<div>Our arrival at Barceloneta Beach...</div>' +
'</div><img width=200 height=200 src="https://images.unsplash.com/photo-1536012283419-09392f86fb35?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=334&q=80"></img></div>');

// TODO: добавляем здесь дополнительные маркеры
}

var platform = new H.service.Platform({
'apikey': 'your_api_key'
});

var defaultLayers = platform.createDefaultLayers();

var map = new H.Map(document.getElementById('map'), defaultLayers.vector.normal.map, {
// расположение Барселоны
center: new H.geo.Point(41.3828939, 2.1774322),
zoom: 11.5,
pixelRatio: window.devicePixelRatio || 1
});

window.addEventListener('resize', () => map.getViewPort().resize());
// Поведение реализует предустановленные взаимодействия для панорамирования/масштабирования
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
var ui = H.ui.UI.createDefault(map, defaultLayers);

addInfoBubble(map);

</script>
</body>
</html>

Рассмотрим наиболее важные части кода.

  • Импортируем требуемые скрипты для рендеринга карты. 
  • Обязательно заменяем apikey HERE своими. 
  • Для проекта выбран город Барселона, чье расположение по умолчанию указывается на карте. 
  • Функция addMarkerToGroup() добавляет место на карту. В данном примере был создан один маркер  —  Barceloneta Beach. В ближайшее время рассмотрим, как получить координаты из местоположения. Эта функция позволяет добавлять столько угодно мест. 
  • Функция addEventListener('tap') вызывается при касании на местоположение. 
  • Функция addInfoBubble() отображает пользовательский текст и фотографию при нажатии на маркер. 

4. Для извлечения широты и долготы местоположения создаем отдельный файл Python со следующим кодом: 

from geopy.geocoders import Nominatim

geolocator = Nominatim(user_agent="coordinates_finder")
location = geolocator.geocode("Barceloneta")
print(location.address)
print((location.latitude, location.longitude))

Только что с помощью библиотеки geopy мы получили координаты: 

la Barceloneta, Ciutat Vella, Barcelona, Barcelonès, Barcelona, Catalunya, 08001, España
(41.3806533, 2.1899274)

Обратите внимание, что вместо имени можно также передать адрес местоположения. 

5. Повторяем этот шаг применительно ко всем местам посещения. 

6. Добавляем маркеры на пользовательскую карту. По сути, нужно добавить еще больше мест на карту с помощью метода addMarkerToGroup

  • Добавляем широту и долготу. 
  • Настраиваем нужные ширину и высоту изображения. 
  • Заменяем фото URL своим. 

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

Тестирование проекта

Теперь локально запускаем приложение Flask: 

python3 app_runner.py

Открываем браузер http://127.0.0.1:5000/ и кликаем на маркеры: 

Информационные пузырьки с фотографиями на пользовательской карте HERE

Отлично! Фотографии отображаются согласно замыслу. 

Продолжайте экспериментировать с маркерами HTML-кода, придавая информационным пузырькам более интересный вид. 

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

Развертывание приложения на Heroku 

Пора сделать приложение общедоступным. Мы развернем его на Heroku и поделимся ссылкой с друзьями. 

  1. Создаем файл requirements.txt в директории проекта: 
Flask==1.1.1
gunicorn==19.9.0
Jinja2==2.10.1

Этот файл уведомит Heroku о библиотеках, подлежащих установке. Версии можно свободно менять. 

2. Создаем Procfile в каталоге проекта: 

web: gunicorn app_runner:app

Данный файл определяет команды, которые должна выполнить Heroku для запуска приложения. Команда web запускает веб-сервер, используя gunicorn в качестве HTTP-сервера Python WSGI. Приложение называется app_runner на основе файла app_runner.py.

3. Авторизуемся на Heroku и создаем новое приложение: 

4. Существуют разные стратегии для развертывания приложения на Heroku. В этом примере воспользуемся Heroku CLI. Его нужно скачать. 

5.Инициализируем новый репозиторий Git в каталоге проекта: 

git init

6. Добавляем приложение в удаленный репозиторий: 

heroku git:remote -a here-maps-demo

7. Отправляем изменения: 

git add .
git commit -m "added app files"
git push heroku master

Готово!

Вы увидите, как на Heroku происходит развертывание приложения. Если все идет по плану, то в конце вывода команды появится URL приложения. 

remote: https://here-maps-demo.herokuapp.com/ deployed to Heroku

Открываем URL приложения, и перед нами  —  итоговый результат выполненной работы: 

Демо карты HERE с информационными пузырьками

Теперь ваши друзья смогут освежить прекрасные воспоминания и даже скачать фотографии из приложения. 

Заключение

Вот вы и узнали, как создать пользовательскую карту с помощью API HERE maps. Результатом работы стало простое и общедоступное веб-приложение на основе Flask, которое мы развернули на Heroku.  

Обратите внимание, что не рекомендуется афишировать API-ключи в репозитории Git. В статье этот вопрос затронут не был, но если вы намереваетесь дорабатывать приложение, то рассмотрите использование config vars на Heroku.

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

Читайте также:

Читайте нас в TelegramVK и Яндекс.Дзен


Перевод статьи Kirshi Yin: Build a Python Flask App To See the Places You’ve Travelled

Предыдущая статьяПо маршруту SQLite - Pandas: 7 основных операций
Следующая статьяKotlin-реализация RecyclerView на Android