diff --git a/AgroBase/AgroBase/Forms/Operacoes/frmParametrizacaoOperacao.Designer.cs b/AgroBase/AgroBase/Forms/Operacoes/frmParametrizacaoOperacao.Designer.cs index 266562cc1..67cf71a82 100644 --- a/AgroBase/AgroBase/Forms/Operacoes/frmParametrizacaoOperacao.Designer.cs +++ b/AgroBase/AgroBase/Forms/Operacoes/frmParametrizacaoOperacao.Designer.cs @@ -45,6 +45,7 @@ this.nudTemposalvarlog = new System.Windows.Forms.NumericUpDown(); this.lblTemposalvarlog = new System.Windows.Forms.Label(); this.gpbP_Atu = new System.Windows.Forms.GroupBox(); + this.chbPulverizadorAutomatico = new System.Windows.Forms.CheckBox(); this.nudAtuarem = new System.Windows.Forms.NumericUpDown(); this.lblAtuarem = new System.Windows.Forms.Label(); this.nudQtdCameras = new System.Windows.Forms.NumericUpDown(); @@ -52,6 +53,7 @@ this.nudQtdBicos = new System.Windows.Forms.NumericUpDown(); this.lblQtdBicos = new System.Windows.Forms.Label(); this.gpbP_Dir = new System.Windows.Forms.GroupBox(); + this.chbDirecionalAutomatico = new System.Windows.Forms.CheckBox(); this.lblAngulomax = new System.Windows.Forms.Label(); this.nudAnguloMinimo = new System.Windows.Forms.NumericUpDown(); this.nudVelocidadeMP = new System.Windows.Forms.NumericUpDown(); @@ -59,6 +61,7 @@ this.nudAnguloMaximo = new System.Windows.Forms.NumericUpDown(); this.lblAngulomin = new System.Windows.Forms.Label(); this.gpbP_Mov = new System.Windows.Forms.GroupBox(); + this.chbMovimentacaoAutomatica = new System.Windows.Forms.CheckBox(); this.nudVelocidadeComErvas = new System.Windows.Forms.NumericUpDown(); this.lblKmhCErvas = new System.Windows.Forms.Label(); this.lblVelocidadeComErvas = new System.Windows.Forms.Label(); @@ -85,9 +88,9 @@ this.nudCapacidadereservatorio = new System.Windows.Forms.NumericUpDown(); this.lblUnCapcaidadereservatorio = new System.Windows.Forms.Label(); this.lblCapacidadereservatorio = new System.Windows.Forms.Label(); - this.chbPulverizadorAutomatico = new System.Windows.Forms.CheckBox(); - this.chbDirecionalAutomatico = new System.Windows.Forms.CheckBox(); - this.chbMovimentacaoAutomatica = new System.Windows.Forms.CheckBox(); + this.lblAnteciparManobra = new System.Windows.Forms.Label(); + this.txtAnteciparManobraM = new System.Windows.Forms.TextBox(); + this.lblAnteciparManobraM = new System.Windows.Forms.Label(); this.gpbModulos.SuspendLayout(); this.gpbP_Knt.SuspendLayout(); this.gpbP_Sen.SuspendLayout(); @@ -162,6 +165,9 @@ // // gpbP_Knt // + this.gpbP_Knt.Controls.Add(this.lblAnteciparManobraM); + this.gpbP_Knt.Controls.Add(this.txtAnteciparManobraM); + this.gpbP_Knt.Controls.Add(this.lblAnteciparManobra); this.gpbP_Knt.Controls.Add(this.chbMatrizCusto); this.gpbP_Knt.Controls.Add(this.chbImuParadaInclinacao); this.gpbP_Knt.Controls.Add(this.chbOakParadaObstaculo); @@ -176,10 +182,11 @@ // chbMatrizCusto // this.chbMatrizCusto.AutoSize = true; - this.chbMatrizCusto.Location = new System.Drawing.Point(10, 94); + this.chbMatrizCusto.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F); + this.chbMatrizCusto.Location = new System.Drawing.Point(10, 100); this.chbMatrizCusto.Margin = new System.Windows.Forms.Padding(6); this.chbMatrizCusto.Name = "chbMatrizCusto"; - this.chbMatrizCusto.Size = new System.Drawing.Size(139, 24); + this.chbMatrizCusto.Size = new System.Drawing.Size(132, 22); this.chbMatrizCusto.TabIndex = 13; this.chbMatrizCusto.Text = "Matriz de Custo"; this.chbMatrizCusto.UseVisualStyleBackColor = true; @@ -323,6 +330,17 @@ this.gpbP_Atu.TabStop = false; this.gpbP_Atu.Text = "Ajustes"; // + // chbPulverizadorAutomatico + // + this.chbPulverizadorAutomatico.AutoSize = true; + this.chbPulverizadorAutomatico.Location = new System.Drawing.Point(10, 155); + this.chbPulverizadorAutomatico.Margin = new System.Windows.Forms.Padding(6); + this.chbPulverizadorAutomatico.Name = "chbPulverizadorAutomatico"; + this.chbPulverizadorAutomatico.Size = new System.Drawing.Size(109, 24); + this.chbPulverizadorAutomatico.TabIndex = 14; + this.chbPulverizadorAutomatico.Text = "Automático"; + this.chbPulverizadorAutomatico.UseVisualStyleBackColor = true; + // // nudAtuarem // this.nudAtuarem.Location = new System.Drawing.Point(130, 97); @@ -394,6 +412,17 @@ this.gpbP_Dir.TabStop = false; this.gpbP_Dir.Text = "Ajustes"; // + // chbDirecionalAutomatico + // + this.chbDirecionalAutomatico.AutoSize = true; + this.chbDirecionalAutomatico.Location = new System.Drawing.Point(9, 155); + this.chbDirecionalAutomatico.Margin = new System.Windows.Forms.Padding(6); + this.chbDirecionalAutomatico.Name = "chbDirecionalAutomatico"; + this.chbDirecionalAutomatico.Size = new System.Drawing.Size(109, 24); + this.chbDirecionalAutomatico.TabIndex = 15; + this.chbDirecionalAutomatico.Text = "Automático"; + this.chbDirecionalAutomatico.UseVisualStyleBackColor = true; + // // lblAngulomax // this.lblAngulomax.AutoSize = true; @@ -485,6 +514,17 @@ this.gpbP_Mov.TabStop = false; this.gpbP_Mov.Text = "Ajustes"; // + // chbMovimentacaoAutomatica + // + this.chbMovimentacaoAutomatica.AutoSize = true; + this.chbMovimentacaoAutomatica.Location = new System.Drawing.Point(6, 155); + this.chbMovimentacaoAutomatica.Margin = new System.Windows.Forms.Padding(6); + this.chbMovimentacaoAutomatica.Name = "chbMovimentacaoAutomatica"; + this.chbMovimentacaoAutomatica.Size = new System.Drawing.Size(109, 24); + this.chbMovimentacaoAutomatica.TabIndex = 16; + this.chbMovimentacaoAutomatica.Text = "Automático"; + this.chbMovimentacaoAutomatica.UseVisualStyleBackColor = true; + // // nudVelocidadeComErvas // this.nudVelocidadeComErvas.Location = new System.Drawing.Point(10, 120); @@ -773,38 +813,34 @@ this.lblCapacidadereservatorio.TabIndex = 9; this.lblCapacidadereservatorio.Text = "Capacidade reservatório"; // - // chbPulverizadorAutomatico + // lblAnteciparManobra // - this.chbPulverizadorAutomatico.AutoSize = true; - this.chbPulverizadorAutomatico.Location = new System.Drawing.Point(10, 155); - this.chbPulverizadorAutomatico.Margin = new System.Windows.Forms.Padding(6); - this.chbPulverizadorAutomatico.Name = "chbPulverizadorAutomatico"; - this.chbPulverizadorAutomatico.Size = new System.Drawing.Size(109, 24); - this.chbPulverizadorAutomatico.TabIndex = 14; - this.chbPulverizadorAutomatico.Text = "Automático"; - this.chbPulverizadorAutomatico.UseVisualStyleBackColor = true; + this.lblAnteciparManobra.AutoSize = true; + this.lblAnteciparManobra.Font = new System.Drawing.Font("Microsoft Sans Serif", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblAnteciparManobra.Location = new System.Drawing.Point(7, 131); + this.lblAnteciparManobra.Name = "lblAnteciparManobra"; + this.lblAnteciparManobra.Size = new System.Drawing.Size(132, 18); + this.lblAnteciparManobra.TabIndex = 15; + this.lblAnteciparManobra.Text = "Antecipar manobra"; // - // chbDirecionalAutomatico + // txtAnteciparManobraM // - this.chbDirecionalAutomatico.AutoSize = true; - this.chbDirecionalAutomatico.Location = new System.Drawing.Point(9, 155); - this.chbDirecionalAutomatico.Margin = new System.Windows.Forms.Padding(6); - this.chbDirecionalAutomatico.Name = "chbDirecionalAutomatico"; - this.chbDirecionalAutomatico.Size = new System.Drawing.Size(109, 24); - this.chbDirecionalAutomatico.TabIndex = 15; - this.chbDirecionalAutomatico.Text = "Automático"; - this.chbDirecionalAutomatico.UseVisualStyleBackColor = true; + this.txtAnteciparManobraM.Location = new System.Drawing.Point(10, 151); + this.txtAnteciparManobraM.Name = "txtAnteciparManobraM"; + this.txtAnteciparManobraM.Size = new System.Drawing.Size(73, 26); + this.txtAnteciparManobraM.TabIndex = 16; + this.txtAnteciparManobraM.Text = "0"; + this.txtAnteciparManobraM.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; // - // chbMovimentacaoAutomatica + // lblAnteciparManobraM // - this.chbMovimentacaoAutomatica.AutoSize = true; - this.chbMovimentacaoAutomatica.Location = new System.Drawing.Point(6, 155); - this.chbMovimentacaoAutomatica.Margin = new System.Windows.Forms.Padding(6); - this.chbMovimentacaoAutomatica.Name = "chbMovimentacaoAutomatica"; - this.chbMovimentacaoAutomatica.Size = new System.Drawing.Size(109, 24); - this.chbMovimentacaoAutomatica.TabIndex = 16; - this.chbMovimentacaoAutomatica.Text = "Automático"; - this.chbMovimentacaoAutomatica.UseVisualStyleBackColor = true; + this.lblAnteciparManobraM.AutoSize = true; + this.lblAnteciparManobraM.Font = new System.Drawing.Font("Microsoft Sans Serif", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblAnteciparManobraM.Location = new System.Drawing.Point(89, 158); + this.lblAnteciparManobraM.Name = "lblAnteciparManobraM"; + this.lblAnteciparManobraM.Size = new System.Drawing.Size(21, 18); + this.lblAnteciparManobraM.TabIndex = 17; + this.lblAnteciparManobraM.Text = "m"; // // frmParametrizacaoOperacao // @@ -915,5 +951,8 @@ private System.Windows.Forms.CheckBox chbPulverizadorAutomatico; private System.Windows.Forms.CheckBox chbDirecionalAutomatico; private System.Windows.Forms.CheckBox chbMovimentacaoAutomatica; + private System.Windows.Forms.Label lblAnteciparManobraM; + private System.Windows.Forms.TextBox txtAnteciparManobraM; + private System.Windows.Forms.Label lblAnteciparManobra; } } \ No newline at end of file diff --git a/AgroBase/AgroBase/Forms/Operacoes/frmParametrizacaoOperacao.cs b/AgroBase/AgroBase/Forms/Operacoes/frmParametrizacaoOperacao.cs index 887843214..2082a0606 100644 --- a/AgroBase/AgroBase/Forms/Operacoes/frmParametrizacaoOperacao.cs +++ b/AgroBase/AgroBase/Forms/Operacoes/frmParametrizacaoOperacao.cs @@ -76,6 +76,8 @@ namespace AgroBase.Forms.Operacoes chbImuParadaInclinacao.Checked = _Parametros.Controle.ImuParadaPorInclinacao; chbOakParadaObstaculo.Checked = _Parametros.Controle.OakParadaPorObstaculo; + + txtAnteciparManobraM.Text = _Parametros.Controle.AnteciparManobraCorredorM.ToString(); } private void chbD_CheckedChanged(object sender, EventArgs e) @@ -142,6 +144,7 @@ namespace AgroBase.Forms.Operacoes Variaveis.OperacaoEmAndamento.Parametros.Controle.DirecionalAutomatico = chbDirecionalAutomatico.Checked; Variaveis.OperacaoEmAndamento.Parametros.Controle.DirAnguloMaximo = (int)(nudAnguloMaximo.Value); Variaveis.OperacaoEmAndamento.Parametros.Controle.DirVelocidadeMovimento = (int)(nudVelocidadeMP.Value); + Variaveis.OperacaoEmAndamento.Parametros.Controle.AnteciparManobraCorredorM = Convert.ToDouble(txtAnteciparManobraM.Text.Replace(".", ",")); Variaveis.OperacaoEmAndamento.tmrLogsInterval = (double)(nudTemposalvarlog.Value * 1000); Variaveis.OperacaoEmAndamento.Parametros.QtdBicos = (int)nudQtdBicos.Value; Variaveis.OperacaoEmAndamento.Parametros.QtdCamerasSolo = (int)nudQtdCameras.Value; diff --git a/AgroBase/AgroBase/Forms/Operacoes/frmResultadosOperacao.cs b/AgroBase/AgroBase/Forms/Operacoes/frmResultadosOperacao.cs index 5b85a4b4a..90c50df82 100644 --- a/AgroBase/AgroBase/Forms/Operacoes/frmResultadosOperacao.cs +++ b/AgroBase/AgroBase/Forms/Operacoes/frmResultadosOperacao.cs @@ -1142,8 +1142,8 @@ namespace AgroBase.Forms.Operacoes lblPercentualBateria.Text = $"Bateria {Log.Bateria.PercentualBateria.ToString("0.00")}%"; FuncoesGlobais.PreencheValorProgressBar(pgbPercentualBateria, Log.Bateria.PercentualBateria); - lblBateriaConsumida.Text = $"Consumido {Log.Bateria.PercentualBateriaConsumidaOperacao.ToString("0.00")}%"; - FuncoesGlobais.PreencheValorProgressBar(pgbBateriaConsumida, Log.Bateria.PercentualBateriaConsumidaOperacao); + lblBateriaConsumida.Text = $"Consumido {Log.Bateria.PercentualBateriaConsumida.ToString("0.00")}%"; + FuncoesGlobais.PreencheValorProgressBar(pgbBateriaConsumida, Log.Bateria.PercentualBateriaConsumida); lblPercentualReservatorio.Text = $"Reservatório {LogAtu.PercentualReservatorio.ToString("0.00")}%"; FuncoesGlobais.PreencheValorProgressBar(pgbPercentualReservatorio, LogAtu.PercentualReservatorio); @@ -1607,10 +1607,31 @@ namespace AgroBase.Forms.Operacoes private void AtualizarInformacoesCameraCaminho() { + double? CalcularErroLateralPctImagem(int width, List centrosCorredor) + { + if (width <= 0 || centrosCorredor == null || centrosCorredor.Count == 0) + return null; + + var basePoint = centrosCorredor[0]; + if (basePoint == null || basePoint.Length < 1 || basePoint[0] == null) + return null; + + double cxImg = width / 2.0; + double xBase = basePoint[0].Value; + + return ((xBase - cxImg) / cxImg) * 100.0; + } + var Log = LogsOperacao[idxMomentoAtual]; txtCamCaminhoErroAngular.Text = (Log.OperadorVisual?.Analises?.segmentacao?.erro_angular ?? 0).ToString("0.00"); - txtCamCaminhoErroLateral.Text = (Log.OperadorVisual?.Analises?.segmentacao?.erro_lateral_pct ?? 0).ToString("0.00"); + txtCamCaminhoErroLateral.Text = $"{(Log.OperadorVisual?.Analises?.segmentacao?.erro_lateral_pct ?? 0):F2}% ({CalcularErroLateralPctImagem(Log.OperadorVisual?.Analises?.segmentacao?.width ?? 0, Log.OperadorVisual?.Analises?.segmentacao?.centros_corredor):F2}%)"; txtCamCaminhoStatusCarro.Text = (Log.OperadorVisual?.Analises?.segmentacao?.status_corredor ?? Enums.StatusCarroMapa.Parado).ToString(); + txtTempoEntrandoRua.Text = $"{(Log.Trajetoria?.CorredorAtual?.DadosVisuais?.TempoForaRuaContinuo ?? 0):F2} s"; + txtTempoCaminhandoRua.Text = $"{(Log.Trajetoria?.CorredorAtual?.DadosVisuais?.TempoDentroRuaTotal ?? 0):F2} s"; + txtTempoSaindoRua.Text = $"{(Log.Trajetoria?.CorredorAtual?.DadosVisuais?.JaAntecipado ?? false)}"; + txtTempoParado.Text = $"{(Log.Trajetoria?.CorredorAtual?.DadosVisuais?.CorredorConfirmado ?? false)}"; + txtTempoDirecionando.Text = $"{(Log.Trajetoria?.CorredorAtual?.DadosVisuais?.DistanciaForaRuaContinuo ?? 0):F2} m"; + txtTempoManobrando.Text = $"{(Log.Trajetoria?.CorredorAtual?.DadosVisuais?.DistanciaRestanteAnterior ?? 0):F2} m"; //txtTempoEntrandoRua.Text = Log.Trajetoria.CorredorAtual.TempoPorStatus.FirstOrDefault(x => x.Key == Enums.StatusCarroMapa.EntrandoRua).Value.ToString("0.00") + " s"; //txtTempoCaminhandoRua.Text = Log.Trajetoria.CorredorAtual.TempoPorStatus.FirstOrDefault(x => x.Key == Enums.StatusCarroMapa.CaminhandoRua).Value.ToString("0.00") + " s"; diff --git a/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs b/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs index 3b8c84652..09dcb8a98 100644 --- a/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs +++ b/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs @@ -390,6 +390,7 @@ namespace AgroBase.Models OakParadaPorObstaculo = false, MpcMatrizCusto = false, MpcHorizonte = 4.0, + AnteciparManobraCorredorM = 0, MovVelocidadeSErvasPercent = 35, MovVelocidadeCErvasPercent = 12, @@ -498,6 +499,7 @@ namespace AgroBase.Models OakParadaPorObstaculo = true, MpcMatrizCusto = false, MpcHorizonte = 4.0, + AnteciparManobraCorredorM = 10.0, MovVelocidadeSErvasPercent = 50, MovVelocidadeCErvasPercent = 20, @@ -636,6 +638,7 @@ namespace AgroBase.Models OakParadaPorObstaculo = false, MpcMatrizCusto = false, MpcHorizonte = 4.0, + AnteciparManobraCorredorM = 0, MovVelocidadeSErvasPercent = 50, MovVelocidadeCErvasPercent = 20, @@ -772,6 +775,7 @@ namespace AgroBase.Models OakParadaPorObstaculo = true, MpcMatrizCusto = false, MpcHorizonte = 4.0, + AnteciparManobraCorredorM = 10.0, MovVelocidadeSErvasPercent = 40, MovVelocidadeCErvasPercent = 20, @@ -869,6 +873,7 @@ namespace AgroBase.Models OakParadaPorObstaculo = true, MpcMatrizCusto = false, MpcHorizonte = 4.0, + AnteciparManobraCorredorM = 0, MovVelocidadeSErvasPercent = 60, MovVelocidadeCErvasPercent = 20, @@ -2424,6 +2429,7 @@ namespace AgroBase.Models } public bool EmFreio { get; set; } = false; //public Direcao Direcao { get; set; } = Direcao.Parado; + [JsonIgnore] public List Bicos => Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.BicosPulverizadores; public double AlturaBarra { get; set; } private TipoMovimentoDirecional _tipoMovimento = TipoMovimentoDirecional.Diagnostico; diff --git a/AgroBase/AgroBase/Models/Operacoes/OperacaoParametrosModel.cs b/AgroBase/AgroBase/Models/Operacoes/OperacaoParametrosModel.cs index a30c165ad..d9e8d60d7 100644 --- a/AgroBase/AgroBase/Models/Operacoes/OperacaoParametrosModel.cs +++ b/AgroBase/AgroBase/Models/Operacoes/OperacaoParametrosModel.cs @@ -261,6 +261,20 @@ namespace AgroBase.Models.Operacoes } } + private double _anteciparManobraCorredorM; + public double AnteciparManobraCorredorM + { + get => _anteciparManobraCorredorM; + set + { + if (_anteciparManobraCorredorM != value) + { + _anteciparManobraCorredorM = value; + OnPropertyChanged(nameof(AnteciparManobraCorredorM)); + } + } + } + private bool _registrarDadosPosProcessamento; public bool RegistrarDadosPosProcessamento { diff --git a/AgroBase/AgroBase/Models/Operadores/VisualWorkerModel.cs b/AgroBase/AgroBase/Models/Operadores/VisualWorkerModel.cs index da618c759..a13b1c8d1 100644 --- a/AgroBase/AgroBase/Models/Operadores/VisualWorkerModel.cs +++ b/AgroBase/AgroBase/Models/Operadores/VisualWorkerModel.cs @@ -563,6 +563,7 @@ namespace AgroBase.Models.Operadores public StatusCarroMapa status_corredor_anterior { get; set; } public VisualWorkerMessageSegmentacaoSemanticaDebugCorredorModel status_corredor_debug { get; set; } public List centros_corredor { get; set; } + public List larguras_px { get; set; } public VisualWorkerMessageSegmentacaoSemanticaModel Clone() { @@ -576,7 +577,8 @@ namespace AgroBase.Models.Operadores status_corredor = status_corredor, status_corredor_anterior = status_corredor_anterior, status_corredor_debug = status_corredor_debug, - centros_corredor = new List(centros_corredor ?? new List()) + centros_corredor = new List(centros_corredor ?? new List()), + larguras_px = new List(larguras_px ?? new List()), }; } } diff --git a/AgroBase/AgroBase/Models/TrajetoriaMapaOperacaoModel.cs b/AgroBase/AgroBase/Models/TrajetoriaMapaOperacaoModel.cs index 4f5a2fcf1..7da79d84d 100644 --- a/AgroBase/AgroBase/Models/TrajetoriaMapaOperacaoModel.cs +++ b/AgroBase/AgroBase/Models/TrajetoriaMapaOperacaoModel.cs @@ -773,14 +773,16 @@ namespace AgroBase.Models private void VerificaFimCorredorSegmentacao() { + // Limiar de "margem" para considerar proximidade do fim + //double limiarDistanciaMargem = DistanciaErroMapaPlantacao > -1 ? DistanciaErroMapaPlantacao : 10.0; + double limiarDistanciaMargem = Variaveis.OperacaoEmAndamento.Parametros?.Controle?.AnteciparManobraCorredorM ?? 0; + if (limiarDistanciaMargem <= 0) return; + if (CorredorAtual == null) return; if (CorredorAtual.DadosVisuais.JaAntecipado) return; bool modoSimulador = false && Variaveis.OperacaoEmAndamento.Simulando; - // Limiar de "margem" para considerar proximidade do fim - double limiarDistanciaMargem = DistanciaErroMapaPlantacao > -1 ? DistanciaErroMapaPlantacao : 5.0; - double distanciaCorredor = CorredorAtual.DistanciaTotal; double distanciaRestanteCorredor = CorredorAtual.DistanciaRestante; double distanciaUltimoPontoCorredor = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, CorredorAtual.Pontos.LastOrDefault().Posicao); @@ -855,11 +857,10 @@ namespace AgroBase.Models dv.DistanciaRestanteAnterior = distanciaRestanteCorredor; // 2) Confirmar se este corredor realmente existiu (teve cana) - const double MIN_DIST_CORREDOR_CONFIRMADO = 5.0; // metros dentro da rua - const double MIN_TEMPO_CORREDOR_CONFIRMADO = 10.0; // segundos dentro da rua - if (!dv.CorredorConfirmado) { + const double MIN_DIST_CORREDOR_CONFIRMADO = 5.0; // metros dentro da rua + const double MIN_TEMPO_CORREDOR_CONFIRMADO = 10.0; // segundos dentro da rua if (dv.DistanciaDentroRuaTotal >= MIN_DIST_CORREDOR_CONFIRMADO || dv.TempoDentroRuaTotal >= MIN_TEMPO_CORREDOR_CONFIRMADO) { dv.CorredorConfirmado = true; @@ -876,7 +877,7 @@ namespace AgroBase.Models bool foraDoCorredorAgora = (statusAtual == StatusCarroMapa.Direcionando); // Limiar de "quanto tempo/distância já estou fora do corredor" para evitar buracos pontuais - const double MIN_TEMPO_FORA_CORREDOR = 2.0; // segundos + const double MIN_TEMPO_FORA_CORREDOR = 1.0; // segundos const double MIN_DIST_FORA_CORREDOR = 1.0; // metros bool foraContinuoSuficiente = dv.TempoForaRuaContinuo >= MIN_TEMPO_FORA_CORREDOR || dv.DistanciaForaRuaContinuo >= MIN_DIST_FORA_CORREDOR; diff --git a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/visual_worker/processamento/segmentacao_semantica.py b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/visual_worker/processamento/segmentacao_semantica.py index 4380d3da0..2bf10343f 100644 --- a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/visual_worker/processamento/segmentacao_semantica.py +++ b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/visual_worker/processamento/segmentacao_semantica.py @@ -180,9 +180,8 @@ class SegmentacaoManager: erro_lateral_pct = 0.0 if centros and centros[base_ix][0] is not None: x_base, _ = centros[base_ix] - w_base = max(1, larguras[base_ix]) - err_px = cx_img - x_base - erro_lateral_pct = (err_px / w_base) * 100.0 + err_px = x_base - cx_img + erro_lateral_pct = (err_px / cx_img) * 100.0 if getattr(self, "_ema_lat", None) is None: self._ema_lat = float(erro_lateral_pct) diff --git a/AgroBase/OperationControl/Controls/MapViewControl.xaml.cs b/AgroBase/OperationControl/Controls/MapViewControl.xaml.cs index c728f856e..225cc9f6a 100644 --- a/AgroBase/OperationControl/Controls/MapViewControl.xaml.cs +++ b/AgroBase/OperationControl/Controls/MapViewControl.xaml.cs @@ -151,7 +151,7 @@ namespace OperationControl.Controls private void HighlightRoad(MIFeature? feature = null, string? id = null) { if (string.IsNullOrEmpty(id)) - id = GetAttr(feature, "Id"); + id = GetAttr(feature, "IdCorrigido"); var rua = RuasMapaCarregado.FirstOrDefault(x => x.Id == id); if (rua == null) return; @@ -854,38 +854,66 @@ namespace OperationControl.Controls var reader = new GeoJsonReader(); var fc = reader.Read(geojson); - // 1) Converte NTS -> IFeature (GeometryFeature) mantendo WGS84 RuasMapaCarregado = new List(); + + var idsUsados = new HashSet(StringComparer.OrdinalIgnoreCase); + int idsCorrigidos = 0; + int total = 0; + foreach (var f in fc) { - if (f.Geometry == null) continue; + if (f.Geometry == null) + continue; + + total++; var gf = new GeometryFeature { - Geometry = f.Geometry // NTS geometry em WGS84 (lon/lat) + Geometry = f.Geometry }; - // copia atributos (opcional) + // copia atributos foreach (var name in f.Attributes.GetNames()) gf[name] = f.Attributes[name]; + bool foiGeradoAutomaticamente; + string idFinal = ResolveUniqueStreetId(gf, RuasMapaCarregado.Count, idsUsados, out foiGeradoAutomaticamente); + + // guarda o original, se quiser rastrear/debugar + var idOriginal = GetAttr(gf, "Id") ?? + GetAttr(gf, "ID") ?? + GetAttr(gf, "id"); + + gf["IdCorrigido"] = idFinal; + + if (!string.IsNullOrWhiteSpace(idOriginal)) + gf["IdOriginal"] = idOriginal; + + if (foiGeradoAutomaticamente) + idsCorrigidos++; + RuasMapaCarregado.Add(new StreetMapDictionaryModel() { - Id = GetAttr(gf, "Id"), + Id = idFinal, Feature = gf, - Selected = false, + Selected = false, Status = StreetMapStyle.Normal }); } - // 2) Provider em WGS84 (fonte) + if (idsCorrigidos > 0) + { + Models.Variaveis.MostrarLog( + $"Mapa carregado com correção automática de IDs. " + + $"Total de ruas: {RuasMapaCarregado.Count}. " + + $"IDs corrigidos/gerados: {idsCorrigidos}."); + } + var mem = new MemoryProvider(RuasMapaCarregado.Select(x => x.Feature)) { CRS = "EPSG:4326" }; - // 3) Projeta on-the-fly para o CRS do mapa (WebMercator) - // Garanta que seu Mapa.Map.CRS esteja em "EPSG:3857" quando criar o Map. var projecting = new ProjectingProvider(mem) { CRS = "EPSG:3857" @@ -894,7 +922,6 @@ namespace OperationControl.Controls if (Mapa.Map.Layers.Any(x => x.Name == MapaPlantacao_Layer?.Name)) Mapa.Map.Layers.Remove(MapaPlantacao_Layer); - // 4) Camada MapaPlantacao_Layer = new Layer("GeoJson") { DataSource = projecting, @@ -910,11 +937,6 @@ namespace OperationControl.Controls markers.BringMarkersToFront(); Mapa.Refresh(); - // 5) Auto-zoom usando o próprio provider projetado - //var extent = projecting.GetExtent(); - //if (extent != null) - // Mapa.Map.Navigator?.ZoomToBox(extent); - try { double _long = ((dynamic)RuasMapaCarregado[0].Feature).Geometry.Coordinate.X; @@ -927,6 +949,52 @@ namespace OperationControl.Controls } } + private string ResolveUniqueStreetId(GeometryFeature feature, int index, HashSet idsUsados, out bool foiGeradoAutomaticamente) + { + foiGeradoAutomaticamente = false; + + // tenta achar algum campo comum de ID + string? idOriginal = + GetAttr(feature, "Id") ?? + GetAttr(feature, "ID") ?? + GetAttr(feature, "id") ?? + GetAttr(feature, "OBJECTID") ?? + GetAttr(feature, "ObjectID") ?? + GetAttr(feature, "FID"); + + idOriginal = idOriginal?.Trim(); + + // caso esteja vazio/null + if (string.IsNullOrWhiteSpace(idOriginal)) + { + string novoId = $"AUTO_{index + 1:D4}"; + idsUsados.Add(novoId); + foiGeradoAutomaticamente = true; + return novoId; + } + + // se ainda não foi usado, aceita + if (!idsUsados.Contains(idOriginal)) + { + idsUsados.Add(idOriginal); + return idOriginal; + } + + // se repetiu, mantém rastreabilidade mas torna único + int sufixo = 2; + string candidato; + do + { + candidato = $"{idOriginal}_{sufixo:D2}"; + sufixo++; + } + while (idsUsados.Contains(candidato)); + + idsUsados.Add(candidato); + foiGeradoAutomaticamente = true; + return candidato; + } + private void OnCenterAreaClicked(object sender, RoutedEventArgs e) { NavigateToView(); diff --git a/AgroBase/OperationControl/Views/Operacao/Monitoramento/ParametrizacaoView.xaml b/AgroBase/OperationControl/Views/Operacao/Monitoramento/ParametrizacaoView.xaml index 82ec41bf7..61b7b0df3 100644 --- a/AgroBase/OperationControl/Views/Operacao/Monitoramento/ParametrizacaoView.xaml +++ b/AgroBase/OperationControl/Views/Operacao/Monitoramento/ParametrizacaoView.xaml @@ -174,6 +174,9 @@ + + +