# KMZ Coverage Integration

## Overview
Integrated real KMZ coverage files (Harare and Bulawayo) to replace simulated distance-based coverage checks with accurate polygon-based coverage verification. The system now uses ONLY KMZ data - no fallback to placeholder nodes.

## Files Added

### 1. KMZ Coverage Service
**File**: `afinet-portal-backend/app/Services/KmzCoverageService.php`

**Features**:
- Parses KMZ files and extracts KML polygon data
- Implements point-in-polygon algorithm for accurate coverage checking
- Calculates distance to coverage edge for medium feasibility
- Auto-detects coverage zone (Harare/Bulawayo) based on coordinates
- Caches parsed polygon data for 24 hours for performance
- Supports both polygon and line-based coverage areas
- Buffers line coverage with ~50m radius for realistic coverage

**Key Methods**:
- `checkCoverage($latitude, $longitude)` - Main coverage check method, returns feasibility level
- `detectCoverageZone($latitude, $longitude)` - Auto-detect city zone
- `getCoveragePolygons($zone)` - Get cached polygon data
- `parseKmzFile($kmzPath)` - Extract and parse KML from KMZ
- `isPointInPolygon($lat, $lon, $polygon)` - Ray casting algorithm
- `distanceToPolygon($lat, $lon, $polygon)` - Calculate distance to nearest edge
- `clearCache($zone)` - Clear cached coverage data

### 2. Migration
**File**: `afinet-portal-backend/database/migrations/2026_02_11_000001_add_coverage_zone_to_feasibility_checks_table.php`

**Changes**:
- Added `coverage_zone` column (harare/bulawayo)
- Added `coverage_type` column (kmz_verified/kmz_near_coverage/outside_coverage)

### 3. Coverage Files
**Location**: `afinet-portal-backend/storage/app/coverage/`
- `harare.kmz` - Harare fiber coverage map
- `bulawayo.kmz` - Bulawayo fiber coverage map

## Updated Files

### 1. FeasibilityController
**File**: `afinet-portal-backend/app/Http/Controllers/API/FeasibilityController.php`

**Changes**:
- Injected `KmzCoverageService` into constructor
- Updated `calculateFeasibility()` method:
  - Uses ONLY KMZ coverage data (no node fallback)
  - Handles three feasibility levels: high, medium, low
  - Returns coverage zone and type in response
- Updated both `publicCheck()` and `check()` methods to save coverage zone/type
- Fixed `show()` method to include Request parameter

### 2. FeasibilityCheck Model
**File**: `afinet-portal-backend/app/Models/FeasibilityCheck.php`

**Changes**:
- Added `coverage_zone` and `coverage_type` to fillable array

### 3. Migration Fix
**File**: `afinet-portal-backend/database/migrations/2026_02_10_000001_add_odoo_product_id_to_product_packages.php`

**Changes**:
- Added `Schema::hasColumn()` check to prevent duplicate column error
- Prevents migration failure if column already exists

## How It Works

### Coverage Check Flow

1. **User submits address with coordinates**
   ```
   POST /api/feasibility/check
   {
     "address": "123 Main St, Harare",
     "latitude": -17.8252,
     "longitude": 31.0335
   }
   ```

2. **Zone Detection**
   - System detects zone based on coordinates
   - Harare: -17.7 to -18.0 lat, 30.9 to 31.2 lon
   - Bulawayo: -20.0 to -20.3 lat, 28.5 to 28.8 lon

3. **KMZ Coverage Check**
   - Loads cached polygon data for detected zone
   - Uses ray casting algorithm to check if point is inside any polygon
   - If inside: Returns HIGH feasibility
   - If within 200m of edge: Returns MEDIUM feasibility
   - If outside: Returns LOW feasibility

4. **Response**
   ```json
   {
     "success": true,
     "data": {
       "feasibility_status": "high",
       "coverage_zone": "harare",
       "coverage_type": "kmz_verified",
       "feasibility_details": {
         "fibre_available": true,
         "coverage_area": "Harare CBD",
         "connection_type": "Direct fibre connection available"
       }
     }
   }
   ```

## Feasibility Levels

### HIGH Feasibility
- **Condition**: Point is inside KMZ coverage polygon
- **Coverage Type**: `kmz_verified`
- **Extension Cost**: $0
- **Installation**: 7-14 days
- **Site Survey**: Not required
- **Message**: "Direct fibre connection available"

### MEDIUM Feasibility
- **Condition**: Point is within 200m of KMZ coverage edge
- **Coverage Type**: `kmz_near_coverage`
- **Extension Cost**: Calculated based on distance
- **Installation**: 14-30 days
- **Site Survey**: Required
- **Message**: "Fibre extension required"

### LOW Feasibility
- **Condition**: Point is outside coverage area or zone
- **Coverage Type**: `outside_coverage`
- **Extension Cost**: null (custom quote)
- **Installation**: null
- **Site Survey**: Required
- **Message**: "Outside coverage - alternative solutions available"

## Coverage Types

### 1. `kmz_verified`
- Location is within KMZ polygon coverage
- Most accurate - based on real fiber network
- Always returns HIGH feasibility
- No extension cost

### 2. `kmz_near_coverage`
- Location is near KMZ coverage (within 200m)
- Extension may be possible
- Returns MEDIUM feasibility
- Extension cost calculated

### 3. `outside_coverage`
- No coverage found in any zone
- Returns LOW feasibility
- Requires custom quote or alternative solutions

## Zone Boundaries

### Harare
- Latitude: -17.7 to -18.0
- Longitude: 30.9 to 31.2
- File: `harare.kmz`

### Bulawayo
- Latitude: -20.0 to -20.3
- Longitude: 28.5 to 28.8
- File: `bulawayo.kmz`

## Performance Optimization

### Caching
- Parsed polygon data cached for 24 hours
- Cache key: `coverage_polygons_{zone}`
- Reduces file parsing overhead

### Clear Cache
```php
// Clear specific zone
$kmzService->clearCache('harare');

// Clear all zones
$kmzService->clearCache();
```

## Adding New Coverage Zones

1. **Add KMZ file**
   ```
   storage/app/coverage/new_city.kmz
   ```

2. **Update zone detection**
   ```php
   // In KmzCoverageService::detectCoverageZone()
   if ($latitude >= X && $latitude <= Y && 
       $longitude >= A && $longitude <= B) {
       return 'new_city';
   }
   ```

3. **Clear cache**
   ```php
   $kmzService->clearCache('new_city');
   ```

## Benefits

### Accuracy
- Real fiber network boundaries instead of simulated data
- Polygon-based coverage matching actual infrastructure
- Eliminates false positives/negatives
- No placeholder node data

### Scalability
- Easy to add new cities by adding KMZ files
- Automatic zone detection
- Cached for performance

### Maintainability
- Coverage updates just require replacing KMZ files
- No code changes needed for coverage updates
- Clear separation of data and logic

### Simplicity
- Single source of truth (KMZ files)
- No fallback logic or placeholder data
- Straightforward coverage determination

## Testing

### Test Coverage Check
```bash
# Test Harare location (inside coverage)
curl -X POST http://localhost:8000/api/feasibility/check \
  -H "Content-Type: application/json" \
  -d '{
    "address": "123 Main St, Harare",
    "latitude": -17.8252,
    "longitude": 31.0335
  }'

# Test Bulawayo location
curl -X POST http://localhost:8000/api/feasibility/check \
  -H "Content-Type: application/json" \
  -d '{
    "address": "456 Oak Ave, Bulawayo",
    "latitude": -20.1500,
    "longitude": 28.5833
  }'

# Test near coverage edge (medium feasibility)
curl -X POST http://localhost:8000/api/feasibility/check \
  -H "Content-Type: application/json" \
  -d '{
    "address": "Edge Location",
    "latitude": -17.8300,
    "longitude": 31.0400
  }'

# Test outside coverage
curl -X POST http://localhost:8000/api/feasibility/check \
  -H "Content-Type: application/json" \
  -d '{
    "address": "Rural Area",
    "latitude": -19.0000,
    "longitude": 30.0000
  }'
```

### Expected Results
- Inside KMZ coverage: `coverage_type: "kmz_verified"`, `status: "high"`
- Near KMZ edge: `coverage_type: "kmz_near_coverage"`, `status: "medium"`
- Outside coverage: `coverage_type: "outside_coverage"`, `status: "low"`

## Migration Status

✅ Migration created: `2026_02_11_000001_add_coverage_zone_to_feasibility_checks_table.php`
✅ Migration run successfully
✅ Columns added: `coverage_zone`, `coverage_type`
✅ Model updated with new fillable fields
✅ Controller updated to save coverage data
✅ No fallback to placeholder nodes - KMZ only

## Next Steps

1. Test coverage checks with real Harare/Bulawayo addresses
2. Verify KMZ polygon data is parsing correctly
3. Monitor cache performance
4. Add more cities as KMZ files become available
5. Consider adding coverage visualization on frontend map
6. Fine-tune the 200m buffer for medium feasibility if needed
