Mis Aventuras con AutoCAD MAP: Acceso a datos Geoespaciales

|

En posts anteriores prometi ir indicando este tipo de cosas para que la gente que se inicia en esto vaya teniendo idea de como funciona el famoso AutoCAD MAP y como usarlo con .NET, pues bien algo fundamental es como acceder a los datos Geoespaciales...
Primero que son los datos Geoespaciales?? Es sencillos terminos son los graficos de los mapas, estos normalmente estan divididos en capas en las cuales se tienen representaciones graficas de objetos de distintos tipos, es decir se tiene una capa que tiene los graficos que representan a las calles, otra capa tendra los hidrantes, otra capa tendra las casas (lotes, parcelas, o como les denominen)....
Estas capas fisicamente pueden estar almacenadas en una base de datos como en uno o varios archivos, como ustedes se imaginaran no es una buena practica desarrollar sistemas de informacion geografica sobre archivos, esto nos deja la opcion de la base de datos...
Es posible almacenar estos datos en algunas bases de datos como por ejemplo Oracle, MySQL y SQL Server, la verdad la que mas avanzada esta en el tema es Oracle, al punto de tener su propio visor de datos geoespaciales en las versiones 9i y 10g y prometen una mejora sustancial que aun no evaluo en 11g, SQL Server 2008 promete tambien soportar bien este tema, sin embargo se pueden usar las versiones 2005 e incluso 2000, con MySQL no tengo experiencia en el tema, pero claro si desean bajar un poco los costos de su solucion podrian evaluar esta opcion...
Asi mismo por varias razones se eligio usar Oracle, se intento con la version 9i pero la verdad tuvimos problemas un poco extraños como por ejemplo que a veces AutoCAD dibujaba los datos pero a veces no, las conversiones de sistemas de coordenadas no siempre funcionaban como debian, etc....
Decidido, se uso 10g una version Enterprise con AutoCAD MAP 3D 2008 SP1, lo del Service Pack del AutoCAD es importante por que quita una serie de Bugs molestosos cuando desarrollas, les cuento ademas que yo uso Visual Studio Team System SP1 sobre Windows Vista Business y no he tenido problemas con eso, una recomendacion si es que hagan que AutoCAD MAP funcione con permisos de administrador, asi cuando una excepcion es arrojada Vista no usara el control de excepciones propio del SO si no te mostrara la excepcion y podras saber que esta sucediendo...
Muy bien ahora la parte de la conexion de datos, como he mencionado en posts anteriores AutoCAD tiene la habilidad de hostear aplicaciones .NET, con esto uno puede hacer lo que desea en cuanto a programacion, pero claro el objetivo es usar las facilidades de AutoCAD, especialmente la concatenacion de datos geoespaciales y datos "normales" en la base de datos...
Me costo un poco de tiempo entender un poco la evolucion de este tema, AutoCAD MAP puede acceder de 2 formas a los datos espaciales de un modo nativo:

OSE: Esta es la primera forma de acceder a los datos, pero no los trata como ciudadanos de primera clase, es decir uno obtiene los datos, los modifica pero es dificil manipular datos "normales" asociados con estos...

FDO: Esta es una forma abierta de acceder a los datos, no solo en cualquier base de datos si no tambien en archivos SDF y servicios web geoespaciales (yo tampoco sabia que existian estos pero es cierto!!!), ademas de que es un proyecto Open Source, lo pueden encontrar aqui http://fdo.osgeo.org, con esto si se puede usar los datos graficos de un modo muy interesante, mas aun para mi si funciona con C#, en el caso de AutoCAD MAP 3D 2008 usa la version 3.2.1 que es uno de los ultimos releases, pero esto no lo libra de los bugs...

Para mi caso es claro que si deseo usar Oracle necesito tambien en la maquina cliente tener el famoso Oracle Client, yo les recomiendo la version 10.2.0.3 es la mas estable al momento y funciona en Windows Vista, las anteriores tienen problemas con Windows Vista...

He decidio usar FDO por muchas razones, la mas fuerte es que AutoCAD MAP 3D 2008 ofrece muchas facilidades para usarla como interfaz al usuario final y tambien al programador .NET, esto se refleja por ejemplo que para obtener los datos desde Oracle se pueden usar DataReaders, claro estos son especializados pero se los puede usar tal cual se usan DataReaders, ademas permite ver los datos adjuntos a los datos espaciales y modificarlos de un modo sencillo para un usuario comun, etc..., es un tanto dificil explicar en un solo post el uso de FDO por eso ire explicando por pasos como usarlo, desde la conexion, creacion de capas, actualizacion de objetos y datos, etc...

Bien con estas decisiones tomadas se puede decir que se puede inciar el trabajo, como les comentaba el problema mas grande que encontre yo es la falta de informacion sobre el tema, es por eso que ahora que ya he descubierto muchas de esas cosas he querido compartir esto para que no pasen lo que yo he pasado, y claro si tienen alguna pregunta con mucho gusto los ayudare, por lo pronto es todo por hoy!!!

Un ejemplo de ADO Entity Framework y LinQ

|

He estado un poco mas libre estos días así es que por esto he decidido poner mas cosas interesantes en mi blog, cuando me refiero a cosas interesantes me refiero a código útil, que en algún momento ya sea de ocio o desesperación, ha hecho que mi vida valga la pena!! Pues bien hay una revolución en nuestro mundo .NET que se está acercando a pasos agigantados como es el ADO Entity Framework, antes solo he escrito solo para anunciarlo o para comentar sobre el mismo, pues hoy les quiero mostrar como se puede usar el Entity Framework combinado con LinQ, es decir ustedes requieren o el Beta 2 de Visual Studio 2008 (Este es mi caso), o su RTM y el ultimo CTP del EF, es el de diciembre, en uno de mis anteriores post esta como descargarlo...


Muy bien!! Primero que es el EF?? El ADO Entity Framework permite que se cree una capa de persistencia automáticamente, cuando hablo de capa de persistencia me refiero a que se crean clases que manejan la interacción entre la Base de Datos y la solución, esta capa esta representada por clases que reflejan los elementos de la base de datos como las tablas, vistas, procedimientos almacenados, funciones, etc. a diferencia de otras soluciones existentes de este tipo (NHibernate y Hibernate para Java) esto es completamente VISUAL!!! A lo que nos tiene acostumbrado MS, es decir hago una conexion en Visual Studio 2008 en el Server Explorer, arrastro las tablas sobre mi modelo, especifico unos NameSpaces y voila!!! Capa de persistencia!! Y es realmente completa, uno ejecuta operaciones sobre las clases y esto se refleja automáticamente sobre la base de datos, además tiene cosas interesantes como el deferred execution, esto significa que la capa ejecuta las instrucciones solo cuando es realmente necesario, incluso se puede indicar que ciertos "campos" de la base de datos no sean obtenidos hasta que sean explícitamente utilizados, para que es útil esto?? Es bueno cuando almacenas archivos en campos binarios por ejemplo...


Como se lo hace?? Bien abren su Visual Studio 2008, se crean una librería de clases y la llaman como quieran, en mi caso TestLibCSharp, y le agregamos un archivo de tipo LinQToSql Classes como este:



Listo ahora desde el Server Explorer se debe arrastrar lo que uno desea incluir como objetos, si no tienen una conexión en el Server Explorer pues no es difícil crearla, al momento con mi versión y con el CTP de EF no es posible usar mas que SQL Server, pero al momento el resto de proveedores de datos como DataDirect ha anunciado que van a soportar también el EF por lo cual absolutamente todas las bases de datos comerciales que normalmente se usan podrán ser usadas también, bueno al arrastrar algunas tablas les debe quedar algo así:





Con eso ya se puede empezar a trabajar, pero antes revisen un poco las propiedades, si presionan F4 puede observar algunas cosas interesantes, como por ejemplo la conexión que usa, el NameSpace en donde puede ser referenciada, algo asi como lo de abajo:




Bueno como se imaginaran ahora lo que falta es usar la capa de persistencia, la verdad seria desaprovechar todo el potencial de .NET si no lo hago con LinQ, asi es que voy a incluir una clase dentro de la misma librería que hace uso del EF con LinQ y claro voy a explicar, de paso topo un par de nuevas características de C# 3.0:



Ahora vamos a seccionar el método LinQExample para indicar que se hizo:


En las líneas 14 y 15 se encuentra la creación de un nuevo DataContext, como recordaran mas arriba se veian propiedades como por ejemplo el NameSpace en el que se encuentra nuestro DataContext, en este caso BudgetClassesDataContext, en su constructor podemos especificar la cadena de conexión que deseamos usar, en mi caso la saco del archivo de configuración de la aplicación.


En las líneas 16, 17 y 18 se encuentra algo muy interesante, hace tiempo atrás en Visual Basic se podían usar tipos de datos Variant, es decir uno podía guardar cualquier cosa ahí, en C# el tipo var no es lo mismo, se la llama una variable de tipo implícito, es decir el tipo de esta variable es inferido basado en el tipo asignado con esto los programadores no están atados a declarar exactamente que tipo es hasta no instanciar la variable, de paso usamos LinQ, como ustedes saben LinQ es un lenguaje de consultas integrado a los lenguajes .NET el cual permite extraer datos en forma de objetos, no solo se puede actuar como en mi caso sobre el EF si no también sobre ciertos objetos, XML e incluso DataSets!! Es muy parecido al SQL, por no decir igualito, y básicamente se lo usa con un generador que es la clausula from, se la llama generador por que inicia la sentencia, en esta se especifica primero un objeto que representa a una entidad del conjunto sobre la cual se puede trabajar en el resto de la consulta, se le agrega un in para indicar de donde van a ser tomadas las entidades, en nuestro caso del DataContext instanciado y a su ves una clase que representa una tabla especifica de la base de datos, con esto ya especificamos el origen de los datos y un objeto sobre el cual podemos especificar condiciones en la siguiente clausula que es el where, como ustedes ven en la línea 17 el where especifica que de la entidad declarada en el from anterior se tome una propiedad de la misma y se cumpla con una condición, en palabras simples que se escoja las entidades que tengan en Active el valor de 1, para finalmente terminar con un select, en este podemos decir si se toma todas las propiedades de la entidad o solo algunas, en mi caso al poner solo el nombre de la entidad se traduce en un select *, esto retorna en este caso una lista de un tipo FiscalPeriod que es un tipo generado por el EF que representa una tabla y estas entidades cumplen con la condición de que el valor de la propiedad Active sea igual a 1.


Listo!! Pero esperen, si ejecutan esto o un ejemplo propio suyo paso a paso resulta que esto funciona muy rápido!! Es sospechoso verdad?? Pues esta correcto, LinQ ejecutara realmente la consulta la primera vez que se use el objeto resultante de la consulta, es decir en la línea 21, que ganamos?? Pues velocidad en el procesamiento y es oportuno además, claro que la línea 21 no es un buen ejemplo de cómo se debe programar en .NET pero es tan solo un ejemplo….


Espero que esta breve guía les sirva y puedan empezar a utilizar LinQ y el EF, realmente es algo muy prometedor y ayuda a reducir aun mas los tiempos de desarrollo, esperemos que tenga un buen futuro!!!

Web 2.0: Que mismo es?

|

Tengo que reconocerlo: No me agrada el termino!!! Definitivamente!!! Lamentablemente un monton de gente experta le da esa denominacion, para lo que a mi respecta, a un paso logico que es la evolucion y mejora de la experiencia del usuario en la Web, y para colmo de males mucha de la gente tecnica piensa que usar Ajax es suficiente!!! Realmente estoy en desacuerdo, es por eso que lo expreso aqui en mi blog!! Quieren una defincion que me agrado bastante??

Wikipedia: http://en.wikipedia.org/wiki/Web_2

Estoy en una especia de campaña de difusion del tema, es bastante ya con que los gobernantes de paises mantengan ignorantes a la gente para que no opine, no debemos dejar que algo similar suceda con el conocimiento en la Web!!!

El Gourmet .NET: Que es mas eficiente, un if, un ?: o un ??

|

Hace tiempo que no hacia una entrega del Goumet .NET, pues bien hace dias estaba preguntandome esto, es que mas eficiente? una instruccion if, el operador ?: o el operador ?? (Este operador lo he descubierto recientemente!!! Es tan grande C# que a uno se le pasan estas cosas...), bueno para probar esto hice el siguiente codigo:


using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
namespace CSharpTestHost
{
public class clsTest
{
///
/// Prueba con instruccion If
///

/// pdtbData1: Parametro a ser evaluado
/// Devuelve: Un datatable instanciado
public DataTable IfTest(DataTable pdtbData1)
{
DataTable dtbResult;
if (pdtbData1 != null)
{
dtbResult = pdtbData1;
}
else
{
dtbResult = new DataTable();
}
return dtbResult;
}

///
/// Prueba con operador ?:
///

/// pdtbData1:Parametro a ser evaluado
/// Devuelve: Un datatable instanciado

public DataTable InLineIfTest(DataTable pdtbData1)
{
return (pdtbData1 != null) ? pdtbData1 : new DataTable();
}

///
/// Prueba con operador ??
///

/// pdtbData1: Parametro a ser evaluado
/// Devuelve: Un datatable instanciado

public DataTable InLineIfTest2(DataTable pdtbData1)
{
return pdtbData1 ?? new DataTable();
}
}
}

Despues de esto si ustedes revisan los 3 metodos de esa clase cumplen exactamente la misma funcion, es decir evaluan si el objeto parametro, en este caso un DataTable, es diferente de null y devuelven un nuevo objeto de ser esto cierto, debemos recordar que el hecho de usar menos codigo no necesariamente quiere decir que es mas eficiente, como ustedes saben cuando uno usa C# la implementacion de operadores es posible y detras de esos tambien se puede poner bastante codigo!!
Con esta duda en mente, se me ocurrio utilizar ildasm (para quienes no la conocen a esta herramienta lo que hace es desemsablar el codigo de tu assembly .net y te lo muestra en MSIL, que es muy parecido al assembler y la verdad es bastante facil de leer) y compare los 3 metodos, con la referencia de que MSIL es casi assembler es un punto perfecto para comparar los 3 metodos, aqui estan los resultados:

Metodo con If:


.method public hidebysig instance class [System.Data]System.Data.DataTable
IfTest(class [System.Data]System.Data.DataTable pdtbData1) cil managed
{
// Code size 29 (0x1d)
.maxstack 2
.locals init ([0] class [System.Data]System.Data.DataTable dtbResult,
[1] class [System.Data]System.Data.DataTable CS$1$0000,
[2] bool CS$4$0001)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldnull
IL_0003: ceq
IL_0005: stloc.2
IL_0006: ldloc.2
IL_0007: brtrue.s IL_000f
IL_0009: nop
IL_000a: ldarg.1
IL_000b: stloc.0
IL_000c: nop
IL_000d: br.s IL_0017
IL_000f: nop
IL_0010: newobj instance void [System.Data]System.Data.DataTable::.ctor()
IL_0015: stloc.0
IL_0016: nop
IL_0017: ldloc.0
IL_0018: stloc.1
IL_0019: br.s IL_001b
IL_001b: ldloc.1
IL_001c: ret
} // end of method clsTest::IfTest

Metodo con In Line If u operador ?:


.method public hidebysig instance class [System.Data]System.Data.DataTable
InLineIfTest(class [System.Data]System.Data.DataTable pdtbData1) cil managed
{
// Code size 17 (0x11)
.maxstack 2
.locals init ([0] class [System.Data]System.Data.DataTable CS$1$0000)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: brtrue.s IL_000b
IL_0004: newobj instance void [System.Data]System.Data.DataTable::.ctor()
IL_0009: br.s IL_000c
IL_000b: ldarg.1
IL_000c: stloc.0
IL_000d: br.s IL_000f
IL_000f: ldloc.0
IL_0010: ret
} // end of method clsTest::InLineIfTest

Metodo con operador ??:


.method public hidebysig instance class [System.Data]System.Data.DataTable
InLineIfTest2(class [System.Data]System.Data.DataTable pdtbData1) cil managed
{
// Code size 16 (0x10)
.maxstack 2
.locals init ([0] class [System.Data]System.Data.DataTable CS$1$0000)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: dup
IL_0003: brtrue.s IL_000b
IL_0005: pop
IL_0006: newobj instance void [System.Data]System.Data.DataTable::.ctor()
IL_000b: stloc.0
IL_000c: br.s IL_000e
IL_000e: ldloc.0
IL_000f: ret
} // end of method clsTest::InLineIfTest2

Ganador: Definitivamente el operador ?? es el ganador, por 1 byte!!

Ahora claro esta comparacion esta basada en la comprobacion de si un objeto esta vacio (es decir tiene una referencia a null) y que devolver, no siempre es practico el operador ??, por ejemplo en objetos que tienen solo valores (tipos primitivos como int, double, etc...) no es aplicable, a menos claro que uses nullable types, y en otros casos en los que tienes que ejecutar varias operaciones definitivamente el tradicional if sera el llamado a ejecutar las operaciones!!!

Espero que esto les ayude en sus decisiones sobre como escribir codigo, a veces 1 milisegundo menos de ejecucion ayuda a todo el perfomance de la aplicacion!!!

ADO Entity Framework Beta 3!!

|

Hace tiempo comentaba yo acerca de este Framework que permitira crear las famosas capas de persistencia con solo tener el modelo fisico de tu base de datos lista!! Si asi es, este mapea las tablas, vistas, stored procedures y demas a entidades en forma de clases, tambien claro hace el trabajito de poner el codigo y generar las sentencias sql necesarias para que estos datos esten siempre sincronizados!!!
La novedad es que se ha anunciado que oficialmente se dara soporte no solo a sql server si no a otros proveedores de datos!!
Para quienes ha utilizado Hibernate u otra solucion de este tipo van a ver que es tan sencillo usar el EF que el tiempo de desarrollo se vera cortado por la mitad!!!

Hay de todas maneras algunas dudas que tengo, por ejemplo con SQL Server estoy seguro que la generacion del SQL sera muy buena y funcionara muy bien, pero en otras bases de datos como por ejemplo Oracle que es muy sensible a como esta generada la sentencia se tendra en cuenta este tipo de cosas?? Espero que si!!!

Quieren saber un poco mas??
Revisen esto:
http://visualstudiomagazine.com/news/article.aspx?editorialsid=9323

Que pasa cuando mi Task Pane se pone en blanco??

|

Hace unas semanas en una de mis instalaciones de Smart Documents me tope con algo interesante, resulta que habia instalado normalmente un SmartDoc de Excel sobre un Office 2007 en Windows XP, todo fue normal, unos dias despues resulta que al iniciar el documento el panel de tareas de las acciones de documentos estaba en blanco, hagas lo que hagas, no sirvio reinstalar Office (es lo primero que se me ocurrio), buscar programas recientemente instalados, cambiar de usuarios, revisar permisos de ejecucion, nada!!! Entoces comence a buscar por los foros y encontre un problema con Office 2003, pero leyendo un poco mas resulta que no era problema con Office si no con IE, al parecer un parque de seguridad pone en lista negra el id del control ActiveX del task pane y simplemente no ejecuta nada!! Como uno puede imaginarse algo asi??
Bien aqui esta el link de donde encontre la solucion:

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2278405&SiteID=1

Y la solucion es quitar esta clave del registro:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{5f61f809-422a-4152-91f5-9ec1b935efd7}

Busquenla, si la encuentran no lo duden, quitenla intenten de nuevo y funciona como magia!!!

ParallelFX: Codigo Manejado en paralelo de verdad!!

|

Escucharon de ParalleFX?? Si no esta es una extension al Framework 3.5 que permite utilizar de verdad y facilmente la capacidad multicore o multiprocesador de tu sistema, y claro como siempre en .NET esta se puede usar muy facil y en cualquier lenguaje como C# o VB, quieren saber mas?? Aqui esta un link a un articulo muy interesante:

http://msdn.microsoft.com/msdnmag/issues/07/10/Futures/default.aspx

Y si quieren bajarlas vayan al sitio de ParallexFX (Parallel Computing Develper Center):

http://msdn2.microsoft.com/en-us/concurrency/default.aspx

Espero que esto marque de verdad una diferencia!!!