]> git.uio.no Git - u/erikhf/frm.git/blame_incremental - src/components/map/map.ts
cleanup in map.css
[u/erikhf/frm.git] / src / components / map / map.ts
... / ...
CommitLineData
1import {Component, EventEmitter,CORE_DIRECTIVES,} from 'angular2/angular2';
2import {Headers, Http} from 'angular2/http';
3
4@Component({
5 selector: 'mou-map',
6 directives: [CORE_DIRECTIVES],
7 events: ['newactive', 'neworg'],
8 templateUrl: './components/map/map.html'
9})
10
11
12export class Map {
13
14 hideModal:any;
15 map:Object;
16 http:Http;
17 LEVEL:number;
18 allLevels:Object;
19 runned:boolean;
20 uprunned:boolean;
21 parent:Object;
22 activeId:string;
23 currentPos:Object;
24 currentMarker:Object;
25 isSearched:boolean;
26 popupON:boolean;
27 popup:Object;
28 COLORS:Object;
29 colornum:number;
30
31 /**
32 * initializes all the global variabels
33 * @param http - for http requests
34 */
35 constructor(http:Http) {
36
37 this.activeId = null;
38 this.newactive = new EventEmitter();
39 this.neworg = new EventEmitter();
40 this.map = new google.maps.Map(document.getElementById("map"), {
41 center: {lat: 0, lng: 0},
42 zoom: 12,
43 mapTypeControlOptions: {
44 position: google.maps.ControlPosition.BOTTOM_CENTER
45 },
46 zoomControlOptions: {
47 position: google.maps.ControlPosition.LEFT_BOTTOM
48 },
49 streetViewControl: false
50 });
51 this.init();
52 this.http = http;
53 this.LEVEL = 2;//
54 this.runned = false;
55 this.getLevels(this);
56 this.parent = null;
57 this.currentPos = null;
58 this.uprunned = false;
59 this.currentMarker = null;
60 this.isSearched = false;
61 this.colornum = 0;
62 this.COLORS = ['#ede1bb', '#1d407e', '#ff512e', '#662d47', '#3b3a35', '#419175', '#983e41', '#f3002d', '#b0a875', '#00bfb5', '#926851', '#47a0a4', '#333f50', '#6f007b'];
63 this.popupON = false;
64 this.popup = null;
65 }
66
67
68 /**
69 * Sets the global variabel
70 * @param id - id of the active marker
71 */
72 setActiveId(id) {
73 this.activeId = id;
74 }
75
76 /**
77 * returns the global map
78 * @returns {Object}
79 */
80 getMap() {
81 return this.map;
82 }
83
84 /**
85 * returns global http
86 * @returns {Http}
87 */
88 getHttp() {
89 return this.http;
90 }
91
92 /**
93 * Sets the avctive markers position
94 * @param latlng - position of the active marker
95 */
96 setcurrentPos(latlng) {
97 this.currentPos = latlng;
98 }
99
100 /**
101 * returns the active markers position
102 * @returns {Object}
103 */
104 getcurrentPos() {
105 return this.currentPos;
106 }
107
108 /**
109 * sets the parent of the avtive marker
110 * @param id - of the parent
111 */
112 setParent(id) {
113 this.parent = id;
114 }
115
116 /**
117 * returns the actice markers parent
118 * @returns {Object}
119 */
120 getParent() {
121 return this.parent;
122 }
123
124 /**
125 * sets a bool value for if the addListner for drilling down has runned (little hack)
126 * @param value - for the runned variabel
127 */
128 setRunned(value) {
129 this.runned = value;
130 }
131
132 /**
133 * sets a bool value for if the addListner for drilling up has runned (little hack)
134 * @param value - for the upRunned variabel
135 */
136 setupRunned(value) {
137 this.uprunned = value;
138 }
139
140 /**
141 * sets the current level in the org.unit hierarchy
142 * @param value - for the level variabel
143 */
144 setLevel(value) {
145 this.LEVEL = value;
146 }
147
148 /**
149 * add level when drilling down (little hack for synconisity)
150 */
151 addLevel() {
152 this.LEVEL++;
153 }
154
155 /**
156 * goes up level when drilling up (little hack for synconisity)
157 */
158 upLevel() {
159 this.LEVEL--;
160 }
161
162 /**
163 * initiates the map with position and zoom
164 */
165 init() {
166
167 let map = this.map;
168 let pos = {lat: 9.1, lng: -11.6};
169 map.setCenter(pos, 0);
170 map.setZoom(7);
171
172 }
173
174 /**
175 * prints out error messages in the console
176 * @param error - the error massage
177 */
178 logError(error) {
179 console.error(error);
180
181 }
182
183 /**
184 * gets data from DHIS API
185 * @param query - for what kind of data to retrieve
186 * @param instance - this instance to use
187 * @param isParent - little hack to see if you want to levels up (the parent of a parent)
188 */
189 getData(query, instance, isParent) {
190 instance.http.get(dhisAPI + '/api/organisationUnits' + query)
191 .map(res => res.json())
192 .subscribe(
193 res => instance.parseResult(res, instance, isParent),
194 error => instance.logError(error)
195 );
196 }
197
198 /**
199 * Gets the number of levels in the org.unit hierarchy from DHIS
200 */
201 getLevels() {
202 this.http.get(dhisAPI + '/api/organisationUnitLevels')
203 .map(res => res.json())
204 .subscribe(
205 res => this.saveLevelTotalandGetdata(res, this),
206 err => this.logError(err)
207 );
208 }
209
210 /**
211 * Saves the data from getLevels() in a global variabel and gets all the data from the second level.
212 * @param res - result from getLevels()
213 * @param instance - witch scope we are in
214 */
215 saveLevelTotalandGetdata(res, instance) {
216 instance.allLevels = res.pager.total;
217 instance.getData('?paging=false&level=2', instance, false);
218 }
219
220 /**
221 * parses all the data from getData() and calles methods based on the incomming data.
222 * @param res - result from getData()
223 * @param instance - witch scope we are in
224 * @param isParent - if it is a parent we have asked for
225 */
226 parseResult(res, instance, isParent) {
227 if (isParent) {
228 instance.setParent(res.parent.id);
229 instance.getData('/' + res.parent.id + '/children', instance, false);
230 }
231 else {
232 if (res.organisationUnits) {
233 for (let item in res.organisationUnits) {
234 this.getData('/' + res.organisationUnits[item].id, this);
235
236 }
237 instance.setupRunned(false);
238 instance.setRunned(false);
239 } else if (!res.displayName && res.children) {
240 for (let item in res.children) {
241 if (res.children[item].level == instance.LEVEL) {
242 this.getData('/' + res.children[item].id, this);
243 }
244 }
245 instance.setRunned(false);
246 instance.setupRunned(false);
247 }
248 else {
249 this.drawPolygon(res, instance);
250 }
251 }
252 }
253
254 /**
255 * creates and draws up the geojson polygons and adds listeners to them.
256 * @param item - an org.unit object
257 * @param instance - witch scope we are in
258 */
259 drawPolygon(item, instance) {
260 let feature;
261 let incoming:string;
262 incoming = item.featureType.toLowerCase();
263 switch (incoming) {
264 case "point":
265 feature = 'Point';
266 break;
267 case "multi_polygon":
268 feature = 'MultiPolygon';
269 break;
270 case "polygon":
271 feature = 'MultiPolygon';
272 break;
273 default:
274 }
275
276 if (feature !== undefined) {
277 let unit = {
278 "type": "Feature",
279 "geometry": {
280 "type": feature,
281 "coordinates": JSON.parse(item.coordinates)
282 },
283 "properties": {
284 "title": item.name,
285 "name": item.name,
286 "id": item.id,
287 "color": instance.COLORS[instance.colornum],
288 "icon": null
289 }
290 };
291 if (instance.COLORS.length == instance.colornum) {
292 instance.colornum = 0;
293 } else {
294 instance.colornum++;
295 }
296
297 if (unit.geometry.type == 'Point') {
298 unit.properties.icon = {
299 path: google.maps.SymbolPath.CIRCLE,
300 strokeColor: 'black',
301 scale: 4
302 };
303 instance.map.setCenter({lat: unit.geometry.coordinates[1], lng: unit.geometry.coordinates[0]});
304 }
305
306 this.map.data.addGeoJson(unit);
307 this.map.data.setStyle(function (feature) {
308 let color = 'gray';
309 let icon;
310 if (feature.getProperty('icon') !== null) {
311 icon = feature.getProperty('icon');
312 }
313 color = feature.getProperty('color');
314 return /** @type {google.maps.Data.StyleOptions} */({
315 fillColor: color,
316 fillOpacity: 0.91,
317 strokeColor: 'white',
318 strokeWeight: 2,
319 icon: icon
320 });
321 });
322 if (instance.isSearched) {
323 instance.seeDetails();
324 }
325 this.map.data.addListener('click', function (event) {
326 $('#myModal').modal('show');
327 instance.setActiveId(event.feature.O.id);
328 instance.setcurrentPos(event.latLng);
329
330 if (instance.uprunned == false && instance.LEVEL == 2) {
331 this.hideModal = document.getElementById("topLevel").style.display = "block";
332 this.hideModal = document.getElementById("middleLevel").style.display = "none";
333 this.hideModal = document.getElementById("bottomLevel").style.display = "none";
334 }
335 else if (instance.runned == false && instance.LEVEL < instance.allLevels) {
336 this.hideModal = document.getElementById("topLevel").style.display = "none";
337 this.hideModal = document.getElementById("middleLevel").style.display = "block";
338 this.hideModal = document.getElementById("bottomLevel").style.display = "none";
339 } else if (instance.runned == false && instance.LEVEL <= instance.allLevels) {
340 this.hideModal = document.getElementById("topLevel").style.display = "none";
341 this.hideModal = document.getElementById("middleLevel").style.display = "none";
342 this.hideModal = document.getElementById("bottomLevel").style.display = "block";
343
344 instance.setcurrentPos(event.latLng);
345 }
346 });
347
348//slette ?? §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
349 /* this.map.data.addListener('mouseover', function (e) {


350 if(!instance.popupON) {
351 instance.popupON = true;
352
353 instance.popup = new google.maps.InfoWindow({
354 content: e.feature.getProperty('name'),
355 position: e.latLng
356 });
357 instance.popup.open(instance.map);
358
359 }
360 });

361 this.map.data.addListener('mouseout', function (event) {


362 instance.popupON = false;
363 instance.popup.open(null);

364 });*/
365
366 }
367 }
368
369 /**
370 * removes the polygon on current level and calles getData on one level down in the org.unit hierarchy
371 */
372 drillDown() {
373 this.closeModal();
374 let map = this.getMap();
375 let id = this.activeId;
376 let level = this.LEVEL;
377 this.setRunned(true);
378 this.setParent(id);
379
380 map.data.forEach(function (feature) {
381 if (!(feature.O.id == id && level == 3)) {
382 map.data.remove(feature);
383
384 }
385 });
386
387 this.addLevel();
388 this.getData('/' + id + '/children', this);
389
390 }
391
392 /**
393 *removes the plogons on the current level and calles the get data with tha parents id and set parent true. this to say that we want this parent's parent
394 */
395 drillUp() {
396 this.setupRunned(true);
397 this.upLevel();
398 let instance = this;
399 this.closeModal();
400 this.map.data.forEach(function (feature) {
401 instance.map.data.remove(feature);
402
403 });
404 if (this.currentMarker !== null) {
405 this.currentMarker.setMap(null);
406 }
407 let parent = instance.getParent();
408 instance.getData('/' + parent, instance, true);
409
410 this.closeModal();
411 }
412
413 /**
414 * focuses map and colors to the clicked marker/polygon and fires an event to sidebar with the id of the marker
415 */
416 seeDetails() {
417 let map = this.getMap();
418 let id = this.activeId;
419 this.closeModal();
420 map.data.forEach(function (feature) {
421 if (feature.getProperty('id') == id) {
422 feature.setProperty('color', 'red');
423 if (feature.getProperty('icon') !== null) {
424 feature.O.icon.strokeColor = 'red';
425 }
426 this.isSearched = false;
427 }
428 else {
429 feature.setProperty('color', 'gray');
430 if (feature.getProperty('icon') !== null) {
431 feature.O.icon.strokeColor = 'black';
432 }
433 }
434 });
435 this.newactive.next(this.activeId);
436 }
437
438 /**
439 * gets the position of the clicked position on the map, saves the parent and sends it in an event.
440 */
441 addUnit() {
442 this.closeModal();
443 let pos = this.getcurrentPos();
444 let lat = pos.lat();
445 let lng = pos.lng();
446 let parent = this.getParent();
447
448 let location = {lat: lat, lng: lng};
449 let event = {location, parent};
450 this.neworg.next(event);
451 this.closeModal();
452 this.setRunned(false);
453 }
454
455 /**
456 * triggered from an event in search and gets the search object from the DHIS API
457 * then calles mapupdate()
458 * @param event - event from an emitter
459 */
460 update(event) {
461 this.newactive.next(event);
462 let map = this.getMap();
463 let http = this.getHttp();
464
465 map.data.forEach(function (feature) {
466 map.data.remove(feature);
467 });
468 http.get(dhisAPI + '/api/organisationUnits/' + event)
469 .map(res => res.json())
470 .subscribe(
471 res => this.mapUpdate(res, this)
472 );
473
474 }
475
476 /**
477 * updates varabels activeId, level and parent to matche the incomming object and gets all the children on the same level.
478 * Then it calles drawPolygon()
479 * @param res - org.unit object
480 * @param instance
481 */
482 mapUpdate(res, instance) {
483 this.setLevel(res.level);
484 this.setActiveId(res.id);
485 this.isSearched = true;
486 this.setParent(res.parent.id);
487
488 instance.getData('/' + res.parent.id + '/children', instance);
489 if (res.coordinates == null || instance.LEVEL == instance.allLevels) {
490 instance.http.get(dhisAPI + '/api/organisationUnits/' + res.parent.id)
491 .map(res => res.json())
492 .subscribe(
493 res => instance.drawPolygon(res, instance)
494 );
495 }
496
497 }
498
499 /**
500 * adds a temperary marker so the user can see an update of the latitude and longitude of a marker
501 * @param pos - position for the temp marker
502 */
503 tempMarker(pos) {
504 let map = this.map;
505 if (this.currentMarker)
506 this.currentMarker.setMap(null);
507
508 this.currentMarker = new google.maps.Marker({
509 position: pos,
510 map: map,
511 title: 'neworg',
512 icon: {
513 path: google.maps.SymbolPath.CIRCLE,
514 scale: 4
515 }
516 });
517 this.currentMarker.setMap(map);
518 map.panTo(this.currentMarker.getPosition());
519 }
520
521
522 /**
523 * closes the modal box over the map.
524 */
525 closeModal() {
526 $("#myModal").modal("hide");
527 this.setRunned(false);
528 }
529
530}
531
532
533
534
535