npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

geo-toolkits

v1.0.0

Published

A comprehensive TypeScript library for geospatial operations including geofencing, polygon containment, area calculations, and coordinate processing. Supports GeoJSON, KML, and KMZ file formats with both local file and remote URL loading capabilities.

Downloads

14

Readme

geo-toolkits

A comprehensive TypeScript library for geospatial data processing, area calculations, and geofencing operations. Supports GeoJSON, KML, and KMZ file formats with both local file and remote URL loading capabilities.

🌟 Features

  • 🗺️ Multi-format Support: Load GeoJSON, KML, and KMZ files
  • 📁 Flexible Loading: Support for both local files and remote URLs
  • 🎯 Geofencing: Point-in-polygon detection with hole support
  • 📐 Area Calculations: Accurate spherical area calculations for Earth surface
  • 📊 Statistical Analysis: Comprehensive area and geometric statistics
  • 🔍 Spatial Queries: Find closest features and multiple containment checks
  • ⚡ Performance Optimized: Bounding box pre-filtering for fast operations
  • 📝 TypeScript: Full type safety and IntelliSense support

📦 Installation

npm install geo-toolkits

🚀 Quick Start

import { GeoToolKit } from 'geo-toolkits';

const kit = new GeoToolKit();

// Load spatial data
await kit.loadFromFile('./boundaries.geojson');
// or from URL
await kit.loadFromUrl('https://example.com/data.geojson');

// Check if a point is inside any polygon
const result = kit.contains(40.7128, -74.0060); // NYC coordinates
if (result.isInside) {
  console.log(`Point is inside feature: ${result.featureIndex}`);
}

// Calculate total area
const totalArea = kit.getArea(); // in square meters
const areaInKm2 = kit.getAreaInUnit('square_kilometers');

// Get bounding box
const bbox = kit.getBoundingBox();
console.log(`Area spans: ${bbox.maxLat - bbox.minLat} degrees latitude`);

📖 API Reference

Data Loading

loadFromFile(filePath: string): Promise<void>

Load spatial data from a local file. Supports GeoJSON (.geojson, .json), KML (.kml), and KMZ (.kmz) formats.

await kit.loadFromFile('./data/boundaries.geojson');
await kit.loadFromFile('./data/regions.kml');
await kit.loadFromFile('./data/areas.kmz');

loadFromUrl(url: string): Promise<void>

Load spatial data from a remote URL. Automatically detects file format and handles network timeouts.

await kit.loadFromUrl('https://example.com/boundaries.geojson');
await kit.loadFromUrl('https://maps.example.com/regions.kml');

isLoaded(): boolean

Check if spatial data has been successfully loaded.

if (kit.isLoaded()) {
  console.log('Data is ready for analysis');
}

Dataset Information

getDatasetInfo()

Get comprehensive information about the loaded dataset.

const info = kit.getDatasetInfo();
console.log({
  source: info.source,
  originalFormat: info.originalFormat, // 'geojson' | 'kml' | 'kmz'
  featureCount: info.featureCount,
  polygonCount: info.polygonCount,
  multiPolygonCount: info.multiPolygonCount,
  fileSize: info.fileSize,
  loadedAt: info.loadedAt
});

Feature Access

getFeatures(): SpatialFeature[]

Get all loaded spatial features (Polygons and MultiPolygons only).

const features = kit.getFeatures();
features.forEach((feature, index) => {
  console.log(`Feature ${index}: ${feature.type}`);
  console.log(`Properties:`, feature.properties);
});

getPolygons(): PolygonFeature[]

Get only Polygon features from the dataset.

const polygons = kit.getPolygons();
console.log(`Found ${polygons.length} polygon features`);

getMultiPolygons(): MultiPolygonFeature[]

Get only MultiPolygon features from the dataset.

const multiPolygons = kit.getMultiPolygons();
console.log(`Found ${multiPolygons.length} multi-polygon features`);

Geofencing Operations

contains(lat: number, lng: number): ContainmentResult

Check if a coordinate point is contained within any polygon feature. Handles polygons with holes and MultiPolygon features.

const result = kit.contains(40.7128, -74.0060);

if (result.isInside) {
  console.log(`Point is inside feature ${result.featureIndex}`);
  console.log(`Feature properties:`, result.properties);
  
  if (result.geometryType === 'MultiPolygon') {
    console.log(`Specific polygon: ${result.polygonIndex}`);
  }
}

findClosestFeature(lat: number, lng: number)

Find the closest feature to a given coordinate point.

const closest = kit.findClosestFeature(40.7128, -74.0060);
if (closest) {
  console.log(`Closest feature: ${closest.featureIndex}`);
  console.log(`Distance: ${closest.distance} meters`);
}

getAllContainingFeatures(lat: number, lng: number): ContainmentResult[]

Get all features that contain the given coordinate (useful for overlapping polygons).

const allContaining = kit.getAllContainingFeatures(40.7128, -74.0060);
console.log(`Point is contained in ${allContaining.length} features`);

allContaining.forEach(result => {
  console.log(`Feature ${result.featureIndex}: ${result.properties.name}`);
});

Geometry Calculations

getBoundingBox(): BoundingBox | null

Get the overall bounding box that encompasses all features.

const bbox = kit.getBoundingBox();
if (bbox) {
  console.log(`Latitude range: ${bbox.minLat} to ${bbox.maxLat}`);
  console.log(`Longitude range: ${bbox.minLng} to ${bbox.maxLng}`);
}

getMidpoint(): MidpointResult | null

Calculate the geometric center (midpoint) of all features.

const center = kit.getMidpoint();
if (center) {
  console.log(`Dataset center: ${center.latitude}, ${center.longitude}`);
}

isWithinBoundingBox(lat: number, lng: number): boolean

Quick check if a coordinate is within the overall dataset bounding box.

const withinBounds = kit.isWithinBoundingBox(40.7128, -74.0060);
console.log(`Point within dataset bounds: ${withinBounds}`);

Area Calculations

getArea(): number

Calculate the total area of all features in square meters using spherical geometry.

const totalArea = kit.getArea(); // square meters
console.log(`Total area: ${totalArea.toLocaleString()} m²`);

getAreaInUnit(unit): number

Get total area in specific units.

const areaKm2 = kit.getAreaInUnit('square_kilometers');
const areaHectares = kit.getAreaInUnit('hectares');
const areaAcres = kit.getAreaInUnit('acres');

console.log(`Area: ${areaKm2.toFixed(2)} km²`);
console.log(`Area: ${areaHectares.toFixed(2)} hectares`);
console.log(`Area: ${areaAcres.toFixed(2)} acres`);

getAreaDetails(): AreaResult

Get detailed area breakdown for each feature.

const details = kit.getAreaDetails();
console.log(`Total area: ${details.totalArea} ${details.unit}`);

details.features.forEach(feature => {
  console.log(`Feature ${feature.featureIndex}: ${feature.area} m²`);
  
  // For MultiPolygon features
  if (feature.polygonAreas) {
    feature.polygonAreas.forEach((polyArea, index) => {
      console.log(`  Polygon ${index}: ${polyArea} m²`);
    });
  }
});

getFeatureArea(featureIndex: number): number

Calculate area of a specific feature by index.

const feature0Area = kit.getFeatureArea(0);
console.log(`Feature 0 area: ${feature0Area} m²`);

getAreaStatistics()

Get comprehensive area statistics for the dataset.

const stats = kit.getAreaStatistics();
console.log({
  totalArea: stats.totalArea,
  averageArea: stats.averageArea,
  largestFeature: stats.largestFeature,
  smallestFeature: stats.smallestFeature,
  distribution: {
    min: stats.areaDistribution.min,
    max: stats.areaDistribution.max,
    median: stats.areaDistribution.median,
    standardDeviation: stats.areaDistribution.stdDev
  }
});

Utility Methods

validateCoordinates(lat: number, lng: number): boolean

Validate if coordinates are within valid ranges.

const isValid = kit.validateCoordinates(40.7128, -74.0060);
if (!isValid) {
  console.log('Invalid coordinates provided');
}

🎯 Use Cases

Real Estate Applications

// Load property boundaries
await kit.loadFromFile('./property-boundaries.geojson');

// Check if a house location is within a specific zone
const houseLocation = kit.contains(40.7128, -74.0060);
if (houseLocation.isInside) {
  const zone = houseLocation.properties.zoning_type;
  console.log(`House is in ${zone} zone`);
}

// Calculate total developable area
const totalArea = kit.getAreaInUnit('acres');
console.log(`Total developable area: ${totalArea} acres`);

Delivery & Logistics

// Load delivery zones
await kit.loadFromUrl('https://api.company.com/delivery-zones.geojson');

// Check if delivery address is serviceable
const deliveryLocation = kit.contains(customerLat, customerLng);
if (deliveryLocation.isInside) {
  const zone = deliveryLocation.properties.delivery_zone;
  const fee = deliveryLocation.properties.delivery_fee;
  console.log(`Delivery available in ${zone} for $${fee}`);
} else {
  console.log('Sorry, we don\'t deliver to this location');
}

Environmental Monitoring

// Load protected areas
await kit.loadFromFile('./protected-areas.geojson');

// Check if coordinates are in protected zone
const location = kit.contains(sensorLat, sensorLng);
if (location.isInside) {
  const protectionLevel = location.properties.protection_level;
  console.log(`Sensor is in ${protectionLevel} protected area`);
}

// Calculate total protected area
const protectedArea = kit.getAreaInUnit('hectares');
console.log(`Total protected area: ${protectedArea} hectares`);

Urban Planning

// Load city districts
await kit.loadFromFile('./city-districts.geojson');

// Analyze district sizes
const areaStats = kit.getAreaStatistics();
console.log(`Largest district: ${areaStats.largestFeature.area / 1000000} km²`);
console.log(`Average district size: ${areaStats.averageArea / 1000000} km²`);

// Find which district a new development is in
const development = kit.contains(newDevLat, newDevLng);
if (development.isInside) {
  const district = development.properties.district_name;
  console.log(`New development is in ${district}`);
}

🔧 Advanced Usage

Working with Multiple Datasets

const residentialKit = new GeoToolKit();
const commercialKit = new GeoToolKit();

await residentialKit.loadFromFile('./residential-zones.geojson');
await commercialKit.loadFromFile('./commercial-zones.geojson');

// Check property zoning
const residentialCheck = residentialKit.contains(lat, lng);
const commercialCheck = commercialKit.contains(lat, lng);

if (residentialCheck.isInside) {
  console.log('Property is in residential zone');
} else if (commercialCheck.isInside) {
  console.log('Property is in commercial zone');
}

Error Handling

try {
  await kit.loadFromUrl('https://example.com/data.geojson');
  
  const result = kit.contains(lat, lng);
  console.log('Geofencing check completed');
  
} catch (error) {
  if (error.code === 'FILE_NOT_FOUND') {
    console.log('Data file not found');
  } else if (error.code === 'INVALID_COORDINATES') {
    console.log('Invalid coordinates provided');
  } else {
    console.log('An error occurred:', error.message);
  }
}

📊 Supported File Formats

| Format | Extension | Description | |--------|-----------|-------------| | GeoJSON | .geojson, .json | Standard geospatial JSON format | | KML | .kml | Keyhole Markup Language | | KMZ | .kmz | Compressed KML format |

Note: Only Polygon and MultiPolygon geometries are supported. Point, LineString, and other geometry types are filtered out during loading.

🌍 Coordinate System

  • Input: WGS84 (EPSG:4326) latitude/longitude coordinates
  • Range: Latitude: -90 to 90, Longitude: -180 to 180
  • Area Calculations: Uses spherical geometry for accurate Earth surface area calculations
  • Distance Calculations: Uses Haversine formula for great circle distances

⚡ Performance

  • Bounding Box Optimization: Fast pre-filtering eliminates ~90% of expensive polygon checks
  • Spatial Indexing: Efficient point-in-polygon operations
  • Memory Efficient: Processes large datasets without excessive memory usage
  • TypeScript: Zero runtime overhead with full compile-time type checking

🔗 TypeScript Support

Full TypeScript support with comprehensive type definitions:

import { 
  GeoToolKit, 
  type ContainmentResult, 
  type BoundingBox,
  type AreaResult 
} from 'geo-toolkits';

const kit = new GeoToolKit();
const result: ContainmentResult = kit.contains(40.7128, -74.0060);
const bbox: BoundingBox | null = kit.getBoundingBox();

📄 License

MIT

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📞 Support

For issues and questions, please visit our GitHub repository.