-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
263 lines (246 loc) · 8.66 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
<!DOCTYPE html>
<html>
<head>
<title>Local Information</title>
<link rel="shortcut icon" type="image/png" href="https://cdn0.iconfinder.com/data/icons/social-icons-rounded/110/Information-Bubble-512.png"/>
<style>
#map{
height: 300px;
width: 100%;
}
#cardplaces{
height:300px;
}
#main_container{
max-width: 700px;
border: 1px solid #ccc;
}
#weather{
height: 200px;
}
.nopadding{
padding: 0 !important;
margin: 0 !important;
}
.cardpadding{
padding-top: 0 !important;
padding-left: 0.2em !important;
padding-right: 0.2em !important;
}
.centertext{
text-align: center;
}
</style>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<div class="container mt-3 px-5 py-4 rounded shadow" id="main_container">
<form id="location-form" novalidate>
<div class="form-group row">
<div class="col nopadding">
<label for="location-input" class="col-form-label text-right">Post Code</label>
</div>
<div class="col-7 nopadding">
<input type="text" id="location-input" placeholder="160-0022" class="form-control" pattern="^\d{3}-\d{4}$" required>
<div class="invalid-feedback" id="errorField"></div>
<small id="notfound" class="form-text text-muted"></small>
</div>
<div class="col-3">
<button type="submit" class="btn btn-secondary btn-block">Submit</button>
</div>
</div>
</form>
<div>
<h2 id="heading" class="mb-2">Tokyo, Shinjuku City</h2>
<h6>3-day forecast</h6>
</div>
<div class="row mb-3">
<div class="col">
<div class="card">
<img class="card-img-top" src="" alt="Weather">
<div class="card-body cardpadding">
<p class="card-subtitle centertext"></p>
<h5 class="card-title centertext"></h5>
<p class="card-subtitle centertext"></p>
</div>
</div>
</div>
<div class="col">
<div class="card">
<img class="card-img-top" src="" alt="Weather">
<div class="card-body cardpadding">
<p class="card-subtitle centertext"></p>
<h5 class="card-title centertext"></h5>
<p class="card-subtitle centertext"></p>
</div>
</div>
</div>
<div class="col">
<div class="card">
<img class="card-img-top" src="" alt="Weather">
<div class="card-body cardpadding">
<p class="card-subtitle centertext"></p>
<h5 class="card-title centertext"></h5>
<p class="card-subtitle centertext"></p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col">
<h5>Map</h5>
<div class="card-block" id="map"></div>
</div>
<div class="col">
<h5>Restaurants (Click for marker)</h5>
<div class="card">
<div class="card-body cardpadding overflow-auto" id="cardplaces">
<ul id="places" class="list-group list-group-flush"></ul>
</div>
</div>
</div>
</div>
</div>
<script>
function init(){
//Initialize map and marker
var location = new google.maps.LatLng(35.693840, 139.703549)
var map = new google.maps.Map(document.getElementById("map"), {
zoom: 14,
center: location
});
var marker = new google.maps.Marker({
position: location,
map: map,
});
//Initialize restaurants
var request = {
location: location,
radius: '500',
type: ['restaurant']
};
var service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, updatePlaces);
//Initialize weather
updateWeather(location.lat(), location.lng())
//Globals
var weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
var places = document.getElementById('places')
var errorField = document.getElementById('errorField');
var inp = document.getElementById('location-input');
var heading = document.getElementById('heading');
var notfound = document.getElementById('notfound');
var cards = document.getElementsByClassName('card');
var locationForm = document.getElementById('location-form');
locationForm.addEventListener('submit', newLocation);
//On new post-code
function newLocation(e){
e.preventDefault();
//Change to Googles accepted format, from NNN-NNNN to NNNNNNN
var postcode = inp.value.replace('-','');
//Notice if post-code not found
notfound.innerHTML = '';
//Validation based on regex pattern, see the html for "location-input"
if(inp.checkValidity() === false){
locationForm.classList.add('was-validated');
errorField.innerHTML = 'Please input a valid post-code: ddd-dddd, where d is a digit.';
return
}
//Fetch localization information from google maps api
axios.get('https://maps.googleapis.com/maps/api/geocode/json',{
params:{
address:postcode,
key:'AIzaSyATf73Nlz6BjuwY1OUzRqbUx8BBMXUIMnc'
}
})
.then(function(response){
//Check if post code not found
if(response.data.status === 'ZERO_RESULTS'){
notfound.innerHTML = 'It looks like this post-code does not exist.<br>Please try another.';
return
}
var results = response.data.results[0];
var lat = results.geometry.location.lat;
var lng = results.geometry.location.lng;
var address = results.address_components;
//Show city and prefecture name (removed postcode and country name)
heading.innerHTML = address.slice(1,-1).map((x) => x.long_name).reverse().join(', ');
updateWeather(lat, lng)
//Update map and marker
location = new google.maps.LatLng(lat, lng);
map.panTo(location);
marker.setPosition(location);
//Clear old restaurant list
while (places.lastChild) {
places.removeChild(places.lastChild);
}
request = {
location: location,
radius: '500',
type: ['restaurant']
};
service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, updatePlaces);
})
.catch(function(error){
console.log(error);
});
}
function updatePlaces(results, status){
//Fill restaurant list
if (status == google.maps.places.PlacesServiceStatus.OK) {
results.forEach((place) => {
var newPlace = document.createElement('li')
places.appendChild(newPlace)
newPlace.classList.add('list-group-item')
newPlace.innerHTML = 'Name: '+place.name+'<br>Rating: '+place.rating+'<br>Address: '+place.vicinity
newPlace.addEventListener('click', addMarker(place.geometry.location))
});
}
}
var addMarker = (location) => () => {
//Add marker for clicked restaurant
var marker = new google.maps.Marker({
position: location,
map: map,
});
}
function updateWeather(lat, lng){
//3 day weather forecast based on longitude and latitude
axios.get('https://api.weatherbit.io/v2.0/forecast/daily',{
params:{
lat:lat,
lon:lng,
days:3,
key:'ba500da895e145edadea7d18dbcf3204'
}
})
.then(function(response){
//Extract wanted info for each day
var weather = response.data.data.map((day) => ({
date: day.datetime,
max_temp: day.max_temp,
min_temp: day.min_temp,
weather: day.weather.description,
icon: day.weather.icon
}))
//Update weather cards
weather.map((e, i) => {
cards[i].children[0].src = 'https://www.weatherbit.io/static/img/icons/'+e.icon+'.png';
var cardbody = cards[i].children[1].children;
cardbody[0].innerHTML = e.date+' '+weekdays[new Date(e.date).getDay()];
cardbody[1].innerHTML = e.weather;
cardbody[2].innerHTML = 'Max: '+e.max_temp+'° Min: '+e.min_temp+'°';
})
})
.catch(function(error){
console.log(error);
});
}
}
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?libraries=places&key=AIzaSyATf73Nlz6BjuwY1OUzRqbUx8BBMXUIMnc&callback=init"></script>
</body>
</html>