地下街・駅構内詳細図のルートを利用する

実行結果

次の例では、地下街・駅構内詳細図の施設を表示します。

Your borwser is not supporting object tag. Please use one of the latest browsers.
Go to ./apisample/detail_route_test/index.html

ソースコードと解説

地下街・駅構内詳細図を表示するには、ZDC.Detailクラスと、ZDC.MapクラスのaddWidget()を利用します。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<script src="//test.api.its-mo.com/v3/loader?key=JSZddc5111626c8|Zo4wz&api=zdcmap.js,shape.js,search.js,detail.js,control.js&enc=UTF8"></script>

<script type="text/javascript">
    var map, scale, controlNormal;

    var defaultLatlon = new ZDC.LatLon(35.6864521, 139.7025495);

    /* 詳細図 */
    var detailLayer;

    function loadMap(options) {
      options = options || {};

        map = new ZDC.Map(
            document.getElementById('ZMap'),
            {
                latlon : defaultLatlon,
                /* 高解像度地図画像を利用する */
                mapType: ZDC.MAPTYPE_FLAT_LV20,
                zoom: 17
            }
        );

        /* 中心点画像を追加 */
        var centerWidget = new ZDC.MapCenter();
        map.addWidget(centerWidget);

        /* 詳細図を追加 */
        detailLayer = new ZDC.Detail(options);
        map.addWidget(detailLayer);

        /* 地図のドラッグを終了したときの動作 */
        ZDC.addListener(map, ZDC.MAP_DRAG_END, getDetailMapInfo);

        /* 詳細図情報取得 */
        getDetailMapInfo();

        scale = new ZDC.ScaleBar();
        map.addWidget(scale);

        controlNormal = new ZDC.Control(
            {
                pos:{
                    top:10,
                    left:10
                },
            type:ZDC.CTRL_TYPE_NORMAL,
            close:true
            }
        );

        /* 通常のコントロールを表示 */
        map.addWidget(controlNormal);

        /* 地図クリック時のリスナを追加 */
        var clickAct = ZDC.addListener(
            map,
            ZDC.MAP_CLICK,
            function() {
                var clickedLatlon = map.getClickLatLon();
                handle_when_click_on_map(clickedLatlon);
            }
        );

    };

    /********** 階層表示 **********/

    var btnFloorArr = []; // 階層ボタン
    var addedEleArr = []; // 階層ボタン表示tr(表示コントロール用)

    function getDetailMapInfo() {
        /* 中心座標を取得 */
        var currLatlonStr = map.getLatLon();

        /* 詳細図の情報を取得 */
        ZDC.Search.getByZmaps('detail_map_info', {
                latlon: currLatlonStr.lat + ',' + currLatlonStr.lon
            },
            function (status, data) {
                /* 階層ボタンクリア */
                cleanBtnArr(btnFloorArr);

                var items = data.item;
                var floorInfoArr; // フロア情報
                for (var i = 0; i < items.length; i++) {
                    /* フロア情報を取得 */
                    floorInfoArr = items[i]['floorInfo'];
                    floorInfoArr = floorInfoArr.sort(function(a, b){return a.floorLevel - b.floorLevel});

                    /* 階層ボタン追加 */
                    addFloorBtn(floorInfoArr, i);
                }
            }
        );
    }

    function cleanBtnArr(btnArr) {
        for (var i = addedEleArr.length - 1; i >= 0; i--) {
          if(addedEleArr[i].parentNode != null){
                addedEleArr[i].parentNode.removeChild(addedEleArr[i]);
            }
        }
        btnArr.length = 0;
    }

    // ボタン背景色
    var btnBgColors = ['#28b9b1', '#2854b9', '#3428b9', '#6228b9', '#9228b9', '#b928b4'];

    function addFloorBtn(floorInfoArr, I) {
        currLevel = detailLayer.getFloorLevel();
        var table = document.getElementById('menuTbl');

        for (var i = floorInfoArr.length - 1; i >= 0; i--) {
            var btn = document.createElement('BUTTON');
            btn.className = 'menuBtn floorBtn';

            btn.style.backgroundColor = btnBgColors[(I < btnBgColors.length) ? I : btnBgColors.length - 1];

            btnFloorArr.push(btn);
            if (currLevel == floorInfoArr[i].floorLevel) {
                btn.style.color = 'red';
            }
            btn.addEventListener('click',
                function () {
                    currLevel = detailLayer.getFloorLevel();
                    detailLayer.moveToFloor(this.value);
                    resetBtnColor(btnFloorArr);

                    redraw();
                    this.style.color = 'red';
                }
            );
            btn.value = floorInfoArr[i].floorLevel;
            var t = document.createTextNode(floorInfoArr[i].floorName);
            var td = document.createElement('TD');
            var tr = document.createElement('TR');
            table.appendChild(tr);
            addedEleArr.push(tr);
            tr.appendChild(td);
            td.appendChild(btn);
            btn.appendChild(t);
        }
    }

    function upToFloor(btn) {
        /* 1階層上の詳細図へ移動 */
        detailLayer.upToFloor();

        /* 表示中の詳細図の階層を取得 */
        var currLevel = detailLayer.getFloorLevel();
        resetBtnColor(btnFloorArr);
        btn.style.color = 'red';
        markFloorByRedColor(btnFloorArr, currLevel);
        document.getElementById('downToFloorBtn').style.color = 'white';
    }

    function downToFloor(btn) {
        /* 1階層下の詳細図へ移動 */
        detailLayer.downToFloor();

        /* 表示中の詳細図の階層を取得 */
        var currLevel = detailLayer.getFloorLevel();
        resetBtnColor(btnFloorArr);
        btn.style.color = 'red';
        markFloorByRedColor(btnFloorArr, currLevel)
        document.getElementById('upToFloorBtn').style.color = 'white';
    }

    function resetBtnColor (btnArr) {
        for (var i = btnArr.length - 1; i >= 0; i--) {
            if (btnArr[i].style.color == 'red') {
                btnArr[i].style.color = 'white';
            }
        }
    }

    function markFloorByRedColor (btnArr, level) {
        for (var i = btnArr.length - 1; i >= 0; i--) {
            if (btnArr[i].value == level) {
                btnArr[i].style.color = 'red';
            }
        }
    }

    /********** ルート表示 **********/

    /* マーカ格納配列 */
    mkArr = [];

    var endP; // end設定点
    var endFloor; // end設定階層
    var startP; // start設定点
    var startFloor; // start設定階層

    var mode = 1; // 1:start設定 2:end設定

    function setStartPointMode() {
      mode = 1;
    }

    function setEndPointMode() {
      mode = 2;
    }

    function handle_when_click_on_map (clickedLatlon) {
        switch(mode) {
            case 0:
                return;
            case 1:
                startP = clickedLatlon;
                startFloor = detailLayer.getFloorLevel();
                initMarker(startP, {markerStyle: 0, lvl: startFloor});
                mode = 2;
                break;
            case 2:
                endP = clickedLatlon;
                endFloor = detailLayer.getFloorLevel();
                initMarker(endP, {markerStyle: 1, lvl: endFloor});
                if (startP && endP) {
                    drawRoute(startP, endP, startFloor, endFloor, map);
                }
                break;
        }
    }

    function initMarker(markerLatlon, info) {
        if (!markerLatlon || !map) {
            alert('マーカの緯度経度、またはマップがない');
            return;
        }

        var iconimg;

        switch (info.markerStyle) {
            case 0:
                iconimg = 'img/icon/start.png';
                break;
            case 1:
                iconimg = 'img/icon/end.png';
                break;
            default:
                break;
        }

        if (iconimg) {
            var newMarker = new ZDC.Marker(
                markerLatlon,
                {
                    /* マーカのサイズに合わせて位置を調整する */
                    offset: new ZDC.Pixel(-32, -64),
                    custom: {
                        base : {
                            src: iconimg
                        }
                    }
                }
            );
        }

        /* start/endマーカを追加 */
        map.addWidget(newMarker);

        mkArr.push({marker: newMarker, info: info});
    }

    function drawRoute(p1, p2, fromlevel, tolevel, map) {

        ZDC.Search.getByZmaps(
            'route/walk',
            {
                from: p1.lat + ',' + p1.lon,
                to: p2.lat + ',' + p2.lon,
                fromlevel: fromlevel,
                tolevel: tolevel
            },
            function (status, result) {
                if(status.code != 200) {
                    alert(status.text);
                } else if(result.status.code !== '0000') {
                    alert(result.status.text);
                } else {
                    handleRouteRes(result, detailLayer.getFloorLevel());
                }
            }
        );
    }

    var line_property = {
        '通常通路'  : {strokeColor: '#3000ff', strokeWeight: 5, lineOpacity: 0.5, lineStyle: 'solid'},
        '横断歩道'  : {strokeColor: '#008E00', strokeWeight: 5, lineOpacity: 0.5, lineStyle: 'solid'},
        '横断通路'  : {strokeColor: '#007777', strokeWeight: 5, lineOpacity: 0.5, lineStyle: 'solid'},
        '歩道橋'    : {strokeColor: '#880000', strokeWeight: 5, lineOpacity: 0.5, lineStyle: 'solid'},
        '踏切内通路': {strokeColor: '#008800', strokeWeight: 5, lineOpacity: 0.5, lineStyle: 'solid'},
        '連絡通路'  : {strokeColor: '#000088', strokeWeight: 5, lineOpacity: 0.5, lineStyle: 'solid'},
        '建物内通路': {strokeColor: '#A400DB', strokeWeight: 5, lineOpacity: 0.5, lineStyle: 'solid'},
        '敷地内通路': {strokeColor: '#c0392b', strokeWeight: 5, lineOpacity: 0.5, lineStyle: 'solid'},
        '乗換リンク': {strokeColor: '#2c3e50', strokeWeight: 5, lineOpacity: 0.5, lineStyle: 'solid'},
        '通路外'    : {strokeColor: '#f39c12', strokeWeight: 5, lineOpacity: 0.5, lineStyle: 'solid'},
        '改札内通路': {strokeColor: '#ff3030', strokeWeight: 5, lineOpacity: 0.5, lineStyle: 'solid'},
        '0'         : {strokeColor: '#ff3030', strokeWeight: 5, lineOpacity: 0.5, lineStyle: 'solid'} };

    /* ルート格納配列 */
    polylineArr = [];

    function handleRouteRes(res, floorLevel) {
        /* ルートのリンク取得 */
        var link = res.route.link;
        var pl, latlons = [];
        for (var i = link.length - 1; i > -1; i--) {
            var linkInfo = link[i];

            var opt = line_property[linkInfo.type];
            if (!opt) {
                opt = line_property['0'];
            }

            var guidance = linkInfo.guidance;
            var lvl;
            if ('undefined' !== typeof (guidance.detailInfo[0]) &&
                null !== guidance.detailInfo[0]) {
                if ('undefined' !== typeof guidance.detailInfo[0].level &&
                    null !== guidance.detailInfo[0].level) {
                    lvl = guidance.detailInfo[0].level;
                }
            }
            var pllatlons = [];

            var latlonArr = linkInfo.line.latlon;
            for (var k = 0, l = latlonArr.length - 1; k < l; k += 2) {
                pllatlons.push(new ZDC.LatLon(latlonArr[k], latlonArr[k + 1]));
                latlons.push(new ZDC.LatLon(latlonArr[k], latlonArr[k + 1]));
            }

            initPolyline(pllatlons, {opt:opt, lvl:lvl, linkInfo:linkInfo});
        }
        redraw();
    }

    function initPolyline(polylineLatlonArr, info) {
        if (!ZDC) {
            showErrorNotFound('ZDC object', 'when init single polyline!');
            return 0;
        }
        var pl;
        if (info.color) {
            noColorSolidLineStyle.strokeColor = info.color;
        }

        /* 線を作成 */
        if (info.opt) {
            pl = new ZDC.Polyline(polylineLatlonArr, info.opt);
        }

        if (polylineArr) {
            polylineArr.push({polyline: pl, info: info});
        }

        map.addWidget(pl);

        redraw();
    }

    function redraw() {
        hideObject();

        /* 現在の階層を取得 */
        var currLevel = detailLayer.getFloorLevel();
        if (mkArr) {
            for (var i = mkArr.length - 1; i >= 0; i--) {
              var markerLevel = mkArr[i]["info"].lvl;
              if (mkArr[i]["marker"] && currLevel === markerLevel) {
                mkArr[i]["marker"].visible();
              }
            }
        }
        if (polylineArr) {
            for (var i = polylineArr.length - 1; i >= 0; i--) {
              var lineLevel = polylineArr[i]["info"].lvl;
              if (polylineArr[i]["polyline"] && currLevel === lineLevel) {
                    polylineArr[i]["polyline"].visible();
                }
            }
        }
    }

    function hideObject () {
        if (mkArr) {
            for (var i = mkArr.length - 1; i >= 0; i--) {
                if (mkArr[i]["marker"]) {
                    mkArr[i]["marker"].hidden();
                }
            }
        }
        if (polylineArr) {
            for (var i = polylineArr.length - 1; i >= 0; i--) {
                polylineArr[i]["polyline"].hidden();
            }
        }
    }

    function clearRoute() {
        if (mkArr) {
            for (var i = mkArr.length - 1; i >= 0; i--) {
                if (mkArr[i]["marker"]) {
                    map.removeWidget(mkArr[i]["marker"]);
                }
            }
            mkArr.length = 0;
        }
        if (polylineArr) {
            for (var i = polylineArr.length - 1; i >= 0; i--) {
                map.removeWidget(polylineArr[i]["polyline"]);
            }
            polylineArr.length = 0;
        }

        mode = 1;
    }

</script>
<style>
.body {
    top:0px;
    position:absolute;
}
.body.map {
    border:1px solid #777777;
    width:750px;
    height:500px;
    left:20px;
}
.body.menu {
    right:40px; top:20px;
}
.menuBtn {
    background-color: #2980b9;
    border: none;
    color: white;
    padding: 8px;
    width: 48px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 16px;
    margin: 4px 2px;
    cursor: pointer;
}
.menuBtn.updownBtn {
    background-color: #2980b9;
}
.menuBtn.floorBtn {
    background-color: #16a085;
}
</style>
</head>

<body onload="loadMap();">
    <div id="ZMap" class="body map"></div>
    <div class="body menu">
        <table id="menuTbl">
            <tr><td><button id="startSetBtn" class="menuBtn" type="button" onclick="setStartPointMode();">start</button></td></tr>
            <tr><td><button id="endSetBtn" class="menuBtn" type="button" onclick="setEndPointMode();">goal</button></td></tr>
            <tr><td><button id="clearBtn" class="menuBtn" onclick="clearRoute();">clear</button></td></tr>
            <tr><td><button id="upToFloorBtn" class="menuBtn updownBtn" type="button" onclick="upToFloor(this);">↑</button></td></tr>
            <tr><td><button id="downToFloorBtn" class="menuBtn updownBtn" type="button" onclick="downToFloor(this);">↓</button></td></tr>
        </table>
    </div>

</body>
</html>