Files
construprogress/app/Livewire/LayerManager copy.php
T

210 lines
7.0 KiB
PHP
Raw Normal View History

2026-05-07 23:31:33 +02:00
<?php
namespace App\Livewire;
use Livewire\Component;
use Livewire\WithFileUploads;
use Livewire\Attributes\Layout;
use App\Models\Project;
use App\Models\Phase;
use App\Models\Layer;
use App\Services\SpatialFileConverter;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
#[Layout('layouts.app')]
class LayerManager extends Component
{
use WithFileUploads;
public Project $project;
public Phase $phase;
public $layers;
public $selectedLayer = null;
public $visibleLayers = []; // IDs de capas visibles
public $uploadFile = null;
public $layerName = '';
public $layerColor = '#3b82f6';
public $manualGeojson = null;
public $drawingMode = false;
protected $rules = [
'uploadFile' => 'required|file|mimes:geojson,kmz,kml,shp,dwg,zip|max:51200',
'layerName' => 'required|string|max:255',
'layerColor' => 'nullable|string|size:7',
];
public function mount(Project $project, Phase $phase)
{
$this->project = $project;
$this->phase = $phase;
$this->loadLayers();
if ($this->phase->project_id !== $this->project->id) {
abort(404);
}
// Por defecto todas visibles
$this->visibleLayers = $this->layers->pluck('id')->toArray();
$this->emitInitialLayersData();
}
public function loadLayers()
{
$this->layers = Layer::where('phase_id', $this->phase->id)->latest()->get();
// Eliminar de visibles las que ya no existen
$this->visibleLayers = array_intersect($this->visibleLayers, $this->layers->pluck('id')->toArray());
}
private function emitInitialLayersData()
{
$layersData = $this->layers->map(function($layer) {
return [
'id' => $layer->id,
'geojson' => $layer->geojson_data,
'color' => $layer->geojson_data['style']['color'] ?? '#3b82f6',
];
});
$this->dispatch('initialLayersData', [
'layers' => $layersData,
'visibleLayers' => $this->visibleLayers,
'selectedLayerId' => $this->selectedLayer?->id,
]);
}
public function toggleLayerVisibility($layerId)
{
if ($this->selectedLayer && $this->selectedLayer->id == $layerId) {
session()->flash('info', 'No puedes ocultar la capa que estás editando.');
return;
}
if (in_array($layerId, $this->visibleLayers)) {
$this->visibleLayers = array_diff($this->visibleLayers, [$layerId]);
} else {
$this->visibleLayers[] = $layerId;
}
$this->dispatch('visibilityChanged', $this->visibleLayers);
}
public function selectLayer($layerId)
{
$this->selectedLayer = Layer::find($layerId);
if (!$this->selectedLayer) return;
// Asegurar que la capa seleccionada está visible
if (!in_array($layerId, $this->visibleLayers)) {
$this->visibleLayers[] = $layerId;
$this->dispatch('visibilityChanged', $this->visibleLayers);
}
$geojson = $this->selectedLayer->geojson_data;
$this->dispatch('layerSelectedForEdit', [
'layerId' => $layerId,
'geojson' => $geojson,
'color' => $geojson['style']['color'] ?? '#3b82f6',
]);
session()->flash('info', 'Editando capa: ' . $this->selectedLayer->name);
}
public function importFile()
{
$this->validate();
$user = Auth::user();
if (!$user->can('upload layers') && !$user->hasRole('Admin')) {
session()->flash('error', 'Sin permisos.');
return;
}
$projectDir = "uploads/projects/{$this->project->id}/layers";
$originalPath = $this->uploadFile->store($projectDir, 'public');
$geojson = SpatialFileConverter::convertToGeoJson($this->uploadFile);
if (!$geojson) {
session()->flash('error', 'Conversión fallida.');
return;
}
$geojson['style'] = ['color' => $this->layerColor ?: '#3b82f6'];
$layer = Layer::create([
'project_id' => $this->project->id,
'phase_id' => $this->phase->id,
'name' => $this->layerName,
'geojson_data' => $geojson,
'original_file' => $originalPath,
'uploaded_by' => $user->id,
]);
$this->loadLayers();
$this->visibleLayers[] = $layer->id;
$this->reset(['uploadFile', 'layerName']);
$this->emitInitialLayersData();
session()->flash('message', 'Capa importada.');
}
public function createEmptyLayer()
{
$user = Auth::user();
$emptyGeojson = [
'type' => 'FeatureCollection',
'features' => [],
'style' => ['color' => $this->layerColor ?: '#3b82f6']
];
$layer = Layer::create([
'project_id' => $this->project->id,
'phase_id' => $this->phase->id,
'name' => $this->layerName ?: 'Nueva capa',
'geojson_data' => $emptyGeojson,
'original_file' => null,
'uploaded_by' => $user->id,
]);
$this->loadLayers();
$this->visibleLayers[] = $layer->id;
$this->selectLayer($layer->id);
$this->emitInitialLayersData();
session()->flash('message', 'Capa vacía creada y seleccionada.');
}
public function saveManualGeojson($geojsonString)
{
if (!$this->selectedLayer) {
session()->flash('error', 'No hay capa seleccionada.');
return;
}
$geojson = json_decode($geojsonString, true);
if (json_last_error() !== JSON_ERROR_NONE) {
session()->flash('error', 'GeoJSON inválido.');
return;
}
$geojson['style'] = ['color' => $this->layerColor ?: ($this->selectedLayer->geojson_data['style']['color'] ?? '#3b82f6')];
$this->selectedLayer->geojson_data = $geojson;
$this->selectedLayer->save();
$this->loadLayers(); // recargar por si acaso
$this->selectLayer($this->selectedLayer->id);
$this->emitInitialLayersData();
session()->flash('message', 'Capa guardada.');
}
public function deleteLayer($layerId)
{
$user = Auth::user();
if (!$user->can('delete layers') && !$user->hasRole('Admin')) abort(403);
$layer = Layer::find($layerId);
if (!$layer) return;
if ($layer->original_file) Storage::disk('public')->delete($layer->original_file);
$layer->delete();
$this->loadLayers();
if ($this->selectedLayer && $this->selectedLayer->id == $layerId) {
$this->selectedLayer = null;
}
$this->emitInitialLayersData();
session()->flash('message', 'Capa eliminada.');
}
public function cancelEditing()
{
$this->selectedLayer = null;
$this->dispatch('layerSelectedForEdit', null);
}
public function render()
{
return view('livewire.layer-manager');
}
}