martes, 5 de mayo de 2015

MapBasic: Etiquetado según atributos de un Tab

En esta oportunidad veremos un ejemplo sencillo de crear un etiquetado para un Tab en Mapinfo (usando MapBasic). Para ello usamos un Tab y leemos dos de sus columnas, una de ellas servirá para etiquetar y el otro será para usarla de condición y crear estilos de textos diferenciados (algo similar al ArcGIS).
Rápidamente veremos las funciones que usaremos en  MapBasic son (toda esta información está en el “Help” de MapBasic):
Función MakeFont: Utilizado para la creación de estilos de Texto. Tiene la siguiente sintaxis:



MakeFont(Nombre Fuente, Estilo, Tamaño, Color de la Fuente, Color de Fondo)


Dónde:
Nombre Fuente: nombre de un tipo de Fuente, de tipo String.
Estilo: El estilo (negrita, cursiva, subrayado, etc.) de la Fuente, de tipo Entero positivo.
Tamaño: el tamaño o altura de la Fuente, de tipo Entero positivo.
Color de la Fuente: como su nombre indica, de tipo Entero.
Color de Fondo: es el color que está detrás del texto, de tipo Entero o -1 si no se quiere ningún color.
Para el estilo, los Enteros para cada estilo son:
0 = Sin Estilo (Plain)
1 = Negrita (Bold)
2 = Italic (Cursiva)
4 = Subrayado (Underline)
8 = Tachado (Strikethrough)
32 = Sombreado (Shadow)
256 = Halo
512 = Mayusculas (All Caps)
1024 = Expanded (Expandido)

Si se quiere usar Negrita y Cursiva a la vez, se suman estos valores. Ejemplo:
Set Style Font
MakeFont("Arial",3,12,MiColor1 ,-1)
Donde 3 es la suma de Negrita (1) + Cursiva (2). Y así se hacen las combinaciones requeridas de Estilos.

Para el caso de los colores, se usa la Función RGB:

RGB(rojo,verde, azul)
Dónde:
rojo: valor para el color rojo, es un entero que va desde 0 hasta 255.
verde: valor para el color verde, es un entero que va desde 0 hasta 255.
azul: valor para el color azul, es un entero que va desde 0 hasta 255.

También vemos la Función Run Command, que tiene la particularidad de ejecutar todo lo que está entre comillas como si fuera comandos de MapBasic

Ejemplo de Uso:
Tenemos un Tab con los departamentos del Perú (“PERU_DEPARTAMENTOS”) y cuenta con dos columnas: la columna “NOMBRE” (donde están los nombres de los Departamentos del Perú y algunos lagos) y la Columna “REGION” (referida en forma genérica a las tres regiones naturales que tiene el Perú). Se desea crear un tab (cuyo nombre será “TAB_ETIQUETA”) con las nombres de los departamentos y de los cuerpos de agua, y que por cada región tenga un tipo diferente de texto. Vemos la Tabla de datos de “PERU_DEPARTAMENTOS” para mayor detalle:




El código a usar es el siguiente:

Include "Mapbasic.def"

Dim MiTabla as String
Dim RutaTabEtiqueta as String
Dim EscalaVista as Float
Dim idMapa as Integer
Dim MiTablaRefEspacial as String
Dim ColSeparar as String
Dim ColEtiquetar as String
Dim ColSepararObj as Alias
Dim ColEtiquetarObj as Alias
Dim MiObj as Alias
Dim X as Float
Dim Y as Float
Dim ValorEtiqueta as String
Dim ValorSeparacion as String
Dim MiColor1, MiColor2, MiColor3, MiColor4 as Integer

idMapa = FrontWindow()'id del Mapa Actual

MiTabla = "PERU_DEPARTAMENTOS"'nombre del Tab de origen de las etiquetas
ColEtiquetar = "NOMBRE" 'campo donde se obtendra el texto a etiquetar
ColSeparar = "REGION" 'campo donde se obtendra la condición para etiquetar
MiTablaRefEspacial = TableInfo(MiTabla ,29) 'referencia espacial del tab de origen de las etiquetas

MiColor1 = RGB(255, 176, 96) 'color para primera condición
MiColor2 = RGB(128, 0, 0)'color para segunda condición 
MiColor3 = RGB(0, 128, 0)'color para tercera condición
MiColor4 = RGB(0, 128, 128)'color para cuarta condición

RutaTabEtiqueta = "C:\MAYO\TAB_ETIQUETA" 'ruta y nombre del tab donde estaran las etiquetas
Create Table "TAB_ETIQUETA" (Label Char(50)) File  RutaTabEtiqueta 'creacion del tab donde estaran las etiquetas
Run Command "Create Map For TAB_ETIQUETA " & MiTablaRefEspacial  'creacion del archivo map donde estaran las etiquetas
Add Map Auto Layer "TAB_ETIQUETA" 'se añade este archivo ultimo creado al Mapa Actual

Fetch First From MiTabla 'Inicio de la lectura de la Tabla de "PERU_DEPARTAMENTOS"
Do While Not EOT (MiTabla) 

 MiObj = MiTabla & ".obj" 'Obtengo la Geometria del registro actualmente leido
 ColEtiquetarObj = MiTabla & "." & ColEtiquetar 'Obtengo el valor de la columna NOMBRE del registro actualmente leido
 ColSepararObj = MiTabla & "." & ColSeparar 'Obtengo el valor de la columna REGION del registro actualmente leido
 ValorEtiqueta = ColEtiquetarObj 'pasar variable ALIAS a STRING
 ValorSeparacion = ColSepararObj 'pasar variable ALIAS a STRING

 X = CentroidX(MiObj) 'Obtengo la coordenada X del Centroide de la Geometria del registro actualmente leido
 Y = CentroidY(MiObj) 'Obtengo la coordenada Y del Centroide de la Geometria del registro actualmente leido

 'Inicio de la condicion para el tipo de Etiquetado
 If ValorSeparacion = "COSTA" Then
  Set Style Font MakeFont("Arial",0,12,MiColor1 ,-1)
 ElseIf ValorSeparacion = "SIERRA" Then
  Set Style Font MakeFont("Tahoma",1,12,MiColor2 ,WHITE)
 ElseIf ValorSeparacion = "SELVA" Then
  Set Style Font MakeFont("Helvetica",3,12,MiColor3, -1 )
 ElseIf ValorSeparacion = "LAGO" Then
  Set Style Font MakeFont("Arial",2,8,MiColor4 ,WHITE)
 End If

 Insert Into "TAB_ETIQUETA" (obj) 'Inserción de los valores de la columna NOMBRE segun el estilo seleccionado
  Values (Createtext (idMapa ,X,Y, ValorEtiqueta ,0, 0, 0  )) 

 Fetch Next From MiTabla 'lectura del siguiente registro
Loop

Commit Table "TAB_ETIQUETA" ' guarda los cambios del Tab "TAB_ETIQUETA"
Explicación del Código: el código esta comentado explicando cada paso seguido. Se hará hincapié en las líneas:
ColEtiquetarObj = MiTabla & "." & ColEtiquetar
ColSepararObj = MiTabla & "." & ColSeparar
ValorEtiqueta =ColEtiquetarObj
ValorSeparacion= ColSepararObj
   Insert Into "TAB_ETIQUETA" (obj) 
           
Values (Createtext (idMapa ,X,Y,
ValorEtiqueta ,0, 0, 0  ))

Si bien se podría haber hecho:
Values
(Createtext (idMapa ,X,Y, ColEtiquetarObj,0, 0, 0  ))
Al hacerlo, genera un error, pareciera que el valor ColEtiquetarObj al ser una variable de tipo Alias no encaja en la función Createtext y debe ser una variable de  tipo String para evitarlo. Se hizo el mismo procedimiento para el caso de ColSepararObj para evitar algunos errores.
El resultado es el siguiente:

 












Esperando que sea de ayuda, será hasta el otro mes. Saludos
ª