Tema 3: Procesamiento y Gestión de datos láser y rádar

Anuncio
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
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.
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
1
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
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|Todos los
Archivos|*.*"
'Le indicamos los filtros que aparecerán al seleccionar 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 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 FileStream
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 los 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 separador "tabulador"
'Limitamos el número de trozos a 3 para no desbordar
el vector
If punto.Length = 3 Then 'Si no hay tres coordenadas
descartamos el dato
dgv_tabla.Rows.Add(punto(0), punto(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
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
2
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
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.
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
3
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
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.
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
4
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
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
0-9
10 - 59
60 - 79
90-99
100 y 102
105
140 - 147
170 - 175
280 - 289
300 - 309
310-319
320-329
330-369
999
1000 - 1009
1010-1059
1060 - 1069
1071
TIPO DE VALOR DE GRUPO
Cadena
Punto 3D de doble precisión
Valor entero de 16 bits
Valor entero de 32 bits
Cadena
Cadena con un valor de identificador hexadecimal
Valor de coma flotante escalar de doble precisión
Valor entero de 16 bits
Valor entero de 8 bits.
Cadena de texto arbitraria
Cadena que representa el valor hexadecimal de un bloque
binario
Cadena que representa un valor de identificador Hexadecimal
Cadena que representa identificador de objeto hexadecimal
Comentario
Cadena
Valor de coma flotante
Valor entero de 16 bits
Valor entero de 32 bits
Hay algunos valores que por lo que se usan conviene tratar con más detalle:
CÓDIGO
0
1
2
5
6
7
8
9
40-48
62
66
67
70-78
DESCRIPCIÓN
Cadena de texto que indica el tipo de entidad (fijo)
Valor de texto principal de una entidad
identificador de atributos, nombre de bloque, etc.
Identificador de entidad. Cadena de texto de hasta 16 dígitos
hexadecimales (fijo)
Nombre de tipo de línea (fijo)
Nombre de estilo de texto (fijo)
Nombre de capa (fijo)
DXF: identificador de nombre de variable (sólo se utiliza en la sección
HEADER (encabezamiento) del archivo DXF)
Valores de coma flotante (altura de texto, factores de escala,etc.)
Número de color (fijo)
Indica que siguen entidades. Caso de entidades complejas
Espacio (modelo o papel).
Valores enteros, como número de repeticiones, bits indicadores o modos.
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
5
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
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
SECTION
2
ENTITIES
0
POINT
8
Puntos
10
150.000
20
125.000
30
75.000
0
POINT
8
Puntos
10
250.000
20
225.000
30
75.000
0
LINE
8
Lineas
62
5
10
100.000
20
100.000
30
100.000
11
200.000
21
200.000
31
200.000
0
ENDSEC
0
EOF
COMIENZO DE SECCIÓN
INDICADOR DE SECCIÓN
CÓDIGO DE GRUPO
INDICADOR DE QUE ES LA SECCIÓN ENTIDADES
CODIGO DE COMIENZO DE ENTIDAD
TIPO DE ENTIDAD PUNTO
CÓDIGO QUE INDICA QUE SIGUE UNA CAPA 8
NOMBRE DE LA CAPA EN ESTE CASO PUNTOS
CÓDIGO DE LA COORDENADA X
VALOR DE LA X DEL PUNTO
CÓDIGO DE LA Y
VALOR DE LA Y DEL PUNTO
CÓDIGO DE LA Z
VALOR DE LA Z
COMIENZO DE OTRA ENTIDAD
INDICA QUE ES UN PUNTO
COMO ANTES LA CAPA Y LA X, Y, Z DEL PUNTO
COMIENZO DE OTRA ENTIDAD
ES UNA LINEA
INDICADOR DE QUE SIGUE UNA CAPA
NOMBRE DE LA CAPA
CODIGO PARA INDICAR UN COLOR DE ENTIDAD
COLOR 5 AZUL
CODIGO DE LA X DEL PUNTO INICIAL DE LA LINEA
VALOR DE LA X DEL INICIO DE LINEA
CÓDIGO DE LA Y
VALOR DE LA Y DEL INICIO DE LINEA
CÓDIGO DE LA Z
VALOR DE LA z DEL INICIO
CÓDIGO DE LA X DEL FIN DE LINEA
VALOR DE LA X DEL FINAL
CÓDIGO DE LA Y
VALOR DE LA Y DEL FINAL
CÓDIGO DE LA Z
VALOR DE LA Z DEL FINAL DE LA LINEA
PARA INDICAR QUE SIGUE UNA PALABRA A ANALIZAR
FINAL DE LA SECCIÓN DE ENTIDADES
QUE SIGUE UNA PALABRA
FINAL DEL FICHERO
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
6
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
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:
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|Archivos
XYZ(*.xyz)|*.xyz|Todos los Archivos|*.*"
'Le indicamos los filtros que aparecerán al seleccionar los
archivos. asc, txt, xyz o todos.
OpenFileDialog1.ShowDialog() 'Mostramos diálogo de Abrir
txt_Original.Text = OpenFileDialog1.FileName 'Colocamos en
el cuadro de texto la ruta y nombre del fichero seleccionado
End Sub
Al botón Archivo Destino le asignamos el código:
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 *.dxf
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
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
7
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
Dejamos la parte de convertir el código para el final y colocamos el fragmento de salir:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
Me.Close()
End Sub
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:
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}, _
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
{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}, _
8
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
{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}, _
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
{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
9
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
'Función que recibe los colores en RGB y devuelve el
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) / 255
If Varianza < menorVarianza Then
menorVarianza = Varianza
ACI_Cercano_RGB = i
End If
Next
End Function
End Module
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:
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 FileStream
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 asociarsela
al fichero que nos han indicado.
'Le ponemos que nos abra o nos cree el archivo si no 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")
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
10
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
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 separador
"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 color
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 hayamos 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 hayamos definido
previamente
escribir.WriteLine("62") 'Código para
decirle que lo siguiente es el color. Si no se indica 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
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
11
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
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
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.
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
12
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
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á:
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
13
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
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:
Imports Voronoi.Data
Imports Voronoi.Mathematics
Imports System.Drawing
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.
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
Al botón Triangulación de Delaunay le asociamos el código:
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
14
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
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 '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 biblioteca 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
Y al botón Diagrama de Voronoi le ponemos:
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 biblioteca que
nos devuelve un Bitmap
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
15
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
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
Al ejecutar el programa si pulsamos en el primer botón nos creará algo así
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
16
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
Y en el segundo pondrá:
Guardamos el proyecto.
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
17
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
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
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
18
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
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 * distanciax + distanciay
* distanciay + distanciaz * distanciaz)
'Calculamos la distancia y se la asignamos al nombre de la
función. Así devolvemos el valor
End Function
End Class
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:
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
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
19
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
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 Object
Get
If indice > Count - 1 Or indice < 0 Then
System.Windows.Forms.MessageBox.Show("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
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
20
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
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
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
21
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
La clase ListaLineas.vb queda:
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
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.
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
22
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
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 asociarsela al
fichero que nos han indicado.
'Le ponemos que nos abra o nos cree el archivo si no
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).ToString)
Next
escribir.Close() 'cerramos el archivo
End Sub
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
23
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
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
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
24
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
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
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:
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
25
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
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.
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
26
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
La parte inicial de la clase queda:
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
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:
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|Todos los
Archivos|*.*"
'Le indicamos los filtros que aparecerán al seleccionar 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 nombre 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 FileStream
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 los
puntos
Dim punto(5) As String 'Vector de tres cadenas para
guardar la X,Y,Z de cada punto
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
27
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
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 separador "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 color
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
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
28
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
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á:
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 *.txt
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.OpenOrCreate))
'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 no
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
Para la opción guardar en DXF utilizamos la biblioteca creada. Nos quedará:
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 *.dxf
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
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
29
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
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
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:
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)
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
30
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
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
Previamente habremos creado el formulario Filtrado.vb con el aspecto
En el botón Reducir puntos escribimos:
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
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:
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
31
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
En el botón reducir escribiremos:
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
En el menú reducir por cota del formulario principal le asociamos
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
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
32
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
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
Guardamos el proyecto y generamos el ejecutable.
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
33
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
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.
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
34
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
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.
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
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ú.
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
35
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
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.
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
36
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
Y aquí marcamos el control.
La ficha de controles aparecería:
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
37
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
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:
que comentábamos
Vamos a incorporar el componente
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.
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
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|Todos los
Archivos|*.*"
'Le indicamos los filtros que aparecerán al seleccionar 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 permitirá
manejar el fichero
'la variable se crea a partir otra de tipo FileStream
asociada al archivo seleccionado y
'Abiendo el archivo
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
38
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
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 creamos
nosotros en la biblioteca de clases de la introducció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 separador "tabulador"
'Limitamos el número de trozos a 3 para no desbordar
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 leido
vdf_punto.y = CDbl(punto(1)) 'Igual en la y
vdf_punto.z = CDbl(punto(2)) 'Igual en la Z
'VdF_visor.BaseControl.ActiveDocument.ActivePenColor.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_punt
o)
'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.CommandAction.Zoom("e",
Nothing, Nothing) 'Hacemos zoom Extension
End Sub
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:
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
39
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
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.GetSaveFileNameDlg(VdF_visor.Ba
seControl.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.SaveAs(nombre)
'Guardamos el documento creado
End If
End Sub
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
el nombre a vdf_visor.
El código a asociar al menú Abrir y dibujar es:
. Le vamos a cambiar
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|Todos los
Archivos|*.*"
'Le indicamos los filtros que aparecerán al seleccionar 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 permitirá
manejar el fichero
'la variable se crea a partir otra de tipo FileStream
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 creamos
nosotros en la biblioteca de clases de la introducción
'Forma de indicar el color con colores del sistema
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
40
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
'Es la misma idea que la clase punto3D que nos creamos
nosotros en la biblioteca de clases de la introducció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 separador "tabulador"
'Limitamos el número de trozos a 3 para no desbordar
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 leido
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.ActivePenColor.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_punt
o)
'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.CommandAction.Zoom("e",
Nothing, Nothing) 'Hacemos zoom Extension
End Sub
Probamos a Cargar el archivo Catedral_RGBmini.asc
Catedral_RGB_Parte.asc para comprobar su funcionamiento.
y
el
archivo
En la opción de guardar le ponemos el mismo código que en el ejemplo anterior.
Escuela Politécnica Superior de Ávila
Universidad de Salamanca
41
Descargar