面向 Web 开发人员的最佳在线制图工具调查:路线图路线图
已发表: 2022-03-11没有什么能比得上一张好的、有用的地图了。
今天,使用在线地图是一个简单而引人入胜的过程。 制作自己的在线地图不再是一项艰巨的任务; 我们拥有各种可用的在线地图工具,从免费和简单到功能丰富且使用复杂。 对于不熟悉 Web 制图的 Web 开发人员来说,选择的痛苦可能令人生畏。 您想制作地图,但不知道从哪里开始,也不知道使用哪些工具。 我是来帮助这个最好的映射工具列表的。
一点点历史
从一开始,技术就对地图制作和地图的使用方式产生了影响。 随着技术的进步,制图和制图过程也随之发展,从在纸莎草纸上手动绘制的地图到网络上的交互式地图。
20 世纪下半叶是制图学的转折点。 计算机成为首选工具。 航空摄影、卫星图像和遥感改变了收集空间数据的方式。 地理信息系统 (GIS) 诞生了。 最终,GIS 地图开始从桌面转移到网络,大型 GIS 供应商开始制作第一个在线地图框架。
但 GIS 制图并不容易。 它需要许多服务器端技术、地理空间标准和协议,以及它们的实现。 它需要了解地理空间数据和地图投影,了解如何收集数据、如何显示数据、使用哪种颜色、如何将数据概括为特定比例、如何在地图上放置标签、如何设置服务地图的服务器,如何使用空间数据库等等。 GIS充满了缩写,如WMS、WFS、EPSG、CRS、SLD、GML、TMS等等,要了解和理解它们,需要阅读书籍、学术论文和文章。
在线地图的演变
第一个 web 地图通常只显示一个非常小的地图图像。 当时,平移是通过在八个可能的指南针方向之一(N、NW、W、SW、S、SE、E、NE)上移动一步(通常是地图大小的一半)来实现的。 用户单击平移或缩放按钮后,需要在地图服务器上渲染一个全新的图像,通过网络加载,然后由浏览器处理。 由于技术的限制,地图只占整个网页很小的一部分。 为了获得更好的交互性,早期的地图需要 Flash 等插件或基于 Java 的专有插件,甚至是仅在 Internet Explorer 中工作的 ActiveX。
谷歌在 2005 年推出谷歌地图时颠覆了地图世界。在其创新中,谷歌通过拖动引入了连续平移。 他们的解决方案是显示一张地图,该地图被分割成许多称为“图块”的较小方形图像。 这些瓦片是从“地图瓦片服务器”渲染和提供的,通常为 256 x 256 像素。 缩放和平移现在只需要加载新的地图图块,而不是重新加载整个网页。 结果是一个更大的可见地图,覆盖了浏览器窗口的一半以上,并为探索地图提供了流畅的体验。 由于能够通过平滑的缩放和平移功能“滑动”地图,这些新地图被称为“滑动地图”。 谷歌还允许编写脚本,因此用户可以将谷歌的地图放在自己的网站上,并将自己的数据添加到地图中。 这导致另一个新术语被创造出来:“地图混搭”。
突然间,在线地图变得流行起来; 要将漂亮的地图添加到您的网站,您不再需要成为制图师或 GIS 专家。 随着“Web 2.0”运动的兴起,在 HTML5、CSS3 和 SVG 等现代技术的基础上,可以轻松创建交互式内容,交互式地图现在正在经历新的复兴。
地图数据
如前所述,早期的在线地图基于 GIS 数据集及其空间地理数据库。 没有多少人可以访问这些数据,更不用说它的价格标签了。 谷歌和 OpenStreetMap (OSM) 项目数据集改变了这一点。 谷歌的数据库是私有的并且有限制,而 OSM 的灵感来自维基百科的概念,作为一个创建免费世界地图的协作项目。 OpenStreetMap 由志愿者地图绘制者社区构建,他们贡献和维护空间数据。
简而言之,今天有助于轻松制作地图的最大革命是与维护地图服务器和空间数据库相关的麻烦已被消除。
选择 Web 映射框架
那么,有了所有选项,我们如何选择正确的在线地图工具? 一方面,有谷歌、MapQuest、微软和诺基亚等商业在线地图提供商。 这些服务提供地图图块和适当的 JavaScript API 来查看它们并与地图交互。 另一方面,有一些开源地图项目可以轻松加载基于 OpenStreetMap 的地图图块。 其中包括 OpenLayers 和 Leaflet。 然后是 MapBox 和 CartoDB 等项目,它们的业务模型基于开源库和 OSM 数据,提供附加值但不是免费的。
让我们看一下这些类别中的一些示例。 在这里,我将讨论其中的几个在线地图工具,提供每个工具的简要概述以及代码示例,并权衡利弊。 我们还编写了一个 D3.js 映射教程,您可能会觉得单独阅读它会很有趣。
谷歌地图
让我们从最明显的选择开始,谷歌地图。 Google Maps API 的第一个版本于 2005 年 2 月推出,当前的 Google Maps API v3 于 2009 年 6 月推出。Google Maps API 不仅仅是 JavaScript API 端点; 它包含更多项目,并提供多种不同的方式将 Google 地图嵌入到具有广泛自定义功能的网页中。
当前可用的 Google Maps API 包括:
- 谷歌地图 JavaScript API
- 谷歌静态地图 API
- 谷歌地图嵌入 API
- 适用于 iOS 的 Google 地图 SDK
- 谷歌地图 Android API v2
为了帮助您选择正确的 API,Google 开发了一个 API 选择器。
值得注意的是,虽然基本 API 是免费的,但存在一些限制。 首先是地图必须对最终用户免费和公开访问。 其次是使用限制:只要您的网站在任何 90 天内每天生成的地图加载量不超过 25,000 次,该服务就是免费的。 如果您需要更大的比例尺或想要私人地图,或者您正在运行企业或商业网站,您应该考虑为 Google Maps API for Work 付费。
执行
下面是一个如何在代码中实现简单的 Google 地图的示例。 它展示了如何使用 API 创建一个简单的地图,在地图上放置一个标记,并通过鼠标单击打开一个弹出窗口。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="http://maps.google.com/maps/api/js?sensor=false"></script> </head> <body> <div></div> <script type="text/javascript"> var map = new google.maps.Map(document.getElementById('map'), { zoom: 10, center: new google.maps.LatLng(45.8167, 15.9833), mapTypeId: google.maps.MapTypeId.ROADMAP }); var infowindow = new google.maps.InfoWindow(); var marker = new google.maps.Marker({ position: new google.maps.LatLng(45.8167, 15.9833), map: map }); google.maps.event.addListener(marker, 'click', (function(marker) { return function() { infowindow.setContent("Zagreb"); infowindow.open(map, marker); } })(marker)); </script> </body> </html>
生成的地图如下所示:
优点
- 由谷歌开发和维护。
- 许多不同的 API 用于在您的网站或应用程序中包含地图。
- 庞大的用户社区。
- 非常好的 API 文档,有很多示例。
缺点
- 我们确定我们不会在某个时候看到添加吗?
- 每个人都在使用它; 所有地图(大部分)看起来都一样。
- 封闭和适当的 API。
- 除了谷歌官方开发的插件外,没有插件。
- Google Maps for Work 的定价不明确。
开放层
OpenLayers 是由 MetaCarta 开发的与 Google Maps 相当的开源软件,第一个版本于 2006 年 6 月发布。OpenLayers 是一个在线地图工具,它实现了用于构建基于 Web 的丰富地理应用程序的 JavaScript API,其 API 类似于谷歌地图 API。 OpenLayers 很快就获得了很大的吸引力,并且一开始的发展也很快。 OpenLayers 2 在 2006 年 8 月版本 1 之后仅两个月发布。该库一直在开发中,并且不断添加具有新功能的新版本。 这种快速进步的缺点是版本 2 库变得非常庞大和笨重,最终达到 1MB 大小并包含超过 100,000 行代码! 尽管它具有许多功能,但普通用户并不需要所有功能。
这是对其库进行全面重写的主要原因。 目标是针对最新的 HTML5 和 CSS3 功能,具有与 OpenLayers 2 相同的功能,例如支持投影、标准协议和编辑功能。 主要关注的是性能改进、更轻的构建、更漂亮的可视化组件和更好的 API。 这个大大改进的 OpenLayers 3 于 2014 年 8 月发布。
执行
让我们看看与上一个示例中的地图有何相同,这次使用的是 OpenLayers 3。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="http://openlayers.org/en/v3.2.1/build/ol.js"></script> <link rel="stylesheet" href="http://openlayers.org/en/v3.2.1/css/ol.css" type="text/css"> <script src="http://openlayers.org/en/v3.2.1/resources/jquery.min.js"></script> <script src="http://openlayers.org/en/v3.2.1/resources/bootstrap/js/bootstrap.min.js"></script> <link rel="stylesheet" href="http://openlayers.org/en/v3.2.1/resources/bootstrap/css/bootstrap.min.css" type="text/css"> </head> <body> <div class="map"> <div></div> </div> <script type="text/javascript"> var iconFeature = new ol.Feature({ geometry: new ol.geom.Point(ol.proj.transform([15.9833, 45.8167], 'EPSG:4326', 'EPSG:3857')), name: 'Zagreb', }); var iconStyle = new ol.style.Style({ image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({ anchor: [0.5, 46], anchorXUnits: 'fraction', anchorYUnits: 'pixels', opacity: 0.75, src: 'http://ol3js.org/en/master/examples/data/icon.png' })) }); iconFeature.setStyle(iconStyle); var vectorSource = new ol.source.Vector({ features: [iconFeature] }); var vectorLayer = new ol.layer.Vector({ source: vectorSource }); var map = new ol.Map({ target: document.getElementById('map'), layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }), vectorLayer ], controls: ol.control.defaults(), view: new ol.View({ center: ol.proj.transform([15.9833, 45.8167], 'EPSG:4326', 'EPSG:3857'), zoom: 10 }) }); var element = document.getElementById('popup'); var popup = new ol.Overlay({ element: element, positioning: 'bottom-center', stopEvent: false }); map.addOverlay(popup); map.on('click', function(evt) { var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature, layer) { return feature; }); if (feature) { var geometry = feature.getGeometry(); var coord = geometry.getCoordinates(); popup.setPosition(coord); $(element).popover({ 'placement': 'top', 'html': true, 'content': feature.get('name') }); $(element).popover('show'); } else { $(element).popover('destroy'); } }); map.on('pointermove', function(e) { if (e.dragging) { $(element).popover('destroy'); return; } var pixel = map.getEventPixel(e.originalEvent); var hit = map.hasFeatureAtPixel(pixel); map.getTarget().style.cursor = hit ? 'pointer' : ''; }); </script> </body> </html>
结果:
优点
- 免费和开源。
- 功能丰富的库,可满足您的映射需求。
- 很多例子。
- 支持一系列数据类型和 GIS 标准。
- 内置支持地图投影和编辑功能。
缺点
- 版本 3 仍在大力开发中,API 仍在随着每个点的发布而变化。
- 复杂的 API 语法。
- 版本 3 文档目前还没有达到应有的全面性。
传单
可以肯定地说,Leaflet 的诞生是为了应对 OpenLayers 的臃肿、杂乱和复杂性。 Vladimir Agafonkin 被要求围绕 OpenLayers 构建一个包装器,但他创建了一个简单且轻量级的 OpenLayers 替代方案,并于 2011 年 5 月诞生了 Leaflet。 Vladimir 专注于这个在线地图工具的简单性、性能和可用性。 核心库只有基本功能,对于大多数实际用例来说已经足够了。 尽管如此,Leaflet 仍然可以使用大量易于开发和添加到核心库之上的插件进行扩展。 此外,Leaflet 是在考虑移动支持的情况下从头开始开发的。
Leaflet 易于使用,并具有文档完善的 API,以及 GitHub 上提供的简单源代码。 由于它专注于性能、可用性、简单性、小尺寸和移动支持,它比 OpenLayers 复杂得多。
Leaflet 的未来看起来也很有趣。 根据 Vladimir 的说法,他计划让下一个主要版本更加简单,进一步提高性能,并升级插件基础设施。
执行
这是和以前一样的地图,这次是使用 Leaflet 实现的。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script> <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" /> </head> <body> <div></div> <script type="text/javascript"> var map = L.map('map').setView([45.8167, 15.9833], 10); var mbUrl = 'https://{s}.tiles.mapbox.com/v3/{id}/{z}/{x}/{y}.png'; L.tileLayer(mbUrl, {id: 'examples.map-i875mjb7'}).addTo(map); var marker = L.marker([45.8167, 15.9833]).bindPopup("Zagreb").addTo(map); </script> </body> </html>

优点
- 免费和开源。
- 小而快。
- 简单易用的 API 语法。
- 移动友好。
- 非常适合快速轻松地获取在线地图。
- 大量示例和非常好的文档。
缺点
- 缺乏高级功能。
地图框
一家名为 MapBox 的初创公司正试图彻底改变在线制图市场,其目标是构建更好看、更通用的在线地图。 MapBox JavaScript API 使用 Leaflet,并被编写为 Leaflet 插件。 它扩展了 Leaflet 功能,并与其他 MapBox Web 服务集成,包括用于用户创建的自定义地图和数据集的 MapBox 托管。 除了 JavaScript API,MapBox 还包括以下连接服务:
- 移动 iOS 和 Android SDK。
- 一组预先设计的地图。
- 无需映射库即可显示的静态地图。
- 地理编码服务。
- 方向服务。
MapBox 不仅提供地图服务,还提供数据访问权限,包括私人获取的卫星图像、来自 NASA 的开放数据以及来自 OpenStreetMap 的社区驱动的世界数据。 数据样式是使用 CartoCSS 完成的,CartoCSS 是 MapBox 创建的一种样式格式,基于 CSS 和 LESS 样式框架。 虽然 MapBox 服务提供免费套餐,但它的带宽和存储空间有限,而且对于任何认真使用该服务都必须付费。
许多大公司已经认识到 MapBox 提供的好处,并在他们自己的网站上使用它。 它们包括 Foursquare、Evernote、Pinterest、金融时报、GitHub 和 Etsy,仅举几例。
CartoCSS
这是一个光滑的 MapBox 地图示例,它使用一种名为Pirates的样式,由 MapBox 的设计师创建。 由于 MapBox 在 Leaflet 之上运行,因此将其嵌入到您的网页中的代码将类似于上面的 Leaflet 示例:
如上所述,CartoCSS 用于在 MapBox 中设置矢量瓦片的样式。 这是使用他们的 MapBox Studio 完成的,它也是开源的。 使用 MapBox Studio,可以从头开始创建自己的地图样式,或者更改和扩展其他设计师创建的现有样式。 一旦您的自定义地图上传到您的 MapBox 帐户,您就可以使用 MapBox API 将其嵌入您的网站。
以下是用于获取Pirates基础层的 CartoCSS 示例:
@name: '[name_en]'; @name_arrr: "[name_en].replace('([Aa]r)','\1rr')"; @land: #fff8f0; @water: #cdd; @park: #cda; Map { background-color:@land; background-image:url(img/noise.png); } #admin[maritime=0][zoom>=3] { line-join: round; line-color: #478; comp-op:multiply; // Countries [admin_level=2] { line-cap:round; line-width: 0.8; [zoom>=6] { line-width: 2; } [zoom>=8] { line-width: 4; } [disputed=1] { line-dasharray: 4,4; line-cap:butt; } } // States / Provices / Subregions [admin_level>=3] { line-width: 0.4; line-dasharray: 10,3,3,3; [zoom>=6] { line-width: 1; } [zoom>=8] { line-width: 2; } [zoom>=12] { line-width: 3; } } } @water_line:lighten(@water,8); #water { ::b { polygon-pattern-file:url(img/water.png); polygon-pattern-alignment:global; } polygon-fill: mix(@water,#fff,50); polygon-gamma: 0.6; comp-op:multiply; a/line-color:@water_line; a/line-width:-0.4; a/line-comp-op:multiply; a/line-smooth:2; b/line-color:@water_line; b/line-width:-0.4; b/line-comp-op:multiply; b/line-smooth:4; c/line-color:@water_line; c/line-width:-0.4; c/line-comp-op:multiply; c/line-smooth:6; [zoom>=12] { a/line-width:0.8; b/line-width:0.8; c/line-width:0.8; } } #waterway { comp-op:multiply; [type='river'], [type='canal'] { line-color: @water; line-width: 0.5; [zoom>=12] { line-width: 1; } [zoom>=14] { line-width: 2; } [zoom>=16] { line-width: 3; } } [type='stream'] { line-color: @water; line-width: 0.5; [zoom>=14] { line-width: 1; } [zoom>=16] { line-width: 2; } [zoom>=18] { line-width: 3; } } } #landuse { ::glow { comp-op:multiply; [class='park'],[class='pitch'],[class='school'] { line-width:2; line-join:round; [class='park'] { line-color:#ddb; } [class='pitch'] { line-color:#eed; } [class='school'] { line-color:#edb; } } } ::main[zoom>=0] { comp-op:multiply; [class='park'] { polygon-pattern-file:url(img/park.png); polygon-pattern-alignment:global; } [class='school'] { polygon-fill:#ed9; polygon-opacity:0.5; } } ::wood[class='wood'] { line-color:#C3CFB4; line-opacity:0.33; line-width:3; line-join:round; polygon-pattern-file:url(img/forest.png); polygon-pattern-alignment:global; comp-op:multiply; opacity:0.5; } } #building { polygon-fill:#efe8d8; comp-op:multiply; [zoom>=15] { line-color:#efe8d8 * 0.9; [zoom>=15] { line-width:0.2; } [zoom>=16] { line-width:0.4; } [zoom>=17] { line-width:0.8; } } } #tunnel { opacity: 0.5; } #road, #tunnel, #bridge { ['mapnik::geometry_type'=2] { line-width: 1; line-color:#edc; line-comp-op:multiply; [class='motorway'], [class='main'], [class='motorway_link']{ line-color:#dba; [zoom>=10] { line-width: 1; } [zoom>=12] { line-width: 2; } [zoom>=14] { line-width: 3; } [zoom>=16] { line-width: 5; } } [class='street'], [class='street_limited'] { [zoom>=13] { line-width: 1.4; } [zoom>=14] { line-width: 2; } [zoom>=16] { line-width: 3; } } [class='street_limited'] { line-dasharray: 4,1; } [class='path'] { line-dasharray: 3,2; } } }
啊,伙计!
在此处查看其他一些预先设计的 MapBox 样式。
优点
- 扩展传单。
- 详细且无云的卫星图像的大型存储库。
- 详细的地形数据。
- 大量的连接服务。
- 开箱即用的精美设计地图。
- 用于样式化和自定义现有地图的图形界面。
缺点
- 好东西不是免费的。
- 定价更多地基于流量而不是功能。
卡托数据库
对于更复杂的地理空间数据可视化和分析,CartoDB 是目前最好的工具之一。 它是一种云服务,可将地理数据存储在名为 PostGIS 的云中启用空间的数据库中,提供访问数据的工具,使用 PostGIS 的空间和地理定位功能对其进行分析,并使用 Leaflet 进行显示。
CartoDB 的创建是由于缺乏易于地理空间数据可视化和存储的替代方案。 因此,CartoDB 可以被认为是 Google 的 Fusion Tables 的替代品。 用户可以导入各种格式的数据集,包括 CSV、KML 或 Excel 表格,并将它们叠加在来自 Google、Here (Nokia) 或 OpenStreetMap 等常见来源的地图上。 由于所有地理数据都存储在真实数据库中,因此可以使用 SQL 访问和查询数据,然后使用 CSS 设置样式。
CartoDB 服务以“免费增值”形式提供; 将数据向公众开放的用户可以在 CartoDB 网站上免费托管他们的项目。 要存储私人数据、导入超过 5MB 的数据或使用超过五个表,用户必须订阅高级计划。
地理JSON
CartoDB 是一种数据可视化工具,因此它的使用方式与其他在线地图工具示例略有不同。 您的 CartoDB 地图将自动可视化地图上具有地理参考坐标的任何数据。 因此,我们可以通过简单地将其添加到 PostGIS 数据库来显示萨格勒布的标签。 下面是一个 GeoJSON 格式的示例:
{ "type": "FeatureCollection", "features": [ { "type":"Feature", "geometry": { "type":"Point", "coordinates":[15.9833,45.8167] }, "properties": { "cartodb_id":1, "name":"Zagreb", "description":null, "created_at":"2015-02-20T21:02:16Z", "updated_at":"2015-02-20T21:03:59Z" } } ] }
但是,要真正了解 CartoDB 的能力,请查看他们的图库。
优点
- 非常适合管理和存储地理空间数据。
- 支持多种数据格式和大型数据集。
- 基于经过验证的开源产品,例如 Leaflet 和 PostGIS。
- 免费增值模式。
缺点
- 不是免费的。
- 定价基于存储的数据大小,如果使用非常大的数据集,这可能会变得昂贵。
Web 开发人员的其他选择
这些是当前可用的最流行的映射框架,但还有其他鲜为人知的选项。 如果您与 Microsoft 生态系统相关联,他们会提供类似于 Google 地图的 API,称为 Bing Maps API。
而且,我们不能不提到在线地图世界中的恐龙 MapQuest。 它仍然存在并提供 MapQuest Mapping Tools。
如果您正在寻找一种稍微不同的地图制作方法,Kartograph 很有趣,因为它的创建考虑了设计师和数据记者的需求。
样式化你的地图
所有这些框架都提供了一种自定义地图样式和外观的方法。 MapBox 和 CartoDB 使用 CSS 或 CSS 的变体提供样式。
在 Google 方面,第 3 版 Google Maps API 引入了自定义样式的地图。 这最终让开发人员,尤其是设计师,有更多的空间来定制随处可见的默认谷歌地图设计,并使其更符合网站的整体视觉主题。 在丰富的 Google 地图社区中,诞生了一些样式资源。 最著名的是 Snazzy Maps,这是一个为 Google 地图创建自定义样式并免费分享的社区。
如果您决定使用 OpenLayers 或 Leaflet,那么您只能使用预渲染的地图图块。 幸运的是,有不同范围的地图图块可供选择,从 Google、诺基亚、Bing 或默认 OSM 图块,到由设计师特别创建的图块,例如 Stamen。 要了解存在多少可用的地图图块,或者它们之间的对比情况,请访问 Streetmap Smackdown 或地图比较网站。
网络地图和地图工具的未来
地图世界的未来看起来很有趣。 以下是一些几年前看起来像科幻小说的新兴技术:
- Vector-Only - 在 D3.js 中使用矢量地图而不是光栅图像带来了一个使用标准框架无法实现的新功能世界。 MapBox 也在朝着这个方向发展,基于 OpenGL 的 MapBox GL。
- 3D - 三维地形和建筑物现在出现在地图中,并且 OpenLayers v3 附带了对 Cesium 的内置支持。
- Web 浏览器中的 GIS 和空间分析- 已经可以使用 Turf。 Turf 是一个 JavaScript 库,支持空间和统计操作、数据分类和 GeoJSON 数据创建,所有这些都在浏览器中进行。
包起来
此处列出的每个最佳在线地图工具都有其优点和缺点。 例如,代码示例显示了使用 Leaflet 的简单性与 OpenLayers 带来的复杂性。 但是 Leaflet 不会像 OpenLayers 那样解决您复杂的空间问题。 选择取决于您的需求。
总结一下:
- 谷歌地图- 完善的、成熟的地图解决方案,特别是非开发人员在网络上获取基本地图,以及谷歌 (in) 著名的所有权力。
- OpenLayers - 适用于其他制图框架无法解决您的空间分析问题的情况。
- Leaflet - 目前,很容易成为用于一般映射目的的最佳映射框架,特别是如果您不需要 MapBox 或 CartoDB 提供的其他服务。
- MapBox - 当您想要更多地控制地图样式或需要其他人不提供的服务(例如详细的卫星图像、地理编码或方向)时,快速增长和市场变化的地图解决方案。
- CartoDB - 如果您有大量数据集,以不同的数据格式存储,请不要再犹豫了。
进一步阅读 Toptal 工程博客:
- 使用更智能的缓存将地图集群服务速度提高 50 倍