如何使用 Mapbox 将地图添加到 Django Web 应用程序项目

如果您不知道从哪里开始,那么在 Django 网络应用程序中构建交互式地图可能会让人望而生畏,但如果您使用 Mapbox 等开发工具,这比您想象的要容易。

在这篇文章中,我们将使用单个应用程序构建一个简单的 Django 项目,并将如下所示的交互式地图添加到 Django 使用 Mapbox MapsAPI 呈现的网页。

我们的工具

本教程强烈推荐使用 Python 3,因为从 2020 年 1 月 1 日起将不再支持 Python 2。本教程使用 Python 3.6.5 构建。我们还将使用以下应用程序依赖项来构建我们的应用程序:

  • Django web 框架,版本 2.0.5
  • pip 和 virtualenv,它们随 Python 3 一起安装,用于安装 Django 库并将其与其他应用程序隔离
  • 一个免费的 Mapbox使用 JavaScript 与他们的 Web API 交互的帐户

如果您在运行此代码之前需要配置开发环境方面的帮助,请查看此指南以在 Ubuntu 16.04 LTS 上设置 Python 3 和 Django。

这篇博文的代码也可以在 GitHub 上的 blog-code-examples 存储库的 maps-django-mapbox 目录中找到。获取代码并将其用于您自己的目的,因为它都是在 MIT 开源许可下提供的。

安装依赖

通过使用以下命令创建一个新的虚拟环境来启动 Django 项目。我建议使用一个单独的目录,例如 ~/venvs/(波浪号是您用户的 home 目录的快捷方式),以便您始终知道所有 virtualenvs 的位置。

python3 -m venv djangomaps

使用 activate shell 脚本激活 virtualenv:

source djangomaps/bin/activate

激活 virtualenv 后命令提示符将发生变化:

激活你的 djangomaps virtualenv。

请记住,您必须在每个要在 virtualenv 中使用依赖项的新终端窗口中激活您的 virtualenv。

我们现在可以将 Djangopackage 安装到已激活但为空的 virtualenv 中。

pip install django==2.0.5

查找以下输出以确认已从 PyPI 正确安装 Django。

  Downloading https://files.pythonhosted.org/packages/23/91/2245462e57798e9251de87c88b2b8f996d10ddcb68206a8a020561ef7bd3/Django-2.0.5-py3-none-any.whl (7.1MB)
      100% |████████████████████████████████| 7.1MB 231kB/s 
      Collecting pytz (from django==2.0.5)
        Using cached https://files.pythonhosted.org/packages/dc/83/15f7833b70d3e067ca91467ca245bae0f6fe56ddc7451aa0dc5606b120f2/pytz-2018.4-py2.py3-none-any.whl
        Installing collected packages: pytz, django
        Successfully installed django-2.0.5 pytz-2018.4

Django 依赖项已准备就绪,现在我们可以创建我们的项目并将一些很棒的地图添加到应用程序中。

构建我们的 Django 项目

我们可以使用 Django django-admin.py 工具创建样板代码结构来启动我们的项目。切换到您开发应用程序的目录。例如,我通常使用 /Users/matt/devel/py/。然后运行以下命令启动一个名为djmaps的Django项目:

django-admin.py startproject djmaps

django-admin.py 命令将创建一个名为 djmaps 的目录以及几个您应该熟悉的子目录,如果您以前使用过 Django。

将目录更改为新项目。

cd djmaps

djmaps 中创建一个新的 Django 应用程序。

python manage.py startapp maps

Django 将为项目生成一个名为 maps 的新文件夹。我们应该更新 URL,以便在我们编写 views.py 代码之前可以访问该应用程序。

打开###。添加突出显示的行,以便 URL 将检查 djmaps/djmaps/urls.py 应用以进行适当的 URL 匹配。

""" (comments)
"""
from django.conf.urls import include
from django.contrib import admin
from django.urls import path


urlpatterns = [
    path('', include('maps.urls')),
    path('admin/', admin.site.urls),
]

保存djmaps/djmaps/urls.py并打开djmaps/djmaps/settings.py。将maps应用添加到settings.py 通过插入突出显示的行:

# Application definition

INSTALLED_APPS = [ 
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'maps',
]

在将任何代码部署到生产环境之前,请确保更改 DEBUG 中的默认 SECRET_KEYsettings.py 值。使用 Django 生产部署清单中的信息正确保护您的应用程序,这样您就不会将您的项目添加到网络上的被黑应用程序列表中。

保存并关闭settings.py

接下来进入djmaps/maps 目录。创建一个名为urls.py 的新文件以包含maps 应用程序的路由。

将这些行添加到空的 djmaps/maps/urls.py 文件中。

from django.conf.urls import url                                                                                                                              
from . import views

urlpatterns = [ 
    url(r'', views.default_map, name="default"),
]

保存 djmaps/maps/urls.py 并打开 djmaps/maps/views.py 添加以下两个突出显示的行。您可以保留样板评论或将其删除。

from django.shortcuts import render


def default_map(request):
    return render(request, 'default.html', {})

接下来,在 templates app 目录下为您的模板文件创建一个名为 djmaps/maps 的目录。

mkdir templates

default.html 中创建一个名为 djmaps/maps/templates 的新文件,其中包含以下 Django 模板标记。

<!DOCTYPE html>
<html>
  <head>
    <title>Interactive maps for Django web apps</title>
  </head>
  <body>
   <h1>Map time!</h1>
  </body>
</html>

我们可以测试这个静态页面以确保我们所有的代码都是正确的,然后我们将使用 Mapbox 在页面中嵌入一个可定制的地图。切换到 manage.py 文件所在的 Django 项目的基本目录。使用以下命令执行开发服务器:

python manage.py runserver

Django 开发服务器将启动,除了未应用的迁移警告之外没有任何问题。

Performing system checks...

System check identified no issues (0 silenced).

You have 14 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

May 21, 2018 - 12:47:54
Django version 2.0.5, using settings 'djmaps.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

打开网络浏览器并转到localhost:8000

普通的旧 HTML 页面。

我们的代码可以工作,但是男孩是一个看起来很普通的 HTML 页面。让我们通过向模板添加 JavaScript 来生成地图来让魔法发生。

使用 Mapbox 添加地图

在您的网络浏览器中前往 mapbox.com 以访问 Mapbox 主页。

Mapbox 主页。

单击“开始”或“免费开始”(文本取决于您是否已经拥有 Mapbox 帐户)。

注册一个 Mapbox 帐户。

注册一个新的免费开发者帐户或登录您现有的帐户。

将 Mapbox 添加到您的应用程序。

点击“JS Web”选项。

选择安装方法。

安装方法选择“使用 Mapbox CDN”。接下来的两个屏幕显示了一些您应该添加到您的 djmaps/maps/templates/default.html 模板文件中的代码。代码如下所示,但您需要将 mapboxgl.accessToken 行替换为您自己的访问令牌。

<!DOCTYPE html>
<html>
  <head>
    <title>Interactive maps for Django web apps</title>
    <script src='https://api.mapbox.com/mapbox-gl-js/v0.44.2/mapbox-gl.js'></script>
    <link href='https://api.mapbox.com/mapbox-gl-js/v0.44.2/mapbox-gl.css' rel='stylesheet' />
  </head>
  <body>
   <h1>Map time!</h1>
   <div id='map' width="100%" style='height:400px'></div>
   <script>
    mapboxgl.accessToken = {{ mapbox_access_token }};
    var map = new mapboxgl.Map({
     container: 'map',
     style: 'mapbox://styles/mapbox/streets-v10'
    });
   </script>
  </body>
</html>

重新打开djmaps/maps/views.py来更新传入Django模板的参数。

from django.shortcuts import render


def default_map(request):
    # TODO: move this token to Django settings from an environment variable
    # found in the Mapbox account settings and getting started instructions
    # see https://www.mapbox.com/account/ under the "Access tokens" section
    mapbox_access_token = 'pk.my_mapbox_access_token'
    return render(request, 'default.html', 
                  { 'mapbox_access_token': mapbox_access_token })

Mapbox 访问令牌确实应该存储在 Django 设置文件中,因此我们留下了“TODO”注释以作为未来的步骤处理。

现在我们可以再次尝试我们的网页。在您的网络浏览器中刷新 localhost:8000

在我们的 Django 前端显示的 Mapbox 地图的屏幕截图。

太棒了,我们有一个实时的交互式地图!它如何缩小以查看整个世界,这有点奇怪。是时候使用一些 JavaScript 参数自定义地图了。

自定义地图

我们可以通过更改样式、缩放级别、位置和许多其他属性的参数来修改地图。

我们将从更改初始地图居中的位置以及缩放级别开始。

重新打开 djmaps/maps/templates/default.html 并修改第一个突出显示的行,使其以逗号结尾,并添加如下所示的两个新突出显示的行。

<!DOCTYPE html>
<html>
  <head>
    <title>Interactive maps for Django web apps</title>
    <script src='https://api.mapbox.com/mapbox-gl-js/v0.44.2/mapbox-gl.js'></script>
    <link href='https://api.mapbox.com/mapbox-gl-js/v0.44.2/mapbox-gl.css' rel='stylesheet' />
  </head>
  <body>
   <h1>Map time!</h1>
   <div id='map' width="100%" style='height:400px'></div>
   <script>
    mapboxgl.accessToken = {{ mapbox_access_token }};
    var map = new mapboxgl.Map({
     container: 'map',
     style: 'mapbox://styles/mapbox/streets-v10',
     center: [-77.03, 38.91],
     zoom: 9
    });
   </script>
  </body>
</html>

center 数组的第一个数字 -77.03 是经度,第二个数字 38.91 是纬度。缩放级别 9 比默认级别 0 的整个世界更接近城市。所有自定义值都列在 Mapbox GL JS API 文档中。

现在在 localhost:8000 刷新页面以重新加载我们的地图。

更新后的地图以华盛顿特区为中心并放大。

太棒了,现在我们放大了华盛顿特区,并且仍然可以四处移动以查看地图的更多部分。在结束之前,让我们对我们的地图做一些其他更改。

再次返回 djmaps/maps/templates/default.html,将 style 键的突出显示行更改为 mapbox://styles/mapbox/satellite-streets-v10 值。这会将抽象地图样式的外观更改为卫星图像数据。更新 zoom: 9,使其在行尾有一个逗号,并添加 bearing: 180 作为配置中的最后一个键值对。

<!DOCTYPE html>
<html>
  <head>
    <title>Interactive maps for Django web apps</title>
    <script src='https://api.mapbox.com/mapbox-gl-js/v0.44.2/mapbox-gl.js'></script>
    <link href='https://api.mapbox.com/mapbox-gl-js/v0.44.2/mapbox-gl.css' rel='stylesheet' />
  </head>
  <body>
   <h1>Map time!</h1>
   <div id='map' width="100%" style='height:400px'></div>
   <script>
    mapboxgl.accessToken = {{ mapbox_access_token }};
    var map = new mapboxgl.Map({
     container: 'map',
     style: 'mapbox://styles/mapbox/satellite-streets-v10',
     center: [-77.03, 38.91],
     zoom: 9,
     bearing: 180
    });
   </script>
  </body>
</html>

保存模板并刷新localhost:8000

更新后的地图带有卫星图像和街道地图叠加层。

地图现在提供了覆盖街道的卫星视图,但它也是……“上下颠倒”的!由于 bearing: 180 值修改了此地图的旋转,至少与大多数地图的绘制方式相比,该地图是颠倒的。

对于我们的 Django 应用程序中的几行 JavaScript 来说还不错。请记住查看 Mapbox GL JS API 文档以获取您可以调整的详尽参数列表。

下一步是什么?

我们刚刚学习了如何将基于 JavaScript 的交互式地图添加到我们的 Django 网络应用程序,以及如何修改地图的外观。接下来尝试 Mapbox 提供的一些其他 API,包括:

  • 方向
  • 地图匹配
  • 地理编码

有问题吗?在 Twitter@fullstackpython 或@mattmakai 上通过 Full Stack Python 存储库上的 GitHub 问题单让我知道。

您是否发现这篇博文中存在拼写错误、语法问题或令人困惑的措辞?在 GitHub 上分叉此页面的源代码并提交带有修复的拉取请求或在 GitHub 上提交问题单。

赞(0) 打赏

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏