Guest User

Untitled

a guest
Nov 21st, 2017
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.38 KB | None | 0 0
  1. import {Component, Input, ElementRef, ViewChild, ViewChildren, QueryList, NgZone} from '@angular/core';
  2. import {Content} from 'ionic-angular';
  3. import {formatDate} from '../../utils/formatDate';
  4. import {getI18n} from 'get-i18n';
  5.  
  6. import immutable from 'immutable';
  7. import { NgRedux } from 'ng2-redux';
  8. import { bindActionCreators } from 'redux';
  9. import { fetchMapSearchResult, clearMapSearchResult } from '../../actions/search/index';
  10.  
  11. declare const plugin: any;
  12.  
  13. @Component({
  14. selector: 'google-maps',
  15. templateUrl: 'template.html',
  16. })
  17.  
  18. export class GoogleMaps {
  19. @ViewChild('map') mapElement: ElementRef;
  20. @Input() private keyword: string;
  21. @Input() private categoryId: string;
  22. @Input() private initialLocation: any;
  23. private map: any;
  24. private products: any;
  25. private hasNextPage: any;
  26.  
  27. private lastActiveBounds: any;
  28. private selectedProductsList: any;
  29. private productSliderVisible: boolean;
  30.  
  31. public i18n: any;
  32. public zone: any;
  33.  
  34. public unsubscribe: any;
  35. public clearMapSearchResult: any;
  36. public fetchMapSearchResult: any;
  37.  
  38. constructor(private elementRef: ElementRef, private ngRedux: NgRedux<any>) {
  39. this.i18n = getI18n('googleMaps');
  40. this.zone = new NgZone({ enableLongStackTrace: false });
  41. }
  42.  
  43. public ngOnChanges(changes): void {
  44. if (this.map) {
  45. console.log('Search keyword changed, should perform new search');
  46. const bounds = this.map.getVisibleRegion();
  47.  
  48. this.clearMapSearchResult();
  49. this.fetchMapSearchResult(this.keyword, this.categoryId, bounds);
  50. }
  51. }
  52.  
  53. public ngAfterContentInit(): void {
  54. this.zone.run(() => {
  55. this.map = plugin.google.maps.Map.getMap(this.mapElement.nativeElement, {
  56. controls: {
  57. compass: false,
  58. myLocationButton: true
  59. },
  60. gestures: {
  61. scroll: true,
  62. tilt: true,
  63. rotate: true,
  64. zoom: true
  65. },
  66. camera : {
  67. target: this.initialLocation || {lat: 63.1123, lng: 16.3539},
  68. zoom: this.initialLocation ? 12 : 4
  69. },
  70. preferences: {
  71. zoom: {
  72. minZoom: 2,
  73. maxZoom: 18
  74. },
  75. building: false
  76. },
  77. // styles: [{ 'featureType': 'all', 'elementType': 'labels.text.fill', 'stylers': [{ 'saturation': 36 }, { 'color': '#333333' }, { 'lightness': 40 }] }, { 'featureType': 'all', 'elementType': 'labels.text.stroke', 'stylers': [{ 'visibility': 'on' }, { 'color': '#ffffff' }, { 'lightness': 16 }] }, { 'featureType': 'all', 'elementType': 'labels.icon', 'stylers': [{ 'visibility': 'off' }] }, { 'featureType': 'administrative', 'elementType': 'geometry.fill', 'stylers': [{ 'color': '#fefefe' }, { 'lightness': 20 }] }, { 'featureType': 'administrative', 'elementType': 'geometry.stroke', 'stylers': [{ 'color': '#fefefe' }, { 'lightness': 17 }, { 'weight': 1.2 }] }, { 'featureType': 'landscape', 'elementType': 'geometry', 'stylers': [{ 'color': '#f5f5f5' }, { 'lightness': 20 }] }, { 'featureType': 'poi', 'elementType': 'geometry', 'stylers': [{ 'color': '#f5f5f5' }, { 'lightness': 21 }] }, { 'featureType': 'poi.attraction', 'elementType': 'all', 'stylers': [{ 'visibility': 'on' }] }, { 'featureType': 'poi.park', 'elementType': 'geometry', 'stylers': [{ 'color': '#dedede' }, { 'lightness': 21 }] }, { 'featureType': 'poi.park', 'elementType': 'geometry.fill', 'stylers': [{ 'color': '#e1f1e2' }] }, { 'featureType': 'road.highway', 'elementType': 'geometry.fill', 'stylers': [{ 'color': '#ffffff' }, { 'lightness': 17 }] }, { 'featureType': 'road.highway', 'elementType': 'geometry.stroke', 'stylers': [{ 'color': '#ffffff' }, { 'lightness': 29 }, { 'weight': 0.2 }] }, { 'featureType': 'road.arterial', 'elementType': 'geometry', 'stylers': [{ 'color': '#ffffff' }, { 'lightness': 18 }] }, { 'featureType': 'road.local', 'elementType': 'geometry', 'stylers': [{ 'color': '#ffffff' }, { 'lightness': 16 }] }, { 'featureType': 'transit', 'elementType': 'geometry', 'stylers': [{ 'color': '#f2f2f2' }, { 'lightness': 19 }] }, { 'featureType': 'water', 'elementType': 'geometry', 'stylers': [{ 'color': '#e9e9e9' }, { 'lightness': 17 }] }, { 'featureType': 'water', 'elementType': 'geometry.fill', 'stylers': [{ 'color': '#e4f1f2' }] }]
  78. });
  79.  
  80. this.map.addEventListener(plugin.google.maps.event.MAP_READY, this.onMapReady.bind(this));
  81. this.map.addEventListener(plugin.google.maps.event.MAP_CLICK, this.onMapClick.bind(this));
  82. this.map.addEventListener(plugin.google.maps.event.CAMERA_MOVE, this.onMapMove.bind(this));
  83. });
  84. }
  85.  
  86. public ngOnDestroy(): void {
  87. this.map.removeEventListener(plugin.google.maps.event.MAP_READY, this.onMapReady);
  88. this.map.removeEventListener(plugin.google.maps.event.CAMERA_MOVE, this.onMapMove);
  89. this.map.removeEventListener(plugin.google.maps.event.CAMERA_MOVE_END, this.onMapMoveEnd);
  90. this.map.removeEventListener(plugin.google.maps.event.MAP_CLICK, this.onMapClick);
  91. this.map.remove();
  92. this.unsubscribe();
  93. this.clearMapSearchResult();
  94. console.log('map should now be destroyed');
  95. }
  96.  
  97. private plotMapMarkers(products: any) {
  98. console.log('A search that returned new results was performed, plotting new markers');
  99. const markers = [];
  100.  
  101. products.map(product => {
  102. const lat = product.getIn(['zipCodeCoordinate', 'latitude']);
  103. const lng = product.getIn(['zipCodeCoordinate', 'longitude']);
  104. markers.push({
  105. position: {
  106. lat,
  107. lng
  108. },
  109. icon: {
  110. url: 'assets/img/geomap/map-pin.png',
  111. size: {
  112. width: 40,
  113. height: 40
  114. }
  115. },
  116. disableAutoPan: true,
  117. productId: product.get('id')
  118. });
  119. });
  120.  
  121. this.map.clear();
  122.  
  123. this.map.addMarkerCluster({
  124. boundsDraw: false,
  125. maxZoomLevel: 18,
  126. markers,
  127. icons: [
  128. {
  129. min: 2,
  130. url: 'assets/img/geomap/map-pin-zoom.png',
  131. anchor: { x: 24, y: 24 },
  132. label: {
  133. color: 'white',
  134. fontSize: 10,
  135. bold: true
  136. },
  137. size: {
  138. width: 64,
  139. height: 64
  140. }
  141. }
  142. ]
  143. }, (markerCluster) => {
  144. markerCluster.on(plugin.google.maps.event.MARKER_CLICK, this.onMarkerClick.bind(this));
  145. });
  146. }
  147.  
  148. private onMapReady() {
  149. this.map.addEventListener(plugin.google.maps.event.CAMERA_MOVE_END, this.onMapMoveEnd.bind(this));
  150.  
  151. this.zone.run(() => {
  152. this.unsubscribe = this.ngRedux.connect(
  153. (state) => this.mapStateToThis(state),
  154. (state) => this.mapDispatchToThis(state)
  155. )(this);
  156. });
  157. }
  158.  
  159. private onMapMoveEnd() {
  160. this.zone.run(() => {
  161. const bounds = this.map.getVisibleRegion();
  162. console.log('CAMERA_MOVE_END');
  163.  
  164. if (this.lastActiveBounds) {
  165. if (!this.hasNextPage && this.lastActiveBounds.contains(bounds.northeast) && this.lastActiveBounds.contains(bounds.southwest)) {
  166. console.log('User has zoomed in and there is no need to perform a new search');
  167. } else {
  168. console.log('Looks like a new location or too many hits were previously returned, will perform new search');
  169. this.fetchMapSearchResult(this.keyword, this.categoryId, bounds);
  170. this.lastActiveBounds = bounds;
  171. }
  172. } else {
  173. console.log('initial search');
  174. this.fetchMapSearchResult(this.keyword, this.categoryId, bounds);
  175. this.lastActiveBounds = bounds;
  176. }
  177. });
  178. }
  179.  
  180. private onMapClick() {
  181. this.zone.run(() => {
  182. console.log('clicked on map');
  183. this.productSliderVisible = false;
  184. });
  185. }
  186.  
  187. private onMapMove() {
  188. this.zone.run(() => {
  189. console.log('Map is moved');
  190. this.productSliderVisible = false;
  191. });
  192. }
  193.  
  194. private onMarkerClick(params: any[]) {
  195. console.log('marker clicked');
  196. console.log(params); // Only returns the location object
  197. }
  198.  
  199. public mapStateToThis(state): any {
  200. const status = state.getIn(['mapSearch', 'status']);
  201. const products = (state.getIn(['mapSearch', 'response', 'products']) || immutable.fromJS({}));
  202. const hasNextPage = state.getIn(['mapSearch', 'response', 'hasNextPage']);
  203.  
  204. if (!immutable.is(this.products, products)) {
  205. console.log('Got new resulys, should call plotMapMarkers()');
  206. this.plotMapMarkers(products);
  207. }
  208.  
  209. return {
  210. status,
  211. products,
  212. hasNextPage
  213. };
  214. }
  215.  
  216. public mapDispatchToThis(dispatch) {
  217. const actions = { fetchMapSearchResult, clearMapSearchResult };
  218. return bindActionCreators(actions, dispatch);
  219. }
  220.  
  221. }
Add Comment
Please, Sign In to add comment