绘制地铁线路html,基于HTML5技术绘制上海地铁图

某市政项目用到地铁图展现,展现地铁站点以及相关信息流,使用Qunee组件能够很好的解决这类需求,作出优美的展示,下面以上海2012地铁图为例,效果以下:node

1460000006788156

示例讲解

首先须要解决数据问题,能够从维基百科或者上海地铁官网中获取,不过也免不了人工,要达到良好的显示效果,须要不仅要记录站点的位置,还须要设置文本标签的理想位置,有时为了不文字叠加,须要设置旋转角度......总之事在人为,想一想办法,最终解决了数据问题,再加上Qunee图形组件的强大展现效果,作出来能够交互的在线地铁图函数

数据格式

采用JSON格式数据,分三种类型:文本标签、站点、地铁线spa

总的结构以下:对象

{

"labels" : [  ... ],

"stations" : [ ... ],

"lines" : [ ... ]

}

文本标签数据

包含坐标和文字信息,若是文字须要旋转,则会增长"rotate"属性,下面是“莘庄”文本标签信息事件

{

"text" : "莘庄",

"x" : 883.591,

"y" : 1625.695

}

文字与节点旋转效果 1460000006788157

站点数据

包含坐标、旋转角度以及编号信息,下面是“莘庄”站的信息ci

{

"id" : 5,

"x" : 869.8513512641732,

"y" : 1597.6559686949402,

"rotate" : 0.7853981633974483

}

地铁线数据

包含名称,颜色,以及通过的站点编号rem

{

"name" : "1",

"color" : "#e52035",

"stations" : [64, 70, 67, 71, 72, 65, 69, 73, 66, 68, 63, 62, 22, 61, 60, {"id": 21, "yOffset": 0.5}, 59, {"id": 18, "yOffset": -0.5}, 17, 58, 14, 7, 57, 6,

56, 44, 47, 5]

}

对于特殊状况,好比两条地铁线共用一条线路的状况,会出现两条线重合,为了不这种状况,还能够指定站点横向偏移量,好比上面一号线中的以下数据get

{"id": 21, "yOffset": 0.5}

由于上海地铁三号线与四号线共用线路较多,因此这种处理更加明显it

三号线数据

{

"name" : "3",

"color" : "#f9d300",

"stations" : [6, 95, 96, 97, {"id":12,"yOffset":0.5}, {"id":11,"yOffset":0.5}, {"id":8,"yOffset":0.5}, {"id":9,"yOffset":0.5},

{"id":10,"yOffset":0.5}, {"id":25,"yOffset":0.5}, {"id":26,"yOffset":0.5}, {"id":238,"yOffset":0.5}, {"id":22,"yOffset":-0.5}, {"id":27,"yOffset":-0.5},

98, 99, 100, 101, 104, 105, 107, 108, 109, 106, 110, 111]

}

地铁共线效果

1460000006788158

建立图元

数据须要转换成qunee图元对象,三种类型分别对应三个建立函数io

建立文本标签

function createText(name, x, y, rotate){

var text = graph.createNode(name, x, y);

if(rotate){

text.rotate = rotate;

}

text.zIndex = 20;

text.image = null;

text.setStyle(Q.Styles.BACKGROUND_COLOR, Q.toColor(0x88FFFFFF));

text.setStyle(Q.Styles.LABEL_ANCHOR_POSITION, Q.Position.LEFT_BOTTOM);

text.setStyle(Q.Styles.LABEL_POSITION, Q.Position.CENTER_MIDDLE);

text.setStyle(Q.Styles.LABEL_PADDING, PADDING);

return text;

}

建立站点

function createStation(station){

var node = graph.createNode(null/**station.name*/, station.x, station.y);

node.stationId = station.id;

node.setStyle(Q.Styles.LABEL_FONT_SIZE, 10);

node.setStyle(Q.Styles.LABEL_ANCHOR_POSITION, Q.Position.CENTER_MIDDLE);

node.setStyle(Q.Styles.LABEL_POSITION, Q.Position.CENTER_MIDDLE);

node.zIndex = 10;

if(station.rotate){

node.image = roundRect;

node.rotate = station.rotate;

}else{

node.image = circle;

}

node.setStyle(Q.Styles.SHAPE_FILL_COLOR, "#FFF");

node.setStyle(Q.Styles.SHAPE_STROKE_STYLE, "#000");

return node;

}

建立地铁线

createLine(...)函数用于建立地铁线,使用了节点类型图元,并设置节点主体为路径,函数updateLine(...)用于从站点信息自动生成线路路径

function createLine(line){

var stations = line.stations;

var node = graph.createNode(line.name);

node.stations = stations;

node.movable = false;

node.setStyle(Q.Styles.LABEL_FONT_SIZE, 50);

node.setStyle(Q.Styles.LABEL_COLOR, line.color);

node.setStyle(Q.Styles.LABEL_ANCHOR_POSITION, Q.Position.LEFT_BOTTOM);

node.setStyle(Q.Styles.LABEL_POSITION, Q.Position.LEFT_TOP);

node.setStyle(Q.Styles.LAYOUT_BY_PATH, true);

node.anchorPosition = null;

node.setStyle(Q.Styles.SHAPE_STROKE, size);

node.setStyle(Q.Styles.SHAPE_STROKE_STYLE, line.color);

updateLine(node, true);

return node;

}

function updateLine(line, addListener){

var path = new Q.Path();

line.image = path;

var stations = line.stations;

var first = true;

Q.forEach(stations, function(s){

var station = getStation(s.id || s);

if(!station){

return;

}

if(addListener){

addLocationChangeListener(station.stationId, line);

}

var location = station.location;

var x = location.x, y = location.y;

if(s.yOffset){

var offset = s.yOffset * size;

var rotate = station.rotate || 0;

var sin = Math.sin(rotate);

var cos = Math.cos(rotate);

x += cos * offset;

y += sin * offset;

}

if(first){

first = false;

path.moveTo(x, y);

}else{

path.lineTo(x, y);

}

})

}

交互处理

增长交互处理,监听站点拖动事件,保持地铁路线跟随站点位置变化

graph.interactionDispatcher.addListener(function(evt){

if(evt.kind != Q.InteractionEvent.ELEMENT_MOVING){

return;

}

var datas = evt.datas;

Q.forEach(datas, function(data){

if(!data.stationId){

return;

}

var listeners = stationLocationChangeListeners[data.stationId];

if(listeners){

for(var l in listeners){

updateLine(listeners[l]);

}

}

});

});

在线示例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值