ZENRIN Maps APIとGoogle Maps APIのバリアフリー歩行者ルート検索の違い


## 要約
本記事では、ZENRIN Maps APIとGoogle Maps APIを使用してバリアフリーに対応した歩行者ルートを検索の違いを比較します。
ZENRIN Maps APIは、バリアフリールートの検索機能を提供しており、特定の条件下で有効です。
一方、Google Maps APIは、バリアフリーに関する直接的なオプションは提供していませんが、代替手段を通じてある程度の対応が可能です。
それぞれのAPIの実装方法や特徴を解説しています。

## はじめに
バリアフリーの歩行者ルート検索は、高齢者、障がいを持つ方、ベビーカー利用者など、移動に制約のある人々にとって非常に重要です。
本記事では、ZENRIN Maps APIとGoogle Maps APIを用いて、このバリアフリールート検索を実装し、それぞれのAPIの特性と実装方法を比較検討します。

### 対象読者
- バリアフリー地図アプリケーションの開発に関心のある方
- 経路探索APIの選定に悩んでいる方
- ZENRIN Maps APIとGoogle Maps APIの違いを詳しく知りたい方

## ZENRIN Maps APIを使用したバリアフリーの歩行者ルート検索
### 実装概要
ZENRIN Maps APIを利用して、特定の出発地点から目的地点までの歩行者ルートを検索し、バリアフリーを考慮した歩行者ルート検索を実装しました。
ZENRIN Maps APIを使用するためには検証用IDとPW取得が必要です。
お試しIDは下記から簡単に発行できました。
[ZENRIN Maps API　無料お試しID　お申込みフォーム（2か月無料でお試しできます）](https://www.zenrin-datacom.net/solution/zenrin-maps-api/trial?fm_cp=6757baf3203e3a00bb118509&fm_mu=676395f4affc4404b17d8f70&utm_campaign=6757baf3203e3a00bb118509&utm_medium=else&utm_source=Qiita21)

詳細手順は[こちら](https://qiita.com/goldie9/items/1983bf8c4ad796290cbf)を参照しました。


## 実装コード
```JavaScript
ZMALoader.setOnLoad(function(mapOptions, error) {
    if (error) {
        console.error('ZMALoader error:', error);
        return;
    }

    const mapElement = document.getElementById('map');
    mapOptions.center = new ZDC.LatLng(35.465833, 139.622778);
    mapOptions.zoom = 17;

    const map = new ZDC.Map(mapElement, mapOptions, function() {
        console.log('Map initialized successfully');

        // コントロールを追加
        map.addControl(new ZDC.ZoomButton('top-left'));
        map.addControl(new ZDC.Compass('top-right'));
        map.addControl(new ZDC.ScaleBar('bottom-left'));

        const start = new ZDC.LatLng(35.465833, 139.622778); //横浜駅
        const end = new ZDC.LatLng(35.46202838, 139.62674483); //新高島駅

        const startMarker = new ZDC.Marker(start);
        const endMarker = new ZDC.Marker(end);
        map.addWidget(startMarker);
        map.addWidget(endMarker);

        const routeUrl = `https://{ドメイン}/route/route_mbn/walk?search_type=5&from=${start.lng},${start.lat}&to=${end.lng},${end.lat}&llunit=dec&datum=JGD`;

        fetch(routeUrl, {
            method: 'GET',
            headers: {
                'x-api-key': '{APIキー}',
                'Authorization': 'ip'
            },
        })
        .then(response => {
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            return response.json();
        })
        .then(data => {
            console.log('API Response:', JSON.stringify(data, null, 2));
            if (data.status === 'OK') {
                if (data.result && data.result.item && data.result.item.length > 0) {
                    const routeItem = data.result.item[0];
                    console.log('Route item:', JSON.stringify(routeItem, null, 2));

                    if (routeItem.route && routeItem.route.section && Array.isArray(routeItem.route.section)) {
                        const sections = routeItem.route.section;
                        console.log('Sections:', JSON.stringify(sections, null, 2));
                        const decodedPath = [];
                        sections.forEach(section => {
                            if (section.link && Array.isArray(section.link)) {
                                section.link.forEach(link => {
                                    if (link.line && link.line.coordinates) {
                                        link.line.coordinates.forEach(coord => {
                                            decodedPath.push(new ZDC.LatLng(coord[1], coord[0]));
                                        });
                                    }
                                });
                            }
                        });

                        if (decodedPath.length > 0) {
                            console.log('Decoded path:', decodedPath);
                            const routeLine = new ZDC.Polyline(decodedPath, {
                                color: '#008dcb',
                                width: 5,
                                opacity: 0.7
                            });
                            map.addWidget(routeLine);
                            console.log('Route line added to map');

                            const bounds = new ZDC.LatLngBounds();
                            decodedPath.forEach(point => bounds.extend(point));
                            map.fitBounds(bounds);
                        } else {
                            console.error('デコードされたパスが空です。sections:', JSON.stringify(sections, null, 2));
                        }
                    } else {
                        console.error('ルートセクションデータが不正です:', routeItem.route);
                    }
                } else {
                    console.error('ルートアイテムが見つかりません:', data.result);
                }
            } else {
                console.error('APIステータスがOKではありません:', data.status);
            }
        })
        .catch(error => {
            console.error('ルート検索エラー:', error);
        });
    }, function() {
        console.error('地図の生成に失敗しました');
    });
})
```
## 実装結果と課題
- **結果**：ZENRIN Maps APIを使用することで、バリアフリーを考慮したルートを地図上に表示できました。
search_type=5を使用することで、APIがバリアフリーに配慮したルートを返すことができました。

- **課題**：バリアフリーの基準が明確でないため、実際にどのような経路が選択されているかの検証が必要そうです。

## Google Maps APIを使用したバリアフリーの歩行者ルート検索
### 実装概要
Google Maps APIを使用して、出発地点から目的地点までの歩行者ルートを検索し、地図上に表示する機能を実装しました。

## 実装コード
```html
<script>
function initMap() {
    const map = new google.maps.Map(document.getElementById("map"), {
        center: { lat: 35.465833, lng: 139.622778 },
        zoom: 15,
    });

    const directionsService = new google.maps.DirectionsService();
    const directionsRenderer = new google.maps.DirectionsRenderer();
    directionsRenderer.setMap(map);

    const request = {
        origin: new google.maps.LatLng(35.465833, 139.622778),
        destination: new google.maps.LatLng(35.46202838, 139.62674483),
        travelMode: google.maps.TravelMode.WALKING,
    };

    directionsService.route(request, (result, status) => {
        if (status === 'OK') {
            directionsRenderer.setDirections(result);
            const route = result.routes[0].legs[0];
            document.getElementById('distance').textContent = '総距離: ' + route.distance.text;
            document.getElementById('duration').textContent = '所要時間: ' + route.duration.text;

            const steps = route.steps;
            const routeSteps = document.getElementById('route-steps');
            steps.forEach(step => {
                const li = document.createElement('li');
                li.innerHTML = step.instructions + ' (' + step.distance.text + ')';
                routeSteps.appendChild(li);
            });
        } else {
            console.error("ルート検索に失敗しました: " + status);
        }
    });
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key={APIキー}&callback=initMap" async defer></script>
```
## 実装結果と課題
- **結果**：Google Maps APIを使用して、基本的な歩行者ルートを地図上に表示し、距離や所要時間などの情報を提供できました。
- **課題**：Google Maps APIはバリアフリーに関する直接的なオプションを提供していないため、階段や段差を避けたルートを自動的に選択することはできません。

## 地図表示
- **ZENRIN Maps API**
![zma_BarrierFree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979666/4f60640a-e31f-423e-9a65-ba6eac68406f.png)


- **Google Maps API**
![gma_BarrierFree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979666/d9252a36-75b6-444d-a767-b67b969641e0.png)


## API比較
- **バリアフリー対応**：ZENRIN Maps APIは、バリアフリールートの検索機能を直接提供しており、search_type=5を使用することでバリアフリーに配慮したルートを返すことができます。
一方、Google Maps APIは直接的なバリアフリーオプションを提供していませんでした。
- **カスタマイズ性**：Google Maps APIは豊富なドキュメントと広範なコミュニティサポートがあり、カスタマイズの幅が広いです。
ZENRIN Maps APIは日本国内に特化した詳細な地図情報を提供しています。
- **使いやすさ**：Google Maps APIは世界中で広く使われており、導入しやすいです。
ZENRIN Maps APIは日本国内での利用に特化しており、日本語のサポートが充実しています。
- **データ**：ZENRIN Maps APIは日本国内の詳細な地図情報を提供しており、特に都市部での精度が高いです。
Google Maps APIはグローバルなカバレッジを持ち、世界中の地図データを提供していますが、日本国内の細かい情報については、ZENRIN Maps APIの方が優れている場合がありそうです。

## まとめ
ZENRIN Maps APIとGoogle Maps APIを使用して、バリアフリーの歩行者ルート検索を実装しました。
ZENRIN Maps APIは屋根付きルートの検索が可能で日本国内の詳細な地図情報を提供する一方、Google Maps APIは世界中で広く使われており、豊富なドキュメントとコミュニティサポートがあります。プロジェクトの要件、利用可能なデータ、開発リソースなどを考慮し、最適なAPIを選択してください。