So you’re a dev, and you just googled. “where is my nearest emergency room” and guess what, there is no easy answer. What if there was a real emergency? How would you get to the emergency room? Let’s pretend that we don’t want to just call an ambulance. You are new to the area, don’t have your insurance paid up to date, it’s not that bad and you think you can walk there, but don’t know what the fastest route is. Whatever. The problem is right there.
Let’s not wait till an emergency to need that tool. Let’s make it here. Today.
Google maps API
https://developers.google.com/maps/
Basic plan:
- Get user location
- sort out where the emergency rooms are
- calculate the closest emergency room
- Suggest a route to there by walking or driving.
- Bonus: if it’s going to take more than 10 minutes to walk there; suggest driving (from a friend) or an Uber, if that will take more than 10 minutes, suggest an Ambulance (first responders can usually provide aid before you get to hospital)
- Advanced: select the closest 5 emergency rooms and calculate all transport routes and suggest the fastest of the options.
There’s no need to derive this from scratch. You know what they say, in order to make a hamburger you must first invent the universe. But also we stand on the shoulders of giants! Don’t rewrite the universe, good artists copy, great artists steal.
- user location
https://developers.google.com/maps/documentation/javascript/tutorials/geolocation
From that page:
<!DOCTYPE html> <html> <head> <title>Geolocation</title> <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> <meta charset="utf-8"> <style> html, body { height: 100%; margin: 0; padding: 0; } #map { height: 100%; } </style> </head> <body> <div id="map"></div> <script> // Note: This example requires that you consent to location sharing when // prompted by your browser. If you see the error "The Geolocation service // failed.", it means you probably did not give permission for the browser to // locate you. function initMap() { var map = new google.maps.Map(document.getElementById('map'), { center: {lat: -34.397, lng: 150.644}, zoom: 6 }); var infoWindow = new google.maps.InfoWindow({map: map}); // Try HTML5 geolocation. if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(function(position) { var pos = { lat: position.coords.latitude, lng: position.coords.longitude }; infoWindow.setPosition(pos); infoWindow.setContent('Location found.'); map.setCenter(pos); }, function() { handleLocationError(true, infoWindow, map.getCenter()); }); } else { // Browser doesn't support Geolocation handleLocationError(false, infoWindow, map.getCenter()); } } function handleLocationError(browserHasGeolocation, infoWindow, pos) { infoWindow.setPosition(pos); infoWindow.setContent(browserHasGeolocation ? 'Error: The Geolocation service failed.' : 'Error: Your browser doesn\'t support geolocation.'); } </script> <script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"> </script> </body> </html>
Oh hey! Yea that works. Just like that. Get the user location.
2. location of emergency rooms:
https://data.gov.au/dataset/australian-hospital-statistics-2012-13
Well; that’s my data. Needs some cleaning up because not all hospitals have an emergency department.
anddddd, the data is formatted as addresses not latitude/longitudes.
Example: NSW data
Hospital name | Address Line 1 | Address Line 2 |
Armidale | 226 Rusden ST | Armidale 2350 |
Auburn | 18-20 Hargrave RD | Auburn 2144 |
Ballina | 78-92 Cherry ST | Ballina 2478 |
Bankstown/ Lidcombe | 68 Eldridge RD | Bankstown 2200 |
Barraba (MPS) | 1 Edward ST | Barraba 2347 |
Batemans Bay | 7 Pacific ST | Batemans Bay 2536 |
Bathurst | 361 Howick ST | Bathurst 2795 |
Bega | 1 McKee DR | Bega 2550 |
Belmont | 16 Croudace Bay RD | Belmont 2280 |
Bingara (MPS) | 1 Keera ST | Bingara 2404 |
Blacktown | 44 Blacktown RD | Blacktown 2148 |
Blue Mountains | Lot 3 Woodlands RD | Katoomba 2780 |
Boggabri (MPS) | 3 Wee Waa ST | Boggabri 2382 |
Bowral | Lot 3 Mona RD | Bowral 2576 |
Broken Hill | 176 Thomas ST | Broken Hill 2880 |
Bulahdelah – Myall Lakes | 1 Richmond ST | Bulahdelah 2423 |
Bulli | 33A Hospital RD | Bulli 2516 |
Byron Bay | 10 Shirley ST | Byron Bay 2481 |
Calvary Mater Newcastle | 4 Edith ST | Waratah 2298 |
Camden | 65 Menangle RD | Camden 2570 |
Campbelltown | 1 Therry RD | Campbelltown 2560 |
Canterbury | 575 Canterbury RD | Campsie 2194 |
Casino | 1 Hotham ST | Casino 2470 |
Cessnock | Lot 1 View ST | Cessnock 2325 |
Children’s Hospital Westmead | 178 Hawkesbury RD | Westmead 2145 |
Coffs Harbour | 345 Pacific HWY | Coffs Harbour 2450 |
Concord | 1a Hospital RD | Concord West 2138 |
Denman (MPS) | 51-53 Ogilvie ST | Denman 2328 |
Dubbo | 1 Myall ST | Dubbo 2830 |
Dungog | 58 Hospital RD | Dungog 2420 |
Fairfield | 360 Prairie Vale RD | Prairiewood 2176 |
Glen Innes | 94 Taylor ST | Glen Innes 2370 |
Gloucester | 166 Church ST | Gloucester 2422 |
Gosford | 76 Holden ST | Gosford 2250 |
Goulburn | 130 Goldsmith ST | Goulburn 2580 |
Grafton | 174 Arthur ST | Grafton 2460 |
Griffith | 1 Noorebar AV | Griffith 2680 |
Gunnedah | 2 Marquis ST | Gunnedah 2380 |
Guyra (MPS) | 44-48 Sole ST | Guyra 2365 |
Hawkesbury | Cnr Macquarie and Day St | Windsor 2756 |
Hornsby and Ku-Ring-Gai | 36-76 Palmerston RD | Hornsby 2077 |
Inverell | 41-61 Swanbrook RD | Inverell 2360 |
John Hunter | 156 Kookaburra CCT | New Lambton Heights 2305 |
Kurri Kurri | 432 Lang ST | Kurri Kurri 2327 |
Lismore | 60 Uralba ST | Lismore 2480 |
Lithgow | 2 Col Drewe DR | Lithgow 2790 |
Liverpool | Lot 2 Elizabeth ST | Liverpool 2170 |
Maclean | 21 Union ST | Maclean 2463 |
Macleay Valley – Kempsey | 119 River ST | Kempsey 2440 |
Maitland | 550 High ST | Maitland 2320 |
Manilla (MPS) | 143 Court ST | Manilla 2346 |
Manly | 150 Darley RD | Manly 2095 |
Manning | 26 York ST | Taree 2430 |
Merriwa (MPS) | 1 Mackenzie ST | Merriwa 2329 |
Milton and Ulladulla | 104 Princes HWY | Milton 2538 |
Mona Vale | 18 Coronation ST | Mona Vale 2103 |
Moree | 35 Alice ST | Moree 2400 |
Moruya | 2-10 River ST | Moruya 2537 |
Mount Druitt | 75 Railway ST | Mount Druitt 2770 |
Mullumbimby | 1-3 Azalea ST | Mullumbimby 2482 |
Murrurundi | 59 O’Connell ST | Murrurundi 2338 |
Murwillumbah | 8 Ewing ST | Murwillumbah 2484 |
Muswellbrook | 36 Brentwood ST | Muswellbrook 2333 |
Narrabri | 11 Cameron ST | Narrabri 2390 |
Nepean | 256 Derby ST | Kingswood 2747 |
Orange Health Service | 1502 Forest RD | Orange 2800 |
Port Macquarie | 1-31 Wrights RD | Port Macquarie 2444 |
Prince Albert Tenterfield | 1-5 Naas ST | Tenterfield 2372 |
Prince of Wales | 147 Barker ST | Randwick 2031 |
Quirindi | 42 Nowland ST | Quirindi 2343 |
Royal North Shore | 1 Reserve RD | St Leonards 2065 |
Royal Prince Alfred | 50 Missenden RD | Camperdown 2050 |
Ryde | 1 Denistone RD | Eastwood 2122 |
Scott Memorial Scone | 24 Stafford ST | Scone 2337 |
Shellharbour | 15-17 Madigan BVD | Mount Warrigal 2528 |
Shoalhaven Memorial | 2 Shoalhaven ST | Nowra 2541 |
Singleton | Lot 20 Dangar RD | Singleton 2330 |
St George | 28 Gray ST | Kogarah 2017 |
St Vincent’s Darlinghurst | 390 Victoria ST | Darlinghurst 2010 |
Sutherland | 430 Kingsway | Caringbah 2229 |
Sydney Children’s | 1 High ST | Randwick 2031 |
Sydney/ Sydney Eye | 8 Macquarie ST | Sydney 2000 |
Tamworth | 31 Dean ST | North Tamworth 2340 |
The Tweed Hospital | 14 Powell ST | Tweed Heads 2485 |
Tingha (MPS) | 1 Inverell RD | Tingha 2369 |
Tomaree Community | 2 Trevally ST | Nelson Bay 2315 |
Vegetable Creek (MPS) | 13-33 Glen Innes RD | Emmaville 2371 |
Wagga Wagga | 260 Edward ST | Wagga Wagga 2650 |
Walcha (MPS) | 7 South ST | Walcha 2354 |
Warialda (MPS) | 146 Long ST | Warialda 2402 |
Wee Waa | 60 Alma ST | Wee Waa 2388 |
Werris Creek | 22-34 North ST | Werris Creek 2341 |
Westmead | 166 Darcy RD | Westmead 2145 |
Wollongong | 348 Crown ST | Wollongong 2500 |
Wyong | Pacific HWY | Kanwal 2259 |
LMGTFY: http://www.unbolt.net/geocode_convertor.php, http://www.findlatitudeandlongitude.com/batch-geocode/, http://www.mapdevelopers.com/batch_geocode_tool.php
Spoilt for choice! You could even do it twice and double check (Hint: I did)
Hospname | original address | latitude | longitude |
Armidale | 226 Rusden ST Armidale 2350 | -30.512477 | 151.656561 |
Auburn | 18-20 Hargrave RD Auburn 2144 | -33.86093 | 151.032587 |
Ballina | 78-92 Cherry ST Ballina 2478 | -28.863182 | 153.564435 |
Bankstown/ Lidcombe | 68 Eldridge RD Bankstown 2200 | -33.933125 | 151.020843 |
Barraba (MPS) | 1 Edward ST Barraba 2347 | -30.382636 | 150.610385 |
Batemans Bay | 7 Pacific ST Batemans Bay 2536 | -35.713737 | 150.182253 |
Bathurst | 361 Howick ST Bathurst 2795 | -33.410636 | 149.574939 |
Bega | 1 McKee DR Bega 2550 | -36.681218 | 149.837464 |
Belmont | 16 Croudace Bay RD Belmont 2280 | -33.024433 | 151.648913 |
Bingara (MPS) | 1 Keera ST Bingara 2404 | -29.86439 | 150.571804 |
Blacktown | 44 Blacktown RD Blacktown 2148 | -33.775361 | 150.91895 |
Blue Mountains | Lot 3 Woodlands RD Katoomba 2780 | -33.7034 | 150.321213 |
Boggabri (MPS) | 3 Wee Waa ST Boggabri 2382 | -30.712277 | 150.04153 |
Bowral | Lot 3 Mona RD Bowral 2576 | -34.484825 | 150.424681 |
Broken Hill | 176 Thomas ST Broken Hill 2880 | -31.947774 | 141.45395 |
Bulahdelah – Myall Lakes | 1 Richmond ST Bulahdelah 2423 | -32.403967 | 152.211854 |
Bulli | 33A Hospital RD Bulli 2516 | -34.336178 | 150.906459 |
Byron Bay | 10 Shirley ST Byron Bay 2481 | -28.64196 | 153.609391 |
Calvary Mater Newcastle | 4 Edith ST Waratah 2298 | -32.898737 | 151.721457 |
Camden | 65 Menangle RD Camden 2570 | -34.062312 | 150.694473 |
Campbelltown | 1 Therry RD Campbelltown 2560 | -34.080098 | 150.803486 |
Canterbury | 575 Canterbury RD Campsie 2194 | -33.921402 | 151.096798 |
Casino | 1 Hotham ST Casino 2470 | -28.86971 | 153.03493 |
Cessnock | Lot 1 View ST Cessnock 2325 | -32.827465 | 151.351592 |
Children’s Hospital Westmead | 178 Hawkesbury RD Westmead 2145 | -33.800966 | 150.99277 |
Coffs Harbour | 345 Pacific HWY Coffs Harbour 2450 | -30.316138 | 153.092842 |
Concord | 1a Hospital RD Concord West 2138 | -33.837305 | 151.090948 |
Denman (MPS) | 51-53 Ogilvie ST Denman 2328 | -32.389667 | 150.684524 |
Dubbo | 1 Myall ST Dubbo 2830 | -32.240492 | 148.616006 |
Dungog | 58 Hospital RD Dungog 2420 | -32.401379 | 151.745778 |
Fairfield | 360 Prairie Vale RD Prairiewood 2176 | -33.859138 | 150.9034 |
Glen Innes | 94 Taylor ST Glen Innes 2370 | -29.732653 | 151.732144 |
Gloucester | 166 Church ST Gloucester 2422 | -32.014856 | 151.958353 |
Gosford | 76 Holden ST Gosford 2250 | -33.42104 | 151.340653 |
Goulburn | 130 Goldsmith ST Goulburn 2580 | -34.747866 | 149.713185 |
Grafton | 174 Arthur ST Grafton 2460 | -29.675738 | 152.941764 |
Griffith | 1 Noorebar AV Griffith 2680 | -34.281205 | 146.048545 |
Gunnedah | 2 Marquis ST Gunnedah 2380 | -30.984714 | 150.249085 |
Guyra (MPS) | 44-48 Sole ST Guyra 2365 | -30.212657 | 151.679175 |
Hawkesbury | Cnr Macquarie and Day St Windsor 2756 | -33.609917 | 150.817869 |
Hornsby and Ku-Ring-Gai | 36-76 Palmerston RD Hornsby 2077 | -33.702574 | 151.112587 |
Inverell | 41-61 Swanbrook RD Inverell 2360 | -29.770603 | 151.129266 |
John Hunter | 156 Kookaburra CCT New Lambton Heights 2305 | -32.925949 | 151.671229 |
Kurri Kurri | 432 Lang ST Kurri Kurri 2327 | -32.823997 | 151.462961 |
Lismore | 60 Uralba ST Lismore 2480 | -28.80889 | 153.291498 |
Lithgow | 2 Col Drewe DR Lithgow 2790 | -33.499637 | 150.126252 |
Liverpool | Lot 2 Elizabeth ST Liverpool 2170 | -33.920691 | 150.927895 |
Maclean | 21 Union ST Maclean 2463 | -29.453827 | 153.201618 |
Macleay Valley – Kempsey | 119 River ST Kempsey 2440 | -31.068203 | 152.819666 |
Maitland | 550 High ST Maitland 2320 | -32.726924 | 151.545491 |
Manilla (MPS) | 143 Court ST Manilla 2346 | -30.746254 | 150.731707 |
Manly | 150 Darley RD Manly 2095 | -33.805457 | 151.294866 |
Manning | 26 York ST Taree 2430 | -31.910288 | 152.455006 |
Merriwa (MPS) | 1 Mackenzie ST Merriwa 2329 | -32.142491 | 150.359803 |
Milton and Ulladulla | 104 Princes HWY Milton 2538 | -35.317254 | 150.438953 |
Mona Vale | 18 Coronation ST Mona Vale 2103 | -33.685954 | 151.308016 |
Moree | 35 Alice ST Moree 2400 | -29.471284 | 149.845008 |
Moruya | 2-10 River ST Moruya 2537 | -35.904658 | 150.070182 |
Mount Druitt | 75 Railway ST Mount Druitt 2770 | -33.765665 | 150.83024 |
Mullumbimby | 1-3 Azalea ST Mullumbimby 2482 | -28.558816 | 153.490569 |
Murrurundi | 59 O’Connell ST Murrurundi 2338 | -31.769738 | 150.836195 |
Murwillumbah | 8 Ewing ST Murwillumbah 2484 | -28.32364 | 153.400389 |
Muswellbrook | 36 Brentwood ST Muswellbrook 2333 | -32.265462 | 150.901484 |
Narrabri | 11 Cameron ST Narrabri 2390 | -30.326302 | 149.777348 |
Nepean | 256 Derby ST Kingswood 2747 | -33.761319 | 150.713938 |
Orange Health Service | 1502 Forest RD Orange 2800 | -33.314353 | 149.09494 |
Port Macquarie | 1-31 Wrights RD Port Macquarie 2444 | -31.452074 | 152.878833 |
Prince Albert Tenterfield | 1-5 Naas ST Tenterfield 2372 | -29.045184 | 152.013893 |
Prince of Wales | 147 Barker ST Randwick 2031 | -33.920844 | 151.236595 |
Quirindi | 42 Nowland ST Quirindi 2343 | -31.49993 | 150.677052 |
Royal North Shore | 1 Reserve RD St Leonards 2065 | -33.819232 | 151.189266 |
Royal Prince Alfred | 50 Missenden RD Camperdown 2050 | -33.887912 | 151.180769 |
Ryde | 1 Denistone RD Eastwood 2122 | -33.794467 | 151.089906 |
Scott Memorial Scone | 24 Stafford ST Scone 2337 | -32.052428 | 150.876581 |
Shellharbour | 15-17 Madigan BVD Mount Warrigal 2528 | -34.557919 | 150.842344 |
Shoalhaven Memorial | 2 Shoalhaven ST Nowra 2541 | -34.86768 | 150.597071 |
Singleton | Lot 20 Dangar RD Singleton 2330 | -32.565712 | 151.183596 |
St George | 28 Gray ST Kogarah 2017 | -33.9678 | 151.133217 |
St Vincent’s Darlinghurst | 390 Victoria ST Darlinghurst 2010 | -33.8791 | 151.221783 |
Sutherland | 430 Kingsway Caringbah 2229 | -34.037477 | 151.114783 |
Sydney Children’s | 1 High ST Randwick 2031 | -33.915175 | 151.228012 |
Sydney/ Sydney Eye | 8 Macquarie ST Sydney 2000 | -33.860316 | 151.213237 |
Tamworth | 31 Dean ST North Tamworth 2340 | -31.075436 | 150.922931 |
The Tweed Hospital | 14 Powell ST Tweed Heads 2485 | -28.177102 | 153.545626 |
Tingha (MPS) | 1 Inverell RD Tingha 2369 | -29.781998 | 151.118333 |
Tomaree Community | 2 Trevally ST Nelson Bay 2315 | -32.720203 | 152.159007 |
Vegetable Creek (MPS) | 13-33 Glen Innes RD Emmaville 2371 | -29.450119 | 151.598799 |
Wagga Wagga | 260 Edward ST Wagga Wagga 2650 | -35.117999 | 147.35696 |
Walcha (MPS) | 7 South ST Walcha 2354 | -30.983941 | 151.590481 |
Warialda (MPS) | 146 Long ST Warialda 2402 | -29.53833 | 150.579153 |
Wee Waa | 60 Alma ST Wee Waa 2388 | -30.227051 | 149.443074 |
Werris Creek | 22-34 North ST Werris Creek 2341 | -31.346486 | 150.652519 |
Westmead | 166 Darcy RD Westmead 2145 | -33.80075 | 150.963773 |
Wollongong | 348 Crown ST Wollongong 2500 | -34.424749 | 150.883505 |
Wyong | Pacific HWY Kanwal 2259 | -33.256507 | 151.486545 |
3. Calculate the closest emergency room to the user: (my favourite tool of the day LMGTFY)
http://stackoverflow.com/questions/4057665/google-maps-api-v3-find-nearest-markers
It’s done. Someone has already coded how to find the nearest of a set of pre-set markers.
Math!
function rad(x) {return x*Math.PI/180;}
function find_closest_marker( event ) {
var lat = event.latLng.lat();
var lng = event.latLng.lng();
var R = 6371; // radius of earth in km
var distances = [];
var closest = -1;
for( i=0;i<map.markers.length; i++ ) {
var mlat = map.markers[i].position.lat();
var mlng = map.markers[i].position.lng();
var dLat = rad(mlat - lat);
var dLong = rad(mlng - lng);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(rad(lat)) * Math.cos(rad(lat)) * Math.sin(dLong/2) * Math.sin(dLong/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
distances[i] = d;
if ( closest == -1 || d < distances[closest] ) {
closest = i;
}
}
alert(map.markers[closest].title);
}
Super do-able. Just needs integration.
4. Navigate to the nearest hospital.
https://developers.google.com/maps/documentation/directions/intro
According to the developer guide it’s going to look something like this:
http://maps.googleapis.com/maps/api/directions/outputFormat?origin= Mylatitude,Mylongditude&destination=NearestHospitalLatitude,NearestHospitalLongitude&mode=walking
and out the back will spit out some directions.
But there’s a better way. After we know the nearest hospital we can open a google maps link to that location:
http://maps.google.com/maps?f=saddr=UserLat,Userlong&daddr=HospitalLat,HospitalLong&directionsmode=walking
Then the user can open a browser on their device with directions OR their local maps app, which can guide them using that URL.
5. Bonus problem. Travel time:
https://developers.google.com/maps/documentation/directions/intro#traffic-model
Method for retrieving travel times can be found here. And because stackX is the answer to all problems:
http://stackoverflow.com/questions/1042885/using-google-maps-api-to-get-travel-time-data
According to this information; it’s against the google TOS to display for the user that travel time; if you are not using a google map to display the information. This needs more thought. More thought than I have time for right now.
But that’s basically it.
6. Advanced goal: Using the learning from 5; it wouldn’t be hard to look up all of the transport methods for the nearest 5 hospitals and then only offer the user the fastest time duration (1-3 options)
Notes for future me: all the geolocations are a little off because even the hospital addresses were not the address of the front door of the emergency room. This is the problem with any data. There are 205 hospitals on the register, this needs to be hard-coded otherwise it’s still going to be hard to find the emergency room for the user. The pin should be directly on top of the door to emergency to make it as easy as possible to get to the door.
Video to go along with it: https://youtu.be/EFCMONjCL_0