martes, 25 de agosto de 2015

Crear una tabla Postgresql / Postgis desde MapInfo usando Mapbasic

En este mes se presentara un ejemplo del uso de un código en MapBasic  para exportar un Table de puntos de MapInfo hacia el Postgresql / Postgis y visualizar las geometrías en el Qgis. Para ello tenemos como referencia estos dos post anteriores:


Se usara un Table de puntos llamado CAPITAL_DEPARTAMENTOS.TAB (lo pueden descargar desde este enlace) que tiene como estructura los siguientes campos mostrados en la figura siguiente:



 De los cuales, solo usaremos el campo “Name”  de tipo String y tiene el nombre de las capitales departamentales del Perú. Señalando que esta Table tiene como Proyección "Geográfica" y Datum "WGS84".

El código mostrado a continuación hace el proceso de exportar la tabla CAPITAL_DEPARTAMENTOS.TAB al Postgresql:


INCLUDE "MAPBASIC.DEF" 

Dim hdbc As Integer 
Dim hstmt As Integer 
Dim NombreTable as String
Dim MiPunto as Object
Dim LatLong as String
dim aux as string 

NombreTable = "CAPITAL_DEPARTAMENTOS" 'NOMBRE DE LA TABLE DE MAPINFO Y DE LA TABLA QUE SE CREARA EN EL POSTGRES
hdbc = Server_Connect("ODBC", "DSN=PostgreSQL30;UID=postgres;PWD=MI_PASSWORD") ' HACE LA CONECCION A LA BASE DE DATOS 

'LA VARIABLE aux TENDRA LA CONSULTA SQL PARA CREAR UNA TABLA CON TRES COLUMNAS:
'gid: QUE ES EL Primary Key
'Nombre: NOMBRE DE LAS CAPITALES
'the_geom: LOS PUNTOS DE LAS CAPITALES
aux = "Create Table " & Chr$(34) & NombreTable & Chr$(34)  & " (gid serial NOT NULL, Nombre Varchar, the_geom geometry); "

'TAMBIEN ESTARAN LOS Constrains NECESARIOS PARA DEFINIR EL Primary Key
aux = aux & "  Alter Table " & Chr$(34) & NombreTable & Chr$(34) & " ADD Primary Key (gid);"

'DIMENSION DE LA GEOMETRIA
aux = aux & "  Alter Table " & Chr$(34) & NombreTable & Chr$(34) & " ADD Constraint enforce_dims_the_geom Check (st_ndims(the_geom) = 2);"


'TIPO DE GEOMETRIA
aux = aux & "  Alter Table " & Chr$(34) & NombreTable & Chr$(34) & " ADD Constraint enforce_geotype_the_geom Check (geometrytype(the_geom) = 'POINT'::text OR the_geom IS NULL);"


'PROJECCION
aux = aux & "  Alter Table " & Chr$(34) & NombreTable & Chr$(34) & " ADD Constraint enforce_srid_the_geom Check (srid(the_geom) = 4326);"

hstmt = Server_Execute(hdbc, aux ) 'EJECUTA LA CONSULTA QUE ESTA EN LA VARIABLE aux

'SELECCIONO LOS DATOS DE LA TABLE "CAPITAL_DEPARTAMENTOS"
Select * from NombreTable order by NAME into MiSeleccion NoSelect 

'RECORREMOS LA SELECCION PARA GUARDARLO EN EL POSTGRESQL:
Fetch First From MiSeleccion 'POSICIONO EL PUNTERO EN LA PRIMERA FILA
Do While Not EOT (MiSeleccion)'ESTE LOOP HACE EL RECORRIDO
 MiPunto = MiSeleccion.obj'LEO EL PUNTO DE LA FILA
 LatLong = "ST_SetSRID(ST_MakePoint(" & Str$(CentroidX(MiPunto))& "," & Str$(CentroidY(MiPunto)) & "), 4326)" 'CONSTRUYO LA CONSULTA PARA LA GEOMETRIA

 'Y CONSTRUYO LA CONSULTA PARA LA NUEVA FILA A INSERTAR EN LA TABLA CREADA
 aux = "Insert Into " & Chr$(34) & NombreTable & Chr$(34) & "( Nombre, the_geom) Values (" & Chr$(39)& MiSeleccion.NAME & Chr$(39)& "," &  LatLong & ")" 

 hstmt = Server_Execute(hdbc, aux)'EJECUTA LA CONSULTA QUE ESTA EN LA VARIABLE aux
 Fetch Next From MiSeleccion'SE MUEVE A LA SIGUIENTE FILA
Loop


El código se encuentra explicado por los comentarios y vemos los resultados como se muestran en las dos figuras siguientes:


































Hay que señalar que faltaría implementar para el caso de que se detecte que la tabla en Postgresql ya exista y ver el tipo de la proyección del Table. Sera hasta el otro mes. Saludos
ª