domingo, 7 de diciembre de 2014

Rotar y Escalar un Punto usando Matrices


En esta oportunidad, veremos el uso de matrices para Rotar y Escalar un punto. Para ello, antes revisamos algo de Multiplicación de Matrices que lo podemos ver en este enlace:


Uso de las Matrices en la Rotación y Escala de un Punto:

Para Rotar y Escalar (entre otras operaciones) un Punto dado, usamos estas ecuaciones:

 


 
 Podemos transformar estas ecuaciones en una forma matricial:



 

 
 
 
Donde tenemos una matriz 3 x 3 donde están los coeficientes de Cálculo, una matriz columna (3 x 1) con las coordenadas iniciales y el resultado será una matriz columna (3 x 1).

Tendremos en esta ocasión dos metodologías de trabajo:

Operando matrices de forma separada:

Se trabajara con la Matriz-Rotación ([R]), Matriz-Escala ([E]) y la Matriz 0:


 
 
 
 
 
 
 
 
 
 
 
 
 
 Ejemplo de Cálculo:

Tenemos la Coordenada 0 (0,0) y la Coordenada Inicial (190.048,130.41), luego a la Coordenada Inicial la Rotamos con un Ángulo de 80º en sentido anti horario (tendrá un signo positivo) y luego lo escalamos 6 veces.










Cálculo:

 
 
 
 
 
 
 
 
 
 Nota: Para el cálculo se transformó los 80º en radianes.

Gráficamente:


















También se demuestra que el resultado es el mismo si invertimos el orden de las matrices:
Cálculo:


 
 
 
 
 
 
 
 
 

Gráficamente:


 
 
 
 
 
 
 
 
 
 
 Operando matrices de forma conjunta:

Es posible trabajar la Matriz-Rotación ([R]), Matriz-Escala ([E]) y la Matriz 0 de forma conjunta:


 



Obteniendo el mismo resultado:

 

 
 
 
 
 
 
 
 

Y de igual manera se verifica si se invierte las matrices Rotación y Escala:


 
 
 
 
 
 
 
 
 
Si bien la Coordenada 0, para este ejemplo tiene valores 0,0, puede tener otros valores, según nuestros requerimientos.

Esperando que les sea útil, será hasta el otro mes.               

domingo, 2 de noviembre de 2014

Postgresql / Postgis: Creación de una Tabla y asociarla a un Trigger:


En este mes, se verá como crear una Tabla con una Proyección y un Trigger para actualizar algunas columnas en ella.
Creación de una Tabla con una Proyección: Para crear una tabla se usaría una estructura en SQL:
  

















Ejemplo:
















 
Creación de un Trigger: Para crear un Trigger con su respectiva Función se usaría una estructura SQL:


















Entre el BEGIN y el END de la Función del Trigger, se coloca las operaciones de la Función. Para ello se usa las variables New, Old (no son necesarios declararlos) para acceder a los valores de la Tabla asociada al Trigger  de la siguiente manera:
New.Columna
Podría explicarse (a mi entender), New es el Nuevo registro y Columna es la Columna del Nuevo registro a leer el Valor.
Ejemplo:


















 
Para más información, pueden leer el siguiente enlace: http://www.postgresql.org/docs/9.1/static/sql-createtrigger.html
Ejemplo de Aplicación:
Este es un ejemplo de aplicación que está dividido en dos partes:
La primera parte será la creación de una Tabla de Puntos que se llamara CCPP_PERU y en ella estarán guardados unos centros poblados del Perú. Esta tabla tendrá una proyección Geográfica en WGS84, teniendo como columnas:
Nombre: nombre de los Centros Poblados, de tipo character varying(35).
long_84: Longitud de los Centros Poblados, de tipo double precision
lat_84: Latitud de los Centros Poblados, de tipo double precision,
dept: nombre del departamento que pertenece el Centros Poblados, de tipo character varying(35).
prov :nombre de la provincia que pertenece el Centro Poblado, de tipo character varying(35).
dist: nombre del distrito que pertenece el Centro Poblado, de tipo character varying(35),
 
gid: PRIMARY KEY de la Tabla CCPP_PERU serial NOT NULL,
the_geom: columna donde estarán los puntos de los Centros Poblados, de tipo geometry.
 
Las Columnas que serán actualizadas por el Trigger serán: dept, prov, dist, the_geom.
 
La segunda parte es la creación del Trigger  con su respectiva Función. Este Trigger permitirá actualizar las columnas dept, prov, dist, the_geom. Para actualizar las columnas dept, prov, dist se usara la Tabla DISTRITOS_PERU donde estarán tres columnas con esta información y dicha tabla estará en la proyección Geográfica en PSAD56. En este enlace pueden descargar un SHP para que lo agreguen en su Base de datos para este ejemplo.
 

Estructura de la Tabla DISTRITOS_PERU
















 
Código SQL para la creación de la Tabla:
 
CREATE TABLE "CCPP_PERU"
(
  "nombre" character varying(35), 
  "long_84" double precision,
  "lat_84" double precision,
  "dept" character varying(35),
  "prov" character varying(35),
  "dist" character varying(35),
  "gid" serial NOT NULL,
  "the_geom" geometry,
  CONSTRAINT "CCPP_PERU_pkey" PRIMARY KEY ("gid"),
  CONSTRAINT "enforce_dims_the_geom" CHECK (st_ndims("the_geom") = 2),
  CONSTRAINT "enforce_srid_the_geom" CHECK (st_srid("the_geom") = 4326)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE "CCPP_PERU" OWNER TO postgres;

CREATE INDEX "CCPP_PERU_the_geom_gist"
  ON "CCPP_PERU"
  USING gist
  ("the_geom");


Código SQL para la creación del  Trigger:

--INICIO DE LA FUNCION 
CREATE OR REPLACE FUNCTION actualizadepprovdist() Returns "trigger" as $BODY$ 
 DECLARE
 r record; --DECLARO UNA VARIABLE DE TIPO RECORD
  BEGIN
       If (New.Long_84 <>0 and New.Lat_84 <>0) Then --VERIFICACION SI LOS VALORES EN long_84, lat_84 SON DIFERENTES DE CERO (0)
  NEW.the_geom := St_SetSRID(St_MakePoint(New.long_84, New.lat_84),4326); --CREO UNA GEOMETRIA CON LOS DATOS DE LAS COLUMNAS long_84, lat_84

  Execute 'Create View mivista as Select "long_84", "lat_84" , "nombdpto", "nombprov", "nombdist" from "CCPP_PERU", "DISTRITOS_PERU" Where Not St_IsEmpty(St_Intersection (St_SetSRID(St_MakePoint(' ||  New.long_84 ||', ' || New.lat_84 ||'),4326) , St_Transform("DISTRITOS_PERU".the_geom,4326))) and "CCPP_PERU".gid = ' || New.gid ;
  --CREO UNA VISTA LLAMADA mivista DONDE SELECCIONO LAS COLUMNAS long_84, lat_84 DE LA TABLA CCPP_PERU, 
  --LAS COLUMNAS nombdpto, nombprov, nombdist USANDO EL COMANDO EXECUTE

  For r in Select * From mivista --SELECCIONO TODOS LOS RECORDS (ES UN DECIR YA QUE SOLO HAY UN SOLO RECORD) DE LA VISTA mivista
  Loop --ESTE LOOP RECORRE CADA REGISTRO DE LA VISTA mivista
   NEW.dept := r.nombdpto; --ASIGNO EL VALOR DE LA COLUMNA nombdpto HACIA LA COLUMNA dept
   NEW.prov := r.nombprov; --ASIGNO EL VALOR DE LA COLUMNA nombprov HACIA LA COLUMNA prov
   NEW.dist := r.nombdist; --ASIGNO EL VALOR DE LA COLUMNA nombdist HACIA LA COLUMNA dist
  
  End Loop;--FIN DEL LOOP
  Execute 'Drop View mivista';  --BORRO LA VISTA mivista CON EXECUTE
  
       End If;

       RETURN NEW; --RETORNO DE LOS VALORES HACIA EL REGISTRO CREADO
  END;

$BODY$ 
LANGUAGE plpgsql; --SE DECLARA EL TIPO DE LENGUAJE DE LA FUNCION: plpgsql 
--FIN DE LA FUNCION 

--INICIO DEL TRIGGER
CREATE TRIGGER actualizadepprovdist
BEFORE INSERT OR UPDATE ON "CCPP_PERU"
    FOR EACH ROW EXECUTE PROCEDURE actualizadepprovdist();
--FIN DEL TRIGGER
 
La mayoría del código para la creación del Trigger esta explicado. Pero se explicara la Línea:
 
Execute 'Create View mivista as Select "long_84", "lat_84" , "nombdpto", "nombprov", "nombdist" from "CCPP_PERU", "DISTRITOS_PERU" Where Not St_IsEmpty(St_Intersection (St_SetSRID(St_MakePoint(' ||  New.long_84 ||', ' || New.lat_84 ||'),4326) , St_Transform("DISTRITOS_PERU".the_geom,4326))) and "CCPP_PERU".gid = ' || New.gid ;
Explicación:
Con el comando Execute ejecutamos alguna consulta SQL que sea necesaria en la Función del Trigger.
Este Trigger debe leer las coordenadas de las columnas long_84, lat_84 que están en el registro recién insertado en la tabla CCPP_PERU (usando New.Long_84 y New.Lat_84) para intersectarlo con la tabla DISTRITOS_PERU y leer las columnas nombdpto, nombprov, nombdist. Para ello, una forma seria creando una Vista o Tabla (en este ejemplo se usó una Vista) temporal donde estén las columnas long_84, lat_84 de la tabla CCPP_PERU y nombdpto, nombprov, nombdist de la tabla DISTRITOS_PERU:
Create View mivista as Select "long_84", "lat_84" , "nombdpto", "nombprov", "nombdist" from "CCPP_PERU", "DISTRITOS_PERU"
Para parametrizar más la selección, usamos la condición Where donde indicamos propiamente la Intersección, pero creamos (otra vez) un punto desde la columna long_84, lat_84:
St_MakePoint(' ||  New.long_84 ||', ' || New.lat_84 ||')
Donde || sirven para concatenar textos o números, y le asignamos la Proyección Geográfica en WGS84:
St_SetSRID(St_MakePoint(' ||  New.long_84 ||', ' || New.lat_84 ||'),4326)
Y proyectamos la table DISTRITOS_PERU de PSAD56 a WGS84 en la Proyección Geográfica:
St_Transform("DISTRITOS_PERU".the_geom,4326)
Con estos tres pasos, usamos la Intersección:
St_Intersection(geometria1,geometria2)
Como el resultado de St_Intersection(geometria1,geometria2) es un booleano Le decimos que si no es Vacío, nos de el resultado:
Not St_IsEmpty(St_Intersection(geometria1,geometria2))
Además, para asegurar que solo nos dé un registro, le indicamos que solo sea cuando el valor de la columna gid de la tabla CCPP_PERU y del New.gid sean iguales:
and "CCPP_PERU".gid = ' || New.gid
 
Parte del código para la creación de la Vista se ha extendido para fines informativos, pudiéndose acortar el código.
Para ver si se ejecuta el Trigger, escribimos la longitud y latitud (o viceversa) en las columnas long_84, lat_84 en el último registro de la tabla (el que tiene un asterisco en la columna “0”) y presionando luego el botón Refresh de la tabla, veremos que se actualiza las columnas dept, prov, dist, the_geom (la columna nombre es para que el usuario escriba el nombre del Centro Poblado y la columna gid se actualiza cada vez que se ingresa un nuevo registro).









 
 
Esperando que sea de utilidad. Sera hasta el otro mes.

domingo, 5 de octubre de 2014

MapBasic (Programación en MapInfo): Brush (Estilo de relleno de un Polígono)


Los archivos Tab de MapInfo permiten guardar en ellos mismos sus estilos (a diferencia del Shapefile que necesitan del Lyr para ello) en cada geometría. En esta oportunidad leeremos los estilos de unos polígonos de un Tab y lo guardaremos en la Tabla de atributos en una copia.

Para ello, necesitamos saber que es un Brush

 Toda esta información es encontrada en el “Help” del MapBasic:  El brush especifica el estilo de relleno de un objeto grafico…

 El Brush está formado de la siguiente manera

Brush (patterns, foreground color, background color)

Dónde:

Patterns: Tipo de relleno que se visualiza en el Brush. Esta expresado como un valor entero

Foreground color: Color del tramado definido en el Pattern. Esta expresado como un valor entero

Background color: Color del fondo del Pattern. Esta expresado como un valor entero




El Foreground color y el Background color están expresados como enteros, resultado de la siguiente expresión:

Red * 65536 + Green * 256 + blue

Donde Red, Green y Blue son los valores RGB que se conocen para el Rojo, Verde y Azul que conocemos. Por ejemplo

Para el color Rojo (255,0,0) = 255 * 65536 + 0 * 256 + 0 = 16711680

Para el color Verde (0,255,0) = 0 * 65536 + 255 * 256 + 0 = 65280

Para el color Azul (0,0,255) = 0 * 65536 + 0 * 256 + 255= 255

Para el color Amarillo (255,255,0) = 255 * 65536 + 255 * 256 + 0= 16776960

Donde los números resultantes de la ecuación son los colores (en formato de entero) que usa el Brush para pintar los polígonos. Para comprobar con lo dicho, pueden revisar esta página web:


 Código de Ejemplo

Acá esta un código que lee el Brush de cada polígono y crea en una Tab nuevo cuatro nuevas columnas:

PATT: de tipo Integer que estará guardado el Pattern.

FORE: de tipo Char que estará guardado el color del Foreground en formato RGB (Red, Green, Blue).

BACK: de tipo Char que estará guardado el color del Background en formato RGB (Red, Green, Blue).

BRUSH: de tipo Char que estará guardado el Brush como se lee originalmente.

  

En el código mismo están como comentarios lo que es cada línea y se usa el Archivo Tab “PERU_DEPARTAMENTOS” que lo pueden descargar en el siguiente enlace y debe estar abierto en el MapInfo para que se ejecute con normalidad



Include "mapbasic.def"

'DECLARACION DE FUNCIONES PARA EL SCRIPT
Declare Function EstiloPoligono (ByVal MiBrush as Brush, ByVal Propiedad as String) as String
Declare Function ColorRGB (ByVal MiNumero as Integer) as String

'DECLARACION DE VARIABLES PARA EL SCRIPT
Dim NumeroEntidades as Integer
Dim i as integer
Dim NombreTabla as String
Dim Objeto as Alias

NombreTabla  = "PERU_DEPARTAMENTOS" 'TAB DE EJEMPLO
NumeroEntidades = TableInfo(NombreTabla  ,TAB_INFO_NROWS)'CALCULA NUMERO DE ENTIDADES

'CREACION DE LAS CUATRO COLUMNAS Y LAS INICIALIZAMOS CON VALORES INICIALES
Add Column NombreTabla (PATT Integer) Values 0
Add Column NombreTabla (FORE Char(50)) Values "" 
Add Column NombreTabla (BACK Char(50)) Values "" 
Add Column NombreTabla (BRUSH Char(50)) Values "" 

'CREACION DE LA COPIA DE LA TABLA DE TRABAJO CON LOS CUATRO CAMPOS CREADOS Y SE LE AGREGA EL TEXTO "_COLOR"
Commit Table NombreTabla  As NombreTabla & "_COLOR" 
NombreTabla = NombreTabla & "_COLOR" 
Open Table "C:\INGEOGRAFOS\GIS\LEYENDA_TABLA\TAB\" & NombreTabla & ".TAB" as NombreTabla 
Map From NombreTabla 

'CREACION DEL OBJETO QUE LEERA LOS POLIGONOS
Objeto = NombreTabla & ".obj"

'SENTENCIA FOR QUE LEERA DE CADA POLIGONO EL BRUSH Y GUADARA CADA VARIABLE DEL BRUSH EN UNA DE LAS 4 COLUMNAS CREADAS
For i = 1 to NumeroEntidades 
 fetch rec i From NombreTabla 
 Update NombreTabla set PATT = EstiloPoligono (ObjectInfo(Objeto ,OBJ_INFO_BRUSH),"Pattern"), 
        FORE = EstiloPoligono (ObjectInfo(Objeto ,OBJ_INFO_BRUSH),"Forecolor"),
        BACK = EstiloPoligono (ObjectInfo(Objeto ,OBJ_INFO_BRUSH),"Backcolor"),
        BRUSH = EstiloPoligono (ObjectInfo(Objeto ,OBJ_INFO_BRUSH),"Brush")
 where RowId = i
next 

'GUARDAR LOS CAMBIOS
Commit Table NombreTabla 

Function EstiloPoligono (ByVal MiBrush as Brush, ByVal Propiedad as String) as String

 Dim Pattern as Integer
 Dim Forecolor as Integer
 Dim Backcolor as Integer

 Pattern = StyleAttr(MiBrush, 1 )
 Forecolor = StyleAttr(MiBrush, 2 )
 Backcolor = StyleAttr(MiBrush, 3 )

 
 if Propiedad = "Pattern" then
  EstiloPoligono  = Pattern 
 elseif Propiedad = "Forecolor" then
  EstiloPoligono  = ColorRGB (Forecolor)
 elseif Propiedad = "Backcolor" then
  EstiloPoligono  = ColorRGB (Backcolor)
 elseif Propiedad = "Brush" then
  EstiloPoligono  = MiBrush
 end if

End Function

Function ColorRGB (ByVal MiNumero as Integer) as String
 Dim Rojo as Integer
 Dim Verde as Integer
 Dim Azul as Integer

 Rojo = Fix(MiNumero / 65536)
 Verde = Fix((MiNumero/65536 - Fix(MiNumero/65536))*256) 
 Azul = Fix((MiNumero/256 - Fix(MiNumero/256))*256) 

 ColorRGB  = Rojo & "," & Verde & "," & Azul '& "," & MiNumero 
End Function


Función EstiloPoligono: Esta función dependiendo de la variable Propiedad obtiene el Pattern, Foreground color, Background color o el Brush.

Función ColorRGB: Esta función transforma el entero que representa el color y lo transforma en valores RGB (Red, Green, Blue) concatenados con comas y en forma de Texto. Vendria a ser lo inverso de Red * 65536 + Green * 256 + blue

Esperando que sea útil, será hasta el otro mes.

sábado, 13 de septiembre de 2014

Transformación o cambio de Datum por 7 parámetros según Bursa-Wolf

Es la transformación / cambio de un Datum hacia otro Datum , usando 7 parámetros, de acuerdo a la formula matricial “Bursa-Wolf”


 
 
Dónde como datos de entrada tenemos:

dX: traslación (shift) en X  (en metros)

dY: traslación (shift) en Y  (en metros)

dZ: traslación (shift) en Z  (en metros)

Rx: Rotación en X (en segundos)

Ry: Rotación en Y  (en segundos)

Rz: Rotación en Z  (en segundos)

Xs: Coordenada geocéntrica / Cartesiana en el eje X

Ys: Coordenada geocéntrica / Cartesiana en el eje Y

Zs: Coordenada geocéntrica / Cartesiana en el eje Z

dS: Corrección de Escala (en partes por millón)

El resultado es la Matriz formada por Xt, Yt, Zt, habiendo de operar dichas matrices que se observan.

 Nota:

1)Rx, Ry,Rz por lo general son conocidos o dados en Segundos, pero en la Matriz debe estar primero transformados en Grados y luego pasarlos a Radianes :

Rx_radian = Rx * Pi / (3600 * 180)

Ry_radian = Ry * Pi / (3600 * 180)

Rz_radian = Rz * Pi / (3600 * 180)

 

2)A partir de dS obtenemos la variable M (mostrada en la Figura superior):

M = (1+ dS * 10^-6)

Luego la Matriz podría quedar de esta forma (tomando en cuenta los dos puntos de la Nota anterior):


 
 
 
 
 
 
 
 
 
  Reversibilidad de los Parámetros

Es posible usar los mismos parámetros con el signo cambiado para hacer la transformación inversa.

Fuente

La fuente que se usó para este Post es: http://www.ihsenergy.com/epsg/guid7.pdf, pagina 60.

Ejemplo de Aplicación

TO_WGS84_TRANS_DATUM_7_PARAMETERS.xlsx: es un ejemplo de aplicación de esta transformación de un Datum hacia el Datum WGS84. En la pestaña "7 PARAMETERS" se colocan los 7 Parámetros de transformación (los que están en rojo son pruebas).

FROM_WGS84_TRANS_DATUM_7_PARAMETERS.xlsx: es un ejemplo de aplicación de esta transformación del Datum WGS84 hacia otro Datum. En la pestaña "7 PARAMETERS" se colocan los 7 Parámetros de transformación (los que están en rojo son pruebas).

Estas dos hojas de cálculo son similares a la presentada en este Post:

http://www.ingeografos.com.pe/2012/10/transformacion-de-coordenadas-utm-tm.html, que esta la transformación de Datums de 3 Parámetros (en la pestaña “CARTESIANAS_GEODESICAS”).

La diferencia (aparte que está en Ingles ahora) con la Hoja de Cálculo del enlace de arriba es que la transformación de 7 Parámetros está en la Pestañas “TRANS 7 PARAMETERS”.

Esperando que sea útil este Post, será hasta el otro mes. Saludos y gracias

lunes, 18 de agosto de 2014

Leer y copiar la simbologia de una capa del ArcMap usando Python (Comtypes)


En este mes veremos como copiar la simbología de un Shapefile o Capa hacia otra en ArcMap usando Python y Comtypes (Comtypes lee los archivos OLB que contiene los objetos del ArcObjects). Para más referencia, pueden consultar este Post: http://www.ingeografos.com.pe/2012/04/python-y-arcobjects-2da-parte.html

Para ello usamos una sola capa y la copiamos en el ArcMap (en este ejemplo se usa un Shapefile o Capa de los departamentos del Perú). La capa de abajo será la capa 1 y tendra la simbologia a copiar  y la capa de arriba será la capa 0 y asignaremos la simbología de la capa 1. Tendremos algo así:


 

 
 
 
 
 
 
 
 
 
 
 Archivos OLB usados para obtención de los módulos requeridos:

esriArcMapUI.olb, que servirá para los siguientes Objetos:

1)      IMxDocument: Leerá el documento mxd actual

esriCarto.olb, que servirá para los siguientes Objetos:

1)       IMap: leera la vista o mapa del documento mxd actual y su contenido.

2)      IGeoFeatureLayer: leerá las simbologías de las capas

3)      IActiveView: accede la vista actual del documento mxd

 

esriFramework.olb, que servirá para los siguientes Objetos:

1)      IAppROT: Leerá la aplicación ArcGIS en ejecución

El código en Python es el siguiente:



from comtypes.client import GetModule, CreateObject
#PASO 01: CARGA DE LOS MODULOS NECESARIOS:
esriArcMapUI = GetModule("C:\Program Files\ArcGIS\com\esriArcMapUI.olb")
esriCarto = GetModule("C:\Program Files\ArcGIS\com\esriCarto.olb")
esriFramework = GetModule ("C:\Program Files\ArcGIS\com\esriFramework.olb")
#PASO 02: LEEMOS LA APLICACION ARCGIS:
pAppROT = CreateObject(esriFramework.AppROT, interface=esriFramework.IAppROT)
Application = pAppROT.Item(0)
MiProyMxd_TMP = Application.Document
MiProyMxd =  MiProyMxd_TMP.QueryInterface(esriArcMapUI.IMxDocument)
#PASO 03: LEEMOS LA VISTA DE LA APLICACION ARCGIS:
MiMapa_TMP = MiProyMxd.FocusMap
MiMapa = MiMapa_TMP.QueryInterface(esriCarto.IMap)
#PASO 04: LEEMOS LA CAPA CON SIMBOLOGIA:
MiLayerConSimbologia_TMP = MiMapa.Layer(1)
MiLayerConSimbologia = MiLayerConSimbologia_TMP.QueryInterface(esriCarto.IGeoFeatureLayer)
MiLeyenda = MiLayerConSimbologia.Renderer #ACA SE OBTIENE LA LEYENDA DE LA CAPA
#PASO 05: LEEMOS LA CAPA SIN SIMBOLOGIA:
MiLayerSinSimbologia_TMP = MiMapa.Layer(0)
MiLayerSinSimbologia = MiLayerSinSimbologia_TMP.QueryInterface(esriCarto.IGeoFeatureLayer)
MiLayerSinSimbologia.Renderer = MiLeyenda #ACA SE ASIGNA LA LEYENDA DE LA CAPA ANTERIOR A LA NUEVA


#PASO 06: REFRESCA LA VISTA Y EL TOC:
ActiveView_TMP = MiProyMxd.ActiveView
ActiveView = ActiveView_TMP.QueryInterface(esriCarto.IActiveView)
ActiveView.Refresh()
MiProyMxd.UpdateContents()



La explicación está dividida en 6 pasos:

Paso 01: Carga de los módulos necesarios (explicado en la descripción de dicho paso).

Paso 02: Lectura de la aplicación ArcGIS y del documento mxd. Las dos primeras líneas leen el ArcMap y las dos últimas leen el documento mxd.

Paso 03: Lectura de la vista o del mapa actual y lo guardamos en el objeto MiMapa (de tipo IMap y previo uso del QueryInterface).

Paso 04: Acá leemos la simbología que queremos copiar. La primera línea leemos la capa con la simbología (que es la capa 1). La segunda línea usando el  QueryInterface creamos el objeto MiLayerConSimbologia (de tipo IGeoFeatureLayer), y en la tercera línea obtenemos su leyenda (guardada en el objeto MiLeyenda).

Paso 05: Asignamos la simbología obtenida en el Paso 04. En la primera línea leemos la capa que asignaremos la simbología (que es la capa 0). En la segunda línea usando el  QueryInterface creamos el objeto MiLayerSinSimbologia (de tipo IGeoFeatureLayer), y en la tercera línea asignamos en la propiedad Renderer del objeto MiLayerSinSimbologia la variable MiLeyenda (proveniente del Paso 04).

Paso 06: Refrescamos la Vista y la Tabla de Contenido (TOC). La línea 1 y 2 creamos el objeto ActiveView (del tipo IActiveView y usando el QueryInterface) para luego actualizarlo “refrescarlo” en la línea 3, esto hará que la vista o mapa se actualice, y en la línea 4 actualizamos el TOC con la simbología copiada

El resultado será así:

 

 
 
 
 
 
 
 
 
 
  
Esperando que sea útil este código, será hasta el otro mes. Saludos.



ª