From 21811c212b9339510a410523d13091b84a638070 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Mon, 30 May 2022 23:35:34 +0200 Subject: [PATCH] =?UTF-8?q?A=C3=B1adir=20metodos=20sincronizados=20para=20?= =?UTF-8?q?lo=20que=20se=20ejecute=20desde=20un=20thread?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Helper/HelperGdb.cs | 393 +++++++++++++++++++++++++++++++++++++++++-- Model/OliviaGlob.cs | 8 + Services/EjecServ.cs | 8 +- 3 files changed, 392 insertions(+), 17 deletions(-) diff --git a/Helper/HelperGdb.cs b/Helper/HelperGdb.cs index 0dad392..1eb2f84 100644 --- a/Helper/HelperGdb.cs +++ b/Helper/HelperGdb.cs @@ -142,7 +142,27 @@ namespace OliviaAddInPro.Helper return spatref; } - + public static ArcGIS.Core.Geometry.SpatialReference GetSpatRefSync(string ftclassName) + { + FeatureClass fc = GetFtClassFromShp(ftclassName).Result; + if (fc == null) + return null; + ArcGIS.Core.Geometry.SpatialReference spatref = null; + + try + { + spatref = fc.GetDefinition().GetSpatialReference(); + } + catch + { + spatref = null; + } + finally + { + fc.Dispose(); + } + return spatref; + } /** * Devuelve el sistema de coordenadas de una capa */ @@ -159,10 +179,26 @@ namespace OliviaAddInPro.Helper } catch { - + spatref = null; } }); - task.Wait(); + return spatref; + } + public static ArcGIS.Core.Geometry.SpatialReference GetSpatRefSync(FeatureClass fc) + { + if (fc == null) + return null; + ArcGIS.Core.Geometry.SpatialReference spatref = null; + + + try + { + spatref = fc.GetDefinition().GetSpatialReference(); + } + catch + { + spatref = null; + } return spatref; } @@ -190,7 +226,7 @@ namespace OliviaAddInPro.Helper } catch { - + fcdef = null; } }); task.Wait(); @@ -206,7 +242,43 @@ namespace OliviaAddInPro.Helper Free(fcdef); } } - + /** + * Devuelve el sistema de coordenadas de un dataset + */ + public static ArcGIS.Core.Geometry.SpatialReference GetSpatRefSync(string gdbName, string dataset) + { + if (gdbName == null || string.IsNullOrEmpty(dataset)) + return null; + Geodatabase gdb = null; + FeatureClassDefinition fcdef = null; + try + { + gdb = GetGdb(gdbName).Result; + if (gdb == null) + return null; + ArcGIS.Core.Geometry.SpatialReference spatref = null; + try + { + fcdef = gdb.GetDefinition(dataset); + spatref = fcdef.GetSpatialReference(); + } + catch + { + fcdef = null; + } + + return spatref; + } + catch + { + return null; + } + finally + { + Free(gdb); + Free(fcdef); + } + } //Dado el tipo de FtClass y una posición inicial abre un diálogo de búsqueda de ftclass //si se cancela o no es una feature class lo que se ha abierto devuelve null //si no, devuelve la featureclass directamente abierta @@ -330,6 +402,32 @@ namespace OliviaAddInPro.Helper //return fileGeodatabase; } + //Dado un path aunque sea de una feature class, devuelve el path de la gdb que la contiene, o si + //es de gdb directamente, y si no tiene .gdb, devuelve null + public static Geodatabase GetGdbSync(string pathGdb) + { + Geodatabase fileGeodatabase = null; + if (string.IsNullOrEmpty(pathGdb)) + return null; + ReiniciaOutStr(); + + string path = GetPathGdb(pathGdb); + if (!string.IsNullOrEmpty(path)) + { + try + { + fileGeodatabase = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(path))); + } + catch (Exception ex) + { + HelperGdb.OutStr = "Error al abrir Geodatabase " + path + ": " + ex.Message; + return null; + } + } + return fileGeodatabase; + + } + //Dado un path de una feature class devuelve la ftclass abierta directamente, //o null si ha habido algún problema o no lo ha encontrado public static FeatureClass GetFtClass(string pathFtClss) @@ -350,7 +448,26 @@ namespace OliviaAddInPro.Helper Free(gdb); return ftclss; } - + //Dado un path de una feature class devuelve la ftclass abierta directamente, + //o null si ha habido algún problema o no lo ha encontrado + public static FeatureClass GetFtClassSync(string pathFtClss) + { + FeatureClass ftclss = null; + if (string.IsNullOrEmpty(pathFtClss)) + return null; + Geodatabase gdb = GetGdbSync(pathFtClss); + ReiniciaOutStr(); + if (gdb != null) + { + ftclss = GetFtClassSync(System.IO.Path.GetFileNameWithoutExtension(pathFtClss), gdb); + } + else //mira a ver si es shapefile + { + ftclss = GetFtClassFromShpSync(pathFtClss); + } + Free(gdb); + return ftclss; + } //Dado el path de una gdb y el nombre de una feature class, devuelve la //feature class abierta, o null si hay algun problema public static Task GetFtClass(string nameFtclss, Geodatabase gdb) @@ -373,6 +490,26 @@ namespace OliviaAddInPro.Helper return ftclss; })); } + //Dado el path de una gdb y el nombre de una feature class, devuelve la + //feature class abierta, o null si hay algun problema + public static FeatureClass GetFtClassSync(string nameFtclss, Geodatabase gdb) + { + FeatureClass ftclss = null; + if (string.IsNullOrEmpty(nameFtclss)) + return null; + ReiniciaOutStr(); + + try + { + ftclss = gdb.OpenDataset(nameFtclss); + } + catch (Exception ex) + { + HelperGdb.OutStr = "Error al abrir Feature Class " + nameFtclss + ": " + ex.Message; + return null; + } + return ftclss; + } //Abre una feature class cuando es un shapefile public static Task GetFtClassFromShp(string pathShp) @@ -400,15 +537,37 @@ namespace OliviaAddInPro.Helper return ftclss; })); } - + //Abre una feature class cuando es un shapefile + public static FeatureClass GetFtClassFromShpSync(string pathShp) + { + FeatureClass ftclss = null; + ReiniciaOutStr(); + + if (!string.IsNullOrEmpty(pathShp) && pathShp.Contains(SHP_EXT)) + { + try + { + string shpname = System.IO.Path.GetFileNameWithoutExtension(pathShp); + var shapeFileConnPath = new FileSystemConnectionPath(new Uri(System.IO.Path.GetDirectoryName(pathShp)), + FileSystemDatastoreType.Shapefile); + var shapefile = new FileSystemDatastore(shapeFileConnPath); + ftclss = shapefile.OpenDataset(shpname); + } + catch (Exception ex) + { + HelperGdb.OutStr = "Error al abrir Shapefile " + pathShp + ": " + ex.Message; + return null; + } + } + return ftclss; + } //devuelve el campo dado el nombre - private static Task GetFieldByName(FeatureClass ftClss, string fieldName) + private static ArcGIS.Core.Data.Field GetFieldByNameSinc(FeatureClass ftClss, string fieldName) { FeatureClassDefinition ftcldef = ftClss.GetDefinition(); ReiniciaOutStr(); ArcGIS.Core.Data.Field field = null; - return ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run((Func)(() => - { + try { field = ftcldef.GetFields().First(x => x.Name.Equals(fieldName)); @@ -419,7 +578,6 @@ namespace OliviaAddInPro.Helper return null; } return field; - })); } @@ -478,6 +636,35 @@ namespace OliviaAddInPro.Helper })); } + //Devuelve la lista de IDs de la clase que cumplen la consulta + public static List GetIdsSync(FeatureClass fc, ArcGIS.Core.Data.QueryFilter filt) + { + ReiniciaOutStr(); + List ids = new List(); + Selection sel = null; + + if (fc == null) + return null; + try + { + if (filt == null) + filt = new ArcGIS.Core.Data.QueryFilter(); + sel = fc.Select(filt, SelectionType.ObjectID, SelectionOption.Normal); + int nsel = sel.GetCount(); + IReadOnlyList ids_ = sel.GetObjectIDs(); + ids = ids_.ToList(); + return ids; + } + catch (Exception ex) + { + HelperGdb.OutStr = "Error al conseguir IDs " + fc.GetName() + ": " + ex.Message; + return ids; + } + finally + { + Free(sel); + } + } //Devuelve una lista con los campos de una feature class public static Task> GetFields(FeatureClass fc) @@ -508,6 +695,34 @@ namespace OliviaAddInPro.Helper })); } + //Devuelve una lista con los campos de una feature class + public static ObservableCollection GetFieldsSync(FeatureClass fc) + { + FeatureClassDefinition ftcldef = null; + IReadOnlyList fields = null; + ReiniciaOutStr(); + ObservableCollection fields_st = new ObservableCollection(); + + if (fc == null) + return null; + try + { + ftcldef = fc.GetDefinition(); + fields = ftcldef.GetFields(); + foreach (ArcGIS.Core.Data.Field f in fields) + { + fields_st.Add(f.Name); + } + } + catch (Exception ex) + { + HelperGdb.OutStr = "Error al leer los campos " + fc.GetName() + ": " + ex.Message; + return fields_st; + } + return fields_st; + } + + /* * Comprueba que en la capa dada exista un campo con nombre 'field' */ @@ -529,7 +744,27 @@ namespace OliviaAddInPro.Helper return true; } + /* + * Comprueba que en la capa dada exista un campo con nombre 'field' + */ + public static bool CheckFieldSync(string pathCapa, string field) + { + FeatureClass fc = GetFtClassSync(pathCapa); + if (fc == null) + { + HelperGdb.OutStr = "No se puede abrir la capa"; + return false; + } + ObservableCollection fields = GetFieldsSync(fc); + if (!fields.Contains(field)) + { + HelperGdb.OutStr = "No se encuentra el campo " + field; + return false; + } + + return true; + } /* * Lee la capa que se ha seleccionzdo de recogida y se comprueba que contiene los campos necesarios * Devuelve 0 si va todo bien, -1 si da error, y num>0 con los campos que no encuentra @@ -571,7 +806,47 @@ namespace OliviaAddInPro.Helper Free(fc); } } + /* + * Lee la capa que se ha seleccionzdo de recogida y se comprueba que contiene los campos necesarios + * Devuelve 0 si va todo bien, -1 si da error, y num>0 con los campos que no encuentra + */ + public static int CheckFiledsSync(string pathCapa, string[] camps) + { + int i; + FeatureClass fc = null; + try + { + fc = GetFtClassSync(pathCapa); + if (fc == null) + { + OutStr = "No se puede abrir la capa " + pathCapa; + return -1; + } + ObservableCollection fields = GetFieldsSync(fc); + OutStr = "No se encuentran el/los campo/s: "; + int mal = 0; + for (i = 0; i < camps.Length; i++) + { + if (!fields.Contains(camps[i])) + { + OutStr = OutStr + camps[i] + " "; + mal++; + } + } + if (mal == 0) + OutStr = ""; + return mal; + } + catch + { + return -1; + } + finally + { + Free(fc); + } + } //Devuelve comilla simple si el campo es de texto, o nada si es númerico //var whereClause = $"{SelectedField} = {Quote(f)}{FieldValue}{Quote(f)}"; @@ -589,7 +864,15 @@ namespace OliviaAddInPro.Helper return GetFieldVals(fc, fieldName, uniquevals); } + //Dado un nombre de campo, devuelve los valores que encuentra para ese nombre de campo + public static ObservableCollection GetFieldValsSync(string capa, string fieldName, bool uniquevals) + { + FeatureClass fc = GetFtClassSync(capa); + if (fc == null) + return null; + return GetFieldValsSync(fc, fieldName, uniquevals); + } //Dado un nombre de campo, devuelve los valores que encuentra para ese nombre de campo public static Task> GetFieldVals(FeatureClass fc, string fieldName, bool uniquevals) { @@ -630,6 +913,44 @@ namespace OliviaAddInPro.Helper return attribs_st; })); } + //Dado un nombre de campo, devuelve los valores que encuentra para ese nombre de campo + public static ObservableCollection GetFieldValsSync(FeatureClass fc, string fieldName, bool uniquevals) + { + ObservableCollection attribs_st = new ObservableCollection(); + ReiniciaOutStr(); + + try + { + using (FeatureClassDefinition ftcldef = fc.GetDefinition()) + { + ArcGIS.Core.Data.Field field = ftcldef.GetFields().First(x => x.Name.Equals(fieldName)); + using (RowCursor rowCursor = fc.Search()) + { + string str; + while (rowCursor.MoveNext()) + { + using (Row row = rowCursor.Current) + { + str = Convert.ToString(row[fieldName]); + if (uniquevals) + { + if (attribs_st.Contains(str)) + continue; + } + attribs_st.Add(str); + } + } + } + } + } + catch (Exception ex) + { + HelperGdb.OutStr = "Error al leer los campos " + fc.GetName() + ": " + ex.Message; + return attribs_st; + + } + return attribs_st; + } /** * Devuelve una geometría que es la suma de la inicial y la que se añade Add */ @@ -713,7 +1034,16 @@ namespace OliviaAddInPro.Helper return geomIni; })); } - + /** + * Forma la envolvente convexa, el mínimo polígono, + * que contiene los ámbitos para exportar, a partir de ahí la red navegable ampliando a un buffer + */ + public static ArcGIS.Core.Geometry.Geometry GetGeomConvexHullSync(FeatureClass fclss, ArcGIS.Core.Data.QueryFilter filter) + { + ArcGIS.Core.Geometry.Geometry geomIni = null; + geomIni = GetGeomUnique(fclss, filter); + return geomIni; + } /* * A partir de una capa recorre todos los elementos que cumplen el filtro y los une en una única geometría */ @@ -887,6 +1217,36 @@ namespace OliviaAddInPro.Helper } })); } + /** + * Devuelve el número de entidades de una FeatureClass que cumplen la consulta, o todos si la consulta es empty + */ + public static int GetNumElemsSync(FeatureClass fc, string consulta = "") + { + int n = -1; + ReiniciaOutStr(); + try + { + if (fc != null) + { + if (string.IsNullOrEmpty(consulta)) + n = fc.GetCount(); + else + { + //realiza consulta + n = 0; + using (Selection sel = fc.Select(new ArcGIS.Core.Data.QueryFilter { WhereClause = consulta }, SelectionType.ObjectID, SelectionOption.Normal)) + n = sel.GetCount(); + } + } + return n; + } + catch (Exception ex) + { + HelperGdb.OutStr = "Error al contar filas en " + fc.GetName() + ": " + ex.Message; + return n; + + } + } /** * Devuelve el número de entidades de una FeatureClass que cumplen la consulta, o todos si la consulta es empty @@ -898,6 +1258,13 @@ namespace OliviaAddInPro.Helper Free(fc); return n; } + public static int GetNumElemsSync(string pathFtClss, string consulta = "") + { + FeatureClass fc = GetFtClassSync(pathFtClss); + int n = GetNumElemsSync(fc, consulta); + Free(fc); + return n; + } static public bool RenameSHP(string dir, string path, string nameNew) { var extensions = new[] { "cpg", "dbf", "prj", "sbn", "sbx", "shp", "shp.xml", "shx" }; @@ -943,7 +1310,7 @@ namespace OliviaAddInPro.Helper //Abre la featureclass try { - fc = GetFtClass(pathLayerIn); + fc = GetFtClassSync(pathLayerIn); if (fc == null) { OutStr = "Error al abrir Feature Class en exportación"; diff --git a/Model/OliviaGlob.cs b/Model/OliviaGlob.cs index 752d2a0..f5f1624 100644 --- a/Model/OliviaGlob.cs +++ b/Model/OliviaGlob.cs @@ -174,10 +174,12 @@ namespace OliviaAddInPro.Model if (sh) { DockpaneLimpiezaViewModel.Show(); + SetFlagTipEjec(TiposEjecucion.Limp); } else { DockpaneLimpiezaViewModel.Hide_(); + } } else if (OliviaGlob.IsReco()) @@ -185,6 +187,8 @@ namespace OliviaAddInPro.Model if (sh) { DockpaneRecogidaViewModel.Show(); + SetFlagTipEjec(TiposEjecucion.Reco); + } else { @@ -196,12 +200,16 @@ namespace OliviaAddInPro.Model if (sh) { DockpaneConfigViewModel.Show(); + SetFlagTipEjec(TiposEjecucion.Props); + } else { DockpaneConfigViewModel.Hide_(); } } + if(!sh) + SetFlagTipEjec(TiposEjecucion.Ninguno); } /** diff --git a/Services/EjecServ.cs b/Services/EjecServ.cs index a9cf1bb..5548b77 100644 --- a/Services/EjecServ.cs +++ b/Services/EjecServ.cs @@ -66,7 +66,7 @@ namespace OliviaAddInPro.Services } //Cuenta las filas que cumplen la consulta - int nelems = HelperGdb.GetNumElems(com.CapaElems, com.ConsultaAmbs); + int nelems = HelperGdb.GetNumElemsSync(com.CapaElems, com.ConsultaAmbs); if (nelems <= 0) { ErrStr = "No existen ámbitos que cumplan las condiciones introducidas para la exportación " + com.ConsultaAmbs; @@ -273,7 +273,7 @@ namespace OliviaAddInPro.Services Geometry geomAmbits = null; ErrStr = string.Empty; - FeatureClass fc = HelperGdb.GetFtClass(com.CapaElems); + FeatureClass fc = HelperGdb.GetFtClassSync(com.CapaElems); if (fc == null) { ErrStr = "No se ha podido abrir la clase " + com.CapaElems; @@ -308,7 +308,7 @@ namespace OliviaAddInPro.Services if (geomAux == null) { //Ahora hace la geometría de los ámbitos que cumplen la consulta, si no hay ya geometría - geomAmbits = HelperGdb.GetGeomConvexHull(fc, filtro).Result; + geomAmbits = HelperGdb.GetGeomConvexHullSync(fc, filtro); if (geomAmbits == null || geomAmbits.IsEmpty) { ErrStr = "No se ha podido generar geometría de los ámbitos" + com.ConsultaAmbs + HelperGdb.OutStr; @@ -354,7 +354,7 @@ namespace OliviaAddInPro.Services camps = new string[NCAMPS]; camps[0] = LimpiezaDef.Campos.consulta_sector; camps[1] = LimpiezaDef.Campos.consulta_secuen; - return HelperGdb.CheckFileds(pathCapa, camps) == 0; + return HelperGdb.CheckFiledsSync(pathCapa, camps) == 0; } /**