Skip to content

Instantly share code, notes, and snippets.

@andrewtkemp
Created October 13, 2016 15:36
Show Gist options
  • Save andrewtkemp/dbbf17a995ab661dc58a09db59ddaa42 to your computer and use it in GitHub Desktop.
Save andrewtkemp/dbbf17a995ab661dc58a09db59ddaa42 to your computer and use it in GitHub Desktop.
var $ = require('jquery');
window.jQuery = $;
// Headroom = require('democracyos-headroom.js');
var mapInfo = require('./mapinfo');
var _ = require('lodash');
var Vue = require('vue');
var VueFilter = require('vue-filter');
Vue.use(VueFilter);
var GoogleMapsLoader = require('google-maps'); // only for common js environments
GoogleMapsLoader.KEY = 'AIzaSyCLfPbx0v09vJhYEc35uijGZJ1Rd0C9tGo';
GoogleMapsLoader.LIBRARIES = ['geometry', 'places'];
var geolocator = require('geolocator');
var service;
var points;
var map;
var markers = [];
var infoWindows = [];
var locationsURL = "../api/locations";
geolocator.config({
language: "en",
google: {
version: "3",
key: " AIzaSyCLfPbx0v09vJhYEc35uijGZJ1Rd0C9tGo",
}
});
var locateOptions = {
enableHighAccuracy: true,
timeout: 6000,
maximumAge: 0,
desiredAccuracy: 30,
fallbackToIP: true, // fallback to IP if Geolocation fails or rejected
addressLookup: true,
timezone: true,
https: false
};
Vue.component('locations', {
template: '#location',
data: function () {
return {
name: '',
location: '',
zip: '',
state: '',
locationList: [],
distanceList: [],
searchQuery: '',
currentPage: 0,
itemsPerPage: 10,
resultCount: 0,
stateAbbr: '',
distance: 25,
firstCalculationDone: false,
currentLocationLat: null,
currentLocationLon: null,
currentLocation: null,
}
},
ready: function () {
this.createBaseMap();
this.fetchLocations();
//$('#state-buttons').on('click',this.getLocationsByState)
},
methods: {
size(value) {
return _.size(value);
},
updateMessage: function () {
this.location = myLocation;
console.log(this.$el.textContent) // => 'not updated'
this.$nextTick(function () {
console.log(this.$el.textContent) // => 'updated'
})
},
getDirections: function () {
console.log("itemLocation");
},
setPage: function (pageNumber) {
this.currentPage = pageNumber
},
isCurrentPage: function (pageNumber) {
return this.currentPage === pageNumber
},
filterState: function (filter) {
this.state = filter
},
createBaseMap: function () {
markers = [];
geolocator.locate(locateOptions, function (err, location) {
if (err) {
return console.log(err);
} else {
this.setCurrentLocation(location);
this.calculateDistances();
this.setDistanceListByDistance();
this.showMap();
}
}.bind(this));
},
showMap: function () {
GoogleMapsLoader.load(function (google) {
var defaultPin = mapInfo.locationPin('black', 'white');
var myPin = mapInfo.centerPin('red', 'red');
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: this.currentLocationLat,
lng: this.currentLocationLon
},
zoom: 10,
styles: mapInfo.mapStyles,
scrollwheel: false,
navigationControl: false,
mapTypeControl: false,
scaleControl: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
markers = [];
infoWindows = [];
let bounds = new google.maps.LatLngBounds();
this.distanceList.forEach(location=> {
if (location.address_info[0].latitude && location.address_info[0].longitude) {
let latLng = new google.maps.LatLng({
lat: parseFloat(location.address_info[0].latitude),
lng: parseFloat(location.address_info[0].longitude)
});
bounds.extend(latLng);
let addedInfo = new google.maps.InfoWindow({content: this.makeInfo(location)});
let addedMarker = new google.maps.Marker({
position: latLng,
map: map,
title: location.title,
icon: defaultPin
});
infoWindows.push(addedInfo);
markers.push(addedMarker);
addedMarker.addListener('click', function () {
addedInfo.open(map, addedMarker);
});
}
});
if (this.state) {
let boundsCenter = bounds.getCenter();
this.setCurrentLocation({coords:{latitude: boundsCenter.lat(), longitude: boundsCenter.lng()}});
this.setDistanceListByState();
map.setCenter(boundsCenter);
}
let latLng = new google.maps.LatLng({
lat: parseFloat(this.currentLocationLat),
lng: parseFloat(this.currentLocationLon)
});
bounds.extend(latLng);
markers.push(new google.maps.Marker({
position: latLng,
map: map,
icon: myPin
}));
map.fitBounds(bounds);
}.bind(this));
},
makeInfo: function (locationData) {
return `
<div class="info-window">
<p>${locationData.title} - ${locationData.address_info[0].city}</p>
<hr>
<p>${locationData.address_info[0].address}, ${locationData.address_info[0].city} ${locationData.address_info[0].state_province} ${locationData.address_info[0].zip}</p>
<p>Phone: ${locationData.address_info[0].phone}</p>
<p>Hours: ${locationData.hours}</p>
</div>
`;
},
fetchLocations: function () {
if (0 == this.locationList.length) {
$.getJSON(locationsURL, function (locations) {
this.locationList = _.cloneDeep(locations.entries);
this.calculateDistances();
this.setDistanceListByDistance();
this.showMap();
}.bind(this)).error(function () {
console.log('There was a problem loading locations');
});
}
},
setCurrentLocation: function (location) {
this.currentLocation = location.coords;
this.currentLocationLon = location.coords.longitude;
this.currentLocationLat = location.coords.latitude;
this.calculateDistances();
$('.location-results').addClass('slideResultsIn');
},
locateAddress: function (addressVal) {
if (addressVal.length >= 5) {
geolocator.geocode(addressVal, function (err, location) {
if (err) {
return console.log(err);
} else {
this.setCurrentLocation(location);
this.setDistanceListByDistance();
this.showMap();
}
}.bind(this));
}
},
calcLocationDistanceInMiles: function (locationLat, locationLon) {
let radlat1 = Math.PI * this.currentLocationLat / 180;
let radlat2 = Math.PI * locationLat / 180;
let theta = this.currentLocationLon - locationLon;
let radtheta = Math.PI * theta / 180;
let distance = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
distance = Math.acos(distance);
distance = distance * 180 / Math.PI;
distance = distance * 60 * 1.1515;
return distance;
},
calculateDistances: function () {
if (0 < this.locationList.length && this.currentLocationLat && this.currentLocationLon) {
this.locationList.forEach(location => location.distance = this.calcLocationDistanceInMiles(location.address_info[0].latitude, location.address_info[0].longitude));
this.firstCalculationDone = true;
}
},
setDistanceListByDistance: function () {
let newList = this.locationList.filter(location=>location.distance <= this.distance);
this.distanceList = [];
newList.forEach(location=> {
this.distanceList.push(location);
});
},
setDistanceListByState: function(){
let newList = this.locationList.filter(location=>location.address_info[0].state_province == this.state);
this.distanceList = [];
newList.forEach(location=> {
this.distanceList.push(location);
});
},
changeState: function (state) {
this.state = state;
this.zip = '';
geolocator.geocode(this.state, function (err, location) {
if (err) {
return console.log(err);
} else {
this.setCurrentLocation(location);
if(this.state=='DC'){
this.setDistanceListByDistance();
} else {
this.setDistanceListByState();
}
this.showMap();
}
}.bind(this));
}
},
watch: {
'zip': function (val) {
if (5 <= val.length) {
this.state = '';
this.locateAddress(this.zip);
}
},
'distance': function (val) {
this.setDistanceListByDistance();
this.showMap();
},
},
computed: {
totalPages: function () {
return Math.ceil(this.resultCount / this.itemsPerPage)
},
thereAreNoLocations: function () {
return !this.distanceList.length && this.firstCalculationDone;
}
},
filters: {
paginate: function (list) {
this.resultCount = list.length
if (this.currentPage >= this.totalPages) {
this.currentPage = Math.max(0, this.totalPages - 1)
}
var index = this.currentPage * this.itemsPerPage
return list.slice(index, index + this.itemsPerPage)
}
}
})
if ($('.collection').length) {
window.Vue = Vue;
var vw = window.vw = new Vue({
el: '.collection',
});
Vue.config.devtools = true;
Vue.config.debug = true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment