"error", "message" => "Missing required fields"]); exit; } try { // 1. Check for overlapping zones // Using Haversine formula directly in SQL to find any zone where distance < (new_radius + existing_radius) $sql = " SELECT id, zone_name, radius_meters, ( 6371000 * acos( cos(radians(:new_lat)) * cos(radians(latitude)) * cos(radians(longitude) - radians(:new_lng)) + sin(radians(:new_lat)) * sin(radians(latitude)) ) ) AS distance_meters FROM geofence_zones WHERE is_active = 1 AND country_code = :country_code HAVING distance_meters < (radius_meters + :new_radius) LIMIT 1 "; $stmt = $con->prepare($sql); $stmt->bindValue(':new_lat', (float) $latitude); $stmt->bindValue(':new_lng', (float) $longitude); $stmt->bindValue(':new_radius', (int) $radius_meters, PDO::PARAM_INT); $stmt->bindValue(':country_code', $country_code); $stmt->execute(); $overlapping_zone = $stmt->fetch(PDO::FETCH_ASSOC); if ($overlapping_zone) { echo json_encode([ "status" => "error", "message" => "Zone overlaps with existing zone: " . $overlapping_zone['zone_name'], "overlap_details" => $overlapping_zone ]); exit; } // 2. Insert new zone $insert_sql = "INSERT INTO geofence_zones (zone_name, latitude, longitude, radius_meters, priority, country_code) VALUES (:zone_name, :lat, :lng, :radius, :priority, :country)"; $insert_stmt = $con->prepare($insert_sql); $insert_stmt->bindValue(':zone_name', $zone_name); $insert_stmt->bindValue(':lat', (float) $latitude); $insert_stmt->bindValue(':lng', (float) $longitude); $insert_stmt->bindValue(':radius', (int) $radius_meters, PDO::PARAM_INT); $insert_stmt->bindValue(':priority', (int) $priority, PDO::PARAM_INT); $insert_stmt->bindValue(':country', $country_code); $insert_stmt->execute(); echo json_encode([ "status" => "success", "message" => "Geofence zone added successfully", "zone_id" => $con->lastInsertId() ]); } catch (Exception $e) { error_log("Error adding geofence zone: " . $e->getMessage()); echo json_encode(["status" => "error", "message" => "Server error"]); } ?>