OliviaAddIn/OliviaAddIn/Gdb/FunGDB.cs

1529 lines
48 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Collections;
using ESRI.ArcGIS.CatalogUI;
using ESRI.ArcGIS.Catalog;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geoprocessing;
//using ESRI.ArcGIS.Carto;
//using ESRI.ArcGIS.Display;
//using System.Drawing;
//using ESRI.ArcGIS.ADF.COMSupport;
/**
* @file FunGDB.cs
* Clase con funciones de tratamiento de la GDB
*/
/**
* Clase con funciones de tratamiento de la GDB
*/
namespace OliviaAddIn
{
public static class FunGDB
{
//**********************************************************************
//**********************************************************************
//Variables
//**********************************************************************
//Funciones
/**
* Lanza browser tipo catalog para seleccionar feature class
* Devuelve el path completo
*/
public static string selec_ftcls(String title, int parentWnd, string ini_loc = null)
{
string path = null;
IGxDialog gxdlg;
IEnumGxObject workspaces;
IGxObject gxobj = null;
gxdlg = new GxDialogClass();
gxdlg.ObjectFilter = new GxFilterFeatureClasses();
gxdlg.AllowMultiSelect = false;
gxdlg.Title = title;
gxdlg.ButtonCaption = "OK";
if (ini_loc != null)
{
gxdlg.set_StartingLocation(System.IO.Path.GetDirectoryName(ini_loc));
gxdlg.Name = System.IO.Path.GetFileNameWithoutExtension(ini_loc);
}
if (gxdlg.DoModalOpen(parentWnd, out workspaces) && workspaces != null)
{
gxobj = workspaces.Next();
path = gxobj.FullName;
}
else
{
path = null;
}
gxdlg.InternalCatalog.Close();
libera(workspaces);
libera(gxdlg);
return path;
}
/**
* Lanza browser tipo catalog para guardar feature class
* Devuelve el path completo
*/
public static string save_ftcls(string title, int parentWnd, string name_ini, out bool replacing, out string final_loc)
{
string path = null;
IGxDialog gxdlg;
replacing = false;
gxdlg = new GxDialogClass();
gxdlg.ObjectFilter = new GxFilterFeatureClasses();
gxdlg.AllowMultiSelect = false;
gxdlg.Title = title;
gxdlg.ButtonCaption = "OK";
gxdlg.set_StartingLocation(System.IO.Path.GetDirectoryName(name_ini));
gxdlg.Name=System.IO.Path.GetFileNameWithoutExtension(name_ini);
if (gxdlg.DoModalSave(parentWnd))
{
path = gxdlg.Name;
}
else
{
path = null;
}
replacing = gxdlg.ReplacingObject;
final_loc = gxdlg.InternalCatalog.SelectedObject.Name;
gxdlg.InternalCatalog.Close();
libera(gxdlg);
return path;
}
/**
* Lanza browser tipo catalog para seleccionar gdb
*/
public static IWorkspace selec_gdb(string title, int parentWnd, string reintentar_text = null)
{
IGxObject gxobj;
IGxDialog gxdlg;
IGxDatabase gxdb;
IEnumGxObject workspaces;
IWorkspace ws = null;
gxdlg = new GxDialogClass();
gxdlg.ObjectFilter = new GxFilterFileGeodatabasesClass();
gxdlg.AllowMultiSelect = false;
gxdlg.Title = title;
gxdlg.ButtonCaption = "OK";
if (gxdlg.DoModalOpen(parentWnd, out workspaces) && workspaces != null)
{
gxobj = workspaces.Next();
if (gxobj is IGxDatabase)
{
gxdb = (IGxDatabase)gxobj;
if (gxdb != null)
ws = gxdb.Workspace;
}
libera(workspaces);
}
else if (reintentar_text!=null)
{
if (DialogResult.Cancel == MessageBox.Show(reintentar_text, "Olivia", MessageBoxButtons.OKCancel, MessageBoxIcon.Question))
{
ws = selec_gdb(title, parentWnd);
}
else
return null;
}
gxdlg.InternalCatalog.Close();
libera(gxdlg);
return ws;
}
/**
* Devuelve el Feature Workspace dado el path de la clase o del directorio
*/
public static IFeatureWorkspace abre_ftws(string clase_path)
{
IWorkspace ws;
try
{
ws = abre_ws(clase_path);
if (ws == null)
return null;
IFeatureWorkspace feat_ws = (IFeatureWorkspace)ws;
return feat_ws;
}
catch (Exception)
{
return null;
}
}
/**
* Devuelve el IWorkspaceName dado el path de la clase o del directorio
*/
public static IWorkspaceName abre_wsn(string clase_path)
{
IWorkspace ws;
IDataset data;
IName name;
IWorkspaceName wsn;
try
{
ws = abre_ws(clase_path);
if (ws == null)
return null;
data = (IDataset)ws;
name = data.FullName;
wsn = (IWorkspaceName)name;
return wsn;
}
catch (Exception)
{
return null;
}
}
/**
* Devuelve el IWorkspace dado el path de la clase o del directorio
*/
public static IWorkspace abre_ws(string clase_path)
{
IWorkspaceFactory wsf;
IWorkspace ws;
GPUtilities gp = new GPUtilities();
string dir = null;
try
{
IGxObject obj;
/*
//Información
Category = "File Geodatabase Feature Class"
obj = (IGxObject)gp.GetGxObjectFromLocation("C:\\Olivia\\gdbs\\BASE DE DATOS MADRE.gdb\\Comun\\c_Instalaciones");
Category = "Shapefile"
obj = (IGxObject)gp.GetGxObjectFromLocation("c:\\Olivia\\otros_data\\data_F01_C00_20180430_154828_I.shp");
Category = "File Geodatabase"
obj = (IGxObject)gp.GetGxObjectFromLocation("C:\\Olivia\\gdbs\\BASE DE DATOS MADRE.gdb");
Category = "File Geodatabase Feature Dataset"
obj = (IGxObject)gp.GetGxObjectFromLocation("C:\\Olivia\\gdbs\\BASE DE DATOS MADRE.gdb\\Comun");
* */
obj = (IGxObject)gp.GetGxObjectFromLocation(clase_path);
if (obj.Category == "Shapefile") //clase_path=c://archivos..//capa.shp, por ejemplo
{
wsf = new ShapefileWorkspaceFactoryClass();
dir = obj.Parent.FullName;
}
else if (obj.Category == "File Geodatabase Feature Class")//clase_path=c://archivos..//datos.gdb//capa, por ejemplo
{
wsf = new FileGDBWorkspaceFactoryClass();
if (obj.Parent.Category == "File Geodatabase Feature Dataset")//mira si está en un dataset
dir = obj.Parent.Parent.FullName;
else if (obj.Parent.Category == "File Geodatabase")
dir = obj.Parent.FullName;
}
else if (obj.Category == "File Geodatabase")//clase_path=c://archivos..//datos.gdb, por ejemplo
{
wsf = new FileGDBWorkspaceFactoryClass();
dir = obj.FullName;
}
else if (obj.Category.Contains("Folder"))//clase_path=c://archivos.., por ejemplo
{
wsf = new ShapefileWorkspaceFactoryClass();
dir = obj.FullName;
}
else
return null;
if (dir == null)
return null;
ws = wsf.OpenFromFile(dir, 0);
return ws;
}
catch (Exception)
{
return null;
}
}
/**
* Dado el path completo dels shape a crear, devuelve el IFeatureClassName del shape
*/
public static IFeatureClassName crea_shp(string dir, string nomb)
{
IDatasetName shp_dsn = null;
IWorkspaceName shp_wsn = null;
IFeatureClassName shp_ftcn = null;
try
{
shp_ftcn = new FeatureClassNameClass();
shp_dsn = (IDatasetName)shp_ftcn;
shp_dsn.Name = nomb;
shp_wsn = abre_wsn(dir);
if (shp_wsn == null)
return null;
shp_dsn.WorkspaceName = shp_wsn;
}
catch (Exception)
{
return null;
}
return shp_ftcn;
}
/**
* Devuelve la Feature Class dado el path de la clase
* Hay que liberarla después de usarla
*/
public static IFeatureClass abre_ftclass(string clase_path)
{
IFeatureWorkspace feat_ws = abre_ftws(clase_path);
if (feat_ws == null)
return null;
IFeatureClass ftclass;
try
{
ftclass = feat_ws.OpenFeatureClass(System.IO.Path.GetFileNameWithoutExtension(clase_path));
}
catch (Exception)
{
return null;
}
return ftclass;
}
/**
* Devuelve la Feature Class dado el path de la gdb y el nombre de la clase
* Hay que liberarla después de usarla
*/
public static IFeatureClass abre_ftclass(string gdb_path, string ftclass_st)
{
IFeatureWorkspace feat_ws = abre_ftws(gdb_path);
if (feat_ws == null)
return null;
IFeatureClass ftclass;
try
{
ftclass = feat_ws.OpenFeatureClass(ftclass_st);
}
catch (Exception)
{
return null;
}
return ftclass;
}
/**
* Devuelve la tabla de campos de una clase dado su path
* Hay que liberarla después de usarla
*/
public static ITable dame_tabla_clase(string clase_path)
{
ITable tabla;
IFeatureWorkspace feat_ws = abre_ftws(clase_path);
if (feat_ws == null)
return null;
try
{
tabla = feat_ws.OpenTable(System.IO.Path.GetFileNameWithoutExtension(clase_path));
}
catch (Exception)
{
return null;
}
return tabla;
}
/**
* Devuelve la tabla de campos de una clase dado el nombre y la gdb que la contiene
* Hay que liberarla después de usarla
*/
public static ITable dame_tabla_clase(string gdb_path, string ftclass)
{
ITable tabla;
IFeatureWorkspace feat_ws = abre_ftws(gdb_path);
if (feat_ws == null)
return null;
try
{
tabla = feat_ws.OpenTable(ftclass);
}
catch (Exception)
{
return null;
}
return tabla;
}
/*
* Dado un path de clase y una consulta devuelve cuántas filas contienen datos
*/
public static int cuenta_filas_ftclass(string clase_path, string consulta)
{
int f = -1;
IQueryFilter filter = null;
ITable tabla = null;
try
{
//se abre la tabla
tabla = dame_tabla_clase(clase_path);
if (tabla == null)
return -1;
//se aplica filtro
filter = new QueryFilterClass();
filter.WhereClause = consulta;
f = tabla.RowCount(filter);
return f;
}
catch (Exception)
{
return -1;
}
finally
{
libera(filter);
libera(tabla);
}
}
/*
* Dado el nombre de una clase y la gdb que la contiene, y una consulta devuelve cuántas filas contienen datos
*/
public static int cuenta_filas_ftclass(string gdb_path, string ftclass, string consulta)
{
int f = -1;
IQueryFilter filter = null;
ITable tabla = null;
try
{
//se abre la tabla
tabla = dame_tabla_clase(gdb_path, ftclass);
if (tabla == null)
return -1;
//se aplica filtro
filter = new QueryFilterClass();
filter.WhereClause = consulta;
f = tabla.RowCount(filter);
return f;
}
catch (Exception)
{
return -1;
}
finally
{
libera(filter);
libera(tabla);
}
}
/*
* Devuelve los objectid de los elementos de clase_path que cumplan la consulta
*/
public static int[] dame_ids_consulta(string clase_path, string consulta, IFeatureClass ftclass_=null)
{
IQueryFilter filtro_lin = null;
ISelectionSet selectionSet = null;
IEnumIDs enumIDs = null;
IWorkspace ws = null;
IFeatureWorkspace ft_ws = null;
int n = 0, aux = 0, id = 0;
int[] ids=null;
IFeatureClass ftclass = null;
//se cuenta el numero de filas (campos) que existen en la tabla.
try
{
if (ftclass_ == null)
{
ft_ws = abre_ftws(clase_path);
if (ft_ws == null)
return null;
ws = (IWorkspace)ft_ws;
ftclass = abre_ftclass(clase_path);
if (ftclass == null)
return null;
}
else
ftclass = ftclass_;
filtro_lin = new QueryFilterClass();
filtro_lin.WhereClause = consulta;
//se hace una seleccion de todos los elementos que conforman la capa de entrada.
selectionSet = ftclass.Select(filtro_lin, esriSelectionType.esriSelectionTypeIDSet,
esriSelectionOption.esriSelectionOptionNormal, ws);
n = selectionSet.Count;
enumIDs = selectionSet.IDs;
//Tiene en enumIDS los objectid de los elementos que cumplen el filtro, lo pasa a un array de enteros
ids = new int[n];
aux = 0;
id = enumIDs.Next();
//se hace una rray de enteros conformado por los IDs
while (id != -1) //-1 es devuelto después del último ID válido de enumIDs(que es un array con los IDs de los elementos seleccionados)
{
ids[aux] = id;
aux++;
id = enumIDs.Next();
}
return ids;
}
catch (Exception)
{
return null;
}
finally
{
libera(filtro_lin);
if (ftclass_ == null)
{
libera(selectionSet);
libera(ftclass);
}
}
}
/**
* Devuelve los campos de una clase
*/
public static string[] dame_campos_clase(string clase_path, out int err)
{
ITable tabla;
IFields campos;
int ncampos;
string[] elems = null;
err = 0;
tabla = FunGDB.dame_tabla_clase(clase_path);
if (tabla == null)
{
err = 1;
return null;
}
try
{
campos = tabla.Fields;
ncampos = campos.FieldCount;
}
catch (Exception)
{
err = 2;
return null;
}
if (ncampos <= 0)
{
err = 3;
return null;
}
elems = new string[ncampos];
try
{
//se leen los campos de texto que contiene la capa para mostrarlos en la lista
for (int i = 0; i < ncampos; i++)
{
elems[i] = campos.get_Field(i).Name;
}
return elems;
}
catch (Exception)
{
err = 4;
return null;
}
finally
{
libera(tabla);
}
}
/*
* Devuelve los atributos de un campo determinado de una tabla y se copian en un array string
*/
public static string[] dame_valores_consulta(string clase_path, string campo, string consulta, out int err)
{
int[] ids=null;
IRow row=null;
ITable tabla = null;
int n=0;
string[] valores = null;
err = 0;
try
{
ids = dame_ids_consulta(clase_path, consulta);
if (ids == null)
{
err = 1;
return null;
}
n = ids.Length;
if (n == 0)
{
err = 2;
return null;
}
tabla = dame_tabla_clase(clase_path);
if (tabla == null)
{
err = 3;
return null;
}
valores = new string[n];
for (int i = 0; i < n; i++)
{
row = tabla.GetRow(ids[i]);
valores[i] = (row.get_Value(row.Fields.FindField(campo))).ToString();
libera(row);
}
return valores;
}
catch (Exception)
{
err = 4;
return null;
}
finally
{
libera(tabla);
}
}
/*
* Devuelve los valores únicos de un campo determinado de una tabla y se copian en un array string
*/
public static string[] dame_valunic_consulta(string clase_path, string campo, string consulta, out int err)
{
ITable tabla = null;
int n = 0;
string[] valores = null;
IDataStatistics dataStats = null;
ICursor cursor = null;
IEnumerator ienum=null;
object ob;
err = 0;
try
{
tabla = dame_tabla_clase(clase_path);
if (tabla == null)
{
err = 2;
return null;
}
cursor = tabla.Search(null, false);
dataStats = new ESRI.ArcGIS.Geodatabase.DataStatisticsClass();
dataStats.Field = campo;
dataStats.Cursor = cursor;
ienum = dataStats.UniqueValues;
List<string> val_list = new List<string>();
ienum.MoveNext();
ob = ienum.Current;
while (ob!=null)
{
val_list.Add((string)ob);
ienum.MoveNext();
ob = ienum.Current;
n++;
}
if (n > 0)
{
valores = new string[n];
val_list.CopyTo(valores, 0);
}
else
{
err = 3;
}
return valores;
}
catch (Exception)
{
err = 4;
return null;
}
finally
{
libera(tabla);
libera(cursor);
}
}
/**
* Libera el objeto
*/
public static IGeometry reproyecta(IGeometry geom, int coorsys = (int)esriSRProjCS4Type.esriSRProjCS_ETRS1989_UTM_Zone_30N)
{
try
{
IGeometry geom_sal;
ISpatialReference spatialReference;
IProjectedCoordinateSystem coord_proy;
ISpatialReferenceFactory3 spatialReferenceFactory;
spatialReferenceFactory = (ISpatialReferenceFactory3)new SpatialReferenceEnvironment();
coord_proy = spatialReferenceFactory.CreateProjectedCoordinateSystem(coorsys);//ETRS89_UTM30N 25830
spatialReference = (ISpatialReference)coord_proy;
geom.Project(spatialReference);
geom_sal = geom;
return geom_sal;
}
catch
{
return null;
}
}
/*
* Devuelve la geometría de modificando las coordendas de geograficas a proyectadas WGS84 UTM 30
* reutilizar en el siguiente método? es copia lo que sale?
*/
public static ISpatialReference dame_spatialref(IFeatureClass fc)
{
int ind;
IFields campos;
String shapeFieldName;
IField shapeField;
IGeometryDef geom_def, dest_geom;
IClone geom_clon, dest_clon;
IGeometryDefEdit geom_edit;
try
{
campos = fc.Fields;
//se consigue la forma (shape) de la featureclass de interés
shapeFieldName = fc.ShapeFieldName;
ind = fc.FindField(shapeFieldName);
shapeField = campos.get_Field(ind);
//conseguir la geometria definida por el campo shape
geom_def = shapeField.GeometryDef;
geom_clon = (IClone)geom_def;
dest_clon = geom_clon.Clone();
dest_geom = (IGeometryDef)dest_clon;
geom_edit = (IGeometryDefEdit)dest_geom;
return geom_edit.SpatialReference;
}
catch (Exception)
{
return null;
}
}
/*
* Devuelve la geometría de modificando las coordendas de geograficas a proyectadas WGS84 UTM 30
*/
public static IGeometryDef dame_geom_coords(IFeatureClass fc, int coorsys = (int)esriSRProjCS4Type.esriSRProjCS_ETRS1989_UTM_Zone_30N)//ETRS89_UTM30N 25830
{
int ind;
IFields campos;
ISpatialReferenceFactory3 spatialReferenceFactory=null;
ISpatialReference spatialReference;
String shapeFieldName;
IField shapeField;
IGeometryDef geom_def, dest_geom=null;
IClone geom_clon, dest_clon;
IGeometryDefEdit geom_edit=null;
IProjectedCoordinateSystem coord_proy;
try
{
campos = fc.Fields;
//se consigue la forma (shape) de la featureclass de interés
shapeFieldName = fc.ShapeFieldName;
ind = fc.FindField(shapeFieldName);
shapeField = campos.get_Field(ind);
//conseguir la geometria definida por el campo shape
geom_def = shapeField.GeometryDef;
geom_clon = (IClone)geom_def;
dest_clon = geom_clon.Clone();
dest_geom = (IGeometryDef)dest_clon;
geom_edit = (IGeometryDefEdit)dest_geom;
/*if(geom_edit.SpatialReference.FactoryCode==0)
{
//si no tiene info de proyección, se le dice que viene de coorsys (utm30n)
ISpatialReferenceFactory3 spatialReferenceFactory_aux = (ISpatialReferenceFactory3)new SpatialReferenceEnvironment();
IProjectedCoordinateSystem coord_proy_aux = spatialReferenceFactory.CreateProjectedCoordinateSystem(OliviaGlob.coorsys);
ISpatialReference spatialReference_aux = (ISpatialReference)coord_proy_aux;
geom_edit.SpatialReference_2 = spatialReference_aux;
}*/
//se genera un sistema de referencia espacial: de coordenadas proyectadas a coorsys
spatialReferenceFactory = (ISpatialReferenceFactory3)new SpatialReferenceEnvironment();
spatialReference = spatialReferenceFactory.CreateProjectedCoordinateSystem(coorsys);
geom_edit.SpatialReference_2 = spatialReference;//se modifica el sistema de referencia de coordenadas al generado esriSRProjCS_WGS1984UTM_30N
}
catch (Exception)
{
return null;
}
return dest_geom;//esta clase se pasará como argumento a la hora de la exportacion. De modo que realizará el cambio de coordendas oportuno
}
/**
* Libera el objeto
*/
public static void libera(object ob)
{
if (ob != null)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ob);
ob = null;
}
/**
* Une las geometrías geom1 y geom2
*/
public static IGeometry une_geoms(IGeometry geom1, IGeometry geom2)
{
ITopologicalOperator union;
IGeometry geom = null;
try
{
if (geom1 != null)
{
union = (ITopologicalOperator)geom1;
//'union' contiene a geom1
if (geom2 != null)
geom = union.Union(geom2);
else
geom = geom1;
}
else if (geom2 != null)
geom = geom2;
}
catch (Exception)
{
return null;
}
return geom;
}
/**
* Realiza la intersección entre las dos geometrías que se pasan como argumentos.
* Le quita geom_quita a geom_tot
*/
public static IGeometry intersec_geoms(IGeometry geom1, IGeometry geom2)
{
ITopologicalOperator union;
IGeometry geom = null;
try
{
if (geom1 != null)
{
union = (ITopologicalOperator)geom1;
//'union' contiene a geom1
if (geom2 != null)
geom = union.Intersect(geom2, esriGeometryDimension.esriGeometry2Dimension);
else
geom = geom1;
}
else if (geom2 != null)
geom = geom2;
}
catch (Exception)
{
return null;
}
return geom;
}
/**
* Realiza la diferencia simétrica entre las dos geometrías que se pasan como argumentos.
* Le quita geom_quita a geom_tot
*/
public static IGeometry diferencia_geoms(IGeometry geom_tot, IGeometry geom_quita)
{
ITopologicalOperator union;
IGeometry geom = null;
try
{
if (geom_tot != null)
{
union = (ITopologicalOperator)geom_tot;
//'union' contiene a geom1
if (geom_quita != null)
geom = union.Difference(geom_quita);
else
geom = geom_tot;
}
else if (geom_quita != null)
geom = geom_quita;
}
catch (Exception)
{
return null;
}
return geom;
}
/**
* Forma el envelope que contiene los ámbitos para exportar, a partir de ahí la red navegable ampliando a un buffer
* Envelope es un rectángulo, no es el polígono mínimo que los contiene
*/
public static IGeometry dame_geom_envelope(string path_clase)
{
IFeatureClass capa;
IGeoDataset gds;
Polygon poli;
ISegmentCollection segcol;
IGeometry geom_envelope = null;
try
{
capa = abre_ftclass(path_clase);
if (capa == null)
{
return null;
}
//castea la capa a IGeoDataset, de donde obtendrá el envelope
gds = (IGeoDataset)capa;
//crea un polígono partiendo del rectángulo envelope
poli = new PolygonClass();
segcol = (ISegmentCollection)poli;
segcol.SetRectangle(gds.Extent);
geom_envelope = (IGeometry)poli;
//libera
FunGDB.libera(capa);
return geom_envelope;
}
catch
{
return null;
}
}
/*
* A partir de una capa recorre todos los elementos que cumplen el filtro y los une en una única geometría
*/
public static IGeometry une_geometria(IFeatureClass fc1, IQueryFilter filtro, out string err_st)
{
IFeatureCursor fcc = null;
IFeature f1 = null, f2 = null;
IGeometry queryGeometry = null;
ITopologicalOperator union = null;
err_st = "";
try
{
fcc = fc1.Search(filtro, false);
}
catch (Exception)
{
err_st = string.Format("La capa {0} no contiene elementos que cumplan la consulta: {1}", fc1.AliasName, filtro.WhereClause);
return null;
}
try
{
f2 = f1 = fcc.NextFeature();
if (f1 == null)
{
err_st = string.Format("La capa {0} no contiene elementos que cumplan la consulta: {1}", fc1.AliasName, filtro.WhereClause);
return null;
}
f2 = fcc.NextFeature();
union = (ITopologicalOperator)f1.Shape;
while (f1 != null && f2 != null)
{
f1.Shape = union.Union(f2.Shape);
union = (ITopologicalOperator)f1.Shape;
f2.Delete();
FunGDB.libera(f2);
f2 = fcc.NextFeature();
}
queryGeometry = f1.Shape;
f1.Store();
return queryGeometry;
}
catch (Exception ex)
{
err_st = string.Format("Error al unir geometría de la capa {0} con el filtro {1}: {2}", fc1.AliasName, filtro.WhereClause, ex.Message);
return null;
}
finally
{
//libera
FunGDB.libera(f1);
FunGDB.libera(f2);
FunGDB.libera(fcc);
}
}
/**
* Forma la envolvente compleja, el mínimo polígono,
* que contiene los ámbitos para exportar, a partir de ahí la red navegable ampliando a un buffer
*/
public static IGeometry dame_geom_convexhull(string path_clase)
{
IFeatureClass fc;
IGeometry geom, geom_convhull;
ITopologicalOperator convhull = null;
IQueryFilter filtro;
string err_st;
try
{
filtro = new QueryFilterClass();
filtro.WhereClause="";
fc = abre_ftclass(path_clase);
if (fc == null)
{
return null;
}
geom = une_geometria(fc, filtro, out err_st);
if (geom == null)
{
return null;
}
//castea la geometría a itopologicaloperator
convhull = (ITopologicalOperator)geom;
geom_convhull = convhull.ConvexHull();
//libera
FunGDB.libera(fc);
return geom_convhull;
}
catch
{
return null;
}
}
/**
* Amplia la geom para que contenga el punto p ampliando el rectangulo del envelope
*/
public static IGeometry amplia_geom(IGeometry geom, double p_x, double p_y)
{
IEnvelope env = null;
IPoint[] points;
IPolygon poli = new PolygonClass();
ISegmentCollection segcol;
env = geom.Envelope;
points = new IPoint[5];
points[0] = env.LowerLeft;
points[1] = env.LowerRight;
points[2] = env.UpperLeft;
points[3] = env.UpperRight;
points[4] = new PointClass();
points[4].PutCoords(p_x, p_y);
IEnvelopeGEN envelopegen = new EnvelopeClass();
try
{
envelopegen.DefineFromPoints(ref points);
poli = new PolygonClass();
segcol = (ISegmentCollection)poli;
segcol.SetRectangle((IEnvelope)envelopegen);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
geom = (IGeometry)poli;
return geom;
}
/**
* Amplia la geom para que contenga el punto p ampliando la envolvente convexa
*/
public static IGeometry amplia_geom_convexhull(IGeometry geom, double p_x, double p_y)
{
IPoint p;
ITopologicalOperator union;
IGeometry geom_p,geom_tot, geom_convhull;
IGeometry5 geom_p_;
try
{
p = new Point();
p.PutCoords(p_x, p_y);
geom_p_ = (IGeometry5)p;
geom_p_.SpatialReference = geom.SpatialReference;
union = (ITopologicalOperator)geom_p_;
geom_p = union.Buffer(100);
union = (ITopologicalOperator)geom_p;
//une el punto nuevo a la geometría geom
geom_tot = union.Union(geom);
//reapunta union al total
union = (ITopologicalOperator)geom_tot;
geom_convhull = union.ConvexHull();
return geom_convhull;
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
return null;
}
}
/*
* Añade a la capa de origen la columna que se pasa como argumento
*/
public static bool add_campo(string path_clase, string nombre_campo, esriFieldType tipo_campo, out int err)
{
IFeatureClass fc = null;
IFields oldFields = null, fields = null;
IClone clone_fuente = null, clone_dest = null;
IFieldsEdit fields_edit = null;
ITable tabla = null;
IField field = null;
IFieldEdit field_edit = null;
err = 0;
try
{
fc = abre_ftclass(path_clase);
if (fc == null)
{
err = 1;
return false;
}
oldFields = fc.Fields;
clone_fuente = (IClone)oldFields;
clone_dest = clone_fuente.Clone();
fields = (IFields)clone_dest;
//se castea para poder enditar los campos de las tablas
fields_edit = (IFieldsEdit)fields;
tabla = dame_tabla_clase(path_clase);
if (tabla == null)
{
err = 2;
return false;
}
if (tabla.FindField(nombre_campo) > 0)
{
err = 3;
return false;
}
//se añade un campo entero
field = new FieldClass();
field_edit = (IFieldEdit)field;
field_edit.Name_2 = nombre_campo;
field_edit.Type_2 = tipo_campo;
//string_field_edit.Length_2 = 100;
field_edit.Precision_2 = 38;
field_edit.Scale_2 = 0;
fc.AddField(field_edit);
return true;
}
catch
{
return false;
}
finally
{
libera(fc);
libera(tabla);
}
}
/*
* Exporta de la gdb src al shp dest
*/
public static bool exporta(string dir_gdb_src, string nom_src, string dir_shp_dest, string nom_dest, IQueryFilter filtro, out IDatasetName shp_data_name, out string err_st)
{
string name = "";
IFeatureClassName shp_fcn = null;
IGeometryDef dest_geom = null;
ITable tabla = null;
int nfilas;
ESRI.ArcGIS.GeoDatabaseUI.IExportOperation exportOperation;
IFeatureClassName gdb_fcn;
IDatasetName gdb_dsn;
IWorkspaceName gdb_wsn;
err_st = "";
shp_data_name = null;
//prepara el shp donde va a exportar
shp_fcn = FunGDB.crea_shp(dir_shp_dest, nom_dest);
if (shp_fcn == null)
{
err_st = "Error al crear el shape de exportación " + name;
return false;
}
/////////////////////////////////////////////
//obtiene la geomdef con las coordenadas proyectadas
IFeatureClass fc;
if (nom_src == null)
fc = abre_ftclass(dir_gdb_src);
else
fc = abre_ftclass(dir_gdb_src, nom_src);
if (fc == null)
return false;
dest_geom = FunGDB.dame_geom_coords(fc, OliviaGlob.coorsys);
if (dest_geom == null)
{
err_st = "Error al generar el sistema de coordendas proyectadas en la capa " + nom_src;
return false;
}
FunGDB.libera(fc);
//Inicia la gdb de donde va a exportar
gdb_wsn = FunGDB.abre_wsn(dir_gdb_src);
if (gdb_wsn == null)
{
err_st = "Error al abrir la gdb de exportación " + name;
return false;
}
try
{
gdb_fcn = new FeatureClassNameClass();
gdb_dsn = (IDatasetName)gdb_fcn;
if (nom_src == null)
gdb_dsn.Name = System.IO.Path.GetFileNameWithoutExtension(dir_gdb_src);
else
gdb_dsn.Name = nom_src;
gdb_dsn.WorkspaceName = (IWorkspaceName)gdb_wsn;
//Se prepara para exportar
if (nom_src == null)
tabla = FunGDB.dame_tabla_clase(dir_gdb_src);
else
tabla = FunGDB.dame_tabla_clase(dir_gdb_src, nom_src);
if (tabla == null)
{
err_st = "Error al abrir la tabla de exportación " + name;
return false;
}
nfilas = tabla.RowCount(filtro);
if (nfilas <= 0)
{
err_st = string.Format("No hay elementos que cumplan la condición y se encuentren en el nivel y en la zona seleccionados");
return false;
}
//se prepara la exportación
exportOperation = new ESRI.ArcGIS.GeoDatabaseUI.ExportOperationClass();
exportOperation.ExportFeatureClass(gdb_dsn, filtro, null, dest_geom, shp_fcn, 0);
}
catch (Exception)
{
err_st = "Error al exportar el ámbito de trabajo con los datos introducidos";
return false;
}
finally
{
FunGDB.libera(tabla);
}
shp_data_name = (IDatasetName)shp_fcn;
return true;
}
/*
* Devuelve las coordenadas de la feature class
*/
public static int dame_factory_code(string dir_gdb_src, string nom_src)
{
IFeatureClass fc;
int coor = -1;
if (nom_src == null)
fc = abre_ftclass(dir_gdb_src);
else
fc = abre_ftclass(dir_gdb_src, nom_src);
if (fc == null)
return coor;
coor = ((IGeoDataset)fc).SpatialReference.FactoryCode;
FunGDB.libera(fc);
return coor;
}
/*
* Devuelve los atributos de un campo determinado de una tabla y se copian en un array string
*/
public static bool quita_filas(string shp_path, List<int> ids_filas)
{
ITable tabla = null;
IRow row = null;
try
{
//borra las líneas que se han indicado
int offset = 0;
tabla = FunGDB.dame_tabla_clase(shp_path);
if (tabla == null)
return false;
for (int j = 0; j < ids_filas.Count; j++)
{
row = tabla.GetRow(ids_filas[j] - offset); //offset porque según va borrando se van desplazando las filas.
row.Delete();
offset++;
FunGDB.libera(row);
}
}
catch
{
return false;
}
finally
{
FunGDB.libera(tabla);
FunGDB.libera(row);
}
return true;
}
/**
* Indica si el punto está en el polígono de la geometría
*/
public static bool is_pto_in_geom(double x, double y, IGeometry geom_poly)
{
Point punto_ins = new Point();
IGeometry geom_ins, geom;
ITopologicalOperator union;
try
{
punto_ins.PutCoords(x, y);
geom_ins = (IGeometry)punto_ins;
union = (ITopologicalOperator)geom_poly;
geom = union.Intersect(geom_ins, esriGeometryDimension.esriGeometry0Dimension);
if (!geom.IsEmpty)
{
return true;
}
return false;
}
catch
{
return false;
}
}
/**
* Borra la ftclass de la gdb para poder sobreescribir
*/
public static bool borra_ftclass(string path_gdb, string ftclass_nomb)
{
IWorkspace2 ws_gdb_;
IFeatureWorkspace fws;
IDataset data_delete;
ws_gdb_ = (IWorkspace2)FunGDB.abre_ws(path_gdb);
if (ws_gdb_ == null)
return false;
fws = (IFeatureWorkspace)ws_gdb_;
if (!ws_gdb_.get_NameExists(esriDatasetType.esriDTFeatureClass, ftclass_nomb))
return true;//no existe, no hay nada que borrar
data_delete = (IDataset)fws.OpenFeatureClass(ftclass_nomb);
if ((data_delete != null) && data_delete.CanDelete())
{
try
{
data_delete.Delete();
}
catch
{
return false;
}
}
else
{
return false;
}
return true;
}
/**
*Crea el feature dataset
*/
public static int crea_ftdataset(string path_gdb, string dataset_nomb, ISpatialReference spref)
{
IWorkspace2 ws_gdb_;
IFeatureWorkspace fws;
IFeatureDataset ft_dataset=null;
try
{
ws_gdb_ = (IWorkspace2)FunGDB.abre_ws(path_gdb);
if (ws_gdb_ == null)
return 1;
fws = (IFeatureWorkspace)ws_gdb_;
if (ws_gdb_.get_NameExists(esriDatasetType.esriDTFeatureDataset, dataset_nomb))
{
if (!same_spatref_dataset(fws.OpenFeatureDataset(dataset_nomb), spref))
{
//avisa
return 2;
}
return 0;//existe, no hay nada que crear
}
ft_dataset = fws.CreateFeatureDataset(dataset_nomb, spref);
if (ft_dataset == null)
{
return 1;
}
return 0;
}
catch
{
return 1;
}
}
/**
* Comprueba si el dataset de nombre dado tiene la misma spatialref que la dada
*/
public static bool same_spatref_dataset(IFeatureDataset ft_dataset, ISpatialReference spref)
{
IFeatureClass ftc;
IEnumDataset enumDS = ft_dataset.Subsets;
IDataset ds = enumDS.Next();
while (ds != null)
{
if (ds is IFeatureClass)
{
ftc = ds as IFeatureClass;
if (dame_spatialref(ftc).FactoryCode!=spref.FactoryCode)
return false;
else
return true;
}
}
return true;//esta vacío
}
/**
* Indica si la capa contiene puntuales
*/
public static bool is_ftclass_punt(IFeatureClass clase)
{
return clase.ShapeType == esriGeometryType.esriGeometryPoint ||
clase.ShapeType == esriGeometryType.esriGeometryMultipoint;
}
/**
* Indica si la capa contiene superficiales
*/
public static bool is_ftclass_sup(IFeatureClass clase)
{
return clase.ShapeType == esriGeometryType.esriGeometryPolygon;
}
/**
* Indica si la capa contiene lineales
*/
public static bool is_ftclass_lin(IFeatureClass clase)
{
return clase.ShapeType == esriGeometryType.esriGeometryPolyline;
}
/**
* Indica si el campo es string
*/
public static bool is_str_field(string clase_path,string campo)
{
int ind=-1;
ITable tabla = dame_tabla_clase(clase_path);
if(tabla!=null)
ind=tabla.FindField(campo);
if (ind >= 0)
return tabla.Fields.get_Field(ind).Type == esriFieldType.esriFieldTypeString;
else
return false;
}
}
}