zh

# 基于html5技术绘制上海地铁图 - 双车道路况信息

2014-05-13

### 双车道的绘制

#### 绘制双车道，计算拐点的法线和夹角

function drawDoubleLine(path, points, isDoubleLine, size, lineDirection) {
var p0, p1;
Q.forEach(points, function (p) {
if (!p1) {
p1 = p;
return;
}
p1._a = Math.atan2(p.y - p1.y, p.x - p1.x);
if (p0) {
p1.angle = Math.atan2(Math.sin(p0._a) + Math.sin(p1._a), Math.cos(p0._a) + Math.cos(p1._a));
p1.angle -= Math.PI / 2;
var theta = Math.abs(p1._a - p0._a);
if (theta > Math.PI) {
theta = 2 \* Math.PI - theta;
}
p1.inclinedAngle = Math.PI - theta;
} else {
p1.angle = p1._a - Math.PI / 2;
}
p0 = p1;
p1 = p;
});
p1.angle = Math.atan2(p1.y - p0.y, p1.x - p0.x) - Math.PI / 2;
if (lineDirection == "left") {
drawLine(path, points, 0.5, size);
return;
}
if (lineDirection == "right") {
drawLine(path, points, -0.5, size);
return;
}
if (!isDoubleLine) {
drawLine(path, points, 0, size);
return;
}
drawLine(path, points, 0.5, size);
drawLine(path, points, -0.5, size);
}

#### 绘制连线

function drawLine(path, points, yOffset, size, doubleLine) {
Q.forEach(points, function (p, index) {
var angle = p.angle;
var inclinedAngle = p.inclinedAngle;
var x = p.x, y = p.y;
var offset = yOffset;
if (offset) {
offset \*= 2 / 3 \* 0.8;
}
if (p.yOffset) {
offset += p.yOffset;
}
if (offset) {
offset \*= size;
if (inclinedAngle) {
offset /= Math.max(0.2, Math.sin(inclinedAngle / 2));
}
var sin = Math.sin(angle);
var cos = Math.cos(angle);
x += cos \* offset;
y += sin \* offset;
}
if (index == 0) {
path.moveTo(x, y);
} else {
path.lineTo(x, y);
}
});
}

### 路况状态绘制

function drawDoubleLine(path, points, isDoubleLine, size, lineDirection) {
...
if (lineDirection == "left") {
drawLine(path, points, 0.5, size);
return;
}
if (lineDirection == "right") {
drawLine(path, points, -0.5, size);
return;
}
...
}

#### 路况模拟数据

[{
"line": "11",
"fragments": [
{
"color": "#FF0000",
"direction": "right",
"stations": [230, 231, 232]
},
{
"color": "#FFFF00",
"direction": "left",
"stations": [229, 230, 231, 232]
},
{
"color": "#00FF00",
"direction": "left",
"stations": [227, 228, 229]
}
]
}]