Skip to content

Instantly share code, notes, and snippets.

@ebellempire
Last active May 31, 2018 18:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ebellempire/84020816b59358d90eee53655df939b3 to your computer and use it in GitHub Desktop.
Save ebellempire/84020816b59358d90eee53655df939b3 to your computer and use it in GitHub Desktop.
Map provider and use in 2 components
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, Events } from 'ionic-angular';
import { MapProvider } from '../../providers/map/map';
import { Storage } from '@ionic/storage';
import { StoryDetailPage } from '../story-detail/story-detail';
@IonicPage()
@Component({
selector: 'page-map',
templateUrl: 'map.html',
})
export class MapPage {
locationAware: boolean = false;
initialMapLoad: boolean = true;
constructor(
public mapProvider: MapProvider,
public navCtrl: NavController,
public navParams: NavParams,
public storage: Storage,
public events: Events,
) {
this.events.subscribe('pushStoryPage', (id) => {
this.pushStoryPage(id);
});
}
ionViewWillEnter(){
this.locationAware=this.mapProvider.isLocationAware();
if (!this.initialMapLoad) {
// subsequent loads...
this.mapProvider.resetMapContainer('map',true,600);
} else {
// first load only...
this.storage.get('stories').then(stories=>{
this.mapProvider.loadMap('map',stories,false);
this.initialMapLoad = false;
});
}
}
pushStoryPage(id){
this.navCtrl.push(StoryDetailPage,{
id:id
});
}
}
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, Events } from 'ionic-angular';
import { ProjectConfigProvider } from '../../providers/project-config/project-config';
import { DatabaseProvider } from '../../providers/database/database';
import { HelpersProvider } from '../../providers/helpers/helpers';
import { StoryDetailPage } from '../story-detail/story-detail';
import { SocialSharing } from '@ionic-native/social-sharing';
import { MapProvider } from '../../providers/map/map';
@IonicPage()
@Component({
selector: 'page-tour-detail',
templateUrl: 'tour-detail.html',
})
export class TourDetailPage {
tourlabel_s:string=this.project.getTourLabel('singular');
storylabel_p:string=this.project.getStoryLabel('plural');
id:number=Number(this.navParams.get('id'));
eventName:string='tour_'+this.id+'Ready';
tour:any;
title:any;
maintext:any;
byline:any;
tour_segment:string="text";
locations:any;
locationAware: boolean = false;
initialMapLoad: boolean = true;
constructor(
public navCtrl: NavController,
public navParams: NavParams,
private project: ProjectConfigProvider,
public database: DatabaseProvider,
public events: Events,
public helpers: HelpersProvider,
private socialSharing: SocialSharing,
public mapProvider: MapProvider,
) { }
async initTourDetail(id:number){
return this.database.tourDetailDB(id)
}
share(){
if(this.tour){
let url=this.project.getSiteRoot()+'tours/show/'+this.id
return this.socialSharing.share(this.tour.title, this.tour.title, null, url);
}else{
return null;
}
}
segmentChange(event){
if(event.value=='map'){
this.mapProvider.resetMapContainer('tourmap',true,600);
}
}
pushStoryPage(id){
this.navCtrl.push(StoryDetailPage,{
id:id,
tour:this.tour,
});
}
ionViewWillEnter(){
this.locationAware=this.mapProvider.isLocationAware();
this.initTourDetail(this.id).then(()=>{
this.events.subscribe(this.eventName, tour=>{
this.tour=tour;
this.locations=tour.items;
this.title=this.helpers.smarten(this.tour.title);
this.maintext=this.helpers.normalizeParagraphs(this.tour.description);
this.byline=this.helpers.createTourByline(this.tour.title, this.tour.creator, this.tour.postscript_text);
// initial map load...
if (!this.initialMapLoad) {
console.log('initial:'+this.initialMapLoad);
// subsequent loads...
this.mapProvider.resetMapContainer('map',true,600);
} else {
console.log('initial:'+this.initialMapLoad);
// first load only...
this.mapProvider.loadMap('tourmap',this.locations,true);
this.initialMapLoad = false;
}
});
});
}
ionViewDidEnter() {
this.helpers.normalizeLinksOnLoad();
// hide bottom nav tabs, which are visible by default when map is rendered
this.events.publish('hideTabs');
}
ionViewWillLeave(){
this.events.unsubscribe(this.eventName);
this.events.publish('showTabs'); // restore tabs
}
}
import { Injectable } from '@angular/core';
import { FabContainer, Events } from 'ionic-angular';
import { LocationProvider } from '../../providers/location/location';
import { ProjectConfigProvider } from '../../providers/project-config/project-config';
import { GoogleMaps, GoogleMap, GoogleMapsEvent, GoogleMapOptions, HtmlInfoWindow, Marker, LatLng, LatLngBounds } from '@ionic-native/google-maps';
import { Storage } from '@ionic/storage';
@Injectable()
export class MapProvider {
map: GoogleMap;
bounds: LatLngBounds;
mapSettings = this.project.getMapSettings();
default_coords = this.mapSettings['coords'];
default_zoom = this.mapSettings['zoom'];
default_tilt = this.mapSettings['tilt'];
initialMapLoad: boolean = true;
newcenter: LatLng;
locationAware: boolean;
reloadEvent: boolean = false;
constructor(
private location: LocationProvider,
private project: ProjectConfigProvider,
public storage: Storage,
public events: Events,
) {
this.events.subscribe('storiesDBUpdated', () => {
this.reloadEvent=true;
});
}
loadMap(div:string,stories:any[],fitAll:boolean=false) {
this.map = GoogleMaps.create(div, this.customMapOptions());
this.map.setIndoorEnabled(false);
this.bounds = new LatLngBounds();
this.addMarkersForLocations(stories);
setTimeout(()=>{
if(fitAll) this.zoomToBounds();
},500);
}
customMapOptions(){
let mapOptions: GoogleMapOptions = {
controls: {
compass:true,
indoorPicker:false,
},
camera: {
target: {
lat: this.default_coords[0],
lng: this.default_coords[1]
},
zoom: this.default_zoom,
tilt: this.default_tilt,
},
styles: [
{
featureType: "all",
stylers: [
{ saturation: -80 }
]
},{
featureType: "road.arterial",
elementType: "geometry",
stylers: [
{ hue: "#00ffee" },
{ saturation: 50 }
]
},{
featureType: "poi.business",
elementType: "labels",
stylers: [
{ visibility: "off" }
]
}
],
};
return mapOptions;
}
addMarkersForLocations(locations:any[]){
return locations.forEach((loc)=>{
let htmlInfoWindow = new HtmlInfoWindow();
let boundsll= new LatLng( loc.latitude, loc.longitude );
this.bounds.extend(boundsll);
let frame: HTMLElement = document.createElement('div');
frame.innerHTML = [
'<div class="marker-iw-bg" '+
'style="background-image:linear-gradient(to top, rgba(0, 0, 0, .3) 0%, rgba(0, 0, 0, .15) 33%, rgba(0, 0, 0, 0) 50%), '+
'url('+loc.fullsize+');"></div>',
'<div><p class="marker-iw-txt">'+loc.title+'</p></div>',
].join("");
frame.addEventListener("click", () => {
//this.pushStoryPage(loc.id);
this.events.publish('pushStoryPage',loc.id);
});
htmlInfoWindow.setContent(frame, {'padding':'0','margin':'0','width':'100% !important'}); // add styles to container
this.map.addMarker({
position: {
lat: loc.latitude,
lng: loc.longitude},
}).then((marker: Marker) => {
marker.on(GoogleMapsEvent.MARKER_CLICK).subscribe(() => {
let pos= new LatLng( loc.latitude, loc.longitude );
this.map.fromLatLngToPoint(pos).then((a)=>{ // convert to px
let adj = Math.floor(a[1] - 120); // move camera center down by about half the height of the infowindow
this.map.fromPointToLatLng([a[0],adj]).then((b)=>{ // convert back to latlng
this.newcenter = b;
this.map.animateCamera({
target: this.newcenter,
duration:700,
bearing:0,
}).then(()=>{
htmlInfoWindow.open(marker);
});
});
});
});
});
});
}
reloadMarkers(){
return this.map.clear().then(()=>{
this.storage.get('stories').then(locations=>{
this.addMarkersForLocations(locations);
})
});
}
zoomToBounds(fab: FabContainer = null){
if(fab) fab.close();
if(this.map && this.bounds){
this.map.animateCamera({
target: this.bounds,
duration:1000,
bearing:0,
}).then(()=>{
this.map.animateCameraZoomOut();
});
}
}
resetMapView(userLocation:any=null,fab: FabContainer=null){
let resetLat = userLocation ? userLocation['lat'] : this.default_coords[0];
let resetLon = userLocation ? userLocation['lon'] : this.default_coords[1];
if(fab) fab.close();
if(this.map){
this.map.animateCamera({ // pan, zoom, tilt
target: {
lat: resetLat,
lng: resetLon
},
tilt: this.default_tilt,
zoom: this.default_zoom,
duration:1500,
}).then(()=>{
if(userLocation){
this.map.setMyLocationEnabled(true); // add blue dot
}
});
}
}
resetMapContainer(div:string,visible:boolean,timer:number){
if(this.map){
setTimeout(()=>{
this.map.setDiv(div);
this.map.setVisible(visible);
if(this.reloadEvent==true) this.reloadMarkers().then(()=>this.reloadEvent=false);
},timer);
}
}
isLocationAware(){
return this.location.locationAware;
}
showUserLocation(fab: FabContainer){
this.location.getUserLocation().then(loc=>{
let userLocation=loc;
this.resetMapView(userLocation,fab);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment