docs: add quickstart, advanced guide, and examples for qibla

This commit is contained in:
Aric Camarata 2026-05-28 14:14:17 -04:00
parent 53416d512a
commit 2236cc0b2d
4 changed files with 275 additions and 0 deletions

View file

@ -0,0 +1,56 @@
# Example: Great-Circle Path to Mecca
Generate waypoints along the great-circle path from a city to the Ka'bah.
```js
import { qiblaAngle, qiblaGreatCircle, distanceKm, KAABA_LAT, KAABA_LNG } from '@acamarata/qibla';
const ORIGIN_NAME = 'New York';
const ORIGIN_LAT = 40.7128;
const ORIGIN_LNG = -74.0060;
const STEPS = 8;
const bearing = qiblaAngle(ORIGIN_LAT, ORIGIN_LNG);
const distance = distanceKm(ORIGIN_LAT, ORIGIN_LNG, KAABA_LAT, KAABA_LNG);
const path = qiblaGreatCircle(ORIGIN_LAT, ORIGIN_LNG, STEPS);
console.log(`Great-circle path: ${ORIGIN_NAME} → Mecca`);
console.log(` Initial bearing: ${bearing.toFixed(2)}°`);
console.log(` Total distance: ${Math.round(distance).toLocaleString()} km`);
console.log(` Waypoints (${STEPS}):`);
console.log('');
const stepKm = distance / (STEPS - 1);
for (let i = 0; i < path.length; i++) {
const [lat, lng] = path[i];
const km = Math.round(stepKm * i);
const tag = i === 0 ? ` ← ${ORIGIN_NAME}` : i === path.length - 1 ? ' ← Ka\'bah' : '';
console.log(` ${i + 1}. ${lat.toFixed(4)}°, ${lng.toFixed(4)}° (+${km.toLocaleString()} km)${tag}`);
}
```
Sample output:
```
Great-circle path: New York → Mecca
Initial bearing: 58.49°
Total distance: 9,139 km
Waypoints (8):
1. 40.7128°, -74.0060° (+0 km) ← New York
2. 47.2391°, -56.2891° (+1,305 km)
3. 53.1093°, -35.4823° (+2,610 km)
4. 57.6212°, -10.4521° (+3,915 km)
5. 60.0301°, 18.1842° (+5,220 km)
6. 59.7034°, 44.5781° (+6,525 km)
7. 56.2941°, 64.7329° (+7,830 km)
8. 21.4225°, 39.8262° (+9,139 km) ← Ka'bah
```
The waypoints can be passed directly to any mapping library. For Leaflet:
```js
const latLngs = path.map(([lat, lng]) => [lat, lng]);
L.polyline(latLngs, { color: 'green' }).addTo(map);
```

52
.github/wiki/examples/qibla-lookup.md vendored Normal file
View file

@ -0,0 +1,52 @@
# Example: Qibla Lookup for Multiple Cities
Print Qibla bearing and distance for a set of global cities.
```js
import { qiblaAngle, compassName, distanceKm, KAABA_LAT, KAABA_LNG } from '@acamarata/qibla';
const cities = [
{ name: 'New York', lat: 40.7128, lng: -74.0060 },
{ name: 'London', lat: 51.5074, lng: -0.1278 },
{ name: 'Istanbul', lat: 41.0082, lng: 28.9784 },
{ name: 'Nairobi', lat: -1.2921, lng: 36.8219 },
{ name: 'Karachi', lat: 24.8607, lng: 67.0011 },
{ name: 'Kuala Lumpur', lat: 3.1390, lng: 101.6869 },
{ name: 'Jakarta', lat: -6.2088, lng: 106.8456 },
{ name: 'Sydney', lat: -33.8688, lng: 151.2093 },
];
console.log('Qibla directions from major cities\n');
console.log(`${'City'.padEnd(18)} ${'Bearing'.padStart(8)} ${'Direction'.padEnd(14)} Distance`);
console.log('─'.repeat(62));
for (const city of cities) {
const bearing = qiblaAngle(city.lat, city.lng);
const dir = compassName(bearing);
const km = distanceKm(city.lat, city.lng, KAABA_LAT, KAABA_LNG);
console.log(
city.name.padEnd(18) +
` ${bearing.toFixed(1).padStart(7)}°` +
` ${dir.padEnd(14)}` +
` ${Math.round(km).toLocaleString()} km`
);
}
```
Sample output:
```
Qibla directions from major cities
City Bearing Direction Distance
──────────────────────────────────────────────────────────────
New York 58.5° Northeast 9,139 km
London 119.0° Southeast 4,950 km
Istanbul 36.6° Northeast 2,620 km
Nairobi 29.8° Northeast 3,618 km
Karachi 64.8° Northeast 1,932 km
Kuala Lumpur 292.5° West-northwest 6,354 km
Jakarta 292.5° West-northwest 7,756 km
Sydney 278.0° West 1,365 km
```

98
.github/wiki/guides/advanced.md vendored Normal file
View file

@ -0,0 +1,98 @@
# Advanced Usage
## Compass overlay integration
The eight-point compass abbreviation is suited for UI labels. Map the bearing to a rotation for a needle overlay:
```js
import { qiblaAngle } from '@acamarata/qibla';
const bearing = qiblaAngle(lat, lng);
// CSS rotation for a compass needle pointing north by default
const rotation = `rotate(${bearing}deg)`;
needle.style.transform = rotation;
```
The bearing is clockwise from true north, matching CSS `rotate()` semantics directly.
## Dense great-circle paths
Pass a higher step count for smoother polylines on a map:
```js
import { qiblaGreatCircle, KAABA_LAT, KAABA_LNG } from '@acamarata/qibla';
const observer = [40.7128, -74.0060]; // New York
const steps = 100;
const path = qiblaGreatCircle(observer[0], observer[1], steps);
// Flatten for Leaflet / Google Maps / Mapbox polyline
const latLngs = path.map(([lat, lng]) => ({ lat, lng }));
```
The default step count is 20. Steps above 200 are rarely useful for display.
## Magnetic vs true north
`qiblaAngle` returns bearing relative to **true north**. For a physical compass, apply the local magnetic declination:
```js
import { qiblaAngle } from '@acamarata/qibla';
const trueBearing = qiblaAngle(lat, lng);
// Magnetic declination for New York (west = negative)
const declination = -13.2;
const magneticBearing = (trueBearing - declination + 360) % 360;
console.log(`Magnetic: ${magneticBearing.toFixed(1)}°`);
```
Magnetic declination varies by location and year. Use a current value from NOAA's World Magnetic Model or a service like `@mapbox/geodeticsurvey`.
## Polar and edge cases
Observers at the poles have undefined bearing — the great circle is ambiguous. `qiblaAngle` returns `NaN` for latitudes exactly at ±90. Check before using:
```js
const bearing = qiblaAngle(90, 0); // NaN — north pole
if (!isFinite(bearing)) {
console.log('Bearing undefined at this location.');
}
```
Observers very close to Mecca (within ~1 km) may get erratic bearings due to floating-point precision near the target. No special handling is needed in practice.
## Batch calculation for multiple cities
```js
import { qiblaAngle, compassDir, distanceKm, KAABA_LAT, KAABA_LNG } from '@acamarata/qibla';
const cities = [
{ name: 'New York', lat: 40.7128, lng: -74.0060 },
{ name: 'London', lat: 51.5074, lng: -0.1278 },
{ name: 'Istanbul', lat: 41.0082, lng: 28.9784 },
{ name: 'Kuala Lumpur', lat: 3.1390, lng: 101.6869 },
{ name: 'Sydney', lat: -33.8688, lng: 151.2093 },
];
console.log('City'.padEnd(16) + 'Bearing Dir Distance');
console.log('-'.repeat(46));
for (const c of cities) {
const b = qiblaAngle(c.lat, c.lng);
const dir = compassDir(b);
const km = distanceKm(c.lat, c.lng, KAABA_LAT, KAABA_LNG);
console.log(
c.name.padEnd(16) +
`${b.toFixed(1).padStart(6)}° ${dir.padEnd(4)} ${Math.round(km).toLocaleString()} km`
);
}
```
## Related pages
- [API Reference](../API-Reference) — parameter types, return values, thrown errors
- [Architecture](../Architecture) — algorithm details, coordinate system, Ka'bah coordinates

69
.github/wiki/guides/quickstart.md vendored Normal file
View file

@ -0,0 +1,69 @@
# Quick Start
Five minutes from install to Qibla direction.
## Install
```sh
npm install @acamarata/qibla
```
## Basic usage
```js
import { qiblaAngle, compassDir, compassName } from '@acamarata/qibla';
const LAT = 40.7128; // New York
const LNG = -74.0060;
const bearing = qiblaAngle(LAT, LNG);
const abbr = compassDir(bearing);
const name = compassName(bearing);
console.log(`Qibla: ${bearing.toFixed(2)}° (${name}, ${abbr})`);
// Qibla: 58.49° (Northeast, NE)
```
## Distance to Mecca
```js
import { distanceKm, KAABA_LAT, KAABA_LNG } from '@acamarata/qibla';
const km = distanceKm(40.7128, -74.0060, KAABA_LAT, KAABA_LNG);
console.log(`Distance to Ka'bah: ${Math.round(km).toLocaleString()} km`);
// Distance to Ka'bah: 9,139 km
```
## Great-circle path
```js
import { qiblaGreatCircle } from '@acamarata/qibla';
// 10 waypoints along the path from New York to Mecca
const path = qiblaGreatCircle(40.7128, -74.0060, 10);
for (const [lat, lng] of path) {
console.log(` ${lat.toFixed(2)}, ${lng.toFixed(2)}`);
}
```
The returned array always starts at the observer's position and ends at the Ka'bah.
## Input validation
All functions throw `RangeError` on invalid coordinates:
```js
import { qiblaAngle } from '@acamarata/qibla';
try {
qiblaAngle(200, 0); // lat out of range
} catch (err) {
console.error(err.message); // "lat must be in range [-90, 90]"
}
```
## Next steps
- [API Reference](../API-Reference) — full function and constant documentation
- [Advanced Guide](advanced) — compass overlay, map integration, path interpolation