Passed
Pull Request — master (#250)
by Markus
05:02
created

pokemon.maps.js ➔ initMap   A

Complexity

Conditions 1
Paths 4

Size

Total Lines 73

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 0 Features 0
Metric Value
cc 1
c 7
b 0
f 0
nc 4
nop 0
dl 0
loc 73
rs 9.0675

1 Function

Rating   Name   Duplication   Size   Complexity  
A pokemon.maps.js ➔ ... ➔ $.getJSON(ꞌcore/json/variables.jsonꞌ) 0 71 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
/** global: google */
2
/** global: pokemon_id */
3
/** global: navigator */
4
5
var map, heatmap;
6
var pokemonMarkers = [];
7
var updateLiveTimeout;
8
9
var ivMin = 80;
10
var ivMax = 100;
11
12
function initMap() {
13
	$.getJSON( "core/json/variables.json", function( variables ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
14
		var latitude = Number(variables['system']['map_center_lat']);
15
		var longitude = Number(variables['system']['map_center_long']);
16
		var zoom_level = Number(variables['system']['zoom_level']);
17
		var pokeimg_suffix = variables['system']['pokeimg_suffix'];
18
19
		map = new google.maps.Map(document.getElementById('map'), {
20
			center: {
21
				lat: latitude,
22
				lng: longitude
23
			},
24
			zoom: zoom_level,
25
			zoomControl: true,
26
			scaleControl: false,
27
			scrollwheel: true,
28
			disableDoubleClickZoom: false,
29
			streetViewControl: false,
30
			mapTypeControlOptions: {
31
				mapTypeIds: [
32
					google.maps.MapTypeId.ROADMAP,
33
					'pogo_style',
34
					'dark_style',
35
				]
36
			}
37
		});
38
39
		$.getJSON( 'core/json/pogostyle.json', function( data ) {
40
			var styledMap_pogo = new google.maps.StyledMapType(data, {name: 'PoGo'});
41
			map.mapTypes.set('pogo_style', styledMap_pogo);
42
		});
43
		$.getJSON( 'core/json/darkstyle.json', function( data ) {
44
			var styledMap_dark = new google.maps.StyledMapType(data, {name: 'Dark'});
45
			map.mapTypes.set('dark_style', styledMap_dark);
46
		});
47
		$.getJSON( 'core/json/defaultstyle.json', function( data ) {
48
			map.set('styles', data);
49
		});
50
51
		$.ajax({
52
			'async': true,
53
			'type': "GET",
54
			'global': false,
55
			'dataType': 'json',
56
			'url': "core/process/aru.php",
57
			'data': {
58
				'request': "",
59
				'target': 'arrange_url',
60
				'method': 'method_target',
61
				'type': 'maps_localization_coordinates'
62
			}
63
		}).done(function(coordinates) {
64
			if (navigator.geolocation) {
65
				navigator.geolocation.getCurrentPosition(function(position) {
66
					var pos = {
67
						lat: position.coords.latitude,
68
						lng: position.coords.longitude
69
					};
70
71
					if (position.coords.latitude <= coordinates.max_latitude && position.coords.latitude >= coordinates.min_latitude) {
72
						if (position.coords.longitude <= coordinates.max_longitude && position.coords.longitude >= coordinates.min_longitude) {
73
							map.setCenter(pos);
74
						}
75
					}
76
				});
77
			}
78
		});
79
		
80
		initHeatmap();
81
		initSelector(pokeimg_suffix);
82
		
83
	});
84
}
85
86
function initSelector(pokeimg_suffix){
87
	$('#heatmapSelector').click(function(){
88
		hideLive();
89
		showHeatmap();
90
		$('#heatmapSelector').addClass('active');
91
		$('#liveSelector').removeClass('active');
92
	});
93
	$('#liveSelector').click(function(){
94
		hideHeatmap();
95
		map.setMapTypeId(google.maps.MapTypeId.ROADMAP);
96
		initLive(pokeimg_suffix);
97
		
98
		
99
		$('#liveSelector').addClass('active');
100
		$('#heatmapSelector').removeClass('active');
101
	});
102
}
103
104
function initLive(pokeimg_suffix){
105
	showLive();
106
	$("#liveFilterSelector").rangeSlider({
107
		bounds:{
108
			min: 0,
109
			max: 100
110
		},
111
		defaultValues:{
112
			min: ivMin,
113
			max: ivMax
114
		},
115
		formatter:function(val) {
116
			return "IV: "+Math.round(val)+"%";
117
		}
118
	});
119
	
120
	$("#liveFilterSelector").bind("valuesChanged",function(e, data){
121
		clearTimeout(updateLiveTimeout);
122
		removePokemonMarkerByIv(data.values.min,data.values.max);
123
		ivMin = data.values.min;
124
		ivMax = data.values.max;
125
		updateLive(pokeimg_suffix);
126
	});
127
	updateLive(pokeimg_suffix);
128
	
129
}
130
131
function initHeatmap(){
132
	$.ajax({
133
		'async': true,
134
		'type': "GET",
135
		'global': false,
136
		'dataType': 'json',
137
		'url': "core/process/aru.php",
138
		'data': {
139
			'request': "",
140
			'target': 'arrange_url',
141
			'method': 'method_target',
142
			'type' : 'pokemon_slider_init'
143
		}
144
	}).done(function(bounds){
145
		initHeatmapData(bounds);
146
	});
147
	
148
}
149
150
function initHeatmapData(bounds){
151
	var boundMin = new Date(bounds.min.replace(/-/g, "/"));
152
	var boundMax = new Date(bounds.max.replace(/-/g, "/"));
153
	var selectorMax = boundMax;
154
	var selectorMin = boundMin;
155
156
	// two weeks in millisec
157
	var twoWeeks = 12096e5;
158
	var maxMinus2Weeks = new Date(selectorMax.getTime() - twoWeeks);
159
	if(selectorMin < maxMinus2Weeks){
160
		selectorMin = maxMinus2Weeks;
161
	}
162
163
	// dict with millisec => migration nr.
164
	var migrations = {};
165
	// start at 4 because 06. Oct 2016 was the 4th migration
166
	var migr_nr = 4;
167
	$("#timeSelector").dateRangeSlider({
168
		bounds:{
169
			min: boundMin,
170
			max: boundMax
171
		},
172
		defaultValues:{
173
			min: selectorMin,
174
			max: selectorMax
175
		},
176
		scales: [{
177
			first: function(value) {
178
				// 06. Oct 2016 (4th migration). 2 week schedule starts with this migration
179
				var migrationStart = new Date("2016-10-06T00:00:00Z");
180
				var now = new Date();
181
				var result = new Date();
182
				for (var migration = migrationStart; migration <= now; migration.setTime(migration.getTime() + twoWeeks)) {
183
					if (migration >= value) {
184
						result = migration;
185
						migrations[result.getTime()] = migr_nr;
186
						break;
187
					}
188
					migr_nr++;
189
				}
190
				return result;
191
			},
192
			next: function(value){
193
				var next = new Date(new Date(value).setTime(value.getTime() + twoWeeks));
194
				migr_nr++;
195
				migrations[next.getTime()] = migr_nr;
196
				return next;
197
			},
198
			label: function(value){
199
				if (isMobileDevice() && isTouchDevice()) {
200
					return "#" + migrations[value.getTime()];
201
				}
202
				return "Migration #" + migrations[value.getTime()];
203
			},
204
		}]
205
	});
206
	createHeatmap();
207
208
}
209
210
function createHeatmap() {
211
	
212
	heatmap = new google.maps.visualization.HeatmapLayer({
213
		data: [],
214
		map: map
215
	});
216
217
	var gradient = [
218
		'rgba(0, 255, 255, 0)',
219
		'rgba(0, 255, 255, 1)',
220
		'rgba(0, 191, 255, 1)',
221
		'rgba(0, 127, 255, 1)',
222
		'rgba(0, 63, 255, 1)',
223
		'rgba(0, 0, 255, 1)',
224
		'rgba(0, 0, 223, 1)',
225
		'rgba(0, 0, 191, 1)',
226
		'rgba(0, 0, 159, 1)',
227
		'rgba(0, 0, 127, 1)',
228
		'rgba(63, 0, 91, 1)',
229
		'rgba(127, 0, 63, 1)',
230
		'rgba(191, 0, 31, 1)',
231
		'rgba(255, 0, 0, 1)'
232
	];
233
	heatmap.set('gradient', gradient);
234
	heatmap.setMap(map);
235
	$("#timeSelector").bind("valuesChanged",function(){updateHeatmap()});
236
	$("#timeSelector").dateRangeSlider("min"); // will trigger valuesChanged
237
}
238
239
function updateHeatmap() {
240
	var dateMin = $("#timeSelector").dateRangeSlider("min");
241
	var dateMax = $("#timeSelector").dateRangeSlider("max");
242
	$("#loaderContainer").show();
243
	$.ajax({
244
		'async': true,
245
		'type': "GET",
246
		'global': false,
247
		'dataType': 'json',
248
		'url': "core/process/aru.php",
249
		'data': {
250
			'request': "",
251
			'target': 'arrange_url',
252
			'method': 'method_target',
253
			'type' : 'pokemon_heatmap_points',
254
			'pokemon_id' : pokemon_id,
255
			'start' : Math.floor(dateMin.getTime()/1000),
256
			'end' : Math.floor(dateMax.getTime()/1000)
257
		}
258
	}).done(function(points){
259
		var googlePoints = [];
260
		for (var i = 0; i < points.length; i++) {
261
			googlePoints.push(new google.maps.LatLng(points[i].latitude,points[i].longitude))
262
		}
263
		var newPoints = new google.maps.MVCArray(googlePoints);
264
		heatmap.set('data', newPoints);
265
		$("#loaderContainer").hide();
266
	});
267
}
268
269
function hideHeatmap() {
270
	$("#timeFilterContainer").hide();
271
	heatmap.set('map', null);
272
}
273
274
function showHeatmap() {
275
	$("#timeFilterContainer").show();
276
	heatmap.set('map', map);
277
	hideLive();
278
}
279
280
function hideLive() {
281
	$("#liveFilterContainer").hide();
282
	clearTimeout(updateLiveTimeout);
283
	clearPokemonMarkers();
284
}
285
286
function showLive() {
287
	hideHeatmap();
288
	clearTimeout(updateLiveTimeout);
289
	$("#liveFilterContainer").show();
290
	
291
}
292
293
function updateLive(pokeimg_suffix){
294
	$.ajax({
295
		'async': true,
296
		'type': "POST",
297
		'global': false,
298
		'dataType': 'json',
299
		'url': "core/process/aru.php",
300
		'data': {
301
			'request': "",
302
			'target': 'arrange_url',
303
			'method': 'method_target',
304
			'type' : 'pokemon_live',
305
			'pokemon_id' : pokemon_id,
306
			'inmap_pokemons' : extractEncountersId(),
307
			'ivMin' : ivMin,
308
			'ivMax' : ivMax
309
		}
310
	}).done(function(pokemons){
311
		for (var i = 0; i < pokemons.points.length; i++) {
312
			addPokemonMarker(pokemons.points[i],pokeimg_suffix, pokemons.locale)
313
		}
314
		updateLiveTimeout=setTimeout(function(){ updateLive(pokeimg_suffix) },5000);
315
	});
316
}
317
318
function addPokemonMarker(pokemon,pokeimg_suffix, locale) {
319
	var image = {
320
		url:'core/pokemons/'+pokemon.pokemon_id+pokeimg_suffix,
321
		scaledSize: new google.maps.Size(32, 32),
322
		origin: new google.maps.Point(0,0),
323
		anchor: new google.maps.Point(16, 16),
324
		labelOrigin : new google.maps.Point(16, 36)
325
	};
326
	var encounter = false;
327
	var ivPercent = 100;
328
	if (pokemon.individual_attack != null) {
0 ignored issues
show
Best Practice introduced by
Comparing pokemon.individual_attack to null using the != operator is not safe. Consider using !== instead.
Loading history...
329
		encounter = true;
330
		ivPercent = ((100/45)*(parseInt(pokemon.individual_attack)+parseInt(pokemon.individual_defense)+parseInt(pokemon.individual_stamina))).toFixed(2);
331
	}
332
	var marker = new google.maps.Marker({
333
		position: {lat: parseFloat(pokemon.latitude), lng:parseFloat(pokemon.longitude)},
334
		map: map,
335
		icon: image,
336
		encounterId: pokemon.encounter_id,
337
		ivPercent: ivPercent
338
	});
339
	if (encounter) {
340
		marker.setLabel({
341
			color:getIvColor(ivPercent),
342
			text:ivPercent+"%"
343
		});
344
	}
345
	var contentString = '<div>'+
346
			'<h4> '+pokemon.name+' #'+pokemon.pokemon_id+ (encounter?' IV: '+ivPercent+'% ':'')+'</h4>'+
347
			'<div id="bodyContent">'+
348
				'<p class="disappear_time_display text-center">'+pokemon.disappear_time_real+'<span class="disappear_time_display_timeleft"></span></p>';
349
	if (encounter) {
350
		contentString +=
351
				'<p></p>'+
352
				'<div class="progress" style="height: 6px; width: 120px; margin-bottom: 10px; margin-top: 2px; margin-left: auto; margin-right: auto">'+
353
					'<div title="'+locale.ivAttack+': '+pokemon.individual_attack+'" class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="'+pokemon.individual_attack+'" aria-valuemin="0" aria-valuemax="45" style="width: '+(((100/15)*pokemon.individual_attack)/3)+'%">'+
354
						'<span class="sr-only">'+locale.ivAttack+': '+pokemon.individual_attack+'</span>'+
355
					'</div>'+
356
					'<div title="'+locale.ivDefense+': '+pokemon.individual_defense+'" class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="'+pokemon.individual_defense+'" aria-valuemin="0" aria-valuemax="45" style="width: '+(((100/15)*pokemon.individual_defense)/3)+'%">'+
357
						'<span class="sr-only">'+locale.ivDefense+': '+pokemon.individual_defense+'</span>'+
358
					'</div>'+
359
					'<div title="'+locale.ivStamina+': '+pokemon.individual_stamina+'" class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="'+pokemon.individual_stamina+'" aria-valuemin="0" aria-valuemax="45" style="width: '+(((100/15)*pokemon.individual_stamina)/3)+'%">'+
360
						'<span class="sr-only">'+locale.ivStamina+': '+pokemon.individual_stamina+'</span>'+
361
					'</div>'+
362
				'</div>'+
363
				'<p class="text-center">('+pokemon.individual_attack+"/"+pokemon.individual_defense+"/"+pokemon.individual_stamina+')</p>'+
364
				'<p class="text-center">'+pokemon.quick_move+"/"+pokemon.charge_move+'</p>';
365
		}
366
		contentString +='</div>';
367
368
	var infoWindow = new google.maps.InfoWindow({
369
		content: contentString
370
	});
371
	infoWindow.isClickOpen = false;
372
	marker.addListener('click', function() {
373
		infoWindow.isClickOpen = true;
374
		infoWindow.open(map, this);
375
	});
376
	google.maps.event.addListener(infoWindow,'closeclick',function(){
377
		this.isClickOpen = false;
378
	});
379
	marker.addListener('mouseover', function() {
380
		infoWindow.open(map, this);
381
	});
382
383
	// assuming you also want to hide the infowindow when user mouses-out
384
	marker.addListener('mouseout', function() {
385
		if(infoWindow.isClickOpen === false){
386
			infoWindow.close();
387
		}
388
	});
389
	pokemonMarkers.push(marker);
390
	var now = new Date().getTime();
391
	var endTime = new Date(pokemon.disappear_time_real.replace(/-/g, "/")).getTime();
392
	
393
	setTimeout(function(){ removePokemonMarker(pokemon.encounter_id) },endTime-now);
394
}
395
396
397
function getIvColor(ivPercent){
398
	var ivColor="rgba(0, 0, 0, 0)";
399
	if(ivPercent>80){
400
		ivColor="rgba(0, 0, 255, 0.70)";
401
	}
402
	if(ivPercent>90){
403
		ivColor="rgba(246, 178, 107, 0.90)";
404
	}
405
	if(ivPercent>99){
406
		ivColor="rgba(255, 0, 0, 1)";
407
	}
408
	return ivColor;
409
}
410
411
function clearPokemonMarkers() {
412
	for (var i = 0; i < pokemonMarkers.length; i++) {
413
		pokemonMarkers[i].setMap(null);
414
	}
415
	pokemonMarkers = [];
416
}
417
function removePokemonMarker(encounter_id) {
418
	for (var i = 0; i < pokemonMarkers.length; i++) {
419
		if(pokemonMarkers[i].encounterId == encounter_id){
420
			pokemonMarkers[i].setMap(null);
421
			pokemonMarkers.splice(i,1);
422
			break;
423
		}
424
		
425
	}
426
	
427
}
428
429
function removePokemonMarkerByIv(ivMin,ivMax) {
430
	var cleanMarkers=[];
431
	for (var i = 0; i < pokemonMarkers.length; i++) {
432
		if(pokemonMarkers[i].ivPercent < ivMin || pokemonMarkers[i].ivPercent > ivMax){
433
			pokemonMarkers[i].setMap(null);
434
		}
435
		else{
436
			cleanMarkers.push(pokemonMarkers[i]);
437
		}
438
		
439
	}
440
	pokemonMarkers = cleanMarkers;
441
}
442
443
function extractEncountersId(){
444
	var inmapEncounter = [];
445
	for (var i = 0; i < pokemonMarkers.length; i++) {
446
		inmapEncounter[i]=pokemonMarkers[i].encounterId;
447
	}
448
	
449
	return inmapEncounter;
450
}
451
452
function isTouchDevice() {
453
	// Should cover most browsers
454
	return 'ontouchstart' in window || navigator.maxTouchPoints
455
}
456
457
function isMobileDevice() {
458
	// Basic mobile OS (not browser) detection
459
	return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent))
460
}
461