]>
Commit | Line | Data |
---|---|---|
1 | import {Component, EventEmitter,CORE_DIRECTIVES,} from 'angular2/angular2'; | |
2 | import {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 | ||
12 | export 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 |