无编辑摘要
(增加图例)
 
(未显示1个用户的2个中间版本)
第1行: 第1行:
[[Category:公共设施]]
[[Category:公共设施]]<br/>
{{未完成}}
{{未完成}}<br/>
<html>
{{铁路}}<br/>
<body>
图例:<br/>
    <div id="MainMap"></div>
{{角标|背景颜色=#B02E26|文字颜色=#FFFFFF|内容=1号线}}
    <script>
{{角标|背景颜色=#3C44AA|文字颜色=#FFFFFF|内容=2号线}}
        window.dataset = {
{{角标|背景颜色=#FED83D|文字颜色=#000000|内容=3号线}}
            "lines": {
{{角标|背景颜色=#169C9C|文字颜色=#FFFFFF|内容=4号线}}
                "1": {
{{角标|背景颜色=#8932B8|文字颜色=#FFFFFF|内容=5号线}}
                    "color": "#B02E26",
{{角标|背景颜色=#C74EBD|文字颜色=#FFFFFF|内容=6号线}}
                    "route": [
{{角标|背景颜色=#5E7C16|文字颜色=#FFFFFF|内容=8号线}}<br/>
                        { "SCZCT": "" },
                        { "CZHCT": "" },
                        { "NNCNL": "" },
                        { "SPAWN": "" },
                        { "MNTDY": "" },
                        { "EYYCT": "" },
                        { "LNYCT": "" }
                    ]
                },
                "2": {
                    "color": "#3C44AA",
                    "route": [
                        { "WTCCT": "" },
                        { "LNYCT": "" },
                        { "WUMIN": "" },
                        { "XJIAN": "" },
                        { "PGNUN": "" }
                    ],
                    "stat": "planned"
                },
                "2支线": {
                    "color": "#3C44AA",
                    "route": [
                        { "WUMIN": "" },
                        { "STRHD": "" },
                        { "BREAD": "" }
                    ]
                },
                "3": {
                    "color": "#FED83D",
                    "route": [
                        { "SPAWN": "" },
                        { "NNCNL": "" },
                        { "pos": [0, 4], "stat": "planned" },
                        { "INITS": "" },
                        { "KEMOW": "" },
                        { "UKN03": "" },
                        { "YXLAN": "" }
                    ],
                    "stat": "planned"
                },
                "4": {
                    "color": "#169C9C",
                    "route": [
                        { "HINDA": "" },
                        { "UKN01": "" },
                        { "KMRPK": "" },
                        { "SPAWN": "" },
                        { "SCZCT": "" },
                        { "BAIZE": "" },
                        { "STADM": "" },
                        { "UKN02": "" }
                    ]
                },
                "4支线": {
                    "color": "#169C9C",
                    "route": [
                        { "STADM": "" },
                        { "ACBTF": "" }
                    ]
                },
                "5": {
                    "color": "#8932B8",
                    "route": [
                        { "SCZCT": "" },
                        { "CZHCT": "" },
                        { "XNMCT": "" },
                        { "MUYLN": "" },
                        { "pos": [-8, 4], "stat": "planned" },
                        { "ACBTF": "" },
                        { "pos": [-12, 2], "stat": "planned" },
                        { "YGHOM": "" },
                        { "pos": [-12, 8], "stat": "planned" },
                        { "pos": [-14, 8], "stat": "planned" },
                        { "SZHCT": "" }
                    ]
                },
                "6": {
                    "color": "#C74EBD",
                    "route": [
                        { "QIWAN": "" },
                        { "pos": [-6, 12], "stat": "planned" },
                        { "ENSHM": "" },
                        { "CINDA": "" },
                        { "XNMCT": "" },
                        { "pos": [-2, 4], "stat": "planned" },
                        { "GJHOM": "" },
                        { "KEMOW": "" },
                        { "UKN03": "" },
                        { "KMRPK": "" },
                        { "LINDA": "" },
                        { "XYHOM": "" },
                        { "BREAD": "" },
                        { "ICERF": "" }
                    ]
                },
                "8": {
                    "color": "#5E7C16",
                    "route": [
                        { "ENSHM": "" },
                        { "WNSHM": "" },
                        { "pos": [-12, 8], "stat": "planned" },
                        { "YGHOM": "" }
                    ]
                }
            },
            "stations": {
                "ACBTF": {
                    "label": "古战场",
                    "pos": [-8, 2],
                    "stat": "planned"
                },
                "BAIZE": {
                    "label": "白泽",
                    "pos": [-4, 0],
                    "stat": "planned"
                },
                "BREAD": {
                    "label": "面包",
                    "pos": [8, -6],
                    "stat": "planned"
                },
                "CINDA": {
                    "label": "工业区空置域",
                    "pos": [-6, 6],
                    "stat": "planned"
                },
                "CZHCT": {
                    "label": "赐召",
                    "pos": [-2, 2],
                    "stat": "finished"
                },
                "ENSHM": {
                    "label": "满天星家东",
                    "pos": [-6, 8],
                    "stat": "planned"
                },
                "EYYCT": {
                    "label": "漪阳东",
                    "pos": [0, -4],
                    "stat": "finished"
                },
                "GJHOM": {
                    "label": "烧仙草家",
                    "pos": [-2, 6],
                    "stat": "planned"
                },
                "HINDA": {
                    "label": "重工业区",
                    "pos": [12, 0],
                    "stat": "planned"
                },
                "ICERF": {
                    "label": "冰道",
                    "pos": [10, -8],
                    "stat": "planned"
                },
                "INITS": {
                    "label": "元始",
                    "pos": [4, 4],
                    "stat": "planned"
                },
                "KEMOW": {
                    "label": "科魔",
                    "pos": [4, 6],
                    "stat": "planned"
                },
                "KMRPK": {
                    "label": "烟草公园",
                    "pos": [8, 0],
                    "stat": "planned"
                },
                "LINDA": {
                    "label": "轻工业区",
                    "pos": [8, -2],
                    "stat": "planned"
                },
                "LNYCT": {
                    "label": "临漪",
                    "pos": [0, -6],
                    "stat": "finished"
                },
                "MNTDY": {
                    "label": "定漪山",
                    "pos": [0, -2],
                    "stat": "finished"
                },
                "MUYLN": {
                    "label": "暮阳陵",
                    "pos": [-6, 4],
                    "stat": "planned"
                },
                "NNCNL": {
                    "label": "北运河北",
                    "pos": [0, 2],
                    "stat": "finished"
                },
                "PGNUN": {
                    "label": "鸽联",
                    "pos": [4, -10],
                    "stat": "planned"
                },
                "QIWAN": {
                    "label": "绮湾",
                    "pos": [-2, 12],
                    "stat": "planned"
                },
                "SCZCT": {
                    "label": "赐召南",
                    "pos": [-2, 0],
                    "stat": "planned"
                },
                "SPAWN": {
                    "label": "主城",
                    "pos": [0, 0],
                    "stat": "finished"
                },
                "STADM": {
                    "label": "玩家体育场",
                    "pos": [-8, 0],
                    "stat": "planned"
                },
                "STRHD": {
                    "label": "要塞",
                    "pos": [6, -6],
                    "stat": "planned"
                },
                "SZHCT": {
                    "label": "汕州",
                    "pos": [-14, 10],
                    "stat": "planned"
                },
                "UKN01": {
                    "label": "Unknown01",
                    "pos": [10, 0],
                    "stat": "planned"
                },
                "UKN02": {
                    "label": "Unknown02",
                    "pos": [-8, -4],
                    "stat": "planned"
                },
                "UKN03": {
                    "label": "Unknown03",
                    "pos": [8, 6],
                    "stat": "planned"
                },
                "WNSHM": {
                    "label": "满天星家西",
                    "pos": [-10, 8],
                    "stat": "finished"
                },
                "WTCCT": {
                    "label": "天策西",
                    "pos": [-2, -6],
                    "stat": "finished"
                },
                "WUMIN": {
                    "label": "梧鸣",
                    "pos": [2, -6],
                    "stat": "planned"
                },
                "XJIAN": {
                    "label": "薪涧",
                    "pos": [4, -8],
                    "stat": "planned"
                },
                "XNMCT": {
                    "label": "星眸",
                    "pos": [-4, 4],
                    "stat": "finished"
                },
                "XYHOM": {
                    "label": "逍遥家",
                    "pos": [8, -4],
                    "stat": "planned"
                },
                "YGHOM": {
                    "label": "叶光",
                    "pos": [-12, 6],
                    "stat": "finished"
                },
                "YXLAN": {
                    "label": "垭西兰",
                    "pos": [8, 8],
                    "stat": "planned"
                }
            }
        }
    </script>
    <script>
        const BLACK = "#000000"
        const LIGHTGRAY = "#AAAAAA"
        const WHITE = "#FFFFFF"
 
        function canvPos(x, y) {
            x = - Number(minx) + Number(x) + 1
            y = Number(maxy) - Number(y) + 1
            return [Math.round(x), Math.round(y)]
        }
 
        function drawMap(mapData, lineGet) {
            // 处理只显示单条的情况
            if(lineGet != undefined && mapData["lines"][lineGet] != undefined) {
                // 处理线路列表
                const lineShow = mapData["lines"][lineGet]
                mapData["lines"] = {}
                mapData["lines"][lineGet] = lineShow
                // 处理站点列表(删除不需要的站点)
                for (let station in mapData.stations) {
                    let get = false
                    for(let site in mapData["lines"][lineGet]["route"]) {
                        if(Object.keys(mapData["lines"][lineGet]["route"][site]) == station) {
                            get = true
                            break
                        }
                    }
                    if(!get) {
                        delete mapData.stations[station]
                    }
                }
            }
            // 计算全图大小
            for (let station in mapData.stations) {
                station = mapData.stations[station]
                let [x, y] = station.pos
                maxx = Math.max(maxx, x)
                maxy = Math.max(maxy, y)
                minx = Math.min(minx, x)
                miny = Math.min(miny, y)
            }
            size = Math.max(Math.abs(maxx) + Math.abs(minx), Math.abs(maxy) + Math.abs(miny)) * 0.55
            // 计算中心偏移
            adx = (minx + maxx) / 2
            ady = (miny + maxy) / 2
            // 开始显示
            let links = []
            for (let line in mapData.lines) {
                let lastpoint = undefined
                for (let waypoint in mapData.lines[line].route) {
                    waypoint = mapData.lines[line].route[waypoint]
                    if (waypoint.pos == undefined) {
                        waypoint = mapData.stations[Object.keys(waypoint)[0]]
                    }
                    else {
                        if (waypoint.stat == undefined) { waypoint.stat = "finished" }
                    }
                    if (lastpoint != undefined) {
                        let color = { "finished": mapData.lines[line].color, "planned": LIGHTGRAY }
                        let stat = "finished"
                        if (waypoint.stat == "planned" || lastpoint.stat == "planned") stat = "planned"
                        if (mapData.lines[line].stat == "planned") stat = "planned"
                        if (links[[lastpoint.pos, waypoint.pos]] != undefined) {
                            links[[lastpoint.pos, waypoint.pos]].push([line, color[stat]])
                        }
                        else {
                            if (links[[waypoint.pos, lastpoint.pos]] != undefined) {
                                links[[waypoint.pos, lastpoint.pos]].push([line, color[stat]])
                            }
                            else links[[lastpoint.pos, waypoint.pos]] = [[line, color[stat]]]
                        }
                    }
                    lastpoint = waypoint
                }
            }
 
            /* Draw lines */
            // 构建线条图层
            const gLine = document.createElementNS('http://www.w3.org/2000/svg','g')
            gLine.id = "LineList"
            gLine.style.transform = "translateX(" + adx / size * 50 + "%)"
            gLine.style.transform = "translateY(" + ady / size * 50 + "%)"
            for (let link in links) {
                let [x1, y1, x2, y2] = link.split(",")
                let linklen = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
                linkInfo = links[link]
                for (let rail in linkInfo) {
                    let dl = (rail - (linkInfo.length - 1) / 2) * 0.25
                    let [dx, dy] = [- (y2 - y1) / linklen * dl, (x2 - x1) / linklen * dl]
                    let [startx, starty] = [
                            50 + (Number(x1) / size * 50) + "%",
                            50 - (Number(y1) / size * 50) + "%"
                        ]
                    let [stopx, stopy] = [
                            50 + (Number(x2) / size * 50) + "%",
                            50 - (Number(y2) / size * 50) + "%"
                        ]
 
                    const line = document.createElementNS('http://www.w3.org/2000/svg','line')
                    line.dataset.raw = link
                    line.dataset.name = linkInfo[rail][0]
                    line.setAttribute("x1", startx)
                    line.setAttribute("y1", starty)
                    line.setAttribute("x2", stopx)
                    line.setAttribute("y2", stopy)
                    line.style.strokeWidth = "0.25rem"
                    line.style.strokeLinecap = "round"
                    line.style.stroke = linkInfo[rail][1]
                    line.style.transition = "stroke-width .3s"
                    // 偏移
                    let move = ""
                    if(dx > 0) {
                        move += "translateX(0.15rem) "
                    } else if(dx < 0) {
                        move += "translateX(-0.15rem) "
                    }
                    if(dy > 0) {
                        move += "translateY(0.15rem) "
                    } else if(dy < 0) {
                        move += "translateY(-0.15rem) "
                    }
                    line.style.transform = move
 
                    // 鼠标事件
                    line.onmouseover = function()  { onLineHover(line) }
                    line.onmouseleave = function()  { onLineLeave(line) }
 
                    if(gLine.children.length == 0) {
                        gLine.append(line)
                    } else {
                        gLine.insertBefore(line, gLine.firstChild)
                    }
                }
            }
            this.append(gLine)
 
 
            /* Draw stations */
            // 构建站点图层
            const gSite = document.createElementNS('http://www.w3.org/2000/svg','g')
            gSite.style.transform = "translateX(" + adx / size * 50 + "%)"
            gSite.style.transform = "translateY(" + ady / size * 50 + "%)"
            for (let station in mapData.stations) {
                station = mapData.stations[station]
                let stationColor = BLACK
                if (station.stat == "planned") stationColor = LIGHTGRAY
                let name = station.label
                let [x, y] = station.pos
 
                // <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>
                const point = document.createElementNS('http://www.w3.org/2000/svg','circle')
                point.dataset.raw = station.pos
                point.setAttribute("cx", 50 + (Number(x) / size * 50) + "%")
                point.setAttribute("cy", 50 - (Number(y) / size * 50) + "%")
                point.style.transition = "r .3s, stroke-width .3s"
                point.style.r = "0.5rem"
                point.style.fill = WHITE
                point.style.stroke = stationColor
                point.style.strokeWidth = "0.2rem"
 
                point.onmouseover = function()  { onPointOver(point)    }
                point.onmouseleave = function() { onPointLeace(point)  }
 
                // <text x="0" y="15" fill="red">I love SVG</text>
                const text = document.createElementNS('http://www.w3.org/2000/svg','text')
                text.setAttribute("x", 50 + (Number(x) / size * 50) + "%")
                text.setAttribute("y", 50 - (Number(y) / size * 50) + "%")
                text.style.transform = "translateX(0.7rem) translateY(-0.7rem)"
                text.style.fontSize = "0.6rem"
                text.style.fill = BLACK
                text.innerHTML = name
 
                if(gSite.children.length == 0) {
                    gSite.append(point)
                    gSite.append(text)
                } else {
                    gSite.insertBefore(point, gSite.firstChild)
                    gSite.insertBefore(text, gSite.firstChild)
                }
            }
            this.append(gSite)
        }
 
        // 整图大小
        let minx = 0, miny = 0, maxx = 0, maxy = 0, size = 0, adx = 0, ady = 0, view = 900
 
        // 初始化
        const div = document.getElementById("MainMap")                // SVG 框架
        // 生成 SVG
        // <svg  width="100vh" height="100%" view-box="0 0 2048 2048">
        window.mainMap = document.createElementNS('http://www.w3.org/2000/svg','svg')
        mainMap.setAttribute('version','1.1')
        mainMap.setAttribute("viewBox", "0 0 " + view + " " + view)
        mainMap.setAttribute("preserveAspectRatio", "xMidYMid meet")
        mainMap.style.width = '100vh'
        mainMap.style.height = '100%'
 
        mainMap.drawMap = drawMap
        mainMap.drawMap(dataset)
 
        div.append(mainMap)
    </script>
    <script>
        // 线段悬停事件
        function onLineHover(sender) {
            // 线名
            const name = sender.dataset.name
            // 寻找所有线段
            const list = document.getElementById("LineList").children
            for(let i=0; i<=list.length; i++) {
                if(list[i] != undefined && list[i].dataset.name == name) {
                    list[i].style.strokeWidth = "0.4rem"
                }
            }
        }
        function onLineLeave(sender) {
            // 线名
            const name = sender.dataset.name
            // 寻找所有线段
            const list = document.getElementById("LineList").children
            for(let i=0; i<=list.length; i++) {
                if(list[i] != undefined && list[i].dataset.name == name) {
                    list[i].style.strokeWidth = "0.25rem"
                }
            }
        }
 
        // 站点悬停事件
        function onPointOver(sender) {
            sender.style.r = "1px"
            sender.style.strokeWidth = "1rem"
        }
        function onPointLeace(sender) {
            sender.style.r = "0.5rem"
            sender.style.strokeWidth = "0.2rem"
        }
    </script>
</body>
 
</html>

2022年11月30日 (三) 19:08的最新版本


Icon-warn.png
内容未完成
本页面内容处于未完成状态。




图例:
1号线 2号线 3号线 4号线 5号线 6号线 8号线