Skip to content

Instantly share code, notes, and snippets.

@cormundo
Created May 1, 2018 02:52
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 cormundo/b7703bb55b8a74d19caa0ebf75c856cf to your computer and use it in GitHub Desktop.
Save cormundo/b7703bb55b8a74d19caa0ebf75c856cf to your computer and use it in GitHub Desktop.
// source https://jsbin.com
<title>Contractors</title>
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.css' rel='stylesheet'
<script src='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v2.0.1/mapbox-gl-geocoder.js'></script>
<link rel='stylesheet' href='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v2.0.1/mapbox-gl-geocoder.css' type='text/css' />
<script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>
<style>
body {
color: #404040;
font: 400 15px/22px 'Source Sans Pro', 'Helvetica Neue', Sans-serif;
margin: 0;
padding: 0;
-webkit-font-smoothing: antialiased;
}
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
h1 {
font-size: 22px;
margin: 0;
font-weight: 400;
line-height: 20px;
padding: 20px 2px;
}
a {
color: #404040;
text-decoration: none;
}
a:hover {
color: #101010;
}
.sidebar {
position: absolute;
width: 33.3333%;
height: 100%;
top: 0;
left: 0;
overflow: hidden;
border-right: 1px solid rgba(0, 0, 0, 0.25);
}
.pad2 {
padding: 0px;
}
.map {
position: absolute;
left: 33.3333%;
width: 66.6666%;
top: 0;
bottom: 0;
}
.heading {
background: #fff;
border-bottom: 1px solid #eee;
height: 60px;
line-height: 60px;
padding: 0 10px;
}
.listings {
height: 100%;
overflow: auto;
padding-bottom: 60px;
}
.listings .item {
display: block;
border-bottom: 1px solid #eee;
padding: 10px;
text-decoration: none;
}
.listings .item:last-child { border-bottom: none; }
.listings .item .title {
display: block;
color: #00853e;
font-weight: 700;
}
.listings .item .title small { font-weight: 400; }
.listings .item.active .title,
.listings .item .title:hover { color: #8cc63f; }
.listings .item.active {
background-color: #f8f8f8;
}
::-webkit-scrollbar {
width: 3px;
height: 3px;
border-left: 0;
background: rgba(0, 0, 0, 0.1);
}
::-webkit-scrollbar-track {
background: none;
}
::-webkit-scrollbar-thumb {
background: #00853e;
border-radius: 0;
}
.clearfix { display: block; }
.clearfix::after {
content: '.';
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.marker {
position: absolute;
cursor: pointer;
height: 20px;
width: 20px;
background-image: url('QCleaf3.png');
background-color: rgba(0, 0, 0, 0);
}
.mapboxgl-popup-close-button {
display: circle;
}
.mapboxgl-popup-content {
font: 400 15px/22px 'Source Sans Pro', 'Helvetica Neue', Sans-serif;
padding: 5;
width: 180px;
}
.mapboxgl-popup-content-wrapper {
padding: 5%;
}
.mapboxgl-popup-content h3 {
background: #3d8c51;
color: #d0f2cb;
margin: 1;
display: block;
padding: 15px;
border-radius: 5px 5px 5px 5px;
font-weight: 600;
margin-top: 0px;
}
.mapboxgl-popup-content h4 {
margin: 1;
display: block;
padding: 14px;
margin-top: 5px;
font-weight: 400;
background: #e1ede1;
}
.mapboxgl-popup-content div {
padding: 10px;
}
.mapboxgl-container .leaflet-marker-icon {
cursor: pointer;
}
.mapboxgl-popup-anchor-top > .mapboxgl-popup-content {
margin-top: 15px;
}
.mapboxgl-popup-anchor-top > .mapboxgl-popup-tip {
border-bottom-color: #91c949;
}
a:link {
color: black;
background-color: transparent;
text-decoration: none;
}
a:visited {
color: black;
background-color: transparent;
text-decoration: none;
}
a:hover {
color: black;
background-color: transparent;
text-decoration: underline;
}
a:active {
color: black;
background-color: transparent;
text-decoration: underline;
}
.mapboxgl-ctrl-geocoder {
border: 0;
border-radius: 0;
position: relative;
top: 0;
width: 800px;
margin-top: 0;
}
.mapboxgl-ctrl-geocoder > div {
min-width: 100%;
margin-left: 0;
}
</style>
<body>
<div class='sidebar'>
<div class='heading'>
<h1>Quiet Contractors</h1>
</div>
<div id='listings' class='listings'></div>
</div>
<div id='map' class='map pad2'>
</div>
<script>
if (!('remove' in Element.prototype)) {
Element.prototype.remove = function() {
if (this.parentNode) {
this.parentNode.removeChild(this);
}
};
}
mapboxgl.accessToken = 'pk.eyJ1IjoiY2RpY2tpbnNvbjExIiwiYSI6ImNqY3J6eDlscTBweHMycXMwcWltbnRiN3MifQ.X68p3M-5wwH3AudbxEYdfw';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/cdickinson11/cjg6j2hvr112u2rqgqfbdxpqg',
center: [-71.3039, 42.4259],
zoom: 8,
maxZoom: 11,
minZoom: 5,
cluster: true,
});
var stores = 'MasterDirectory_QC_V10.geojson';
map.on('load', function (e) {
map.addSource('places', {
type: 'geojson',
data: 'stores'
});
buildLocationList(stores);
var geocoder = new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
bbox: [-124.848974, 24.396308 , -66.885444, 49.384358]
});
map.addControl(geocoder, 'top-right');
map.addSource('single-point', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: []
}
});
map.addLayer({
id: 'point',
source: 'single-point',
type: 'circle',
paint: {
'circle-radius': 7,
'circle-color': '#00853e',
'circle-stroke-width': 3,
'circle-stroke-color': '#f2822d'
}
});
geocoder.on('result', function(ev) {
var searchResult = ev.result.geometry;
map.getSource('single-point').setData(searchResult);
var options = { units: 'miles' };
stores.features.forEach(function(store) {
Object.defineProperty(store.properties, 'distance', {
value: turf.distance(searchResult, store.geometry, options),
writable: true,
enumerable: true,
configurable: true
});
stores.features.sort(function(a, b) {
if (a.properties.distance > b.properties.distance) {
return 1;
}
if (a.properties.distance < b.properties.distance) {
return -1;
}
return 0;
});
var listings = document.getElementById('listings');
while (listings.firstChild) {
listings.removeChild(listings.firstChild);
}
function sortLonLat(storeIdentifier) {
var lats = [stores.features[storeIdentifier].geometry.coordinates[1], searchResult.coordinates[1]];
var lons = [stores.features[storeIdentifier].geometry.coordinates[0], searchResult.coordinates[0]];
var sortedLons = lons.sort(function(a, b) {
if (a > b) {
return 1;
}
if (a.distance < b.distance) {
return -1;
}
return 0;
});
var sortedLats = lats.sort(function(a, b) {
if (a > b) {
return 1;
}
if (a.distance < b.distance) {
return -1;
}
return 0;
});
map.fitBounds([
[sortedLons[0], sortedLats[0]],
[sortedLons[1], sortedLats[1]]
], {
padding: 100
});
}
sortLonLat(0);
createPopUp(stores.features[0]);
buildLocationList(stores);
});
});
});
stores.features.forEach(function(marker, i) {
var el = document.createElement('div');
el.id="marker-"+i;
el.className = 'marker';
el.collision = 'true';
new mapboxgl.Marker(el, { offset: [6, 15] })
.setLngLat(marker.geometry.coordinates)
.addTo(map);
el.addEventListener('click', function(e) {
var activeItem = document.getElementsByClassName('active');
flyToStore(marker);
createPopUp(marker);
e.stopPropagation();
if (activeItem[0]) {
activeItem[0].classList.remove('active');
}
var listing = document.getElementById('listing-' + i);
console.log(listing);
listing.classList.add('active');
});
});
function flyToStore(currentFeature) {
map.flyTo({
center: currentFeature.geometry.coordinates,
zoom: 11
});
}
function createPopUp(currentFeature) {
var popUps = document.getElementsByClassName('mapboxgl-popup');
if (popUps[0]) popUps[0].remove();
var popup = new mapboxgl.Popup({closeOnClick: false})
.setLngLat(currentFeature.geometry.coordinates)
.setHTML('<h3><a href=' + currentFeature.properties.URL2 + '>' + currentFeature.properties.Company + '</a></h4>'+ ' &middot; ' + currentFeature.properties.City + ", " + currentFeature.properties.State + '</p>' + ' &middot; ' + "Phone: " + currentFeature.properties.Phone + '</p>')
.addTo(map);
}
function buildLocationList(data) {
for (i = 0; i < data.features.length; i++) {
var currentFeature = data.features[i];
var prop = currentFeature.properties;
var listings = document.getElementById('listings');
var listing = listings.appendChild(document.createElement('div'));
listing.className = 'item';
listing.id = "listing-" + i;
var link = listing.appendChild(document.createElement('a'));
link.href = '#';
link.className = 'title';
link.dataPosition = i;
link.innerHTML = prop.Company;
var details = listing.appendChild(document.createElement('div'));
details.innerHTML = prop.City + ', ' + prop.State;
if (prop.Phone) {
details.innerHTML += ' &middot; ' + prop.Phone;
}
if (prop.distance) {
var roundedDistance = Math.round(prop.distance * 100) / 100;
details.innerHTML += '<p><strong>' + roundedDistance + ' miles away</strong></p>';
}
link.addEventListener('click', function(e) {
var clickedListing = data.features[this.dataPosition];
flyToStore(clickedListing);
createPopUp(clickedListing);
var activeItem = document.getElementsByClassName('active');
if (activeItem[0]) {
activeItem[0].classList.remove('active');
}
this.parentNode.classList.add('active');
});
}
}
</script>
<script id="jsbin-source-html" type="text/html"><title>Contractors</title>
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.js'><\/script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.css' rel='stylesheet'
<script src='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v2.0.1/mapbox-gl-geocoder.js'><\/script>
<link rel='stylesheet' href='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v2.0.1/mapbox-gl-geocoder.css' type='text/css' />
<script src='https://npmcdn.com/@turf/turf/turf.min.js'><\/script>
<style>
body {
color: #404040;
font: 400 15px/22px 'Source Sans Pro', 'Helvetica Neue', Sans-serif;
margin: 0;
padding: 0;
-webkit-font-smoothing: antialiased;
}
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
h1 {
font-size: 22px;
margin: 0;
font-weight: 400;
line-height: 20px;
padding: 20px 2px;
}
a {
color: #404040;
text-decoration: none;
}
a:hover {
color: #101010;
}
.sidebar {
position: absolute;
width: 33.3333%;
height: 100%;
top: 0;
left: 0;
overflow: hidden;
border-right: 1px solid rgba(0, 0, 0, 0.25);
}
.pad2 {
padding: 0px;
}
.map {
position: absolute;
left: 33.3333%;
width: 66.6666%;
top: 0;
bottom: 0;
}
.heading {
background: #fff;
border-bottom: 1px solid #eee;
height: 60px;
line-height: 60px;
padding: 0 10px;
}
.listings {
height: 100%;
overflow: auto;
padding-bottom: 60px;
}
.listings .item {
display: block;
border-bottom: 1px solid #eee;
padding: 10px;
text-decoration: none;
}
.listings .item:last-child { border-bottom: none; }
.listings .item .title {
display: block;
color: #00853e;
font-weight: 700;
}
.listings .item .title small { font-weight: 400; }
.listings .item.active .title,
.listings .item .title:hover { color: #8cc63f; }
.listings .item.active {
background-color: #f8f8f8;
}
::-webkit-scrollbar {
width: 3px;
height: 3px;
border-left: 0;
background: rgba(0, 0, 0, 0.1);
}
::-webkit-scrollbar-track {
background: none;
}
::-webkit-scrollbar-thumb {
background: #00853e;
border-radius: 0;
}
.clearfix { display: block; }
.clearfix::after {
content: '.';
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.marker {
position: absolute;
cursor: pointer;
height: 20px;
width: 20px;
background-image: url('QCleaf3.png');
background-color: rgba(0, 0, 0, 0);
}
.mapboxgl-popup-close-button {
display: circle;
}
.mapboxgl-popup-content {
font: 400 15px/22px 'Source Sans Pro', 'Helvetica Neue', Sans-serif;
padding: 5;
width: 180px;
}
.mapboxgl-popup-content-wrapper {
padding: 5%;
}
.mapboxgl-popup-content h3 {
background: #3d8c51;
color: #d0f2cb;
margin: 1;
display: block;
padding: 15px;
border-radius: 5px 5px 5px 5px;
font-weight: 600;
margin-top: 0px;
}
.mapboxgl-popup-content h4 {
margin: 1;
display: block;
padding: 14px;
margin-top: 5px;
font-weight: 400;
background: #e1ede1;
}
.mapboxgl-popup-content div {
padding: 10px;
}
.mapboxgl-container .leaflet-marker-icon {
cursor: pointer;
}
.mapboxgl-popup-anchor-top > .mapboxgl-popup-content {
margin-top: 15px;
}
.mapboxgl-popup-anchor-top > .mapboxgl-popup-tip {
border-bottom-color: #91c949;
}
a:link {
color: black;
background-color: transparent;
text-decoration: none;
}
a:visited {
color: black;
background-color: transparent;
text-decoration: none;
}
a:hover {
color: black;
background-color: transparent;
text-decoration: underline;
}
a:active {
color: black;
background-color: transparent;
text-decoration: underline;
}
.mapboxgl-ctrl-geocoder {
border: 0;
border-radius: 0;
position: relative;
top: 0;
width: 800px;
margin-top: 0;
}
.mapboxgl-ctrl-geocoder > div {
min-width: 100%;
margin-left: 0;
}
</style>
<body>
<div class='sidebar'>
<div class='heading'>
<h1>Quiet Contractors</h1>
</div>
<div id='listings' class='listings'></div>
</div>
<div id='map' class='map pad2'>
</div>
<script>
if (!('remove' in Element.prototype)) {
Element.prototype.remove = function() {
if (this.parentNode) {
this.parentNode.removeChild(this);
}
};
}
mapboxgl.accessToken = 'pk.eyJ1IjoiY2RpY2tpbnNvbjExIiwiYSI6ImNqY3J6eDlscTBweHMycXMwcWltbnRiN3MifQ.X68p3M-5wwH3AudbxEYdfw';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/cdickinson11/cjg6j2hvr112u2rqgqfbdxpqg',
center: [-71.3039, 42.4259],
zoom: 8,
maxZoom: 11,
minZoom: 5,
cluster: true,
});
var stores = 'MasterDirectory_QC_V10.geojson';
map.on('load', function (e) {
map.addSource('places', {
type: 'geojson',
data: 'stores'
});
buildLocationList(stores);
var geocoder = new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
bbox: [-124.848974, 24.396308 , -66.885444, 49.384358]
});
map.addControl(geocoder, 'top-right');
map.addSource('single-point', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: []
}
});
map.addLayer({
id: 'point',
source: 'single-point',
type: 'circle',
paint: {
'circle-radius': 7,
'circle-color': '#00853e',
'circle-stroke-width': 3,
'circle-stroke-color': '#f2822d'
}
});
geocoder.on('result', function(ev) {
var searchResult = ev.result.geometry;
map.getSource('single-point').setData(searchResult);
var options = { units: 'miles' };
stores.features.forEach(function(store) {
Object.defineProperty(store.properties, 'distance', {
value: turf.distance(searchResult, store.geometry, options),
writable: true,
enumerable: true,
configurable: true
});
stores.features.sort(function(a, b) {
if (a.properties.distance > b.properties.distance) {
return 1;
}
if (a.properties.distance < b.properties.distance) {
return -1;
}
return 0;
});
var listings = document.getElementById('listings');
while (listings.firstChild) {
listings.removeChild(listings.firstChild);
}
function sortLonLat(storeIdentifier) {
var lats = [stores.features[storeIdentifier].geometry.coordinates[1], searchResult.coordinates[1]];
var lons = [stores.features[storeIdentifier].geometry.coordinates[0], searchResult.coordinates[0]];
var sortedLons = lons.sort(function(a, b) {
if (a > b) {
return 1;
}
if (a.distance < b.distance) {
return -1;
}
return 0;
});
var sortedLats = lats.sort(function(a, b) {
if (a > b) {
return 1;
}
if (a.distance < b.distance) {
return -1;
}
return 0;
});
map.fitBounds([
[sortedLons[0], sortedLats[0]],
[sortedLons[1], sortedLats[1]]
], {
padding: 100
});
}
sortLonLat(0);
createPopUp(stores.features[0]);
buildLocationList(stores);
});
});
});
stores.features.forEach(function(marker, i) {
var el = document.createElement('div');
el.id="marker-"+i;
el.className = 'marker';
el.collision = 'true';
new mapboxgl.Marker(el, { offset: [6, 15] })
.setLngLat(marker.geometry.coordinates)
.addTo(map);
el.addEventListener('click', function(e) {
var activeItem = document.getElementsByClassName('active');
flyToStore(marker);
createPopUp(marker);
e.stopPropagation();
if (activeItem[0]) {
activeItem[0].classList.remove('active');
}
var listing = document.getElementById('listing-' + i);
console.log(listing);
listing.classList.add('active');
});
});
function flyToStore(currentFeature) {
map.flyTo({
center: currentFeature.geometry.coordinates,
zoom: 11
});
}
function createPopUp(currentFeature) {
var popUps = document.getElementsByClassName('mapboxgl-popup');
if (popUps[0]) popUps[0].remove();
var popup = new mapboxgl.Popup({closeOnClick: false})
.setLngLat(currentFeature.geometry.coordinates)
.setHTML('<h3><a href=' + currentFeature.properties.URL2 + '>' + currentFeature.properties.Company + '</a></h4>'+ ' &middot; ' + currentFeature.properties.City + ", " + currentFeature.properties.State + '</p>' + ' &middot; ' + "Phone: " + currentFeature.properties.Phone + '</p>')
.addTo(map);
}
function buildLocationList(data) {
for (i = 0; i < data.features.length; i++) {
var currentFeature = data.features[i];
var prop = currentFeature.properties;
var listings = document.getElementById('listings');
var listing = listings.appendChild(document.createElement('div'));
listing.className = 'item';
listing.id = "listing-" + i;
var link = listing.appendChild(document.createElement('a'));
link.href = '#';
link.className = 'title';
link.dataPosition = i;
link.innerHTML = prop.Company;
var details = listing.appendChild(document.createElement('div'));
details.innerHTML = prop.City + ', ' + prop.State;
if (prop.Phone) {
details.innerHTML += ' &middot; ' + prop.Phone;
}
if (prop.distance) {
var roundedDistance = Math.round(prop.distance * 100) / 100;
details.innerHTML += '<p><strong>' + roundedDistance + ' miles away</strong></p>';
}
link.addEventListener('click', function(e) {
var clickedListing = data.features[this.dataPosition];
flyToStore(clickedListing);
createPopUp(clickedListing);
var activeItem = document.getElementsByClassName('active');
if (activeItem[0]) {
activeItem[0].classList.remove('active');
}
this.parentNode.classList.add('active');
});
}
}
<\/script>
</body>
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment