Skip to content

Instantly share code, notes, and snippets.

@treighton
Created April 19, 2022 17:26
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 treighton/e009a268a5fd6a94d91486f944bc55bf to your computer and use it in GitHub Desktop.
Save treighton/e009a268a5fd6a94d91486f944bc55bf to your computer and use it in GitHub Desktop.
map example 2
import * as L from 'leaflet';
import * as EL from 'esri-leaflet';
/**
* Init function
*
* @return Map object
*/
const initMap = async () => {
if ( !document.querySelector( '#map' ) ) {
return;
}
const locationData = await getLocations();
const locations = buildLocationMarkers( locationData );
const locationsFeature = L.featureGroup( locations );
const topo = EL.basemapLayer( 'Topographic', { detectRetina: true } );
const map = buildMap( 'map', [topo, locationsFeature] );
const search = document.querySelector( '#search' );
search.addEventListener( 'click', e => handleSearch( e, locationsFeature ) );
return map;
};
/**
* Build Map
*
* @returns Map opbject
*/
const buildMap = ( mapEl, layers ) => {
return L.map( mapEl, {
layers: layers,
scrollWheelZoom: false,
dragging: true,
} ).setView( [37.0902, -95.7129], 4 );
};
/**
* Apply filters to layers
* @param {array} loations
*/
const applyFilters = ( locations, locationGroup ) => {
const newLocationMarkers = buildLocationMarkers( locations );
locationGroup.clearLayers();
locationGroup.addLayer( L.layerGroup( newLocationMarkers ) );
};
/**
* Get locations from fallback markup
*
* @return array of location objects
*/
const getLocations = async ( location ) => {
if ( !location ) {
try {
const locations = await fetch( '/wp-json/wp/v2/op-sales-rep' );
return await locations.json();
} catch {
return [];
}
} else {
const {lat, lng} = location;
const url = `/wp-json/wp/v2/op-sales-rep?lat=${lat()}&lng=${lng()}`;
try {
const locations = await fetch( url );
const locationJson = await locations.json();
return locationJson;
} catch {
return [];
}
}
};
/**
* build location markers
*
* @return array of location markers
*/
const buildLocationMarkers = ( locations ) =>
locations.map( ( location ) => {
if ( location.latitude && location.longitude ) {
return L.marker( [location.latitude, location.longitude] ).bindPopup( `
<div class="location-details">
${ location.title.rendered
? `<p class="title">${location.title.rendered}</p>`
: '' }
${ location.address
? `<p class="address">${location.address}</p>`
: '' }
<p><strong>Service Center Contact:</strong></p>
<ul>
${ location.contact_name
? `<li class="name">${location.contact_name}</li>`
: '' }
${ location.phone_number
? `<li class="phone">Phone: <a href="tel:+1${location.phone_number.replace( /[\s-]+/g, '' )}">${location.phone_number}</a></li>`
: '' }
${ location.description
? `<li class="desc">${location.description}</li>`
: '' }
</ul>
</div>
` );
}
} );
/**
* Handle Search
*
* @returns void
*/
const handleSearch = async ( e, locationsFeature ) => {
e.preventDefault();
const search = e.target.parentElement;
const address = search.querySelector( '#address' ).value;
const radius = parseInt( search.querySelector( '#radius' ).value ) || 100;
const locationCount = document.querySelector( '.location-count' );
try {
const geocodedAddress = await geocodeSearch( address );
const locations = await getLocations( geocodedAddress );
const filteredLocations = locations.filter( ( {distance} ) => {
const withInRadius = parseFloat( distance.replace( ',', '' ) ) <= radius;
return withInRadius;
} );
applyFilters( filteredLocations, locationsFeature );
document.activeElement.blur();
locationCount.innerHTML = `${filteredLocations.length} Locations Found`;
} catch ( error ) {
document.activeElement.blur();
locationCount.innerHTML = 'Something went wrong, please double check your search criteria.';
}
};
/**
* Gecode searched address
* @param {string} address
* @returns object or null
*/
const geocodeSearch = async ( address ) => {
// Google defined globally
// eslint-disable-next-line no-undef
const geocoder = new google.maps.Geocoder();
const { results } = await geocoder.geocode( { address: address } );
if ( results.length ) {
return results[0].geometry.location;
}
return null;
};
initMap();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment