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.
- πΊοΈ 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
npm install geo-toolkitsimport { 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`);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');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');Check if spatial data has been successfully loaded.
if (kit.isLoaded()) {
console.log('Data is ready for analysis');
}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
});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);
});Get only Polygon features from the dataset.
const polygons = kit.getPolygons();
console.log(`Found ${polygons.length} polygon features`);Get only MultiPolygon features from the dataset.
const multiPolygons = kit.getMultiPolygons();
console.log(`Found ${multiPolygons.length} multi-polygon features`);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}`);
}
}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`);
}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}`);
});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}`);
}Calculate the geometric center (midpoint) of all features.
const center = kit.getMidpoint();
if (center) {
console.log(`Dataset center: ${center.latitude}, ${center.longitude}`);
}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}`);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Β²`);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`);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Β²`);
});
}
});Calculate area of a specific feature by index.
const feature0Area = kit.getFeatureArea(0);
console.log(`Feature 0 area: ${feature0Area} mΒ²`);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
}
});Validate if coordinates are within valid ranges.
const isValid = kit.validateCoordinates(40.7128, -74.0060);
if (!isValid) {
console.log('Invalid coordinates provided');
}// 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`);// 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');
}// 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`);// 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}`);
}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');
}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);
}
}| 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.
- 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
- 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
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();MIT
Contributions are welcome! Please feel free to submit a Pull Request.
For issues and questions, please visit our GitHub repository.