Tema3 Lidar

41
Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura Escuela Politécnica Superior de Ávila 1 Universidad de Salamanca 1 Cargar archivo de datos terrestres Vamos a comenzar leyendo un archivo de puntos de datos Terrestre con las coordenadas xyz de los mismos. Utilizaremos algo de lo usado en el ejercicio 9 de la parte de introducción para permitir leer un archivo de puntos y mostrar las coordenadas en una tabla, en este caso los archivos que vamos a leer utilizan como separador el tabulador. Después probaremos a representar los puntos leídos ayudándonos de un componente de evaluación. Comenzamos un proyecto nuevo que se llamará “LeerFicherosTerrestre”. Vamos a intentar leer ficheros de puntos en coordenadas X Y Z, separados por “tabulador”. Y vamos a representar esos puntos. Creamos el menú con el control MenuStrip en el grupo Menús y Barras de Herramientas. El formulario presentará el aspecto: Las etiquetas que vemos, un cuadro de texto con nombre “txt_ruta” para ver la ruta del archivo leído, un cuadro de texto “txt_leidos” en el que mostraremos el número de puntos que se lean, un cuadro de texto “txt_visor” en el que pondremos la propiedad Multiline a True, para mostrar las líneas que vamos leyendo del fichero y un DataGridView que encontramos en la categoría de Datos y llamamos “dgv_tabla”. Al insertar la tabla le agregamos tres columnas con los nombres de las coordenadas de los puntos X, Y, Z.

Transcript of Tema3 Lidar

Page 1: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 1 Universidad de Salamanca

1 Cargar archivo de datos terrestres

Vamos a comenzar leyendo un archivo de puntos de datos Terrestre con las coordenadas

xyz de los mismos. Utilizaremos algo de lo usado en el ejercicio 9 de la parte de

introducción para permitir leer un archivo de puntos y mostrar las coordenadas en una

tabla, en este caso los archivos que vamos a leer utilizan como separador el tabulador.

Después probaremos a representar los puntos leídos ayudándonos de un componente de

evaluación.

Comenzamos un proyecto nuevo que se llamará “LeerFicherosTerrestre”. Vamos a

intentar leer ficheros de puntos en coordenadas X Y Z, separados por “tabulador”. Y

vamos a representar esos puntos.

Creamos el menú con el control MenuStrip en el grupo Menús y Barras de

Herramientas.

El formulario presentará el aspecto:

Las etiquetas que vemos, un cuadro de texto con nombre “txt_ruta” para ver la ruta del

archivo leído, un cuadro de texto “txt_leidos” en el que mostraremos el número de

puntos que se lean, un cuadro de texto “txt_visor” en el que pondremos la propiedad

Multiline a True, para mostrar las líneas que vamos leyendo del fichero y un

DataGridView que encontramos en la categoría de Datos y llamamos “dgv_tabla”. Al

insertar la tabla le agregamos tres columnas con los nombres de las coordenadas de los

puntos X, Y, Z.

Page 2: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 2 Universidad de Salamanca

Para el acceso al sistema de archivos utilizaremos el diálogo OpenFileDialog del grupo

de controles Diálogos.

Comenzamos con la opción la operación de leer que asociaremos al menú

Archivo/Abrir.

Para el utilizar las clases relacionadas con la entrada y salida, importamos el espacio de

nombres Imports System.IO al comienzo del código.

Escribimos el código siguiente:

Private Sub AbrirToolStripMenuItem_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AbrirToolStripMenuItem.Click OpenFileDialog1.Filter = "Archivos Ascii(*.asc)|*.asc|Archivos de Texto(*.txt)|*.txt|T odos los Archivos|*.*" 'Le indicamos los filtros que aparecerán al selecci onar los archivos. asc, txt, o todos. OpenFileDialog1.ShowDialog() 'Mostramos diálogo de Abrir txt_ruta.Text = OpenFileDialog1.FileName 'Colocamos en el cuadro de texto la ruta y nombre del fichero selecc ionado Dim leer As New StreamReader( New FileStream(OpenFileDialog1.FileName, FileMode.Open) ) 'Creamos la variable de tipo StreamReader que nos p ermitirá manejar el fichero 'la variable se crea a partir otra de tipo FileStre am asociada al archivo seleccionado y 'Abiendo el archivo Dim linea As String txt_visor.Clear() 'Borramos el cuadro que visionará las lineas leídas dgv_tabla.Rows.Clear() 'Borramos la tabla que muestra las coordenadas de l os puntos Dim punto(2) As String 'Vector de tres cadenas para guardar la X,Y,Z de cada punto Do linea = leer.ReadLine 'Leemos una linea del fichero If Not linea Is Nothing Then 'Si la linea no está vacia punto = Split(linea, vbTab, 3) 'Separamos con la función Split la linea por la posición del separado r "tabulador" 'Limitamos el número de trozos a 3 para no desborda r el vector If punto.Length = 3 Then 'Si no hay tres coordenadas descartamos el dato dgv_tabla.Rows.Add(punto(0), pu nto(1), punto(2)) 'Añado las coordenadas del punto a la tabla End If txt_visor.AppendText(linea & vbCrLf ) 'Añado la linea leída al visor. vbCrLf es un salto de linea End If Loop Until linea Is Nothing 'Repetimos hasta que linea sea vacia que se habrá terminado el fichero leer.Close() 'Cerramos el fichero leer = Nothing txt_leidos.Text = dgv_tabla.Rows.Count - 1 'Pongo en txt_leidos el numero de puntos añadidos a la tabla. End Sub

Page 3: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 3 Universidad de Salamanca

Se puede entender el código a partir de los comentarios. Se podría realizar un control

más preciso de errores para contemplar casos en que los archivos proporcionados no se

ajusten al formato previsto. Pero como comienzo lo dejamos así.

Intentamos probar el código que hemos escrito hasta el momento. Abrimos el fichero

“CuatroPostesmini.asc” que se proporciona como ejemplo, tiene 16650 puntos. Luego

probamos con el completo.

Guardamos el proyecto y lo cerramos.

Page 4: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 4 Universidad de Salamanca

2 Convertir los puntos a DXF.

Cuando realicemos algunas operaciones sobre los puntos y queramos utilizarlos en

alguno de los programas habituales de diseño gráfico, necesitaremos tenerlos en algún

formato estándar. El formato DXF nos lo reconocerá la mayoría de los programas.

Podríamos utilizar algún componente existente para la conversión a DXF, pero algunos

no son gratuitos. Otros no están disponibles para Visual .Net. Además así lo conocemos

y podemos añadir esa funcionalidad a nuestras aplicaciones. Vamos a intentar entender

la estructura de un archivo DXF, y vamos a programar una aplicación sencilla para

realizar la conversión sólo de puntos. Después en otro ejercicio posterior, crearemos una

biblioteca de clases para dejar preparada la conversión a DXF para otras aplicaciones

futuras.

2.1 ESTRUCTURA DE UN ARCHIVO DXF.

DXF viene de Drawing eXchange Format, es un archivo de intercambio de dibujos de

CAD. Los archivos DXF son archivos ASCII. También hay DXF binarios pero con el

tiempo los ASCII han ganado protagonismo y si no se indica lo contrario cuando nos

hablan de DXF se refieren a estos. Los archivos DXF se componen de pares de códigos

y valores asociados. Los códigos, se llaman códigos de grupo e indican el tipo de valor

que les sigue. Los archivos DXF se organizan en secciones, que constan de registros a

su vez compuestos o por un código de grupo o un elemento de datos: cada código de

grupo y su valor cuentan con su propia línea en el archivo DXF. Cada sección comienza

con un código de grupo 0 seguido por la cadena SECTION. A continuación aparece un

código de grupo 2 y una cadena que indica el nombre de la sección (por ejemplo,

HEADER). Las secciones terminan con un 0 seguido de la cadena ENDSEC.

Las principales secciones de un archivo DXF y su orden son:

SECCIÓN DESCRIPCIÓN Sección HEADER Información de carácter general sobre el dibujo. Se compone de

un número de versión de base de datos de AutoCAD y de una

serie de variables de sistema. Cada uno de los parámetros

contiene un nombre de variable y su valor asociado.

Sección CLASSES Información de las clases definidas por la aplicación, cuyas

apariciones se contienen en las secciones BLOCKS, ENTITIES

y OBJECTS de la base de datos

Sección TABLES Definiciones de las siguientes tablas: APPID (tabla de

identificación de las aplicaciones) BLOCK_RECORD (tabla de

referencia de bloques) DIMSTYLE (tabla de estilos de

acotación) LAYER (tabla de capas) LTYPE (tabla de tipos de

línea) STYLE (tabla de estilos de texto) UCS (tabla del Sistema

de coordenadas personales) VIEW (tabla de visualización)

VPORT (tabla de configuración de la ventana gráf.)

Sección BLOCKS Definiciones de bloques

Sección ENTITIES Contiene los objetos gráficos (entidades) del dibujo, incluidas

las referencias a bloques (entidades insertadas).

Sección OBJECTS Los objetos no gráficos del dibujo. En esta sección es donde se

almacenan todos los objetos que no sean entidades ni registros

de la tabla de símbolos.

Page 5: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 5 Universidad de Salamanca

Los códigos de grupo definen el tipo de valor asociado como un número entero, un

número de coma flotante o una cadena, según la siguiente tabla de rangos de código de

grupo.

RANGO DE CÓDIGO

TIPO DE VALOR DE GRUPO

0 - 9 Cadena

10 - 59 Punto 3D de doble precisión

60 - 79 Valor entero de 16 bits

90-99 Valor entero de 32 bits

100 y 102 Cadena

105 Cadena con un valor de identificador hexadecimal

140 - 147 Valor de coma flotante escalar de doble precisión

170 - 175 Valor entero de 16 bits

280 - 289 Valor entero de 8 bits.

300 - 309 Cadena de texto arbitraria

310-319 Cadena que representa el valor hexadecimal de un bloque

binario

320-329 Cadena que representa un valor de identificador Hexadecimal

330-369 Cadena que representa identificador de objeto hexadecimal

999 Comentario

1000 - 1009 Cadena

1010-1059 Valor de coma flotante

1060 - 1069 Valor entero de 16 bits

1071 Valor entero de 32 bits

Hay algunos valores que por lo que se usan conviene tratar con más detalle:

CÓDIGO DESCRIPCIÓN 0 Cadena de texto que indica el tipo de entidad (fijo)

1 Valor de texto principal de una entidad

2 identificador de atributos, nombre de bloque, etc.

5 Identificador de entidad. Cadena de texto de hasta 16 dígitos

hexadecimales (fijo)

6 Nombre de tipo de línea (fijo)

7 Nombre de estilo de texto (fijo)

8 Nombre de capa (fijo)

9 DXF: identificador de nombre de variable (sólo se utiliza en la sección

HEADER (encabezamiento) del archivo DXF)

40-48 Valores de coma flotante (altura de texto, factores de escala,etc.)

62 Número de color (fijo)

66 Indica que siguen entidades. Caso de entidades complejas

67 Espacio (modelo o papel).

70-78 Valores enteros, como número de repeticiones, bits indicadores o modos.

Page 6: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 6 Universidad de Salamanca

Algunas entidades del formato DXF:

ALGUNAS ENTIDADES POINT LINE POLYLINE 3DFACE

3DSOLID ARC CIRCLE DIMENSION

ELLIPSE SOMBREADO TEXT SPLINE

IMAGE SHAPE SOLID VERTEX

En el archivo siguiente se aprecia un documento básico en DXF con dos entidades

punto y una Línea. Usamos alguna capa sin definirla antes, de esta forma se le asigna el

tipo de línea continuo y el color 7 (Blanco). Lo hacemos así por ahorrar todo el código

posible. Tampoco indicamos las variables de la cabecera. Si cogemos un DXF de alguna

aplicación CAD nos daríamos cuenta de la gran cantidad de variables que aparecen.

Para un ejemplo sencillo prescindimos de ellas.

0 COMIENZO DE SECCIÓN SECTION INDICADOR DE SECCIÓN 2 CÓDIGO DE GRUPO ENTITIES INDICADOR DE QUE ES LA SECCIÓN ENTIDADES 0 CODIGO DE COMIENZO DE ENTIDAD POINT TIPO DE ENTIDAD PUNTO 8 CÓDIGO QUE INDICA QUE SIGUE UNA CAPA 8 Puntos NOMBRE DE LA CAPA EN ESTE CASO PUNTOS 10 CÓDIGO DE LA COORDENADA X 150.000 VALOR DE LA X DEL PUNTO 20 CÓDIGO DE LA Y 125.000 VALOR DE LA Y DEL PUNTO 30 CÓDIGO DE LA Z 75.000 VALOR DE LA Z 0 COMIENZO DE OTRA ENTIDAD POINT INDICA QUE ES UN PUNTO 8 COMO ANTES LA CAPA Y LA X, Y, Z DEL PUNTO Puntos 10 250.000 20 225.000 30 75.000 0 COMIENZO DE OTRA ENTIDAD LINE ES UNA LINEA 8 INDICADOR DE QUE SIGUE UNA CAPA Lineas NOMBRE DE LA CAPA 62 CODIGO PARA INDICAR UN COLOR DE ENTIDAD 5 COLOR 5 AZUL 10 CODIGO DE LA X DEL PUNTO INICIAL DE LA LINEA 100.000 VALOR DE LA X DEL INICIO DE LINEA 20 CÓDIGO DE LA Y 100.000 VALOR DE LA Y DEL INICIO DE LINEA 30 CÓDIGO DE LA Z 100.000 VALOR DE LA z DEL INICIO 11 CÓDIGO DE LA X DEL FIN DE LINEA 200.000 VALOR DE LA X DEL FINAL 21 CÓDIGO DE LA Y 200.000 VALOR DE LA Y DEL FINAL 31 CÓDIGO DE LA Z 200.000 VALOR DE LA Z DEL FINAL DE LA LINEA 0 PARA INDICAR QUE SIGUE UNA PALABRA A ANALIZAR ENDSEC FINAL DE LA SECCIÓN DE ENTIDADES 0 QUE SIGUE UNA PALABRA EOF FINAL DEL FICHERO

Page 7: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 7 Universidad de Salamanca

2.2 CREACIÓN DE LA APLICACIÓN. Creamos ahora el programa que leerá puntos en formato XYZ, con o sin información de

color RGB. Creamos la aplicación de tipo Aplicación para Windows como en otras

ocasiones y asignamos el nombre convertir_a_DXF a la misma. Sólo tendremos un

formulario principal en el programa, le ponemos como nombre frm_convertir.vb.

Presentará el aspecto:

Como vemos hemos colocado un GroupBox con el título “Convertir a DXF” a modo de

contenedor. Sobre él, dos cuadros de texto a los que llamaremos txt_Original y

txt_Destino y los cuatro botones que vemos. El mensaje de aviso sobre los puntos que

podemos utilizar lo hemos puesto con una etiqueta (Label). También necesitamos los

cuadros de diálogo para abrir el archivo de puntos y para seleccionar el nombre y la

ubicación en la que se guardará el archivo DXF generado. Agregaremos un

OpenFileDialog del grupo Cuadros de diálogo, y un SaveFileDialog del mismo grupo.

Al botón Archivo Original le asignamos el código:

Al botón Archivo Destino le asignamos el código:

Private Sub Button3_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click OpenFileDialog1.Filter = "Archivos Ascii(*.asc)|*.asc|Archivos de Texto(*.txt)|*.txt|A rchivos XYZ(*.xyz)|*.xyz|Todos los Archivos|*.*" 'Le indicamos los filtros que aparecerán al selecci onar los archivos. asc, txt, xyz o todos. OpenFileDialog1.ShowDialog() 'Mostramos diálogo de Abrir txt_Original.Text = OpenFileDialog1.FileNam e 'Colocamos en el cuadro de texto la ruta y nombre del fichero sel eccionado End Sub

Private Sub Button4_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click SaveFileDialog1.Filter = "Archivo DXF(*.dxf)|*.dxf" 'Establecemos el formato de archivo de salida a *.d xf SaveFileDialog1.ShowDialog() 'Abrimos el diálogo de guardar txt_Destino.Text = SaveFileDialog1.FileName 'Ponemos en el cuadro la ruta de guardar el nombre y ruta del archivo. End Sub

Page 8: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 8 Universidad de Salamanca

Dejamos la parte de convertir el código para el final y colocamos el fragmento de salir:

Los archivos colores en DXF siguen una distribución diferente a los RGB que nosotros

leemos. Crearemos un módulo para definir en el una función que nos convierta los

colores de RGB al formato compatible con DXF. Para Agregar el módulo pulsamos en

el menú Proyecto/Agregar Módulo y añadimos un módulo con nombre Funciones.vb.

Este módulo contiene:

Private Sub Button2_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Me.Close() End Sub

Module Funciones Dim ACI_RGBValues(,) As Integer = New Integer (,) {{0, 0, 0}, _ {255, 0, 0}, _ {255, 255, 0}, _ {0, 255, 0}, _ {0, 255, 255}, _ {0, 0, 255}, _ {255, 0, 255}, _ {255, 255, 255}, _ {65, 65, 65}, _ {128, 128, 128}, _ {255, 0, 0}, _ {255, 170, 170}, _ {189, 0, 0}, _ {189, 126, 126}, _ {129, 0, 0}, _ {129, 86, 86}, _ {104, 0, 0}, _ {104, 69, 69}, _ {79, 0, 0}, _ {79, 53, 53}, _ {255, 63, 0}, _ {255, 191, 170}, _ {189, 46, 0}, _ {189, 141, 126}, _ {129, 31, 0}, _ {129, 96, 86}, _ {104, 25, 0}, _ {104, 78, 69}, _ {79, 19, 0}, _ {79, 59, 53}, _ {255, 127, 0}, _ {255, 212, 170}, _ {189, 94, 0}, _ {189, 157, 126}, _ {129, 64, 0}, _ {129, 107, 86}, _ {104, 52, 0}, _ {104, 86, 69}, _ {79, 39, 0}, _ {79, 66, 53}, _ {255, 191, 0}, _ {255, 234, 170}, _ {189, 141, 0}, _ {189, 173, 126}, _ {129, 96, 0}, _ {129, 118, 86}, _ {104, 78, 0}, _ {104, 95, 69}, _ {79, 59, 0}, _ {79, 73, 53}, _ {255, 255, 0}, _ {255, 255, 170}, _ {189, 189, 0}, _ {189, 189, 126}, _ {129, 129, 0}, _ {129, 129, 86}, _

{104, 104, 0}, _ {104, 104, 69}, _ {79, 79, 0}, _ {79, 79, 53}, _ {191, 255, 0}, _ {234, 255, 170}, _ {141, 189, 0}, _ {173, 189, 126}, _ {96, 129, 0}, _ {118, 129, 86}, _ {78, 104, 0}, _ {95, 104, 69}, _ {59, 79, 0}, _ {73, 79, 53}, _ {127, 255, 0}, _ {212, 255, 170}, _ {94, 189, 0}, _ {157, 189, 126}, _ {64, 129, 0}, _ {107, 129, 86}, _ {52, 104, 0}, _ {86, 104, 69}, _ {39, 79, 0}, _ {66, 79, 53}, _ {63, 255, 0}, _ {191, 255, 170}, _ {46, 189, 0}, _ {141, 189, 126}, _ {31, 129, 0}, _ {96, 129, 86}, _ {25, 104, 0}, _ {78, 104, 69}, _ {19, 79, 0}, _ {59, 79, 53}, _ {0, 255, 0}, _ {170, 255, 170}, _ {0, 189, 0}, _ {126, 189, 126}, _ {0, 129, 0}, _ {86, 129, 86}, _ {0, 104, 0}, _ {69, 104, 69}, _ {0, 79, 0}, _ {53, 79, 53}, _ {0, 255, 63}, _ {170, 255, 191}, _ {0, 189, 46}, _ {126, 189, 141}, _ {0, 129, 31}, _ {86, 129, 96}, _ {0, 104, 25}, _ {69, 104, 78}, _ {0, 79, 19}, _ {53, 79, 59}, _ {0, 255, 127}, _ {170, 255, 212}, _ {0, 189, 94}, _ {126, 189, 157}, _

Page 9: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 9 Universidad de Salamanca

{0, 129, 64}, _ {86, 129, 107}, _ {0, 104, 52}, _ {69, 104, 86}, _ {0, 79, 39}, _ {53, 79, 66}, _ {0, 255, 191}, _ {170, 255, 234}, _ {0, 189, 141}, _ {126, 189, 173}, _ {0, 129, 96}, _ {86, 129, 118}, _ {0, 104, 78}, _ {69, 104, 95}, _ {0, 79, 59}, _ {53, 79, 73}, _ {0, 255, 255}, _ {170, 255, 255}, _ {0, 189, 189}, _ {126, 189, 189}, _ {0, 129, 129}, _ {86, 129, 129}, _ {0, 104, 104}, _ {69, 104, 104}, _ {0, 79, 79}, _ {53, 79, 79}, _ {0, 191, 255}, _ {170, 234, 255}, _ {0, 141, 189}, _ {126, 173, 189}, _ {0, 96, 129}, _ {86, 118, 129}, _ {0, 78, 104}, _ {69, 95, 104}, _ {0, 59, 79}, _ {53, 73, 79}, _ {0, 127, 255}, _ {170, 212, 255}, _ {0, 94, 189}, _ {126, 157, 189}, _ {0, 64, 129}, _ {86, 107, 129}, _ {0, 52, 104}, _ {69, 86, 104}, _ {0, 39, 79}, _ {53, 66, 79}, _ {0, 63, 255}, _ {170, 191, 255}, _ {0, 46, 189}, _ {126, 141, 189}, _ {0, 31, 129}, _ {86, 96, 129}, _ {0, 25, 104}, _ {69, 78, 104}, _ {0, 19, 79}, _ {53, 59, 79}, _ {0, 0, 255}, _ {170, 170, 255}, _ {0, 0, 189}, _ {126, 126, 189}, _ {0, 0, 129}, _ {86, 86, 129}, _ {0, 0, 104}, _ {69, 69, 104}, _ {0, 0, 79}, _ {53, 53, 79}, _ {63, 0, 255}, _ {191, 170, 255}, _ {46, 0, 189}, _ {141, 126, 189}, _ {31, 0, 129}, _ {96, 86, 129}, _ {25, 0, 104}, _ {78, 69, 104}, _ {19, 0, 79}, _

{78, 69, 104}, _ {19, 0, 79}, _ {59, 53, 79}, _ {127, 0, 255}, _ {212, 170, 255}, _ {94, 0, 189}, _ {157, 126, 189}, _ {64, 0, 129}, _ {107, 86, 129}, _ {52, 0, 104}, _ {86, 69, 104}, _ {39, 0, 79}, _ {66, 53, 79}, _ {191, 0, 255}, _ {234, 170, 255}, _ {141, 0, 189}, _ {173, 126, 189}, _ {96, 0, 129}, _ {118, 86, 129}, _ {78, 0, 104}, _ {95, 69, 104}, _ {59, 0, 79}, _ {73, 53, 79}, _ {255, 0, 255}, _ {255, 170, 255}, _ {189, 0, 189}, _ {189, 126, 189}, _ {129, 0, 129}, _ {129, 86, 129}, _ {104, 0, 104}, _ {104, 69, 104}, _ {79, 0, 79}, _ {79, 53, 79}, _ {255, 0, 191}, _ {255, 170, 234}, _ {189, 0, 141}, _ {189, 126, 173}, _ {129, 0, 96}, _ {129, 86, 118}, _ {104, 0, 78}, _ {104, 69, 95}, _ {79, 0, 59}, _ {79, 53, 73}, _ {255, 0, 127}, _ {255, 170, 212}, _ {189, 0, 94}, _ {189, 126, 157}, _ {129, 0, 64}, _ {129, 86, 107}, _ {104, 0, 52}, _ {104, 69, 86}, _ {79, 0, 39}, _ {79, 53, 66}, _ {255, 0, 63}, _ {255, 170, 191}, _ {189, 0, 46}, _ {189, 126, 141}, _ {129, 0, 31}, _ {129, 86, 96}, _ {104, 0, 25}, _ {104, 69, 78}, _ {79, 0, 19}, _ {79, 53, 59}, _ {51, 51, 51}, _ {80, 80, 80}, _ {105, 105, 105}, _ {130, 130, 130}, _ {190, 190, 190}, _ {255, 255, 255}} 'Vector con los colores en DXF

Page 10: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 10 Universidad de Salamanca

Queda un listado muy largo. Son los componentes RGB de los colores con número que

se usan en DXF. LA función devolverá el más aproximado al número de color en DXF.

En DXF le indicamos el color con el código 62 y en la línea siguiente el número. En las

versiones nuevas nos reconoce el color en color verdadero. Se indicaría con el código

420 y a continuación el valor del color. Hemos preferido mantener el color por el

sistema tradicional para hacerlo más compatible con distintas aplicaciones CAD.

En concreto se pondría 420 como código fr color verdadero y en la línea siguiente el

número decimal correspondiente al valor hexadecimal de RRGGBB. Por ejemplo para

un valor de Rojo=200, Verde=100 y Azul=50 quedaría C86432 que en decimal es

13132850.

Por último al botón, Comenzar conversión le asociamos:

'Función que recibe los colores en RGB y devuelve e l equivalente en DXF considerando el más cercano Function ACI_Cercano_RGB( ByVal r As Integer , ByVal g As Integer , ByVal b As Integer ) As Integer Dim i As Integer Dim Varianza, menorVarianza As Single menorVarianza = 3 For i = 0 To 255 Varianza = Math.Abs(ACI_RGBValues(i, 0) - r) / 255 _ + Math.Abs(ACI_RGBValues(i, 1) - g) / 255 _ + Math.Abs(ACI_RGBValues(i, 2) - b) / 2 55 If Varianza < menorVarianza Then menorVarianza = Varianza ACI_Cercano_RGB = i End If Next End Function End Module

Private Sub Button1_Click_1( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Me.Cursor = Cursors.WaitCursor 'Para que aparezca el Reloj de Arena si tarda If txt_Original.Text.Length > 0 And txt_Destino.Text.Length > 0 Then Dim leer As New StreamReader( New FileStream(txt_Original.Text, FileMode.Open)) 'Creamos la variable de tipo StreamReader que nos permitirá manejar el fichero 'la variable se crea a partir otra de tipo FileStre am asociada al archivo seleccionado y 'Abiendo el archivo Dim linea As String Dim punto(5) As String 'Vector de seis cadenas para guardar la X,Y,Z de cada punto y los colores RGB Dim escribir As New StreamWriter( New FileStream(txt_Destino.Text, FileMode.OpenOrCreate) ) 'Usamos la variable de tipo StreamWriter para asoci arsela al fichero que nos han indicado. 'Le ponemos que nos abra o nos cree el archivo si n o existiese escribir.WriteLine( "0" ) 'Escribimos las lineas de comienzo del DXF en el fichero de salida. escribir.WriteLine( "SECTION" ) escribir.WriteLine( "2" ) escribir.WriteLine( "ENTITIES" )

Page 11: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 11 Universidad de Salamanca

Do linea = leer.ReadLine 'Leemos una linea del fichero de puntos XYZ If Not linea Is Nothing Then 'Si la linea no está vacia punto = Split(linea, vbTab, 6) 'Separamos con la función Split la linea por la posición del separ ador "tabulador" 'Limitamos el número de trozos a 6 para no desbordar el vector If punto.Length = 6 Then 'Si hay tres coordenadas y 3 colores escribimos en el DXF el col or escribir.WriteLine( "0" ) 'Que sigue el indicador de entidad escribir.WriteLine( "POINT" ) 'Escribimos cada punto escribir.WriteLine( "8" ) 'Para decirle que lo siguiente es una capa escribir.WriteLine( "Puntos" ) 'Nombre de la capa en la que va el punto. LA crea aunque no la ha yamos definido previamente escribir.WriteLine( "62" ) 'Código para decirle que lo siguiente es el color escribir.WriteLine( CStr (ACI_Cercano_RGB( CInt (punto(3)), CInt (punto(4)), CInt (punto(5))))) 'Número de color escribir.WriteLine( "10" ) 'Código para indicar que lo que sigue es la X escribir.WriteLine(punto(0) ) 'Coordenada X del punto escribir.WriteLine( "20" ) 'Código para indicar que sigue la coordenada Y escribir.WriteLine(punto(1) ) 'Valor de la coordenada Y escribir.WriteLine(30) 'Código que indica que sigue la Z escribir.WriteLine(punto(2) ) 'Valor de la coordenada Z ElseIf punto.Length = 3 Then 'Si hay tres coordenadas escribimos el punto, si no descartamos el dato escribir.WriteLine( "0" ) 'Que sigue el indicador de entidad escribir.WriteLine( "POINT" ) 'Escribimos cada punto escribir.WriteLine( "8" ) 'Para decirle que lo siguiente es una capa escribir.WriteLine( "Puntos" ) 'Nombre de la capa en la que va el punto. LA crea aunque no la ha yamos definido previamente escribir.WriteLine( "62" ) 'Código para decirle que lo siguiente es el color. Si no se indi ca sería por capa escribir.WriteLine( "4" ) 'Número del color en Autocad. El 4 es Cián escribir.WriteLine( "10" ) 'Código para indicar que lo que sigue es la X escribir.WriteLine(punto(0) ) 'Coordenada X del punto escribir.WriteLine( "20" ) 'Código para

Page 12: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 12 Universidad de Salamanca

Resaltar que la operación puede durar un tiempo si los archivos de puntos son muy

grandes. Para que el usuario note que se están realizando cálculos, hemos colocado la

instrucción:

Me.Cursor = Cursors.WaitCursor

Al comienzo del código para que salga el puntero del ratón transformado en el reloj de

arena al comenzar la conversión. Y hemos puesto:

Me.Cursor = Cursors.Default

Al final del código para que vuelva a dejar el puntero normal.

No hay que olvidar incorporar la línea:

Imports System.IO

Al comienzo del código para que se carguen las bibliotecas de entrada y salida

necesarias para el manejo de ficheros.

Probamos a convertir alguno de los archivos que se proporcionan como ejemplo, y

probamos a visualizar su contenido con un editor de texto, o a importarlos a un

programa CAD.

escribir.WriteLine( "20" ) 'Código para indicar que sigue la coordenada Y escribir.WriteLine(punto(1) ) 'Valor de la coordenada Y escribir.WriteLine(30) 'Código que indica que sigue la Z escribir.WriteLine(punto(2) ) 'Valor de la coordenada Z End If End If Loop Until linea Is Nothing 'Repetimos hasta que linea sea vacia que se habrá terminado el fichero leer.Close() 'Cerramos el fichero original leer = Nothing escribir.WriteLine( "0" ) 'Escribimos la parte final del fichero DXF escribir.WriteLine( "ENDSEC") 'Fin de sección de entidades escribir.WriteLine( "0" ) escribir.WriteLine( "EOF" ) 'Fin del fichero escribir.Close() 'Cerramos el fichero de destino escribir = Nothing MessageBox.Show( "Conversión Finalizada" , "Conversión a DXF") Else MessageBox.Show( "Debe seleccionar el fichero de origen y el de destino" , "Conversión a DXF" ) End If Me.Cursor = Cursors.Default 'Para volver al puntero del ratón normal End Sub

Page 13: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 13 Universidad de Salamanca

3 Triangular puntos.

Se hace necesario triangular nubes de puntos para generar mallas que ayuden a la

representación del Modelo Digital del Terreno. De los distintos tipos de mallas la más

usada es la Triangulación de Delaunay. Utilizaremos en este ejercicio una librería ya

creada para ilustrar el funcionamiento de la Triangulación de Delaunay y los diagramas

de Voronoi. Después intentaremos crear nosotros una Biblioteca de Clases que se

encargue de realizar el proceso para los puntos reales.

3.1 Triangulación de Delaunay. En la triangulación de Delaunay los triángulos formados son lo mas regulares posibles,

la longitud de los lados de los triángulos es mínima, y la triangulación formada es única,

dando lugar a la red irregular de triángulos que aparentemente ofrece una imagen mas

fiel del terreno real, y que permite una interpolación coherente entre los valores de

altitud de cada uno de los puntos o vértices.

La triangulación de Delaunay tiene la propiedad de que la circunferencia circunscrita a

cada triángulo no contiene a ningún otro punto de la triangulación. Otra propiedad es

que dos puntos pi y pj pertenecientes a P forman un lado de la Triangulación de

Delaunay de P, si y solamente si, existe un círculo que contiene a pi y pj en su

circunferencia y no contiene en su interior ningún punto de P.

Se podría definir la triangulación de Delaunay como: Sea P un conjunto de puntos en el

plano y T una triangulación de P, T es una triangulación de Delaunay de P, si y

solamente si, la circunferencia circunscrita de cualquier triángulo de T no contiene

puntos de P.

3.2 Creación de la aplicación que ilustra el proceso. Creamos una aplicación nueva con nombre ver_triangulación. Al formulario le

ponemos el nombre frm_triangulacion.vb. Colocamos un GroupBox, dos botones y un

PictureBox para la zona inferior. Cambiamos el color al Picture poniéndole color blanco

en la propiedad BackColor. El aspecto del Formulario será:

Page 14: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 14 Universidad de Salamanca

Vamos a utilizar la Librería que se proporciona como recurso. Para importarla damos al

menú “Proyecto/Agregar Referencias” y en la solapa examinar seleccionamos el

fichero FortuneVoronoi.dll.

Ahora añadiremos los espacios de nombres que vamos a necesitar en concreto ponemos:

Los dos primeros se corresponden con la dll proporcionada, el último es para acceder a

las utilidades de dibujo.

Queremos que al redimensionar el formulario se ajuste el tamaño del PictureBox1 sobre

el que vamos a dibujar los puntos y las líneas. Asociamos lo siguiente a la propiedad

Resize del formulario.

Al botón Triangulación de Delaunay le asociamos el código:

Imports Voronoi.Data Imports Voronoi.Mathematics Imports System.Drawing

Private Sub frm_triangulacion_Resize( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Resize PictureBox1.Width = Me.Width - 12 'Igualamos el ancho del Picture al ancho del formulario PictureBox1.Height = Me.Height - 80 'Igualamos el alto End Sub

Page 15: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 15 Universidad de Salamanca

Y al botón Diagrama de Voronoi le ponemos:

Private Sub Button1_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim puntos As New HashSet 'Creamos una variable con la coleccion de puntosDim puntos As New HashSet 'Cream os una variable con la coleccion de puntos Dim r As Random = New Random() puntos.Clear() 'borramos los puntos Dim i As Integer For i = 0 To 200 'Creamos 201 puntos aleatorios y los añadimos a la coleccion puntos.Add( New Vector(10.0 + r.NextDouble() * ( Me.PictureBox1.Width - 40), 10.0 + r.NextDouble() * ( Me.PictureBox1.Height - 30))) Next Dim imagen As New Bitmap( Me.PictureBox1.Width, Me.PictureBox1.Height) 'Llamamos a la funcion que nos proporciona la bibli oteca que nos devuelve un Bitmap Dim g As Graphics = Graphics.FromImage(imagen) Dim graph As VoronoiGraph = Fortune.ComputeVoronoiGraph(puntos) For Each v As Vector In puntos 'Dibujamos los puntos. Como GDI+ no permite puntos hacemos un pequeño circulo g.DrawEllipse(Pens.Red, CInt (v(0)) - 1, CInt (v(1)) - 1, 2, 2) g.DrawEllipse(Pens.Black, CInt (v(0)) - 2, CInt (v(1)) - 2, 4, 4) For Each borde As VoronoiEdge In graph.Edges If ((borde.LeftData(0) = v(0)) And (borde.LeftData(1) = v(1))) Then 'Dibujamos las lineas. g.DrawLine(Pens.Blue, CInt (borde.LeftData(0)), CInt (borde.LeftData(1)), CInt (borde.RightData(0)), CInt (borde.RightData(1))) End If Next Next Me.PictureBox1.Image = imagen End Sub

Private Sub Button2_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim puntos As New HashSet 'Creamos una variable con la coleccion de puntos Dim r As Random = New Random() puntos.Clear() 'borramos los puntos Dim i As Integer For i = 0 To 200 'Creamos 201 puntos aleatorios y los añadimos a la coleccion puntos.Add( New Vector(10.0 + r.NextDouble() * ( Me.PictureBox1.Width - 40), 10.0 + r.NextDouble() * ( Me.PictureBox1.Height - 30))) Next Dim imagen As New Bitmap( Me.PictureBox1.Width, Me.PictureBox1.Height) 'Llamamos a la funcion que nos proporciona la bibli oteca que nos devuelve un Bitmap

Page 16: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 16 Universidad de Salamanca

Al ejecutar el programa si pulsamos en el primer botón nos creará algo así

Dim g As Graphics = Graphics.FromImage(imagen) Dim graph As VoronoiGraph = Fortune.ComputeVoronoiGraph(puntos) For Each v As Vector In graph.Vertizes 'Dibujamos los puntos. Como GDI+ no permite puntos hacemos un pequeño circulo negro y abajo otro rojo g.DrawEllipse(Pens.Black, CInt (v(0)) - 2, CInt (v(1)) - 2, 4, 4) g.DrawEllipse(Pens.Red, CInt (v(0)) - 1, CInt (v(1)) - 1, 2, 2) Next For Each borde As VoronoiEdge In graph.Edges Try 'Dibujamos las lineas. g.DrawLine(Pens.Brown, CInt (borde.VVertexA(0)), CInt (borde.VVertexA(1)), CInt (borde.VVertexB(0)), CInt (borde.VVertexB(1))) Catch End Try Next Me.PictureBox1.Image = imagen End Sub

Page 17: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 17 Universidad de Salamanca

Y en el segundo pondrá:

Guardamos el proyecto.

Page 18: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 18 Universidad de Salamanca

4 Creación de Biblioteca para manejar puntos.

En la mayoría de los ejercicios anteriores no cargamos los puntos en memoria. Los

leemos y los dibujamos, o los leemos y los escribimos en otro archivo, en el caso de la

conversión a DXF. Cuando necesitamos trabajar con esos datos, sería conveniente

crearse una estructura que los use. Vamos a crear una clase para manejar los puntos,

será una versión ampliada de la de Punto3D de la introducción. Tendremos también otra

para líneas. Así como una colección para guardar un conjunto de puntos y otra para un

conjunto de líneas.

Llamaremos a la biblioteca de clases LidarBase. Comenzamos creando la clase

PuntoLidar.vb en Proyecto/Agregar elemento y elegimos clase.

En esta biblioteca vamos a necesitar la referencia a System.Windows.Forms. Lo

añadimos desde Proyecto/Agregar referencia.

Ahora crearemos una clase con nombre PuntoLidar.vb. En ella declaramos un punto

con las coordenadas XYZ y los colores. También los constructores necesarios y una

función para calcular la distancia.

El código de la clase punto queda:

Public Class PuntoLidar Public x, y, z As Double 'Variables de la clase Punto son públicas, permitirán acceder a ellas. 'Se podrían haber creado como propiedades Public rojo, verde, azul As Byte 'Para los colores Public colorDXF As Boolean 'Para indicar si es color DXF o RGB True indica DXF y en el rojo metemos el color Sub New() 'Constructor por Defecto. Inicializa las Variables y muestra un mensaje cuando es invocado x = 0 y = 0 z = 0 rojo = 7 'Aprovechamos el rojo para asignar el color en el caso de que usemos color DXF

Page 19: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 19 Universidad de Salamanca

Tendremos otra clase LineaLidar.vb para almacenar una línea con una variable de tipo

PuntoLidar para el punto inicial y otra del mismo tipo para el final. El código queda:

verde = 0 azul = 0 colorDXF = True End Sub Sub New( ByVal coord_x As Double , ByVal coord_y As Double , ByVal coord_z As Double ) 'Constructor de parámetros x = coord_x y = coord_y z = coord_z End Sub Sub New( ByVal p2 As PuntoLidar) 'Constructor de copia x = p2.x y = p2.y z = p2.z colorDXF = p2.colorDXF rojo = p2.rojo verde = p2.verde azul = p2.azul End Sub Function distanciaA( ByVal p2 As PuntoLidar) As Double 'Función distancia. Calcula la distancia al 'punto que nos pasan como argumento Dim distanciax, distanciay, distanciaz As Double distanciax = p2.x - x distanciay = p2.y - y distanciaz = p2.z - z distanciaA = Math.Sqrt(distanciax * distanc iax + distanciay * distanciay + distanciaz * distanciaz) 'Calculamos la distancia y se la asignamos al nombr e de la función. Así devolvemos el valor End Function End Class

Public Class LineaLidar Public inicio, final As PuntoLidar Sub New() 'Constructor por Defecto. Inicializa las Variables y muestra un mensaje cuando es invocado inicio = New PuntoLidar final = New PuntoLidar End Sub Sub New( ByVal ini As PuntoLidar, ByVal fin As PuntoLidar) 'Constructor de parámetros inicio = New PuntoLidar(ini) final = New PuntoLidar(fin) End Sub Sub New( ByVal l2 As LineaLidar) 'Constructor de copia inicio = New PuntoLidar(l2.inicio) final = New PuntoLidar(l2.final) End Sub End Class

Page 20: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 20 Universidad de Salamanca

Ahora creamos dos clases como colecciones de datos. Serán listas para almacenar los

puntos por un lado y las líneas por el otro.

La clase ListaPuntos.vb quedará:

Public Class ListaPuntos Inherits System.Collections.CollectionBase 'Lista que hereda de CollectionBase Public Sub Add( ByRef punto As PuntoLidar) List.Add(punto) End Sub Public Sub Remove( ByVal indice As Integer ) 'Redefinimos Remove para controlar el rango If indice > Count - 1 Or indice < 0 Then System.Windows.Forms.MessageBox.Show( "Punto fuera de rango!" ) Else List.RemoveAt(indice) End If End Sub Public ReadOnly Property Item( ByVal indice As Integer ) As PuntoLidar 'Redefinimos item para que maneje PuntoLidar y no O bject Get If indice > Count - 1 Or indice < 0 Then System.Windows.Forms.MessageBox.Sho w( "Punto fuera de rango!" ) Return Nothing Else Return CType(List.Item(indice), PuntoLidar) End If End Get End Property Public Function MaximoX() As Double 'Creamos funciones para el máximo y mínimo de X,Y,Z Dim i As Integer If Count > 0 Then MaximoX = CType(List.Item(0), PuntoLidar).x For i = 0 To Count - 1 If MaximoX < CType(List.Item(i), PuntoLidar).x Then MaximoX = CType(List.Item(i), PuntoLidar).x End If Next Else MaximoX = 0 End If End Function Public Function MinimoX() As Double If count > 0 Then Dim i As Integer MinimoX = CType(List.Item(0), PuntoLidar).x For i = 0 To Count - 1 If MinimoX > CType(List.Item(i), PuntoLidar).x Then MinimoX = CType(List.Item(i), PuntoLidar).x End If Next Else minimoX = 0 End If End Function

Page 21: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 21 Universidad de Salamanca

Public Function MaximoY() As Double If count > 0 Then Dim i As Integer MaximoY = CType(List.Item(0), PuntoLidar).y For i = 0 To Count - 1 If MaximoY < CType(List.Item(i), PuntoLidar).y Then MaximoY = CType(List.Item(i), PuntoLidar).y End If Next Else maximoy = 0 End If End Function Public Function MinimoY() As Double If count > 0 Then Dim i As Integer MinimoY = CType(List.Item(0), PuntoLidar).y For i = 0 To Count - 1 If MinimoY > CType(List.Item(i), PuntoLidar).y Then MinimoY = CType(List.Item(i), PuntoLidar).y End If Next Else minimoy = 0 End If End Function Public Function MaximoZ() As Double If count > 0 Then Dim i As Integer MaximoZ = CType(List.Item(0), PuntoLidar).z For i = 0 To Count - 1 If MaximoZ < CType(List.Item(i), PuntoLidar).z Then MaximoZ = CType(List.Item(i), PuntoLidar).z End If Next Else maximoz = 0 End If End Function Public Function MinimoZ() As Double If count > 0 Then Dim i As Integer Minimoz = CType(List.Item(0), PuntoLidar).z For i = 0 To Count - 1 If Minimoz > CType(List.Item(i), PuntoLidar).z Then Minimoz = CType(List.Item(i), PuntoLidar).z End If Next Else minimoz = 0 End If End Function End Class

Page 22: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 22 Universidad de Salamanca

La clase ListaLineas.vb queda:

Guardamos el proyecto y Generamos la Biblioteca en Generar/Generar LidarBase.

Recordamos que en la ruta \Visual Studio 2005\Projects\LidarBase\LidarBase\bin\

Release si guardamos el proyecto en la ruta por defecto nos habrá dejado el archivo

LidarBase.dll.

5 Creación de la Biblioteca para Generar DXF.

Creamos ahora una Biblioteca de Clases que nos permita automatizar la forma de

exportar a DXF que utilizamos en uno de los ejercicios anteriores, para incorporar esta

utilidad en futuras aplicaciones. Damos el nombre Biblio_A_DXF a la Biblioteca

creada.

En esta biblioteca vamos a necesitar la referencia a System.Windows.Forms. Lo

añadimos desde Proyecto/Agregar referencia.

Public Class ListaLineas Inherits System.Collections.CollectionBase Public Sub Add( ByRef linea As LineaLidar) List.Add(linea) End Sub Public Sub Remove( ByVal indice As Integer ) If indice > Count - 1 Or indice < 0 Then System.Windows.Forms.MessageBox.Show( "¡Linea fuera de rango!" ) Else List.RemoveAt(indice) End If End Sub Public ReadOnly Property Item( ByVal indice As Integer ) As LineaLidar Get Return CType(List.Item(indice), LineaLidar) End Get End Property End Class

Page 23: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 23 Universidad de Salamanca

También la Biblioteca LidarBase.dll creada en el ejercicio anterior.

En esta biblioteca tendremos una clase con nombre ListaFichero que contendrá la lista

de las líneas que se escribirán en el DXF.

Imports System.IO Imports LidarBase Public Class ListaFichero Inherits System.Collections.CollectionBase Public Sub Add( ByRef renglon As String ) List.Add(renglon) End Sub Public Sub Remove( ByVal indice As Integer ) If indice > Count - 1 Or indice < 0 Then System.Windows.Forms.MessageBox.Show( "¡renglon fuera de rango!" ) Else List.RemoveAt(indice) End If End Sub Public ReadOnly Property Item( ByVal indice As Integer ) As String Get Return CType(List.Item(indice), String ) End Get End Property Public Sub escribir_DXF( ByVal nombre_fich As String ) Dim escribir As New StreamWriter( New FileStream(nombre_fich, FileMode.OpenOrCreate)) 'Usamos la variable de tipo StreamWriter para asoci arsela al fichero que nos han indicado. 'Le ponemos que nos abra o nos cree el archivo si n o existiese Dim i As Integer For i = 0 To List.Count - 1 'Recorremos los renglones y los escribimos en el fichero escribir.WriteLine(List.Item(i).ToStrin g) Next escribir.Close() 'cerramos el archivo End Sub

Page 24: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 24 Universidad de Salamanca

Public Sub agregar_comienzo() List.Add( "0" ) 'Escribimos las lineas de comienzo del DXF en la lista de renglones. List.Add( "SECTION" ) List.Add( "2" ) List.Add( "ENTITIES" ) End Sub Public Sub agregar_fin() List.Add( "0" ) 'Escribimos la parte final del fichero DXF List.Add( "ENDSEC") 'Fin de sección de entidades List.Add( "0" ) List.Add( "EOF" ) 'Fin del fichero End Sub Public Sub agregar_Lista_Puntos( ByVal listapun As ListaPuntos, ByVal capa As String ) Dim i As Integer For i = 0 To listapun.Count - 1 List.Add( "0" ) 'Que sigue el indicador de entidad List.Add( "POINT" ) 'Escribimos cada punto List.Add( "8" ) 'Para decirle que lo siguiente es una capa List.Add(capa) 'Nombre de la capa en la que va el punto. LA crea aunque no la hayamos definido previamente List.Add( "62" ) 'Código para decirle que lo siguiente es el color List.Add( CStr (ACI_Cercano_RGB(listapun.Item(i).rojo, listapun.Item(i).verde, listapun.Item(i).azul))) 'Número de color List.Add( "10" ) 'Código para indicar que lo que sigue es la X List.Add(listapun.Item(i).x) 'Coordenada X del punto List.Add( "20" ) 'Código para indicar que sigue la coordenada Y List.Add(listapun.Item(i).y) 'Valor de la coordenada Y List.Add( "30" ) 'Código que indica que sigue la Z List.Add(listapun.Item(i).z) 'Valor de la coordenada Z Next End Sub Public Sub agregar_Lista_Lineas( ByVal listalin As ListaLineas, ByVal capa As String , ByVal color As Byte ) Dim i As Integer For i = 0 To listalin.Count - 1 List.Add( "0" ) 'Que sigue el indicador de entidad List.Add( "LINE" ) 'Escribimos cada Linea List.Add( "8" ) 'Para decirle que lo siguiente es una capa List.Add(capa) 'Nombre de la capa en la que va la linea List.Add( "62" ) 'Código para decirle que lo siguiente es el color List.Add( "" & color) 'Número de color List.Add( "10" ) 'Código para indicar que lo que sigue es la X del inicio de la linea List.Add(listalin.Item(i).inicio.x) 'Coordenada X List.Add( "20" ) 'Código para indicar que sigue la coordenada Y List.Add(listalin.Item(i).inicio.y) 'Valor de la coordenada Y List.Add( "30" ) 'Código que indica que sigue la Z List.Add(listalin.Item(i).inicio.z) 'Valor de la coordenada Z

Page 25: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 25 Universidad de Salamanca

Además creamos un módulo con nombre Funciones.vb en el que situamos la

información de los colores DXF y además la función de conversión. Esté módulo queda

igual que el del ejercicio de prueba de conversión.

Guardamos el proyecto y Generamos la Biblioteca en Generar/Generar Biblio_A_DXF.

En la ruta \bin\Release dentro de la carpeta del proyecto nos habrá dejado el archivo

Biblio_A_DXF.dll.

6 Procesar puntos.

Vamos a crear un proyecto nuevo con nombre ProcesarPuntos. En el colocamos un

formulario al que llamaremos frm_Procesar.vb. En el colocaremos una tabla

DataViewGrid, un panel sobre el que colocamos las etiquetas y cuadros de texto que se

observan, el menú, un OpenFileDialog y un SaveFileDialog. Presentará el siguiente

aspecto:

List.Add( "11" ) 'Código para indicar que lo que sigue es la X del final de la linea List.Add(listalin.Item(i).final.x) 'Coordenada X del final List.Add( "21" ) 'Código para indicar que sigue la coordenada Y List.Add(listalin.Item(i).final.y) 'Valor de la coordenada Y List.Add( "31" ) 'Código que indica que sigue la Z List.Add(listalin.Item(i).final.z) 'Valor de la coordenada Z Next End Sub End Class

Page 26: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 26 Universidad de Salamanca

En la tabla hemos añadido las columnas con lo nombres que vemos, dando al botón

derecho sobre ella y luego Editar/Columnas, pulsamos Agregar y aparece:

Recordamos que el nombre no puede contener espacios pero el texto del encabezado

que es lo que se mostrará sí puede tenerlos.

Para los Cuadros de Texto de la derecha se ha añadido un GroupBox, y sobre él se han

ido colocando. El primero se llama txt_total, el siguiente txt_xMax, y los demás

siguiendo el nombre de este último cambiando x por y o z y Max por Min según el caso.

En este proyecto utilizaremos las bibliotecas de los ejercicios anteriores

Biblio_A_DXF.dll y LidarBase.dll. Las cargamos desde Proyecto/Agregar Referencia.

Page 27: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 27 Universidad de Salamanca

La parte inicial de la clase queda:

Como vemos hemos importado las bibliotecas anteriores y la de entrada y salida para

leer y escribir en ficheros. En el formulario Creamos una instancia de la clase

ListaPuntos definida en la biblioteca LidarBase que es la que usaremos para almacenar

los puntos leídos.

A la hora de manejar algunos datos Visual usa el formato numérico por defecto de

Windows. Si nuestros puntos tienen el separador decimal “.” podría no convertirlos

bien. Para solucionarlo le asociamos al evento cargar el formulario(Load) el código

indicado que cambia la configuración de idioma de la aplicación actual al Ingles US

para que coja como separador decimal el “.”

En el menú Archivo/Abrir colocamos el código:

Imports System.IO Imports LidarBase Imports Biblio_A_DXF Public Class frm_Procesar Dim Listado As New ListaPuntos Private Sub Form1_Load( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Application.CurrentCulture = New System.Globalization.CultureInfo( "en-US" ) End Sub

Private Sub AbrirToolStripMenuItem_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AbrirToolStripMenuItem.Click OpenFileDialog1.Filter = "Archivos XYZ(*.xyz)|*.xyz|Archivos Ascii(*.asc)|*.asc|Archivos de Texto(*.txt)|*.txt|T odos los Archivos|*.*" 'Le indicamos los filtros que aparecerán al selecci onar los archivos. asc, txt, o todos. If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then 'Mostramos diálogo de Abrir Me.Cursor = Cursors.WaitCursor 'Para que aparezca el Reloj de Arena si tarda Me.Text = "PROCESANDO ARHIVO" & OpenFileDialog1.FileName 'Colocamos en el titulo del formulario la ruta y no mbre del fichero seleccionado Dim leer As New StreamReader( New FileStream(OpenFileDialog1.FileName, FileMode.Open) ) 'Creamos la variable de tipo StreamReader que nos permitirá manejar el fichero 'la variable se crea a partir otra de tipo FileStre am asociada al archivo seleccionado y 'Abiendo el archivo Dim linea As String Dim unpuntoLidar As PuntoLidar 'Borramos el cuadro que visionará las lineas leídas dgv_tabla.Rows.Clear() 'Borramos la tabla que muestra las coordenadas de l os puntos Dim punto(5) As String 'Vector de tres cadenas para guardar la X,Y,Z de cada punto

Page 28: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 28 Universidad de Salamanca

Do linea = leer.ReadLine 'Leemos una linea del fichero If Not linea Is Nothing Then 'Si la linea no está vacia punto = Split(linea, vbTab, 6) 'Separamos con la función Split la linea por la posición del separado r "tabulador" 'Limitamos el número de trozos a 6 para no desbordar el vector If punto.Length = 6 Then 'Si hay tres coordenadas y 3 colores escribimos en el DXF el col or unpuntoLidar = New PuntoLidar( CDbl (punto(0)), CDbl (punto(1)), CDbl (punto(2))) 'Creamos un punto del tipo definido en la biblioteca de clase unpuntoLidar.rojo = CByte (punto(3)) unpuntoLidar.verde = CByte (punto(4)) unpuntoLidar.azul = CByte (punto(5)) unpuntoLidar.colorDXF = False Listado.Add(unpuntoLidar) dgv_tabla.Rows.Add(punto(0) , punto(1), punto(2), punto(3), punto(4), punto(5)) 'Añado las coordenadas del punto a la tabla ElseIf punto.Length = 3 Then unpuntoLidar = New PuntoLidar( CDbl (punto(0)), CDbl (punto(1)), CDbl (punto(2))) 'Creamos un punto del tipo definido en la biblioteca de clase unpuntoLidar.rojo = 7 'Color Blanco en DXF unpuntoLidar.verde = 0 unpuntoLidar.azul = 0 unpuntoLidar.colorDXF = True Listado.Add(unpuntoLidar) dgv_tabla.Rows.Add(punto(0) , punto(1), punto(2), 7) 'Añado las coordenadas del punto a la tabla End If End If Loop Until linea Is Nothing 'Repetimos hasta que linea sea vacia que se habrá terminado el fichero leer.Close() 'Cerramos el fichero leer = Nothing txt_total.Text = Listado.Count 'Pongo en txt_leidos el numero de puntos añadidos a la tabla. txt_xmax.Text = Listado.MaximoX txt_Ymax.Text = Listado.MaximoY txt_Zmax.Text = Listado.MaximoZ txt_Xmin.Text = Listado.MinimoX txt_Ymin.Text = Listado.MinimoY txt_Zmin.Text = Listado.MinimoZ Me.Cursor = Cursors.Default 'Para volver al puntero del ratón normal End If End Sub

Page 29: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 29 Universidad de Salamanca

Además de la Opción Abrir en el menú añadimos:

En la opción Guardar en XYZ guardaremos en formato de texto delimitado por

tabulaciones como en algún otro ejercicio. El código quedará:

Para la opción guardar en DXF utilizamos la biblioteca creada. Nos quedará:

Private Sub GuardarEnXYZToolStripMenuItem_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GuardarEnXYZToolStripMenuItem.Click SaveFileDialog1.Filter = "Archivos de Texto delimitado por tabulaciones(*.txt)|*.txt" 'Establecemos el formato de archivo de salida a *.t xt If SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then 'Abrimos el diálogo de guardar Dim linea As String Dim i As Integer Dim escribir As New StreamWriter( New FileStream(SaveFileDialog1.FileName, FileMode.OpenO rCreate)) 'Usamos la variable de tipo StreamWriter para asociarsela al fichero que nos han indicado. 'Le ponemos que nos abra o nos cree el archivo si n o existiese 'Ponemos en el cuadro la ruta de guardar el nombre y ruta del archivo. For i = 0 To Listado.Count - 1 'Recorremos las filas del listado de puntos linea = Listado.Item(i).x.ToString & vbTab & Listado.Item(i).x.ToString & vbTab & Listado.Item(i ).x.ToString 'Generamos una linea con las coordenadas de los puntos, el tabulador(vbTab) entre ellas y un salto de linea al final escribir.WriteLine(linea) 'Escribimos la linea generada en el fichero. Next escribir.Close() 'Cerramos el fichero escribir = Nothing End If End Sub

Private Sub GuardarComoDXFToolStripMenuItem_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GuardarComoDXFToolStripMenuItem.Click SaveFileDialog1.Filter = "Archivo DXF(*.dxf)|*.dxf" 'Establecemos el formato de archivo de salida a *.d xf If SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then 'Abrimos el diálogo de guardar Dim listafich As New ListaFichero listafich.agregar_comienzo() 'ESCRIBIMOS LA PARTE INICIAL

Page 30: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 30 Universidad de Salamanca

Probamos a ejecutar el Programa y vemos su uso con el archivo Andarax_Micro.xyz

proporcionado.

Ahora probamos a analizar los puntos en el menú incluimos:

En la opción reducir por distancia mínima incluimos:

listafich.agregar_Lista_Puntos(Listado, "Puntos" ) 'LLAMAMOS A LA FUNCIÓN QUE ESCRIBE LOS PUNTOS 'EL CODIGO SIGUIETE SERÍA UN EJEMPLO DE LA LLAMADA DXF PARA LINEAS 'CREAMOS UNA LINEA DEL PRIMER PUNTO AL ÚLTIMO Y SE LA AÑADIMOS A LA LISTA 'LUEGO AGREGAMOS LA LISTA DE LINEAS AL LISTADO DE INSTRUCCIONES PARA EL DXF 'Dim listali As New ListaLineas 'listali.Add(New LineaLidar(Listado.Item(0), Listado.Item(Listado.Count - 1))) 'listafich.agregar_Lista_Lineas(listali, "LINEAS", 5) listafich.agregar_fin() 'AGREGAMOS LA PARTE FINAL listafich.escribir_DXF(SaveFileDialog1. FileName) 'ESCRIBIMOS REALMENTE EN EL ARCHIVO End If End Sub

Private Sub mnu_Filtrardistancia_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnu_Filtrardistancia.Click Dim dialogo As New Filtrado Dim i, j As Integer Dim distanciaminima As Double If dialogo.ShowDialog() = Windows.Forms.DialogResult. OK And Listado.Count > 0 Then distanciaminima = CDbl (dialogo.txt_distancia.Text) 'Recogemos el valor del formulario dialogo Me.Cursor = Cursors.WaitCursor 'Para que aparezca el Reloj de Arena si tarda i = 0 While i < Listado.Count - 1 j = i + 1 While j < Listado.Count If Listado.Item(i).distanciaA(Listado.Item(j)) < distanciaminima Then Listado.RemoveAt(j) Else

j = j + 1 End If End While i = i + 1 End While dgv_tabla.Rows.Clear() For i = 0 To Listado.Count - 1 dgv_tabla.Rows.Add(Listado.Item(i). x, Listado.Item(i).y, Listado.Item(i).z, Listado.Item( i).rojo, Listado.Item(i).verde, Listado.Item(i).azul)

Page 31: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 31 Universidad de Salamanca

Previamente habremos creado el formulario Filtrado.vb con el aspecto

En el botón Reducir puntos escribimos:

Lo suyo sería contemplar en un único formulario varios filtros. Para probar lo estamos

haciendo en varios para no complicar. Creamos otro para descartar puntos por cota con

nombre fi y el aspecto:

txt_total.Text = Listado.Count 'Pongo en txt_leidos el numero de puntos añadidos a la tabla. txt_xmax.Text = Listado.MaximoX txt_Ymax.Text = Listado.MaximoY txt_Zmax.Text = Listado.MaximoZ txt_Xmin.Text = Listado.MinimoX txt_Ymin.Text = Listado.MinimoY txt_Zmin.Text = Listado.MinimoZ Me.Cursor = Cursors.Default 'Para dejar el puntero normal End If End Sub

Private Sub Button1_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click If Me.txt_distancia.Text.Length > 0 Then If IsNumeric( Me.txt_distancia.Text) Then Me.DialogResult = Windows.Forms.DialogResult.OK Else MessageBox.Show( "Escriba una distancia válida" , "REducir puntos por distancia" ) End If Else MessageBox.Show( "Escriba una distancia válida" , "REducir puntos por distancia" ) End If End Sub

Page 32: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 32 Universidad de Salamanca

En el botón reducir escribiremos:

En el menú reducir por cota del formulario principal le asociamos

Private Sub Button1_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click If Me.txt_Zminima.Text.Length > 0 And Me.txt_Zmaxima.Text.Length > 0 Then If IsNumeric( Me.txt_Zminima.Text) And IsNumeric( Me.txt_Zmaxima.Text) Then If CDbl ( Me.txt_Zminima.Text) < CDbl ( Me.txt_Zmaxima.Text) Then Me.DialogResult = Windows.Forms.DialogResult.OK Else MessageBox.Show( "Escriba unos valores validos minima debe ser menor maximo" ) End If Else MessageBox.Show( "Escriba unos valores validos no son numeros" ) End If Else MessageBox.Show( "Escriba unos valores validos" ) End If End Sub

Private Sub mnu_filtrarcota_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnu_filtrarcota.Click Dim dialogo As New frm_filtrado_cota Dim i As Integer Dim cotaminima, cotamaxima As Double If dialogo.ShowDialog() = Windows.Forms.DialogResult. OK And Listado.Count > 0 Then cotaminima = CDbl (dialogo.txt_Zminima.Text) 'Recogemos el valor del formulario dialogo cotamaxima = CDbl (dialogo.txt_Zmaxima.Text) 'Recogemos el valor del formulario dialogo Me.Cursor = Cursors.WaitCursor 'Para que aparezca el Reloj de Arena si tarda i = 0 While i < Listado.Count If Listado.Item(i).z < cotaminima Or Listado.Item(i).z > cotamaxima Then Listado.RemoveAt(i)

Else i = i + 1

End If End While dgv_tabla.Rows.Clear() For i = 0 To Listado.Count - 1 dgv_tabla.Rows.Add(Listado.Item(i). x, Listado.Item(i).y, Listado.Item(i).z, Listado.Item( i).rojo, Listado.Item(i).verde, Listado.Item(i).azul) Next

Page 33: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 33 Universidad de Salamanca

Guardamos el proyecto y generamos el ejecutable.

txt_total.Text = Listado.Count 'Pongo en txt_leidos el numero de puntos añadidos a la tabla. txt_xmax.Text = Listado.MaximoX txt_Ymax.Text = Listado.MaximoY txt_Zmax.Text = Listado.MaximoZ txt_Xmin.Text = Listado.MinimoX txt_Ymin.Text = Listado.MinimoY txt_Zmin.Text = Listado.MinimoZ Me.Cursor = Cursors.Default 'Para que aparezca el puntero normal End If End Sub

Page 34: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 34 Universidad de Salamanca

7 Algunos componentes para CAD.

Para comenzar con la representación de puntos en la pantalla vamos a utilizar algunos

componentes. Estos que comentamos en su versión de Evaluación tienen algunas

limitaciones. Nos decantamos por estos porque así cualquiera tiene acceso a probarlos

descargándolos de la página del autor.

7.1 MTBCadViewerX. En su versión de Evaluación sólo nos permite cargar archivos en varios formatos CAD,

visualizarlos y guardarlos igualmente en varios formatos. Además presenta un mensaje

indicativo de versión de pruebas en la parte inferior de la pantalla.

La web de la empresa creadora es:

http://www.mtbsoftware.net/

Lo podemos descargar en:

http://www.mtbsoftware.net/download/MTBCadViewerX_Install.zip

Una vez descargado lo instalaremos siguiendo los pasos por defecto y nos dejará el

componente en la carpeta C:\Archivos de programa\Archivos comunes\MTBCadViewer

v.3. Allí nos dejará el componente mtbcadviewer.ocx que es el que incorporaremos al

proyecto, también un fichero de ayuda ‘Manual MTBCadViewer.pdf’ en la carpeta

C:\Archivos de programa\MTB SOFTWARE\MTBCadViewer v.3.

Para utilizar el componente en .NET, procederemos a importarlo. Vamos a crear un

proyecto nuevo con nombre MTBPrueba.

En el mismo añadimos el control, para ello iremos al

cuadro de herramientas. En la parte de abajo en la ficha

general pulsamos al botón derecho del ratón y elegimos

‘Agregar Ficha’ con esto creamos un nuevo grupo que

llamaremos ‘Controles CAD’.

Dentro de esta ficha damos de nuevo al botón derecho

del ratón y seleccionamos ‘Elegir Elementos’.

Nos muestra ahora la ventana de la página siguiente. En

ella pulsamos la pestaña Componentes COM, luego el botón de Examinar y

localizamos el componente mtbcadviewer.ocx en la ruta que elegimos durante la

instalación.

Después de seleccionarlo nos aparecerá el componente en la lista seleccionado como se

ve en la segunda ventana de la página siguiente.

Page 35: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 35 Universidad de Salamanca

Pulsamos Aceptar y en el cuadro de herramientas se habrá incorporado el componente

presentando el aspecto:

Colocamos el componente en el formulario del proyecto al que habremos dado el

nombre frm_visorMTB, al componente añadido le ponemos el nombre MTBvisor.

Hacemos doble-clic en el fondo del formulario, elegimos el evento Resize y colocamos

el código siguiente para que el visor se adapte al cambio de tamaño del formulario.

Se podría reemplazar la barra de Herramientas del componente por una propia, e ir

programando el código para cada botón y/o para cada opción del menú.

Private Sub frm_MTBvisor_Resize( ByVal sender As Object , ByVal e As System.EventArgs) Handles Me.Resize MTBvisor.Width = Me.Width - 15 'Igualamos el ancho del visor al ancho del formulario MTBvisor.Height = Me.Height - 50 'Igualamos el alto End Sub

Page 36: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 36 Universidad de Salamanca

Probamos a abrir el archivo Cuadros.dwg proporcionado, y practicamos con el zoom,

etc.

Para facilitar la distribución posterior de esta aplicación que utiliza componentes

externos nos aseguramos de activar la copia local del mismo. En el menú

Proyecto/Propiedades de MTBPrueba, seleccionamos la referencia a MTBCadViewer y

nos aseguramos que en las propiedades Aislada esté a False y Copia Local a True.

Generamos el ejecutable en Generar/GenerarPruebaMTB.

Este proyecto se podría completar con menús y barras de herramientas propias

ayudándonos de las indicaciones del componente en el archivo ‘Manual

MTBCadViewer.pdf’.

Cerramos el Proyecto.

7.2 Vector DRAW. Esta empresa proporciona varios componentes para desarrollar aplicaciones CAD con

.NET. La versión de evaluación del componente que usaremos dura 90 días. También

pone un mensaje molesto en el fondo del visor, y un diálogo indicativo de los días de

uso que llevamos. Nos hemos decidido por el por sus grandes posibilidades, porque está

accesible a todos, a pesar de las limitaciones de la versión de pruebas.

La web de la empresa creadora es:

http://www.vdraw.com/

Tenemos varios componentes disponibles, nosotros probamos a descargar VectorDraw

Developers Framework Trial en la ruta

http://www.vdraw.com/eval/vdf_eval.zip

En esta ruta el manual.

http://www.vdraw.com/vdframed.pdf

Además descargaremos e instalaremos la aplicación VectorDraw File Converter Lite

3.0 que utilizaremos para convertir los archivos creados desde alguno de los programas

que vayamos desarrollando. Aquí el enlace.

http://www.vdraw.com/converter/fc_lite.zip

Tras la instalación vamos a crear un Proyecto VDFPrueba para añadir los componentes.

Seguimos los pasos del caso anterior y en el botón derecho sobre la ficha Controles

CAD que creamos antes, en Elegir componentes, ahora en la ficha de Componentes de

.Net Framework, pulsamos Examinar. Localizamos vdFramedControl.dll

normalmente estará en la ruta C:\Archivos de programa\VectorDraw\Common\6014 o

6XXX para versiones posteriores. Al pulsar Aceptar, nos aparece el componente en la

lista, lo marcamos y pulsamos de nuevo Aceptar. Tendremos el componente en la ficha

Controles CAD.

Esta sería la ventana.

Page 37: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 37 Universidad de Salamanca

Y aquí marcamos el control.

La ficha de controles aparecería:

Page 38: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 38 Universidad de Salamanca

Como en el caso anterior, nos aseguramos de copiar el componente a la carpeta local del

programa o si deseamos quitarlo para no duplicar componentes lo haríamos en

Proyecto/Propiedades en el apartado Referencias. Probamos las opciones incorporadas.

Guardamos el proyecto.

8 Cargar y dibujar puntos de datos terrestres.

Creamos otro proyecto nuevo para dibujar los puntos con nombre “DibujarTerrestre”.

Cambiamos el nombre al formulario y le llamamos frm_visor. En el incorporamos un

menú como el siguiente:

Vamos a incorporar el componente que comentábamos

anteriormente. Le vamos a cambiar el nombre a vdf_visor. Queremos que el espacio de

dibujo que nos proporciona el control utilizado se redimensione ajustándose al tamaño

que le demos al formulario, para ellos vamos a asociar el código siguiente al evento

Resize del formulario.

Preparamos ahora el código necesario para cargar y dibujar los puntos:

Private Sub AbrirToolStripMenuItem_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AbrirToolStripMenuItem.Click OpenFileDialog1.Filter = "Archivos Ascii(*.asc)|*.asc|Archivos de Texto(*.txt)|*.txt|T odos los Archivos|*.*" 'Le indicamos los filtros que aparecerán al selecci onar los archivos. asc, txt, o todos. OpenFileDialog1.ShowDialog() 'Mostramos diálogo de Abrir Dim leer As New StreamReader( New FileStream(OpenFileDialog1.FileName, FileMode.Open) ) 'Creamos la variable de tipo StreamReader que nos p ermitirá manejar el fichero 'la variable se crea a partir otra de tipo FileStre am asociada al archivo seleccionado y 'Abiendo el archivo

Private Sub frm_visor_Resize( ByVal sender As Object , ByVal e As System.EventArgs) Handles Me.Resize VdF_visor.Width = Me.Width - 15 'Igualamos el ancho del visor al ancho del formulario VdF_visor.Height = Me.Height - 65 'Igualamos el alto End Sub

Page 39: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 39 Universidad de Salamanca

Podemos entender el funcionamiento del código a partir de los comentarios en el

mismo.

Podemos utilizar las herramientas del menú inferior para cambiar de vista, etc.

Vamos a escribir el código para guardar el documento creado. En la versión de

evaluación solo nos permite guardarlo en formato “vdml”, pero podemos utilizar la

aplicación Vector Draw File converter para convertir a DWG, DGN o DXF entre otros.

El código sería:

Dim linea As String Dim vdf_punto As New VectorDraw.Geometry.gPoint 'Variable de la clase punto que proporciona vector Draw. 'Es la misma idea que la clase punto3D que nos crea mos nosotros en la biblioteca de clases de la introducc ión VdF_visor.BaseControl.ActiveDocument.[New]( ) ' Creamos un documento nuevo Dim punto(2) As String 'Vector de tres cadenas para guardar la X,Y,Z de cada punto Do linea = leer.ReadLine 'Leemos una linea del fichero If Not linea Is Nothing Then 'Si la linea no está vacia punto = Split(linea, vbTab, 3) 'Separamos con la función Split la linea por la posición del separado r "tabulador" 'Limitamos el número de trozos a 3 para no desborda r el vector If punto.Length = 3 Then 'Si no hay tres coordenadas descartamos el dato vdf_punto.x = CDbl (punto(0)) 'Ponemos en la coordenada x del punto de vector Draw el valor leid o vdf_punto.y = CDbl (punto(1)) 'Igual en la y vdf_punto.z = CDbl (punto(2)) 'Igual en la Z 'VdF_visor.BaseControl.ActiveDocument.ActivePenColo r.SystemColor = Color.Yellow 'Forma de indicar el color con colores del sistema VdF_visor.BaseControl.ActiveDocument.ActivePenColor .TrueColor = RGB(0, 255, 255) 'Indicamos el color en RGB VdF_visor.BaseControl.ActiveDocument.CommandAction. CmdPoint(vdf_punto) 'Dibujamos el punto End If End If Loop Until linea Is Nothing 'Repetimos hasta que linea sea vacia que se habrá terminado el fichero leer.Close() 'Cerramos el fichero leer = Nothing VdF_visor.BaseControl.ActiveDocument.Comman dAction.Zoom( "e" , Nothing , Nothing ) 'Hacemos zoom Extension End Sub

Page 40: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 40 Universidad de Salamanca

Guardamos y cerramos el proyecto.

9 Cargar y dibujar puntos con información de color.

Vamos a crear otro proyecto casi igual al anterior, pero ahora los ficheros a parte de la

X,Y,Z tendrán también información de color en RGB. Creamos otro proyecto nuevo

para dibujar los puntos con nombre “DibujarColor”. Cambiamos el nombre al

formulario y le llamamos frm_visor. En el incorporamos un menú como el siguiente:

Vamos a incorporar el componente . Le vamos a cambiar

el nombre a vdf_visor.

El código a asociar al menú Abrir y dibujar es:

Private Sub GuardarToolStripMenuItem_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GuardarToolStripMenuItem.Click Dim ver As String = "" Dim nombre As String = VdF_visor.BaseControl.ActiveDocument.GetSaveFileNam eDlg(VdF_visor.BaseControl.ActiveDocument.FileName, ver) 'Tomamos el nombre del dialogo de guardar que nos proporciona vector Draw If Not (nombre Is Nothing ) Then VdF_visor.BaseControl.ActiveDocument.Sa veAs(nombre) 'Guardamos el documento creado End If End Sub

Private Sub AbrirToolStripMenuItem_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AbrirToolStripMenuItem.Click OpenFileDialog1.Filter = "Archivos Ascii(*.asc)|*.asc|Archivos de Texto(*.txt)|*.txt|T odos los Archivos|*.*" 'Le indicamos los filtros que aparecerán al selecci onar los archivos. asc, txt, o todos. OpenFileDialog1.ShowDialog() 'Mostramos diálogo de Abrir Dim leer As New StreamReader( New FileStream(OpenFileDialog1.FileName, FileMode.Open) ) 'Creamos la variable de tipo StreamReader que nos p ermitirá manejar el fichero 'la variable se crea a partir otra de tipo FileStre am asociada al archivo seleccionado y 'Abiendo el archivo Dim linea As String Dim vdf_punto As New VectorDraw.Geometry.gPoint 'Variable de la clase punto que proporciona vector Draw. 'Es la misma idea que la clase punto3D que nos crea mos nosotros en la biblioteca de clases de la introducc ión 'Forma de indicar el color con colores del sistema

Page 41: Tema3 Lidar

Herram. Inf. para el Geoprocesado. Procesamiento y Gestión de datos Láser y Rádar Geotecnologías Cartográficas en Ingeniería y Arquitectura

Escuela Politécnica Superior de Ávila 41 Universidad de Salamanca

Probamos a Cargar el archivo Catedral_RGBmini.asc y el archivo

Catedral_RGB_Parte.asc para comprobar su funcionamiento.

En la opción de guardar le ponemos el mismo código que en el ejemplo anterior.

'Es la misma idea que la clase punto3D que nos crea mos nosotros en la biblioteca de clases de la introducc ión VdF_visor.BaseControl.ActiveDocument.[New]( ) ' Creamos un documento nuevo Dim punto(5) As String 'Vector de tres cadenas para guardar la X,Y,Z de cada punto Dim rojo, verde, azul As Integer Do linea = leer.ReadLine 'Leemos una linea del fichero If Not linea Is Nothing Then 'Si la linea no está vacia punto = Split(linea, vbTab, 6) 'Separamos con la función Split la linea por la posición del separado r "tabulador" 'Limitamos el número de trozos a 3 para no desborda r el vector If punto.Length = 6 Then 'Si no hay tres coordenadas y 3 colores descartamos el dato vdf_punto.x = CDbl (punto(0)) 'Ponemos en la coordenada x del punto de vector Draw el valor leid o vdf_punto.y = CDbl (punto(1)) 'Igual en la y vdf_punto.z = CDbl (punto(2)) 'Igual en la Z rojo = CInt (punto(3)) verde = CInt (punto(4)) azul = CInt (punto(5)) 'VdF_visor.BaseControl.ActiveDocument.ActivePenColo r.SystemColor = Color.Yellow 'Forma de indicar el color con colores del sistema VdF_visor.BaseControl.ActiveDocument.ActivePenColor .TrueColor = RGB(rojo, verde, azul) 'Indicamos el color en RGB VdF_visor.BaseControl.ActiveDocument.CommandAction. CmdPoint(vdf_punto) 'Dibujamos el punto End If End If Loop Until linea Is Nothing 'Repetimos hasta que linea sea vacia que se habrá terminado el fichero leer.Close() 'Cerramos el fichero leer = Nothing VdF_visor.BaseControl.ActiveDocument.Comman dAction.Zoom( "e" , Nothing , Nothing ) 'Hacemos zoom Extension End Sub