OliviaAddInPro/Helper/HelperGdb.cs

2878 lines
110 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using ArcGIS.Desktop.Catalog;
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Framework;
using System.Collections.ObjectModel;
using ArcGIS.Core.Geometry;
using ArcGIS.Core.Data;
using ArcGIS.Desktop.Mapping;
using ArcGIS.Core.Internal.CIM;
using ArcGIS.Desktop.Internal.Layouts.Utilities;
using ArcGIS.Desktop.Core.Geoprocessing;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Editing;
using OliviaAddInPro.Model;
using System.IO;
using System.Diagnostics;
using OliviaAddInPro.View;
using OliviaAddInPro.Model.contract;
using ArcGIS.Core.Data.DDL;
using ArcGIS.Core.CIM;
using System.Threading;
using ArcGIS.Core.Data.Exceptions;
using Microsoft.Win32;
using Microsoft.WindowsAPICodePack.Dialogs;
using System.Security.Cryptography;
namespace OliviaAddInPro.Helper
{
public static class HelperGdb
{
private static string out_str = string.Empty;
public static string OutStr
{
get
{
/*string val = "";
val.CopyFrom(out_str);
out_str = string.Empty; //lo borra cada vez que se consulta
return val;*/
return out_str;
}
set { out_str = value; }
}
private static string texto_sal = string.Empty;
public static string TextoSal
{
get
{
/*string val = "";
val.CopyFrom(texto_sal);
texto_sal = string.Empty; //lo borra cada vez que se consulta
return val; */
return texto_sal;
}
set { texto_sal = value; }
}
public static string SHP_EXT = ".shp";
public static string GDB_EXT = ".gdb";
[Flags]
public enum TiposOpenFileDlg
{
OpenFtrClassLine = 1,
OpenFtrClassPoint = 2,
OpenFtrClassPolygon = 4,
OpenGdb = 8,
OpenDataset = 16
}
private static void ReiniciaOutStr()
{
out_str = string.Empty;
}
//Proceso para sacar un diálogo y seleccionar una o varias geometrías de dentro de una fclass
public static ArcGIS.Core.Geometry.Geometry OpenGeom(TiposOpenFileDlg tipo, out string txt_sal, string initialLoc = "", bool multisel = false)
{
//inicialmente
ArcGIS.Core.Geometry.Geometry geom = null;
txt_sal = Resource1.String_selec_capa;
//abre
FeatureClass fc = HelperGdb.OpenFtClassDialog(tipo);
if (fc != null)
{
//hace geom
geom = SelecLeeGeom(fc, out txt_sal, multisel);
if (geom == null && (HelperGdb.OutStr.Length > 0))
HelperGlobal.ponMsg(HelperGdb.OutStr, System.Windows.MessageBoxImage.Error);
HelperGdb.Free(fc);
}
return geom;
}
/*
* Saca ventana para seleccionar el campo del que leer para elegir la geometría
*/
private static ArcGIS.Core.Geometry.Geometry SelecLeeGeom(FeatureClass fc, out string text_sal, bool multisel)
{
ArcGIS.Core.Geometry.Geometry geomsal = null;
text_sal = "";
if (fc != null)
{
//saca la ventana de selección de campo
ShowProWndSelectFields selfwnd = new ShowProWndSelectFields(fc, multisel);
if (selfwnd.SelFieldVals.Count > 0)
{
geomsal = HelperGdb.GetGeomSel(fc, selfwnd.SelField, selfwnd.SelFieldVals).Result;
text_sal = HelperGdb.TextoSal;
}
}
return geomsal;
}
/**
* Devuelve el sistema de coordenadas de una capa
*/
public static ArcGIS.Core.Geometry.SpatialReference GetSpatRef(string ftclassName)
{
FeatureClass fc = GetFtClassFromShp(ftclassName).Result;
if (fc == null)
return null;
ArcGIS.Core.Geometry.SpatialReference spatref = null;
var task = ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
try
{
spatref = fc.GetDefinition().GetSpatialReference();
}
catch
{
}
finally
{
fc.Dispose();
}
});
task.Wait();
return spatref;
}
public static ArcGIS.Core.Geometry.SpatialReference GetSpatRefSync(string ftclassName)
{
FeatureClass fc = GetFtClassSync(ftclassName);
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
*/
public static ArcGIS.Core.Geometry.SpatialReference GetSpatRef(FeatureClass fc)
{
if (fc == null)
return null;
ArcGIS.Core.Geometry.SpatialReference spatref = null;
var task = ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
try
{
spatref = fc.GetDefinition().GetSpatialReference();
}
catch
{
spatref = null;
}
});
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;
}
/**
* Devuelve el sistema de coordenadas de un dataset
*/
public static ArcGIS.Core.Geometry.SpatialReference GetSpatRef(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;
var task = ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
try
{
fcdef = gdb.GetDefinition<FeatureClassDefinition>(dataset);
spatref = fcdef.GetSpatialReference();
}
catch
{
fcdef = null;
}
});
task.Wait();
return spatref;
}
catch
{
return null;
}
finally
{
Free(gdb);
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<FeatureClassDefinition>(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
public static FeatureClass OpenFtClassDialog(TiposOpenFileDlg tipo, string initialLoc = "")
{
FeatureClass fc = null;
ReiniciaOutStr();
string path = OpenFileDialog(tipo, initialLoc);
if (!string.IsNullOrEmpty(path))
{
fc = GetFtClass(path);
}
return fc;
}
//Libera el objeto
public static void Free(IDisposable obj)
{
if (obj != null)
obj.Dispose();
}
//Devuelve el Path del archivo seleccionado o un string vacío si se ha cancelado
public static string OpenFileDialog(TiposOpenFileDlg tipo, string initialLoc = "", string tit_ = "")
{
string titulo;
ReiniciaOutStr();
titulo = "Abrir Archivo";
//Create a browse filter that uses Pro's "esri_browseDialogFilters_geodatabases" filter.
//The browse filter is used in an OpenItemDialog.
//fuentes filtros
//https://github.com/Esri/arcgis-pro-sdk-community-samples/blob/master/Map-Exploration/IdentifyWindow/Daml.cs
BrowseProjectFilter filtro = new BrowseProjectFilter();
if ((tipo & TiposOpenFileDlg.OpenFtrClassLine) == TiposOpenFileDlg.OpenFtrClassLine)
{
filtro.AddFilter(BrowseProjectFilter.GetFilter("esri_browseDialogFilters_featureClasses_line"));
titulo = "Abrir Feature Class";
}
if ((tipo & TiposOpenFileDlg.OpenFtrClassPoint) == TiposOpenFileDlg.OpenFtrClassPoint)
{
filtro.AddFilter(BrowseProjectFilter.GetFilter("esri_browseDialogFilters_featureClasses_point"));
titulo = "Abrir Feature Class";
}
if ((tipo & TiposOpenFileDlg.OpenFtrClassPolygon) == TiposOpenFileDlg.OpenFtrClassPolygon)
{
filtro.AddFilter(BrowseProjectFilter.GetFilter("esri_browseDialogFilters_featureClasses_polygon"));
titulo = "Abrir Feature Class";
}
if ((tipo & TiposOpenFileDlg.OpenGdb) == TiposOpenFileDlg.OpenGdb)
{
filtro.AddFilter(BrowseProjectFilter.GetFilter("esri_browseDialogFilters_geodatabases"));
titulo = "Abrir Geodatabase";
}
if ((tipo & TiposOpenFileDlg.OpenDataset) == TiposOpenFileDlg.OpenDataset)
{
filtro.AddFilter(BrowseProjectFilter.GetFilter("esri_browseDialogFilters_featureDatasets_all"));
titulo = "Abrir Dataset";
}
if (tipo == 0)
{
filtro.AddFilter(BrowseProjectFilter.GetFilter(""));
}
if (!string.IsNullOrEmpty(tit_))
titulo = tit_;
//Display the filter in an Open Item dialog
OpenItemDialog aNewFilter = new OpenItemDialog
{
Title = titulo,
MultiSelect = false,
//Set the BrowseFilter property to Pro's Geodatabase filter.
BrowseFilter = filtro
};
if (!string.IsNullOrEmpty(initialLoc))
aNewFilter.InitialLocation = initialLoc;
bool? ok = aNewFilter.ShowDialog();
if ((ok ?? true) && aNewFilter.Items.Count() > 0)
return aNewFilter.Items.First().Path;
else
return string.Empty;
}
//Dado un path comprueba que sea de una gdb, termina en .gdb, o si tiene .gdb en medio lo corta ahí
//y si no tiene devuelve vacío
public static string GetPathGdb(string path)
{
if (path == null)
return string.Empty;
string pathGdb = string.Empty;
int i = 0;
if (path.Contains(GDB_EXT))
{
i = path.IndexOf(GDB_EXT, 0, path.Length);
pathGdb = path.Substring(0, i + 4);
}
return pathGdb;
}
//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 Task<Geodatabase> GetGdb(string pathGdb)
{
Geodatabase fileGeodatabase = null;
if (string.IsNullOrEmpty(pathGdb))
return null;
ReiniciaOutStr();
return ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run((Func<Geodatabase>)(() =>
{
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;
}));
//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 GetFtClassSync(string pathFtClss)
{
FeatureClass ftclss = null;
FeatureDataset dtset = null;
if (string.IsNullOrEmpty(pathFtClss))
return null;
Geodatabase gdb = GetGdbSync(pathFtClss);
ReiniciaOutStr();
if (gdb != null)
{
string dtsetName = new DirectoryInfo(System.IO.Path.GetDirectoryName(pathFtClss)).Name;
try
{
dtset = gdb.OpenDataset<FeatureDataset>(dtsetName);
}
catch (Exception ex)
{
HelperGdb.OutStr = "Error al abrir Dataset " + dtsetName + ": " + ex.Message;
dtset= null;
}
string ftclassName = System.IO.Path.GetFileNameWithoutExtension(pathFtClss);
if (dtset != null)
{
try
{
ftclss = dtset.OpenDataset<FeatureClass>(ftclassName);
}
catch (Exception ex)
{
ftclss = null;
}
}
else
{
try
{
ftclss = gdb.OpenDataset<FeatureClass>(ftclassName);
}
catch (Exception ex)
{
ftclss = null;
}
}
if(ftclss==null)
HelperGdb.OutStr = "Error al abrir Feature Class " + ftclassName;
}
else //mira a ver si es shapefile
{
ftclss = GetFtClassFromShpSync(pathFtClss);
}
Free(gdb);
Free(dtset);
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 GetFtClass(string pathFtClss)
{
FeatureClass ftclss = null;
FeatureDataset dtset = null;
if (string.IsNullOrEmpty(pathFtClss))
return null;
Geodatabase gdb = GetGdb(pathFtClss).Result;
ReiniciaOutStr();
if (gdb != null)
{
var task = ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run((Func<FeatureClass>)(() =>
{
string dtsetName = new DirectoryInfo(System.IO.Path.GetDirectoryName(pathFtClss)).Name;
try
{
dtset = gdb.OpenDataset<FeatureDataset>(dtsetName);
}
catch (Exception ex)
{
HelperGdb.OutStr = "Error al abrir Dataset " + dtsetName + ": " + ex.Message;
dtset = null;
}
string ftclassName = System.IO.Path.GetFileNameWithoutExtension(pathFtClss);
if (dtset != null)
{
try
{
ftclss = dtset.OpenDataset<FeatureClass>(ftclassName);
}
catch (Exception ex)
{
ftclss = null;
}
}
else
{
try
{
ftclss = gdb.OpenDataset<FeatureClass>(ftclassName);
}
catch (Exception ex)
{
ftclss = null;
}
}
if (ftclss == null)
HelperGdb.OutStr = "Error al abrir Feature Class " + ftclassName;
return ftclss;
}));
task.Wait();
}
else //mira a ver si es shapefile
{
ftclss = GetFtClassFromShp(pathFtClss).Result;
}
Free(gdb);
Free(dtset);
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<FeatureClass> GetFtClass(string nameFtclss, Geodatabase gdb)
{
FeatureClass ftclss = null;
if (string.IsNullOrEmpty(nameFtclss))
return null;
ReiniciaOutStr();
return ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run((Func<FeatureClass>)(() =>
{
try
{
ftclss = gdb.OpenDataset<FeatureClass>(nameFtclss);
}
catch (Exception ex)
{
HelperGdb.OutStr = "Error al abrir Feature Class " + nameFtclss + ": " + ex.Message;
return null;
}
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<FeatureClass>(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<FeatureClass> GetFtClassFromShp(string pathShp)
{
FeatureClass ftclss = null;
ReiniciaOutStr();
return ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run((Func<FeatureClass>)(() =>
{
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<FeatureClass>(shpname);
}
catch (Exception ex)
{
HelperGdb.OutStr = "Error al abrir Shapefile " + pathShp + ": " + ex.Message;
return null;
}
}
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<FeatureClass>(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 ArcGIS.Core.Data.Field GetFieldByNameSync(FeatureClass ftClss, string fieldName)
{
FeatureClassDefinition ftcldef = ftClss.GetDefinition();
ReiniciaOutStr();
ArcGIS.Core.Data.Field field = null;
try
{
field = ftcldef.GetFields().First(x => x.Name.Equals(fieldName));
}
catch (Exception ex)
{
HelperGdb.OutStr = "No se encuentra el campo " + fieldName + ": " + ex.Message;
return null;
}
return field;
}
//Crea un filtro espacial a partir de una consulta y en todo caso, una geometría
public static ArcGIS.Core.Data.SpatialQueryFilter CreateFiler(string consulta, ArcGIS.Core.Geometry.Geometry geom, SpatialRelationship rel = SpatialRelationship.Contains)
{
ArcGIS.Core.Data.SpatialQueryFilter filt = null;
if (geom != null)
{
SpatialQueryFilter filtSpat = new SpatialQueryFilter
{
WhereClause = consulta,
FilterGeometry = geom,
SpatialRelationship = rel,
};
filt = filtSpat;
}
else
{
filt = new ArcGIS.Core.Data.SpatialQueryFilter();
filt.WhereClause = consulta;
}
return filt;
}
//Devuelve la lista de IDs de la clase que cumplen la consulta
public static Task<List<long>> GetIds(FeatureClass fc, ArcGIS.Core.Data.QueryFilter filt)
{
ReiniciaOutStr();
List<long> ids = new List<long>();
Selection sel = null;
return ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run((Func<List<long>>)(() =>
{
if (fc == null)
return null;
try
{
if (filt == null)
filt = new ArcGIS.Core.Data.QueryFilter();
sel = fc.Select(filt, SelectionType.ObjectID, SelectionOption.Normal);
long nsel = sel.GetCount();
IReadOnlyList<long> 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 la lista de IDs de la clase que cumplen la consulta
public static List<long> GetIdsSync(FeatureClass fc, ArcGIS.Core.Data.QueryFilter filt)
{
ReiniciaOutStr();
List<long> ids = new List<long>();
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);
var nsel = sel.GetCount();
IReadOnlyList<long> 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<ObservableCollection<string>> GetFields(FeatureClass fc)
{
FeatureClassDefinition ftcldef = null;
IReadOnlyList<ArcGIS.Core.Data.Field> fields = null;
ReiniciaOutStr();
ObservableCollection<string> fields_st = new ObservableCollection<string>();
return ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run((Func<ObservableCollection<string>>)(() =>
{
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;
}));
}
//Devuelve una lista con los campos de una feature class
public static ObservableCollection<string> GetFieldsSync(FeatureClass fc)
{
FeatureClassDefinition ftcldef = null;
IReadOnlyList<ArcGIS.Core.Data.Field> fields = null;
ReiniciaOutStr();
ObservableCollection<string> fields_st = new ObservableCollection<string>();
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;
}
//Devuelve una lista con los campos de una feature class
public static IReadOnlyList<ArcGIS.Core.Data.Field> GetFieldsSyncEx(FeatureClass fc)
{
FeatureClassDefinition ftcldef = null;
IReadOnlyList<ArcGIS.Core.Data.Field> fields = null;
ReiniciaOutStr();
if (fc == null)
return null;
try
{
ftcldef = fc.GetDefinition();
fields = ftcldef.GetFields();
}
catch (Exception ex)
{
HelperGdb.OutStr = "Error al leer los campos " + fc.GetName() + ": " + ex.Message;
return fields;
}
return fields;
}
/*
* Comprueba que en la capa dada exista un campo con nombre 'field'
*/
public static bool CheckField(string pathCapa, string field)
{
FeatureClass fc = GetFtClass(pathCapa);
if (fc == null)
{
HelperGdb.OutStr = "No se puede abrir la capa";
return false;
}
ObservableCollection<string> fields = GetFields(fc).Result;
if (!fields.Contains(field))
{
HelperGdb.OutStr = "No se encuentra el campo " + field;
Free(fc);
return false;
}
Free(fc);
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<string> fields = GetFieldsSync(fc);
bool encuentra = true;
if (!fields.Contains(field))
{
HelperGdb.OutStr = "No se encuentra el campo " + field;
encuentra= false;
}
Free(fc);
return encuentra;
}
/*
* 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 CheckFileds(string pathCapa, string[] camps)
{
int i;
FeatureClass fc = null;
try
{
fc = GetFtClass(pathCapa);
if (fc == null)
{
OutStr = "No se puede abrir la capa " + pathCapa;
return -1;
}
ObservableCollection<string> fields = GetFields(fc).Result;
OutStr = "No se encuentran el/los campo/s: ";
int mal = 0;
for (i = 0; i < camps.Length; i++)
{
//if (!fields.Any(f=>f.ToUpper().Trim().Contains(camps[i].Substring (0,Math.Min(camps[i].Length, ComunDef.MaxCaracteresBBDD)).ToUpper().Trim())))
if (!fields.Any(f=>f.ToUpper().Trim().Equals(camps[i].ToUpper().Trim())))
{
OutStr = OutStr + camps[i] + " ";
mal++;
}
}
if (mal == 0)
OutStr = "";
return mal;
}
catch
{
return -1;
}
finally
{
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<string> fields = GetFieldsSync(fc);
OutStr = "No se encuentran el/los campo/s: ";
int mal = 0;
for (i = 0; i < camps.Length; i++)
{
//if (!fields.Any(f => f.ToUpper().Trim().Contains(camps[i].Substring(0, Math.Min(camps[i].Length, ComunDef.MaxCaracteresBBDD)).ToUpper().Trim())))
if (!fields.Any(f => f.ToUpper().Trim().Equals(camps[i].ToUpper().Trim())))
{
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)}";
public static string Quote(ArcGIS.Core.Data.Field f)
{
return f.FieldType == FieldType.String ? "'" : "";
}
//Dado un nombre de campo, devuelve los valores que encuentra para ese nombre de campo
public static Task<ObservableCollection<string>> GetFieldVals(string capa, string fieldName, bool uniquevals)
{
FeatureClass fc = GetFtClass(capa);
if (fc == null)
return null;
return GetFieldVals(fc, fieldName, uniquevals);
}
//Dado un nombre de campo, devuelve los valores que encuentra para ese nombre de campo
public static ObservableCollection<string> 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<ObservableCollection<string>> GetFieldVals(FeatureClass fc, string fieldName, bool uniquevals)
{
ObservableCollection<string> attribs_st = new ObservableCollection<string>();
ReiniciaOutStr();
return ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run((Func<ObservableCollection<string>>)(() =>
{
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;
}));
}
//Dado un nombre de campo, devuelve los valores que encuentra para ese nombre de campo
public static ObservableCollection<string> GetFieldValsSync(FeatureClass fc, string fieldName, bool uniquevals)
{
ObservableCollection<string> attribs_st = new ObservableCollection<string>();
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
*/
public static ArcGIS.Core.Geometry.Geometry IntersectGeom(ArcGIS.Core.Geometry.Geometry geomIni, ArcGIS.Core.Geometry.Geometry geomInters,
GeometryDimensionType resultDimension = GeometryDimensionType.EsriGeometryUnknownDimension)//esriGeometryNoDimension)
{
if (geomIni == null)
return geomInters;
if (geomInters == null)
return geomIni;
ArcGIS.Core.Geometry.Geometry geomSal = null;
try
{
if (resultDimension == GeometryDimensionType.EsriGeometryUnknownDimension)//GeometryDimension.esriGeometryNoDimension)
geomSal = GeometryEngine.Instance.Intersection(geomIni, geomInters);
else
geomSal = GeometryEngine.Instance.Intersection(geomIni, geomInters, resultDimension);
return geomSal;
}
catch
{
return null;
}
}
/**
* Devuelve una geometría que es la suma de la inicial y la que se añade Add
*/
public static ArcGIS.Core.Geometry.Geometry UneGeom(ArcGIS.Core.Geometry.Geometry geomIni, ArcGIS.Core.Geometry.Geometry geomUne)
{
if (geomIni == null)
return geomUne;
if (geomUne == null)
return geomIni;
ArcGIS.Core.Geometry.Geometry geomSal = null;
try
{
geomSal = GeometryEngine.Instance.Union(geomIni, geomUne);
return geomSal;
}
catch
{
return null;
}
}
/**
* Devuelve una geometría a la que dada una geometría inicial se le quita Excl
*/
public static ArcGIS.Core.Geometry.Geometry QuitaGeom(ArcGIS.Core.Geometry.Geometry geomIni, ArcGIS.Core.Geometry.Geometry geomQuita)
{
if (geomIni == null)
return geomQuita;
if (geomQuita == null)
return geomIni;
ArcGIS.Core.Geometry.Geometry geomSal = null;
try
{
geomSal = GeometryEngine.Instance.Difference(geomIni, geomQuita);
return geomSal;
}
catch
{
return null;
}
}
/**
* Reproyecta la geometría dada a la spatial reference, si son diferentes
*/
public static ArcGIS.Core.Geometry.Geometry ReproyectaGeom(ArcGIS.Core.Geometry.Geometry geom, ArcGIS.Core.Geometry.SpatialReference spatref)
{
ArcGIS.Core.Geometry.Geometry geomSal = null;
try
{
if (geom == null)
return null;
if (geom.SpatialReference == null)
return geom;
if (geom.SpatialReference.Equals(spatref))
return geom;
geomSal = GeometryEngine.Instance.Project(geom, spatref);
return geomSal;
}
catch
{
return null;
}
}
/**
* 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 Task<ArcGIS.Core.Geometry.Geometry> GetGeomConvexHull(FeatureClass fclss, ArcGIS.Core.Data.QueryFilter filter)
{
ArcGIS.Core.Geometry.Geometry geomIni = null;
return ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run((Func<ArcGIS.Core.Geometry.Geometry>)(() =>
{
geomIni = GetGeomUnique(fclss, filter);
geomIni = GeometryEngine.Instance.ConvexHull(geomIni);
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);
geomIni = GeometryEngine.Instance.ConvexHull(geomIni);
return geomIni;
}
/*
* A partir de una capa recorre todos los elementos que cumplen el filtro y los une en una única geometría
*/
public static ArcGIS.Core.Geometry.Geometry GetGeomUnique(FeatureClass fclss, ArcGIS.Core.Data.QueryFilter filtro)
{
ArcGIS.Core.Geometry.Geometry geomsal = null;
ReiniciaOutStr();
try
{
var geom = new List<ArcGIS.Core.Geometry.Geometry>();
using (RowCursor rowCursor = fclss.Search(filtro))
{
while (rowCursor.MoveNext())
{
using (Row row = rowCursor.Current)
{
if (row is Feature ft)
geom.Add(ft.GetShape());
}
}
geomsal = GeometryEngine.Instance.Union(geom);
}
}
catch (Exception ex)
{
OutStr = "Error al leer generar geometría única " + OutStr + ex.Message;
return geomsal;
}
return geomsal;
}
/**
* Dado un campo de una feature class y el valor que se quiere para el campo
* devuelve las geometrías que cumplen dicho criterio
*/
public static Task<ArcGIS.Core.Geometry.Geometry> GetGeomSel(FeatureClass fclss, string fieldName, ObservableCollection<string> selFieldVals)
{
ArcGIS.Core.Geometry.Geometry geomsal = null;
ArcGIS.Core.Geometry.Geometry geomAux = null;
string where = "";
ArcGIS.Core.Data.Field f;
ArcGIS.Core.Data.QueryFilter filtro;
bool ok = true;
ReiniciaOutStr();
string txtsal = string.Empty;
ReiniciaOutStr();
return ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run((Func<ArcGIS.Core.Geometry.Geometry>)(() =>
{
try
{
using (FeatureClassDefinition ftcldef = fclss.GetDefinition())
{
f = ftcldef.GetFields().First(x => x.Name.Equals(fieldName));
//se embucla para unir las geoms
for (int i = 0; i < selFieldVals.Count && ok; i++)
{
where = $"{fieldName} = {Quote(f)}{selFieldVals[i]}{Quote(f)}";
filtro = new ArcGIS.Core.Data.QueryFilter { WhereClause = where };
geomAux = GetGeomUnique(fclss, filtro);
if (geomAux == null)
{
ok = false;
continue;
}
geomsal = UneGeom(geomsal, geomAux);
txtsal = txtsal + HelperGlobal.RevisaText(selFieldVals[i]);
}
TextoSal = txtsal;
}
}
catch (Exception ex)
{
HelperGdb.OutStr = "Error al generar geometría en " + fclss.GetName() + " Con filtro " + where + ": " + ex.Message;
return geomsal;
}
if (!ok)
HelperGdb.OutStr = "Error al generar geometría en " + fclss.GetName() + " Con filtro " + where + HelperGdb.OutStr;
return geomsal;
}));
}
/**
* Devuelve el número de entidades de una FeatureClass que cumplen la consulta, o todos si la consulta es empty
*/
public static long GetNumElems(string pathGdb, string ftclssName, string consulta = "")
{
Geodatabase gdb = GetGdb(pathGdb).Result;
FeatureClass fc = null;
long n = -1;
if (gdb != null)
{
fc = GetFtClass(ftclssName, gdb).Result;
if (fc != null)
n = GetNumElems(fc, consulta).Result;
}
Free(fc);
Free(gdb);
return n;
}
/**
* Devuelve los valores únicos de un campo dado
*/
public static ObservableCollection<string> GetUniqueVals(string capa, string campo)
{
ObservableCollection<string> uniqueVals = null;
FeatureClass ftclass = GetFtClass(capa);
if (ftclass == null)
return null;
using (FeatureClassDefinition featureClassDefinition = ftclass.GetDefinition())
{
// Get fields
ArcGIS.Core.Data.Field fld = featureClassDefinition.GetFields().First(x => x.Name.Equals(campo));
// Create StatisticsDescriptions
StatisticsDescription uniqStatDesc = new StatisticsDescription(fld, new List<ArcGIS.Core.Data.StatisticsFunction>()
{ ArcGIS.Core.Data.StatisticsFunction.Count });
// Create TableStatisticsDescription
TableStatisticsDescription tableStatisticsDescription = new TableStatisticsDescription(new List<StatisticsDescription>() { uniqStatDesc });
tableStatisticsDescription.GroupBy = new List<ArcGIS.Core.Data.Field>() { fld };
tableStatisticsDescription.OrderBy = new List<SortDescription>() { new SortDescription(fld) };
// Calculate Statistics
IReadOnlyList<TableStatisticsResult> statisticsResults = ftclass.CalculateStatistics(tableStatisticsDescription);
TableStatisticsResult statRes = statisticsResults.ElementAt(0); //solo hay 1 grupo
// Code to process results goes here...
uniqueVals = new ObservableCollection<string>();
for (int i = 0; i < statRes.StatisticsResults.Count; i++)
{
uniqueVals.Add(statRes.StatisticsResults.ElementAt(i).ToString());
}
}
Free(ftclass);
return uniqueVals;
}
/**
* Devuelve el número de entidades de una FeatureClass que cumplen la consulta, o todos si la consulta es empty
*/
public static Task<long> GetNumElems(FeatureClass fc, string consulta = "")
{
long n = -1;
ReiniciaOutStr();
return ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run((Func<long>)(() =>
{
try
{
if (fc != null)
{
if (string.IsNullOrEmpty(consulta))
n = fc.GetCount();
else
{
//realiza consulta
n = 0;
//fc.GetDefinition().GetFields().First().Name kfadpskfpasp
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
*/
public static long GetNumElemsSync(FeatureClass fc, string consulta = "")
{
long 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
*/
public static long GetNumElems(string pathFtClss, string consulta = "")
{
FeatureClass fc = GetFtClass(pathFtClss);
var n = GetNumElems(fc, consulta).Result;
Free(fc);
return n;
}
public static long GetNumElemsSync(string pathFtClss, string consulta = "")
{
FeatureClass fc = GetFtClassSync(pathFtClss);
var 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" };
string old_ext = System.IO.Path.GetExtension(path);
string name = System.IO.Path.GetFileName(path);
if (!string.IsNullOrEmpty(old_ext))
name.Replace(old_ext, "");
string _ex = System.IO.Path.GetExtension(nameNew);
string nn = nameNew;
if (!string.IsNullOrEmpty(_ex))
nn = nn.Replace(_ex, "");
var res = true;
foreach (var ex in extensions)
{
try
{
var po = string.Format("{0}{1}.{2}", dir, name, ex);
var pn = string.Format("{0}{1}.{2}", dir, nn, ex);
if (!File.Exists(po))
res = false;//no existe
if (File.Exists(pn))
File.Delete(pn);
File.Move(po, pn);
}
catch
{
res = false;
}
}
return res;
}
public static bool ExportShp2(string pathLayerIn, SpatialQueryFilter filter, string nameShp, string outpath, IprocessManager cps, ArcGIS.Core.Geometry.SpatialReference sr = null, int incmax = 100)
{
if (!System.IO.Directory.Exists(outpath))
System.IO.Directory.CreateDirectory(outpath);
FeatureClass fc = null;
bool debug = false;
/////////////////////////////////////////////////////////
//Prepara una where_clause con las entidades que cumplen el filtro
//Abre la featureclass
try
{
if (debug)
HelperGlobal.ponMsg("pathLayerIn " + pathLayerIn);
fc = GetFtClassSync(pathLayerIn);
if (fc == null)
{
OutStr = "Error al abrir Feature Class en exportación";
return false;
}
List<long> ids = new List<long>();
if (debug)
HelperGlobal.ponMsg("fc " + fc.GetName() + " tipo " + fc.GetType().Name);
/////////////////////////////////////////////////////////
//Añade a la lista los ids que cumplen el filtro espacial
try
{
ids = fc.Select(filter, SelectionType.ObjectID, SelectionOption.Normal).GetObjectIDs().ToList();
}
catch(Exception ex)
{
OutStr = "Error al seleccionar IDs. "+ex.Message;
ids = new List<long>();
}
/*using (RowCursor cursor = fc.Search(filter))
{
while (cursor.MoveNext() && !cps.Getcancelled())
{
using (Feature feature = (Feature)cursor.Current)
{
ids.Add(feature.GetObjectID());
}
}
}*/
if (ids.Count <= 0)
{
OutStr = "Error al aplicar filtro espacial en exportación: "+ OutStr;
return false;
}
/////////////////////////////////////////////////////////
if (cps.Getcancelled())
{
OutStr = Resource1.String_cancel_progreso;
return false;
}
//convierte la lista de ids a string para la clause de la forma
//(id1, id2, id3..)
string whereClause = GetWhereClauseFromIds(ids,fc.GetDefinition().GetObjectIDField());
///////////////////////////////////////////////////////////
///Exporta
string[] args = { pathLayerIn, outpath, nameShp, whereClause };
// execute the tool
if (sr == null)
{
sr = fc.GetDefinition().GetSpatialReference();
}
var environments = Geoprocessing.MakeEnvironmentArray(outputCoordinateSystem: sr);
//SpatialReferenceBuilder.CreateSpatialReference(3857)
double valini = cps.GetProgress();
var gpres = Geoprocessing.ExecuteToolAsync("FeatureClassToFeatureClass_conversion", args,
environments, null,
(event_name, o) => // implement delegate and handle events
{
switch (event_name)
{
case "OnValidate": // stop execute if any warnings
//if ((o as IGPMessage[]).Any(it => it.Type == GPMessageType.Warning))
//_cts.Cancel();
break;
case "OnProgressMessage":
{
string msg = string.Format("{0}: {1}", new object[] { event_name, (string)o });
Debug.WriteLine(msg); ;
}
break;
case "OnProgressPos":
{
string msg2 = string.Format("{0}: {1} %", new object[] { event_name, (int)o });
Debug.WriteLine(msg2);
var av = (int)o;
if (av > 0)
{
cps.SetProgress(valini + (Math.Min((double)av / 100.0, 100.0) * Math.Min(incmax, 100 - valini)));
}
// if ((int)o < 0)
//System.Windows.MessageBox.Show(msg2);
//_cts.Cancel();
break;
}
}
});
while (!gpres.IsCompleted && !gpres.IsCanceled && !gpres.IsFaulted)
Thread.Sleep(10);
IGPResult gpResult = gpres.Result;
if (gpResult.IsCanceled)
{
cps.Setcancelled();
return false;
}
if (gpResult.IsFailed)
{
string msg;
if (gpResult.ErrorMessages != null)
msg = gpResult.ErrorMessages.First().Text;
else
msg = "Errores en la exportación";
OutStr = "Error: " + msg;
return false;
}
gpres.Dispose();
return true;
}
catch (Exception ex)
{
OutStr = "Error: " + ex.Message;
return false;
}
finally
{
Free(fc);
}
}
public static bool ExportShp(string pathLayerIn, SpatialQueryFilter filter, string nameShp, string outpath, CancelableProgressorSource cps, out string msgOut, ProgressorSource progrDialog = null)
{
msgOut = "";
if (!System.IO.Directory.Exists(outpath))
System.IO.Directory.CreateDirectory(outpath);
//fc.
/*
using (RowCursor rowCursor = fc.Search(filter))
{
while (rowCursor.MoveNext())
{
using (Row row = rowCursor.Current)
{
if (row is Feature ft)
{
var sh = ft.GetShape();
sh = ft.GetShape();
sh.
}
}
}
}*/
//Selection selFeatures = featureClass.Select(filter, SelectionType.ObjectID, SelectionOption.Normal);
// make a value array of strings to be passed to ExecuteToolAsync
/*
System.Threading.CancellationTokenSource _cts1 = new System.Threading.CancellationTokenSource();
cps.Status = "Guardando geometria a shp";
string[] args1 = { pathLayerIn, outpath };
IGPResult gpResult1 = Geoprocessing.ExecuteToolAsync("FeatureClassToFeatureClass", args1,
null, _cts1.Token,
(event_name, o) => // implement delegate and handle events
{
switch (event_name)
{
case "OnValidate":
break;
case "OnProgressMessage":
{
string msg = string.Format("{0}: {1}", new object[] { event_name, (string)o });
//progrDialog.Message = (string)o;
Debug.WriteLine(msg);
}
break;
case "OnProgressPos":
{
string msg2 = string.Format("{0}: {1} %", new object[] { event_name, (int)o });
Debug.WriteLine(msg2);
break;
}
}
}).Result;
*/
cps.Status = "Guardando geometria a shp";
string[] args = { pathLayerIn, outpath };
// execute the tool
IGPResult gpResult = Geoprocessing.ExecuteToolAsync("FeatureClassToShapefile_conversion", args,
null, cps.CancellationTokenSource.Token,
(event_name, o) => // implement delegate and handle events
{
switch (event_name)
{
case "OnValidate": // stop execute if any warnings
//if ((o as IGPMessage[]).Any(it => it.Type == GPMessageType.Warning))
//_cts.Cancel();
break;
case "OnProgressMessage":
{
string msg = string.Format("{0}: {1}", new object[] { event_name, (string)o });
//progrDialog.Message = (string)o;
Debug.WriteLine(msg);
;
//System.Windows.MessageBox.Show(msg);
//_cts.Cancel();
}
break;
case "OnProgressPos":
{
string msg2 = string.Format("{0}: {1} %", new object[] { event_name, (int)o });
Debug.WriteLine(msg2);
var av = (int)0;
if (av > 0)
{
cps.Value = (uint)(80 * av * 0.2);
}
// if ((int)o < 0)
//System.Windows.MessageBox.Show(msg2);
//_cts.Cancel();
break;
}
}
}).Result;
cps.Status = "Finalizando exportacion";
//renombrado de ficheros:
if (!RenameSHP(outpath, pathLayerIn, nameShp))
{
msgOut = "Error al exportar a shp.";
return false;
}
/*
//filtra entidades---
var pn = string.Format("{0}{1}.{2}", pathLayerIn, nameShp);
FeatureClass fc = HelperGdb.GetFtClass(pn);
var f = new ArcGIS.Core.Data.QueryFilter();
//f.
fc.DeleteRows*/
return true;
}
/**
* Comprueba si un punto está contenido en un polígono
*/
public static Respuesta<bool> IsPtoInGeom(Coordinate2D pto, ArcGIS.Core.Geometry.Geometry geom)
{
Respuesta<bool> resp = new Respuesta<bool>();
try
{
//ArcGIS.Core.Geometry.Geometry geom_convexhull = GeometryEngine.Instance.ConvexHull(geom);
//ArcGIS.Core.Geometry.Polygon poli = (ArcGIS.Core.Geometry.Polygon)geom_convexhull;
ArcGIS.Core.Geometry.Polygon poli = (ArcGIS.Core.Geometry.Polygon)geom;
bool contains = GeometryEngine.Instance.Contains(poli, pto.ToMapPoint());
resp.Value = contains;
return resp;
}
catch
{
resp.Value = false;
resp.Error.Add("Error al comprobar si punto está contenido en polígono");
return resp;
}
}
/**
* Amplía la geometría para añadirele buffer
*/
public static Respuesta<ArcGIS.Core.Geometry.Geometry> BufferGeom(ArcGIS.Core.Geometry.Geometry geom, double buffer)
{
Respuesta<ArcGIS.Core.Geometry.Geometry> resp = new Respuesta<ArcGIS.Core.Geometry.Geometry>();
ArcGIS.Core.Geometry.Geometry geomBuff = null;
try
{
geomBuff = GeometryEngine.Instance.Buffer(geom, buffer);
}
catch
{
}
resp.Value = geomBuff;
return resp;
}
/**Amplía la geometría para que incluya el punto
*/
public static Respuesta<ArcGIS.Core.Geometry.Geometry> AddPtoInGeom(Coordinate2D pto, ArcGIS.Core.Geometry.Geometry geom, int buff=100)
{
Respuesta<ArcGIS.Core.Geometry.Geometry> resp = new Respuesta<ArcGIS.Core.Geometry.Geometry>();
double buffer = 0;//m de distancia desde la instalación
bool repite = true;
ArcGIS.Core.Geometry.Geometry geom_pto, geom_sal;
try
{
/*do
{
buffer += buff;
geom_pto = GeometryEngine.Instance.Buffer(pto.ToMapPoint(), buffer);
if (geom_pto == null || geom_pto.IsEmpty)
{
resp.Value = null;
resp.Error.Add("Error al bufferear punto para incluirlo en polígono");
return resp;
}
//hace la convex hull, por si no fueran conexas las zonas
repite = GeometryEngine.Instance.Disjoint(geom_pto, geom);
/*if (geom_aux == null || geom_aux.IsEmpty)
{
ArcGIS.Core.Geometry.Envelope env1 = geom_sal.Extent;
ArcGIS.Core.Geometry.Envelope env2 = geom_pto.Extent;
ArcGIS.Core.Geometry.Envelope env3 = env1.Union(env2);
geom_sal = (ArcGIS.Core.Geometry.Geometry) env3;
//geom_sal = GeometryEngine.Instance.Envelope(geom_sal);
if (geom_sal == null || geom_sal.IsEmpty)
{
resp.Value = null;
resp.Error.Add("Error al hacer envolvente en unir punto al polígono");
return resp;
}
}
}
while (repite);*/
buffer = buff;
geom_pto = GeometryEngine.Instance.Buffer(pto.ToMapPoint(), buffer);
if (geom_pto == null || geom_pto.IsEmpty)
{
resp.Value = null;
resp.Error.Add("Error al bufferear punto para incluirlo en polígono");
return resp;
}
geom_sal = GeometryEngine.Instance.Union(geom_pto, geom);
geom_sal = GeometryEngine.Instance.ConvexHull(geom_sal);
if (geom_sal == null || geom_sal.IsEmpty)
{
resp.Value = null;
resp.Error.Add("Error al unir punto a polígono");
return resp;
}
resp.Value = geom_sal;
return resp;
}
catch
{
resp.Value = null;
resp.Error.Add("Error al incluir punto en polígono");
return resp;
}
}
/*
* Dada una lista de ids de elemento, crea una consulta en la que se llama a todos esos elementos
* campo IN (id1, id2, id3..)
*/
public static string GetWhereClauseFromIds(List<long> ids, string ObjectId = "OBJECTID")
{
if (ids.Count <= 0)
return string.Empty;
//string ids_str = "("+;
return ObjectId+" IN (" + String.Join(",", ids) + ")";
/*
bool first = true;
foreach (long i in ids)
{
if (first)
{
ids_str += i.ToString();
first = false;
}
else
ids_str += "," + i.ToString();
}
//el último
ids_str += ")";*/
//string whereClause = ObjectId + " IN " + ids_str; //Cambiar id a otro sitio
//return whereClause;
/*string consulta, orstr;
consulta = string.Empty;
orstr = string.Empty;
var n = ids.Count;
for (int i = 0; i < n; i++)
{
consulta = consulta + orstr + "(" + RecogidaDef.campos.cons_id + "=" + ids.ElementAt(i) + ")";
if (String.IsNullOrEmpty(orstr))
orstr = " OR ";
}
if (consulta == "()")
consulta = string.Empty;
return consulta;*/
}
/**
* Elimina las filas indicadas del shp
**/
public static bool RemoveRowsFromShp(FeatureClass fc, List<long> quita)
{
//Crea la consulta
var consulta = GetWhereClauseFromIds(quita, fc.GetDefinition().GetObjectIDField());
if (String.IsNullOrEmpty(consulta))
return false;
string message = String.Empty;
bool deletionResult = false;
var task = ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
EditOperation editOperation = new EditOperation();
editOperation.Callback(context =>
{
ArcGIS.Core.Data.QueryFilter openCutFilter = new ArcGIS.Core.Data.QueryFilter { WhereClause = consulta };
using (RowCursor rowCursor = fc.Search(openCutFilter, false))
{
while (rowCursor.MoveNext())
{
using (Row row = rowCursor.Current)
{
// In order to update the Map and/or the attribute table. Has to be called before the delete.
context.Invalidate(row);
row.Delete();
}
}
}
}, fc);
try
{
deletionResult = editOperation.Execute();
if (!deletionResult)
{
message = editOperation.ErrorMessage;
}
}
catch (GeodatabaseException exObj)
{
message = exObj.Message;
}
});
task.Wait();
if (!string.IsNullOrEmpty(message))
{
OutStr = message;
return false;
}
else
return true;
/*FeatureClass fc = HelperGdb.GetFtClassFromShp(shp_path).Result;
if (fc == null)
return false;
//Crea la consulta
var consulta = GetWhereClauseFromIds(quita);
if (String.IsNullOrEmpty(consulta))
return false;
string message = String.Empty;
bool deletionResult = false;
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() => {
string shpname = System.IO.Path.GetFileNameWithoutExtension(shp_path);
var shapeFileConnPath = new FileSystemConnectionPath(new Uri(System.IO.Path.GetDirectoryName(shp_path)),
FileSystemDatastoreType.Shapefile);
var shapefile = new FileSystemDatastore(shapeFileConnPath);
using (Table table = shapefile.OpenDataset<Table>(shp_path))
{
EditOperation editOperation = new EditOperation();
editOperation.Callback(context =>
{
ArcGIS.Core.Data.QueryFilter openCutFilter = new ArcGIS.Core.Data.QueryFilter { WhereClause = consulta };
using (RowCursor rowCursor = table.Search(openCutFilter, false))
{
while (rowCursor.MoveNext())
{
using (Row row = rowCursor.Current)
{
// In order to update the Map and/or the attribute table. Has to be called before the delete.
context.Invalidate(row);
row.Delete();
}
}
}
}, table);
try
{
deletionResult = editOperation.Execute();
if (!deletionResult)
{
message = editOperation.ErrorMessage;
}
}
catch (GeodatabaseException exObj)
{
message = exObj.Message;
}
}
});
if (!string.IsNullOrEmpty(message))
{
OutStr = message;
return false;
}
else
return true;
*/
}
/**
* Recorre los ámbitos lineales del shp viendo qué longitud tienen dentro de la geometría, y si
* es menos de un porcentaje, lo quitan del shp
**/
public static bool RemoveRowsGeom(string shp_path, ArcGIS.Core.Geometry.Geometry geom_zon, double porc)
{
FeatureClass fc = HelperGdb.GetFtClassFromShp(shp_path).Result;
if (fc == null)
return false;
ArcGIS.Core.Geometry.Geometry geom = null;
ArcGIS.Core.Geometry.Polyline line = null;
Feature f = null;
double longi_zon = 0, longi_tot = 0;
List<long> quita = new List<long>();
int j = 0;
List<long> ids;
try
{
//Obtiene los IDs
ids = GetIds(fc, null).Result;
//Recorre las features de la capa
RowCursor cursor = fc.Search();
while (cursor.MoveNext())
{
f = (Feature)cursor.Current;
geom = f.GetShape();
line = (ArcGIS.Core.Geometry.Polyline)geom;
longi_tot = line.Length;
geom = IntersectGeom(geom_zon, line, GeometryDimensionType.EsriGeometry1Dimension);//GeometryDimension.esriGeometry1Dimension);
line = (ArcGIS.Core.Geometry.Polyline)geom;
longi_zon = line.Length;//se consigue la longitud de ámbito (linea) que interseca con el nivel)
if ((longi_zon / longi_tot) < porc)
{
//quita esa línea
quita.Add(ids[j]);
}
j++;
Free(f);
}
Free(f);
Free(cursor);
//comprueba que no se haya quedado sin ámbitos
if (quita.Count >= fc.GetCount())
{
OutStr = "No quedan ámbitos que cumplan la geometría seleccionada.";
return false;
}
//Quita los ámbitos del shp
if (quita.Count > 0)
{
//borra las líneas que se han indicado
if (!RemoveRowsFromShp(fc, quita))
return false;
}
Free(fc);
return true;
}
catch (Exception)
{
return false;
}
finally
{
HelperGdb.Free(fc);
HelperGdb.Free(f);
}
}
/**
* Dado un nombre de capa mira si está abierta y la cierra
*/
public static bool CloseLayer(string nombCapa)
{
try
{
var lyr = MapView.Active.Map.FindLayers(nombCapa).FirstOrDefault() as FeatureLayer;
if (lyr!= null)
MapView.Active.Map.RemoveLayer(lyr);
return true;
}
catch (Exception ex)
{
return false;
}
}
/**
* Cierra todas las capas abiertas
*/
public static bool CloseAllLayers()
{
try
{
ReadOnlyObservableCollection<Layer> lyrs= MapView.Active.Map.Layers;
while(lyrs.Any())
{
var fl = lyrs.FirstOrDefault();
if (fl != null)
MapView.Active.Map.RemoveLayer(fl);
}
return true;
}
catch (Exception)
{
return false;
}
}
/**
* Saca diálogo para guardar un archivo
*/
public static string SaveFileDlg(string title_, string initloc_, string ext_, string filt_, BrowseProjectFilter brwsFilt = null)
{
//Display the filter in an Open Item dialog
SaveItemDialog dlg = new SaveItemDialog
{
Title = title_,
OverwritePrompt = true,
};
if (!string.IsNullOrEmpty(initloc_))
dlg.InitialLocation = initloc_;
else
dlg.AlwaysUseInitialLocation = false;
if (!string.IsNullOrEmpty(filt_))
dlg.Filter = filt_;
if (!string.IsNullOrEmpty(ext_))
dlg.DefaultExt = ext_;
if (brwsFilt != null)
{
brwsFilt.BrowsingFilesMode = true;
dlg.BrowseFilter = brwsFilt;
}
try
{
bool? ok = dlg.ShowDialog();
if ((ok ?? true) && dlg.FilePath.Length > 0)
return dlg.FilePath;
else
return string.Empty;
}
catch(Exception ex)
{
return string.Empty;
}
}
/**
* Saca diálogo para elegir directorio
*/
public static string FolderBrowseDlg(string title_, string initloc_)
{
var openFileDialog = new CommonOpenFileDialog();
//{ IsFolderPicker = true };
if(!String.IsNullOrEmpty(initloc_))
openFileDialog.InitialDirectory = initloc_;
openFileDialog.IsFolderPicker = true;
//openFileDialog.InitialDirectory = initloc_;
openFileDialog.Title = title_;
//openFileDialog.Filter = "Folders";
//if (openFileDialog.ShowDialog() == true)
if (openFileDialog.ShowDialog() == CommonFileDialogResult.Ok)
return openFileDialog.FileName;
return null;
}
/**
* Comprueva si existe un Dataset, con ruta completa
*/
public static Task<bool> CheckDataset(string datasetName)
{
return ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run((Func<bool>)(() =>
{
if (string.IsNullOrEmpty(datasetName))
return false;
try
{
Geodatabase gdb = GetGdbSync(datasetName);
if (gdb == null)
return false;
var datname = new System.IO.DirectoryInfo(datasetName).Name;
FeatureDataset ftdst = gdb.OpenDataset<FeatureDataset>(datname);
ftdst.Dispose();
return true;
}
catch
{
return false;
}
}));
}
/**
* Comprueva si una GDB contiene un Dataset
*/
public static Task<bool> CheckDataset(Geodatabase gdb, string datasetName)
{
return ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run((Func<bool>)(() =>
{
try
{
FeatureDataset ftdst = gdb.OpenDataset<FeatureDataset>(datasetName);
ftdst.Dispose();
return true;
}
catch
{
return false;
}
}));
}
/**
* Comprueba si el dataset dado tiene la referencia espacial dada
* Devuelve 0 si es la misma, 2 si no es la misma, 1 si ha dado error
*/
public static Task<int> CheckSpatRefDataset(Geodatabase gdb, string datasetName, ArcGIS.Core.Geometry.SpatialReference spatref)
{
return ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run((Func<int>)(() =>
{
try
{
FeatureDatasetDefinition featureDatasetDefinition = gdb.GetDefinition<FeatureDatasetDefinition>(datasetName);
ArcGIS.Core.Geometry.SpatialReference entr = featureDatasetDefinition.GetSpatialReference();
if (entr.Wkid==spatref.Wkid)
return 0;
return 2;
}
catch (Exception ex)
{
return 1;
}
}));
}
/**
* Crea un FeatureDataset con el nombre dado y la spatialrefernece dada en la gdb dada
* Devuelve 0 si no hay que crear nada, existe y coincide ref espac
* 2 si existe el dataset pero con otra referencia espacial, así que se crea otro
* 1 si da error
* 4 si no existe así que se crea
*/
public static Respuesta<int> CreateDataset(string gdbPath, string datasetName, ArcGIS.Core.Geometry.SpatialReference spatref, out string datasetNameOut)
{
Respuesta<int> res = new Respuesta<int> { Value = 1 };
datasetNameOut = string.Empty;
Geodatabase gdb = null;
FeatureDatasetDefinition featureDatasetDefinition = null;
try
{
gdb = GetGdb(gdbPath).Result;
if (gdb == null)
{
res.Value = 1;
res.Error.Add("Error al abrir la gdb " + gdbPath);
return res;
}
//comprueba si extiste ya el dataset
bool repite = false;
bool crea = false;
int idat = 1;
int r = 2;
bool refspatdif = false;
while(r==2)
{
var task1 = CheckDataset(gdb, datasetName);
task1.Wait();
if (task1.Result)
{
//comprueba si tiene la misma referencia espacial
r = CheckSpatRefDataset(gdb, datasetName, spatref).Result;
if (r == 0)
{
res.Value = 0; //no hay nada que crear, existe y coincide la spatial ref
//return res;
}
else if (r == 2)
{
//existe ese nombre, pero con otra ref espacial
//crea un nuevo dataset y avisa
datasetName = string.Format("{0}_{1}",datasetName,idat);
refspatdif = true;
idat++;
}
else//r==1
{
//ha dado error al comprobar
res.Value = 1;
res.Error.Add("Errores al crear el Dataset " + datasetName);
//return res;
}
}
else
r = 3; //no existe, lo crea con ese nombre
};
datasetNameOut = datasetName;
if (r!=3)
return res;
//no existe, lo crea
var task = ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run((Func<Respuesta<bool>>)(() =>
{
Respuesta<bool> res2 = new Respuesta<bool> { Value = false };
SchemaBuilder schemaBuilder = null;
try
{
schemaBuilder = new SchemaBuilder(gdb);
// Create a FeatureDataset
FeatureDatasetDescription featureDatasetDescription = new FeatureDatasetDescription(datasetName, spatref);
schemaBuilder.Create(featureDatasetDescription);
// Build status
res2.Value = schemaBuilder.Build();
if (!res2.Value && schemaBuilder.ErrorMessages.Count > 0)
res2.Error.Add(schemaBuilder.ErrorMessages.FirstOrDefault());
return res2;
}
catch
{
if (schemaBuilder != null && schemaBuilder.ErrorMessages.Count > 0)
res2.Error.Add(schemaBuilder.ErrorMessages.FirstOrDefault());
else
res2.Error.Add("Error 1 al crear Dataset.");
return res2;
}
}));
task.Wait();
if (task.Result.Value)//ha ido bien
{
//avisa
if (refspatdif)
res.Value = 2;
else
res.Value = 4;
//actualiza la gdb
Refresh(gdbPath);
}
else// Build errors
{
res.Value = 1;
res.Error.Add(task.Result.Error.FirstOrDefault());
}
return res;
}
catch (Exception ex)
{
res.Value = 1;
res.Error.Add("Errores al crear el Dataset " + datasetName + " " + ex.Message);
return res;
}
finally
{
Free(featureDatasetDefinition);
Free(gdb);
}
}
/**
* Importa el shp en la gdb y el dataset, como una featureclass
*/
public static Respuesta<bool> ImportShp(string nom_shp, string Gdb_dataset, string namefc)
{
var res = new Respuesta<bool> { Value = false };
string[] args = { nom_shp, Gdb_dataset, namefc };
// execute the tool
try
{
ArcGIS.Core.Geometry.SpatialReference spatref = GetSpatRef(nom_shp);
var environments = Geoprocessing.MakeEnvironmentArray(outputCoordinateSystem: spatref);
//CancelableProgressorSource cps = new CancelableProgressorSource();
var _cts = new System.Threading.CancellationTokenSource();
var completa = false;
var gpres = Geoprocessing.ExecuteToolAsync("FeatureClassToFeatureClass_conversion", args, environments, _cts.Token,
(event_name, o) => // implement delegate and handle events
{
switch (event_name)
{
case "OnValidate": // stop execute if any warnings
//if ((o as IGPMessage[]).Any(it => it.Type == GPMessageType.Warning))
//_cts.Cancel();
break;
case "OnProgressMessage":
{
string msg = string.Format("{0}: {1}", new object[] { event_name, (string)o });
Debug.WriteLine(msg); ;
}
break;
case "OnProgressPos":
{
string msg2 = string.Format("{0}: {1} %", new object[] { event_name, (int)o });
Debug.WriteLine(msg2);
var av = (int)o;
if ((int)o < 0)
{
//completa = true;
//System.Windows.MessageBox.Show(msg2);
// _cts.Cancel();
}
break;
}
}
});
while (!gpres.IsCompleted && !gpres.IsCanceled && !gpres.IsFaulted)
Thread.Sleep(10);
if (gpres.IsCanceled)
{
return res;
}
if (gpres.IsFaulted)
{
var gpResult = gpres.Result;
string msg;
if (gpResult.ErrorMessages != null)
msg = gpResult.ErrorMessages.First().Text;
else
msg = "Errores en la importación";
res.Error.Add("Error: " + msg);
return res;
}
/*
_cts.Cancel();
for (int ii = 0; ii < 1000; ii++)
{
if (gpres.IsCompleted && gpres.IsCanceled && gpres.IsFaulted)
break;
Thread.Sleep(10);
}
try
{
if (!gpres.IsCompleted && !gpres.IsCanceled && !gpres.IsFaulted)
gpres.Dispose();
}
catch (Exception e)
{
string msg = "";
msg = e.Message;
}*/
res.Value = true;
gpres.Dispose();
//actualiza la gdb
Refresh(System.IO.Path.GetDirectoryName(Gdb_dataset));
return res;
}
catch (Exception ex)
{
res.Error.Add("Error: " + ex.Message);
return res;
}
}
/**
* Borrar una feature class de un dataset
* Devuelve -1 si da error al abrir la gdb, -2 si da error al abrir el ftclass (igual porque no existe)
* y 0 si da error el proceso de borrar, y 1 si va todo bien
*/
public static Respuesta<int> DeleteFeatureClassSync(string gdbPathDataset, string featureClassName)
{
var res = new Respuesta<int> { Value = 0 };
Geodatabase gdb = GetGdbSync(gdbPathDataset);
if (gdb == null)
{
res.Value = -1;
return res;
}
FeatureClass ftclss = GetFtClassSync(gdbPathDataset + " \\"+ featureClassName);
if (ftclss == null)
{
res.Value = -2;
return res;
}
Respuesta<bool> resp = new Respuesta<bool> { Value = false };
SchemaBuilder schemaBuilder = null;
try
{
// Create a FeatureClassDescription object
FeatureClassDescription featureClassDescription = new FeatureClassDescription(ftclss.GetDefinition());
// Create a SchemaBuilder object
schemaBuilder = new SchemaBuilder(gdb);
// Add the deletion fo the feature class to our list of DDL tasks
schemaBuilder.Delete(featureClassDescription);
// Execute the DDL
resp.Value = schemaBuilder.Build();
if (!resp.Value && schemaBuilder.ErrorMessages.Count > 0)
resp.Error.Add(schemaBuilder.ErrorMessages.FirstOrDefault());
}
catch
{
resp.Error.Add(schemaBuilder.ErrorMessages.FirstOrDefault());
}
if (resp.Value)
res.Value = 1;
else
{
res.Error.Add(resp.Error.FirstOrDefault());
}
Free(gdb);
Free(ftclss);
return res;
}
/**
* Borrar una feature class de un dataset
*/
public static Respuesta<bool> DeleteFeatureClass(string gdbPathDataset, string featureClassName)
{
var res = new Respuesta<bool> { Value = false };
Geodatabase gdb = GetGdb(gdbPathDataset).Result;
if (gdb == null)
return res;
FeatureClass ftclss = GetFtClass(gdbPathDataset + " \\" + featureClassName);
if (ftclss == null)
return res;
var task = ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run((Func<Respuesta<bool>>)(() =>
{
Respuesta<bool> resp = new Respuesta<bool> { Value = false };
SchemaBuilder schemaBuilder = null;
try
{
// Create a FeatureClassDescription object
FeatureClassDescription featureClassDescription = new FeatureClassDescription(ftclss.GetDefinition());
// Create a SchemaBuilder object
schemaBuilder = new SchemaBuilder(gdb);
// Add the deletion fo the feature class to our list of DDL tasks
schemaBuilder.Delete(featureClassDescription);
// Execute the DDL
resp.Value = schemaBuilder.Build();
if (!resp.Value && schemaBuilder.ErrorMessages.Count > 0)
resp.Error.Add(schemaBuilder.ErrorMessages.FirstOrDefault());
return resp;
}
catch
{
resp.Error.Add(schemaBuilder.ErrorMessages.FirstOrDefault());
return resp;
}
}));
if (task.Result.Value)
res.Value = true;
else
{
res.Error.Add(task.Result.Error.FirstOrDefault());
}
Free(gdb);
Free(ftclss);
return res;
}
/**
* Refresca la gdb después de añadir dataset y featureclass
*/
public static void Refresh(string gdbPath)
{
Item gdb = null;
try
{
gdb = ItemFactory.Instance.Create(gdbPath);
if (gdb == null)
return;
var contentItem = gdb;
//Check if the MCT is required for Refresh()
if (contentItem.IsMainThreadRequired)
{
//QueuedTask.Run must be used if item.IsMainThreadRequired
//returns true
QueuedTask.Run(() => contentItem.Refresh());
}
else
{
//if item.IsMainThreadRequired returns false, any
//thread can be used to invoke Refresh(), though
//BackgroundTask is preferred.
contentItem.Refresh();
//Or, via BackgroundTask
ArcGIS.Core.Threading.Tasks.BackgroundTask.Run(() =>
contentItem.Refresh(), ArcGIS.Core.Threading.Tasks.BackgroundProgressor.None);
}
}
catch
{
}
}
/**
* Abre en el mapa la capa seleccionada, con los parámetros seleccionados
*/
public static Respuesta<bool> OpenLayerUniqueValue(string ftclasspath, string campValUniq, bool visible = true)
{
var res = new Respuesta<bool> { Value = false };
var mapView = MapView.Active;
int indexNumber = mapView.Map.Layers.Count;
string ftclassname = System.IO.Path.GetFileNameWithoutExtension(ftclasspath);
if (mapView != null)//Check if there is a map
{
try
{
System.Uri ftclass_uri = new System.Uri(ftclasspath); //creating uri for the ftclass
//mira el tipo de geometría
GeometryType tipo = GetGeomType(ftclasspath);
if (tipo == GeometryType.Unknown)
{
res.Error.Add("Tipo de geometría desconocido en la capa a importar");
return res;
}
var task = QueuedTask.Run(() =>
{
Layer layer = null;
FeatureLayer selectedLayer = null;
try
{
layer = mapView.Map.FindLayers(ftclassname).FirstOrDefault();
}
catch
{
layer = null;
}
if (layer == null)
{
layer = LayerFactory.Instance.CreateLayer(ftclass_uri, mapView.Map, indexNumber, ftclassname);
//selectedLayer = mapView.GetSelectedLayers()[0] as FeatureLayer;
}
selectedLayer = layer as FeatureLayer;
//Do something with selected layer
SetSimpleRendererPoint(selectedLayer, campValUniq, tipo);
selectedLayer.SetVisibility(visible);
});
task.Wait();
}
catch
{
res.Error.Add("Errores en creación de renderer para valor único");
return res;
}
}
res.Value = true;
return res;
}
/*
* Crea el renderer para la capa, dado un campo en el que fijarse y una simbología
*/
internal static void SetSimpleRendererPoint(FeatureLayer featureLayer, string field, GeometryType tipo)
{
if (featureLayer == null)
return;
//QueuedTask.Run(() =>
//{
try
{
List<String> fields = new List<string>();
fields.Add(field);
UniqueValueRendererDefinition uniqueValueRendererDef;
CIMSymbolReference symbolTemplate=new CIMSymbolReference();
if (tipo == GeometryType.Point)//puntual
{
CIMPointSymbol pointSym = SymbolFactory.Instance.ConstructPointSymbol(
ColorFactory.Instance.GreenRGB, 10.0, SimpleMarkerStyle.Circle); //constructing a point symbol as a template symbol
symbolTemplate = pointSym.MakeSymbolReference();
}
else if(tipo== GeometryType.Polyline)//lineal
{
CIMLineSymbol lineSym = SymbolFactory.Instance.ConstructLineSymbol(ColorFactory.Instance.GreenRGB, 3);
symbolTemplate = lineSym.MakeSymbolReference();
}
//constructing renderer definition for unique value renderer
uniqueValueRendererDef = new UniqueValueRendererDefinition(fields, symbolTemplate);
//creating a unique value renderer
CIMUniqueValueRenderer uniqueValueRenderer = (CIMUniqueValueRenderer)featureLayer.CreateRenderer(uniqueValueRendererDef);
//setting the renderer to the feature layer
featureLayer.SetRenderer(uniqueValueRenderer);
}
catch (Exception ex)
{
}
//});
}
public static GeometryType GetGeomType(string ftclassName)
{
FeatureClass ftcl = GetFtClass(ftclassName);
GeometryType tipo = GeometryType.Unknown;
if (ftcl == null)
return tipo ;
var task = QueuedTask.Run(() =>
{
tipo = ftcl.GetDefinition().GetShapeType();
});
task.Wait();
Free(ftcl);
return tipo;
}
/*
* Renombra un campo de la feature class dada
*/
public static bool RenameFieldSync(string fcname, string oldFieldName, string newFieldName, string newFieldAlias)
{
bool res = false;
string[] args = { fcname, oldFieldName, newFieldName,newFieldAlias };
// execute the tool
try
{
var gpres = Geoprocessing.ExecuteToolAsync("management.AlterField", args);
while (!gpres.IsCompleted && !gpres.IsCanceled && !gpres.IsFaulted)
Thread.Sleep(10);
if (!gpres.IsCompletedSuccessfully)
{
var gpResult = gpres.Result;
string msg;
if (gpResult.ErrorMessages != null)
msg = gpResult.ErrorMessages.First().Text;
else
msg = "Errores al renombrar campo "+newFieldName;
}
else
res= true; //ha ido bien
gpres.Dispose();
return res;
}
catch
{
}
return res;
}
public struct FieldToAdd
{
public string Name;
public string Tipo; //LONG, TEXT, ...
public string Alias;
public int Length;
public FieldToAdd(string nomb, string tip, string al, int len)
{
Name = nomb; //obligatorio
Tipo = tip; //obligatorio
Alias = al;
Length = len;
}
}
/*
* Renombra un campo de la feature class dada
*/
public static bool AddFieldsSync(string fcname, FieldToAdd[] fields)
{
bool res = false;
// set up the arguments
string fields_str = "";
int camps = 0;
for(int i=0;i<fields.Length;i++)
{
if (CheckFieldSync(fcname, fields[i].Name))
continue;
camps++;
fields_str += fields[i].Name + " " + fields[i].Tipo + " ";
if (!string.IsNullOrEmpty(fields[i].Alias))
fields_str += fields[i].Alias;
else
fields_str += "#";
fields_str += " ";
if (fields[i].Length != 0)
fields_str += fields[i].Length;
else
fields_str += "#";
fields_str += " #"; //def value siempre #
if (i < fields.Length - 1)
fields_str += ";";
}
if (camps == 0)
return true;//no tiene que añadir ningún campo porque los tiene
//var f1 = "field1 long field1 # #;field2 Text # 255 myDefaultValue"; //los # son opciones sin rellenar el orden es: Nombre Tipo Alias Longitud Valor Defecto
var args = Geoprocessing.MakeValueArray(fcname, fields_str);
// run the tool
try
{
var gpres = Geoprocessing.ExecuteToolAsync("management.AddFields", args);
while (!gpres.IsCompleted && !gpres.IsCanceled && !gpres.IsFaulted)
Thread.Sleep(10);
if (gpres.IsFaulted)
{
var gpResult = gpres.Result;
string msg;
if (gpResult.ErrorMessages != null)
msg = gpResult.ErrorMessages.First().Text;
else
msg = "Errores al añadir campos";
}
else
res = true; //ha ido bien
gpres.Dispose();
return res;
}
catch
{
}
return res;
}
public static bool ExplodeAll(string pahtFc)
{
/*
var ft = GetFtClassSync(pahtFc);
var ids=ft.Select(new ArcGIS.Core.Data.QueryFilter() { WhereClause = "true" }, SelectionType.ObjectID, SelectionOption.Normal).GetObjectIDs().ToList();
var explodeFeatures = new EditOperation();
explodeFeatures.Name = "Explode Features";
//Take a multipart and convert it into one feature per part
//Provide a list of ids to convert multiple
explodeFeatures.Explode(ft, ids, true);
//Execute to execute the operation
//Must be called within QueuedTask.Run
if (!explodeFeatures.IsEmpty)
{
var result = explodeFeatures.Execute(); //Execute and ExecuteAsync will return true if the operation was successful and false if not
}
return true;
//or use async flavor
//await explodeFeatures.ExecuteAsync();
*/
return true;
}
/*
* Añadir columna calculada
*/
public static bool CalculateFieldsSync(string fcname, string field, string sqlquery)
{
bool res = false;
var args = Geoprocessing.MakeValueArray(fcname, field, sqlquery, "ARCADE");
// run the tool
try
{
var gpres = Geoprocessing.ExecuteToolAsync("management.CalculateField", args);
while (!gpres.IsCompleted && !gpres.IsCanceled && !gpres.IsFaulted)
Thread.Sleep(10);
if (gpres.IsFaulted)
{
var gpResult = gpres.Result;
string msg;
if (gpResult.ErrorMessages != null)
msg = gpResult.ErrorMessages.First().Text;
else
msg = "Errores al calcular campo "+ field;
}
else
{
res = true; //ha ido bien
}
gpres.Dispose();
return res;
}
catch
{
}
return res;
}
}
}