gaiaGeom到AGSGeometry的转换

在iOS应用中做离线数据管理和查询的时候,libspatialite是一个不错的选择。那么使用ArcGIS runtime for iOS 作为基本开发框架的时候,数据交互就成为一个基本的功能,libspatialite 提供的Geometry为gaiaGeom 类型,ArcGIS runtime for iOS无法使用,需要将其转换为AGSGeometry对象。 下面的代码完成数据的转换: - (AGSGeometry *) geometryWithGaiaGeomColl: (void *)geometry { int pts = 0; int lns = 0; int pgs = 0; int type;

int iv; int ib; double x; double y; double x0; double y0;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng; int ring_points; int n_items;
gaiaGeomCollPtr gaia = (gaiaGeomCollPtr)geometry; if (!gaia) return NULL;
pt = gaia->FirstPoint; while (pt)
{ /* counting how many POINTs are there */ pts++;
    pt = pt->Next;
}
ln = gaia->FirstLinestring; while (ln)
{ /* counting how many LINESTRINGs are there */ lns++;
    ln = ln->Next;
}
pg = gaia->FirstPolygon; while (pg)
{ /* counting how many POLYGONs are there */ pgs++;
    pg = pg->Next;
} if (pts == 0 && lns == 0 && pgs == 0) return nil; else if (pts == 1 && lns == 0 && pgs == 0)
{ if (gaia->DeclaredType == GAIA_MULTIPOINT)
        type = GAIA_MULTIPOINT; else if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION)
        type = GAIA_GEOMETRYCOLLECTION; else type = GAIA_POINT;
} else if (pts == 0 && lns == 1 && pgs == 0)
{ if (gaia->DeclaredType == GAIA_MULTILINESTRING)
        type = GAIA_MULTILINESTRING; else if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION)
        type = GAIA_GEOMETRYCOLLECTION; else type = GAIA_LINESTRING;
} else if (pts == 0 && lns == 0 && pgs == 1)
{ if (gaia->DeclaredType == GAIA_MULTIPOLYGON)
        type = GAIA_MULTIPOLYGON; else if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION)
        type = GAIA_GEOMETRYCOLLECTION; else type = GAIA_POLYGON;
} else if (pts > 1 && lns == 0 && pgs == 0)
{ if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION)
        type = GAIA_GEOMETRYCOLLECTION; else type = GAIA_MULTIPOINT;
} else if (pts == 0 && lns > 1 && pgs == 0)
{ if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION)
        type = GAIA_GEOMETRYCOLLECTION; else type = GAIA_MULTILINESTRING;
} else if (pts == 0 && lns == 0 && pgs > 1)
{ if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION)
        type = GAIA_GEOMETRYCOLLECTION; else type = GAIA_MULTIPOLYGON;
} else type = GAIA_GEOMETRYCOLLECTION;

AGSGeometry * agsGeometry = nil; switch (type)
{ case GAIA_POINT:
        {
            agsGeometry = [[AGSMutablePoint alloc] initWithX:DBL_MIN y:DBL_MIN spatialReference:nil];
            pt = gaia->FirstPoint;
            [((AGSMutablePoint*)agsGeometry) updateWithX:pt->X y:pt->Y];

        } break; case GAIA_LINESTRING:
        {
            ln = gaia->FirstLinestring;
            agsGeometry = [[AGSMutablePolyline alloc] init];
            [((AGSMutablePolyline*)agsGeometry) addPathToPolyline]; for (iv = 0; iv < ln->Points; iv++)
            {
                gaiaGetPoint (ln->Coords, iv, &x, &y);
                [((AGSMutablePolyline*)agsGeometry) addPointToPath:[AGSPoint pointWithX:x y:y spatialReference:nil]];
            }
        } break; case GAIA_POLYGON:
        {
             agsGeometry = [[AGSMutablePolygon alloc] init];

            [((AGSMutablePolygon*)agsGeometry) addRingToPolygon];
            pg = gaia->FirstPolygon;
            rng = pg->Exterior; /* exterior ring */ ring_points = rng->Points; if (gaiaIsNotClosedRing (rng))
                ring_points++; for (iv = 0; iv < rng->Points; iv++)
            { if (iv == 0)
                { /* saving the first vertex */ x0 = x;
                    y0 = y;
                }
                gaiaGetPoint (rng->Coords, iv, &x, &y);
                [((AGSMutablePolygon*)agsGeometry) addPointToRing:[AGSPoint pointWithX:x y:y spatialReference:nil]];

            } if (ring_points > rng->Points)
            { /* ensuring Ring's closure */ [((AGSMutablePolygon*)agsGeometry) addPointToRing:[AGSPoint pointWithX:x0 y:y0 spatialReference:nil]];

            } if (pg->NumInteriors > 0)
            { for (ib = 0; ib < pg->NumInteriors; ib++)
                {
                    [((AGSMutablePolygon*)agsGeometry) addRingToPolygon]; /* interior ring */ rng = pg->Interiors + ib;
                    ring_points = rng->Points; if (gaiaIsNotClosedRing (rng))
                        ring_points++; for (iv = 0; iv < rng->Points; iv++)
                    {
                        gaiaGetPoint (rng->Coords, iv, &x, &y); if (iv == 0)
                        { /* saving the first vertex */ x0 = x;
                            y0 = y;
                        }
                    }
                    [((AGSMutablePolygon*)agsGeometry) addPointToRing:[AGSPoint pointWithX:x y:y spatialReference:nil]]; if (ring_points > rng->Points)
                    {
                        [((AGSMutablePolygon*)agsGeometry) addPointToRing:[AGSPoint pointWithX:x0 y:y0 spatialReference:nil]];
                    }

                }
            }
        } break; default: break;
} 

return agsGeometry;

}

需要注意的是,AGSGeometry 不支持MutilPolyline和MultiPolygon类型,所以在转换的时候过滤掉。因此在制作spatialite数据的时候尽量使用简单类型。

This entry was posted in ArcGIS.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre lang="" line="" escaped="" cssfile="">