Skip to content

Geospatial Operators โ€‹

Location-based filtering with powerful spatial operators for proximity search, bounding boxes, and polygon containment.

Interactive Playground ๐ŸŽฎ โ€‹

Try geospatial operators live with real Buenos Aires data! Click the map, adjust controls, and see real-time filtering.

๐Ÿ“Š Filtered Results

91/ 128(71.1%)
#1La Cabrera
rating:4.8
cuisine:Argentinian
priceLevel:3
๐Ÿ“ -34.5765, -58.4267
#2Don Julio
rating:4.9
cuisine:Argentinian
priceLevel:4
๐Ÿ“ -34.5798, -58.4245
#3Sushi Club
rating:4.5
cuisine:Japanese
priceLevel:2
๐Ÿ“ -34.5789, -58.4289
#4Cucina Paradiso
rating:4.6
cuisine:Italian
priceLevel:3
๐Ÿ“ -34.5756, -58.4212
#5Kansas
rating:4.3
cuisine:American
priceLevel:2
๐Ÿ“ -34.5823, -58.4301
#6El Preferido de Palermo
rating:4.7
cuisine:Argentinian
priceLevel:2
๐Ÿ“ -34.5834, -58.4256
#7Proper
rating:4.4
cuisine:American
priceLevel:3
๐Ÿ“ -34.5712, -58.4198
#8Osaka
rating:4.5
cuisine:Japanese
priceLevel:4
๐Ÿ“ -34.5845, -58.4167
#9La Carnicerรญa
rating:4.7
cuisine:Argentinian
priceLevel:3
๐Ÿ“ -34.5812, -58.4278
#10Chori
rating:4.4
cuisine:Argentinian
priceLevel:1
๐Ÿ“ -34.5891, -58.4334
#11Taco Box
rating:4.2
cuisine:Mexican
priceLevel:2
๐Ÿ“ -34.5778, -58.4189
#12La Bistecca
rating:4.6
cuisine:Italian
priceLevel:3
๐Ÿ“ -34.5723, -58.4156
#13Sipan
rating:4.5
cuisine:Japanese
priceLevel:3
๐Ÿ“ -34.5867, -58.4112
#14Burger Joint
rating:4.1
cuisine:American
priceLevel:2
๐Ÿ“ -34.5845, -58.4289
#15Mishiguene
rating:4.8
cuisine:Argentinian
priceLevel:3
๐Ÿ“ -34.5801, -58.4223
#16Pizza Cero
rating:4.3
cuisine:Italian
priceLevel:2
๐Ÿ“ -34.5756, -58.4289
#17Gran Dabbang
rating:4.6
cuisine:Japanese
priceLevel:3
๐Ÿ“ -34.5889, -58.4267
#18Tegui
rating:4.9
cuisine:Argentinian
priceLevel:4
๐Ÿ“ -34.5834, -58.4312
#19Crizia
rating:4.7
cuisine:Italian
priceLevel:3
๐Ÿ“ -34.5812, -58.4198
#20Fayer
rating:4.5
cuisine:Mexican
priceLevel:2
๐Ÿ“ -34.5867, -58.4256
#21Parrilla Peรฑa
rating:4.4
cuisine:Argentinian
priceLevel:2
๐Ÿ“ -34.5745, -58.4234
#22Kuuraku
rating:4.6
cuisine:Japanese
priceLevel:3
๐Ÿ“ -34.5823, -58.4178
#23Nola
rating:4.3
cuisine:American
priceLevel:2
๐Ÿ“ -34.5778, -58.4312
#24La Mar
rating:4.7
cuisine:Japanese
priceLevel:4
๐Ÿ“ -34.5698, -58.4156
#25Parilla Don Ignacio
rating:4.5
cuisine:Argentinian
priceLevel:2
๐Ÿ“ -34.5856, -58.4223
#26Ninina Bakery
rating:4.4
cuisine:Italian
priceLevel:1
๐Ÿ“ -34.5790, -58.4145
#27La Cabaรฑa Porteรฑo
rating:3.7
cuisine:American
priceLevel:3
๐Ÿ“ -34.5889, -58.4373
#28El Buen Argentino
rating:4.7
cuisine:Argentinian
priceLevel:2
๐Ÿ“ -34.5643, -58.4224
#29Parrilla Premium
rating:4.1
cuisine:Thai
priceLevel:1
๐Ÿ“ -34.5735, -58.4068
#30Parrilla Colonial
rating:4.6
cuisine:Thai
priceLevel:3
๐Ÿ“ -34.5896, -58.4150
#31La Estancia Gourmet
rating:4
cuisine:Indian
priceLevel:2
๐Ÿ“ -34.5806, -58.4069
#32El Novillo Porteรฑo
rating:4.2
cuisine:Argentinian
priceLevel:1
๐Ÿ“ -34.5671, -58.4342
#33Parrilla Premium
rating:3.7
cuisine:Thai
priceLevel:2
๐Ÿ“ -34.5694, -58.4199
#34Parrilla Premium
rating:4.6
cuisine:Chinese
priceLevel:1
๐Ÿ“ -34.5671, -58.4402
#35El Viejo Colonial
rating:4.7
cuisine:Italian
priceLevel:4
๐Ÿ“ -34.5654, -58.4408
#36Casa de de la Plaza
rating:4.3
cuisine:Japanese
priceLevel:2
๐Ÿ“ -34.5620, -58.4357
#37Rincรณn Argentino
rating:4.6
cuisine:Spanish
priceLevel:4
๐Ÿ“ -34.5653, -58.4327
#38El Viejo Premium
rating:4.8
cuisine:Mexican
priceLevel:3
๐Ÿ“ -34.5606, -58.4279
#39El Palacio Gourmet
rating:3.6
cuisine:Chinese
priceLevel:4
๐Ÿ“ -34.5695, -58.4137
#40La Estancia Tradicional
rating:4.7
cuisine:Indian
priceLevel:4
๐Ÿ“ -34.5772, -58.4444
#41El Novillo de Palermo
rating:3.7
cuisine:Argentinian
priceLevel:1
๐Ÿ“ -34.5820, -58.4447
#42El Buen Gourmet
rating:4.8
cuisine:Italian
priceLevel:2
๐Ÿ“ -34.5672, -58.4213
#43El Buen Premium
rating:3.8
cuisine:Argentinian
priceLevel:3
๐Ÿ“ -34.5774, -58.4447
#44La Cabaรฑa Porteรฑo
rating:4.9
cuisine:Japanese
priceLevel:1
๐Ÿ“ -34.5809, -58.4178
#45Rincรณn Premium
rating:4.9
cuisine:Thai
priceLevel:1
๐Ÿ“ -34.5870, -58.4397
#46El Novillo de la Plaza
rating:4.1
cuisine:Indian
priceLevel:2
๐Ÿ“ -34.5719, -58.4372
#47El Novillo Colonial
rating:5
cuisine:American
priceLevel:1
๐Ÿ“ -34.5745, -58.4452
#48Casa de del Barrio
rating:3.9
cuisine:Mexican
priceLevel:1
๐Ÿ“ -34.5906, -58.4182
#49La Estancia Porteรฑo
rating:4.9
cuisine:Italian
priceLevel:4
๐Ÿ“ -34.5614, -58.4241
#50La Estancia Premium
rating:3.6
cuisine:Chinese
priceLevel:3
๐Ÿ“ -34.5821, -58.4429
#51Casa de Tradicional
rating:4.1
cuisine:Mexican
priceLevel:3
๐Ÿ“ -34.5614, -58.4331
#52La Estancia Porteรฑo
rating:4.7
cuisine:Indian
priceLevel:1
๐Ÿ“ -34.5893, -58.4264
#53El Novillo del Centro
rating:4.3
cuisine:Chinese
priceLevel:3
๐Ÿ“ -34.5712, -58.4328
#54El Palacio de Palermo
rating:4.8
cuisine:Argentinian
priceLevel:1
๐Ÿ“ -34.5839, -58.4121
#55El Palacio Gourmet
rating:3.6
cuisine:Mexican
priceLevel:3
๐Ÿ“ -34.5755, -58.4086
#56El Buen de Palermo
rating:4.4
cuisine:Chinese
priceLevel:3
๐Ÿ“ -34.5796, -58.4231
#57El Viejo Premium
rating:4.5
cuisine:Italian
priceLevel:2
๐Ÿ“ -34.5751, -58.4171
#58Don Premium
rating:4.1
cuisine:American
priceLevel:4
๐Ÿ“ -34.5775, -58.4053
#59El Novillo Argentino
rating:4
cuisine:Chinese
priceLevel:2
๐Ÿ“ -34.5871, -58.4383
#60El Palacio Gourmet
rating:3.7
cuisine:French
priceLevel:3
๐Ÿ“ -34.5873, -58.4283
#61La Cabaรฑa de la Plaza
rating:4.4
cuisine:French
priceLevel:3
๐Ÿ“ -34.5890, -58.4266
#62El Palacio Premium
rating:4.6
cuisine:Japanese
priceLevel:4
๐Ÿ“ -34.5904, -58.4162
#63El Buen de la Plaza
rating:4.9
cuisine:American
priceLevel:4
๐Ÿ“ -34.5661, -58.4170
#64La Cabaรฑa Colonial
rating:3.8
cuisine:American
priceLevel:1
๐Ÿ“ -34.5752, -58.4137
#65Parrilla Tradicional
rating:3.8
cuisine:Japanese
priceLevel:4
๐Ÿ“ -34.5891, -58.4263
#66El Buen de la Plaza
rating:4.3
cuisine:Japanese
priceLevel:3
๐Ÿ“ -34.5843, -58.4163
#67El Novillo Argentino
rating:4.4
cuisine:Spanish
priceLevel:2
๐Ÿ“ -34.5867, -58.4288
#68Casa de Porteรฑo
rating:4.5
cuisine:American
priceLevel:4
๐Ÿ“ -34.5952, -58.4265
#69Don Premium
rating:4
cuisine:Spanish
priceLevel:1
๐Ÿ“ -34.5677, -58.4095
#70El Viejo de la Plaza
rating:3.7
cuisine:American
priceLevel:1
๐Ÿ“ -34.5857, -58.4266
#71Parrilla Porteรฑo
rating:4
cuisine:Italian
priceLevel:2
๐Ÿ“ -34.5764, -58.4211
#72Don Colonial
rating:4.1
cuisine:French
priceLevel:1
๐Ÿ“ -34.5794, -58.4052
#73El Viejo Premium
rating:4
cuisine:Thai
priceLevel:3
๐Ÿ“ -34.5705, -58.4421
#74El Buen Tradicional
rating:3.6
cuisine:Thai
priceLevel:1
๐Ÿ“ -34.5795, -58.4207
#75La Estancia Argentino
rating:4.1
cuisine:Argentinian
priceLevel:1
๐Ÿ“ -34.5673, -58.4149
#76El Viejo de Palermo
rating:4.8
cuisine:American
priceLevel:2
๐Ÿ“ -34.5892, -58.4330
#77Parrilla Tradicional
rating:4
cuisine:Thai
priceLevel:3
๐Ÿ“ -34.5787, -58.4316
#78El Palacio de Palermo
rating:3.9
cuisine:Italian
priceLevel:2
๐Ÿ“ -34.5647, -58.4126
#79Rincรณn Premium
rating:4
cuisine:French
priceLevel:1
๐Ÿ“ -34.5646, -58.4347
#80El Buen Premium
rating:4.7
cuisine:Thai
priceLevel:3
๐Ÿ“ -34.5757, -58.4342
#81El Palacio Porteรฑo
rating:3.6
cuisine:Mexican
priceLevel:4
๐Ÿ“ -34.5600, -58.4274
#82Parrilla Tradicional
rating:4.8
cuisine:Argentinian
priceLevel:1
๐Ÿ“ -34.5605, -58.4321
#83El Palacio de Palermo
rating:3.9
cuisine:Chinese
priceLevel:3
๐Ÿ“ -34.5920, -58.4269
#84Casa de Porteรฑo
rating:4.2
cuisine:Italian
priceLevel:1
๐Ÿ“ -34.5768, -58.4232
#85Casa de del Barrio
rating:4.3
cuisine:Thai
priceLevel:3
๐Ÿ“ -34.5778, -58.4431
#86Don del Barrio
rating:4
cuisine:Mexican
priceLevel:3
๐Ÿ“ -34.5684, -58.4332
#87El Palacio de la Plaza
rating:4.8
cuisine:Indian
priceLevel:2
๐Ÿ“ -34.5843, -58.4129
#88La Estancia Colonial
rating:4.4
cuisine:Argentinian
priceLevel:4
๐Ÿ“ -34.5611, -58.4230
#89La Cabaรฑa del Barrio
rating:5
cuisine:Japanese
priceLevel:4
๐Ÿ“ -34.5671, -58.4229
#90Rincรณn Premium
rating:3.6
cuisine:Mexican
priceLevel:2
๐Ÿ“ -34.5679, -58.4441
#91La Cabaรฑa Premium
rating:4.6
cuisine:American
priceLevel:2
๐Ÿ“ -34.5914, -58.4172

Generated Filter Code

filter(restaurants, {
  "location": {
    "$near": {
      "center": {
        "lat": -34.577645,
        "lng": -58.42672
      },
      "maxDistanceMeters": 2000
    }
  }
})
Results:91

๐Ÿ’ก This filter expression will return 91 items

Geospatial Operator

Proximity Settings

๐Ÿ’ก Click the map to change center point

Creates an exclusion zone around the center

Additional Filters


Overview โ€‹

Geospatial operators allow you to filter data based on geographic coordinates. Perfect for:

  • Restaurant and store locators
  • Real estate property searches
  • Delivery zone validation
  • IoT device monitoring
  • Location-based services

Available Operators โ€‹

  • $near - Find points within radius
  • $geoBox - Find points within bounding box
  • $geoPolygon - Find points within polygon

GeoPoint Type โ€‹

All geospatial operators use the GeoPoint interface:

typescript
interface GeoPoint {
  lat: number;  // Latitude: -90 to 90
  lng: number;  // Longitude: -180 to 180
}

Find points within a specified radius of a center point.

Basic Usage โ€‹

typescript
import { filter, type GeoPoint } from '@mcabreradev/filter';

interface Restaurant {
  name: string;
  location: GeoPoint;
  rating: number;
}

const userLocation: GeoPoint = { lat: 52.52, lng: 13.405 };

filter(restaurants, {
  location: {
    $near: {
      center: userLocation,
      maxDistanceMeters: 2000
    }
  }
});

With Minimum Distance โ€‹

Exclude points that are too close:

typescript
filter(restaurants, {
  location: {
    $near: {
      center: userLocation,
      maxDistanceMeters: 5000,
      minDistanceMeters: 1000
    }
  }
});

Distance Calculation โ€‹

Uses the spherical law of cosines for fast, accurate distance calculation:

  • Suitable for most use cases
  • Earth radius: 6,371,000 meters
  • Returns distance in meters
  • Handles edge cases (poles, date line)

$geoBox - Bounding Box โ€‹

Find points within a rectangular area.

Basic Usage โ€‹

typescript
filter(stores, {
  location: {
    $geoBox: {
      southwest: { lat: 52.5, lng: 13.3 },
      northeast: { lat: 52.6, lng: 13.5 }
    }
  }
});

Use Cases โ€‹

Delivery zone:

typescript
const deliveryZone = {
  southwest: { lat: 40.7, lng: -74.02 },
  northeast: { lat: 40.8, lng: -73.9 }
};

filter(orders, {
  deliveryAddress: {
    $geoBox: deliveryZone
  },
  status: 'pending'
});

Map viewport:

typescript
const getVisibleMarkers = (bounds: BoundingBox) => {
  return filter(markers, {
    location: { $geoBox: bounds }
  });
};

$geoPolygon - Polygon Containment โ€‹

Find points inside a custom polygon area.

Basic Usage โ€‹

typescript
const neighborhoodBoundary = {
  points: [
    { lat: 52.51, lng: 13.4 },
    { lat: 52.54, lng: 13.4 },
    { lat: 52.54, lng: 13.43 },
    { lat: 52.51, lng: 13.43 }
  ]
};

filter(properties, {
  location: {
    $geoPolygon: neighborhoodBoundary
  }
});

Complex Polygons โ€‹

Supports any polygon shape:

typescript
const schoolDistrict = {
  points: [
    { lat: 52.5, lng: 13.3 },
    { lat: 52.55, lng: 13.35 },
    { lat: 52.6, lng: 13.3 },
    { lat: 52.6, lng: 13.5 },
    { lat: 52.5, lng: 13.5 }
  ]
};

filter(schools, {
  location: {
    $geoPolygon: schoolDistrict
  }
});

Requirements โ€‹

  • Minimum 3 points required
  • Points define the polygon boundary
  • Uses ray casting algorithm
  • Automatically closes polygon

Combining with Other Operators โ€‹

With Comparison Operators โ€‹

typescript
filter(restaurants, {
  location: {
    $near: {
      center: userLocation,
      maxDistanceMeters: 3000
    }
  },
  rating: { $gte: 4.5 },
  priceLevel: { $lte: 2 }
});

With Logical Operators โ€‹

typescript
filter(restaurants, {
  $and: [
    {
      location: {
        $near: {
          center: userLocation,
          maxDistanceMeters: 5000
        }
      }
    },
    {
      $or: [
        { cuisine: 'Italian' },
        { cuisine: 'Japanese' }
      ]
    },
    {
      isOpen: true,
      rating: { $gte: 4.0 }
    }
  ]
});

With String Operators โ€‹

typescript
filter(restaurants, {
  location: {
    $geoBox: deliveryZone
  },
  name: { $contains: 'pizza' },
  tags: { $contains: 'delivery' }
});

Utility Functions โ€‹

Calculate Distance โ€‹

typescript
import { calculateDistance } from '@mcabreradev/filter';

const berlin: GeoPoint = { lat: 52.52, lng: 13.405 };
const paris: GeoPoint = { lat: 48.8566, lng: 2.3522 };

const distance = calculateDistance(berlin, paris);
console.log(`${(distance / 1000).toFixed(0)} km`);

Validate Coordinates โ€‹

typescript
import { isValidGeoPoint } from '@mcabreradev/filter';

isValidGeoPoint({ lat: 52.52, lng: 13.405 });
isValidGeoPoint({ lat: 91, lng: 0 });
isValidGeoPoint({ lat: 0, lng: 181 });

Evaluate Operators Directly โ€‹

typescript
import { evaluateNear, evaluateGeoBox, evaluateGeoPolygon } from '@mcabreradev/filter';

const point: GeoPoint = { lat: 52.52, lng: 13.405 };

evaluateNear(point, {
  center: { lat: 52.52, lng: 13.4 },
  maxDistanceMeters: 1000
});

evaluateGeoBox(point, {
  southwest: { lat: 52.5, lng: 13.3 },
  northeast: { lat: 52.6, lng: 13.5 }
});

evaluateGeoPolygon(point, {
  points: [
    { lat: 52.5, lng: 13.4 },
    { lat: 52.6, lng: 13.4 },
    { lat: 52.6, lng: 13.5 }
  ]
});

Real-World Examples โ€‹

Restaurant Finder โ€‹

typescript
interface Restaurant {
  name: string;
  location: GeoPoint;
  cuisine: string;
  rating: number;
  priceLevel: number;
  isOpen: boolean;
}

const findRestaurants = (
  userLoc: GeoPoint,
  options: {
    maxDistance?: number;
    cuisine?: string;
    minRating?: number;
    maxPrice?: number;
  } = {}
) => {
  const {
    maxDistance = 5000,
    cuisine,
    minRating = 4.0,
    maxPrice = 4
  } = options;

  return filter(restaurants, {
    location: {
      $near: {
        center: userLoc,
        maxDistanceMeters: maxDistance
      }
    },
    ...(cuisine && { cuisine }),
    rating: { $gte: minRating },
    priceLevel: { $lte: maxPrice },
    isOpen: true
  });
};

const nearbyItalian = findRestaurants(
  { lat: 52.52, lng: 13.405 },
  { cuisine: 'Italian', maxDistance: 3000 }
);

Delivery Zone Validator โ€‹

typescript
const deliveryZones = [
  {
    name: 'Downtown',
    boundary: {
      southwest: { lat: 40.7, lng: -74.02 },
      northeast: { lat: 40.75, lng: -73.95 }
    }
  },
  {
    name: 'Midtown',
    boundary: {
      southwest: { lat: 40.75, lng: -74.0 },
      northeast: { lat: 40.8, lng: -73.92 }
    }
  }
];

const isDeliveryAvailable = (address: GeoPoint): boolean => {
  return deliveryZones.some(zone => {
    const result = filter([{ location: address }], {
      location: { $geoBox: zone.boundary }
    });
    return result.length > 0;
  });
};
typescript
interface Property {
  address: string;
  location: GeoPoint;
  price: number;
  bedrooms: number;
  sqft: number;
  features: string[];
}

const searchProperties = (
  criteria: {
    neighborhood?: GeoPoint[];
    maxPrice?: number;
    minBedrooms?: number;
    requiredFeatures?: string[];
  }
) => {
  const {
    neighborhood,
    maxPrice = 1000000,
    minBedrooms = 1,
    requiredFeatures = []
  } = criteria;

  return filter(properties, {
    ...(neighborhood && {
      location: {
        $geoPolygon: { points: neighborhood }
      }
    }),
    price: { $lte: maxPrice },
    bedrooms: { $gte: minBedrooms },
    ...(requiredFeatures.length > 0 && {
      features: {
        $in: requiredFeatures
      }
    })
  });
};

IoT Device Monitoring โ€‹

typescript
interface Device {
  id: string;
  location: GeoPoint;
  status: 'online' | 'offline' | 'maintenance';
  batteryLevel: number;
  lastSeen: Date;
}

const getDevicesInArea = (
  center: GeoPoint,
  radiusMeters: number,
  options?: {
    status?: string;
    minBattery?: number;
  }
) => {
  return filter(devices, {
    location: {
      $near: {
        center,
        maxDistanceMeters: radiusMeters
      }
    },
    ...(options?.status && { status: options.status }),
    ...(options?.minBattery && {
      batteryLevel: { $gte: options.minBattery }
    })
  });
};

const criticalDevices = getDevicesInArea(
  { lat: 52.52, lng: 13.405 },
  10000,
  { status: 'online', minBattery: 20 }
);

Performance Optimization โ€‹

Use Lazy Evaluation โ€‹

For large datasets, use lazy evaluation:

typescript
import { filterLazy, filterFirst } from '@mcabreradev/filter';

const nearbyLazy = filterLazy(millionRestaurants, {
  location: {
    $near: {
      center: userLocation,
      maxDistanceMeters: 5000
    }
  }
});

for (const restaurant of nearbyLazy) {
  if (found === 10) break;
}

const first20 = filterFirst(millionRestaurants, {
  location: {
    $near: {
      center: userLocation,
      maxDistanceMeters: 3000
    }
  }
}, 20);

Choose the Right Operator โ€‹

  • Bounding box is fastest for rectangular areas
  • Proximity is best for "nearby" searches
  • Polygon is most flexible but slightly slower

Enable Caching โ€‹

For repeated queries:

typescript
filter(restaurants, {
  location: {
    $near: {
      center: userLocation,
      maxDistanceMeters: 5000
    }
  }
}, { enableCache: true });

Edge Cases โ€‹

Invalid Coordinates โ€‹

Invalid coordinates are automatically excluded:

typescript
const points = [
  { location: { lat: 52.52, lng: 13.405 } },
  { location: { lat: 91, lng: 0 } },
  { location: { lat: 0, lng: 181 } }
];

filter(points, {
  location: {
    $near: {
      center: { lat: 52.52, lng: 13.405 },
      maxDistanceMeters: 1000
    }
  }
});

Missing Location Data โ€‹

Items without location are excluded:

typescript
const items = [
  { name: 'A', location: { lat: 52.52, lng: 13.405 } },
  { name: 'B' },
  { name: 'C', location: { lat: 52.521, lng: 13.406 } }
];

filter(items, {
  location: {
    $near: {
      center: { lat: 52.52, lng: 13.405 },
      maxDistanceMeters: 1000
    }
  }
});

Polygon Requirements โ€‹

Polygons must have at least 3 points:

typescript
evaluateGeoPolygon(point, {
  points: [
    { lat: 52.5, lng: 13.4 }
  ]
});

evaluateGeoPolygon(point, {
  points: [
    { lat: 52.5, lng: 13.4 },
    { lat: 52.6, lng: 13.4 },
    { lat: 52.6, lng: 13.5 }
  ]
});

TypeScript Support โ€‹

Full type safety with intelligent autocomplete:

typescript
import type {
  GeoPoint,
  NearQuery,
  BoundingBox,
  PolygonQuery,
  GeospatialOperators
} from '@mcabreradev/filter';

const nearQuery: NearQuery = {
  center: { lat: 52.52, lng: 13.405 },
  maxDistanceMeters: 5000,
  minDistanceMeters: 500
};

const box: BoundingBox = {
  southwest: { lat: 52.5, lng: 13.3 },
  northeast: { lat: 52.6, lng: 13.5 }
};

const polygon: PolygonQuery = {
  points: [
    { lat: 52.5, lng: 13.4 },
    { lat: 52.6, lng: 13.4 },
    { lat: 52.6, lng: 13.5 }
  ]
};

Distance Calculation Details โ€‹

The library uses the spherical law of cosines for distance calculation:

typescript
distance = R ร— arccos(sin(ฯ†1) ร— sin(ฯ†2) + cos(ฯ†1) ร— cos(ฯ†2) ร— cos(ฮ”ฮป))

Where:

  • R = Earth radius (6,371,000 meters)
  • ฯ†1, ฯ†2 = latitudes in radians
  • ฮ”ฮป = longitude difference in radians

This formula provides:

  • Fast computation
  • Accuracy suitable for most applications
  • Handles edge cases correctly

Coordinate System โ€‹

All coordinates use the WGS84 standard:

  • Latitude range: -90ยฐ (South Pole) to 90ยฐ (North Pole)
  • Longitude range: -180ยฐ to 180ยฐ
  • Positive latitude = North
  • Positive longitude = East

Further Reading โ€‹

Released under the MIT License.