本文概述
没有什么比一个好的, 有用的地图更好的了。
今天, 使用在线地图是一个简单而有趣的过程。制作自己的在线地图不再是一件大事。我们提供各种在线地图工具, 从免费和简单到功能丰富和复杂的使用。对于不熟悉Web映射的Web开发人员, 选择的痛苦可能令人生畏。你想制作地图, 但不知道从哪里开始, 也不知道要使用哪些工具。我在这里为你提供最佳映射工具列表的帮助。
历史的一点点
从一开始, 技术就对地图制作以及地图的使用方式产生了影响。随着技术的进步, 制图和制图过程也随之发展, 从纸莎草纸上的手工绘制地图到网络上的交互式地图。
过去的映射。
20世纪下半叶是制图学的转折点。计算机成为首选工具。航空摄影, 卫星图像和遥感技术改变了空间数据的收集方式。地理信息系统(GIS)诞生了。最终, GIS地图开始从台式机迁移到网络, 大型GIS供应商开始制作第一个在线地图框架。
但是GIS映射并不容易。它需要许多服务器端技术, 地理空间标准和协议及其实现。它需要了解地理空间数据和地图投影, 了解如何收集数据, 如何显示数据, 使用哪种颜色, 如何将数据归纳到特定比例, 如何在地图上放置标签, 如何设置地图。服务于地图的服务器, 如何使用空间数据库等。 GIS充满了缩写, 例如WMS, WFS, EPSG, CRS, SLD, GML, TMS, 仅举几例, 要了解和理解它们, 你需要阅读书籍, 学术论文和文章。
在线制图的演变
最初的网络地图通常只显示一个非常小的地图图像。那时, 平移是通过在八个可能的指南针方向之一(N, NW, W, SW, S, SE, E, NE)中移动一个步(通常为地图大小的一半)来实现的。用户单击”平移”或”缩放”按钮后, 将需要在地图服务器上呈现一个完整的新图像, 通过网络进行加载, 然后由浏览器进行处理。由于技术的限制, 地图仅占据整个网页的一小部分。为了获得更好的交互, 早期的地图需要使用Flash插件或基于Java的专有插件, 甚至是ActiveX, 它们只能在Internet Explorer中使用。
Google在2005年推出Google Maps时颠倒了地图世界。在其创新中, Google引入了通过拖动进行连续平移的功能。他们的解决方案是显示地图, 将地图切成许多较小的正方形图像, 称为”平铺”。这些图块是通过”地图图块服务器”渲染和提供的, 通常为256 x 256像素。现在, 缩放和平移仅需要加载新的地图图块, 而无需重新加载整个网页。结果是更大的可见地图覆盖了浏览器窗口的一半以上, 并为浏览地图提供了流畅的体验。由于能够使用平滑的缩放和平移功能”滑动”地图, 因此这些新地图被称为”滑动地图”。 Google还允许编写脚本, 因此用户可以将Google的地图放在自己的网站上, 并将自己的数据添加到地图上。这导致了另一个新名词的诞生:”地图混搭”。
突然, 在线地图开始流行。要将精美的地图添加到你的网站, 你不再需要成为制图师或GIS专家。在” Web 2.0″运动的翅膀上, 并基于诸如HTML5, CSS3和SVG之类的现代技术, 这些技术使交互式内容的创建变得容易, 交互式地图现在正在焕发新生。
将来会映射吗?
地图数据
如前所述, 早期的在线地图是基于GIS数据集及其空间地理数据库的。没有多少人可以访问该数据, 更不用说它的价格了。 Google和OpenStreetMap(OSM)项目数据集对此进行了更改。 Google的数据库是私有数据库, 并有一定的限制, 而OSM则受Wikipedia概念的启发, 该概念是创建免费世界地图的协作项目。 OpenStreetMap由志愿者映射器社区构建, 这些映射器有助于并维护空间数据。
简而言之, 当今简化地图制作的最大革命是与维护地图服务器和空间数据库有关的麻烦已消除。
选择Web映射框架
因此, 在所有选项中, 我们如何选择正确的在线地图绘制工具?一方面, 有商业在线地图提供商, 例如Google, MapQuest, Microsoft和Nokia。这些服务提供地图图块和适当的JavaScript API, 以查看它们并与地图进行交互。另一方面, 有些开源地图绘制项目可以轻松加载基于OpenStreetMap的地图图块。这些包括OpenLayers和Leaflet。然后还有诸如MapBox和CartoDB之类的项目, 这些项目的业务模型基于开源库和OSM数据, 并提供附加值, 但并非免费。
让我们看一下这些类别中的一些示例。在这里, 我将讨论其中的几种在线映射工具, 并简要概述每种工具以及代码示例, 并权衡利弊。我们还编写了一个D3.js映射教程, 单独阅读可能会很有趣。
谷歌地图
让我们从最明显的选择开始, 即Google地图。 Google Maps API的第一版于2005年2月推出, 而当前的Google Maps API v3于2009年6月推出。它包含更多项目, 并提供了多种不同的方式将Google Maps嵌入到具有广泛自定义功能的网页中。
当前可用的Google Maps API包括:
- Google Maps Javascript API
- Google静态地图API
- Google Maps Embed API
- 适用于iOS的Google Maps SDK
- Google Maps 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 id="map" style="width: 600px; height: 600px;"></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>
生成的地图如下所示:
优点
- 由Google开发和维护。
- 许多不同的API, 用于在你的网站或应用程序中包含地图。
- 庞大的用户社区。
- 很好的API文档, 其中包含许多示例。
缺点
- 我们确定在某个时候不会看到添加吗?
- 每个人都在使用它;所有地图(大部分)看起来都一样。
- 封闭和适当的API。
- 除了Google正式开发的插件外, 没有其他插件。
- Google Maps for Work的定价不清楚。
OpenLayers
OpenLayers由MetaCarta开发, 相当于Google Maps的开源, 第一版于2006年6月发布。OpenLayers是一种在线映射工具, 该工具实施JavaScript API来构建基于网络的丰富地理应用程序, 其API与Google Maps API。 OpenLayers很快获得了很多关注, 并且一开始的发展很快。 OpenLayers 2在版本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 id="map" class="map" style="width: 600px; height: 600px;">
<div id="popup" style="padding-bottom: 45px;"></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月诞生。 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 id="map" style="width: 600px; height: 600px;"></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。
- 一组预先设计的地图。
- 无需映射库即可显示的静态地图。
- GeoCoding服务。
- 路线服务。
MapBox不仅提供地图服务, 还可以访问数据, 包括私人获取的卫星图像, NASA的开放数据以及OpenStreetMap的社区驱动的世界数据。数据样式使用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(诺基亚)或OpenStreetMap等常见来源的地图上。由于所有地理数据都存储在真实的数据库中, 因此可以使用SQL访问和查询数据, 然后使用CSS设置样式。
CartoDB服务以”免费增值”的形式提供;向公众开放数据的用户可以免费在CartoDB网站上托管其项目。要存储私有数据, 导入超过5MB的数据或使用五个以上的表, 用户必须订阅高级计划。
GeoJSON
CartoDB是用于数据可视化的工具, 因此它的用法与其他在线映射工具示例有所不同。你的CartoDB地图将自动显示地图上具有地理参考坐标的所有数据。因此, 我们可以通过简单地将Zagreb的标签添加到我们的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 Maps的API, 称为Bing Maps API。
而且, 我们必须提到在线地图世界MapQuest中的恐龙。它仍然存在, 并提供MapQuest映射工具。
如果你正在寻找一种略有不同的地图制作方法, 那么Kartograph会很有趣, 因为它的创建是考虑到设计师和数据记者的需求的。
样式化你的地图
所有这些框架都提供了一种自定义地图样式和外观的方法。 MapBox和CartoDB提供使用CSS或CSS变体的样式。
在Google方面, Google Maps API的第3版引入了自定义样式的地图。最终, 开发人员(尤其是设计师)有了更多的空间来自定义随处可见的默认Google Maps设计, 并使它与网站的整体视觉主题更加吻合。在丰富的Google Maps社区中, 诞生了一些样式资源。最著名的是Snazzy Maps, 这是一个为Google Maps创建自定义样式并免费共享样式的人社区。
如果你决定使用OpenLayers或Leaflet, 则只能使用预渲染的地图图块。幸运的是, 从Google, Nokia, Bing或默认的OSM磁贴到由Stamen等设计师专门创建的磁贴, 可以选择不同的范围。要了解存在多少可用的地图图块, 或者它们彼此之间的外观, 请访问Streetmap Smackdown或Map比较站点。
网络地图和制图工具的未来
映射世界的未来看起来很有趣。以下是一些几年前才看起来像科幻小说的新兴技术:
- 仅矢量-在D3.js中使用矢量地图代替光栅图像带来了新功能, 这些功能是使用标准框架无法实现的。 MapBox也在基于OpenGL的MapBox GL朝着这个方向发展。
- 3D-现在, 地图中显示了三维地形和建筑物, OpenLayers v3附带了对Cesium的内置支持。
- Web浏览器中的GIS和空间分析-已经可以使用Turf。 Turf是一个JavaScript库, 支持在浏览器中进行空间和统计操作, 数据分类和GeoJSON数据创建。
本文总结
这里列出的每种最佳的在线地图绘制工具都有其优点和缺点。例如, 代码示例显示了使用Leaflet的简单性, 而不是OpenLayers带来的复杂性。但是Leaflet无法解决OpenLayers所能解决的复杂空间问题。选择取决于你的需求。
总结一下:
- Google Maps-完善而完善的地图解决方案, 特别是对于非开发人员而言, 可以在网络上获取基本地图, 以及Google闻名的所有功能。
- OpenLayers-适用于其他地图绘制框架无法解决你的空间分析问题的情况。
- 传单-当前, 这是用于常规地图绘制的最佳映射框架, 尤其是在你不需要MapBox或CartoDB提供的其他服务时。
- MapBox-快速增长和市场变化的地图绘制解决方案, 当你想更好地控制地图样式或需要其他人不提供的服务时, 例如详细的卫星图像, 地理编码或方向。
- CartoDB-如果你有大量的数据集, 以不同的数据格式存储, 则无需再寻找了。
评论前必须登录!
注册