スポンサードリンク

トータルの合計距離+地図から行きたい場所を探して、出発、中継点、到着点を入力クリックしてドライブルート経路検索

◆Google Maps API V3 + Directions API (トータルの合計距離を表示させたい)

デモギャラリーサンプルをいじってみたが、何か足りん。

そう、地図右側に表示されるルート表示のサイドバーでは、トータルの距離がわからないのである。ぐっ不便。

しかしながら、デモギャラリーでなく、Google Maps Javascript API V3 Examplesのサンプルを見ていたらtotal distanceを表示したサンプルが・・・。

せっかくなので、MarkerClustererと組み合わせて、MarkerClustererで表示されたアイコン間をドライブした気分でルート検索した合計距離を表示させてみる。

◆script

<script type="text/javascript">
    var center = new google.maps.LatLng(35.62674, 139.75880);
    var zoom = 13;
    var mapTypeId = google.maps.MapTypeId.ROADMAP

</script>
<script type="text/javascript">
//<![CDATA[

  var directionDisplay;
  var directionsService = new google.maps.DirectionsService();
  var map;
  var origin = null;
  var destination = null;
  var waypoints = [];
  var directionmarkers = [];
  var directionsVisible = false;

google.load('search','1');
var mcmarkers = [];

var customIcons = {
kouen: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/tree.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/tree.shadow.png'
      },
oyogu: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/swimming.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/swimming.shadow.png'
      },
temapark: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/motorcycling.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/cycling.shadow.png'
      },
sakana: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/water.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/water.shadow.png'
      },
suizokukan: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/fishing.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/fishing.shadow.png'
      },
onsen: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/hotsprings.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/hotsprings.shadow.png'
      },
doubutsu: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/horsebackriding.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/horsebackriding.shadow.png'
      },
outdoor: {
        icon: 'http://maps.google.com/mapfiles/ms/micons/sunny.png',
        shadow: 'http://maps.google.com/mapfiles/ms/micons/sunny.shadow.png'
      },
maturi: {
        icon: 'http://waox.main.jp/maps/gif/illust2212_thumb.gif',
        shadow: 'http://waox.main.jp/maps/gif/shadow-illust2212_thumb.png'
      },
sakura: {
        icon: 'http://waox.main.jp/maps/gif/sakura-ai.gif',
        shadow: 'http://waox.main.jp/maps/gif/shadow-sakura-ai.png'
      },
momiji: {
        icon: 'http://waox.main.jp/maps/gif/momiji01_002.gif',
        shadow: 'http://waox.main.jp/maps/gif/shadow-momiji01_002.png'
      },
kaisui: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/waterfalls.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/waterfalls.shadow.png'
      },
mikaku: {
        icon: 'http://waox.main.jp/maps/gif/budou01_s.gif',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/info.shadow.png'
      },
fuyu: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/snowflake_simple.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/snowflake_simple.shadow.png'
      },
banga: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/rangerstation.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/rangerstation.shadow.png'
      },
bbq: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/firedept.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/firedept.shadow.png'
      },
event: {
        icon: 'http://maps.google.com/mapfiles/ms/micons/volcano.png',
        shadow: 'http://maps.google.com/mapfiles/ms/micons/volcano.shadow.png'
      },
hakubutsukan: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/info.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/info.shadow.png'
      },
camping: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/campground.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/campground.shadow.png'
      },
drivespot: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/ltblu-pushpin.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/pushpin_shadow.png'
      },
kanko: {
        icon: 'http://maps.google.com/mapfiles/ms/micons/camera.png',
        shadow: 'http://maps.google.com/mapfiles/ms/micons/camera.shadow.png'
      },
restaurant: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/restaurant.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/restaurant.shadow.png'
      },
restaurant: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/restaurant.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/restaurant.shadow.png'
      },
hotel: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/homegardenbusiness.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/homegardenbusiness.shadow.png'
      },
shop: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/shopping.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/convienancestore.shadow.png'
      },
camera: {
        icon: 'http://maps.google.com/mapfiles/ms/micons/webcam.png',
        shadow: 'http://maps.google.com/mapfiles/ms/micons/webcam.shadow.png'
      },
ski: {
        icon: 'http://maps.google.com/mapfiles/ms/micons/ski.png',
        shadow: 'http://maps.google.com/mapfiles/ms/micons/ski.shadow.png'
      },
car: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/cabs.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/cabs.shadow.png'
      },
rail: {
        icon: 'http://maps.google.com/mapfiles/ms/micons/rail.png',
        shadow: 'http://maps.google.com/mapfiles/ms/micons/rail.shadow.png'
      },
parking: {
        icon: 'http://maps.google.co.jp/mapfiles/ms/icons/parkinglot.png',
        shadow: 'http://maps.google.co.jp/mapfiles/ms/icons/parkinglot.shadow.png'
      } 

};

function initialize()
{

    var myOptions =
    {
    zoom: zoom,
    center: center,
    mapTypeId: mapTypeId
    };

    gbarOptions=
    {
       // we're going with the defaults
    };

    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    var gbar=new window.jeremy.jGoogleBar(map,gbarOptions);
    map.controls[google.maps.ControlPosition.BOTTOM_LEFT].push(gbar.container); 

           directionsDisplay = new google.maps.DirectionsRenderer({draggable: true});
    directionsDisplay.setMap(map);
    directionsDisplay.setPanel(document.getElementById("directionsPanel"));

    google.maps.event.addListener(directionsDisplay, 'directions_changed', function()
    {//◆総距離合計
    computeTotalDistance(directionsDisplay.directions);
    });

    google.maps.event.addListener(map, 'click', function(event)
    {
        if (origin == null)
        {
             origin = event.latLng;
        addMarker(origin);
        }
        else if (destination == null)
        {
        destination = event.latLng;
        addMarker(destination);
        }
        else
        {
            if (waypoints.length < 9)
            {
            waypoints.push({ location: destination, stopover: true });
            destination = event.latLng;
            addMarker(destination);

            }
            else
            {
            alert("Way Pointは、これ以上設定できません。");
            }
        }
    });

    downloadUrl("http://waox.main.jp/news/maps/googlemapsapi/example/cluster2-demo.php", function(data)
    {
    var infoWindow = new google.maps.InfoWindow;
    var cmarkers = data.documentElement.getElementsByTagName("marker");
        for (var i = 0; i < cmarkers.length; i++)
        {
        var name = cmarkers[i].getAttribute("name");
        var explanation = cmarkers[i].getAttribute("explanation");
        var category = cmarkers[i].getAttribute("category");
        var point = new google.maps.LatLng(
        parseFloat(cmarkers[i].getAttribute("lat")),
        parseFloat(cmarkers[i].getAttribute("lng")));
        var linkurl = cmarkers[i].getAttribute("linkurl");
        var html = '<div style="height: 150px; width: 200px"><b>'+name+'</b><br>'+explanation+'</b><br>'+linkurl+'</b>' +
        '<form action="http://maps.google.co.jp/maps" method="get" target="_blank">' +
        '<input value="ここへのルート検索" type="submit">' +
        '<input type="hidden" name="daddr" value="' + point.lat() + ',' + point.lng() +
        '"/>'  ;
        var icon = customIcons[category] || {};
            var marker = new google.maps.Marker(
            {
            map: map,
            position: point,
            icon: icon.icon,
            shadow: icon.shadow,
            title: name
            });
            bindInfoWindow(marker, map, infoWindow, html);
            function bindInfoWindow(marker, map, infoWindow, html)
            {
                google.maps.event.addListener(marker, 'click', function()
                {
                infoWindow.setContent(html);
                infoWindow.open(map, marker);
                });
            }
            mcmarkers.push(marker);
        }
        var markerCluster = new MarkerClusterer(map, mcmarkers,{gridSize: 200,maxZoom:11});
    });

}

function addMarker(latlng)
{
    directionmarkers.push(new google.maps.Marker(
    {
    position: latlng,
    map: map,
    icon: "http://maps.google.com/mapfiles/marker" + String.fromCharCode(directionmarkers.length + 65) + ".png"
    }));
}

function calcRoute()
{
    if (origin == null)
    {
    alert("Click on the map to add a start point");
    return;
    }

    if (destination == null)
    {
    alert("Click on the map to add an end point");
    return;
    }

    var mode;
    switch (document.getElementById("mode").value)
    {
    case "driving":
    mode = google.maps.DirectionsTravelMode.DRIVING;
    break;
    case "walking":
    mode = google.maps.DirectionsTravelMode.WALKING;
    break;
    }

    var request =
    {
    origin: origin,
    destination: destination,
    waypoints: waypoints,
    travelMode: mode,
    optimizeWaypoints: document.getElementById('optimize').checked,
    avoidHighways: document.getElementById('highways').checked,
    avoidTolls: document.getElementById('tolls').checked
    };

    directionsService.route(request, function(response, status)
    {
        if (status == google.maps.DirectionsStatus.OK)
        {
        directionsDisplay.setDirections(response);
        }
    });

    clearMarkers();
    directionsVisible = true;
}

function updateMode()
{
    if (directionsVisible)
    {
    calcRoute();
    }
}

function clearMarkers()
{
    for (var i = 0; i < directionmarkers.length; i++)
    {
    directionmarkers[i].setMap(null);
    }
}

function clearWaypoints()
{
    directionmarkers = [];
    origin = null;
    destination = null;
    waypoints = [];
    directionsVisible = true;
  }

//◆総距離合計
function computeTotalDistance(result)
{
var total = 0;
var myroute = result.routes[0];
    for (i = 0; i < myroute.legs.length; i++)
    {
    total += myroute.legs[i].distance.value;
    }
    total = total / 1000.
    document.getElementById("total").innerHTML = total + " km";
}   

function reset()
{
clearMarkers();
clearWaypoints();
directionsDisplay.setMap(null);
directionsDisplay.setPanel(null);
directionsDisplay = new google.maps.DirectionsRenderer({draggable: true});
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById("directionsPanel"));
    //◆総距離合計リセット
    google.maps.event.addListener(directionsDisplay, 'directions_changed', function()
    {
    computeTotalDistance(directionsDisplay.directions);
    });
}

google.setOnLoadCallback(initialize);//◆ローカルサーチ用

//]]>
</script>

◆html

<!--ここからGoogle Maps v3用-->
<table style="width: 400px">
  <tr>
    <td><input type="checkbox" id="optimize" checked="checked" />ルート最適化</td>
    <td><input type="checkbox" id="highways"  />一般道優先</td>
    <td><input type="checkbox" id="tolls" />有料道路を避ける</td>
  </tr>
  <tr>
    <td>
    <select id="mode" onchange="updateMode()">
    <option value="driving">自動車</option>
    <option value="walking">徒歩</option>
    </select>
    </td>
    <td><input type="button" value="リセット" onclick="reset()" /></td>
    <td><input type="button" value="ルートを検索する。" onclick="calcRoute()" /></td>
  </tr>
</table>
<div style="position:relative; border: 1px; width : 965px; height : 596px;">
  <div id="map_canvas" style="border: 1px solid black; position:absolute; width : 677px; height : 581px; top : 6px; left : -11px;"></div>
  <div id="directionsPanel" style="position:absolute; left : 682px; width : 263px; height : 575px; overflow: auto; top : 0px; ">
    <p>合計距離: <span id="total"></span></p>
  </div>
</div>
<!--ここまでGoogle Maps v3用-->

◆サンプルページ

なかなか楽しい。MarkerClustererで表示させたアイコンが邪魔。クリックするとインフォウィンドウが開いてしまう。適当にアイコンの近くをクリックしてルートを表示させてから、緑色のマーカーを動かせば良いかな?

iPhone用にこのクリックして表示させるのはいいかも。操作性が良さそう。iPhone(アイフォン)画面をタップして、赤色マーカーでドライブルートを検索するなんて使い方が出来そう。iPhone(アイフォン)アプリのGoogle Mapルート(経路)検索では、複数のWaypointを簡単に追加できないし・・・・・うーむ。こっちの方がいい気が・・・・・。次回試してみよう。

ちなみにiPhone上でこのURLhttp://maps.google.co.jp/maps?をクリックするとiPhone(アイフォン)アプリのGoogle Mapルート(経路)検索で東京-大阪間のルート結果が表示されます。

◆Google Maps JavaScript API V3

スポンサードリンク

Related Posts

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <img localsrc="" alt="">