Copyright Derek O'Reilly, Dundalk Institute of Technology (DkIT), Dundalk, Co. Louth, Ireland.
It is possible to get the current location of a mobile device. This can be used with GoogleMaps to provide localised mapping apps.
PhoneGap has a Geolocation plugin, which can be used to obtain the latitude and longitude of the current location.
config.xml
<widget xmlns="http://cordova.apache.org/ns/1.0"
version="1.0.0"
id="ie.dkit.derek_e120" > <name>e120</name> <description>Demo with Geolocation</description> <author email="derek.oreilly@dkit.ie" href="https://derek.comp.dkit.ie">Derek O Reilly</author> <platform name="ios"> <icon src="res/icons/ios/icon-1024.png" width="1024" height="1024"/> <icon src="res/icons/ios/icon-small.png" width="29" height="29"/> <icon src="res/icons/ios/icon-small@2x.png" width="58" height="58"/> <icon src="res/icons/ios/icon-small@3x.png" width="87" height="87"/> <icon src="res/icons/ios/icon-small-40.png" width="40" height="40"/> <icon src="res/icons/ios/icon-small-40@2x.png" width="80" height="80"/> <icon src="res/icons/ios/icon-small-40@3x.png" width="120" height="120"/> <icon src="res/icons/ios/icon-small-50.png" width="50" height="50"/> <icon src="res/icons/ios/icon-small-50@2x.png" width="100" height="100"/> <icon src="res/icons/ios/icon.png" width="57" height="57"/> <icon src="res/icons/ios/icon@2x.png" width="114" height="114"/> <icon src="res/icons/ios/icon-60.png" width="60" height="60"/> <icon src="res/icons/ios/icon-60@2x.png" width="120" height="120"/> <icon src="res/icons/ios/icon-60@3x.png" width="180" height="180"/> <icon src="res/icons/ios/icon-72.png" width="72" height="72"/> <icon src="res/icons/ios/icon-72@2x.png" width="144" height="144"/> <icon src="res/icons/ios/icon-76.png" width="76" height="76"/> <icon src="res/icons/ios/icon-76@2x.png" width="152" height="152"/> <icon src="res/icons/ios/icon-167.png" width="167" height="167"/> <icon src="res/icons/ios/icon-83.5@2x.png" width="167" height="167"/> <splash src="res/screens/ios/Default~iphone.png" width="320" height="480"/> <splash src="res/screens/ios/Default@2x~iphone.png" width="640" height="960"/> <splash src="res/screens/ios/Default-Portrait~ipad.png" width="768" height="1024"/> <splash src="res/screens/ios/Default-Portrait@2x~ipad.png" width="1536" height="2048"/> <splash src="res/screens/ios/Default-568h@2x~iphone.png" width="640" height="1136"/> <splash src="res/screens/ios/Default-667h.png" width="750" height="1334"/> <splash src="res/screens/ios/Default-736h.png" width="1242" height="2208"/> </platform> <platform name="android"> <icon density="ldpi" src="res/icons/android/ldpi.png"/> <icon density="mdpi" src="res/icons/android/mdpi.png"/> <icon density="hdpi" src="res/icons/android/hdpi.png"/> <icon density="xhdpi" src="res/icons/android/xhdpi.png"/> <icon density="xxhdpi" src="res/icons/android/xxhdpi.png"/> <icon density="xxxhdpi" src="res/icons/android/xxxhdpi.png"/> <splash density="port-ldpi" src="res/screens/android/splash-port-ldpi.png"/> <splash density="port-mdpi" src="res/screens/android/splash-port-mdpi.png"/> <splash density="port-hdpi" src="res/screens/android/splash-port-hdpi.png"/> <splash density="port-xhdpi" src="res/screens/android/splash-port-xhdpi.png"/> <splash density="port-xxhdpi" src="res/screens/android/splash-port-xxhdpi.png"/> <splash density="port-xxxhdpi" src="res/screens/android/splash-port-xxxhdpi.png"/> </platform> <platform name="windows"> <icon src="res/icons/windows/storelogo.png" target="StoreLogo" /> <icon src="res/icons/windows/smalllogo.png" target="Square30x30Logo" /> <icon src="res/icons/windows/Square44x44Logo.png" target="Square44x44Logo" /> <icon src="res/icons/windows/Square70x70Logo.png" target="Square70x70Logo" /> <icon src="res/icons/windows/Square71x71Logo.png" target="Square71x71Logo" /> <icon src="res/icons/windows/Square150x150Logo.png" target="Square150x150Logo" /> <icon src="res/icons/windows/Square310x310Logo.png" target="Square310x310Logo" /> <splash src="res/screens/windows/splashscreen.png" target="SplashScreen"/> <splash src="res/screens/windows/splashscreenphone.png" target="SplashScreenPhone"/> </platform> <preference name="DisallowOverscroll" value="true" /> <!-- ios: stop overscroll/bounce --> <preference name="orientation" value="portrait" /> <!-- all: default means both landscape and portrait are enabled --> <preference name="fullscreen" value="true" /> <!-- all: hides the status bar at the top of the screen --> <preference name="exit-on-suspend" value="true" /> <!-- ios: if set to true, app will terminate when home button is pressed --> <config-file platform="ios" parent="UIViewControllerBasedStatusBarAppearance" overwrite="true"> <false/> <!-- true = show status bar, false = hide status bar --> </config-file> <plugin name="cordova-plugin-geolocation" spec="~2.4.3" /> <!-- Allow access various files that relate to the GoogleMaps API --> <access origin="*" /> </widget>
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1, width=device-width, height=device-height, viewport-fit=cover">
<title>Geolocation Demo</title>
<!-- This is needed to access the PhoneGap JavaScript -->
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script>
window.onload = onAllAssetsLoaded;
document.write("<div id='loadingMessage'>Loading...</div>");
function onAllAssetsLoaded()
{
// Wait for Cordova to connect with the device
document.addEventListener("deviceready", onDeviceReady, false);
}
// Cordova is ready to be used!
function onDeviceReady()
{
// note, it takes a few seconds for the gps to work, so you need to give a high timeout value
let options = {maximumAge: 1000, timeout: 50000, enableHighAccuracy: true};
navigator.geolocation.getCurrentPosition(onGeolocationSuccess, onGeolocationError, options);
}
function onGeolocationSuccess(position)
{
document.getElementById('geolocationDetails').innerHTML = 'Latitude: ' + position.coords.latitude + '<br>' +
'Longitude: ' + position.coords.longitude + '<br>' +
'Altitude: ' + position.coords.altitude;
}
function onGeolocationError(error)
{
document.getElementById('geolocationDetails').innerHTML = 'code: ' + error.code + '<br>' +
'message: ' + error.message + '<br>';
}
</script>
</head>
<body>
<h1>Geolocation Demo</h1>
<p id="geolocationDetails">Finding geolocation...</p>
</body>
</html>
<widget xmlns="http://cordova.apache.org/ns/1.0"
version="1.0.0"
id="ie.dkit.derek_e121" > <name>e121</name> <description>Demo with Geolocation Map of Current Location</description> <author email="derek.oreilly@dkit.ie" href="https://derek.comp.dkit.ie">Derek O Reilly</author> <platform name="ios"> <icon src="res/icons/ios/icon-1024.png" width="1024" height="1024"/> <icon src="res/icons/ios/icon-small.png" width="29" height="29"/> <icon src="res/icons/ios/icon-small@2x.png" width="58" height="58"/> <icon src="res/icons/ios/icon-small@3x.png" width="87" height="87"/> <icon src="res/icons/ios/icon-small-40.png" width="40" height="40"/> <icon src="res/icons/ios/icon-small-40@2x.png" width="80" height="80"/> <icon src="res/icons/ios/icon-small-40@3x.png" width="120" height="120"/> <icon src="res/icons/ios/icon-small-50.png" width="50" height="50"/> <icon src="res/icons/ios/icon-small-50@2x.png" width="100" height="100"/> <icon src="res/icons/ios/icon.png" width="57" height="57"/> <icon src="res/icons/ios/icon@2x.png" width="114" height="114"/> <icon src="res/icons/ios/icon-60.png" width="60" height="60"/> <icon src="res/icons/ios/icon-60@2x.png" width="120" height="120"/> <icon src="res/icons/ios/icon-60@3x.png" width="180" height="180"/> <icon src="res/icons/ios/icon-72.png" width="72" height="72"/> <icon src="res/icons/ios/icon-72@2x.png" width="144" height="144"/> <icon src="res/icons/ios/icon-76.png" width="76" height="76"/> <icon src="res/icons/ios/icon-76@2x.png" width="152" height="152"/> <icon src="res/icons/ios/icon-167.png" width="167" height="167"/> <icon src="res/icons/ios/icon-83.5@2x.png" width="167" height="167"/> <splash src="res/screens/ios/Default~iphone.png" width="320" height="480"/> <splash src="res/screens/ios/Default@2x~iphone.png" width="640" height="960"/> <splash src="res/screens/ios/Default-Portrait~ipad.png" width="768" height="1024"/> <splash src="res/screens/ios/Default-Portrait@2x~ipad.png" width="1536" height="2048"/> <splash src="res/screens/ios/Default-568h@2x~iphone.png" width="640" height="1136"/> <splash src="res/screens/ios/Default-667h.png" width="750" height="1334"/> <splash src="res/screens/ios/Default-736h.png" width="1242" height="2208"/> </platform> <platform name="android"> <icon density="ldpi" src="res/icons/android/ldpi.png"/> <icon density="mdpi" src="res/icons/android/mdpi.png"/> <icon density="hdpi" src="res/icons/android/hdpi.png"/> <icon density="xhdpi" src="res/icons/android/xhdpi.png"/> <icon density="xxhdpi" src="res/icons/android/xxhdpi.png"/> <icon density="xxxhdpi" src="res/icons/android/xxxhdpi.png"/> <splash density="port-ldpi" src="res/screens/android/splash-port-ldpi.png"/> <splash density="port-mdpi" src="res/screens/android/splash-port-mdpi.png"/> <splash density="port-hdpi" src="res/screens/android/splash-port-hdpi.png"/> <splash density="port-xhdpi" src="res/screens/android/splash-port-xhdpi.png"/> <splash density="port-xxhdpi" src="res/screens/android/splash-port-xxhdpi.png"/> <splash density="port-xxxhdpi" src="res/screens/android/splash-port-xxxhdpi.png"/> </platform> <platform name="windows"> <icon src="res/icons/windows/storelogo.png" target="StoreLogo" /> <icon src="res/icons/windows/smalllogo.png" target="Square30x30Logo" /> <icon src="res/icons/windows/Square44x44Logo.png" target="Square44x44Logo" /> <icon src="res/icons/windows/Square70x70Logo.png" target="Square70x70Logo" /> <icon src="res/icons/windows/Square71x71Logo.png" target="Square71x71Logo" /> <icon src="res/icons/windows/Square150x150Logo.png" target="Square150x150Logo" /> <icon src="res/icons/windows/Square310x310Logo.png" target="Square310x310Logo" /> <splash src="res/screens/windows/splashscreen.png" target="SplashScreen"/> <splash src="res/screens/windows/splashscreenphone.png" target="SplashScreenPhone"/> </platform> <preference name="DisallowOverscroll" value="true" /> <!-- ios: stop overscroll/bounce --> <preference name="orientation" value="portrait" /> <!-- all: default means both landscape and portrait are enabled --> <preference name="fullscreen" value="true" /> <!-- all: hides the status bar at the top of the screen --> <preference name="exit-on-suspend" value="true" /> <!-- ios: if set to true, app will terminate when home button is pressed --> <config-file platform="ios" parent="UIViewControllerBasedStatusBarAppearance" overwrite="true"> <false/> <!-- true = show status bar, false = hide status bar --> </config-file> <plugin name="cordova-plugin-geolocation" spec="~2.4.3" /> <!-- Allow access various files that relate to the GoogleMaps API --> <access origin="*" /> </widget>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="initial-scale=1, width=device-width, height=device-height, viewport-fit=cover"> <title>Geolocation Demo</title> <style> * { -webkit-touch-callout: none; /* Disable element selection in app */ -webkit-user-select: none; /* Disable text selection in app */ } html, body, #geolocationDetails { width:100%; height:100%; margin:0px; padding:0px; } h3, p { margin:5px; } #mapType { position:absolute; bottom:10px; right:10px; visibility:hidden; } </style> <!-- This is needed to access the PhoneGap JavaScript --> <script type="text/javascript" charset="utf-8" src="cordova.js"></script> <!-- Google Maps --> <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script> <script> let currentLocationMap; window.onload = onAllAssetsLoaded; document.write("<div id='loadingMessage'>Loading...</div>"); function onAllAssetsLoaded() { // Wait for Cordova to connect with the device document.addEventListener("deviceready", onDeviceReady, false); } // Cordova is ready to be used! function onDeviceReady() { // note, it takes a few seconds for the gps to work, so you need to give a high timeout value let options = {maximumAge: 1000, timeout: 50000, enableHighAccuracy: true}; navigator.geolocation.getCurrentPosition(onGeolocationSuccess, onGeolocationError, options); } function onGeolocationSuccess(position) { // Make the map type button visible, so that the user can change the map type document.getElementById('mapType').style.visibility = 'visible'; let latitude = position.coords.latitude; let longitude = position.coords.longitude; let mapOptions = {zoom: 15, center: new google.maps.LatLng(latitude, longitude), mapTypeId: google.maps.MapTypeId.ROADMAP}; currentLocationMap = new google.maps.Map(document.getElementById('geolocationDetails'), mapOptions); let currentLocation = ['You are here!', latitude, longitude, 1]; let locationMarker; let mapWindow = new google.maps.InfoWindow(); locationMarker = new google.maps.Marker({position: new google.maps.LatLng(currentLocation[1], currentLocation[2]), map: currentLocationMap}); let locationMarkerNumber = 0; google.maps.event.addListener(locationMarker, 'click', (function (locationMarker, locationMarkerNumber) { return function () { mapWindow.setContent(currentLocation[0]); mapWindow.open(currentLocationMap, locationMarker); } })(locationMarker, locationMarkerNumber)); } function onGeolocationError(error) { document.getElementById('geolocationDetails').innerHTML = 'code: ' + error.code + '<br>' + 'message: ' + error.message + '<br>'; } function toggleMapType() { if (document.getElementById('mapType').innerHTML == 'Change Map To Hybrid') { currentLocationMap.setMapTypeId(google.maps.MapTypeId.HYBRID); document.getElementById('mapType').innerHTML = 'Change Map To Road'; } else { currentLocationMap.setMapTypeId(google.maps.MapTypeId.ROADMAP); document.getElementById('mapType').innerHTML = 'Change Map To Hybrid' } } </script> </head> <body> <div id="geolocationDetails"> <h3>Current Location Map Demo</h3> <p>loading...</p><p>It can take several seconds for the map to load. Please be patient.</p> </div> <button id = 'mapType' onclick = 'toggleMapType()'>Change Map To Hybrid</button> </body> </html>
<widget xmlns="http://cordova.apache.org/ns/1.0"
version="1.0.0"
id="ie.dkit.derek_e122" > <name>e122</name> <description>Demo with Route Finder</description> <author email="derek.oreilly@dkit.ie" href="https://derek.comp.dkit.ie">Derek O Reilly</author> <platform name="ios"> <icon src="res/icons/ios/icon-1024.png" width="1024" height="1024"/> <icon src="res/icons/ios/icon-small.png" width="29" height="29"/> <icon src="res/icons/ios/icon-small@2x.png" width="58" height="58"/> <icon src="res/icons/ios/icon-small@3x.png" width="87" height="87"/> <icon src="res/icons/ios/icon-small-40.png" width="40" height="40"/> <icon src="res/icons/ios/icon-small-40@2x.png" width="80" height="80"/> <icon src="res/icons/ios/icon-small-40@3x.png" width="120" height="120"/> <icon src="res/icons/ios/icon-small-50.png" width="50" height="50"/> <icon src="res/icons/ios/icon-small-50@2x.png" width="100" height="100"/> <icon src="res/icons/ios/icon.png" width="57" height="57"/> <icon src="res/icons/ios/icon@2x.png" width="114" height="114"/> <icon src="res/icons/ios/icon-60.png" width="60" height="60"/> <icon src="res/icons/ios/icon-60@2x.png" width="120" height="120"/> <icon src="res/icons/ios/icon-60@3x.png" width="180" height="180"/> <icon src="res/icons/ios/icon-72.png" width="72" height="72"/> <icon src="res/icons/ios/icon-72@2x.png" width="144" height="144"/> <icon src="res/icons/ios/icon-76.png" width="76" height="76"/> <icon src="res/icons/ios/icon-76@2x.png" width="152" height="152"/> <icon src="res/icons/ios/icon-167.png" width="167" height="167"/> <icon src="res/icons/ios/icon-83.5@2x.png" width="167" height="167"/> <splash src="res/screens/ios/Default~iphone.png" width="320" height="480"/> <splash src="res/screens/ios/Default@2x~iphone.png" width="640" height="960"/> <splash src="res/screens/ios/Default-Portrait~ipad.png" width="768" height="1024"/> <splash src="res/screens/ios/Default-Portrait@2x~ipad.png" width="1536" height="2048"/> <splash src="res/screens/ios/Default-568h@2x~iphone.png" width="640" height="1136"/> <splash src="res/screens/ios/Default-667h.png" width="750" height="1334"/> <splash src="res/screens/ios/Default-736h.png" width="1242" height="2208"/> </platform> <platform name="android"> <icon density="ldpi" src="res/icons/android/ldpi.png"/> <icon density="mdpi" src="res/icons/android/mdpi.png"/> <icon density="hdpi" src="res/icons/android/hdpi.png"/> <icon density="xhdpi" src="res/icons/android/xhdpi.png"/> <icon density="xxhdpi" src="res/icons/android/xxhdpi.png"/> <icon density="xxxhdpi" src="res/icons/android/xxxhdpi.png"/> <splash density="port-ldpi" src="res/screens/android/splash-port-ldpi.png"/> <splash density="port-mdpi" src="res/screens/android/splash-port-mdpi.png"/> <splash density="port-hdpi" src="res/screens/android/splash-port-hdpi.png"/> <splash density="port-xhdpi" src="res/screens/android/splash-port-xhdpi.png"/> <splash density="port-xxhdpi" src="res/screens/android/splash-port-xxhdpi.png"/> <splash density="port-xxxhdpi" src="res/screens/android/splash-port-xxxhdpi.png"/> </platform> <platform name="windows"> <icon src="res/icons/windows/storelogo.png" target="StoreLogo" /> <icon src="res/icons/windows/smalllogo.png" target="Square30x30Logo" /> <icon src="res/icons/windows/Square44x44Logo.png" target="Square44x44Logo" /> <icon src="res/icons/windows/Square70x70Logo.png" target="Square70x70Logo" /> <icon src="res/icons/windows/Square71x71Logo.png" target="Square71x71Logo" /> <icon src="res/icons/windows/Square150x150Logo.png" target="Square150x150Logo" /> <icon src="res/icons/windows/Square310x310Logo.png" target="Square310x310Logo" /> <splash src="res/screens/windows/splashscreen.png" target="SplashScreen"/> <splash src="res/screens/windows/splashscreenphone.png" target="SplashScreenPhone"/> </platform> <preference name="DisallowOverscroll" value="true" /> <!-- ios: stop overscroll/bounce --> <preference name="orientation" value="portrait" /> <!-- all: default means both landscape and portrait are enabled --> <preference name="fullscreen" value="true" /> <!-- all: hides the status bar at the top of the screen --> <preference name="exit-on-suspend" value="true" /> <!-- ios: if set to true, app will terminate when home button is pressed --> <config-file platform="ios" parent="UIViewControllerBasedStatusBarAppearance" overwrite="true"> <false/> <!-- true = show status bar, false = hide status bar --> </config-file> <plugin name="cordova-plugin-geolocation" spec="~2.4.3" /> <!-- Allow access various files that relate to the GoogleMaps API --> <access origin="*" /> </widget>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="initial-scale=1, width=device-width, height=device-height, viewport-fit=cover"> <title>Route Finder Demo</title> <style> * { -webkit-touch-callout: none; /* Disable element selection in app */ -webkit-user-select: none; /* Disable text selection in app */ } html, body, #geolocationDetails { width:100%; height: 100%; margin: 0px; padding: 0px } #controlPanel { position: absolute; top: 10px; left: 10px; z-index: 2; background-color: #fff; padding: 5px; border: 1px solid #999; visibility:hidden; } h3, p { margin:5px; } </style> <!-- This is needed to access the PhoneGap JavaScript --> <script type="text/javascript" charset="utf-8" src="cordova.js"></script> <!-- Google Maps --> <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script> <script> let currentLocationMap; let directionsDisplay; let directionsService = new google.maps.DirectionsService(); let currentLocationMap; let latitude; let longitude; window.onload = onAllAssetsLoaded; document.write("<div id='loadingMessage'>Loading...</div>"); function onAllAssetsLoaded() { // Wait for Cordova to connect with the device document.addEventListener("deviceready", onDeviceReady, false); } // Cordova is ready to be used! function onDeviceReady() { // note, it takes a few seconds for the gps to work, so you need to give a high timeout value let options = {maximumAge: 1000, timeout: 50000, enableHighAccuracy: true}; navigator.geolocation.getCurrentPosition(onGeolocationSuccess, onGeolocationError, options); } function onGeolocationSuccess(position) { latitude = position.coords.latitude; longitude = position.coords.longitude; // set the value for the Current Location selection document.getElementById('currentLocationOption').value = latitude.toString() + "," + longitude.toString(); // Show the controlPanel document.getElementById('controlPanel').style.visibility = 'visible'; // route planner directionsDisplay = new google.maps.DirectionsRenderer(); let currentLocationMap = new google.maps.LatLng(latitude, longitude); let mapOptions = {zoom: 10, center: currentLocationMap}; currentLocationMap = new google.maps.Map(document.getElementById('geolocationDetails'), mapOptions); // assign the directionsDisplay to the map directionsDisplay.setMap(currentLocationMap); calculateRoute(); // calculate initial route from current location to DkIT } function onGeolocationError(error) { document.getElementById('geolocationDetails').innerHTML = 'code: ' + error.code + '<br>' + 'message: ' + error.message + '<br>'; } function calculateRoute() { let start = document.getElementById('start').value; let end = document.getElementById('end').value; let request = {origin: start, destination: end, travelMode: google.maps.TravelMode.DRIVING}; directionsService.route(request, function (response, status) { if (status == google.maps.DirectionsStatus.OK) { directionsDisplay.setDirections(response); } }); } </script> </head> <body> <div id="controlPanel"> <b>Start: </b> <select id="start" onchange="calculateRoute();"> <option id = 'currentLocationOption'>Current Location</option> <!-- Current Location value can only be set after the location is known --> <option value="Dundalk Institute of Technology Louth Ireland">DkIT</option> <option value="Dublin City University Collins Avenue Extension Whitehall Dublin 9">DCU</option> <option value="Maynooth University Ireland">Maynooth</option> </select> <br><b>End: </b> <select id="end" onchange="calculateRoute();"> <option value="Dundalk Institute of Technology Louth Ireland">DkIT</option> <option value="Dublin City University Collins Avenue Extension Whitehall Dublin 9">DCU</option> <option value="Maynooth University Ireland">Maynooth</option> </select> </div> <div id="geolocationDetails"> <h3>Route Finder Demo</h3> <p>loading...</p><p>It can take several seconds for the map to load. Please be patient.</p> </div> </body> </html>
Adjust the above code to include the route's text directions, as shown here (this app is called e123).
The compass plugin retrieves the magnetic bearinctx. In order to use the compas plugin, you need to include the code below in the config.xml
<gap:plugin name="orctx.apache.cordova.device-orientation" />
<widget xmlns="http://cordova.apache.org/ns/1.0"
version="1.0.0"
id="ie.dkit.derek_e124" > <name>e124</name> <description>Demo showing a phones compass mangetic heading</description> <author email="derek.oreilly@dkit.ie" href="https://derek.comp.dkit.ie">Derek O Reilly</author> <platform name="ios"> <icon src="res/icons/ios/icon-1024.png" width="1024" height="1024"/> <icon src="res/icons/ios/icon-small.png" width="29" height="29"/> <icon src="res/icons/ios/icon-small@2x.png" width="58" height="58"/> <icon src="res/icons/ios/icon-small@3x.png" width="87" height="87"/> <icon src="res/icons/ios/icon-small-40.png" width="40" height="40"/> <icon src="res/icons/ios/icon-small-40@2x.png" width="80" height="80"/> <icon src="res/icons/ios/icon-small-40@3x.png" width="120" height="120"/> <icon src="res/icons/ios/icon-small-50.png" width="50" height="50"/> <icon src="res/icons/ios/icon-small-50@2x.png" width="100" height="100"/> <icon src="res/icons/ios/icon.png" width="57" height="57"/> <icon src="res/icons/ios/icon@2x.png" width="114" height="114"/> <icon src="res/icons/ios/icon-60.png" width="60" height="60"/> <icon src="res/icons/ios/icon-60@2x.png" width="120" height="120"/> <icon src="res/icons/ios/icon-60@3x.png" width="180" height="180"/> <icon src="res/icons/ios/icon-72.png" width="72" height="72"/> <icon src="res/icons/ios/icon-72@2x.png" width="144" height="144"/> <icon src="res/icons/ios/icon-76.png" width="76" height="76"/> <icon src="res/icons/ios/icon-76@2x.png" width="152" height="152"/> <icon src="res/icons/ios/icon-167.png" width="167" height="167"/> <icon src="res/icons/ios/icon-83.5@2x.png" width="167" height="167"/> <splash src="res/screens/ios/Default~iphone.png" width="320" height="480"/> <splash src="res/screens/ios/Default@2x~iphone.png" width="640" height="960"/> <splash src="res/screens/ios/Default-Portrait~ipad.png" width="768" height="1024"/> <splash src="res/screens/ios/Default-Portrait@2x~ipad.png" width="1536" height="2048"/> <splash src="res/screens/ios/Default-568h@2x~iphone.png" width="640" height="1136"/> <splash src="res/screens/ios/Default-667h.png" width="750" height="1334"/> <splash src="res/screens/ios/Default-736h.png" width="1242" height="2208"/> </platform> <platform name="android"> <icon density="ldpi" src="res/icons/android/ldpi.png"/> <icon density="mdpi" src="res/icons/android/mdpi.png"/> <icon density="hdpi" src="res/icons/android/hdpi.png"/> <icon density="xhdpi" src="res/icons/android/xhdpi.png"/> <icon density="xxhdpi" src="res/icons/android/xxhdpi.png"/> <icon density="xxxhdpi" src="res/icons/android/xxxhdpi.png"/> <splash density="port-ldpi" src="res/screens/android/splash-port-ldpi.png"/> <splash density="port-mdpi" src="res/screens/android/splash-port-mdpi.png"/> <splash density="port-hdpi" src="res/screens/android/splash-port-hdpi.png"/> <splash density="port-xhdpi" src="res/screens/android/splash-port-xhdpi.png"/> <splash density="port-xxhdpi" src="res/screens/android/splash-port-xxhdpi.png"/> <splash density="port-xxxhdpi" src="res/screens/android/splash-port-xxxhdpi.png"/> </platform> <platform name="windows"> <icon src="res/icons/windows/storelogo.png" target="StoreLogo" /> <icon src="res/icons/windows/smalllogo.png" target="Square30x30Logo" /> <icon src="res/icons/windows/Square44x44Logo.png" target="Square44x44Logo" /> <icon src="res/icons/windows/Square70x70Logo.png" target="Square70x70Logo" /> <icon src="res/icons/windows/Square71x71Logo.png" target="Square71x71Logo" /> <icon src="res/icons/windows/Square150x150Logo.png" target="Square150x150Logo" /> <icon src="res/icons/windows/Square310x310Logo.png" target="Square310x310Logo" /> <splash src="res/screens/windows/splashscreen.png" target="SplashScreen"/> <splash src="res/screens/windows/splashscreenphone.png" target="SplashScreenPhone"/> </platform> <preference name="DisallowOverscroll" value="true" /> <!-- ios: stop overscroll/bounce --> <preference name="orientation" value="portrait" /> <!-- all: default means both landscape and portrait are enabled --> <preference name="fullscreen" value="true" /> <!-- all: hides the status bar at the top of the screen --> <preference name="exit-on-suspend" value="true" /> <!-- ios: if set to true, app will terminate when home button is pressed --> <config-file platform="ios" parent="UIViewControllerBasedStatusBarAppearance" overwrite="true"> <false/> <!-- true = show status bar, false = hide status bar --> </config-file> <!-- Compass --> <plugin name="cordova-plugin-device-orientation" /> </widget>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="initial-scale=1, width=device-width, height=device-height, viewport-fit=cover"> <!-- This is needed to access the PhoneGap JavaScript --> <script type="text/javascript" charset="utf-8" src="cordova.js"></script> <title>Worked example from lecture notes</title> <style> *{ -webkit-touch-callout: none; -webkit-user-select: none; /* Disable selection/copy in UIWebView */ } body { padding:0px; margin:0px; } p { margin-left:5px; } #loadingMessage { position:fixed; top:100px; left:100px; z-index:100; font-size:50px; } </style> <script> let compassWatchID = null; window.onload = onAllAssetsLoaded; document.write("<div id='loadingMessage'>Loading...</div>"); function onAllAssetsLoaded() { // Wait for Cordova to connect with the device document.addEventListener("deviceready", onDeviceReady, false); } // Cordova is ready to be used! function onDeviceReady() { // hide the webpage loading message document.getElementById('loadingMessage').style.visibility = "hidden"; startCompassWatch(); } function startCompassWatch() { // Update compass every 1 second let options = {frequency: 100}; compassWatchID = navigator.compass.watchHeading(getCompassHeading, onError, options); } function getCompassHeading(heading) { document.getElementById('compass').innerHTML = "<p>Magnetic Heading: " + heading.magneticHeading + "</p>"; } function onError(compassError) { alert('Compass error: ' + compassError.code); } </script> </head> <body> <div id = "compass"> <p>Getting magnetic heading</p> </div> </body> </html>
Write code to display a compass, as shown here (this app is called e125).
Write code to overlay a compass on a map of the current location, as shown here (this app is called e126).
The GoogleMaps API WatchPosition() function can be used to continuously keep track of the current GPS position. The is useful in apps that involve the user moving around. The example below will display the path on a map of the route that a user has taken.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="initial-scale=1, width=device-width, height=device-height, viewport-fit=cover"> <title>Worked example from lecture notes</title> <style> *{ -webkit-touch-callout: none; -webkit-user-select: none; /* Disable selection/copy in UIWebView */ } html, body { width:100%; height: 100%; margin: 0px; padding: 0px; } #walkDetailsDiv { width:100%; height: 5%; min-height:3em; margin: 0px; padding: 0px; background-color: #fff; padding: 5px; visibility:hidden; } #routeDiv { width:100%; height: 75%; margin: 0px; padding: 0px; } h3, p { margin:5px; } input[type="button"] { padding:0.2em; margin:0.2em; font-size:larger; } #startStopButton { background-color: #0f0; } </style> <!-- This is needed to access the PhoneGap JavaScript --> <script type="text/javascript" charset="utf-8" src="cordova.js"></script> <!-- Google Maps --> <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script> <script> let routeMap; let directionsDisplay; let directionsService = new google.maps.DirectionsService(); let routeMap; let latitude = 0.0; let longitude = 0.0; let latitudeAndLongitude; let poly = null; let marker = null; let id = null; let routeMap = null; let mapZoom = 16; let textOutputInterval = null; let distanceInMeters = 0; let options = {maximumAge: 1000, timeout: 50000, enableHighAccuracy: true}; // note, it takes a few seconds for the gps to work, so you need to give a high timeout value let oldLatitude = null; let oldLongitude = null; let path = null; document.addEventListener("deviceready", onDeviceReady, false); function onDeviceReady() { document.getElementById('walkDetailsDiv').style.visibility = 'visible'; // Show the walkDetailsDiv navigator.geolocation.getCurrentPosition(onGetCurrentPositionSuccess, onGeolocationError, options); } function onGetCurrentPositionSuccess(position) { latitude = position.coords.latitude; longitude = position.coords.longitude; initialiseMapPosition(latitude, longitude); } function initialiseMapPosition(latitude, longitude) { directionsDisplay = new google.maps.DirectionsRenderer(); latitudeAndLongitude = new google.maps.LatLng(latitude, longitude); let mapOptions = {zoom: mapZoom, center: routeMap, mapTypeId: google.maps.MapTypeId.ROADMAP}; routeMap = new google.maps.Map(document.getElementById('routeDiv'), mapOptions); // assign the directionsDisplay to the map directionsDisplay.setMap(routeMap); poly = new google.maps.Polyline({ strokeColor: '#f00', strokeOpacity: 0.5, strokeWeight: 7 }); poly.setMap(routeMap); } function onGeolocationSuccess(position) { // set latitude and longitude global variables latitude = position.coords.latitude; longitude = position.coords.longitude; if (oldLatitude === null) { oldLatitude = latitude; oldLongitude = longitude; marker = new google.maps.Marker({ position: latitudeAndLongitude, map: routeMap, title: "You are here." }); } latitudeAndLongitude = new google.maps.LatLng(latitude, longitude); path = poly.getPath(); path.push(latitudeAndLongitude); distanceInMeters = google.maps.geometry.spherical.computeLength(path); // recentre map around current location routeMap.setCenter(new google.maps.LatLng(latitude, longitude)); marker.setPosition(new google.maps.LatLng(latitude, longitude)); oldLatitude = latitude; oldLongitude = longitude; } function displayTextOutput() { details = "Distance walked: " + distanceInMeters.toFixed(0); document.getElementById("walkDetailsDiv").innerHTML = details; } function onGeolocationError(error) { document.getElementById("walkDetailsDiv").innerHTML = "Error: " + details; } function startStop() { clearInterval(textOutputInterval); if (document.getElementById('startStopButton').value === 'Start') { document.getElementById('startStopButton').value = 'Stop'; document.getElementById('startStopButton').style.backgroundColor = '#f00'; initialiseMapPosition(latitude, longitude); // start the route marker = null; oldLatitude = null; oldLongitude = null; path = null; window.plugins.insomnia.keepAwake(); let options = {'enableHighAccuracy': true, 'timeout': 10000, 'maximumAge': 20000}; id = navigator.geolocation.watchPosition(onGeolocationSuccess, onGeolocationError, options); textOutputInterval = setInterval(displayTextOutput, 1000); // update the text output every second } else { document.getElementById('startStopButton').value = 'Start'; document.getElementById('startStopButton').style.backgroundColor = '#0f0'; // stop tracking the route window.plugins.insomnia.allowSleepAgain(); navigator.geolocation.clearWatch(id); } } </script> </head> <body> <div id="controlPanelDiv"> <input id="startStopButton" type="button" value="Start" onclick="startStop()"> </div> <div id="walkDetailsDiv"></div> <div id="routeDiv"> <h3>Route Finder Demo</h3> <p>loading...</p><p>It can take several seconds for the map to load. Please be patient.</p> </div> </body> </html>
Copyright Derek O' Reilly, Dundalk Institute of Technology (DkIT), Dundalk, Co. Louth, Ireland.