Archivo de la categoría: Digi3D

Aprovechando el hardware de una estación Delta en Digi3D.NET

La semana pasada una empresa que tenía una estación fotogramétrica Delta (de la empresa ucraniana Geosystems que ahora se llaman Analytica Ltd) adquirieron una licencia de Digi3D.NET.

La idea era aprovechar al 100% el hardware que tenían (manivelas y estereóscopo).

El estereóscopo se aprovecha trivialmente, en Digi3D.NET tan solo tienes que configurar como sistema de visión estereoscópica la opción de estereóscopo tal y como puedes ver en la siguiente captura de pantalla:

y Digi3D.NET se encarga de mostrar en la ventana fotogramétrica la pantalla partida para un estereóscopo.

El problema era aprovechar las manivelas, ya que las manivelas de esa estación están conectadas a una tarjeta PCI v1.0 que se pincha directamente en la placa base del ordenador:

Esta tarjeta tiene dos problemas:

  1. Las placas base modernas no suelen disponer de conector PCI v1.0, pero eso se puede solventar comprando un adaptador de PCI v1.0 a PCI express que puedes encontrar en Amazon por muy poco dinero.
  2. Esta tarjeta necesita un controlador para que Windows la reconozca, y no hay controladores de 64 bits para esta tarjeta, y no puedes instalar un controlador de 32 bits en un sistema operativo de 64 bits, así que no podemos conectar esta tarjeta en el mismo equipo en el que está Digi3D.NET

La única solución que se nos ha ocurrido consiste en utilizar dos ordenadores: Hemos instalado un Windows 10 de 32 bits (porque la máquina original tenía un XP) en la máquina que tenía conectada la tarjeta y hemos creado un servicio de Windows (de 32 bits) que se ejecuta en dicho ordenador.

Este servicio lo único que hace es leer coordenadas de la tarjeta de codificadores. Cuando detecta algún movimiento de manivelas o que se ha pulsado un pedal, envía coordenadas por UDP/IP a la dirección IP y al puerto configurados al instalar el servicio.

Hemos hecho este servicio Open Source, y lo hemos alojado en el siguiente repositorio:

https://github.com/digi21/ServicioLecturaCodificadoresDPW

En ese repositorio puedes ver cómo se leen coordenadas de esa tarjeta, la lógica para convertir los pedales a un formato compatible con Digi3D.NET, cómo enviar por UDP/IP un paquete de datos y cómo crear un servicio de Windows.

Por otro lado, hemos añadido en Digi3D.NET un nuevo tipo de dispositivo de entrada (UDP/IP) en la opción del menú Herramientas/Configuración de dispositivos de entrada…

Puedes configurar tanto el puerto en el que escucha la ventana fotogramétrica coordenadas de codificadores como los tensores (para asignar velocidades o cambiar sentido de movimiento).

Puedes ver en acción el nuevo servicio y cómo recibe en tiempo real Digi3D.NET coordenadas en el siguiente vídeo:

Desarrollando en .NET para la versión 2024 de Digi3D.NET

Hoy día 8 de enero de 2024 hemos publicado la versión 2024 de Digi3D.NET.

Esta versión viene cargada de novedades, y si eres desarrollador hay una que te va a afectar: El programa hora no es compatible con .NET Framework, sino que lo hemos portado a .NET 8.0.

Si has desarrollado alguna extensión para el programa o si has desarrollado algún programa de consola utilizando los ensamblados de Digi3D.NET, tendrás que portarlos de .NET Framework a .NET 8.0.

Para portar tus aplicaciones tan sólo tienes que instalar en Visual Studio 2022 la extensión .NET Upgrade Assistant, cargar tu proyecto y en el explorador de soluciones pulsar el botón derecho del ratón y seleccionar la opción de Upgrade. Aparecerá un asistente que migrará tanto los archivos de proyecto (actualizando paquetes NuGet, moviendo información que antes estaba en el archivo AssemblyInfo.cs al propio archivo de proyecto, etc.

Una de las diferencias más importantes entre .NET Framework y .NET es que ya no existe el Global Area Cache.

Cuando instalas en tu aplicación cualquiera de los paquetes NuGet que proporcionamos para desarrollar extensiones o aplicaciones:

Lo que instalas realmente es un Ensamblado De Referencia, es decir: un ensamblado que no tiene código ejecutable, únicamente tiene declaraciones de tipos, con sus propiedades, métodos, etc., pero sin código.

Cuando se instala una versión anterior de Digi3D.NET, el instalador almacena en el Global Area Cache los ensamblados de runtime (estos sí que tienen código) equivalentes.

Cuando ejecutas tu aplicación compilada con los ensamblados de referencia, el cargador de CLR de .NET Framework ve que tu aplicación depende de un ensamblado, por ejemplo: Digi21.DigiNG, versión 23.0.0.0, lo busca en el Global Area Cache y sabe que este está implementado por una DLL denominada Digi21.DigiNG.dll y la carga en memoria.

En Digi3D 2024 hemos seguido con la misma lógica: Los paquetes NuGet publican ensamblados de referencia y únicamente actualizamos estos paquetes NuGet cuando ha cambiado algo en la superficie pública de estos ensamblados. Si se modifica el programa por cualquier motivo (en el año 2023 hemos publicado en el canal BETA más de 140 versiones del programa) y dicha modificación no realiza ninguna modificación en la superficie pública de estos ensamblados, no es necesario actualizar los paquetes NuGet: el usuario actualiza la aplicación y tus herramientas siguen funcionando.

Pero conseguir que todo esto funcione de una forma transparente como con las versiones de .NET Framework no ha sido nada sencillo y te lo explico a continuación. Si no quieres entrar en detalles, mira el vídeo de abajo del todo y porque a partir de ahora me pondo un poquito más técnico:

.NET está pensado para que cargues en tus proyectos paquetes NuGet, que idealmente tienen o un único ensamblado de runtime o un ensamblado de referencia y múltiples ensamblados runtime (que implementan lo indicado en dicho ensamblado de referencia, como, por ejemplo, una versión específica para .NET Core 3.0, otra para .NET 5, otra para .NET 6, otra para Linux, otra para Mac, otra para Windows 10…).

Cuando el compilador se encuentra con un paquete NuGet de alguno de los dos casos indicados en el párrafo anterior (es decir que tienen al menos un ensamblado de runtime), almacena en el archivo .deps.json de la aplicación compilada una entrada denominada «runtime» en la que indica el nombre de la DLL a cargar.

El 100% de los paquetes que he visto en NuGet.org son así. Como todos tienen ensamblados de runtime, el compilador de manera automática rellena esa información en el archivo .deps.json.

Pero nuestros paquetes no tienen ensamblados de runtime, de manera que cuando se compilaba con las versiones alpha de nuestros paquetes NuGet para .NET 8.0, las aplicaciones no incluían en el archivo .deps.json información de runtime y el cargador del CLR no sabía qué DLL cargar.

Para solucionar esto, ahora todos los nuestros paquetes NuGet añaden un PostBuildEvent que modifica el archivo .deps.json de la aplicación compilada, añadiendo en caso de que no exista ya, una entrada runtime en la que se indica el nombre de la DLL que implementa el ensamblado.

Si te interesa cómo está hecho, he publicado en mi GitHub personal un repositorio en el que lo explico en detalle: https://github.com/joseangelmt/AddRuntimeToDepsJson

Y por último: si lo que has hecho no es una extensión para Digi3D.NET sino que es una aplicación que utiliza los ensamblados publicados por Digi3D.NET, como por ejemplo el ensamblado Digi21.DigiNG.IO.BinDouble, si no copias tu programa en el mismo directorio que la aplicación principal, no se va a localizar la DLL: Digi21.DigiNG.IO.BinDouble.dll, que es la que implementa dicho ensamblado.

Para solucionar esto, podemos añadir un nodo additionalProbingPaths en el archivo .runtimeconfig.json de tu programa indicando la ruta de instalación de la aplicación principal.

Para evitar tener que hacer esto manualmente, hemos creado el paquete NuGet: Digi21.Digi3D.App que lo único que hace es añadir un PostBuildEvent que añade al archivo .runtimeconfig.json de la aplicación compilada, en el nodo additionalProbingPaths una entrada al directorio de instalación de Digi3D.NET, y con esta entrada ya sí que podemos ejecutar nuestro programa desde cualquier directorio.
Tienes publicado el código de este paquete NuGet en el siguiente repositorio: https://github.com/digi21/Digi21.Digi3D.App

A continuación, un vídeo explicando todo esto de una manera sencilla:

Controles de calidad reescrito desde 0 por tercera (y esperemos definitiva) vez

A finales del 2014 presentamos en Digi3D.NET la funcionalidad Desencadenadores.
Eran controles de calidad se habilitaban en la tabla de códigos y se ejecutaban en tiempo real, es decir: al almacenar una geometría se desencadenaba (de
ahí el nombre de desencadenadores) que se analizasen las reglas asignadas al código.

Tenía el problema de que era una caja negra que únicamente disponía de una serie de reglas (programadas por nosotros en Digi21). El usuario no tenía libertad de añadir reglas propias.

En 2016 decidimos cambiarle el nombre que pasó de llamarse a Modelo semántico y se añadió una orden booleana denominada ANALIZAR_MODELO_SEMANTICO que básicamente habilitaba o deshabilitaba el análisis. De esta manera, podíamos deshabilitarlo para que no nos estuviera molestando el programa, pero esto era una evolución de lo presentado en 2014: seguíamos teniendo una caja negra.

A finales de 2016 añadimos el menú Modelo semántico que permitía (además de cambiar el valor de la orden ANALIZAR_MODELO_SEMANTICO), ejecutar tests de modelo semántico bajo demanda, analizando todas las geometrías del archivo de dibujo y mostrando los errores descubiertos en el panel de tareas de la aplicación.

Seguíamos con el problema de que los tests eran una caja negra: Si un usuario quería detectar como error una geometría con un número impar de vértices si el día en el que se analizaba la geometría era lunes, no podía, porque ese test no existe (ni creo que a nadie se le ocurra hacer algo así).

Debido a que nuestra política ha sido siempre evitar las cajas negras, decidimos hacer un primer borrón y cuenta nueva y cambiar todo lo relacionado con Modelo Semántico y hacer que sea el propio usuario el que pudiese programar a su antojo las reglas. Para ello eliminamos los cuadros de diálogo de selección de modelo semántico y añadimos a cada código la posibilidad de añadir un pequeño guion en cualquier lenguaje .NET (en la práctica C#) que se ejecutaría cada vez que el usuario digitaliza una geometría o cada vez que el usuario forzase un análisis bajo demanda.

Gracias a esto pudimos implementar el modelo de MGCP en Digi3D.NET y hace ya muchos años es lo que utilizan en el Centro Geográfico del Ejército para hacer sus tests.

El problema de este modelo es que al desaparecer los cuadros de diálogo de selección de tests y al requerir tener conocimientos de programación, en la práctica esta
funcionalidad la utilizaban en una o dos empresas.

Por otro lado, en 2021 añadimos el soporte para trabajar con Python en Digi3D.NET.

Python es un lenguaje de introducción a la programación que es muy sencillo, y hay muchas más posibilidades de que usuarios avanzados de GIS y cartografía lo conozcan.

Como Digi3D.NET es programable en .NET desde que le pusimos el apellido .NET (antes se llamaba Digi3D a secas), utilizamos una implementación de Python de Microsoft denominada IronPython, y con muy poco esfuerzo teníamos la posibilidad de interpretar guiones Python dentro del programa exponiendo todo el modelo de objetos de .NET.

Esta solución no era muy pythonic, pues lo expuesto no utilizaba a penas listas ni tuplas, sino objetos .NET en Python, pero era completamente funcional y cualquiera podía hacer guiones que interactuasen con Digi3D.NET. No se podían hacer órdenes, interactivas, pero sí guiones con lógica.

El problema de esta librería es que estaba anclada a la versión Python 2.7 que ya está anticuada (curiosamente acabo de ver mientras buscaba el enlace a IronPython para ponerlo más arriba que el 12 de diciembre de 2022 han publicado una versión compatible con Python 3.x).

Precisamente en diciembre de 2022 hemos añadido a MDTopX la posibilidad de ejecutar guiones Python. Como MDTopX es una aplicación 100% nativa, no tiene sentido utilizar IronPython para usarlo como motor de Python, de manera que hemos utilizado CPython, que es la implementación de Python nativa.

Una vez finalizada la implementación de Python en MDTopX, como lo teníamos fresco decidimos reescribir desde 0 también el motor de Python de Digi3D.NET.

Debido a este cambio, y viendo las posibilidades que tenía, hemos vuelto a hacer otro borrón y cuenta nueva, y hemos empezado de cero por tercera vez (esperemos que esta sea la definitiva) y hemos hecho que por un lado sea súper flexible, porque cualquiera puede añadir sus controles de calidad (como por ejemplo poder detectar como error geometrías con un número impar de vértices si el test lo ejecutamos un lunes), y por otro lado, tenemos cuadros de diálogo para añadir y configurar los controles de calidad gráficamente.

El truco consiste en que hemos añadido al editor de tablas de códigos un botón que permite descargar los controles de calidad de internet (de un repositorio GitHub).
Tan solo tienes que pulsar ese botón y los tienes en tu tabla de códigos y ya puedes asignarlos gráficamente a tus códigos.

Si sabes programar en Python, puedes modificar esos guiones, o comenzar de cero con tu propio sistema. Si creas algún control de calidad que crees que pueda ser útil para la comunidad, tan solo tienes que forkear el repositorio añadir tus controles de calidad y hacernos un pull-request que estaremos encantados de aceptar.

Además, le hemos vuelto a cambiar de nombre al concepto que pasa a denominarse Controles de Calidad.

Puedes ver esta nueva funcionalidad en el siguiente vídeo:

Todo lo relacionado con Python reescrito desde 0 en Digi3D.NET 2023

En Digi3D.NET hemos reescrito desde 0 todo lo relacionado con Python.

Hemos pasado de utilizar el motor IronPython a utilizar CPython. Gracias a esto, podemos programar en la versión 3.10 del lenguaje y además podemos utilizar las librerías que tengamos instaladas con PIP INSTALL en nuestro equipo.

Además, hemos cambiado el modelo de objetos. Antes, al utilizar el motor de IronPython lo que se hacía era publicar el modelo de objetos de .NET de Digi3D en el mundo de Python, de manera que los nombres de las clases, métodos, etc. adoptaban las recomendaciones de lenguajes .NET y no del lenguaje Python, es decir: El modelo de objetos no era «pythonic».

Ahora el modelo de objetos de Python de Digi3D.NET no tiene nada que ver con el modelo de objetos de .NET.

Este modelo de objetos nuevo permite además crear órdenes interactivas: Órdenes que esperan a que el usuario pulse un botón, una tecla, etc.

Además, hemos modificado el interfaz de usuario: Hemos eliminado el panel de Python Interactivo y ahora tenemos el panel Guion Python. Gracias a este panel, ahora podemos ver el código fuente en color, además de poder cargar, guardar y ejecutar el guion desde el propio panel.

Hemos modificado el código fuente de los guiones que teníamos en el repositorio ComandosDigi3DPython y además, para presentar al mundo todo esto, hemos creado la primera orden interactiva de Digi3D.NET programada en Python: dibuja_texto_extraido_callejero_catastro que puedes ver en el siguiente vídeo:

Rellena de manera automática atributos de geometrías mediante macros

Hemos modificado tanto el cuadro de diálogo que aparece cuando pulsamos el botón Mas (+) del panel de Atributos Activos como la orden ANADE_ATRIBUTO_ACTIVO para que nos permita indicar como valor por defecto del atributo una macro que se sustituirá en el momento de almacenar la geometría.

Puedes ver esta nueva funcionalidad en acción en el siguiente vídeo:

Controles de calidad en Digi3D.NET en Python

Hemos añadido a Digi3D.NET la posibilidad de crear controles de calidad utilizando el lenguaje de programación Python.

Hasta ahora podíamos crear controles de calidad en .NET. A partir de hoy podemos seleccionar la opción Python en el lenguaje de programación del guion que se ejecutará para un determinado código.

Puedes ver esta nueva funcionalidad en acción en el siguiente vídeo:

Diccionarios de atributos en las geometrías en Digi3D.NET

Acabamos de añadir a Digi3D.NET un diccionario de atributos a las geometrías. En este diccionario podremos almacenar tantos pares clave-valor como queramos.

Este diccionario no tiene ningún significado para el programa, pero sí para nosotros como usuarios ya que podemos añadir información alfanumérica a cada geometría.

Cada geometría dispone de su propio diccionario de atributos, de manera que podríamos tener con el código Persona una geometría sin atributos, otra con el mismo código, pero con un diccionario en el que se almacena únicamente el nombre de una persona y una tercera geometría que tenga el mismo código, pero en su diccionario de atributos tanto el nombre, como la edad y la altura. Es el usuario quien añade dinámicamente los atributos que quiere asignar a la geometría.

Hemos añadido un nuevo panel denominado Atributos Activos que nos permite añadir/eliminar dinámicamente atributos.

Además, hemos añadido la orden ELIMINA_ATRIBUTOS_ACTIVOS para limpiar el panel de atributos activos.

También hemos añadido la orden ANADE_ATRIBUTO_ACTIVO que nos va a permitir añadir atributos activos desde la línea de comandos.

Puedes listar los atributos de una geometría existente en el panel de resultados mediante la orden LISTA_ATRIBUTOS.

Si quieres establecer como atributos activos los que tenga una geometría existente, puedes ejecutar la orden CLONAR_ATRIBUTOS.

Puedes editar los atributos de una geometría existente mediante la orden EDITAR_ATRIBUTOS.

Si quieres asignar a una geometría existente los atributos del panel Atributos Activos, puedes hacerlo con la orden CAMB_ATRIBUTOS.

Puedes ver esta nueva funcionalidad en acción en el siguiente vídeo.

Sensor satelital Tri-Estéreo

Resulta que con el sensor satelital Pléiades puedes solicitar un producto denominado tri-stereo que consiste en tres imágenes con distintas orientaciones que permiten la visualización estereoscópica del modelo evitando ocultaciones.

Hemos añadido en Digi3D.NET la posibilidad de cargar las tres imágenes de manera simultánea y poder cambiar en tiempo real el par de imágenes que se muestran en la ventana fotogramétrica.

Puedes ver esta novedad en acción en el siguiente vídeo:

Abrir Google Street View y OpenStreetMap en la posición de la ventana fotogramétrica

Acabamos de añadir más opciones al grupo de opciones «Abrir xxxx en esta posición» en la ventana fotogramétrica de Digi3D.NET.

A partir de ahora podrás abrir un navegador mostrando Google Street View o OpenStreetMap en la posición en la que tienes la ventana fotogramétrica.

Puedes ver esta novedad en acción en el siguiente vídeo: