BETA Unlocked: Address Input!

//===== Init =====

var catCafesData = null;

export async function catCafes_ready() {

// Fetch Cat Cafes data once (it is static) and keep it in a global variable.

catCafesData = await getCatCafesData($w('#catCafes'));

// Set the default address to be the first Google Maps location, which is used as the placeholder for the visitor entered address.

let DEFAULT_VISITOR_ADDRESS = $w('#googleMaps1').location;

// Display distances of all Cat Cafes from this address and sort them by it.

displayDistances(DEFAULT_VISITOR_ADDRESS);
sortByDistance();
}

function getCatCafesData(catCafesDataset) {
return catCafesDataset.getItems(0, catCafesDataset.getPageSize())
.then((result) => {
return result.items;
})
}


//===== Event Handlers =====

export async function addressInput1_change(event) {
let address = $w('#addressInput1').value;
if (!address || !address.location) return;
viewAddressOnMap(address);
displayDistances(address.location);
sortByDistance();
}

//===== View address on Google Maps =====

function viewAddressOnMap(address) {
if (!address || !address.location) return;
$w("#googleMaps1").location = {
"latitude": address.location.latitude,
"longitude": address.location.longitude,
"description": address.formatted
};
}

//===== Display and sort Cat Cafes (Repeater items) by distance from an address =====

function displayDistances(addressLocation) {
let catCafeNameToDistance = catCafesData.reduce((map, item) => (map[item.title] = getDistanceFromLatLonInKm(addressLocation.latitude, addressLocation.longitude, item.address.location.lat, item.address.location.lng), map), {});

// Add the distance of the address from each Cat Cafe on the Repeater data. We will need if for sorting.

$w("#catCafesInfo").data = $w("#catCafesInfo").data.map((item) => { item['distance'] = catCafeNameToDistance[item.title]; return item });

// Update the distance text indication for each Repeater item.

$w("#catCafesInfo").forEachItem(($item, itemData, index) => {
$item("#catCafeDistance").text = itemData.distance.toFixed(2) + ' km';
});
}

function sortByDistance() {
$w("#catCafesInfo").data = $w("#catCafesInfo").data.sort(
function (item1, item2) {
let d1 = item1.distance;
let d2 = item2.distance;
if (d1 < d2) {
return -1;
}
if (d1 > d2) {
return 1;
}
return 0;
}
);
}

//===== Lat/lon distance calculations =====

// I simply copied it from: https://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula
 
function deg2rad(deg) {
return deg * (Math.PI / 180)
}

function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2 - lat1);
var dLon = deg2rad(lon2 - lon1);
var a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c; // Distance in km
return d;
}