Ionic 4 Creating a search filter for map, trouble with javascript in .ts


#1

Creating a map application where I would like to filter items depending on user input in the search bar,
I’m having trouble with ionic managing to recognize the Javascript in the .ts

I’m wondering if there is a quick fix beside importing the Javascript in the html using or rewriting the code to Typescript, since I’m not too familiar with typescript

import { Component, ElementRef, ViewChild, ViewEncapsulation } from '@angular/core';
import { ConferenceData } from '../../providers/conference-data';
import { NotificationPage } from '../notification/notification.page';
import { Platform, ModalController, PopoverController  } from '@ionic/angular';
import { MapLayerComponent } from '../map-layer/map-layer.component';
//import mapboxgl from 'mapbox-gl/dist/mapbox-gl.js';
import * as mapboxgl from 'mapbox-gl';
import { StatusBar } from '@ionic-native/status-bar/ngx';


@Component({
  selector: 'page-map',
  templateUrl: 'map.html',
  styleUrls: ['./map.scss'],
  encapsulation: ViewEncapsulation.None
})
export class MapPage{

  /// default settings
  map: mapboxgl.Map;
  style = 'mapbox://styles/johnbrattaker/cjiobwfne1rpa2soesmqtzp68';
  lat = 20.0066;
  lng = 40.7135;
  message = 'Hello World!';

  // data
  source: any;
  markers: any;
  excludeTracks: any = [];
  
  constructor(
    public confData: ConferenceData,
    public platform: Platform,
    public statusBar: StatusBar,
    public modalCtrl: ModalController,
    public popoverController: PopoverController
  ) 
  {
    
    mapboxgl.accessToken = 'pk.eyJ1Ijoiam9obmJyYXR0YWtlciIsImEiOiJjamlmemFidnQwbW5sM3dxcGR1c3ZvYzd6In0.vq8bxeJ5wJ5hdQtySfAk8Q';
  }

  ionViewDidEnter() {

    this.buildMap();
  };  

 

  async presentFilter() {
    const modal = await this.modalCtrl.create({
      component: NotificationPage,
      componentProps: { excludedTracks: this.excludeTracks }
    });
    
    await modal.present();    
  }

  async presentLayersFilter(ev: any) {
    const popover = await this.popoverController.create({
      component: MapLayerComponent,
      event: ev,
      translucent: true
    });
    
    /* const { data } = await popover.onWillDismiss(); */
    return await popover.present();
   
  }

  toogleFullscreen() {
    this.platform.ready().then(() => {
       this.statusBar.hide();
    });
  }
    
  buildMap() { 
    this.map = new mapboxgl.Map({
      container: 'map',
      style: this.style,
      zoom: 2,
      center: [this.lng, this.lat]
    });

    // Holds visible vessel features for filtering
var vessels = [];

// Create a popup, but don't add it to the map yet.
var popup = new mapboxgl.Popup({
    closeButton: false
});

var filterEl = document.getElementById('feature-filter');
var listingEl = document.getElementById('feature-listing');


renderListings(features) {
  // Clear any existing listings
  listingEl.innerHTML = '';
  if (features.length) {
      features.forEach(function(feature) {
          var prop = feature.properties;
          var item = document.createElement('a');
          item.href = prop.wikipedia;
          item.target = '_blank';
          item.textContent = prop.name + ' (' + prop.abbrev + ')';
          item.addEventListener('mouseover', function() {
              // Highlight corresponding feature on the map
              popup.setLngLat(feature.geometry.coordinates)
                  .setText(feature.properties.name + ' (' + feature.properties.abbrev + ')')
                  .addTo(map);
          });
          listingEl.appendChild(item);
      });

      // Show the filter input
      filterEl.parentNode.style.display = 'block';
  } else {
      var empty = document.createElement('p');
      empty.textContent = 'Drag the map to populate results';
      listingEl.appendChild(empty);

      // Hide the filter input
      filterEl.parentNode.style.display = 'none';

      // remove features filter
      map.setFilter('vessel', ['has', 'abbrev']);
  }
}

function normalize(string) {
  return string.trim().toLowerCase();
}

function getUniqueFeatures(array, comparatorProperty) {
  var existingFeatureKeys = {};
  // Because features come from tiled vector data, feature geometries may be split
  // or duplicated across tile boundaries and, as a result, features may appear
  // multiple times in query results.
  var uniqueFeatures = array.filter(function(el) {
      if (existingFeatureKeys[el.properties[comparatorProperty]]) {
          return false;
      } else {
          existingFeatureKeys[el.properties[comparatorProperty]] = true;
          return true;
      }
  });

  return uniqueFeatures;
}


    this.map.on('load', (event) => {  

      //ais
        this.map.addSource('veh-incidents-1', {
          type: 'geojson',
          data: 'https://dl.dropbox.com/s/hfzw58r625fhshu/points.geojson?dl=0',
          buffer: 0,
          maxzoom: 12
      });
  
      //vessels
      this.map.addSource('veh-incidents-2', {
          type: 'geojson',
          data: 'https://dl.dropbox.com/s/algouut0sf5vggo/vessels.geojson?dl=0',
          buffer: 0,
          maxzoom: 12
      });
      
      
      //ais: https://dl.dropbox.com/s/hfzw58r625fhshu/points.geojson?dl=0
      //vessels: https://dl.dropbox.com/s/algouut0sf5vggo/vessels.geojson?dl=0
      
      var zoomThreshold = 4;

  //map without zoom    
  this.map.addLayer({
      "id": "points",
      "type": "symbol",
      "source": 'veh-incidents-2',
      'maxzoom': zoomThreshold,
      "layout": {
          "icon-allow-overlap": true,
          "icon-image": "Asset-Icon-Map-vessel-17",
          "icon-rotation-alignment": "map",
          "icon-text-fit": "none",
          "icon-rotate": {
              "type": "identity",
              "property": "course"
           },
           "text-field": "{name}",
           "text-allow-overlap": false,
           "text-ignore-placement": false,
           "text-optional": true,
           "text-font": ["Open Sans Semibold", "Arial Unicode MS Bold"],
           "text-size": 8,          
           "text-offset": [1.2, 0],
           "text-anchor": "left"               
      }
  });

  //map with zoom
  this.map.addLayer({
    "id": "points2",
    "type": "symbol",
    "source": 'veh-incidents-2',
    'minzoom': zoomThreshold,
    "layout": {
        "icon-allow-overlap": true,        
        "icon-image": "Asset-Icon-Map-vessel-large",
        "icon-rotation-alignment": "map",
        "icon-text-fit": "none",
        "icon-rotate": {
            "type": "identity",
            "property": "course"
         },
         "text-field": "{name}",
        "text-allow-overlap": false,
        "text-ignore-placement": false,
        "text-optional": true,
        "text-font": ["Open Sans Semibold", "Arial Unicode MS Bold"],
        "text-size": 12,          
        "text-offset": [1.2, 0],
        "text-anchor": "left"       
    }
});


map.on('moveend', function() {
  var features = map.queryRenderedFeatures({layers:['vessel']});

  if (features) {
      var uniqueFeatures = getUniqueFeatures(features, "iata_code");
      // Populate features for the listing overlay.
      renderListings(uniqueFeatures);

      // Clear the input container
      filterEl.value = '';

      // Store the current features in sn `vessels` variable to
      // later use for filtering on `keyup`.
      vessels = uniqueFeatures;
  }
});

map.on('mousemove', 'vessel', function(e) {
  // Change the cursor style as a UI indicator.
  map.getCanvas().style.cursor = 'pointer';

  // Populate the popup and set its coordinates based on the feature.
  var feature = e.features[0];
  popup.setLngLat(feature.geometry.coordinates)
      .setText(feature.properties.name + ' (' + feature.properties.abbrev + ')')
      .addTo(map);
});

map.on('mouseleave', 'vessel', function() {
  map.getCanvas().style.cursor = '';
  popup.remove();
});

filterEl.addEventListener('keyup', function(e) {
  var value = normalize(e.target.value);

  // Filter visible features that don't match the input value.
  var filtered = vessels.filter(function(feature) {
      var name = normalize(feature.properties.name);
      var code = normalize(feature.properties.abbrev);
      return name.indexOf(value) > -1 || code.indexOf(value) > -1;
  });

  // Populate the sidebar with filtered results
  renderListings(filtered);

  // Set the filter to populate features into the layer.
  map.setFilter('vessel', ['match', ['get', 'abbrev'], filtered.map(function(feature) {
      return feature.properties.abbrev;
  }), true, false]);
});

// Call this function on initialization
// passing an empty array to render an empty state
renderListings([]);
});

  
    this.map.resize();

  });
  }

}