Skip to content

Instantly share code, notes, and snippets.

@nguyenkiidu
Created September 18, 2018 16:39
Show Gist options
  • Save nguyenkiidu/3ade20dd3890088f01dec96a7db6d9c9 to your computer and use it in GitHub Desktop.
Save nguyenkiidu/3ade20dd3890088f01dec96a7db6d9c9 to your computer and use it in GitHub Desktop.
const earthRadius = 6371.0
async function getNearNannies(req, res, next) {
const params = req.query;
let nannies = []
let {lat, lon, distance} = req.body
lat = parseFloat(lat)
lon = parseFloat(lon)
distance = parseFloat(distance) || 1
const {swLat, swLon, neLat, neLon} = boundingBox(lat, lon, distance)
if (!lat || !lon || !distance) {
res.json({success: false, error: 'Missing params'})
} else {
await db.sequelize.query(`SELECT "User"."id", "User"."email", "User"."phone", "User"."first_name", "User"."last_name", "User"."avatar", "employee"."latitude" AS "latitude", "employee"."longitude" AS "longitude", ${earthRadius} * 2 * ASIN(SQRT(POWER(SIN(( ${lat} - employee.latitude) * PI() / 180 / 2), 2) + COS( ${lat} * PI() / 180) * COS(employee.latitude * PI() / 180) * POWER(SIN(( ${lon} - employee.longitude) * PI() / 180 / 2), 2))) AS distance FROM "users" AS "User" INNER JOIN "employees" AS "employee" ON "User"."id" = "employee"."user_id" AND "employee"."latitude" IS NOT NULL WHERE ( employee.latitude BETWEEN ${swLat} AND ${neLat} AND employee.longitude BETWEEN ${swLon} AND ${neLon} AND ( ${earthRadius} * 2 * ASIN(SQRT(POWER(SIN(( ${lat} - employee.latitude) * PI() / 180 / 2), 2) + COS( ${lat} * PI() / 180) * COS(employee.latitude * PI() / 180) * POWER(SIN(( ${lon} - employee.longitude) * PI() / 180 / 2), 2))) ) BETWEEN 0.0 AND ${distance} ) ORDER BY distance ASC`).spread((results, metadata) => {
results.map(user => {
nannies.push({
id: user.id,
email: user.email,
phone: user.phone,
first_name: user.first_name,
last_name: user.last_name,
avatar_url: `https://kiidu.s3-ap-southeast-1.amazonaws.com/uploads/user/avatar/${user.id}/${user.avatar}`,
latitude: user.latitude,
longitude: user.longitude,
distance: user.distance
})
})
})
res.json({success: true, length: nannies.length, nannies: nannies})
}
}
const boundingBox = (lat, lon, distance) => {
return {
swLat: lat - (distance / latitudeDegreeDistance()),
swLon: lon - (distance / longitudeDegreeDistance(lat)),
neLat: lat + (distance / latitudeDegreeDistance()),
neLon: lon + (distance / longitudeDegreeDistance(lat))
}
}
const latitudeDegreeDistance = () => {
return (2 * Math.PI * earthRadius / 360)
}
const longitudeDegreeDistance = (latitude) => {
return latitudeDegreeDistance() * Math.cos(toRadians(latitude))
}
const toRadians = (arg) => {
return (arg * (Math.PI / 180))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment