UNPKG

geo-toolkits

Version:

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.

440 lines (339 loc) β€’ 12.9 kB
# 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 ```bash npm install geo-toolkits ``` ## πŸš€ Quick Start ```typescript 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. ```typescript 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. ```typescript 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. ```typescript if (kit.isLoaded()) { console.log('Data is ready for analysis'); } ``` ### Dataset Information #### `getDatasetInfo()` Get comprehensive information about the loaded dataset. ```typescript 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). ```typescript 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. ```typescript const polygons = kit.getPolygons(); console.log(`Found ${polygons.length} polygon features`); ``` #### `getMultiPolygons(): MultiPolygonFeature[]` Get only MultiPolygon features from the dataset. ```typescript 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. ```typescript 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. ```typescript 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). ```typescript 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. ```typescript 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. ```typescript 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. ```typescript 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. ```typescript const totalArea = kit.getArea(); // square meters console.log(`Total area: ${totalArea.toLocaleString()} mΒ²`); ``` #### `getAreaInUnit(unit): number` Get total area in specific units. ```typescript 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. ```typescript 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. ```typescript const feature0Area = kit.getFeatureArea(0); console.log(`Feature 0 area: ${feature0Area} mΒ²`); ``` #### `getAreaStatistics()` Get comprehensive area statistics for the dataset. ```typescript 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. ```typescript const isValid = kit.validateCoordinates(40.7128, -74.0060); if (!isValid) { console.log('Invalid coordinates provided'); } ``` ## 🎯 Use Cases ### Real Estate Applications ```typescript // 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 ```typescript // 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 ```typescript // 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 ```typescript // 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 ```typescript 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 ```typescript 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: ```typescript 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](https://github.com/bolu1/geo-toolkits).