Re: [Gvsig_desarrolladores] problema con geometrías

Francisco José fpenarru en iver.es
Vie Dic 23 13:22:47 CET 2005


Fernando González Cortés escribió:

>Hola Fran, 
>
>Este es mas fluido... Busca los comentarios entre tu correo, hay 3 ;).
>
>El vie, 23-12-2005 a las 09:27, Francisco José escribió:
>  
>
>>Hola Fernando.
>>    
>>
>ok, gracias por la info
>
>sólo me queda pues la duda del shapefile, de la serie de aros en la que
>no se puede saber qué agujero es de qué borde...
>
>  
>
Puedes probar alguno de los algoritmos que hay en el JTS. Coges un punto 
que pertenece al "hole" y testeas si es interior a cada uno de los aros 
externos.

>Vale, este problema sea posíblemente sólo mío, aunque conviene que lo
>tengais en cuenta. Creo recordar que al editar postGIS, y terminar la
>edición creo una serie de comandos SQL (INSERT, UPDATE y DELETE) que
>actualizan la tabla. Obtengo la geometría en JTS y luego obtengo la
>representación en WKT. De esa manera obtengo "Polygon(...)" en una tabla
>de multipolígonos y eso viola restricciones de la tabla de postgis ya
>que no se puede insertar un polígono en una tabla de multipolígonos. No
>se si es exactamente así, pero por ahí van los tiros.
>
>saludos y feliz navidad a todos...
>
>
>  
>
A mi también me pasó en el ejemplo que viene con la extensión para bases 
de datos espaciales. El ejemplo lo que hace es meter una capa (sea de lo 
que sea) en una tabla en PostGis.
Al intentarlo por primera vez, sobre una capa ya hecha, daba el problema 
de que normalmente esas capas han sido generadas con el programa que 
viene con la instalación de PostGIS, y genera la tabla de polígonos con 
la restricción de que todo lo que metas ahí dentro debe ser MultiPolygon 
(y en el caso de las líneas, creo que MultiLineString).
Para evitar eso de manera rápida, lo que hice fue crear las tablas de 
Postgis para que admitan cualquier tipo de entidad (el importador está 
pensado como un ejemplo, como un punto de partida para importadores más 
elaborados.
Bueno, el caso es que cuando creas la tabla, si la creas con
 String strGeometryFieldType = "GEOMETRY" como tipo de columna, te 
acepta cualquier tipo de entidad.

Si tienes que guardar entidades en tablas que han sido creadas con el 
otro método, necesitarás convertir tus entidades a MultiPolygon, 
MultiLineString, etc, aunque sean de tipo Polygon solo. Puedes ver un 
ejemplo de cómo lo hace ese programa si te bajas el código de PostGIS. 
(En el cvs postgis.refractions.net, en el path /home/cvs/postgis el 
módulo postgis/loader
Este es el método que decide en qué va a convertir las geometrías:

void
SetPgType(void)
{
    switch(shpfiletype)
    {
        case SHPT_POINT: // Point
            pgtype = "POINT";
            wkbtype = POINTTYPE;
            pgdims = 2;
            break;
        case SHPT_ARC: // PolyLine
            pgtype = "MULTILINESTRING";
            wkbtype = MULTILINETYPE ;
            pgdims = 2;
            break;
        case SHPT_POLYGON: // Polygon
            pgtype = "MULTIPOLYGON";
            wkbtype = MULTIPOLYGONTYPE;
            pgdims = 2;
            break;
        case SHPT_MULTIPOINT: // MultiPoint
            pgtype = "MULTIPOINT";
            wkbtype = MULTIPOINTTYPE;
            pgdims = 2;
            break;
        case SHPT_POINTM: // PointM
            wkbtype = POINTTYPE | WKBMOFFSET;
            if ( ! hwgeom ) {
                pgtype = "POINTM";
                pgdims = 3;
                istypeM = 1;
            } else {
                pgtype = "POINT";
                pgdims = 2;
            }
            break;
        case SHPT_ARCM: // PolyLineM
            wkbtype = MULTILINETYPE | WKBMOFFSET;
            if ( ! hwgeom ) {
                pgtype = "MULTILINESTRINGM";
                pgdims = 3;
                istypeM = 1;
            } else {
                pgtype = "MULTILINESTRING";
                pgdims = 2;
            }
            break;
        case SHPT_POLYGONM: // PolygonM
            wkbtype = MULTIPOLYGONTYPE | WKBMOFFSET;
            if ( ! hwgeom ) {
                pgtype = "MULTIPOLYGONM";
                pgdims = 3;
                istypeM = 1;
            } else {
                pgtype = "MULTIPOLYGON";
                pgdims = 2;
            }
            break;
        case SHPT_MULTIPOINTM: // MultiPointM
            wkbtype = MULTIPOINTTYPE | WKBMOFFSET;
            if ( ! hwgeom ) {
                pgtype = "MULTIPOINTM";
                pgdims = 3;
                istypeM = 1;
            } else {
                pgtype = "MULTIPOINT";
                pgdims = 2;
            }
            break;
        case SHPT_POINTZ: // PointZ
            wkbtype = POINTTYPE | WKBMOFFSET | WKBZOFFSET;
            pgtype = "POINT";
            if ( ! hwgeom ) pgdims = 4;
            else pgdims = 3;
            break;
        case SHPT_ARCZ: // PolyLineZ
            pgtype = "MULTILINESTRING";
            wkbtype = MULTILINETYPE | WKBZOFFSET | WKBMOFFSET;
            if ( ! hwgeom ) pgdims = 4;
            else pgdims = 3;
            break;
        case SHPT_POLYGONZ: // MultiPolygonZ
            pgtype = "MULTIPOLYGON";
            wkbtype = MULTIPOLYGONTYPE | WKBZOFFSET | WKBMOFFSET;
            if ( ! hwgeom ) pgdims = 4;
            else pgdims = 3;
            break;
        case SHPT_MULTIPOINTZ: // MultiPointZ
            pgtype = "MULTIPOINT";
            wkbtype = MULTIPOINTTYPE | WKBZOFFSET | WKBMOFFSET;
            if ( ! hwgeom ) pgdims = 4;
            else pgdims = 3;
            break;
        default:
            pgtype = "GEOMETRY";
            wkbtype = COLLECTIONTYPE | WKBZOFFSET | WKBMOFFSET;
            pgdims = 4;
            fprintf(stderr, "Unknown geometry type: %d\n",
                shpfiletype);
            break;
    }
}

donde puedes ver que, por ejemplo, el Polygon lo convertirá siempre a 
MULTIPOLYGON.

Resumiendo: Que tendremos que meter algún método del tipo 
ConvertToWKT(IGeomety, toWktType), y que como mínimo cree el WKT a 
MULTIPOLYGON y a MULTILINESTRING). Los de tipo M son un poco especiales, 
no creo que corra prisa.

Saludos, y Feliz Navidad.

-- 
Francisco José Peñarrubia
Equipo gvSIG

IVER T.I. S.A.
c/Salamanca 50
46005 Valencia
Spain




Más información sobre la lista de distribución gvSIG_desarrolladores