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();
});
}
}