作者常常想如果騎Youbike時,但又不知騎到哪一站時才能停車時,此時此刻如果可以查詢出附近的哪一個Youbike站有停車格是多麼令人感動的事啊! 雖然已經有不少APP已經有類似的功能了,但作者還是想自己動手做。
一、下戴Youbike的串接資料及官方的文件說明
請先下戴有關Youbike的json檔案
因為作者僅是示範教學,如果需要用到官方的即時資訊,是需要事先申請的,還請各位注意,記得把資料的串接改成GET模式
二、引用google Map v3的函式庫
<link href="Content/jquery.mobile-1.4.5.min.css" rel="stylesheet" /> 
<script src="scripts/jquery-2.1.4.min.js"></script> 
<script src="scripts/jquery.mobile-1.4.5.js"></script>   
<script src="scripts/index.js"></script> 
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true&libraries=geometry"></script> 
 | 
 
但沒有提供導航的效果喔~
三、html網頁結構
<div data-role="page"
id="yobikePage"> 
        <div data-role="header"
data-theme="b">        </div> 
        <div data-role="content"
data-theme="b"> 
            <div id="map_canvas"
style="left:0;top:0;width:100%;height:95%;position:absolute;"></div> 
            <a href="#geolocation_destination"
data-rel="close"
id="geolocation_showDialog">Open
dialog</a>            
        </div> 
        <div data-role="footer"
data-id="foo1"
data-position="fixed"
data-theme="b"> 
            <div data-role="navbar"> 
                <ul> 
                    <li><a href="#yobikePage"
class="ui-btn-active
ui-state-persist"><img src="images/youBike.png"
/></a></li> 
                    <li><a href="#navigationPage"><img src="images/natigation.png"
/></a></li> 
                </ul> 
            </div> 
        </div> 
<!-- 顯示點選的Youbike站的相關資訊(站名、住址、經緯度、現有腳踏車數、 
允許停車空位數)  --> 
        <div data-role="panel"
data-position="right"
data-display="overlay"
id="geolocation_destination"
data-theme="b"> 
            <div data-role="header"> 
                <center><span id="markerTitle"></span></center> 
            </div> 
            <div data-role="content"> 
                <h2><b>經緯度:</b></h2> 
                <p><span id="markerLong"></span>  /  
<span id="markerLat"></span></p> 
                <h2><b>住址:</b></h2> 
                <p> 
                    <span id="markerAddr"></span> 
                </p> 
                <h2><b>距離位置</b></h2> 
                <p><span id="markerDistance"></span> 單位: (米/尺)</p> 
                <h2><b>場內車輛數</b></h2> 
                <p><span id="markerSbi"></span> 單位: (台)</p> 
                <h2><b>場內停車數</b></h2> 
                <p><span id="markerBemp"></span> 單位: (位)</p> 
                <a href="#pageone"
id="btnDestination"
data-rel="close"
class="ui-btn
ui-btn-inline ui-shadow ui-corner-all ui-btn-a ui-icon-delete
ui-btn-icon-left">設定目的地</a> 
            </div> 
        </div> 
    </div> 
 <div
data-role="page"
id="navigationPage"> 
        <div data-role="header"
data-theme="b">            
        </div> 
        <div data-role="content"> 
            <ul data-role="listview"
data-filter="true"
id="youBikes"></ul> 
        </div> 
        <div data-role="footer"
data-id="foo1"
data-position="fixed"
data-theme="b"> 
            <div data-role="navbar"> 
                <ul> 
                    <li><a href="#yobikePage"><img src="images/youBike.png"
/></a></li> 
                    <li><a href="#navigationPage"
class="ui-btn-active
ui-state-persist"><img src="images/natigation.png"
/></a></li> 
                </ul> 
            </div> 
        </div>  
    </div> 
</body> 
</html> 
 | 
 
網頁的功能如下所示:
(1) 顯示所有Youbike的所有站名
(2) 在地圖上顯示所有Youbike的位置,Youbike的Marker可以設定終點站,
就能偵測『目前位置』自動導航到『設為終點』的Youbike站
(3) 顯示點選的Youbike站的相關資訊(站名、住址、經緯度、現有腳踏車數、 
允許停車空位數)
四、初始化google map的語法
var map; 
var mapOptions = { 
        zoom: 12, //預設地圖的比例大小 
        center: new google.maps.LatLng(25.051150, 121.566002), 
        mapTypeId:
  google.maps.MapTypeId.ROADMAP 
    } 
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions); 
 | 
 
五、設定加入導航
var directionsService = new google.maps.DirectionsService(); 
//規畫路徑呈現選項 
var rendererOptions = { 
    suppressMarkers: true, 
}; 
directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions); 
directionsDisplay.setMap(map); 
 | 
 
六、取得目前的座標,並將Marker加在地圖上
var options = { 
    enableHighAccuracy: true, 
    timeout: 5000, 
    maximumAge: 0 
}; 
navigator.geolocation.getCurrentPosition(success,
  error, options); 
function success(position) {   
   
   
  setCurrentLocation(position.coords.latitude,
  position.coords.longitude); 
}; 
function error() { 
    alert("取得經緯失敗"); 
}; 
function setCurrentLocation(lat, lon) { 
    currentPosition = new google.maps.LatLng(lat, lon); //設目前位置的座標    
   
  map.setCenter(currentPosition); //以自已位置為地圖中心 
    currentMarker = new google.maps.Marker({ 
        position: currentPosition, 
        map: map, 
        title: '目前位置', 
        icon: "http://maps.google.com/mapfiles/ms/icons/purple-dot.png", 
    });  //將目前位置的座標加入到地圖中 
    //經過經緯度反查目前座標的住址 
    var geocoder = new google.maps.Geocoder(); 
    geocoder.geocode({ 
        'latLng': currentPosition 
    }, function (results, status) { 
        if (status === google.maps.GeocoderStatus.OK) { 
            if (results) { 
                startAddr =
  results[0].formatted_address; 
                var contentString = '目前位置:' + results[0].formatted_address; 
                var infowindow = new google.maps.InfoWindow({ 
                    content:
  contentString 
                }); 
//點選目前位置座標,有文字方塊顯示目前的地址 
               
  google.maps.event.addListener(currentMarker, 'click', function () { 
                   
  infowindow.open(map, currentMarker); 
                }); 
            } 
        } else { 
            alert("Reverse Geocoding failed because: " + status); 
        } 
    }); 
} 
 | 
 
七、取得目前的座標,並將Marker加在地圖上
$.getJSON('scripts/youbike.json', function (data) { 
        var youBikeData = data["retVal"]; 
//逐筆把youbike 的經緯度放在列表和地圖上 
        $.each(youBikeData, function (i, v) { 
            $('#youBikes').append('<li><a href="#"><h2>' + v["sna"] + '</h2><p>' + v["ar"] + '</p><span
  class="ui-li-count">' + v["sbi"] + '</span></a></li>').listview('refresh'); 
            var myLatlng = new google.maps.LatLng(v["lat"], v["lng"]); //youbike站名 
            var intSbi = parseInt(v["sbi"]);//剩下腳踏車數量  
            var color = ""; 
            if (intSbi == 0) 
            { 
                color = "red"; 
            } 
            else if (intSbi > 0 && intSbi <= 5) { 
                color = "yellow"; 
            } else { 
                color = "green"; 
            } 
            setMarket(color, { "title": v["sna"], "addr": v["ar"], "bemp": v["bemp"],"sbi":v["sbi"] }, myLatlng,
  map); 
        }); 
    }); 
function setMarket(color, title, myLatlng, map) { 
    var strMakerLink = ""; 
    switch (color) { 
        case "red": 
            strMakerLink = 'http://maps.google.com/mapfiles/ms/icons/red-dot.png'; 
            break; 
        case "blue": 
            strMakerLink = 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png'; 
            break; 
        case "yellow": 
            strMakerLink = 'http://maps.google.com/mapfiles/ms/icons/yellow-dot.png'; 
            break; 
        case "purple": 
            strMakerLink = 'http://maps.google.com/mapfiles/ms/icons/purple-dot.png'; 
            break; 
        case "green": 
            strMakerLink = 'http://maps.google.com/mapfiles/ms/icons/green-dot.png'; 
            break; 
        default: 
            strMakerLink = 'http://maps.google.com/mapfiles/ms/icons/red-dot.png'; 
            break; 
    } 
    //建立地圖google座標 
    var marker = new google.maps.Marker({ 
        position: myLatlng, 
        title: title.title, 
        icon: strMakerLink, 
    }) 
    //google座標放進地圖 
    marker.setMap(map); 
    google.maps.event.addListener(marker,
  'click', function () { 
        var myLatLng = this.position;         
        $("#markerTitle").text(this.title); 
        $("#markerLat").text(myLatLng.A); 
        $("#markerLong").text(myLatLng.F); 
        destinationPosition =
  myLatLng; 
        destionAddr = title.addr; 
        $("#markerAddr").text(destionAddr); 
//估算『目前位置』和『終點』的距離 
        var meters =
  google.maps.geometry.spherical.computeDistanceBetween(currentMarker.getPosition(),
  marker.getPosition()); 
        $("#markerDistance").text(meters); 
        $("#markerSbi").text(title.sbi); 
        $("#markerBemp").text(title.bemp); 
        $("#geolocation_showDialog").click(); //點選座標後,跳出 panel 視窗 
        return false; 
    }); 
} 
 | 
 
示範畫面:
| 
 | 
  
 | 
八、設定Youbke的站為終點站
//點選設定終點的按鈕 
$("#btnDestination").click(function () { 
     calcRoute(currentPosition,
  destinationPosition); 
}); 
//從起點到終點的導航路徑 
function calcRoute(startPoint, endPoint) {     
    var request = { 
        origin: startPoint,   //可輸入住址名稱或Google座標 
        destination: endPoint, 
        travelMode:
  google.maps.TravelMode.DRIVING 
    }; 
   
  directionsService.route(request, function (response, status) { 
        if (status == google.maps.DirectionsStatus.OK) { 
           
  directionsDisplay.setDirections(response); 
        } 
    }); 
} 
 | 
 
示範: 
點選Youbike的marker後,出現panel
畫面,點選『設定為目的地』,就會從目前位置導航路徑到『設為目的地』的站   
全部的範例程式
var map; //地圖 
var currentPosition; //取得目前的位置 
var destinationPosition; //設定目的地 
var directionsService;//導航 
var startAddr; //起始點 
var destionAddr; //結束點 
var currentMarker;//取得起點座標 
function setCurrentLocation(lat, lon) { 
    currentPosition = new google.maps.LatLng(lat, lon);     
   
  map.setCenter(currentPosition); 
    currentMarker = new google.maps.Marker({ 
        position: currentPosition, 
        map: map, 
        title: '目前位置', 
        icon: "http://maps.google.com/mapfiles/ms/icons/purple-dot.png", 
    });  
    //經過經緯度反查住址 
    var geocoder = new google.maps.Geocoder(); 
    geocoder.geocode({ 
        'latLng': currentPosition 
    }, function (results, status) { 
        if (status === google.maps.GeocoderStatus.OK) { 
            if (results) { 
                startAddr =
  results[0].formatted_address; 
                var contentString = '目前位置:' + results[0].formatted_address; 
                var infowindow = new google.maps.InfoWindow({ 
                    content:
  contentString 
                }); 
               
  google.maps.event.addListener(currentMarker, 'click', function () { 
                   
  infowindow.open(map, currentMarker); 
                }); 
            } 
        } else { 
            alert("Reverse Geocoding failed because: " + status); 
        } 
    }); 
} 
function success(position) {   
   
    setCurrentLocation(position.coords.latitude,
  position.coords.longitude); 
}; 
function error() { 
    alert("取得經緯失敗"); 
}; 
function setMarket(color, title, myLatlng, map) { 
    var strMakerLink = ""; 
    switch (color) { 
        case "red": 
            strMakerLink = 'http://maps.google.com/mapfiles/ms/icons/red-dot.png'; 
            break; 
        case "blue": 
            strMakerLink = 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png'; 
            break; 
        case "yellow": 
            strMakerLink = 'http://maps.google.com/mapfiles/ms/icons/yellow-dot.png'; 
            break; 
        case "purple": 
            strMakerLink = 'http://maps.google.com/mapfiles/ms/icons/purple-dot.png'; 
            break; 
        case "green": 
            strMakerLink = 'http://maps.google.com/mapfiles/ms/icons/green-dot.png'; 
            break; 
        default: 
            strMakerLink = 'http://maps.google.com/mapfiles/ms/icons/red-dot.png'; 
            break; 
    } 
    //建立地圖google座標 
    var marker = new google.maps.Marker({ 
        position: myLatlng, 
        title: title.title, 
        icon: strMakerLink, 
    }) 
    //google座標放進地圖 
    marker.setMap(map); 
   
  google.maps.event.addListener(marker, 'click', function () { 
        var myLatLng = this.position;         
        $("#markerTitle").text(this.title); 
        $("#markerLat").text(myLatLng.A); 
        $("#markerLong").text(myLatLng.F); 
        destinationPosition =
  myLatLng; 
        destionAddr = title.addr; 
        $("#markerAddr").text(destionAddr); 
        var meters =
  google.maps.geometry.spherical.computeDistanceBetween(currentMarker.getPosition(),
  marker.getPosition()); 
        $("#markerDistance").text(meters); 
        $("#markerSbi").text(title.sbi); 
        $("#markerBemp").text(title.bemp); 
        $("#geolocation_showDialog").click(); //點選座標後,跳出視窗 
        return false; 
    }); 
} 
function setPath(map) {   
   
    directionsService = new google.maps.DirectionsService(); 
    //規畫路徑呈現選項 
    var rendererOptions = { 
        suppressMarkers: true, 
    }; 
    directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions); 
    directionsDisplay.setMap(map); 
} 
function calcRoute(startPoint, endPoint) {     
    var request = { 
        origin: startPoint, 
        destination: endPoint, 
        travelMode:
  google.maps.TravelMode.DRIVING 
    }; 
   
  directionsService.route(request, function (response, status) { 
        if (status == google.maps.DirectionsStatus.OK) { 
           
  directionsDisplay.setDirections(response); 
        } 
    }); 
} 
$(document).ready(function () { 
    var mapOptions = { 
        zoom: 12, 
        center: new google.maps.LatLng(25.051150, 121.566002), 
        mapTypeId:
  google.maps.MapTypeId.ROADMAP 
    } 
    map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions); 
    var options = { 
        enableHighAccuracy: true, 
        timeout: 5000, 
        maximumAge: 0 
    };     
    setPath(map); 
   
  navigator.geolocation.getCurrentPosition(success, error, options); 
    $.getJSON('scripts/youbike.json', function (data) { 
        //逐筆加入youbike 站 
        var youBikeData = data["retVal"]; 
        $.each(youBikeData, function (i, v) { 
            $('#youBikes').append('<li><a href="#"><h2>' + v["sna"] + '</h2><p>' + v["ar"] + '</p><span
  class="ui-li-count">' + v["sbi"] + '</span></a></li>').listview('refresh'); 
            var myLatlng = new google.maps.LatLng(v["lat"], v["lng"]); //youbike經緯度 
            var intSbi = parseInt(v["sbi"]);//剩下腳踏車數量  
            var color = ""; 
            if (intSbi == 0) 
            { 
                color = "red"; 
            } 
            else if (intSbi > 0 && intSbi <= 5) { 
                color = "yellow"; 
            } else { 
                color = "green"; 
            } 
//可以用JSON格式,將多重值傳遞的方式 
            setMarket(color, { "title": v["sna"], "addr": v["ar"], "bemp": v["bemp"],"sbi":v["sbi"] }, myLatlng,
  map); 
        }); 
    }); 
    $("#btnDestination").click(function () { 
        calcRoute(currentPosition,
  destinationPosition); 
    }); 
}); 
 | 
 
九、參考文獻
疑難雜症:
如果各位在phoneGap 中嵌入google Map 是否會遇到總是空白,無法正確地圖顯示,原來是jQueryMobile 的預設onLoad 的事件只是觸發在第一個Page上,所以放置地圖頁面要放在最上面。




沒有留言:
張貼留言