using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using OliviaAddInPro.Model; using ArcGIS.Core.Data; using ArcGIS.Core.Geometry; using OliviaAddInPro.Helper; using ArcGIS.Core.Internal.Data; using ArcGIS.Desktop.Framework.Threading.Tasks; using System.Windows; namespace OliviaAddInPro.Services { public enum ModosEjec { Sectoriza, Planifica } //Clase que realiza las funciones de la ejecución public class EjecServ { //Cadenas de nombres internos para la exportación/importación de los archivos public string prefNameExport = "data_"; public string extShp = ".shp"; public string prefNameExportNw = "nw_"; public string ErrStr = ""; SpatialQueryFilter filtroEspacial = null; SpatialReference spatRef = null; public TratamientoComun com; /** * Acciones para comenzar ejecución * Modo 0, sectorizar * Modo 1, planificar */ public bool LanzaEjec(ModosEjec modo, out string ErrStr) { ErrStr = string.Empty; try { com.ProgrSrc.Init("Exportando datos"); //Comprueba que tiene las columnas necesarias para planificar if ((modo == ModosEjec.Planifica) && !CompruebaPlanif()) { ErrStr = "En la capa de ámbitos seleccionada no se encuentran columnas de SECTOR y/o SECUENCIA, necesarias para planificar"; return false; } //Cuenta las filas que cumplen la consulta int nelems = HelperGdb.GetNumElems(com.CapaElems, com.ConsultaAmbs); if (nelems <= 0) { ErrStr = "No existen ámbitos que cumplan las condiciones introducidas para la exportación " + com.ConsultaAmbs; return false; } com.ProgrSrc.IncMessage(0, "Exportando geometria"); //Obtiene la geometría que envuelve a los ámbitos Geometry geom_export = null; geom_export = GetGeomAmbitsExport(); if (geom_export == null || geom_export.IsEmpty) { ErrStr = "No se ha podido generar geometría de los ámbitos" + com.ConsultaAmbs + ErrStr; return false; } //crea el filtro de exportación //mira spatialreference de los datos de entrada spatRef = geom_export.SpatialReference; filtroEspacial = HelperGdb.CreateFiler(com.ConsultaAmbs, geom_export); if (filtroEspacial == null) { ErrStr = "Error al crear el filtro de exportacion de los ámbitos"; return false; } //Termina de preparar nombre //Prepara nombre string fechaHora = string.Empty; //se consigue el tiempo en este instante para añadirlo a los nombres de los archivos de salida (shapefiles) fechaHora = DateTime.Now.ToString("yyyyMMdd_Hmmss"); //Pone nombre al shape en función de los ámbitos, el tratamiento, y los polígonos + timestamp com.NombreShpExport = prefNameExport + com.NombreShpExp_PrefTto + "_" + fechaHora + extShp; com.ProgrSrc.IncMessage(10, "Exportando ámbitos de trabajo"); //exporta los datos de entrada if (!HelperGdb.ExportShp2(com.CapaElems, filtroEspacial, com.NombreShpExport, OliviaGlob.Paths.DirData, com.ProgrSrc._ProgrSrc, 40)) { ErrStr = "Error al exportar los ámbitos: " + HelperGdb.OutStr; return false; } if (com.ProgrSrc._ProgrSrc.CancellationTokenSource.IsCancellationRequested) { ErrStr = Resource1.String_cancel_progreso; return false; } //Guarda el nombre OliviaGlob.Paths.PathData = OliviaGlob.Paths.DirData + com.NombreShpExport; com.ProgrSrc.IncMessage(50, "Preparando exportación de red navegable"); //hace intersecciones espaciales en caso de ámbitos lineales para quitar los que tienen más parte fuera de la zona que dentro //REVISAR /*if (((com.GeomNiv != null) || (com.GeomZon != null)) && (OliviaGlob.IsReco() || (OliviaGlob.IsLimp() && (com.TipoTto < (int)LimpiezaDef.TiposTto.TtoPapeVaci)))) { if (!HelperGdb.RemoveRowsGeom(OliviaGlob.Paths.PathData, geom_export, 0.4)) { ErrStr = "Error al quitar los ámbitos que sobresalen: " + HelperGdb.OutStr; return false; } }*/ /////////////////////////////////////////////////////////////////////////// //comprueba, si hay restricciones de circulación y hay instalación, que la instalación no está en ellas if (!com.CoordsInstal.IsEmpty && (com.CoordsInstal.X != 0) && (com.GeomRestr != null)) { Respuesta resp = HelperGdb.IsPtoInGeom(com.CoordsInstal, com.GeomRestr); if (!resp.Value && resp.HasError) { ErrStr = "Error al comprobar si la instalación está contenida en el polígono de restricciones: " + resp.Error.ElementAt(0); return false; } else if (resp.Value) //sí está contenido en las restricciones { ErrStr = "Error, la instalación está en la zona restringida a la circulación "; return false; } } /////////////////////////////////////////////////////////////////////////// //exporta la red navegable (buffer, le quita las restr...) //se obtiene la geometría a intersecar con la red, que será la que contiene //a todos los ámbitos y la instalación, ampliada un buffer, mayor si hay //restricciones de circulación geom_export = HelperGdb.BufferGeom(geom_export, com.BuffExport).Value; if (geom_export == null) { ErrStr = "Error al añadir buffer a la geometría"; return false; } //quita las restricciones if (com.GeomRestr != null) { geom_export = HelperGdb.QuitaGeom(geom_export, com.GeomRestr); if (geom_export == null) { ErrStr = "Error al intersecar con las restricciones."; return false; } } ////////////////////////////////////////////////////////////// //comprueba si la geometría de exportación contiene a la instalación y a la planta de descarga Coordinate2D[] coords = { com.CoordsInstal, com.CoordsPlanta }; for (int i = 0; i < coords.Length; i++) { if (!coords[i].IsEmpty && (coords[i].X != 0)) { Respuesta resp = HelperGdb.IsPtoInGeom(coords[i], geom_export); if (!resp.Value) //si no lo contiene { //ha ido mal if (resp.HasError) { ErrStr = "Error al comprobar si la instalación está contenida en el polígono de exportación: " + resp.Error.ElementAt(0); return false; } else { //amplía la geom Respuesta respGeom = HelperGdb.AddPtoInGeom(coords[i], geom_export); if (respGeom.Value == null) { //ha ido mal if (resp.HasError) ErrStr = resp.Error.ElementAt(0); else ErrStr = "Error al incluir punto de instalación en polígono de exportación."; return false; } //actualiza la geometría geom_export = respGeom.Value; } } } } //Hace el filtro con la geometría final filtroEspacial = HelperGdb.CreateFiler(String.Empty, geom_export); if (filtroEspacial == null) { ErrStr = "Error al crear el filtro de exportacion de la red navegable"; return false; } com.ProgrSrc.IncMessage(60, "Exportando red navegable"); //Prepara nombre de exportación com.NombreShpExportNw = prefNameExportNw + fechaHora + extShp; //exporta los datos de entrada string capaNw =System.IO.Path.Combine(OliviaGlob.Paths.PathGdbNw, OliviaGlob.Capas.ftclass_ejes); if (!HelperGdb.ExportShp2(capaNw, filtroEspacial, com.NombreShpExportNw, OliviaGlob.Paths.DirData, com.ProgrSrc._ProgrSrc,40)) { ErrStr = "Error al exportar la red navegable: " + HelperGdb.OutStr; return false; } //guarda los nombres del shape OliviaGlob.Paths.PathNW = OliviaGlob.Paths.DirData + com.NombreShpExportNw; if (com.ProgrSrc._ProgrSrc.CancellationTokenSource.IsCancellationRequested) { ErrStr = Resource1.String_cancel_progreso; return false; } } catch (Exception ex) { ErrStr = "Errores al comenzar la ejecución: " + ex.Message; return false; } return true; } /** * Prepara la geometría para exportar los ámbitos */ public Geometry GetGeomAmbitsExport() { Geometry geomAux = null; Geometry geomAmbits = null; ErrStr = string.Empty; FeatureClass fc = HelperGdb.GetFtClass(com.CapaElems); if (fc == null) { ErrStr = "No se ha podido abrir la clase " + com.CapaElems; return null; } //Hace la intersección de zonas y niveles geomAux = null; if (com.GeomNiv != null || com.GeomZon != null) { geomAux = HelperGdb.IntersectGeom(com.GeomNiv, com.GeomZon); if (geomAux == null) { ErrStr = "Error al intersecar zonas y/o niveles."; return null; } if (geomAux.IsEmpty) { ErrStr = "No existen ámbitos en la intersección entre zonas y/o niveles."; return null; } } //comprueba que, en el caso de ejes de vía, hayan metido polígono de exportación if ((geomAux == null) && (com.CapaElems == OliviaGlob.Capas.ftclass_ejes)) { ErrStr = "Al emplear ejes de calle como ámbitos es necesario indicar polígono de exportación"; return null; } //prepara el filtro con consulta y espacial SpatialQueryFilter filtro = HelperGdb.CreateFiler(com.ConsultaAmbs, geomAux); 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; if (geomAmbits == null || geomAmbits.IsEmpty) { ErrStr = "No se ha podido generar geometría de los ámbitos" + com.ConsultaAmbs + HelperGdb.OutStr; return null; } geomAux = geomAmbits; } //le quita las restricciones if (com.GeomRestr != null) { geomAux = HelperGdb.QuitaGeom(geomAux, com.GeomRestr); if (geomAux == null) { ErrStr = "Error al intersecar con las restricciones."; return null; } } HelperGdb.Free(fc); return geomAux; } /** * Devuelve el string a concatenar en el nombre del path dependiendo de los polígonos seleccionados (zonas, turnos... etc) */ public string DameStrPoligs() { string str = ""; if (com.TextGeomNiv != "" && com.GeomNiv != null) str += "_N" + com.TextGeomNiv; if (com.TextGeomZon != "" && com.GeomZon != null) str += "_Z" + com.TextGeomZon; if (com.TextGeomRestr != "" && com.GeomRestr != null) str += "_R" + com.TextGeomRestr; return str; } /* * 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 int CompruebaCampos(string pathCapa, string[] camps) { int i; if (string.IsNullOrEmpty(pathCapa)) { ErrStr = "No se encuentra la capa"; return -1; } ErrStr = "No se encuentran el/los campo/s: "; int mal = 0; for (i = 0; i < camps.Length; i++) { if (!HelperGdb.CheckField(pathCapa, camps[i])) { ErrStr = ErrStr + camps[i] + " "; mal++; } } if(mal==0) ErrStr = ""; return mal; } public bool ComprCamposPlanif(string pathCapa) { int NCAMPS = 2; string[] camps; camps = new string[NCAMPS]; camps[0] = LimpiezaDef.Campos.consulta_sector; camps[1] = LimpiezaDef.Campos.consulta_secuen; return CompruebaCampos(pathCapa, camps) == 0; } /** * Comprueba lo necesario para ver si hay campos para la planificación */ public bool CompruebaPlanif() { //si ha importado no hace falta que compruebe, seguro que las tiene if (OliviaGlob.IsConfig2()) return true; //no ha importado, comprueba capa if (ComprCamposPlanif(com.CapaElems)) return true; return false; } /** * Borra los archivos exportados para el proceso */ public static void BorraFiles() { string[] list = null; string capa_principal = System.IO.Path.GetFileNameWithoutExtension(OliviaGlob.Paths.PathData); string capa_principal_nw = System.IO.Path.GetFileNameWithoutExtension(OliviaGlob.Paths.PathNW); try { if (capa_principal == null) return; list = System.IO.Directory.GetFiles(OliviaGlob.Paths.DirData, capa_principal + "*"); if (list.Length > 0) { foreach (string f in list) { if (System.IO.Path.GetExtension(f) == ".lock") continue; System.IO.File.Delete(f); } } if (capa_principal_nw == null) return; list = System.IO.Directory.GetFiles(OliviaGlob.Paths.DirData, capa_principal_nw + "*"); if (list.Length > 0) { foreach (string f in list) { System.IO.File.Delete(f); } } } catch (Exception ex) { MessageBox.Show(ex.Message); } } } }