eegeo.js是基于流行的映射库Leaflet构建的开源 3D地图API。
有许多贴图库可让您嵌入或构建简单的2D贴图。 尤其是Google Maps 、 Bing Maps 、 HERE 、 Mapbox和OpenStreetMap 。 流行的映射抽象库(例如OpenLayers和Leaflet)还允许您更改地图的“基础层”,而无需更改应用程序逻辑。
随着Google Earth API的使用下降到NPAPI安全性弃用 ,3D map API的选择受到限制。 确实存在替代方案,例如流行的Cesium库。 eegeo.js是另一种,它提供了从空间到室内地图的动态、真正无缝的3D世界地图。 在浏览器中使用WebGL。
在本文中,我将向您展示嵌入精美的伦敦3D地图并使用Transport for London API添加一些基本功能有多么简单。
剧透:3D地图就像使用2D地图一样简单。
免责声明:我是eeGeo的软件开发高级副总裁,我负责eegeo.js的开发。
有很多关于如何使用Leaflet的教程。 eeGeo.js是有意识地基于Leaflet构建的,因此已经熟悉Leaflet的开发人员可以立即启动并运行。 我完全推荐传单示例和文档 。
本文将介绍基本的HTML、CSS、JavaScript和简单的映射概念。
本文将介绍一些关键组件:
首先,让我们使用Leafet和Open Street Map创建伦敦的2D地图。 传单非常简单。 您只需要一点HTML来设置页面,一个 让我们用以下标记创建一个HTML文件: 要包含Leaflet,就像添加Leaflet JavaScript库和CSS一样简单。 将这些包括在 JavaScript的以下几行初始化Leaflet,并将OpenStreetMap用作图块层。 您可以将其添加为外部JavaScript文件,或者为了简单起见,可以添加到 该代码以WGS84(十进制纬度,经度 将您的HTML上传到某个地方,或在本地查看。 我建议不要直接从文件系统加载,而要使用本地回送Web服务器。 将HTML保存为 您将看到以伦敦的霍尔本地铁站为中心的以下地图: 由于eeGeo.js是基于Leaflet构建的,因此只需进行很少的更改即可将伦敦的2D地图转换为精美的3D地图。 将上面添加的将 JavaScript现在应显示为: 更改我们添加到 就是这样! 通过仅更改几行,您现在将看到Holborn Tube Station的完全相同的视图,但是是以华丽的3D形式显示: 由于eeGeo.js是完全3D的,因此可以旋转和倾斜地图。 支持Leaflet 添加以下JavaScript,10秒钟后,地图将以3D模式从Holborn Tube Station到伦敦的小黄瓜进行无缝动画处理: 在CodePen上查看带有eeGeo.js的Pen Gorgeous 3D地图过渡和 SitePoint( @SitePoint )的Leaflet 。 上面 现在,让我们为地图添加一些有用的东西。 支持大多数Leaflet图元,例如标记,折线和多边形。 要将Holborn地铁站的标记添加到地图,请调用 要在罗素广场添加多边形,请调用 要添加一条从布卢姆斯伯里(始于Great James St.到博物馆St.)的路线的折线: 刷新后,三个Leaflet基本体现在将显示在地图上: 您会注意到对 接下来,让我们将来自真实世界API的一些数据添加到伦敦的3D地图中。 伦敦交通运输(TfL)API庞大而复杂。 它涵盖伦敦的所有运输,包括公共汽车、地铁、地面、自行车租赁,并提供实时状态和到达时间数据。 完整的TfL API的范围太大,本文无法涵盖。 我将只关注描述伦敦地铁的极少数API端点,特别是回答: TfL API可以在没有严格限制速率的API密钥的情况下使用。 如果您在实际的生产部署中使用TfL API,则应注册API密钥 。 为了回答“有哪些可用的管线”问题,TfL API 在“管线”资源上提供了一个端点 我们仅对“管状”运输方式感兴趣,因此请进行以下调用: 返回带有Line实体数组的JSON响应。 我们只对每个条目的 为了简化与TfL API的交互,我们将使用jQuery,但是对jQuery的依赖是完全可选的。 以下JavaScript调用 稍后,我将使用这些Line ID来查询其他TfL端点,这些端点描述了沿着特定地下路线的车站。 您可以将伦敦地铁视为图表 。 图包含顶点和边。 对于伦敦地铁,我将这些站点视为“顶点”,而这些管线将形成“边缘”。 将中心线(上方红色)建模为图形,在北阿克顿,西阿克顿和挂车巷处将有顶点。 由于中线从北阿克顿(North Acton)西行有一个分支,因此在北阿克顿(North Acton)和西阿克顿(West Acton)之间以及北阿克顿(North Acton)和Hanger Lane之间也存在一条中线Edge 。 在中心线以东,是诺丁山门。 诺丁山门地铁站只有一个,但它有三条线的站台:中央(红色)、圆形(黄色)和地区(绿色)。 我们只想为诺丁山门添加一个传单标记,而不是三个。 如果我们将诺丁山门建模为顶点,则将有中心线Edges (至Holland Park和Queens Way), 圆线和区域线Edges至Bayswater和High Street Kensington。 这很重要,因为TfL API将Underground建模为有向图 。 现在,我们有了地下每条线的线号。 我还计划将桩号和线作为Graph中的顶点和边进行松散建模。 给定线路ID,TfL API然后可以告诉我们每条线路停在哪个车站。 TfL API将这些称为 让我们再次调用TfL API,以描述中心线的出站路由: 这将返回一个非常大的JSON有效负载,超过8000条漂亮的印刷行。 幸运的是,我们只对 此属性是JSON对象的列表,这些对象将行分成连续的部分。 在StopPointSequence中,沿线依次是所有StopPoint。 下面的JavaScript处理唯一的桩号的创建以及折线的创建,因此我们可以为管状线的边缘绘制一条线。 现在,我们可以为Underground的每一行调用上述JavaScript。 之后,我们将在 稍后,我将展示如何添加传单标记和折线以直观地显示试管桩号和线。 我们需要的最终TfL API端点是实时到达。 在上一节中,我们可以看到工作站在API中具有唯一标识符。 对于Notting Hill Gate,ID为 现在,我们可以调用TfL StopPoint API ,提供一个StopPoint ID: 这将返回一系列到达: 这表明到埃平的东行火车将在不到5分钟的时间(290秒)内到达3号站台。 到目前为止,我已经向您展示了如何: 现在将这些简单的概念整合在一起,以生成伦敦的3D交互式地图,显示伦敦地铁的线路和车站以及所有车站的实时到达时间! 在上一个请求 我们已通过标记传递了其他“选项”。 如此一来,稍后在处理鼠标悬停事件时,我们便知道我们已经悬停了哪个Station ID和Name。 再次,在请求 上面的颜色可能来自按行ID查找。 在这种情况下,根据TfL设计指南 ,我将硬编码的圆线红色 我想显示来自TfL API的实时到达信息。 将Leaflet Marker悬停在鼠标上时,可能会收到回调。 还可以显示一个Leaflet Popup,以显示工作站的名称。 在下面的更复杂的CodePen中,我将展示_hovercard。*回调如何向TfL API发出请求,并使用实时到达车站填充标注卡。 通过附加的关注点分离和更好的建模,您可以在此代码笔中看到eegeo.js,Leaflet和TfL API的完整演示: 见笔eeGeo.js和伦敦交通局API由SitePoint( @SitePoint上) CodePen 。 在本文中,我展示了如何使用JavaScript和Leaflet将2D地图添加到您的网站,以及如何添加简单的地图功能(例如标记,折线和多边形)。 然后,我展示了如何轻松地从真实的API(例如,伦敦交通局(TfL)API)中添加数据 我已经强调了针对映射抽象库(例如OpenLayers和Leaflet)进行编码的好处。 地图的视觉效果可能会发生巨大变化,而代码几乎没有变化。 我还展示了使用eegeo.js可以进行简单的3D映射。 如果您对本文有任何意见或疑问,请在下面的评论中告诉我。 原文链接: https://www.sitepoint.com/3d-maps-with-eegeo-and-leaflet/创建HTML
包括传单
标记内:
添加传单JavaScript
下面的
块中:
var map = L.map('map', {
center: [51.517327, -0.120005],
zoom: 15
});
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
51.517327, -0.120005
为中心,以Holborn地铁站为中心初始化地图。 您可以通过右键单击并在maps.eegeo.com或Google Maps等数字地图上选择“这里是什么”来获取这些坐标。 稍后您会看到,大多数地理空间API都以标准WGS84十进制度的纬度和经度返回位置,包括TfL API。启动2D地图
index.html
,并在同一文件夹中运行: python -m SimpleHTTPServer 8000
然后,您可以在浏览器中访问http://localhost:8000/
。显示伦敦的3D地图
var map = L.map ...
读取的JavaScript更改为以下内容。 需要免费的eeGeo API密钥 。 您也应该删除不再需要调用L.tileLayer
的JavaScript。var map = L.eeGeo.map('map', '
的
包含以包含
eegeo.js
而不是Leaflet。 eegeo.js
文件已经包含Leaflet,因此请不要同时包含两者:
更改缩放、倾斜和方向
setView
函数,具有可选的倾斜和航向参数以支持地图的3D行为。setTimeout(function() {
map.setView([51.514613, -0.081019], 17, {headingDegrees: 204.374, tiltDegrees:15.0});
}, 10000);
setView()
的其他参数如下:
领域
类型
描述
headingDegrees
小数
顺时针方向从北开始的十进制度,其中0.0是北。
tiltDegrees
小数
以度为单位的倾斜度,其中45.0直接在顶部,而0.0是默认的倾斜视图
与伦敦3D地图互动
L.marker()
:L.marker([51.517327, -0.120005]).addTo(map);
L.polygon()
。 多边形由四个顶点按顺时针方向定义,从罗素广场北偏东角的Bernard St&Wolborn Place交界处开始:L.polygon([[51.522771, -0.125772],
[51.521520, -0.124192],
[51.520631, -0.126358],
[51.521963, -0.127895]]).addTo(map);
L.polyline([[51.521788, -0.117101],
[51.520732, -0.116524],
[51.520430, -0.117641],
[51.519873, -0.119602],
[51.519034, -0.120993],
[51.518784, -0.121537],
[51.517265, -0.125088],
[51.516257, -0.124466]]).addTo(map);
L.marker()
、 L.polyline()
和L.polygon()
的调用都是Leaflet API调用。 如果我们将地图从以前的版本还原回OpenStreetMap,则完全相同的调用仍将在2D OSM基本层上起作用:伦敦运输(TfL)API
有哪些可用的管线?
curl -v https://api.tfl.gov.uk/line/mode/tube
id
属性感兴趣:[{
"id": "bakerloo",
"name": "Bakerloo",
"modeName": "tube",
"disruptions": [],
"lineStatuses": [],
"routeSections": [],
...
},...]
Line
端点并收集Line ID:$.getJSON( "https://api.tfl.gov.uk/line/mode/tube", function(data) {
var lines = [];
$.each(data, function(k, line) {
lines.push(line.id);
});
});
将伦敦地铁建模为图形
特定地铁线上有哪些车站?
StopPoints
。 我们将称为终点的线、路线,包括停靠点的顺序curl -v https://api.tfl.gov.uk/line/central/route/sequence/outbound
stopPointSequences
键感兴趣:"stopPointSequences": [
{
"lineId": "central",
...
"stopPoint": [
...
{
"id": "940GZZLUNHG",
"name": "Notting Hill Gate Underground Station",
...
"lat": 51.509128,
"lon": -0.196104
},
{
"id": "940GZZLUQWY",
"name": "Queensway Underground Station",
...
"lat": 51.510312,
"lon": -0.187152
},
...
],
},
...
]
var stopPoints = {};
$.getJSON( "https://api.tfl.gov.uk/line/central/route/sequence/outbound", function( data ) {
var lineSegments = [];
$.each(data.stopPointSequences, function(k, v) {
var line = [];
$.each(v.stopPoint, function(k, sp) {
line.push([sp.lat, sp.lon]);
if (!(sp.id in stopPoints)) {
stopPoints[sp.id] = {"id":sp.id, "name":sp.name, "lat":sp.lat, "lon":sp.lon};
}
});
lineSegments.push(line);
});
});
stopPoint
词典中整理每个唯一的站点。 对于每条线,我们还有一组折线的集合,这些折线表示lineSegments
数组中管线的各个lineSegments
。哪些火车到达特定车站?
940GZZLUNHG
:{
"id": "940GZZLUNHG",
"name": "Notting Hill Gate Underground Station",
...
"lat": 51.509128,
"lon": -0.196104
}
curl -v https://api.tfl.gov.uk/stoppoint/940GZZLUNHG/arrivals?mode=tube
[{
...
"naptanId": "940GZZLUNHG",
"stationName": "Notting Hill Gate Underground Station",
"lineId": "central",
"platformName": "Eastbound - Platform 3",
"direction": "outbound",
...
"destinationName": "Epping Underground Station",
"timeToStation": 290,
"currentLocation": "Between White City and Shepherd's Bush",
"towards": "Epping",
...
},
...]
把它放在一起
添加地铁站标记
https://api.tfl.gov.uk/line/central/route/sequence/outbound
$.getJSON()
调用中,为每个站点调用L.marker()
:$.each(stopPoints, function(k, sp) {
L.marker([sp.lat, sp.lon],
{
title: sp.name,
options: {"id":sp.id, "name":sp.name}
}).addTo(map);
});
为地下线添加折线
https://api.tfl.gov.uk/line/central/route/sequence/outbound
的上一个Ajax调用中,为每个线段添加一个L.polyline()
调用:$.each(lineSegments, function(k, ls)
{
L.polyline(ls, {weight:8, color:"#CC3333"}).addTo(map);
});
在传单标记上处理鼠标悬停事件
$.each(stopPoints, function(k, sp) {
var marker = L.marker([sp.lat, sp.lon],
{
title: sp.name,
options: {"id":sp.id, "name":sp.name}
}).addTo(map);
marker.bindPopup(sp.name);
marker.on('mouseover',_hovercard.overstation);
marker.on('mouseout',_hovercard.outstation);
});
放在一起
3D地图不必太难