using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using ArcGIS.Core.CIM; using ArcGIS.Core.Data; using ArcGIS.Core.Data.UtilityNetwork.Trace; using ArcGIS.Core.Geometry; using ArcGIS.Desktop.Catalog; using ArcGIS.Desktop.Core; using ArcGIS.Desktop.Editing; using ArcGIS.Desktop.Extensions; using ArcGIS.Desktop.Framework; using ArcGIS.Desktop.Framework.Contracts; using ArcGIS.Desktop.Framework.Dialogs; using ArcGIS.Desktop.Framework.Threading.Tasks; using ArcGIS.Desktop.Mapping; using System.Collections.ObjectModel; using OliviaAddInPro.Model; using OliviaAddInPro.Helper; using ArcGIS.Desktop.Internal.Layouts.Utilities; namespace OliviaAddInPro { internal class PaneLimpiezaSub1ViewModel : PanelViewModelBase, ILimpieza { private ObservableCollection tiposTto = new ObservableCollection(LimpiezaDef.tipos_tto_str); private ObservableCollection opsAmbs=new ObservableCollection(); private int selOpAmb = -1; private ObservableCollection> ambitos = new ObservableCollection>(); private bool capaAbierta = false; /** * Array de variables de tipo AmbitsList para mostrar en la lista, se rellena al elegir el tipo de tratamiento */ private ObservableCollection ambs_list = null; /** * Array de variables de tipo AmbitsList para mostrar en la lista, para la opción editable (puedes elegir cualquier ámbito) */ private ObservableCollection ambs_list_tod_lin = null; /** * Array de variables de tipo AmbitsList para mostrar en la lista, para la opción editable (puedes elegir cualquier ámbito) */ private ObservableCollection ambs_list_tod_pto = null; /** * Array de variables de tipo AmbitsList para mostrar en la lista, para la opción genérica (puedes elegir los ejes de las calles) */ private ObservableCollection ambs_list_eje = null; /** * Matriz que da true aquellos ámbitos de trabajo que están contemplados en .gdb una vez leida */ bool[] amb_tra_gdb = null; //implementan la interfaz Limpieza private int selTto = -1; private bool[] ambitosSel; private string capaElems = ""; #region Properties public override string DisplayName { get { return Resource1.String_tto; } } private string lblCapaLimp; public string LblCapaLimp { get { return lblCapaLimp; } set { base.SetProperty(ref lblCapaLimp, value, () => LblCapaLimp); } } private string textVeloDespl; public string TextVeloDespl { get { return textVeloDespl; } set { base.SetProperty(ref textVeloDespl, value, () => TextVeloDespl); } } private string lblUdsVeloDespl; public string LblUdsVeloDespl { get { return lblUdsVeloDespl; } set { base.SetProperty(ref lblUdsVeloDespl, value, () => LblUdsVeloDespl); } } private int timeTto; public int TimeTto { get { return timeTto; } set { base.SetProperty(ref timeTto, value, () => TimeTto); } } private string lblUdsTimeTto; public string LblUdsTimeTto { get { return lblUdsTimeTto; } set { base.SetProperty(ref lblUdsTimeTto, value, () => LblUdsTimeTto); } } private int udsTTto; public int UdsTTto { get { return udsTTto; } set { base.SetProperty(ref udsTTto, value, () => UdsTTto); } } private string lblTimeTto; public string LblTimeTto { get { return lblTimeTto; } set { base.SetProperty(ref lblTimeTto, value, () => LblTimeTto); } } private bool respSentCirc; public bool RespCirc { get { return respSentCirc; } set { base.SetProperty(ref respSentCirc, value, () => RespCirc); } } public ObservableCollection TiposTto { get { return tiposTto; } set { tiposTto = value; base.NotifyPropertyChanged("TiposTto"); } } public int TipoTto { get { return selTto; } set { selTto = value; base.NotifyPropertyChanged("TipoTto"); } } public ObservableCollection OpsAmbs { get { return opsAmbs; } set { opsAmbs = value; base.NotifyPropertyChanged("OpsAmbs"); } } public int SelOpAmb { get { return selOpAmb; } set { selOpAmb = value; base.NotifyPropertyChanged("SelOpAmb"); } } public ObservableCollection> Ambitos { get { return ambitos; } set { ambitos = value; base.NotifyPropertyChanged("OpsAmbs"); } } public bool[] AmbitosSel { get { return ambitosSel; } set { ambitosSel = value; base.NotifyPropertyChanged("AmbitosSel"); } } public bool CapaAbierta { get { return capaAbierta; } set { capaAbierta = value; base.NotifyPropertyChanged("CapaAbierta"); } } public string CapaElems { get { return capaElems; } set { capaElems = value; base.NotifyPropertyChanged("CapaElems"); } } #endregion Properties public PaneLimpiezaSub1ViewModel() { lblCapaLimp = Resource1.String_selec_capa; timeTto = 10; textVeloDespl = "10"; lblUdsTimeTto = "min"; lblUdsVeloDespl = "km/h"; } /** * Realiza las comprobaciones para cuando se ha abierto una capa */ public void AbiertaCapa(string capa) { capaElems = capa; CapaAbierta = false; //comprueba los campos de limpieza string ss = ""; if (!CompruebaCamposLimp(capa, out ss)) { HelperGlobal.ponMsg(ss, System.Windows.MessageBoxImage.Warning); return; } amb_tra_gdb = BuscAmbGdb(capa); bool hay_alguno = false; foreach (bool b in amb_tra_gdb) { if (b) { hay_alguno = true; break; } } if (!hay_alguno) { HelperGlobal.ponMsg(Resource1.String_error_elems_tabla, System.Windows.MessageBoxImage.Warning); return; } //hay elementos en la gdb OpsAmbs.Clear(); Ambitos.Clear(); CapaAbierta = true; } /** * Realiza los cambios en los ámbitos cuando se ha seleccionado un tratamiento */ public void ComboTtoSel(int tto) { if (tto < 0) return; TipoTto = tto; cambia_tiempo_tto(); ambitosSel = new bool[(int)LimpiezaDef.AmbitsTra.AmbN]; //reinicia los ambitos seleccionados //////////////////////////////////////// //Otros cambios que dependen del tratamiento if (TipoTto != (int)LimpiezaDef.TiposTto.TtoNoDef) { RespCirc = LimpiezaDef.rest_circ[TipoTto]; if (LimpiezaDef.v_desplazamiento[TipoTto] > 0) TextVeloDespl = Convert.ToString(LimpiezaDef.v_desplazamiento[TipoTto]); else TextVeloDespl = Resource1.String_velo_nodef; } ////////////////////////////////////////////////////////////// //rellena el combo de opciones de los ambitos Ambitos.Clear(); OpsAmbs.Clear(); OpsAmbs.Add("Editable"); OpsAmbs.Add("Genérico"); //en el caso del tratamiento customizable no se pondrán sus opciones particulares, sólo interesan las opciones globales a todos los tratamientos. //las opciones particulares del tratamiento customizable, son realemnte las opciones globales a todos los ttos. if ((TipoTto != (int)LimpiezaDef.TiposTto.TtoNoDef) && (TipoTto < (int)LimpiezaDef.TiposTto.TtoCustom)) { for (int i = 0; i < (LimpiezaDef.ambs_val[TipoTto].n_ops); i++) OpsAmbs.Add("Opción " + (i + 1)); } } /** * Cambio el tiempo del tratamiento en función del tipo de tratamiento seleccionado */ private void cambia_tiempo_tto() { if (TipoTto == (int)LimpiezaDef.TiposTto.TtoNoDef) { //no está definido LblTimeTto = Resource1.String_lbl_timetto; return; } else if (TipoTto >= (int)LimpiezaDef.TiposTto.TtoPapeVaci) { //tipo puntual, el tiempo es en minutos LblTimeTto = Resource1.String_lbl_timetto; UdsTTto = (int)GeneralDef.OlvTiposTto.OlvTipTtoMin; } else if ((TipoTto == (int)LimpiezaDef.TiposTto.TtoBarrMecCalz) || (TipoTto == (int)LimpiezaDef.TiposTto.TtoBaldMecCalz)) { //tipo lineal, es velocidad en m/h LblTimeTto = Resource1.String_lbl_velotto; UdsTTto = (int)GeneralDef.OlvTiposTto.OlvTipTtoMh; } else { //tipo lineal, es velocidad en m2/h LblTimeTto = Resource1.String_lbl_velotto; UdsTTto = (int)GeneralDef.OlvTiposTto.OlvTipTtoM2h; } LblUdsTimeTto = GeneralDef.UdsTto[UdsTTto]; TimeTto = (int)LimpiezaDef.tiempos_tto[(int)TipoTto]; } /** * Realiza los cambios en los ámbitos cuando se ha seleccionado un tratamiento */ public void ComboAmbSel(int opAmb) { if (opAmb < 0) return; Ambitos.Clear(); SelOpAmb = opAmb; ObservableCollection lista; lista = pon_ambitos(); //checkea los ámbitos de esta opción check_ambitos(SelOpAmb, lista); } /**Checkea de la lista los ámbitos de trabajo en función del tipo de tratamiento * y la opción elegida */ private void check_ambitos(int iop, ObservableCollection lista) { bool check = false; if (lista == null) return; for (int i = 0; i < lista.Count; i++) { check = false; if (iop < 0) { //para reseteo check=false; } else if (iop == 0) { //dependiendo del tratamiento seleccionado en la opción 0(Editable) se seleccionarán diferentes opciones del TtoCustom(diferenciando entre ttos lineales o puntuales) //para ámbitos lineales if (TipoTto < (int)LimpiezaDef.TiposTto.TtoPapeVaci) { check = LimpiezaDef.ambs_val[(int)LimpiezaDef.TiposTto.TtoCustom].ambs_ops[iop].ambs[(int)((AmbitsList)lista[i]).amb_i] && amb_tra_gdb[(int)((AmbitsList)lista[i]).amb_i]; } //para ámbitos puntuales else if ((TipoTto > (int)LimpiezaDef.TiposTto.TtoCaidaHoja) && (TipoTto < (int)LimpiezaDef.TiposTto.TtoCustom)) { //es la opción Genérica que es la opción 1 del TtoCustom, de ahi que el índice sea [iop + 1] check = LimpiezaDef.ambs_val[(int)LimpiezaDef.TiposTto.TtoCustom].ambs_ops[iop + 1].ambs[(int)((AmbitsList)lista[i]).amb_i] && amb_tra_gdb[(int)((AmbitsList)lista[i]).amb_i]; } //para ámbito custom else { check = LimpiezaDef.ambs_val[(int)LimpiezaDef.TiposTto.TtoCustom].ambs_ops[iop].ambs[(int)((AmbitsList)lista[i]).amb_i] && amb_tra_gdb[(int)((AmbitsList)lista[i]).amb_i]; } } else if (iop == 1) { //es la opción Genérica que es la opción 2 del TtoCustom, de ahi que el índice sea [iop + 1] check = LimpiezaDef.ambs_val[(int)LimpiezaDef.TiposTto.TtoCustom].ambs_ops[iop + 1].ambs[(int)((AmbitsList)lista[i]).amb_i] && amb_tra_gdb[(int)((AmbitsList)lista[i]).amb_i]; } else if ((iop - 2) < (LimpiezaDef.ambs_val[TipoTto].n_ops)) { //pone el check si el elemento que aparece en la lista porque es común o no común //esa opción en concreto le tiene check = LimpiezaDef.ambs_val[TipoTto].ambs_ops[iop - 2].ambs[(int)((AmbitsList)lista[i]).amb_i] && amb_tra_gdb[(int)((AmbitsList)lista[i]).amb_i]; } Ambitos.ElementAt(i).IsChecked = check; } } /** * Rellena una lista con los ámbitos comunes y no comunes para mostrar en el listbox en función del tipo de tratamiento */ private void rellena_amb_list() { bool[] amb_val; bool[] amb_val_tod; bool[] amb_val_eje; //lo hace para todos los tratamientos excepto para el Customizble ya que sólo se quieren mostrar las opciones alternaitvas al tratamiento if (TipoTto < (int)LimpiezaDef.TiposTto.TtoCustom) { //pide un array de booleanos donde es true en las posiciones de los ámbitos comunes amb_val = DameAmbTto(selTto); //crea un array con el número de elementos del array anterior que sean true ambs_list = new ObservableCollection();//cuenta los trues //rellena el array apuntando los índices y los textos correspondientes a los trues for (int i = 0; i < amb_val.Length; i++) { if (amb_val[i]) { ambs_list.Add(new AmbitsList((LimpiezaDef.AmbitsTra)i, LimpiezaDef.ambits_tra_str[i])); } } } //se hace lo mismo para la opción que da la posibilidad de seleccionar cualquier ámbito lineal amb_val_tod = LimpiezaDef.ambs_val[(int)LimpiezaDef.TiposTto.TtoCustom].ambs_ops[0].ambs; ambs_list_tod_lin = new ObservableCollection(); for (int i = 0; i < amb_val_tod.Length; i++) { if (amb_val_tod[i]) { ambs_list_tod_lin.Add(new AmbitsList((LimpiezaDef.AmbitsTra)i, LimpiezaDef.ambits_tra_str[i])); } } //se hace lo mismo para la opción que da la posibilidad de seleccionar cualquier ámbito puntual amb_val_tod = LimpiezaDef.ambs_val[(int)LimpiezaDef.TiposTto.TtoCustom].ambs_ops[1].ambs; ambs_list_tod_pto = new ObservableCollection(); for (int i = 0; i < amb_val_tod.Length; i++) { if (amb_val_tod[i]) { ambs_list_tod_pto.Add(new AmbitsList((LimpiezaDef.AmbitsTra)i, LimpiezaDef.ambits_tra_str[i])); } } //se hace lo mismo para la opción que permite seleccionar únicamente los ejes de calle amb_val_eje = LimpiezaDef.ambs_val[(int)LimpiezaDef.TiposTto.TtoCustom].ambs_ops[2].ambs; ambs_list_eje = new ObservableCollection(); for (int i = 0; i < amb_val_eje.Length; i++) { if (amb_val_eje[i]) { ambs_list_eje.Add(new AmbitsList((LimpiezaDef.AmbitsTra)i, LimpiezaDef.ambits_tra_str[i])); } } } /**Pone en la lista los ámbitos de trabajo en función del tipo de tratamiento * Los comunes y no comunes a sus opciones. Luego checkea los correspondientes a la opción */ private ObservableCollection pon_ambitos() { ObservableCollection lista = null; try { if (TipoTto == (int)LimpiezaDef.TiposTto.TtoNoDef) { return lista; } rellena_amb_list(); if ((SelOpAmb == 0) && ((TipoTto < (int)LimpiezaDef.TiposTto.TtoPapeVaci) || (TipoTto >= (int)LimpiezaDef.TiposTto.TtoCustom))) { lista = ambs_list_tod_lin; } else if ((SelOpAmb == 0) && (TipoTto > (int)LimpiezaDef.TiposTto.TtoCaidaHoja)) { lista = ambs_list_tod_pto; } else if (SelOpAmb == 1) { lista = ambs_list_eje; } else { lista = ambs_list; } AmbitsList al; for (int i = 0; i < lista.Count; i++) { al = lista.ElementAt(i); Ambitos.Add(new CheckedListItem(al.amb_str)); } return lista; } catch (Exception) { //MessageBox.Show("Error al poner los ámbitos", "Olivia", MessageBoxButtons.OK, MessageBoxIcon.Error); return null; } } /** * Añade a la lista de ambitos seleccionados los que están checkeados de la lista de posibles */ public bool lee_ambitos() { ambitosSel = new bool[(int)LimpiezaDef.AmbitsTra.AmbN]; //reinicia los ambitos seleccionados if (ambitos.Count == 0) return false; else if ((selOpAmb == 0) && (selTto < (int)LimpiezaDef.TiposTto.TtoPapeVaci)) { for (int i = 0; i < ambitos.Count; i++) { //lo pone a true si ese elemento está checkeado, para lo que coge el índice al array de ámbitos de ese elemento if(ambitos.ElementAt(i).IsChecked) ambitosSel[(int)((AmbitsList)ambs_list_tod_lin[i]).amb_i] = true; } } else if ((selOpAmb == 0) && (selTto >= (int)LimpiezaDef.TiposTto.TtoPapeVaci)) { for (int i = 0; i < ambitos.Count; i++) { //lo pone a true si ese elemento está checkeado, para lo que coge el índice al array de ámbitos de ese elemento if (ambitos.ElementAt(i).IsChecked) ambitosSel[(int)((AmbitsList)ambs_list_tod_pto[i]).amb_i] = true; } } else if (selOpAmb == 1) { for (int i = 0; i < ambitos.Count; i++) { //lo pone a true si ese elemento está checkeado, para lo que coge el índice al array de ámbitos de ese elemento if (ambitos.ElementAt(i).IsChecked) ambitosSel[(int)((AmbitsList)ambs_list_eje[i]).amb_i] = true; } } else { for (int i = 0; i < ambitos.Count; i++) { //lo pone a true si ese elemento está checkeado, para lo que coge el índice al array de ámbitos de ese elemento if (ambitos.ElementAt(i).IsChecked) ambitosSel[(int)((AmbitsList)ambs_list[i]).amb_i] = true; } } if (ambitosSel[(int)LimpiezaDef.AmbitsTra.AmbEjeCalle])//si es ámbito tipo eje de calle { if (udsTTto == (int)GeneralDef.OlvTiposTto.OlvTipTtoMh) udsTTto = (int)GeneralDef.OlvTiposTto.OlvTipTtoMh_eje; else if (udsTTto == (int)GeneralDef.OlvTiposTto.OlvTipTtoM2h) udsTTto = (int)GeneralDef.OlvTiposTto.OlvTipTtoM2h_eje; } return true; } /* * Lee la capa que se ha seleccionzdo de limpieza y se comprueba que los campos que se han editado corresponden con la capa * (es decir, se puede leer la capa con los campos configurados) */ public bool CompruebaCamposLimp(string pathCapa, out string err_str) { int NCAMPS = 2; string[] camps; int i; camps = new string[NCAMPS]; camps[0] = LimpiezaDef.Campos.consulta_entidad; camps[1] = LimpiezaDef.Campos.consulta_mecan; FeatureClass fc = HelperGdb.GetFtClass(pathCapa); err_str = ""; if (fc == null) { err_str = "No se puede abrir la capa"; return false; } ObservableCollection fields = HelperGdb.GetFields(fc).Result; for (i = 0; i < NCAMPS; i++) { if (!fields.Contains(camps[i])) { err_str = "No se encuentra el campo " + camps[i]; break; } } if (i < NCAMPS) return false; return true; } /** * Lee la gdb y devuelve el array de ámbitos en función de si hay en la gdb o no */ public bool[] BuscAmbGdb(string pathCapa) { string consulta; int numero_lin; bool[] amb_gdb = new bool[(int)LimpiezaDef.AmbitsTra.AmbN];//se inician a false string ftclass; //mira a ver si hay ejes de calle ftclass = LimpiezaDef.ftclass[(int)LimpiezaDef.AmbitsTra.AmbEjeCalle]; consulta = LimpiezaDef.filtro_str[(int)LimpiezaDef.AmbitsTra.AmbEjeCalle]; numero_lin = HelperGdb.GetNumElems(OliviaGlob.Paths.PathGdbNw, ftclass, consulta); if (numero_lin > 0) { amb_gdb[(int)LimpiezaDef.AmbitsTra.AmbEjeCalle] = true; } //mira a ver si hay el resto de capas y tienen entidades for (int i = (int)LimpiezaDef.AmbitsTra.AmbBordLibreMec; i < (int)LimpiezaDef.AmbitsTra.AmbN; i++) { consulta = LimpiezaDef.filtro_str[i]; numero_lin = HelperGdb.GetNumElems(pathCapa, consulta); if (numero_lin > 0) { amb_gdb[i] = true; } } return amb_gdb; } /**Devuelve el array de los ámbitos comunes y no comunes de las opciones de un tratamiento tto * Es un array de longitud el número de ámbitos totales, con true en las posiciones en los que el ámbito sea común o * no común en las opciones */ public bool[] DameAmbTto(int tto) { int i; bool sig; bool[] amb_com = new bool[(int)LimpiezaDef.AmbitsTra.AmbN]; for (int j = 0; j < (int)LimpiezaDef.AmbitsTra.AmbN; j++) { sig = false; for (i = 0; i < LimpiezaDef.ambs_val[tto].n_ops && !sig; i++) { if (LimpiezaDef.ambs_val[tto].ambs_ops[i].ambs[j]) //con que encuentre uno true lo pone y pasa al siguiente { amb_com[j] = sig = true; } } } return amb_com; } /** * Devuelve qué consulta hay que hacer, el filtro de los ámbitos y el nombre de la clase donde están */ public string dame_consul_amb_clas(out string ambitos, out string nom_class) { string consulta, orstr; consulta = null; ambitos = ""; orstr = null; nom_class = null; for (int i = 0; i < AmbitosSel.Length; i++) { if (AmbitosSel[i]) { if (nom_class == null) nom_class = LimpiezaDef.ftclass[i]; consulta = consulta + orstr + "(" + LimpiezaDef.filtro_str[i] + ")"; ambitos = ambitos + i.ToString("00"); if (orstr == null) orstr = " OR "; } } ambitos = "_A" + ambitos; if (consulta == "()") consulta = ""; return consulta; } } /** * Clase para la lista de ámbitos, relaciona el tipo de ámbito con su texto */ internal class AmbitsList { private LimpiezaDef.AmbitsTra mi_amb_i; private string mi_amb_str; public AmbitsList(LimpiezaDef.AmbitsTra amb_i, string amb_str) { this.mi_amb_i = amb_i; this.mi_amb_str = amb_str; } public LimpiezaDef.AmbitsTra amb_i { get { return mi_amb_i; } set { mi_amb_i = value; } } public string amb_str { get { return mi_amb_str; } set { mi_amb_str = value; } } } }